title: assign shapes to nodes programmatically in D3
body: <p>I am trying to assign a shape based on node values. My code is something like:</p>
  
  <pre><code>// some variables from the UI
  var anodezoom = d3.select("#nodezoom").property("value");
  var asize = d3.select("#ona").property("value");
  var acolor = d3.select("#color").property("value");
  var ameasure = d3.select("#shape").property("value");
  // build, resize, recolor and reshape the nodes
  nodes = svg.selectAll('.node')
     .data(graph.nodes.filter(function (d) {
         return d.degree &gt; 0;
     }))
     .enter()
     .append(function (d) {
         shaping(ameasure, d);
     })
     .attr('class', 'node')
     .attr('r', function (d) {
         return resizing(anodezoom, asize, d);
     })
     .style('fill', function (d) {
         return coloring(acolor, d);
     })
     .style('stroke', function (d) {
         return coloring(acolor, d);
     })
     .call(force.drag);
  </code></pre>
  
  <p>The error I get is:</p>
  
  <pre><code>TypeError: Argument 1 ('node') to Node.appendChild must be an instance of Node
  </code></pre>
  
  <p>and this happens because I fail in returning a node object in the shaping function, which is:</p>
  
  <pre><code>function shaping(ashape, anode) {
      var shape = null;
      if (ashape === "gender") {
          if (anode.gender === "M") {
              shape = d3.svg.symbolTypes[0];
          } else if (anode.gender === "F") {
              shape = d3.svg.symbolTypes[1];
          } else {
              shape = d3.svg.symbolTypes[2];
          }
      return shape;
   };
  </code></pre>
  
  <p>I basically return a string, which to me sounded good since it's legit to do:</p>
  
  <pre><code>.append('circle')
  </code></pre>
  
  <p>but it's not working, so is there a way to return a Node object with the correct shape assigned in my shaping() function?</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>I have changed my code to:</p>
  
  <pre><code>nodes = svg.selectAll('path')
                      .data(graph.nodes.filter(function (d) {
                          return d.degree &gt; 0;
                      }))
                      .enter()
                      .append('path')
                      .attr('d', d3.svg.symbol().type(function (d) {
                          return shaping(ashape, d);
                      }))
                      .attr('class', 'node')
                      .attr('r', function (d) {
                          return resizing(anodezoom, asize, d);
                      })
                      .style('fill', function (d) {
                          return coloring(acolor, d);
                      })
                      .style('stroke', function (d) {
                          return coloring(acolor, d);
                      })
                      .call(force.drag);
  </code></pre>
  
  <p>but while the links are displayed as expected, all the nodes are in the upper left corner, barely visible... what am I missing here?</p>