(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。我必须设置&#s; 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以显示我想要做的事情。
答案 0 :(得分:1)
在D3的最新版本中,您可以append
元素作为函数调用的结果。也就是说,您可以传递一个计算要添加的元素的函数,而不是传递静态名称。
它的使用方式并不完全 - 仅仅从函数中返回元素的名称是不够的。而不是
g.append(function (d) { return svgShape(d); })
其中svgShape
返回一个字符串,你需要做类似
g.append(function(d) {
return document.createElementNS("http://www.w3.org/2000/svg", svgShape(d));
})
将创建相应的形状。我已经更新了你的jsbin here来演示。
在您的情况下,始终附加path
并更改行生成器(即d
属性值)可能更容易。也就是说,对于圆形,您将传入一个返回圆形路径的函数,对于一个多边形,该函数返回特定的多边形路径等。