如何填补dc.js系列图表中的空白? [英] How can I fill gaps in a dc.js series chart?
问题描述
我有以下dc.js 系列图:
I have the following dc.js series chart:
var data = [
{day: 1, service: 'ABC', count: 100},
{day: 2, service: 'ABC', count: 80},
{day: 4, service: 'ABC', count: 10},
{day: 7, service: 'XYZ', count: 380},
{day: 8, service: 'XYZ', count: 400}
];
var ndx = crossfilter(data);
var dim = ndx.dimension(function (d) { return [d.service, d.day]; });
var grp = dim.group().reduceSum(function(d) { return +d.count; });
var chart = dc.seriesChart('#graph')
.width(620)
.height(175)
.chart(function(c) { return dc.lineChart(c).renderArea(true);})
.dimension(dim)
.group(grp)
.seriesAccessor(function(d) { return d.key[0]; })
.keyAccessor(function(d) { return d.key[1]; })
.x(d3.scaleLinear().domain([1, 8]))
.legend(dc.legend().horizontal(true).x(80))
.render();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dc/3.0.4/dc.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dc/3.0.4/dc.css"/>
<div id="graph"></div>
它可以按预期方式工作...但是由于我的数据中存在空白",因此看起来不太好.有没有办法告诉dc.js,将没有特定系列数据的点默认为0?
It works as expected... but since there are "gaps" in my data, it doesn't look so good. Is there any way to tell dc.js to default to 0 the points where there isn't data for a particular series?
基本上,我想要这个结果,但是不必为每个系列创建一个不同的组并将它们自己堆叠在一起:
Basically, I want this result, but without having to create a different group for each series and stacking them together myself:
var data = [
{day: 1, service: 'ABC', count: 100},
{day: 2, service: 'ABC', count: 80},
{day: 4, service: 'ABC', count: 10},
{day: 7, service: 'XYZ', count: 380},
{day: 8, service: 'XYZ', count: 400}
];
var ndx = crossfilter(data);
var dim = ndx.dimension(function (d) { return d.day; });
var grpABC = dim.group().reduceSum(function(d) { return d.service === 'ABC' ? +d.count : 0; });
var grpXYZ = dim.group().reduceSum(function(d) { return d.service === 'XYZ' ? +d.count : 0; });
var chart = dc.lineChart('#graph')
.width(620)
.height(175)
.dimension(dim)
.group(grpABC)
.stack(grpXYZ)
.renderArea(true)
.x(d3.scaleLinear().domain([1, 8]))
.legend(dc.legend().horizontal(true).x(80))
.render();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dc/3.0.4/dc.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dc/3.0.4/dc.css"/>
<div id="graph"></div>
第一个示例的seriesChart有什么方法可以实现相同目的吗?
Is there any way to achieve the same with the seriesChart of the first example?
我已经看到了这个问题,它可能很相似,但是他们正在使用NVD3.js和Underscore.我们有jQuery,d3.js和dc.js.
I have seen this question which might be similar, but they're using NVD3.js and Underscore. We have jQuery, d3.js and dc.js instead.
推荐答案
dc.js常见问题解答包含有关预处理数据的部分.在这种情况下,您要确保所有空值都填充为零,并且 ensure_group_bins
与您想要的东西非常接近.
The dc.js FAQ contains a section on preprocessing data. In this case, you want to ensure that any empty values are filled with zero, and ensure_group_bins
is pretty close to what you want.
在这里,我已经对其进行了调整,以将所需的垃圾箱作为数组而不是参数,因为我们需要大量垃圾箱- d3.cross 目的.
Here I've adapted it to take the required bins as an array instead of as arguments, because we need to require a lot of bins - the Cartesian product of all the services and all the days. Handily, D3v4 contains d3.cross for exactly this purpose.
然后我们只用ensure_group_bins
产生的假组包裹我们的组,我们就离开了!
Then we just wrap our group with the fake group produced by ensure_group_bins
and we are off!
有趣的是,这暴露了您之前被遮盖的数据的详细信息-由于折线图仅在其具有数据的位置绘制点,因此以前尚不清楚服务ABC/第3天为零.
Interestingly, this exposes a detail about your data which was obscured before - since the line chart only draws points where it has data, it was previously not clear that service ABC / day 3 is zero.
function ensure_group_bins(source_group, bins) {
return {
all:function () {
var result = source_group.all().slice(0), // copy original results (we mustn't modify them)
found = {};
result.forEach(function(d) {
found[d.key] = true;
});
bins.forEach(function(d) {
if(!found[d])
result.push({key: d, value: 0});
});
return result;
}
};
};
var needed = d3.cross(['ABC', 'XYZ'], d3.range(1,8));
var data = [
{day: 1, service: 'ABC', count: 100},
{day: 2, service: 'ABC', count: 80},
{day: 4, service: 'ABC', count: 10},
{day: 7, service: 'XYZ', count: 380},
{day: 8, service: 'XYZ', count: 400}
];
var ndx = crossfilter(data);
var dim = ndx.dimension(function (d) { return [d.service, d.day]; });
var grp = dim.group().reduceSum(function(d) { return +d.count; });
grp = ensure_group_bins(grp, needed);
var chart = dc.seriesChart('#graph')
.width(620)
.height(175)
.chart(function(c) { return dc.lineChart(c).renderArea(true);})
.dimension(dim)
.group(grp)
.seriesAccessor(function(d) { return d.key[0]; })
.keyAccessor(function(d) { return d.key[1]; })
.x(d3.scaleLinear().domain([1, 8]))
.legend(dc.legend().horizontal(true).x(80))
.render();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dc/3.0.4/dc.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dc/3.0.4/dc.css"/>
<div id="graph"></div>
这篇关于如何填补dc.js系列图表中的空白?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!