问题
I have a table with aggregated data that groups on two columns and gets its data from a fake crossfilter dimension:
var groupedDimension = ndx.dimension(function(d) {return d.date + "/./" +d.Supplier})
.group().reduceSum(function (d) {return +d.total;});
I cannot get the table to hide rows with 0-values when it is crossfiltered, though. For example, I have tried to tack another fake group onto the fake dimension to get rid of the 0's but that threw an error.
Here is the jsfiddle: https://jsfiddle.net/zks59ndm/2/ Any help is greatly appreciated.
Also, does anybody know why sorting the table in ascending order throws an error?
回答1:
These are actually related problems: the data table is expecting a crossfilter dimension for its dimension()
parameter, and groups and fake groups don't supply all the methods that the data table expects.
Looking at the browser debug console is a great way to diagnose these problems. For example, adding:
.dimension(remove_empty_bins(groupedDimension))
results in the error
Uncaught TypeError: _chart.dimension(...).top is not a function
So it wants .top()
as well as .all()
, glad to oblige:
function remove_empty_bins(source_group) {
function non_zero_pred(d) {
return d.value != 0;
}
return {
all: function () {
return source_group.all().filter(non_zero_pred);
},
top: function(n) {
return source_group.top(Infinity)
.filter(non_zero_pred)
.slice(0, n);
}
};
}
This is from the FAQ... I know, it's become a hefty tome by now.
You almost never have to supply .top()
- up through 2.0.* it's needed for capped charts and data tables only. As of 2.1.* it's only needed for data tables.
That brings us to the other question: why does d3.ascending
not work?
Again, the debug console will show the way:
Uncaught TypeError: _chart.dimension(...).bottom is not a function
Ah right, in order to show them in ascending order, it wants to take the lowest N items, so now it expects the dimension to support .bottom()
. Here is the issue describing this problem, which concludes that we'd better document this somewhere or add it to the voluminous FAQ.
It also provides another workaround, the heart of which is:
bottom: function(N) {
return group.top(Infinity).slice(-N).reverse();
}
That is, pull all the data in descending order, take the last N from the array, and reverse the resulting array. If we stick our nonzero-filter after .top(Infinity)
but before .slice(-n)
, we'll get the most stupendously over-capable remove_empty_bins
ever!
function remove_empty_bins(source_group) {
function non_zero_pred(d) {
return d.value != 0;
}
return {
all: function () {
return source_group.all().filter(non_zero_pred);
},
top: function(n) {
return source_group.top(Infinity)
.filter(non_zero_pred)
.slice(0, n);
},
bottom: function(n) {
return source_group.top(Infinity)
.filter(non_zero_pred)
.slice(-n).reverse();
}
};
}
Working fork of your fiddle: https://jsfiddle.net/gordonwoodhull/5ntxvsfb/5/
来源:https://stackoverflow.com/questions/43325695/removing-0-values-from-dc-js-aggregated-data-table