score:1

Accepted answer

There are numerous ways to do this, so here is one possible way. I would group together the three pieces of the legend--the rectangle, the key text, and the text over the rectangle--in a g element and bind dataDnt4 to each item. The rectangle colour and the legend text can be retrieved by position, i.e. the first dataDnt4 item corresponds to color_rect[0] and legendTextArr[0], the second to color_rect[1] and legendTextArr[1], etc.

I've cut out the code that is not relevant to the positioning of the legend items -- you can restore that in your script.

var width = 512,

height = 600,

radius = (Math.min(width, height) / 2.5) - 60;

var sym = "%"

var legendTextArr = ["alpha", "beta", "Gamma", "vvv", "www", "xxx", "yyy", "zzz"]
var dataDnt4 =      [42, 31, 16, 4, 3, 2, 1];

var color_rect =    ["#00338D", "#BC204B", "#0091DA", "#eaaa00", "#005eb8", "#f68d2e", "#009444", "#470a68"]

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

var title = svg.append("text")
  .attr("font-weight", "bold")
  .attr("class", "title1")
  .html("scroll down!")
  .attr("transform", function() {
    return "translate(" + -184 + "," + -180 + ")"
  })

var legendG = svg.append("g")
  .attr("class", "legendG")
  .attr("transform", function() {
  // this moves the whole legend box
  // you can change this to whatever transformation is appropriate for your chart
    return "translate(" + -((width / 2)-40) + "," + 120 + ")"
  })

// group each legend item in a `g` element
var legendText = legendG.selectAll("g")
  .data(dataDnt4)
  .enter()
  .append('g')
    .attr('transform', function(d, i) {
   // instead of having a hard-coded list of multiples of 25, you can multiply
   // the array index, `i`, by 25 to get the correct position
      return 'translate(0,' + (i*25) + ')';
    });

 legendText.append("rect")
  .attr("width", 25)
  .attr("height", 17)
  .attr("class", "icon1")
  .attr("fill", function(d, i) {
    return color_rect[i];
  })

 // the text "in" the rectangle
 // use 'text-anchor: middle' and an x offset of 12.5 (rectangle width / 2)
 // to centre the labels
 // change the `y` attribute to alter the vertical positioning
 legendText.append("text")
  .attr("x", 12.5)
  .attr("y", 13)
  .attr('text-anchor', 'middle')
  .attr('fill', 'white')
  // d is the items in dataDnt4
  .text(function(d) {
    return d;
  })

 // legend text items
 legendText.append("text")
  .attr("x", 40)
  .attr("y", 13)
  // take legendTextArr item in position i
  .text(function(d,i) {
    return legendTextArr[i];
  })
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="chartdiv"></div>

You have some errors in your code (e.g. you declare the variables legendG and title twice), and it would probably be helpful for you to run your code through a code linter so you can see the problems that you might not pick up by eye.


Related Query