d3 v5中更新路径的平滑过渡

V S*_*S X 3 javascript css jquery d3.js

我正在尝试构建d3折线图,该图将在每次单击时更新图表数据。到目前为止,这是我的进度:

var n = 10,
  random = d3.randomNormal(0, .2),
  data = d3.range(n).map(random);

var svg = d3.select("svg"),
  margin = {
    top: 20,
    right: 20,
    bottom: 20,
    left: 40
  },
  width = +svg.attr("width") - margin.left - margin.right,
  height = +svg.attr("height") - margin.top - margin.bottom,
  g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var x = d3.scaleLinear()
  .domain([0, n - 1])
  .range([0, width]);

var y = d3.scaleLinear()
  .domain([-1, 1])
  .range([height, 0]);

var line = d3.line()
  .x(function(d, i) {
    return x(i);
  })
  .y(function(d, i) {
    return y(d);
  });

g.append("defs").append("clipPath")
  .attr("id", "clip")
  .append("rect")
  .attr("width", width)
  .attr("height", height);

g.append("g")
  .attr("class", "axis axis--x")
  .attr("transform", "translate(0," + y(0) + ")")
  .call(d3.axisBottom(x));

g.append("g")
  .attr("class", "axis axis--y")
  .call(d3.axisLeft(y));

g.append("g")
  .attr("clip-path", "url(#clip)")
  .append("path")
  .datum(data)
  .attr("class", "line")
  .attr('d', line)

function tick() {

  // Push a new data point onto the back.
  data.push(random());

  // Redraw the line.
  d3.select(".line")
    .attr("d", line)
    .attr("transform", null)
    .transition()
    .duration(300)

  // Slide it to the left.
  d3.select(".line")
    .attr("transform", "translate(" + x(-1) + ",0)")
    .transition()
    .duration(300)

  // Pop the old data point off the front.
  data.shift();

}

d3.select("#translate")
  .on("click", tick)
Run Code Online (Sandbox Code Playgroud)
.line {
  fill: none;
  stroke: #000;
  stroke-width: 1.5px;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://d3js.org/d3.v5.min.js"></script>
<button id="translate">Translate</button>
<svg width="960" height="500"></svg>
Run Code Online (Sandbox Code Playgroud)

当前,图表会立即更新,而不会发生任何过渡(即使我已在更新功能中添加了过渡)。我在这里做错了什么?

我想实现类似https://bl.ocks.org/mbostock/1642874的功能,但是要实现“单击”而不是“启动”事件。

And*_*eid 5

您没有进行任何过渡:

d3.select(".line")
  .attr("...")
  .transition()
  .duration()
Run Code Online (Sandbox Code Playgroud)

这并不表示您要转换任何东西。前两行返回选择,后两行返回过渡-您需要在过渡上使用.attr()来实际过渡某些内容。如果对选择使用.attr(),则它只会更新该属性。因此,您需要使用以下模式:

d3.select(".line")
  .transition()
  .duration()
  .attr("...")  // attribute to be transitioned
Run Code Online (Sandbox Code Playgroud)

要么:

d3.select(".line")
  .transition()
  .attr("...")  // attribute to be transitioned
  .duration()
Run Code Online (Sandbox Code Playgroud)

另外,您无需转换两次,添加新数据,然后移动图形:

// Redraw the line.
d3.select(".line")
  .attr("d", line)
  .attr("transform", null)
  .transition()
  .attr("transform", "translate(" + x(-1) + ",0)")
  .duration(300)
Run Code Online (Sandbox Code Playgroud)

片段:

d3.select(".line")
  .attr("...")
  .transition()
  .duration()
Run Code Online (Sandbox Code Playgroud)
d3.select(".line")
  .transition()
  .duration()
  .attr("...")  // attribute to be transitioned
Run Code Online (Sandbox Code Playgroud)
d3.select(".line")
  .transition()
  .attr("...")  // attribute to be transitioned
  .duration()
Run Code Online (Sandbox Code Playgroud)