我的dc.js dataTable只有两列,其中一列是数字。我需要添加第三列,该列具有相同的数字,但以占总数的百分比表示:
VENDOR SCORE PERCENT
------- ----- -------
Charles 5 50.0 %
Sarah 4 40.0 %
John 1 10.0 %
如果表是静态的,我只需要计算百分比并将它们添加到数据数组中,然后再将其传递给Crossfilter:
let sum = data.reduce((accum, d) => accum + d.score, 0);
data.forEach(d => { d.percent = 100 * d.score / sum; });
但是可以过滤数据(使用dc.js图表和selectMenus),例如,用户可以选择仅显示女性供应商,然后该表将仅显示Sarah ...,但原来的百分比是40%而不是将其重新计算为100%。
有什么办法可以解决这个问题?我想没有办法自动计算百分比。但是也许我可以向某个事件添加一个侦听器,该事件在过滤数据之后但在dc.js重绘表之前触发?
顺便说一句,以防万一,让事情变得更糟...更糟糕的是,我没有直接处理数据维度,而是将一个伪造的组传递给表(code borrowed from here) :
function filteredGroup(originalGroup, filterFunction) {
return {
all: () => originalGroup.all().filter(filterFunction),
top: n => originalGroup.top(Infinity).filter(filterFunction).slice(0, n),
bottom: n => originalGroup.top(Infinity).filter(filterFunction).slice(-n).reverse()
};
}
let ndx = crossfilter(data);
let dim = ndx.dimension(d => d.vendor);
let grp = filteredGroup(dim.group().reduceCount(), d => d.value > 0);
dc.dataTable('#id')
.dimension(grp)
.group(d => d.someOtherField)
.showGroups(true)
.columns([d => d.vendor, d => d.score])
...
(我的实际数据数组将包含Charles的5个条目,Sarah的4个条目和John的1个条目。每个条目包含更多信息,例如日期和时间,这些信息在selectMenus中用于允许过滤。但是我需要表格上的汇总数据。这就是为什么我使用组而不是维度。)
答案 0 :(得分:1)
实际上很容易做到。我已经失去了视野,一个“团体”并不是一个神奇的神奇事物。它只是一个具有3个函数的对象:all
,它返回一个包含所有数据的数组,top
和bottom
,它们执行相同的操作,但仅返回前N个或后N个元素。正如戈登在其评论中指出的那样,每次显示表格时都会调用这些函数。
因此,我只需要计算假组定义中的百分比:
function filteredGroup(originalGroup, filterFunction) {
return {
all: () => calc(originalGroup.all().filter(filterFunction)),
top: n => calc(originalGroup.top(Infinity).filter(filterFunction)).slice(0, n),
bottom: n => calc(originalGroup.top(Infinity).filter(filterFunction)).slice(-n).reverse()
};
}
function calc(data) {
let sum = data.reduce((accum, d) => accum + d.score, 0);
data.forEach(d => { d.percent = 100 * d.score / sum; });
return data;
}