dc.js - 交叉过滤器减少正在崩溃
问题描述
我无法成功呈现 dc.js 堆叠条形图,并且收到控制台错误
无法读取未定义的属性“总计”
我是图书馆的新手,怀疑我的组或减少没有成功指定。
我该如何解决这个问题?
$scope.riskStatusByMonth = function(){
var data = [
{"Month":"Jan","High":12},{"Month":"Jan","Med":14},{"Month":"Jan","Low":2},{"Month":"Jan","Closed":8},
{"Month":"Feb","High":12},{"Month":"Feb","Med":14},{"Month":"Feb","Low":2},{"Month":"Feb","Closed":8},
{"Month":"Mar","High":12},{"Month":"Mar","Med":14},{"Month":"Mar","Low":2},{"Month":"Mar","Closed":8},
{"Month":"Apr","High":12},{"Month":"Apr","Med":14},{"Month":"Apr","Low":2},{"Month":"Apr","Closed":8},
{"Month":"May","High":12},{"Month":"May","Med":14},{"Month":"May","Low":2},{"Month":"May","Closed":8},
{"Month":"Jun","High":12},{"Month":"Jun","Med":14},{"Month":"Jun","Low":2},{"Month":"Jun","Closed":8},
{"Month":"Jul","High":12},{"Month":"Jul","Med":14},{"Month":"Jul","Low":2},{"Month":"Jul","Closed":8},
{"Month":"Aug","High":12},{"Month":"Aug","Med":14},{"Month":"Aug","Low":2},{"Month":"Aug","Closed":8},
{"Month":"Sep","High":12},{"Month":"Sep","Med":14},{"Month":"Sep","Low":2},{"Month":"Sep","Closed":8},
{"Month":"Oct","High":12},{"Month":"Oct","Med":14},{"Month":"Oct","Low":2},{"Month":"Oct","Closed":8},
{"Month":"Nov","High":12},{"Month":"Nov","Med":14},{"Month":"Nov","Low":2},{"Month":"Nov","Closed":8},
{"Month":"Dec","High":8},{"Month":"Dec","Med":6},{"Month":"Dec","Low":13},{"Month":"Dec","Closed":8},
]
data.forEach(function(x) {
x.Total = 0;
});
var ndx = crossfilter(data)
var xdim = ndx.dimension(function (d) {return d.Month;});
function root_function(dim,stack_name) {
return dim.group().reduce(
function(p, v) {
p[v[stack_name]] = (p[v[stack_name]] || 0) + v.High;
return p;},
function(p, v) {
p[v[stack_name]] = (p[v[stack_name]] || 0) + v.Med;
return p;},
function(p, v) {
p[v[stack_name]] = (p[v[stack_name]] || 0) + v.Low; <-------------------here is where error occurs
return p;},
function(p, v) {
p[v[stack_name]] = (p[v[stack_name]] || 0) + v.Closed;
return p;},
function() {
return {};
});}
var ydim = root_function(xdim,'Total')
function sel_stack(i) {
return function(d) {
return d.value[i];
};}
$scope.monthlyRiskStatus = dc.barChart("#risk-status-by-month");
$scope.monthlyRiskStatus
.x(d3.scaleLinear().domain(xdim))
.dimension(xdim)
.group(ydim, '1', sel_stack("Jan"))
.xUnits(dc.units.ordinal);
month = [null,'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
for(var i = 2; i<=12; ++i)
$scope.monthlyRiskStatus.stack(ydim, ''+i, sel_stack(month[i]));
$scope.monthlyRiskStatus.render();
}
解决方案
group.reduce()接受三个参数:add、remove、init。
你通过了5。
看起来它试图将第三个调用为初始化程序,没有参数,因此v
未定义。
如何按层堆叠
看起来您真正想做的是按月(X 轴)分组,然后按状态或级别堆叠。这是一种方法。
首先,你在正确的轨道上使用一个带有堆栈名称的函数,但我们希望它采用所有堆栈名称:
function root_function(dim,stack_names) {
return dim.group().reduce(
function(p, v) {
stack_names.forEach(stack_name => { // 1
if(v[stack_name] !== undefined) // 2
p[stack_name] = (p[v[stack_name]] || 0) + v[stack_name] // 3
});
return p;},
function(p, v) {
stack_names.forEach(stack_name => { // 1
if(v[stack_name] !== undefined) // 2
p[stack_name] = (p[v[stack_name]] || 0) + v[stack_name] // 3
});
return p;},
function() {
return {};
});}
- 在 add 和 reduce 函数中,我们将遍历所有堆栈名称
- 堆栈名称是每行中可能存在或不存在的字段。如果堆栈名称存在于当前行中...
- 我们将从
stack_name
当前 bin 中具有相同名称的字段中添加或减去行字段。
我们将同时定义levels
和months
数组。levels
将用于堆叠并将months
用于序数 X 域:
var levels = ['High', 'Med', 'Low', 'Closed']
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
当我们定义组时,我们将传递levels
给root_function()
:
var ygroup = root_function(xdim,levels)
我看到您在“维度”的英语/数学定义和交叉过滤维度之间有些混淆。是的,在英语中“Y”是一个维度,但在 crossfilter 和 dc.js 中,“维度”是您聚合的内容,而组是通常进入 Y 的聚合。(命名很困难。)
我们将使用序数比例(你有一半序数一半线性,这是行不通的):
$scope.monthlyRiskStatus
.x(d3.scaleOrdinal().domain(months))
.dimension(xdim)
.group(ygroup, levels[0], sel_stack(levels[0]))
.xUnits(dc.units.ordinal);
将月份传递到序数比例域告诉 dc.js 以该顺序绘制条形图。(警告:折线图有点复杂,因为您还必须对输入数据进行排序。)
请注意,我们是按级别堆叠的,而不是按月份堆叠的。也在这里:
for(var i = 1; i<levels.length; ++i)
$scope.monthlyRiskStatus.stack(ygroup, levels[i], sel_stack(levels[i]));
让我们也添加一个图例,这样我们就知道我们在看什么:
.margins({left:75, top: 0, right: 0, bottom: 20})
.legend(dc.legend())
推荐阅读
- c++ - 在多线程代码中实现安全恢复的断点
- c# - 将 IdentityUser 关联到 EF Core 中的实体
- html - 为什么 nth-child 选择器在 css 中不起作用?
- linux - 为什么 React Native 会挂在 59% 上?
- c# - 等效于 C# 中的 C++“this”指针
- java - java合并两个List
- android - Android - 仅启用 URL 链接,但在触及 TextView 中的非 URL 链接时禁用其他链接
- bash - How to write String to a text File
- python - 使用索引列表对numpy数组的元素执行操作
- java - 读取对象类java实例的属性