DC.js barchart bars disappear on brush and total amount for date range problems
I am working on a couple simple DC, D3, and Crossfilter data visualization charts. After much tinkering and looking at different examples I still can't figure out why the bars on the barchart disappear when I move the brush over them.
One other thing I am struggling with is trying to create a second chart and tie it to the date ranges selected in the first. The first problem obviously needs to be fixed for that to work but I know there are other problems with my code as well. I want this second chart to be a bar chart with a single bar that displays the total of the "h" field for the selected dates in the first graph. Even before the brush is moved it is only showing three for the total now so just feeding it the h dimension and a group I created off the date dimension is not sufficient.
JSFiddle: https://jsfiddle.net/schins02/bLkgLuhg/
rData.forEach(function(d, i) {
d.date = d3.time.format("%Y-%m-%d").parse(d.date);
});
var playerData = crossfilter(rData);
//dimensions and groups
var dateDim = playerData.dimension(function(d) {
return d.date;
});
var abDim = playerData.dimension(function(d) {
return d.ab
});
var hitDim = playerData.dimension(function(d) {
return d.h
});
var absGroupByDate = dateDim.group().reduceSum(function(d) {
return d.ab
});
var hitsGroupByDate = dateDim.group().reduceSum(function(d) {
return d.h
});
var x_domain = d3.extent(rData, function(d) {
return d.date;
});
var x_scale = d3.time.scale();
x_scale.domain(x_domain);
var abChart = dc.barChart("#ab-bar-chart");
abChart
.width(WIDTH)
.height(HEIGHT + 30)
.x(x_scale)
.y(d3.scale.linear().domain([0, d3.max(rData, function(d) {
return d.ab
})]))
.yAxisLabel("")
.centerBar(true)
.dimension(abDim)
.alwaysUseRounding(true)
.xUnits(function() {
return 15;
})
.group(absGroupByDate);
abChart.elasticX(true);
abChart.xAxisPadding(1);
abChart.xAxis().tickFormat(d3.time.format("%b %d")).ticks(d3.time.days, 3);
abChart.yAxis().tickFormat(d3.format("d"));
abChart.render();
abChart.on("filtered", function(chart) {
//???
//console.log(chart);
//console.log(dateDim);
//dc.redrawAll(chart.chartGroup());
//hitDim.filterRange(newDate(?) , new Date(?));
});
var hitChart = dc.barChart("#hit-bar-chart");
var totalHits = playerData.groupAll().reduceSum(function(d) {
return d.h;
}).value();
hitChart
.width(200)
.height(HEIGHT + 30)
.x(d3.scale.ordinal().domain(["Hits"]))
.xUnits(dc.units.ordinal)
.y(d3.scale.linear().domain([0, totalHits]))
.yAxisLabel("")
.centerBar(true)
.dimension(hitDim)
.brushOn(false)
.alwaysUseRounding(true)
.group(hitsGroupByDate)
hitChart.render();
Any help would be greatly appreciated.
Indeed, crossfilter's model of the world takes some getting used to. The name "dimension" can be somewhat misleading - it's really "a thing you want to filter on", and any groups which are built off that dimension will not observe its filters, just other dimensions.
So that means
You normally want the group and dimension for a single chart to match, so that its own data doesn't get removed when you filter it. Since the first chart displays dates, go ahead and use the dateDim
for that. That way, when a date range is applied by the filter (based on the keys in the group), the types will match. And it won't filter itself either.
For getting a single bar that rolls up the sum of all data, you can use the trick in this recent answer to make a crossfilter groupAll behave like an ordinary group. Here it doesn't matter what the dimension is because there is nothing to filter.
The second part will look like this:
function regularize_groupAll(groupAll) {
return {
all: function() {
return [{key: 'all', value: groupAll.value()}];
}
};
}
var allHits = playerData.groupAll().reduceSum(function(d) {
return d.h;
});
var totalHits = allHits.value();
var regAllHits = regularize_groupAll(allHits);
Fork of your fiddle: https://jsfiddle.net/gordonwoodhull/sfLnoxdr/7/
链接地址: http://www.djcxy.com/p/32690.html