我一直非常密切地关注这篇关于 D3 线转换的帖子,实现了与此类似的东西,除了按时间进行轴转换。
最终目标是显示实时数据点。
我已经定义了轴,如下所示:
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));
Run Code Online (Sandbox Code Playgroud)
和这样的行:
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); });
Run Code Online (Sandbox Code Playgroud)
我正在添加一个转换函数,就像链接的帖子所说的随着时间的推移水平转换点:
(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);
})();
Run Code Online (Sandbox Code Playgroud)
到目前为止,当 Y 轴域固定时,一切都很好。我想动态调整 Y 轴的域和标签的大小,所以我在转换函数中添加了以下内容:
y.domain([
Math.min.apply(Math, data) - 10,
Math.max.apply(Math, data) + 10
])
axisy.call(y.axis);
Run Code Online (Sandbox Code Playgroud)
而且,虽然 y 轴比例似乎正确调整,但每次调用转换函数时(不是在每个转换函数刻度之间)重绘线条时,都会出现这种明显的故障效果:
显然,问题在于我没有为阶段之间的线的垂直移动设置动画。那么,第一个问题是:D3 中是否有一种简单的方法可以做到这一点?
我意识到根据数据的最大值和最小值设置域是一个挑战,因为数据不再是持续转换,它也在扩展。
所以我想我可能会不得不像这样设置域:
y.domain([temperature - 10, temperature + 10]);
Run Code Online (Sandbox Code Playgroud)
窗户固定的地方。然后我想我将不得不改变过渡,使其具有属性:
.attr('transform', `translate(${x(now - (n - 1) * duration)}, ${y(data[1] - data[0]}))`);
Run Code Online (Sandbox Code Playgroud)
我可以看到这transform将在 上调用关联的y函数line,但我不确定应该如何重新定义它。我试过:
.y(function(d, i) { return y(d / i); });
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用。
我怎样才能让这些线转换工作?非常感谢您的帮助,对于如此深入而冗长的问题,我深表歉意。
编辑:我意识到我的旧方法在很多情况下都是不正确的,并删除了示例代码/计算。当我能够弄清楚出了什么问题时,我会更新......
这是一个很酷的问题。您链接到的示例(Mike Bostock 的)只是在 X 方向插入平移,以便在更新时将曲线平滑地向左移动。但是,在您的示例中,您还想实时更改 Y 轴刻度 -
如果我们考虑一下这一点,这意味着除了将曲线向左移动(通过 X 方向的平移变换)之外,我们还需要将其压扁一点(通过 Y 方向的缩放变换)。除了在 Y 方向上缩放之外,还需要平移一点以弥补 y 轴的新位置。
您可以使用 [SVG 矩阵变换][1] 来完成所有这些操作。你只需要弄清楚你的常数是什么(a,b,c,d,e,f)。这些可以使用您的旧秤和新秤来计算。
| 归档时间: |
|
| 查看次数: |
1339 次 |
| 最近记录: |