简体   繁体   English

D3过渡线发生两次

[英]D3 transition line happening twice

I am very new to D3, I am trying to make a simple live chart loosely based on a snippet from here: https://bost.ocks.org/mike/path/ 我是D3的新手,我试图根据此处的摘录轻松地制作一个简单的实时图表: https : //bost.ocks.org/mike/path/

I want to be able to add a number of lines to a moving live chart and have them be updated from a web socket (I know how to do that bit!!) 我希望能够向移动的实时图表中添加一些折线,并通过网络套接字对其进行更新(我知道该怎么做!!)

When I try and add a second line the chart doesn't update smoothly, I think the transition is being called twice. 当我尝试添加第二条线时,图表无法平滑更新,我认为该转换被调用了两次。 Any help gratefully received. 非常感谢任何帮助。

Code below but here's a fiddle https://jsfiddle.net/q8qgbj58/ 下面的代码,但这是一个小提琴https://jsfiddle.net/q8qgbj58/

var n = 243;
var random = d3.randomNormal(0, .2);

var duration = 500;
var now = new Date(Date.now() - duration);

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.scaleTime()
    .domain([now - (n - 2) * duration, now - duration])
    .range([0, width]);

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

var lineNames = [];
var lines = {};
var data = {};

var line = d3.line()
    .curve(d3.curveBasis)
    .x(function(d, i) { return x(now - (n - 1 - i) * duration); })
    .y(function(d, i) { return y(d); });

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

var axis = 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));

createLine("one");
createLine("two");

d3.selectAll(".line")
    .transition()
        .duration(duration)
        .ease(d3.easeLinear)
        .on("start", tick);

function createLine(name) {
    lineNames.push(name);

    data[name] = d3.range(n).map(random);

    lines[name] = d3.line()
        .curve(d3.curveBasis)
        .x(function(d, i) { return x(now - (n - 1 - i) * duration); })
        .y(function(d, i) { return y(d); });

    g.append("g")
      .attr("clip-path", "url(#clip)")
        .append("path")
        .datum(data[name])
        .attr("class", "line");
}

function tick() {
    var index;
    var i;
    for (i = 0; i < lineNames.length; ++i) {
        index = lineNames[i];

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

        // Redraw the line.
        d3.select(this)
          .attr("d", lines[index])
          .attr("transform", null);

        // Pop the old data point off the front.
        data[index].shift();
    }

    now = new Date();
    x.domain([now - (n - 2) * duration, now - duration]);
    axis.transition()
        .duration(duration)
        .ease(d3.easeLinear)
        .call(d3.axisBottom(x));


    // Slide it to the left.
    d3.active(this)
      .attr("transform", "translate(" + x(now - (n - 1) * duration) + ")")
    .transition()
      .on("start", tick);
}

It looks like the issue was with updating the data for all the lines when one line was calling "tick". 看起来问题在于在一行调用“ tick”时更新所有行的数据。 You will notice your example works fine with 1 line and is even more jerky with 3 lines. 您会注意到您的示例仅用1行就能正常工作,而用3行甚至会更加生涩。 This is because of the for loop in the function tick. 这是因为函数tick中的for循环。 The data binding in D3 is very useful, but takes some time to get used to using. D3中的数据绑定非常有用,但是需要一些时间来习惯使用。
The two major code changes I made were to make the line() a variable and removed the for loop from the tick function. 我所做的两个主要代码更改是使line()成为变量,并从tick函数中删除了for循环。 An updated fiddle (I tried to just comment out the original code, so you can easily see the difference): https://jsfiddle.net/s07d2hs3/ 更新的小提琴(我试图仅注释掉原始代码,所以您可以轻松地看到区别): https : //jsfiddle.net/s07d2hs3/

var line = d3.line()
   .curve(d3.curveBasis)
   .x(function(d, i) { return x(now - (n - 1 - i) * duration); })
   .y(function(d, i) { return y(d); });

function tick() {
    var index;
    var i;
   // Push a new data point onto the back.
   this.__data__.push(random());
   // Redraw the line.
   d3.select(this)
      .attr("d", line)
      .attr("transform", null);

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

    now = new Date();
    x.domain([now - (n - 2) * duration, now - duration]);
    axis.transition()
        .duration(duration)
        .ease(d3.easeLinear)
        .call(d3.axisBottom(x));

    // Slide it to the left.
    d3.active(this)
      .attr("transform", "translate(" + x(now - (n - 1) * duration) + ")")
    .transition()
      .on("start", tick);
}

Cleaned up fiddle: https://jsfiddle.net/Lr5dxgr0/2/ 清理提琴: https : //jsfiddle.net/Lr5dxgr0/2/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM