我一直非常密切关注this post有关D3线转换的信息,实现类似于this的内容,除了按时间轴转换。
最终目标是显示实时数据点。
我已定义了轴,如下所示:
var x = d3.time.scale()
.domain([now - (n - 2) * duration, now - duration])
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0])
.domain([0, 100])
var axisx = svg.append('g')
.attr('class', 'x axis')
.attr('transform', `translate(0, ${height})`)
.call(x.axis = d3.svg.axis().scale(x).orient('bottom').tickPadding(10));
var axisy = svg.append('g')
.attr('class', 'y axis')
.attr('transform', `translate(${width}, 0)`)
.call(y.axis = d3.svg.axis().scale(y).orient('right').tickPadding(10));
这样的界线如下:
var line = d3.svg.line()
.interpolate('basis')
.x(function(d, i) { return x(now - (n - 1 - i) * duration); })
.y(function(d, i) { return y(d); });
我添加了一个转换函数,就像链接的帖子谈到要在一段时间内水平转换点一样:
(function tick() {
transition = transition.each(function() {
// Update the domain of the x-axis
now = new Date();
x.domain([now - (n - 2) * duration, now - duration]);
// Push the new data point
data.push(temperature);
// Redraw the line
svg.select('.line')
.attr('d', line)
.attr('transform', null);
// Slide the x-axis left
axisx.call(x.axis);
// Slide the line left
path.transition()
.attr('transform', `translate(${x(now - (n - 1) * duration)})`);
// Pop the old data point off the front
data.shift();
}).transition().each('start', tick);
})();
到目前为止,当Y轴域固定时,事情很有效。我想动态调整域的大小和Y轴的标签,所以我在转换函数中添加了以下内容:
y.domain([
Math.min.apply(Math, data) - 10,
Math.max.apply(Math, data) + 10
])
axisy.call(y.axis);
并且,虽然y轴刻度似乎正确调整,但每次调用过渡函数时重新绘制线条时会出现这种明显的毛刺效应(不是在每个过渡函数刻度之间):
显然,问题在于我没有动画相位之间线的垂直运动。所以,第一个问题是:D3中有一种简单的方法可以做到这一点吗?
我意识到根据数据的最大值和最小值设置域是一个挑战,因为数据不再一致地转换,它也在缩放。
所以我认为我可能最终不得不接受这样设置域名:
y.domain([temperature - 10, temperature + 10]);
窗户固定的地方。然后我想我将不得不改变转换,以便它具有属性:
.attr('transform', `translate(${x(now - (n - 1) * duration)}, ${y(data[1] - data[0]}))`);
我可以看到此transform
会在y
上调用关联的line
函数,但我不确定如何重新定义它。我试过了:
.y(function(d, i) { return y(d / i); });
但这似乎不起作用。
如何让这些线路转换工作?非常感谢你的帮助,我为这样一个深入而冗长的问题道歉。
答案 0 :(得分:0)
编辑:我意识到我的旧方法在许多情况下是不正确的,并删除了示例代码/计算。当我能够弄清楚出了什么问题时,我会更新......
这是一个很酷的问题。链接到(Mike Bostock)的示例只是在X方向上插入平移,以便在更新时平滑地将曲线向左移动。但是,在您的示例中,您还想要实时更改Y轴刻度 -
如果我们考虑这一点,就意味着除了将曲线向左移动(通过X方向的平移变换),我们还需要将其压缩一点(通过Y方向的尺度变换)。除了在Y方向上缩放之外,还需要将其平移一点以弥补y轴的新位置。
您可以使用[SVG矩阵转换] [1]完成所有这些操作。你只需要弄清楚你的常数是什么(a,b,c,d,e,f)。这些可以使用旧的和新的比例来计算。