Aster Plot legend labels along with the arc

1.5k views Asked by At

I am using aster plot of d3 in my project. I want legend labels along with the arc radius outside the circle.

I could get an example of piechart showing labels along and outside the arc. http://bl.ocks.org/Guerino1/2295263

But i am unable to implement the same in aster plot of d3. http://bl.ocks.org/bbest/2de0e25d4840c68f2db1

Any help would be appreciated. Thanks

1

There are 1 answers

3
Mark On

Couple things to fix.

1.) You have to introduce margins into the aster plot for the labels.

2.) You then have to take the outer arcs, add a an svg g do you can group a path with a text:

var outerGroup = svg.selectAll(".solidArc")
  .data(pie(data))
  .enter()
  .append("g")

outerGroup
  .append("path")
  .attr("fill", function(d) { return d.data.color; })
  .attr("class", "solidArc")
  .attr("stroke", "gray")
  .attr("d", arc)
  .on('mouseover', tip.show)
  .on('mouseout', tip.hide);

outerGroup
  .append("text")
  .attr("transform", function(d) {
    return "translate(" + centroid(60, width, d.startAngle, d.endAngle) + ")";
  })
  .attr("text-anchor", "middle")
  .text(function(d) { return d.data.label });

Note I had to create my own centroid function to move the labels outside the arc. The code in the pie chart example you linked did not work for me (it's using a old d3 version).

Here's my centroid function stolen from the d3 source:

function centroid(innerR, outerR, startAngle, endAngle){
  var r = (innerR + outerR) / 2, a = (startAngle + endAngle) / 2 - (Math.PI / 2);
  return [ Math.cos(a) * r, Math.sin(a) * r ];
}

Here's a working example.


Full code:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>Testing Pie Chart</title>

    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?2.4.5"></script>

    <style type="text/css">
        .slice text {
            font-size: 16pt;
            font-family: Arial;
        }
    </style>
</head>
<body>
<script type="text/javascript">

    var canvasWidth = 500, //width
            canvasHeight = 500,   //height
            outerRadius = 150,   //radius
            //outerRadius =  Math.min(canvasWidth, canvasHeight) / 2,
            color = d3.scale.category20(); //builtin range of colors
    innerRadius =0
    var colorsArray = ['#0099ff','#cc00ff','#ff3366','#cc3300','#ff6600','#ffff33','#cccc00','#0066ff'];
    var dataSet = [
        {"legendLabel":"Testing Text Is", "magnitude":30,'score':4.8,width:20,color:colorsArray[0] },
        {"legendLabel":"Two", "magnitude":8,'score':3.2,width:20,color:colorsArray[1] },
        {"legendLabel":"Three", "magnitude":40,'score':3.9,width:20,color:colorsArray[2] },
        {"legendLabel":"Four", "magnitude":50,'score':3.1,width:20,color:colorsArray[3] },
        {"legendLabel":"Five", "magnitude":16,'score':4.2,width:20,color:colorsArray[4] },
        {"legendLabel":"Six", "magnitude":50,'score':3.1,width:20,color:colorsArray[5] },
        {"legendLabel":"Seven", "magnitude":30,'score':4.3,width:20,color:colorsArray[6] },
        {"legendLabel":"Eight", "magnitude":20,'score':2.3,width:20,color:colorsArray[7] }
       ];

    var vis = d3.select("body")
            .append("svg:svg")
            .data([dataSet])
            .attr("width", canvasWidth)
            .attr("height", canvasHeight)
            .append("svg:g")
            .attr("transform", "translate(" + 1.5*outerRadius + "," + 1.5*outerRadius + ")") // relocate center of pie to 'outerRadius,outerRadius'

    var arc = d3.svg.arc()
            .outerRadius(outerRadius);
    var arc1 = d3.svg.arc()
            .innerRadius(innerRadius)
            .outerRadius(function (d) {
                return (outerRadius - innerRadius) * (d.data.score / 5.0) + innerRadius;
            });

    var pie = d3.layout.pie()
            .sort(null)
            .value(function(d) { return d.width; });

    // Select all <g> elements with class slice (there aren't any yet)
    var arcs = vis.selectAll("g.slice")
            .data(pie)
            .enter()
            .append("svg:g")
            .attr("class", "slice");

    arcs.append("svg:path")
        //set the color for each slice to be chosen from the color function defined above
            .attr("fill", function(d, i) { return d.data.color; } )
        //this creates the actual SVG path using the associated data (pie) with the arc drawing function
            .attr("d", arc1);



  var text = arcs.append("svg:text")
            .attr("transform", function(d) {
                d.outerRadius = outerRadius + 75;
                d.innerRadius = outerRadius + 70;
                return "translate(" + arc.centroid(d) + ")";
            })
            .attr("text-anchor", "middle") //center the text on it's origin
            .style("fill", "black")
            .style("font", "bold 12px Arial")
     
    .each(function (d) {   
      var arr = d.data.legendLabel.split(" ");
      if (arr != undefined) {
          for (i = 0; i < arr.length; i++) {
              d3.select(this).append("tspan")
                  .text(arr[i])
                  .attr("dy", i ? "1.2em" : 0)
                  .attr("x", 0)
                  .attr("text-anchor", "middle")
                  .attr("class", "tspan" + i);
          }
      }
    });


    //.text(function(d, i) { return dataSet[i].legendLabel; })
         // .html(function(d, i) { return  '<tspan>'+dataSet[i].legendLabel+'</tspan></n><tspan>'+dataSet[i].score+'</tspan>'})
   /* arcs.append("foreignObject")
            .attr("transform", function(d) {
                d.outerRadius = outerRadius + 75;
                d.innerRadius = outerRadius + 70;
                return "translate(" + arc.centroid(d) + ")";
            })
            .attr("width", 50)
            .attr("height", 50)
            .append("xhtml:body")
            .style("font", "14px 'Helvetica Neue'")
            .html(function(d, i) { return dataSet[i].legendLabel+'<br>'+dataSet[i].score; });*/




</script>
</body>
</html>