dc.js and crossfilter stack bar chart with filtered versus unfiltered
I'm using the great dc.js/d3.js/crossfilter combination - mostly to great success. However, I have the need to keep the unfiltered dimension data at the same time of the filtered data. I could possibly set up the means to hold the unfiltered dimension data in an object, then access it, but that seems weak when using such a powerful combo.
Specifically, I'm trying to have a stacked bar chart with the bottom of the bar = the unfiltered number, the top of the bar = to the results of the filter. I'm not finding a way to retrieve the starting group count if I filter.
<input type="text" id = "keywordTxt"></input><button id = "filterButton">Filter</button>
<div id="i9chart"></div>
var I9Chart = dc.barChart("#i9chart");
d3.csv("I9.csv",function(csv) {
csv.forEach(function(d) {
d.I9_Formatted = numberFormat(d.I9_Code);
d.I9_Whole = Math.floor(d.I9_Code)
})
//set up dimensions
var ndx = crossfilter(csv);
var I9_DescripDim = ndx.dimension(function(d) { return d.I9_Description; });
var I9_WholeDim = ndx.dimension(function(d) { return d.I9_Whole; });
var I9_WholeGroup = I9_WholeDim.group();
var maxI9 = I9_WholeDim.top(1)[0].I9_Whole;
var I10_DescripDim = ndx.dimension(function(d) { return d.I10_Description; });
I9Chart.width(750)
.height(300)
.margins({top: 10, right: 20, bottom: 30, left: 40})
.dimension(I9_WholeDim)
.group(I9_WholeGroup)
// pretty much every approach I've tried results in the stack having the same y value as the filtered.
.valueAccessor(function (d) {return d.value; })
.stack(I9_WholeDim.group(),function(d,i) { return d.???; })
.x(d3.scale.linear().domain([0,maxI9]))
.rangeChart(ICD9ChartBrush)
.brushOn(false)
.title(function (d) { return d.key + ": " + d.value; })
.elasticY(true)
.centerBar(true);
//filter by the I10 description dimension
document.getElementById("filterButton").onclick = function() {
var keyword = document.getElementById("keywordTxt").value;
var matcher = new RegExp(keyword,'i');
var filteredDim = I10_DescripDim.filter(function(val, i){ return matcher.test(val)});
With stimulation from Ethan Jewett - solving my own question:
Store the full, unfiltered grouped dimension as a static object (found that a hash works best)
First - grab the static group prior to filtering
I9_WholeObjGroup = I9_WholeGroup.top(Infinity);
Then - to make accessing the keys and values easier:
var I9_hash = {};
I9_WholeObjGroup.forEach( function(p,i) {
I9_hash[p.key] = p.value
})
Finally, the I9_hash is used in the stack function (or any other place its needed)
.stack(I9_WholeGroup, "Total Items",function(d) {
if(d.value > 0 ){ //only add the stacked data to filtered bars that have data.
var id = d.key
return I9_hash[id] - d.value; //only add the difference between the filter and totals
}
})
The beauty of stack is that one can add any numeric data - constants, variables based on existing unfiltered data, or even a constant - filtered data (for stacked percentage plots for example)
链接地址: http://www.djcxy.com/p/32732.html上一篇: 减少dc.js中的函数