SVG Text not showing when generated by JS

I’m trying to generate a treemap for some data using the treemap-squarify library. Everything works as it should except when I try to place some text on top of each rectangle, the text fails to display. However, if I copy/paste the generated SVG output into the html body and open in browser, the text shows up fine. What am I doing wrong? Thanks

<html>
  <head>

    <style>
    #something{
      width: 750px;
    }
    </style>

  </head>
  <body>

    <div id="something">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 600" preserveAspectRatio="xMinYMin meet">
      </svg>
    </div>

    <script type="text/javascript" src="https://unpkg.com/treemap-squarify@1.0.1/lib/bundle.min.js"></script>
    <script>
        const result = Treemap.getTreemap({
          data: [
            { value: 18, color: 'red' },
            { value: 7, color: 'pink' },
            { value: 4, color: 'blue' },
            { value: 1, color: 'orange' },
            { value: 5, color: 'green' },
            { value: 9, color: 'grey' },
           ],
          width: 900,
          height: 600,
        });

        console.log(result);

        // lets create some SVG
        const svg = document.querySelector("svg");
        for(let i = 0; i < result.length; i++){
          // create group
          let newG = document.createElementNS("http://www.w3.org/2000/svg", "g");

          // create rectangle
          let rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
          rect.setAttribute("x", result[i].x);
          rect.setAttribute("y", result[i].y);
          rect.setAttribute("width", result[i].width);
          rect.setAttribute("height", result[i].height);
          rect.setAttribute("fill", result[i].data.color);

          // create text node
          let text = document.createElement("text");
          text.setAttribute("x", result[i].x+(result[i].width/2));
          text.setAttribute("y", result[i].y+(result[i].height/2));
          text.setAttribute("fill", "white");
          text.setAttribute("font-family", "Verdana");
          text.setAttribute("font-size", "12");

          let textNode = document.createTextNode(result[i].data.value);
          text.appendChild(textNode);

          newG.appendChild(rect);
          newG.appendChild(text);
          svg.appendChild(newG);

        }
    </script>
  </body>

</html>

>Solution :

Like with g and rect you also need to use createElementNS for text.

const result = Treemap.getTreemap({
  data: [{
      value: 18,
      color: 'red'
    },
    {
      value: 7,
      color: 'pink'
    },
    {
      value: 4,
      color: 'blue'
    },
    {
      value: 1,
      color: 'orange'
    },
    {
      value: 5,
      color: 'green'
    },
    {
      value: 9,
      color: 'grey'
    },
  ],
  width: 900,
  height: 600,
});

console.log(result);

// lets create some SVG
const svg = document.querySelector("svg");
for (let i = 0; i < result.length; i++) {
  // create group
  let newG = document.createElementNS("http://www.w3.org/2000/svg", "g");

  // create rectangle
  let rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
  rect.setAttribute("x", result[i].x);
  rect.setAttribute("y", result[i].y);
  rect.setAttribute("width", result[i].width);
  rect.setAttribute("height", result[i].height);
  rect.setAttribute("fill", result[i].data.color);

  // create text node
  // Change here to createElementNS
  let text = document.createElementNS("http://www.w3.org/2000/svg", "text");
  text.setAttribute("x", result[i].x + (result[i].width / 2));
  text.setAttribute("y", result[i].y + (result[i].height / 2));
  text.setAttribute("fill", "white");
  text.setAttribute("font-family", "Verdana");
  text.setAttribute("font-size", "12");

  let textNode = document.createTextNode(result[i].data.value);
  text.appendChild(textNode);

  newG.appendChild(rect);
  newG.appendChild(text);
  svg.appendChild(newG);

}
#something {
  width: 750px;
}
<script src="https://unpkg.com/treemap-squarify@1.0.1/lib/bundle.min.js"></script>

<div id="something">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 600" preserveAspectRatio="xMinYMin meet">
      </svg>
</div>

Leave a Reply