2014-02-14 31 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