JSFiddle - React, Tailwind, and code Playground

by Neeraj Yadav

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.3/d3.min.js"></script>
<svg height="150" width="500">
<g class="legendHolder"></g>
</svg>

CSS

svg {
  outline: blue dashed 1px;
}

JavaScript

var arr = ["Forgeneration", "Pineapple", "Pin", "Banana", "Pin12345678", "Banana12"];

var svg = d3.select("svg"),
  textWidthHolder = 0,
  left = 0,
  j = 0,
  factor = 0;

function getTextWidth(text, fontSize, fontName) {
  c = document.createElement("canvas");
  ctx = c.getContext("2d");
  ctx.font = fontSize + ' ' + fontName;
  return ctx.measureText(text).width;
}

svg.select(".legendHolder")
  .selectAll(".group")
  .data(arr)
  .enter()
  .append("g")
  .attr("class", "group")
  .attr("transform", function(d, i) {
    let y = (i % 2 === 0) ? 25 : 45;
    return "translate(0, " + y + ")";
  })
  .each(function(d, i) {
    d3.select(this).append("text")
      .attr("x", function(b) {
        if (i % 2 === 0) {
          textWidthHolder += getTextWidth(b, "10px", "calibri");
          j = i;
          debugger;
          if (i > 1) {
            factor = parseInt(textWidthHolder) / 10;
            factor = factor > 3 ? 2.5 : 1;
          }
        }
        left = (factor + j) * 15 + j * 18 + textWidthHolder + 45;
        return left;
      })
      .attr("y", 9)
      .attr("dy", ".35em")
      .style("text-anchor", "start")
      .text(d);

    d3.select(this).append("rect")
      .attr("width", function() {
        return 18;
      })
      .attr("x", function(b) {
        return left - 20;
      })
      .attr("y", function(b) {
        return 0;
      })
      .attr("height", function(b) {
        return 18;
      })
      .style("fill", function(b) {
        return i % 2 === 0 ? "#ffed10" : "#ff1919";
      });
  })