1

(这里是 D3 初学者)

我有以下片段:

// myShape (node) group
// NB: the function arg is crucial here! nodes are known by id, not by index!
myShape = myShape.data(nodes, function(d) { return d.nodeId; });

// update existing nodes (reflexive & selected visual states)
myShape.selectAll('circle')
    .style('fill', function(d) { return (d === selected_node) ? d3.rgb(colors(d.nodeType)).brighter().toString() : colors(d.nodeType); })
    .classed('reflexive', function(d) { return d.reflexive; });

// add new nodes
var g = myShape.enter().append('svg:g');

g.append('svg:circle')
    .attr('r', 12)

但我想让它更灵活:我想使用圆形多边形,而不是只使用圆形。这将在 d 中的属性中选择:

var d = [
    { nodeId: 1, nodeType : 'type1' , shape: 'circle' },
    { nodeId: 2, nodeType : 'type2' , shape: 'triangle' },
];

这意味着,取决于 d.shape。我必须设置“svg:circle”或“svg:polygon”,然后设置半径(对于圆)或点(对于多边形)。我试图像这样设置 svg 形状:

g.append(function (d) { 
    if (d.shape === 'circle' ) { return 'svg:circle'; } 
    else { return 'svg:polygon'; } } )

但这不起作用:我得到一个:

Uncaught Error: NotFoundError: DOM Exception 8

好像append不接受一个函数?如何逐个节点设置 svg 形状?

编辑

我准备了这个jsbin来展示我想要做什么。

4

1 回答 1

1

在最近的 D3 版本中,您可以将append元素作为函数调用的结果。也就是说,您可以传递一个对要添加的元素求值的函数,而不是传递一个静态名称。

它与您使用它的方式不太一样——从函数中返回元素的名称是不够的。代替

g.append(function (d) { return svgShape(d); })

wheresvgShape返回一个字符串,你需要做类似的事情

g.append(function(d) {
  return document.createElementNS("http://www.w3.org/2000/svg", svgShape(d));
})

并创建相应的形状。我在这里更新了你的 jsbin演示。

在您的情况下,始终附加 apath并更改行生成器(即d属性值)可能更容易。也就是说,对于一个圆,您将传入一个返回圆形路径的函数,对于一个多边形,一个返回特定多边形路径的函数等。

于 2013-08-23T12:58:33.793 回答