title: Placing text at center of rectangle
body: <p>In the following code the text is not placed at the center of the rectangle, I am using</p>
  
  <pre><code>.attr("dx", x.bandwidth()/2)
   .attr("dy", y.bandwidth()/2)
  </code></pre>
  
  <p>Rather than trial and error, is there a way to place the text center in the rectangle?</p>
  
  <p>Currently it looks like this (towards bottom and towards right):</p>
  
  <p><a href="https://i.stack.imgur.com/cQia3.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/cQia3.png" alt="enter image description here"></a></p>
  
  <p>Following is my code:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.8/d3.min.js" type="text/JavaScript"&gt;&lt;/script&gt;
  &lt;!--script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.9/d3.js" type="text/JavaScript"&gt;&lt;/script--&gt;
  &lt;style&gt;
      rect {
          stroke: #9A8B7A;
          stroke-width: 1px;
          fill: #CF7D1C;
          opacity:
      }
  &lt;/style&gt;
  &lt;body&gt;
  &lt;svg width="500" height="500"&gt;&lt;/svg&gt;
  
  &lt;/body&gt;
  &lt;script&gt;
      var dataset = [[1,3,3,5,6,7],[3,5,8,3,2,6],[9,0,6,3,6,3],[3,4,4,5,6,8],[3,4,5,2,1,8]];
  
  
  
      var local = d3.local();
  
      var svg = d3.select("svg"),
              margin = {top: 20, right: 20, bottom: 30, left: 40},
              width = +svg.attr("width") - margin.left - margin.right,
              height = +svg.attr("height") - margin.top - margin.bottom;
  
      var x = d3.scaleBand().rangeRound([0, width]);
      var y = d3.scaleBand().rangeRound([0, height]);
  
      y.domain(dataset.map(function(d,i) { return i; }));
  
      var maxChildLength= d3.max(dataset, function(d) { return d.length; });
      var xArr=Array.apply(null, {length: maxChildLength}).map(Function.call, Number);
      x.domain(xArr);
  
      var maxNum = d3.max(dataset, function(array) {
          return d3.max(array);
      });
  
      var color=d3.scaleLinear().domain([0,maxNum]).range([0,1]);
  
      svg.append("g")
              .selectAll("g")
              .data(dataset)//use top-level data to join g
              .enter()
              .append("g")
              .selectAll("rect")
              .data(function(d, i) {//for each &lt;g&gt;, use the second-level data (return d) to join rect
                  local.set(this, i);//this is the &lt;g&gt; parent
                  return d;
              })
              .enter()
              .append("rect")
  
              .attr("x", function(d, i, j) {
                 // return (i * 20) + 40;
                  return x(i);
              })
              .attr("y", function(d) {
              //    return (local.get(this) * 20) + 40;
                  return y(local.get(this));
              })
              //.attr("width",20)
              .attr("width", x.bandwidth())
              .attr("height", y.bandwidth())
              .attr("fill-opacity",function(d){console.log(color(+d));return color(+d);})
  
  
  
      svg.append("g")
              .selectAll("g")
              .data(dataset)
              .enter()
              .append("g")
              .selectAll("text")
              .data(function(d, i) {
  
                  local.set(this, i)
                  return d;
              })
              .enter()
              .append("text")
              .text(function(d, i, j) {
                  return d;
              })
              .attr("x", function(d, i, j) {
                  // return (i * 20) + 40;
                  return x(i);
              })
              .attr("y", function(d) {
                  return y(local.get(this));
                  //return (local.get(this) * 20) + 40;
              })
              .attr("dx", x.bandwidth()/2)
              .attr("dy", y.bandwidth()/2)
              .attr("dominant-baseline", "text-before-edge")
              .attr("font-family", "sans-serif")
              .attr("font-size", "20px")
  
  
  
  
  
  
  
  &lt;/script&gt;
  </code></pre>