Crossfilter 堆叠条形图取负值
Crossfilter stacked bar charts negate values
我正在使用带 dcv3 的 crossfilter2
我的数据在我加载到内存中的 csv 文件中
原始数据
Day, ID
1, 2
1, 2
1, 2
2, 5
3, 6
4, 6
已处理数据
Day, ID, target
1, 2, True
1, 2, True
1, 2, True
2, 5, False
3, 6, False
4, 6, False
目前我想做的是创建一个带有 2 个条形的交叉过滤器堆叠条形图。如果ID == 2
,我认为是一组,ID !=2
是另一组。但是,我无法在 DC/crossfilter 中动态执行它,这导致我必须预处理数据以添加新列并处理该列,如下面的解决方案所示。
有没有更好的方法?
var dimID = ndx.dimension(function(d) { return d.day; });
var id_stacked = dimID.group().reduce(
function reduceAdd(p, v) {
p[v.target] = (p[v.target] || 0) + 1;
return p;
},
function reduceRemove(p, v) {
p[v.target] = (p[v.target] || 0) - 1;
return p;
},
function reduceInitial() {
return {};
});
//Doing the stacked bar chart here
stackedBarChart.width(1500)
.height(150)
.margins({top: 10, right: 10, bottom: 50, left: 40})
.dimension(dimID)
.group(id_stacked, 'Others', sel_stack("True"))
.stack(id_stacked, 'Eeid of interest', sel_stack("False"))
这是我的sel_stack函数
function sel_stack(i) {
return function(d) {
return d.value[i] ? d.value[i] : 0;
};
}
我正在绘制一个条形图,其中 x 轴是日期,Y 轴是堆叠条形图中 ID == 2
或 ID!=2
的频率
所以你想按天分组,然后按是否 ID===2
堆叠。虽然 dc.js 会接受许多不同的格式,但诀窍通常是将数据设置为正确的形状。
您走在正确的轨道上,但您不需要额外的列来为 "is 2" 和 "not 2" 创建堆栈。可以直接计算:
var dayDimension = ndx.dimension(function(d) { return d.Day; }),
idStackGroup = dayDimension.group().reduce(
function add(p, v) {
++p[v.ID===2 ? 'is2' : 'not2'];
return p;
},
function remove(p, v) {
--p[v.ID===2 ? 'is2' : 'not2'];
return p;
},
function init() {
return {is2: 0, not2: 0};
});
这些是标准的 add/remove 函数,用于减少每个 bin 的多个值。你会发现 other variations where the name of the field is driven by the data。但是这里我们知道会存在哪些字段,所以我们可以在init
中将它们初始化为零,而不用担心遇到新的字段。
当一行被添加到交叉过滤器或过滤器发生变化以包含一行时,将调用add
函数;每当从 crossfilter 中过滤掉或删除行时,都会调用 remove
函数。由于我们不担心 undefined
(1) 我们可以简单地增加 (++
) 和减少 (--
) 值。
最后我们需要访问器将这些值从对象中提取出来。我认为将堆栈访问器置于内联更简单 - sel_stack
是为添加动态数量的堆栈而编写的。 (YMMV)
.group(idStackGroup, 'Others', d => d.value.not2)
.stack(idStackGroup, 'Eeid of interest', d => d.value.is2);
https://jsfiddle.net/gordonwoodhull/fu4w96Lh/23/
(1) 如果你对 undefined
进行任何算术运算,它会转换为 NaN
并且 NaN
会破坏所有进一步的计算。
我正在使用带 dcv3 的 crossfilter2
我的数据在我加载到内存中的 csv 文件中
原始数据
Day, ID
1, 2
1, 2
1, 2
2, 5
3, 6
4, 6
已处理数据
Day, ID, target
1, 2, True
1, 2, True
1, 2, True
2, 5, False
3, 6, False
4, 6, False
目前我想做的是创建一个带有 2 个条形的交叉过滤器堆叠条形图。如果ID == 2
,我认为是一组,ID !=2
是另一组。但是,我无法在 DC/crossfilter 中动态执行它,这导致我必须预处理数据以添加新列并处理该列,如下面的解决方案所示。
有没有更好的方法?
var dimID = ndx.dimension(function(d) { return d.day; });
var id_stacked = dimID.group().reduce(
function reduceAdd(p, v) {
p[v.target] = (p[v.target] || 0) + 1;
return p;
},
function reduceRemove(p, v) {
p[v.target] = (p[v.target] || 0) - 1;
return p;
},
function reduceInitial() {
return {};
});
//Doing the stacked bar chart here
stackedBarChart.width(1500)
.height(150)
.margins({top: 10, right: 10, bottom: 50, left: 40})
.dimension(dimID)
.group(id_stacked, 'Others', sel_stack("True"))
.stack(id_stacked, 'Eeid of interest', sel_stack("False"))
这是我的sel_stack函数
function sel_stack(i) {
return function(d) {
return d.value[i] ? d.value[i] : 0;
};
}
我正在绘制一个条形图,其中 x 轴是日期,Y 轴是堆叠条形图中 ID == 2
或 ID!=2
的频率
所以你想按天分组,然后按是否 ID===2
堆叠。虽然 dc.js 会接受许多不同的格式,但诀窍通常是将数据设置为正确的形状。
您走在正确的轨道上,但您不需要额外的列来为 "is 2" 和 "not 2" 创建堆栈。可以直接计算:
var dayDimension = ndx.dimension(function(d) { return d.Day; }),
idStackGroup = dayDimension.group().reduce(
function add(p, v) {
++p[v.ID===2 ? 'is2' : 'not2'];
return p;
},
function remove(p, v) {
--p[v.ID===2 ? 'is2' : 'not2'];
return p;
},
function init() {
return {is2: 0, not2: 0};
});
这些是标准的 add/remove 函数,用于减少每个 bin 的多个值。你会发现 other variations where the name of the field is driven by the data。但是这里我们知道会存在哪些字段,所以我们可以在init
中将它们初始化为零,而不用担心遇到新的字段。
当一行被添加到交叉过滤器或过滤器发生变化以包含一行时,将调用add
函数;每当从 crossfilter 中过滤掉或删除行时,都会调用 remove
函数。由于我们不担心 undefined
(1) 我们可以简单地增加 (++
) 和减少 (--
) 值。
最后我们需要访问器将这些值从对象中提取出来。我认为将堆栈访问器置于内联更简单 - sel_stack
是为添加动态数量的堆栈而编写的。 (YMMV)
.group(idStackGroup, 'Others', d => d.value.not2)
.stack(idStackGroup, 'Eeid of interest', d => d.value.is2);
https://jsfiddle.net/gordonwoodhull/fu4w96Lh/23/
(1) 如果你对 undefined
进行任何算术运算,它会转换为 NaN
并且 NaN
会破坏所有进一步的计算。