我有一个动态增长的时间序列,需要显示在可缩放/可缩放的图表中。
在这里尝试一下(实际上:我的第一个jsFiddle :)):
https://jsfiddle.net/Herkules001/L12k5zwx/29/
我尝试按照此处所述的相同方式进行操作:https://dc-js.github.io/dc.js/examples/replacing-data.html
但是,每次图表更新时,焦点图表上的缩放和滤镜都会丢失。 (但是画笔保留在范围图上。)
如何在不重置视图和不丢失缩放的情况下添加数据?
var chart = dc.lineChart("#test");
var zoom = dc.lineChart("#zoom");
//d3.csv("morley.csv", function(error, experiments) {
var experiments = d3.csvParse(d3.select('pre#data').text());
experiments.forEach(function(x) {
x.Speed = +x.Speed;
});
var ndx = crossfilter(experiments),
runDimension = ndx.dimension(function(d) {return +d.Run;}),
speedSumGroup = runDimension.group().reduceSum(function(d) {return d.Speed * d.Run / 1000;});
chart
.width(768)
.height(400)
.x(d3.scaleLinear().domain([6,20]))
.brushOn(false)
.yAxisLabel("This is the Y Axis!")
.dimension(runDimension)
.group(speedSumGroup)
.rangeChart(zoom);
zoom
.width(768)
.height(80)
.x(d3.scaleLinear().domain([6,20]))
.brushOn(true)
.yAxisLabel("")
.dimension(runDimension)
.group(speedSumGroup);
zoom.render();
chart.render();
var run = 21;
setInterval(
() => {
var chartfilter = chart.filters();
var zoomfilter = zoom.filters();
chart.filter(null);
zoom.filter(null);
ndx.add([{Expt: 6, Run: run++, Speed: 100 + 5 * run}]);
chart.x(d3.scaleLinear().domain([6,run]));
zoom.x(d3.scaleLinear().domain([6,run]));
chart.filter([chartfilter]);
zoom.filter([zoomfilter]);
chart.render();
zoom.render();
},
1000);
//});
答案 0 :(得分:0)
在这种情况下,如果您只是添加数据,则无需执行引用的示例中演示的过滤器的复杂清除和还原操作。
该部分仅是必需的,因为crossfilter.remove()
最初将删除与当前过滤器匹配的数据。尴尬的界面,几乎从来没有想要的。
如果仅添加数据,则不必担心其中的任何一个:
setInterval(
() => {
ndx.add([{Expt: 6, Run: run++, Speed: 5000 + 5 * run}]);
chart.redraw();
zoom.redraw();
},
5000);
请注意,使用redraw
而非render
可以减少闪烁,并获得不错的动画过渡。我还添加了evadeDomainFilter以避免线在图表边缘之前被剪掉。
如果使用谓词形式crossfilter.remove()
,则不必担心保存和还原过滤器:
ndx.remove(d => d.Run < run-20);
但是,这确实暴露了dc.js中的其他错误。似乎elasticY
无效,类似于所描述的in this issue。还有you get some weird animations。
Here's a demo with remove enabled.
最后,dc.js具有一些非常简洁的功能,通常可以通过一种方法使它执行您想要的操作,但是它确实很古怪。这是一个非常复杂的领域,以我的经验,您将在所有功能齐全的图表库中找到其中一些怪癖。
更新:我修复了replacing data example,现在只是ndx.remove(() => true)
。
如Joerg在评论中指出的
我们可以通过添加preRedraw event handler来解决这些问题。那是调整域的理想场所。例如,您可以根据需要手动实施elasticX
。 (正如您稍后看到的,我们做到了!)
首先,一个很容易理解的天真尝试:
chart.on('preRedraw', () => {
chart.elasticX(!zoom.filters().length);
});
我们可以根据范围图表是否具有活动过滤器来打开和关闭elasticX
。
这行得通,而且很好,也很简单,但是当您尝试关注原始图表中未包含的域时,为什么图表会如此混乱?
欢迎,它将记录原始域(source)。这样,如果清除焦点,它就可以还原到该域,并且还可以阻止您缩放或平移超过图形的边缘。
但是从上面的源链接中注意到,我们有一个逃生舱口。设置X标度后,它会记录原始域 。因此,除了设置elasticX
之外,我们还可以计算数据的范围,设置刻度的域,并告诉图表刻度是新的:
chart.on('preRedraw', () => {
if(!zoom.filters().length) {
var xExtent = d3.extent(speedSumGroup.all(), kv => kv.key);
chart.x(chart.x().domain(xExtent));
}
});
New fiddle with zooming issues fixed.
Joerg仍然指出一个小故障:如果在数据输入时移动画笔,则画笔柄有时会偶尔从画笔的末端偏离。以我的经验,这类故障在D3(通常是动态图表)中很常见,因为很难考虑用户交互过程中的数据更改。它可能可以在库中修复(也许是过渡中断吗?),但我在这里不打算讨论。