我正在尝试使用D3.js v4创建时间轴。我已成功创建了带有轴和画笔的散点图,以允许用户定义特定的时间段。
我想让用户能够“播放”时间线,就像具有指示器的音频/视频播放器一样,该指示器将使用可自定义的持续时间从左向右移动。为了达到这个目的,我已经放置了一条带有过渡的垂直线作为指标。
我的问题是在转换运行时我无法检索x轴坐标。我想实现这一点,因为x轴值需要与代码的另一部分进行交互。
我已经尝试了一切,包括玩补间动画和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);
答案 0 :(得分:2)
您应该能够在转换过程中使用补间功能完成此操作。补间函数将在转换的每个滴答上触发,并且是每次滴答调用函数的一种方法。
补间方法需要一个属性名称(因为它旨在为属性提供自定义插值),但这可以是虚拟属性,也可以是未更改的属性(如下面的示例所示)。该方法的文档是here。
在我的示例中,我使用补间函数在屏幕上移动时拉出圆圈的x属性(井,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>
&#13;
{{1}}&#13;
答案 1 :(得分:2)
Andrew's回答是一个很好的答案,可能是传统的方式。
然而,仅仅为了好奇,这里是使用d3.timer的替代答案。
数学当然有点复杂。另外,请记住经过的时间明显:
确切的值可能会有所不同,具体取决于您的JavaScript运行时以及您的计算机正在做什么。请注意,第一个经过的时间是3ms:这是自计时器启动以来经过的时间,而不是计时器的计划时间。
查看演示:
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>