d3.js - D3.js 实时图更新不顺畅
问题描述
我正在获取 JSON 数据做 D3 线图。接下来在最后一个点和 concat() 新数据之后请求新数据,更新行并在每个 transition() 上向左移动
我每次都需要重新计算 xScale 以放置新的时间值并在 x 轴上删除旧的时间值。并且 x 轴平滑且正确地向左滚动。但是当我开始重新计算 xScale 时,我的线路路径会停止向左平滑平移,而只会在每个 update_path() 上立即跳转。如果我删除 xScale.domain(d3.extent(... 路径平滑地向左过渡,但 x 轴上没有新时间。
function update_path(svg,path,dataset,xScale) {
var last=dataset[dataset.length-1];
var last_point=last[Object.keys(last)[0]];
// check new data and put it
d3.json("data.php?chartID=1&last_point="+last_point).then(function(data) {
dataset=dataset.concat(data);
var yScale=d3.scaleLinear()
.domain([d3.max(dataset, function(d) { return d[Object.keys(d)[1]]; }), 0])
.range([0, range]);
xScale.domain(d3.extent(dataset, function(d) { return new Date(d[Object.keys(d)[0]]); }))
var translate=dataset[0];
var translate_point=translate[Object.keys(translate)[0]];
var prelast=dataset[dataset.length-2];
var prelast_point=prelast[Object.keys(prelast)[0]];
var last=dataset[dataset.length-1];
var last_point=last[Object.keys(last)[0]];
var prelast_date=new Date(prelast_point);
var last_date=new Date(last_point);
var seconds = (last_date.getTime() - prelast_date.getTime());
var line=prepare_line(xScale,yScale);
// update x-axis
var xaxis_call=d3.axisBottom(xScale).ticks().tickSize(-height);
svg.selectAll("g.main_g").selectAll("g.x-axis")
.transition()
.duration(seconds)
.ease(d3.easeLinear)
.attr("transform", "translate(-"+ xScale(new Date(translate_point))+",100)")
.call(xaxis_call)
// update line
path
.attr("d", line(dataset))
.transition()
.duration(seconds)
.ease(d3.easeLinear)
.attr("transform", "translate(-"+ xScale(new Date(translate_point))+")")
.on('end', function() {
update_path(svg,path,dataset,xScale);
});
dataset.shift();
});
}
那么如何修复要更新的线路路径并在从右侧传入新数据的同时平滑地向左移动呢?
解决方案
我已经对我的代码进行了一些重新排序,并且在我的情况下,平滑翻译的关键是路径对象上的 .attr('transform', null) 。
function update_path(svg,path,dataset,xScale) {
// get last date
var last=dataset[dataset.length-1];
var last_point=last[Object.keys(last)[0]];
// check new data and put it
d3.json("data.php?chartID=1&last_point="+last_point).then(function(data) {
data=make_dataset(data,data_index); // add some my stuff to dataset object
dataset=dataset.concat(data);
for (i=0; i<data.length; i++) {
dataset.shift();
}
var translate=dataset[0];
var translate_point=translate[Object.keys(translate)[0]];
var prelast=dataset[dataset.length-2];
var prelast_point=prelast[Object.keys(prelast)[0]];
var last=dataset[dataset.length-1];
var last_point=last[Object.keys(last)[0]];
var prelast_date=new Date(prelast_point);
var last_date=new Date(last_point);
var seconds = (last_date.getTime() - prelast_date.getTime());
var line=prepare_line(xScale,yScale);
// update x-axis
var xaxis_call=d3.axisBottom(xScale)
svg.selectAll("g.main_g").selectAll("g.x-axis")
.transition()
.duration(seconds)
.ease(d3.easeLinear)
.attr("transform", "translate(-"+ xScale(new Date(translate_point))+","+height+")")
.call(xaxis_call)
// update line
path.attr('transform', null)
.attr("d", line(dataset))
.transition()
.duration(seconds)
.ease(d3.easeLinear)
.attr("transform", "translate(-"+ xScale(new Date(translate_point))+")")
.on('end', function() {
// my custom functions for preparing Scales
var xScale=axis_scaleTime(dataset, width);
var yScale=axis_scaleLinear_values1(dataset, height);
update_path(svg,path,dataset,xScale);
});
});
}
推荐阅读
- python - 将列添加到一个熊猫数据框到另一个有条件的数据框
- gradle - gradle:让工具 api 模型调用依赖于 buildscript 中的任务
- api - vue中刷新页面后如何获取cookie值并放入Vuex store
- java - 从服务发送到活动的数据不起作用
- c - 在不知道结构实现的情况下如何编写通用列表?
- angular - 通过 ngrx 操作传递回调是一种不好的做法吗
- javascript - 多个或运算符检查不同变量是否为空字符串的简写
- ti-nspire - ti-nspire cx cas 上的简单范围和域功能不起作用
- r - 如何按条件隐藏多个闪亮的 ui,以及如何使用 session$userData?
- python - Confluent-kafka 消费者未阅读最后发布的消息