如何使用d3创建动态追加?

时间:2014-11-03 17:33:50

标签: javascript d3.js

我正在使用d3,我想附加一个附有基本形状的组,如下所示:

  1. startEvent(一个圆圈)
  2. 任务(一个纠结)
  3. endEvent(两个圈子)
  4. 因为我是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);
         });
    

    但我正在

      

    错误:无法在“节点”上执行“appendChild”:新子节点   element为null。

    我想这是因为我正在返回选择器,任何想法?

1 个答案:

答案 0 :(得分:0)

基于thisthis的答案我得到了以下几点,看起来你需要在d3命名空间下手动创建一个实例,一旦你得到了你可以使用d3选择器它返回返回实际DOM代码的元素的node()。

这是代码:

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();
     });