Configuring a basic SVG form based on node -by- node

(beginner D3 is here)

I have the following snippet:

// 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) 

But I would like to make it more flexible: instead of using only circles, I would like to use circles and polygons. This will be selected in property d:

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

This means depending on d.shape. I have to set 'svg: circle' or 'svg: polygon' and then set the radius (for the circle) or the point (for the polygons). I tried to set the svg form as follows:

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

But this does not work: I get:

 Uncaught Error: NotFoundError: DOM Exception 8 

append doesn't seem to accept a function? How to set svg form based on node -by-node?

EDIT

I prepared this jsbin to show what I want to do.

+1
javascript
source share
1 answer

In recent versions of D3, you can append elements that are the result of function calls. That is, instead of passing a static name, you can pass a function that evaluates the element being added.

This is not quite the way you use it - it is not enough to return the element name from this function. Instead

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

where svgShape returns a string, you need to do something like

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

and the corresponding form will be created. I updated jsbin here to demonstrate.

In your case, it would be easier to always add path and change the line generator, i.e. attribute value d . That is, for a circle, you must pass a function that returns a circular path, for a polygon, a function that returns a specific path of a polygon, etc.

+1
source share

All Articles