问题
With the following data, how can I bin by the class column (high, middle, low) and total the values
and display each total with its own dc.numberDisplay
in this form?
回答1:
Well, this is pretty close.
Because the number display only displays one number, we need to generate a div
for each value we want to display.
First, the usual crossfilter stuff, creating a group that bins by class:
var data = d3.csv.parse(d3.select('pre#data').text());
data.forEach(function(d) {
d.value = +d.value;
})
var cf = crossfilter(data);
var classDim = cf.dimension(function(d) { return d.class; });
var classGroup = classDim.group().reduceSum(function(d) { return d.value; });
Now we're going to need to pull the individual values out as if they were different groups. We can create a "fake group" that pulls an individual value by index. Note: this won't work if the number of groups changes over time. But that usually doesn't happen.
function subgroup(group, i) {
return {
value: function() {
return group.all()[i];
}
};
}
Now we need to know the index for each bin we're interested in:
var bins = ['high', 'middle', 'low'];
var indices = {};
classGroup.all().forEach(function(kv, i) {
if(bins.indexOf(kv.key) >= 0)
indices[kv.key] = i;
})
We'll build a div for each of those bins, coloring it and adding a heading based on the name of the bin, and using an array of colors for the background color:
var colors = ['rgb(219,41,0)', 'rgb(255,143,31)', 'rgb(255,198,82)'];
var display = d3.select('#numbers').selectAll('div').data(bins);
display.enter().append('div')
.attr('class', 'display')
.style('background-color', function(d, i) {
return colors[i];
})
.append('span')
.attr('class', 'heading')
.text(function(d) { return d.toUpperCase(); });
Here's the CSS to get it to look approximately as you showed above:
.display {
min-width: 100px;
min-height: 100px;
text-align: center;
vertical-align: middle;
font: 36pt sans-serif;
line-height: 100px;
position: relative;
color: white;
}
.display span.heading {
position: absolute;
top: 4px;
left: 0;
right: 0;
margin: auto;
font: 8pt sans-serif;
color: white;
}
Now, finally, we can actually generate the numberDisplay
widgets for each of those divs. This is the easy part!
display.each(function(d) {
var numberDisplay = dc.numberDisplay(this)
.group(subgroup(classGroup, indices[d]))
.formatNumber(d3.format('d'));
});
dc.renderAll();
Screenshot below.
And the fiddle: http://jsfiddle.net/aw9h8d93/9/
来源:https://stackoverflow.com/questions/42998197/multiple-numberdisplays-from-group