2017-02-09 32 views
0

我很新的D3,我試圖讓鬆散的基礎上的一個片段從這裏一個簡單的現場圖:https://bost.ocks.org/mike/path/D3過渡線發生兩次

我希望能夠多條線路添加到移動現場圖表,讓他們可以從網絡插口更新(我知道如何做到這一點位!)

當我嘗試添加第二行,圖表不會順利更新,我覺得過渡被稱爲兩次。任何幫助感激地收到。以下,但這裏

代碼是一個小提琴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); 
} 
+0

我初步意向爲蜱函數被調用兩次儘可能經常。我可能是錯的,但它看起來像函數被每行調用一次,但每次調用都影響到兩行。我會預計每條線都會打勾並影響該線。或者打勾被調用一次並影響兩行。 –

+0

我已添加小提琴以顯示問題。 – SlimCheney

回答

2

它看起來像問題是與更新數據的所有線路,當一條線在呼喚「嘀」。你會注意到你的例子在1行中工作正常,並且3行更加生澀。這是因爲函數tick中的for循環。 D3中的數據綁定非常有用,但需要一些時間才能習慣使用。
我所做的兩個主要代碼更改是將line()作爲變量並從tick函數中除去for循環。更新的小提琴(我想註釋掉的原代碼,這樣你就可以很容易地看到其中的差別):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); 
} 

盪滌小提琴:https://jsfiddle.net/Lr5dxgr0/2/

+0

好吧,我想我有一絲理解。我想我把表示線的路徑與屏幕上的路徑混淆了。你的小提琴有點混亂,但我把頭轉過來。我在這裏整理我的了一下:https://jsfiddle.net/s07d2hs3/ – SlimCheney

+1

對不起,凌亂的小提琴。我試圖平衡給出答案並顯示答案。它的**非常有用,可以在tick函數內設置開發工具的一箇中斷點,然後查看「this」包含的內容。該框架將爲你保留很多事情。我清理了小提琴並加入了原文。 –