D3.js:在转换为 运行 时检索 x 轴信息
D3.js: Retrieve x-axis information while transition is running
我正在尝试使用 D3.js v4 创建时间轴。我已经成功地创建了带有轴和画笔的散点图,以允许用户定义特定时间段。
我想让用户能够 'play' 时间轴,就像 audio/video 播放器有一个指示器,该指示器会使用可自定义的持续时间从左向右移动。为了实现这一点,我放置了一条带有过渡的垂直线作为指示器。
我的问题是在转换 运行 时无法检索 x 轴坐标。我想实现这一点,因为 x 轴值需要与代码的另一部分进行交互。
我已经尝试了所有方法,包括使用 tween 和 attrTween 函数,但我无法让它工作。理想情况下,我希望指标在画笔限制内开始和停止。
svg.append("g")
.attr("class", "brush")
.call(brush)
.call(brush.move, x.range());
svg.append('line')
.attr("class", "timeline-indicator")
.attr("stroke-width", 2)
.attr("stroke", "black")
.attr("x1", 0)
.attr("y1", 0)
.attr("x2", 0)
.attr("y2", height)
.transition()
.duration(9000)
.attr("x1", 500)
.attr("y1", 0)
.attr("x2", 500)
.attr("y2", height);
您应该能够在过渡中使用补间函数来完成此操作。补间函数将在过渡的每个刻度上触发,并且是每个刻度调用函数的一种方法。
tween 方法需要属性名称(因为它旨在为属性提供自定义插值),但这可以是虚拟属性,也可以是未更改的属性(如我下面的示例所示)。该方法的文档是 here。
在我的示例中,我使用补间函数拉动圆在屏幕上移动时的 x 属性(好吧,cx 属性):
.tween("attr.fill", function() {
var node = this;
return function(t) {
console.log(node.getAttribute("cx"));
}
})
这是工作中的一个片段:
var svg = d3.select("body").append("svg")
.attr("width",400)
.attr("height",400);
var circle = svg.append("circle")
.attr("cx",20)
.attr("cy",20)
.attr("r",10);
circle.transition()
.attr("cx",380)
.attr("cy",20)
.tween("attr.fill", function() {
var node = this;
return function(t) {
console.log(node.getAttribute("cx"));
}
})
.duration(1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
答案很好,而且可能是传统 方法。
但是,出于好奇,这里有一个使用 d3.timer 的替代答案。
数学当然要复杂一些。另外,请记住经过的时间是 apparent:
The exact values may vary depending on your JavaScript runtime and what else your computer is doing. Note that the first elapsed time is 3ms: this is the elapsed time since the timer started, not since the timer was scheduled.
查看演示:
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 100);
var circle = svg.append("circle")
.attr("cx", 30)
.attr("cy", 50)
.attr("r", 20)
.attr("fill", "tan")
.attr("stroke", "dimgray");
var timer = d3.timer(move);
function move(t) {
if (t > 2000) timer.stop();
console.log("position now is: " + ~~(30 + (t / 2000) * 440))
circle.attr("cx", 30 + (t / 2000) * 440)
}
.as-console-wrapper { max-height: 30% !important;}
<script src="https://d3js.org/d3.v4.min.js"></script>
我正在尝试使用 D3.js v4 创建时间轴。我已经成功地创建了带有轴和画笔的散点图,以允许用户定义特定时间段。
我想让用户能够 'play' 时间轴,就像 audio/video 播放器有一个指示器,该指示器会使用可自定义的持续时间从左向右移动。为了实现这一点,我放置了一条带有过渡的垂直线作为指示器。
我的问题是在转换 运行 时无法检索 x 轴坐标。我想实现这一点,因为 x 轴值需要与代码的另一部分进行交互。
我已经尝试了所有方法,包括使用 tween 和 attrTween 函数,但我无法让它工作。理想情况下,我希望指标在画笔限制内开始和停止。
svg.append("g")
.attr("class", "brush")
.call(brush)
.call(brush.move, x.range());
svg.append('line')
.attr("class", "timeline-indicator")
.attr("stroke-width", 2)
.attr("stroke", "black")
.attr("x1", 0)
.attr("y1", 0)
.attr("x2", 0)
.attr("y2", height)
.transition()
.duration(9000)
.attr("x1", 500)
.attr("y1", 0)
.attr("x2", 500)
.attr("y2", height);
您应该能够在过渡中使用补间函数来完成此操作。补间函数将在过渡的每个刻度上触发,并且是每个刻度调用函数的一种方法。
tween 方法需要属性名称(因为它旨在为属性提供自定义插值),但这可以是虚拟属性,也可以是未更改的属性(如我下面的示例所示)。该方法的文档是 here。
在我的示例中,我使用补间函数拉动圆在屏幕上移动时的 x 属性(好吧,cx 属性):
.tween("attr.fill", function() {
var node = this;
return function(t) {
console.log(node.getAttribute("cx"));
}
})
这是工作中的一个片段:
var svg = d3.select("body").append("svg")
.attr("width",400)
.attr("height",400);
var circle = svg.append("circle")
.attr("cx",20)
.attr("cy",20)
.attr("r",10);
circle.transition()
.attr("cx",380)
.attr("cy",20)
.tween("attr.fill", function() {
var node = this;
return function(t) {
console.log(node.getAttribute("cx"));
}
})
.duration(1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
但是,出于好奇,这里有一个使用 d3.timer 的替代答案。
数学当然要复杂一些。另外,请记住经过的时间是 apparent:
The exact values may vary depending on your JavaScript runtime and what else your computer is doing. Note that the first elapsed time is 3ms: this is the elapsed time since the timer started, not since the timer was scheduled.
查看演示:
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 100);
var circle = svg.append("circle")
.attr("cx", 30)
.attr("cy", 50)
.attr("r", 20)
.attr("fill", "tan")
.attr("stroke", "dimgray");
var timer = d3.timer(move);
function move(t) {
if (t > 2000) timer.stop();
console.log("position now is: " + ~~(30 + (t / 2000) * 440))
circle.attr("cx", 30 + (t / 2000) * 440)
}
.as-console-wrapper { max-height: 30% !important;}
<script src="https://d3js.org/d3.v4.min.js"></script>