D3.js:在转换运行时检索x轴信息

时间:2017-06-19 22:05:03

标签: javascript d3.js transition timeline tween

我正在尝试使用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);

2 个答案:

答案 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;
&#13;
&#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>