D3:我可以根据列表中的项目进行svg转换吗?

时间:2017-07-03 22:22:39

标签: javascript d3.js svg

我想列一个清单......

var data = [100, 200, 300] // arbitrarily long

...并根据每个列表项在屏幕上转换元素。例如,我想首先发送一个点到[100,100],[200,100],[300,100]。有没有办法通过数据加入来实现这一目标?

现在,我有一个可行的解决方案,但它的工作原理似乎是一种非常不正确的方式:使用计数器迭代列表,并且不使用数据绑定。排除CSS,这是代码:

<svg>
  <circle/>
</svg>


<script>

var data = [100,200,300]

var circle = d3.selectAll("circle")
    .attr("r",20)
    .attr("cy",100)
    .attr("cx",0)

var count = 0

repeat()

function repeat() {
  var run = circle
    .transition()
    .duration(1000)
    .attr("cx", function (d) {return data[count]});

    count++

  if (count < data.length){
    run
      .each("end", repeat);
  }   
}

</script>

不应该有数据绑定的方法吗?我希望以正确的方式做到这一点,但是现在这只是为了让它发挥作用。

2 个答案:

答案 0 :(得分:1)

将此作为参考:https://bl.ocks.org/mbostock/1125997

我不相信这是最好的方法,因为它仍然依赖于外部变量count,这不是D3。

请注意data

的数组结构

https://jsfiddle.net/e51rzkth/4/

var data = [[[100,100],[200,100],[300,100]]]

var svg = d3.select("body")
    .append("svg")
  .attr("width", 400)
  .attr("height", 400)

var circle = svg.selectAll("circle")
  .data(data)
  .enter()
  .append("circle")
    .attr("r",20)
    .style("fill", "red")

var count = 0

circle
    .transition()
    .duration(1000)
    .delay(250)
    .on("start", function repeat() {
        d3.active(this)
          .transition()
          .attr('cx', d=>d[count][0])
          .attr('cy', d=>d[count][1])
          .transition()
            .on("start", repeat);
            count++;
      });

对于funsies,一个包含多个圆圈的示例,每个圆圈都有自己的路径。

https://jsfiddle.net/e51rzkth/3/

答案 1 :(得分:0)

是的,你可以根据数组中的数据输入/追加圆圈,然后根据它的数据设置cx。此外,您可以通过基于数据点索引的转换延迟来实现交错,例如https://jsfiddle.net/65aeo5q5/

var circle = svg.selectAll("circle")
  .data(data)
  .enter()
  .append("circle")
    .attr("r",20)
    .attr("cy",100)
    .attr("cx",0)
    .style("fill", "red")

var delay = 1000;

circle
    .transition()
    .duration(delay)
    .delay(function (d, i) {return i * delay;})
    .attr("cx", function (d) {return d;});