title: How to add a background color to d3 text elements?
body: <p>I'm trying to add a rect element behind text with d3 to simulate background-color which doesn't exist for d3 text elements. I would like the rect to have the exact same size as the text itself.</p>
  
  <pre><code>node.append("text") 
      .attr("class", "text")
      .attr("text-anchor", "middle")
      .attr("dx", 0)
      .attr("dy", ".35em")
      .text(function(d) {
            var bbox = this.getBBox();
            node.insert("rect",":first-child")
            .attr("x", bbox.x)
            .attr("y", bbox.y)
            .attr("width", bbox.width)
            .attr("height", bbox.height)
            .style("fill", "yellow");
          return d.name;
      });
  </code></pre>
  
  <p>this.getBBox() returns 0 for both x and y.</p>
  
  <p>The following code display the box, but it size doesn't very with text size, and the box is drawn even when text is not (when an image exists).</p>
  
  <pre><code>node.filter(function(d) {return (!d.image)}).append("text") 
      .attr("class", function(d) { return "text "+d.type; })
      .attr("text-anchor", "middle")
      .attr("dx", 0)
      .attr("dy", ".35em")
      //.text(function(d) { if (!d.imgB64) { return d.label; }
      .text(function(d) {
          return d.name;
      })
      .each(function(d) {
         var bbox = this.getBBox();
            node.insert("rect", "text")
            .style("fill", "#FFE6F0")
            .attr("x", bbox.x)
            .attr("y", bbox.y)
            .attr("width", bbox.width)
            .attr("height", bbox.height);
      });
  </code></pre>
  
  <p><strong>SOLUTION</strong></p>
  
  <p>Thanks to Cool Blue, the following code now properly works: display a rect behind the text so that it is readable when larger than the node circle. In the futur it could be improved with a sphere arc rather than the rect to only hide the circle frame behind the text... </p>
  
  <p><a href="https://i.stack.imgur.com/ZOl9i.png" rel="noreferrer"><img src="https://i.stack.imgur.com/ZOl9i.png" alt="enter image description here"></a></p>
  
  <pre><code>// only display node labels if node has no image 
  node.filter(function(d) {return (!d.image)}).append("text") 
      .attr("class", function(d) { return "text "+d.type; })
      .attr("text-anchor", "middle")
      .attr("dx", 0)
      .attr("dy", ".35em")
      .text(function(d) {
          return d.name;
      })
      .call(getTextBox);
  
  // only display a rect behind labels if node has no image 
  node.filter(function(d) {return (!d.image)}).insert("rect","text")
      .attr("x", function(d){return d.bbox.x})
      .attr("y", function(d){return d.bbox.y})
      .attr("width", function(d){return d.bbox.width})
      .attr("height", function(d){return d.bbox.height})
      .style("fill", "#FFE6F0");
  
  function getTextBox(selection) {
      selection.each(function(d) { d.bbox = this.getBBox(); })
  }
  </code></pre>