title: How to set absolute x coordinate of text in svg?
body: <p>I want to align several <code>&lt;text&gt;</code> in the same x coordinate in a <code>&lt;svg&gt;</code> and
  surround the <code>&lt;text&gt;</code> with <code>&lt;rect&gt;</code>.</p>
  
  <p>I specified <code>x</code> attribute of <code>&lt;text&gt;</code> to align several <code>&lt;text&gt;</code>, and
  I got the coordinates of <code>&lt;text&gt;</code> with <code>getBBox()</code> to determine x position of <code>&lt;rect&gt;</code>.
  <code>getBBox().x</code>, however, is different from the specified <code>x</code> in some <code>&lt;text&gt;</code>, although <code>&lt;g&gt;</code> including <code>&lt;text&gt;</code> and <code>&lt;rect&gt;</code> was not transformed yet.</p>
  
  <p>Why are they different?
  How can I set an absolute x coordinate of <code>&lt;text&gt;</code> (e.g. to zero in the following code), and
  how can I get the absolute x coordinate of the <code>&lt;text&gt;</code>?</p>
  
  <p>I executed the following code on Chrome 59 (64bit) on Windows 10 (64bit).</p>
  
  <p><strong>Update:</strong></p>
  
  <p>When I ran the code on Firefox, 
  I got the same (expected) x coordinate using <code>getBBox().x</code> as the <code>x</code> attribute of <code>&lt;text&gt;</code>.</p>
  
  <p>Is additional effort needed on Chrome?</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="false" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const PADDING = 5
  const BOX_X = 10
  
  const data = [
    {text: "My"},
    {text: "x"},
    {text: "coordinate"},
    {text: "is"},
    {text: "zero?"}
  ]
  
  const box = d3.select("svg#svg")
    .selectAll(".text-rect")
    .data(data)
    .enter()
    .append("g")
    .classed("text-rect", true)
  
  // draw text
  const text = box
    .append("text")
    .attr("text-anchor", "start")
    .attr("font-family", "Arial")
    .attr("x", 0) // &lt;- I set `x` to zero here
    .attr("y", 0)
    .text((d) =&gt; d.text)
    .each(function(d){ d.textBBox = this.getBBox() })
  
  // surround text using coorrdinates from `getBBox()` of `&lt;text&gt;`
  box
    .append("rect")
    .attr("x", (d) =&gt; d.textBBox.x - PADDING)
    .attr("y", (d) =&gt; d.textBBox.y - PADDING)
    .attr("width", (d) =&gt; d.textBBox.width + 2 * PADDING)
    .attr("height", (d) =&gt; d.textBBox.height + 2 * PADDING)
    .attr("fill", "none")
    .attr("stroke", "black")
    .attr("stroke-width", 1)
  
  // avoid overlap
  box
    .each(function(d){ d.bbox = this.getBBox() })
    .attr("transform", function(d, i) {
      let oldY = d.bbox.y
      d.bbox.y = (i==0)? 0 : box.data()[i-1].bbox.y + box.data()[i-1].bbox.height
      return `translate(${BOX_X},${d.bbox.y - oldY})`
    });
  
  // show coordinates
  const div = d3.select("div#coordinates")
    .selectAll("p")
    .data(text.data())
    .enter()
    .append("p")
    .text((d) =&gt; `"${d.text}": (${d.textBBox.x}, ${d.textBBox.y})`)
  // I set `x` attribute of `&lt;text&gt;` to zero,
  // but `getBBox()` returned a different x coordinate.</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
    &lt;head&gt;
      &lt;meta http-equiv="content-type" content="text/html; charset=utf-8"&gt;
    &lt;/head&gt;
    &lt;body&gt;
      &lt;h3&gt;SVG is drawn here&lt;/h3&gt;
      &lt;svg id="svg" width="150" height="150"&gt;&lt;/svg&gt;
      &lt;hr&gt;
      &lt;h3&gt;XY coordinates are shown here&lt;/h3&gt;
      &lt;div id="coordinates"&gt;&lt;/div&gt;
      &lt;script src="https://d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;
    &lt;/body&gt;
  &lt;/html&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <ol>
  <li><a href="https://i.stack.imgur.com/VlSKM.png" rel="nofollow noreferrer">Results of Chrome and Firefox</a></li>
  <li><a href="https://i.stack.imgur.com/EiAkj.png" rel="nofollow noreferrer">Results of Different font-size</a></li>
  </ol>