2014-02-14 53 views
1

我想在D3中使用強制佈局來構建圖。我想根據數據構建不同的節點。目前所有節點都有一個類別和一個名稱。所以我畫了一個由兩個rect和兩個text元素組成的svg:g有條件地構建組d3

我的代碼目前看起來是這樣的:

// nodes are in the form: { group: 'string', name: 'string2' } 
this.node = this.node.data(this.node, function(d) { return d.id; }); 

var g = this.node.enter(). 
    append('svg:g'). 
    attr('transform', function(d) { return 'translate('+ d.x +','+ d.y +')'; }); 
g.append('svg:rect').attr('h', 20).attr('w', 100); 
g.append('svg:rect').attr('y', 20).attr('h', 20).attr('w', 100); 
g.append('svg:text').text(function(d) { d.group; }); 
g.append('svg:text').attr('y', 20).text(function(d) { d.name; }); 

如果節點沒有名字,但是,我想剿第二recttext的創建。從邏輯上講,如果它是不隱迭代器,在d我會做這樣的事情:

var g = this.node.enter(). 
    append('svg:g'). 
    attr('transform', function(d) { return 'translate('+ d.x +','+ d.y +')'; }); 
g.append('svg:rect').attr('h', 20).attr('w', 100); 
g.append('svg:text').text(function(d) { d.group; }); 


// unfortunately 'd' isn't defined out here. 
// EDIT: based on comment from the answer below; the conditional should 
// be for the text and the related rectangle. 
if(d.name) { 
    g.append('svg:rect').attr('y', 20).attr('h', 20).attr('w', 100); 
    g.append('svg:text').attr('y', 20).text(function(d) { d.name; }); 
} 

回答

5

你可以使用你的g選擇一個each調用,以決定是否要添加標籤。

g.each(function(d) { 
    if (d.name){ 
     var thisGroup = d3.select(this); 

     thisGroup.append("text") 
       .text(d.group); 
     thisGroup.append("text") 
       .attr("y", 20) 
       .text(d.name); 
}); 

但是,請注意,如果您要更新數據,此結構可能會引起混淆。

如果你希望能夠整齊地更新,我建議做一個嵌套的選擇:

var labels = g.selectAll("text") 
    .data(function(d){ d.name? [d.group, d.name]:[]; }); 

labels.enter().append("text"); 
labels.exit().remove(); 

labels.text(function(d){return d;}) 
      .attr("y", function(d,i){return i*20;}); 

的數據連接功能測試父的數據對象,並在此基礎上無論是傳遞一個包含數組要用於標籤文本的兩個值或空數組。如果它通過空數組,則不會創建標籤;否則,每個標籤都有由數組中的值設置的文本,並且它是由索引設置的垂直位置。

+1

重新閱讀您的問題:我基於第二個代碼片段,其中兩個標籤依賴於名稱值;但你真正的問題是你想要一個標籤和它周圍的矩形取決於名稱值。我希望你能弄清楚如何根據需要調整我的代碼。 'each'版本幾乎是一樣的,嵌套的選擇版本變得更加複雜 - 你需要做兩個嵌套選擇,一個用於文本,一個用於矩形;因爲你的數據連接函數都是'.data(function(d){d.name?[d.group,d.name]:[d.group];});'。 – AmeliaBR

+0

謝謝你的回答。這看起來應該起作用;我會在星期一試一試。你對這兩個標籤是對的。它應該是一個'rect'和'text'有條件構建的,而不是兩個'text'元素。我會編輯來解決這個問題。 – GSP