2014-06-26 31 views
1

我有一個簡單的時間線圖與動態更新的數據值。也就是說,我週期性地添加一個新的數據值,一旦達到「最大值」,當添加一個新值時,我開始從數據集中刪除一個數據值。線圖是「動畫」,這是行得通的,因此一個新的點出現在線的右端,而最老的點從左邊消失。根據新數據的某些屬性(要繪製的值和其他相關值),我需要更改連接最新數據值和一定數量的先前繪製數據值的線段的外觀。如何在d3線圖中的特定點之間對線段進行着色?

例如,假設數據值是一個由{Time,DataValueToPlot,FlagValue}組成的簡單「對象」。正如我所說我目前正在繪製每個數據對象的「DataValueToPlot」對X軸的時間。假設繪製的最後3個值是(1 PM 10),(2 PM 20)和(3 PM 30)(儘管實際時間不統一)。我們繪製了10,20和30.現在一個新值(4 PM15)到達並且15值被添加到線圖中,但是這個新值具有關聯的FlagValue,其指示前三個線段將是比如用紅色表示大筆畫寬度。這如何實現?

需要說明的是,只要有任何數據值超過或低於指定值,我就不會要求繪製彩色線段,而是需要能夠更改所選線段的外觀。

======================= RESPONSE to @jshanley 感謝您的示例代碼。我發現它可以讓我將適當的顏色與「線條」(分段)相關聯,但我無法使其工作。我原本所使用的數據陣列與其中I中使用的行函數描述如何繪製的數據點,諸如SVG路徑結合共用圖案:

lineFcn = d3.svg.line() 
     .x(function(d) { return(d.Time); }) 
     .y(function(d) { return(d.DataValueToPlot); }) 
     .interpolate("linear"); 
var svgContainer = d3.select("body").append("svg") 
            .attr("width",500) 
            .attr("height",500); 
var lineGraph = svgContainer.append("path") 
          .attr("d", lineFcn(lineData)) 
          .attr("stroke","black") 
          .attr("stroke-width",1) 
          .attr("fill","none"); 

這種方法的問題是,我不能不要將你的建議應用於它,因爲你正在將筆畫屬性與每個「行」(分段)相關聯,但在上面的代碼中我們沒有任何這樣的元素。我試圖重寫代碼,以便我不使用svg行()輔助函數的svg路徑,而只是創建一個單獨的「線段」集合。這意味着在你的「輸入」代碼塊中,我們擴展了selection.enter()。append('line')來添加X1,Y1和X2,Y2座標,但這是問題所在。我找不到任何方法可以讓我定義這些值。

我想你的建議擴展到類似:

selection.enter().append('line') 
     .attr("x1",function(d,i) { return(d[i-1].Time); }) 
     .attr("y1",function(d,i) { return(d[i-1].DataValueToPlot)); }) 
     .attr("x2",function(d,i) { return(d].Time); }) 
     .attr("y2",function(d,i) { return(d].DataValueToPlot)); }) 

而是參考 「d [I-1]」 觸發一個錯誤。

1)訪問函數是否有某種方式來引用「先前」數據值? 2)您是否可以擴展先前的代碼示例以向我展示如何實際繪製要設置筆畫屬性的每個線段?

謝謝!

回答

1

假設您使用的是標準Enter,Update,Exit模式described here,您可以在更新部分插入一些分支邏輯,並根據是否出現FlagValue切換顏色或其他樣式。

function update(data) { 

    // reset the flag 
    var flagged = false; 

    var selection = svg.selectAll('line') 
    .data(data); 

    // ENTER 
    selection.enter().append('line') 
    // adding the attribute is superfluous 
    // but it gives us a callback in which 
    // we can set `flagged` to `true` 
    .attr('data-flagged', function(d) { 
     if (d.FlagValue === true) { 
     flagged = true; 
     return true; 
     } else { 
     return false; 
     } 
    }); 

    // ENTER + UPDATE 
    // set the stroke based on whether `flagged` is true 
    selection.attr('stroke', function(d) { 
    if (flagged) { 
     // could also add more conditional 
     // logic here to change only certain lines 
     // for example 
     // if (d.time < someTimeVar) { return 'blue'; } 
     return 'red'; 
    } else { 
     return 'green'; 
    } 
    }); 

    // EXIT 
    selection.exit().remove(); 

}  
+0

我剛剛瞭解到,我無法輸入詳細的答覆作爲評論,我不得不編輯我原來的帖子來回復你的建議。你能告訴我,我應該如何提供答覆的詳細答覆?而且,請看我的回覆。謝謝。 –

相關問題