1
votes

I am trying to add legend to pie chart. I can see the legend element added in the inspect element but I am not able to see it. Could it be due to background color ? I looked into other questions but I am not able to solve the problem.

Can somebody explain what is wrong with my code ?

I also pasted the image below showing that the legend is attached to the svg.

Here is the code snippet

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>barchart</title>
  <script type="text/javascript" src="https://d3js.org/d3.v5.min.js"></script>
</head>

<body>
  <div id="piechart">

  </div>
  <script>
    //chart dimensions

    var width = 300;
    var height = 300;
    var radius = Math.min(width, height) / 2;
    var labelHeight = 18;
    var data = {
      2011: 9,
      2012: 12,
      2013: 10,
      2014: 8,
      2015: 12,
      2016: 20
    }

    //color scale
    var color = d3.scaleOrdinal().range(["#126608", "#049a0d", "#587b08", "#048440", "#177c0a", "#4a8d36", "#3b712b", "#4a8b00", "#426b07", "#4b940b"]);

    //arc

    var arc = d3.arc()
      .outerRadius(radius - 10)
      .innerRadius(0);

    var pie = d3.pie()
      .value(function(d) {
        return d.value;
      })

    var svg = d3.select("#piechart").append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");


    var pie_data = pie(d3.entries(data))
    console.log(pie_data)

    //svg.selectAll("path").remove()

    var g = svg.selectAll("path")
      .data(pie_data)
      .enter().append("g")
      .attr("class", "arc");

    g.append("path")
      .attr("d", arc)
      .style("fill", function(d) {
        return color(d.data.key)
      });

    g.append("text")
      .attr("transform", function(d) {
        return "translate(" + arc.centroid(d) + ")";
      })
      .attr("dy", ".35em")
      .style("text-anchor", "middle")
      .attr("fill", "white")
      .text(function(d) {
        return d.data.key
      });

    var legend = svg.append("g")
      .attr("class", "legend")
      .attr("font-family", "sans-serif")
      .attr("font-size", 20)
      .attr("text-anchor", "start")
      .selectAll("g")
      .data(pie_data)
      .enter().append("g")
      .attr("transform", function(d, i) {
        return "translate(0," + i * 30 + ")";
      });

    legend.append("text")
      .attr("x", radius + 30)
      .attr("y", 9.5)
      .attr("dy", "0.32em")
      .text(function(d) {
        return d.data.key;
      });

    legend.append("rect")
      .attr("x", radius + 10)
      .attr("width", 19)
      .attr("height", 19)
      .attr("fill", function(d) {
        return color(d.data.key);
      });
  </script>
</body>

</html>

the legend element attached to svg

1

1 Answers

1
votes

You simply missed to set a proper with for the content, but what you have to actually do is to implement margin convention for your chart:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>barchart</title>
  <script type="text/javascript" src="https://d3js.org/d3.v5.min.js"></script>
</head>

<body>
  <div id="piechart">

  </div>
  <script>
    //chart dimensions

    var width = 500;
    var height = 300;
    var radius = Math.min(width, height) / 2;
    var labelHeight = 18;
    var data = {
      2011: 9,
      2012: 12,
      2013: 10,
      2014: 8,
      2015: 12,
      2016: 20
    }

    //color scale
    var color = d3.scaleOrdinal().range(["#126608", "#049a0d", "#587b08", "#048440", "#177c0a", "#4a8d36", "#3b712b", "#4a8b00", "#426b07", "#4b940b"]);

    //arc

    var arc = d3.arc()
      .outerRadius(radius - 10)
      .innerRadius(0);

    var pie = d3.pie()
      .value(function(d) {
        return d.value;
      })

    var svg = d3.select("#piechart").append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");


    var pie_data = pie(d3.entries(data))

    //svg.selectAll("path").remove()

    var g = svg.selectAll("path")
      .data(pie_data)
      .enter().append("g")
      .attr("class", "arc");

    g.append("path")
      .attr("d", arc)
      .style("fill", function(d) {
        return color(d.data.key)
      });

    g.append("text")
      .attr("transform", function(d) {
        return "translate(" + arc.centroid(d) + ")";
      })
      .attr("dy", ".35em")
      .style("text-anchor", "middle")
      .attr("fill", "white")
      .text(function(d) {
        return d.data.key
      });

    var legend = svg.append("g")
      .attr("class", "legend")
      .attr("font-family", "sans-serif")
      .attr("font-size", 20)
      .attr("text-anchor", "start")
      .selectAll("g")
      .data(pie_data)
      .enter().append("g")
      .attr("transform", function(d, i) {
        return "translate(0," + i * 30 + ")";
      });

    legend.append("text")
      .attr("x", radius + 30)
      .attr("y", 9.5)
      .attr("dy", "0.32em")
      .text(function(d) {
        return d.data.key;
      });

    legend.append("rect")
      .attr("x", radius + 10)
      .attr("width", 19)
      .attr("height", 19)
      .attr("fill", function(d) {
        return color(d.data.key);
      });
  </script>
</body>

</html>