2012-04-08 209 views
3

着色多行我目前組裝與數據點內有一定的線圖,從格式化像這樣JSON對象的數組:D3:從嵌套數據

var data = [{ 
    "name": "metric1", 
    "datapoints": [ 
     [10.0, 1333519140], 
     [48.0, 1333519200] 
    ] 
}, { 
    "name": "metric2", 
    "datapoints": [ 
     [48.0, 1333519200], 
     [12.0, 1333519260] 
    ] 
}] 

我想有一個顏色爲每個指標,所以我試圖根據數組數據中的對象索引 對它們着色。我現在只是把圓圈中的代碼如下:

// We bind an svg group to each metric. 
var metric_groups = this.vis.selectAll("g.metric_group") 
    .data(data).enter() 
    .append("g") 
    .attr("class", "metric_group"); 

// Then bind a circle for each datapoint. 
var circles = metric_groups.selectAll("circle") 
.data(function(d) { return d.datapoints; }); 

circles.enter().append("circle") 
    .attr("r", 3.5); 

現在,如果我改變,要像最後一位:

circles.enter().append("circle") 
    .attr("r", 3.5); 
    .style("fill", function(d,i) { return i%2 ? "red" : "blue"; } 

我得到交替的紅色和藍色圓圈,因爲可以預期。
以從Nested Selections : 'Nesting and Index'一些建議,我想:

circles.enter().append("circle") 
    .attr("r", 3.5); 
    .style("fill", function(d,i,j) { return j%2 ? "red" : "blue"; } 

不工作(j是不確定的),大概是因爲我們在命名的屬性數據點,而不是一個數組元素。如何在不改變數據結構的情況下去做我想要的着色?謝謝!

+0

我通過設置組的樣式而不是圓圈解決了這個問題(爲什麼需要我在堆棧溢出上發佈才能想到這一點?)。我仍然很欣賞較少的work-around-y答案(例如,對於組內的圓圈和路徑會需要不同樣式,或者孩子的屬性是無論如何都不能繼承的情況)。 – 2012-04-08 23:26:01

回答

3

在這裏做最簡單的事情是有界繼承父g組件填充樣式:

var color = d3.scale.category20(); 

var metricGroup = vis.selectAll(".metric-group") 
    .data(data) 
    .enter().append("g") 
    .attr("class", "metric-group") 
    .style("fill", function(d) { return color(d.name); }); 

var circle = metricGroup.selectAll("circle") 
    .data(function(d) { return d.datapoints; }) 
    .enter().append("circle") 
    .attr("r", 3.5); 

如果定義明確的顏色爲CSS類,你也可以使用動態類名和繼承方式:

var metricGroup = vis.selectAll(".metric-group") 
    .data(data) 
    .enter().append("g") 
    .attr("class", function(d) { return "metric-group " + color(d.name); }); 

有了相應的CSS:

.metric1 circle { fill: red; } 
.metric2 circle { fill: blue; } 

另一個方法是使用each來訪問父數據:

metricGroup.each(function(p, j) { 
    d3.select(this).selectAll("circle") 
     .data(p.datapoints) 
    .enter().append("circle") 
     .attr("r", 3.5) 
     .style("fill", color(p.name)); 
}); 

我也想到用組索引j會工作;我不確定它爲什麼沒有定義,但在代碼示例中有一個僞分號(在.attr("r", 3.5);中),所以有可能還有其他事情正在進行。無論如何,從數據而不是組索引中派生分類顏色更具慣用性,所以我會使用上述技術之一。

1

在我的一個可視化中,我遇到了同樣的問題。我的解決辦法是以下的(適合於您的示例):

var count = 0; 

var color = d3.scale.category20(); 

var metric_groups = this.vis.selectAll("g.metric_group") 
    .data(data).enter() 
    .append("g") 
    .attr("class", "metric_group"); 

var circles = metric_groups.selectAll("circle") 
    .data(function(d) {return d.datapoints;}); 

circles.enter().append("circle") 
    .attr("r", 3.5) 
    .style("fill", function(d,i){ 
    d.number = count; 
    count++; 
    return color(d.number); 
    }); 

的關鍵是要得到的每個數據的唯一屬性,該屬性可以被用於產生相應的元件在不同的基團的獨特顏色。

我希望這有助於或支持您找到類似的解決方案!

+0

非常感謝您的回答!對不起,如果我誤解了這一點,但是這段代碼看起來會爲每個圓圈分配一個獨特的顏色,這是解決不同的問題。我的問題是希望同一行中的每個圓都具有相同的顏色。看起來我可能會想出類似的東西,但我想知道是否有更習慣的方式。 – 2012-04-09 22:22:59

+0

啊,現在我明白了問題所在!我會考慮的! – EightBitBoy 2012-04-09 23:43:05

+0

另一個方法是使用for循環:遍歷指標並繪製循環內的每個圖形和相應的圓。這樣做不是很漂亮,但它確實有效。 – EightBitBoy 2012-04-10 00:02:20