2014-11-03 18 views
0

我使用D3,我想追加一组连接到它的基本形状,类似如下:如何使用d3创建动态追加?

  1. startEvent(圆)
  2. 任务(一recangle)
  3. ENDEVENT (两个圆)

因为我是新来的d3我想知道如何根据'形状类型'动态追加每个组,并避免使用foreach逐个追加每个形状。

这是代码:

var shapes ={ 
    startEvent:function(id,x,y,params){ 
     var radius = 18, 
     cy = Math.floor(Number(y) + radius), 
     cx = Math.floor(Number(x) + radius), 
     g = d3.select('g'); 

     var circle = g.append('circle') 
      .attr('cx', cx) 
      .attr('cy', cy) 
      .attr('r', radius) 
      .attr('id', id); 

     if(params.label!==undefined){ 
      var txt = g.append('text') 
      .attr('y',y).text(params.label); 
       txt.attr('x',Number(x)); 
       txt.attr('y',Number(y)); 
     } 
     return g; 
    }, 
    endEvent:function(id,x,y, params){ 
     // something similar to startEvent, but with two circles instead of one 
    }, 
    task:function(id,x,y, params){ 
     // something similar but with a rectangle 
    } 
}; 

传递数据和渲染的元素:

svg.selectAll('g') 
    .data(data) 
    .enter() 
    .append(function(d){ 
     params={label: d.meta.name}; 
     return shapes[d.type](d.id,d.x,d.y,params); 
    }); 

,但我发现

Error: Failed to execute 'appendChild' on 'Node': The new child element is null.

我想这是因为我返回选择器,有什么想法?

+0

[这个问题](http://stackoverflow.com/questions/21727202/append-dom-element-到-D3)应该有所帮助。 – 2014-11-03 18:16:32

+0

感谢您的参考,但我只想追加一个svg基本元素而不是HTML对象, – 2014-11-03 19:32:12

+0

问题是关于附加SVG元素。 – 2014-11-03 19:49:17

回答

0

基于thisthis解决方案我得到了以下观点,你似乎需要在d3命名空间下手动创建一个实例,一旦你得到了可以使用d3选择器并返回node()返回实际DOM代码的元素。

这是代码:

var shapes ={ 
    startEvent:function(id,x,y,params){ 
     var radius = 18, 
        cy = Math.floor(Number(y) + radius), 
        cx = Math.floor(Number(x) + radius), 
        e = document.createElementNS(d3.ns.prefix.svg,'g'), 
        g = d3.select(e).attr('id', id). 
        attr('class','node'); 
        var circle = g.append('circle') 
        .attr('cx', cx) 
        .attr('cy', cy) 
        .attr('r', radius) 
        .attr('class','circle'); 

        if(params.label!==undefined){ 
         var txt = g.append('text') 
         .attr('y',y).text(params.label); 
         txt.attr('x',Number(x)); 
         txt.attr('y',Number(y)); 

        } 
        return g; 
    }, 
    endEvent:function(id,x,y, params){ 
     // something similar to startEvent, but with two circles instead of one 
    }, 
    task:function(id,x,y, params){ 
     // something similar but with a rectangle 
    } 
}; 

,然后返回该节点

svg.selectAll('g') 
    .data(data) 
    .enter() 
    .append(function(d){ 
     params={label: d.meta.name}; 
     var v = shapes[d.type](d.id,d.x,d.y,params); 
     return v.node(); 
    });