如何删除其他提示选项“全选"从dc.js selectMenu吗? [英] How to remove additional prompt option "Select all" from dc.js selectMenu?
问题描述
我有一个尺寸为A,B,C,D的尺寸.
I have a dimension with the values A,B,C,D.
我想用dc.js创建一个selectMenu,其中
I would like to create a selectMenu with dc.js, where
-
默认情况下选择值A
the value A is selected by default
只能选择一个值(不能多选)
only one value can be selected (no mulit-selection)
始终必须选择一个值
a)我使用了.multiple(false)
,并且期望默认情况下选择一个值.
但是,菜单的默认状态是选择所有可用选项(=不过滤).
a) I used .multiple(false)
and expected that a single value is selected by default.
However, the default state of the menu is to select all available options (=no filtering).
b)我还尝试将promptTitle
和promptValue
设置为所需的初始值A.
另请参见 https://dc-js.github上的文档. io/dc.js/docs/html/SelectMenu.html
b) I also tried to set the promptTitle
and promptValue
to my wanted initial value A.
Also see doc at https://dc-js.github.io/dc.js/docs/html/SelectMenu.html
但是,选项A会显示两次(并且应用初始值也不起作用)
However, then the option A is displayed twice (and applying the initial value does not work either):
let typeSelection = dc.selectMenu('#type');
typeSelection.dimension(typeDim)
.multiple(false)
.group(typeGroupCount)
.title(d => d.key)
.promptText('A')
.promptValue('A')
.controlsUseVisibility(true);
c)我也尝试使用方法filterDisplayed
.但是,仅将单个选项作为参数传递,并且这里似乎没有办法禁用全选"选项.
c) I also tried to use the method filterDisplayed
. However, only the single options are passed as arguments and there does not seem to be a way to disable the 'Select all' option here.
推荐答案
A.这是单个选择组合框的手动实现:
A. Here is a manual implementation of a single selection combo box:
<div>
<label>Type</label>
<select id='type' style='padding:5px;'>
<option>A</option>
<option>B</option>
<option>C</option>
<option>D</option>
</select>
</div>
-
dc.renderAll();
d3.select('#type')
.on('change', applyTypeSelection);
applyTypeSelection();
function applyTypeSelection(){
let selectedType = d3.select('#type').node().value;
typeDim.filter(type => {
return type === selectedType;
});
dc.redrawAll();
}
B.这是另一种方法的完整示例.它基于pretransition
事件,该事件在旧的重复问题的答案中使用
B. Here is a full example for another approach. It is based on the pretransition
event that is used in the answer of the old duplicate question
dc.selectMenu('#type')
.dimension(typeDim)
.multiple(false)
.group(typeGroupCount)
.title(d => d.key)
.on('pretransition', event => {
typeSelection.select('option[value=""]')
.remove();
})
.filter('A');
<html>
<head>
<title>dc demo</title>
<meta http-equiv='content-type' content='text/html; charset=UTF8'>
<!-- this demo is based on following tuturials:
https://www.tutorialspoint.com/dcjs/dcjs_introduction_to_d3js.htm
https://www.codeproject.com/articles/693841/making-dashboards-with-dc-js-part-1-using-crossfil
-->
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/crossfilter2/1.5.2/crossfilter.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/dc/3.1.8/dc.min.js'></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/dc/3.1.8/dc.css" />
</head>
<body>
<div style="font-family:arial;">
<div style="float:left;padding:10px;">
<div >
<label>Number of colors:</label>
<div id='color-chart-count'></div>
</div>
<div>
<label>Value sum for colors:</label>
<div id='color-chart-value-sum'></div>
</div>
</div>
<div style="float:left;padding:10px;">
<div>
<label>Number of ages:</label>
<div id='age-chart-count'></div>
</div>
<div>
<label>Value sum for ages:</label>
<div id='age-chart-value-sum'></div>
</div>
</div>
<div style="float:left;padding:10px;">
<div>
<label>Type</label>
<div id="type"></div>
<!--
<select id='type' style='padding:5px;'>
<option>A</option>
<option>B</option>
<option>C</option>
<option>D</option>
</select>
-->
</div>
</div>
</div>
<div style="font-family:arial; float:left">
<label for='value-chart'>Values:</label>
<div id='value-chart'></div>
</div>
<script>
let data = [
{color: 'red', age: 1, type: 'A', value: 10},
{color: 'red', age: 1, type: 'B', value: 11},
{color: 'red', age: 1, type: 'C', value: 12},
{color: 'red', age: 1, type: 'D', value: 13},
{color: 'red', age: 2, type: 'A', value: 20},
{color: 'red', age: 2, type: 'B', value: 21},
{color: 'red', age: 2, type: 'C', value: 22},
{color: 'red', age: 2, type: 'D', value: 23},
{color: 'red', age: 3, type: 'A', value: 30},
{color: 'red', age: 3, type: 'B', value: 31},
{color: 'red', age: 3, type: 'C', value: 32},
{color: 'red', age: 3, type: 'D', value: 33},
{color: 'green', age: 1, type: 'A', value: 100},
{color: 'green', age: 1, type: 'B', value: 105},
{color: 'green', age: 1, type: 'C', value: 110},
{color: 'green', age: 1, type: 'D', value: 115},
{color: 'green', age: 2, type: 'A', value: 120},
{color: 'green', age: 2, type: 'B', value: 125},
{color: 'green', age: 2, type: 'C', value: 130},
{color: 'green', age: 2, type: 'D', value: 135},
{color: 'green', age: 3, type: 'A', value: 140},
{color: 'green', age: 3, type: 'B', value: 145},
{color: 'green', age: 3, type: 'C', value: 150},
{color: 'green', age: 3, type: 'D', value: 155},
{color: 'blue', age: 1, type: 'A', value: 300},
{color: 'blue', age: 1, type: 'B', value: 305},
{color: 'blue', age: 1, type: 'C', value: 310},
{color: 'blue', age: 1, type: 'D', value: 315},
{color: 'blue', age: 2, type: 'A', value: 320},
{color: 'blue', age: 2, type: 'B', value: 325},
{color: 'blue', age: 2, type: 'C', value: 330},
{color: 'blue', age: 2, type: 'D', value: 335},
{color: 'blue', age: 3, type: 'A', value: 340},
{color: 'blue', age: 3, type: 'B', value: 345},
{color: 'blue', age: 3, type: 'C', value: 350},
{color: 'blue', age: 3, type: 'D', value: 355},
];
//create instance of cross filter
let cf = crossfilter(data);
//define dimensions and groups
let colorDim = cf.dimension(d=> d.color);
let colorGroupCount = colorDim.group().reduceCount();
let colorGroupValueSum = colorDim.group().reduceSum(d => d.value);
let ageDim = cf.dimension(d=> d.age);
let ageGroupCount = ageDim.group().reduceCount();
let ageGroupValueSum = ageDim.group().reduceSum(d => d.value);
let typeDim = cf.dimension(d=> d.type);
let typeGroupCount = typeDim.group().reduceCount();
let typeGroupValueSum = typeDim.group().reduceSum(d => d.value);
let colorAgeDim = cf.dimension(d => [d.color, d.age]);
function reduceAdd(previous, current) {
if(current){
if(current.value !== null){
if(previous.sum === null){
previous.sum = current.value;
previous.count = 1;
} else {
previous.sum += current.value;
previous.count += 1;
}
}
}
return previous;
}
function reduceRemove(previous, current) {
if(current){
if(current.value !== null){
if(previous.sum !== null){
previous.sum -= current.value;
previous.count -= 1;
if(previous.count === 0){
previous.sum = null;
}
}
}
}
return previous;
}
function reduceInit(previous) {
return {
sum: null,
count: 0
};
}
let colorAgeGroup = colorAgeDim.group()
.reduce(reduceAdd, reduceRemove, reduceInit);
let filteredColorAgeGroup = removeMissingEntries(colorAgeGroup);
function removeMissingEntries(sourceGroup) {
return {
all:function () {
return sourceGroup.all().filter(function(d) {
return d.value.sum !== null;
});
}
};
}
let ordinalColors = ['red','green','blue'];
let ordinalAgeColors = ['lightgray','grey','#666666'];
let ordinalTypeColors = ['#ffff0020','#ffff0050','#ffff0090', '#ffff00'];
//color charts
let rgbColorScale = d3.scaleOrdinal().domain(ordinalColors).range(ordinalColors);
let colorChartCount = barChart('#color-chart-count')
.xAxisLabel('Color')
.x(d3.scaleBand().domain(ordinalColors))
.dimension(colorDim)
.yAxisLabel('Count')
.group(colorGroupCount)
.defineColors(rgbColorScale);
colorChartCount.yAxis().ticks(4);
barChart('#color-chart-value-sum')
.xAxisLabel('Color')
.x(d3.scaleBand().domain(ordinalColors))
.dimension(colorDim)
.yAxisLabel('Value sum')
.group(colorGroupValueSum)
.defineColors(rgbColorScale);
//age charts
let ageColorScale = d3.scaleOrdinal().domain([1,2,3]).range(ordinalAgeColors);
let ageChartCount = barChart('#age-chart-count')
.xAxisLabel('Age')
.x(d3.scaleLinear().domain([1,2,3]))
.dimension(ageDim)
.yAxisLabel('Count')
.group(ageGroupCount)
.defineColors(ageColorScale);
ageChartCount.yAxis().ticks(4);
barChart('#age-chart-value-sum')
.xAxisLabel('Age')
.x(d3.scaleLinear().domain([1,2,3]))
.dimension(colorDim)
.yAxisLabel('Value sum')
.group(ageGroupValueSum)
.defineColors(ageColorScale);
//type selection
//dc selection menu
//also see https://dc-js.github.io/dc.js/docs/html/SelectMenu.html#undefined
//and https://stackoverflow.com/questions/51746692/change-text-and-remove-select-all-from-dc-selectmenu
dc.selectMenu('#type')
.dimension(typeDim)
.multiple(false)
.group(typeGroupCount)
.title(d => d.key)
.on('pretransition', event => {
typeSelection.select('option[value=""]')
.remove();
})
.filter('A');
//helper functions
function barChart(elementSelector){
let barChart = dc.barChart(elementSelector)
.width(200)
.height(200)
.xUnits(dc.units.ordinal)
.margins({top:10,left:40,right:5,bottom:35})
.barPadding(0.1)
.outerPadding(0.1)
.transitionDuration(500);
barChart.defineColors = function(colorScale){
this.renderlet(chart=>{
chart.selectAll('rect.bar')
.each(function(d){
let isSelected = this.classList.contains('selected');
if(isSelected){
d3.select(this).attr('style', 'fill: ' + colorScale(d.x) + ';stroke-width:2;stroke:#39ff14');
} else {
d3.select(this).attr('style', 'fill: ' + colorScale(d.x));
}
});
});
return this;
}
return barChart;
}
//value chart
let chart = dc.seriesChart('#value-chart');
chart
.width(500)
.height(500)
.chart( c =>
dc.lineChart(c)
.renderDataPoints(true)
)
.xAxisLabel('Age')
.x(d3.scaleLinear().domain([1,3]))
.dimension(colorAgeDim)
.yAxisLabel('Value')
.elasticY(true)
.group(filteredColorAgeGroup)
.brushOn(false)
.clipPadding(10)
.mouseZoomable(true)
.seriesAccessor(d => d.key[0])
.keyAccessor(d => d.key[1])
.valueAccessor(d => {
return d.value.sum;
})
.ordinalColors(['blue','green','red'])
.legend(dc.legend().x(430).y(350));
dc.renderAll();
//dimensions can also be used for filtering:
//let color_red = colorDim.filter('red');
//let filterResult = JSON.stringify(color_red.top(Infinity)).replace('[','[\n\t').replace(/}\,/g,'},\n\t').replace(']','\n]');
//console.log(filterResult);
//let functionFilter = ageDim.filter(age => age === 2);
//let functionFilterResult = JSON.stringify(functionFilter.top(Infinity)).replace('[','[\n\t').replace(/}\,/g,'},\n\t').replace(']','\n]');
//console.log(functionFilterResult);
</script>
</body>
</html>
这篇关于如何删除其他提示选项“全选"从dc.js selectMenu吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!