title: d3.js Human Shape and pointers app
body: <p><img src="https://i.stack.imgur.com/bv1o5.jpg" alt="enter image description here"></p>
  
  <p>I need to build a person map, using the custom d3 shape. Each person will have a dot and a marker coming off - labelling a particular quality.</p>
  
  <p>It would be good to develop shape templates - maybe mimicking various bio types - male/female, athletic/thin/frumpy.</p>
  
  <p><a href="http://jsfiddle.net/NYEaX/239/" rel="nofollow noreferrer">http://jsfiddle.net/NYEaX/239/</a></p>
  
  <p>I have some commented out code for the labels. I am curious as to how to use the Superformula method to create a human shape. As well as place a circle on the head and plot a marker towards the label. </p>
  
  <pre><code>        //var shapeData = d3.superformulaTypes;
   var shapeData = ["star"];
          //console.log("shapeData", shapeData);
  
  
          svg.selectAll("a")
              .data(shapeData)
            .enter().append("a")
              .attr("xlink:title", String)
              .attr("transform", function(d, i) { return "translate("+ x(d) + ",40)"; })
            .append("path")
              .attr("class", "small")
              .attr("d", small)
              .on("mousedown", function() { d3.select(this).style("fill", "aliceblue"); })
              .on("mouseup", function() { d3.select(this).style("fill", null); })
              .on("click", function(d) { d3.select(".big").transition().duration(500).attr("d", big.type(d)); });
  
  
  
          svg.append("path")
              .attr("class", "big")
              .attr("transform", "translate(250,150)")
              .attr("d", big);
  </code></pre>
  
  <hr>
  
  <p><img src="https://i.stack.imgur.com/bv1o5.jpg" alt="enter image description here"></p>
  
  <p>I've built the label part that can sit on top of the human shapes. Now need help trying to build the human shapes more easily.</p>
  
  <p><a href="http://jsfiddle.net/NYEaX/243/" rel="nofollow noreferrer">http://jsfiddle.net/NYEaX/243/</a></p>
  
  <p>here is the code for the pointers. </p>
  
  <p>My current research on building a human shape - involves either trying to modify a star shape or create a polygon. Is there a more smoother, accurate/mathematical, automatic way of building a human like shape. Like building a custom star and then rotating it accordingly? </p>
  
  <p><a href="http://jsfiddle.net/4xXQT/153/" rel="nofollow noreferrer">http://jsfiddle.net/4xXQT/153/</a>
  <a href="http://jsfiddle.net/NYEaX/241/" rel="nofollow noreferrer">http://jsfiddle.net/NYEaX/241/</a></p>
  
  <pre><code>var personBuilder = {
      init: function(){
  
  
          var size = 300;
  
          var x = d3.scale.ordinal()
              .domain(d3.superformulaTypes)
              .rangePoints([0, 360], 1);
  
          var svg = d3.select("#person").append("svg")
              .attr("width", 560)
              .attr("height", 300);
  
           this.circles = svg.append("g")
              .attr("class", "circles") 
  
           this.labels = svg.append("g")
              .attr("class", "labels")
  
           this.pointers = svg.append("g")
              .attr("class", "pointers")
  
          this.addLabels();
      },
      addLabels: function(){
          var that = this;
          var data = [
              {
                  "label": "Imagination",
                  "y": 20,
                  "x": 50,
                  "radius": 7,
                  "cx": 100,
                  "cy": 150
              },
              {
                  "label": "Love",
                  "y": 20,
                  "x": 300,
                  "radius": 7,
                  "cx": 300,
                  "cy": 150
              },
              {
                  "label": "Careeh",
                  "y": 270,
                  "x": 165,
                  "radius": 7,
                  "cx": 200,
                  "cy": 150
              }
          ]
  
                 //__circles
                                  var circs = that.circles.selectAll("circle")
                                                                    .data(data);
  
  
                                  // Enter
                                  circs.enter()
                                      .append("circle")
                                       .attr("class", "node")
                                        .attr("cx", function (d) { return d.cx; })
                                        .attr("cy", function (d) { return d.cy; })
                                        .attr("r", 1)
                                        .style("fill", function (d) { return "green"; })
                                        //.call(methods.force.drag);
  
                                  // Update
                                  circs
                                      .transition()
                                      .delay(300)
                                      .duration(1000)
                                        .attr("r", function (d) { return d.radius; })
  
                                  // Exit
                                  circs.exit()
                                      .transition()
                                      .duration(250)
                                      .attr("cx", function (d) { return d.cx; })
                                      .attr("cy", function (d) { return d.cy; })
                                      .attr("r", 1)
                                      .remove();
  
  
                //__labels  
                  var labels = that.labels.selectAll("text")
                      .data(data);
  
                  labels.enter()
                      .append("text")
                      .attr("text-anchor", "middle")
  
  
                  labels
                      .attr("x", function(d) {
                          return d.x;
                      })
                      .attr("y", function(d) {
                         return d.y;
                      })
                      .text(function(d) {
                          return d.label; 
                      })
                      .each(function(d) {
                          var bbox = this.getBBox();
                          d.sx = d.x - bbox.width/2 - 2;
                          d.ox = d.x + bbox.width/2 + 2;
                          d.sy = d.oy = d.y + 5;
                      })
                      .transition()
                          .duration(300)
  
                  labels
                      .transition()
                      .duration(300)      
  
                  labels.exit().remove();
                  //__labels            
  
  
  
  
                  //__pointers
              that.pointers.append("defs").append("marker")
                      .attr("id", "circ")
                      .attr("markerWidth", 6)
                      .attr("markerHeight", 6)
                      .attr("refX", 3)
                      .attr("refY", 3)
                      .append("circle")
                      .attr("cx", 3)
                      .attr("cy", 3)
                      .attr("r", 3);
  
                  var pointers = that.pointers.selectAll("path.pointer")
                      .data(data);
  
                  pointers.enter()
                      .append("path")
                      .attr("class", "pointer")
                      .style("fill", "none")
                      .style("stroke", "black")
                      .attr("marker-end", "url(#circ)");
  
                  pointers
                      .attr("d", function(d) {
                          if(d.cx &gt; d.ox) {
                              return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
                          } else {
                              return "M" + d.ox + "," + d.oy + "L" + d.sx + "," + d.sy + " " + d.cx + "," + d.cy;
                          }
                      })
                      .transition()
                          .duration(300)
  
                  pointers
                      .transition()
                      .duration(300)      
  
                  pointers.exit().remove();
  
                  //__pointers    
  
      }
  }
  
  
  personBuilder.init()
  </code></pre>