D3.js 如何在dc.js中按堆栈过滤堆叠折线图?
我正在为仪表板制作堆叠折线图:D3.js 如何在dc.js中按堆栈过滤堆叠折线图?,d3.js,dc.js,crossfilter,D3.js,Dc.js,Crossfilter,我正在为仪表板制作堆叠折线图: var json = [...] var timeFormat = d3.time.format.iso; json = json.map(function(c){ c.date = timeFormat.parse(c.date); return c; }); var data = crossfilter(json); var days = data.dimension(function (d) { return d.date; }); var
var json = [...]
var timeFormat = d3.time.format.iso;
json = json.map(function(c){
c.date = timeFormat.parse(c.date);
return c;
});
var data = crossfilter(json);
var days = data.dimension(function (d) {
return d.date;
});
var minDate = days.bottom(1)[0].date;
var maxDate = days.top(1)[0].date;
var lineValues = days.group().reduce(function (acc, cur) {
acc[cur.line] = (acc[cur.line] || 0) + 1
return acc;
}, function (acc, cur) {
acc[cur.line] = (acc[cur.line] || 0) - 1
return acc;
}, function () {
return {};
});
var personChart = dc.lineChart("#graph");
personChart
.turnOnControls(true)
.width(600).height(350)
.dimension(days)
.group(lineValues, "completed")
.valueAccessor(function (d) {
return d.value.completed || 0;
})
.stack(lineValues, "assigned", function (d) {
return d.value.assigned || 0;
})
.stack(lineValues, "inactive", function (d) {
return d.value.inactive || 0;
})
.stack(lineValues, "active", function (d) {
return d.value.active || 0;
})
.stack(lineValues, "new", function (d) {
return d.value.new || 0;
})
.stack(lineValues, "temp", function (d) {
return d.value.temp || 0;
})
.elasticY(true)
.renderArea(true)
.x(d3.time.scale().domain([minDate, maxDate]))
.ordinalColors(colorScale)
.legend(dc.legend().x(50).y(10).itemHeight(13).gap(5).horizontal(true));
dc.renderAll();
到目前为止,它运行良好,但我遇到了一个障碍。我需要实现一个选项来按单个堆栈过滤图表。这在dc.js中可能吗?如果有必要,我可以修改和重写整个代码,如果需要,还可以要求我的客户以不同的方式重新构建数据。数据中还有其他字段,我可以过滤其他图表,因此保留这些功能非常重要。根据设计,dc.js有很多“泄漏的抽象”,因此通常有一种方法可以获取所需的数据,并通过下拉到d3自定义行为,即使是库没有预料到的功能 您使用饼图的解决方法非常合理,但我同意单击图例会更好 有一种方法可以做到这一点:
var categories = data.dimension(function (d) {
return d.line;
});
personChart
.on('renderlet', function(chart) {
chart.selectAll('.dc-legend-item')
.on('click', function(d) {
categories.filter(d.name);
dc.redrawAll();
})
});
基本上,绘制完图表后,我们选择图例项并替换我们自己的单击行为,它会过滤我们为此创建的另一个维度
这取决于与要筛选的值匹配的图例文本。如果图例与其图表之间的未记录接口.legendables()
,与您的实际用例不匹配,您可能需要自定义该接口,但它在此处有效
这把小提琴的叉子演示了以下功能:
我还添加了一个饼图来说明正在发生的事情。通过执行以下操作,可以通过饼图对图例进行筛选
catPie.filter(d.name);
而不是
categories.filter(d.name);
这样,您可以在饼图的切片中看到结果过滤器。您还可以获得切换行为,即可以再次单击返回空选择,然后单击多个类别。如果需要切换行为,请留下注释,我尝试想出一种不使用饼图的方法来添加它
有时,图例似乎应该是自己的独立图表类型…您的意思是,隐藏和显示堆栈,还是选择一个堆栈,并按堆栈表示的值过滤所有其他图表?理想情况下,客户会同时选择这两种类型。通过实现具有相同维度和值的二级饼图,我成功地创建了一个临时解决方案,该饼图为我提供了必要的功能。我仍然认为如果我能用一张图表来管理它会更好。是否可以添加用于单击图例的筛选器处理程序?