How do I space out and wrap SVG text elements by individual word with d3.js?

Tags: ,



I have the following array of words and colors:

let dat = [{"word": "Lorum", "color": "red"}, 
     {"word": "ipsum", "color": "green"},
     {"word": "dolor", "color": "blue"},
     {"word": "sit", "color": "purple"},
     {"word": "amet", "color": "yellow"},
     {"word": "consectetur", "color": "orange"},
     {"word": "adipiscing", "color": "red"},
     {"word": "elit", "color": "purple"},
     {"word": "sed", "color": "blue"},
     {"word": "eiusmod", "color": "blue"},
     {"word": "tempor", "color": "green"}];

Using d3.js, I want to: (1) space these words evenly along an x-axis; and (2) wrap the words accordingly to a given width (move words to the next line).

I started a jsfiddle here, but the words for now all share x and y coordinates. I’d like it to appear as a sentence.

Answer

Added the below code that will use foriegnObject to append data like we do in HTML. Now with little manipulations, i am adding span tag with the required color attribute.

const width = 400,
  height = 400;
let svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height)

let dat = [{
    "word": "Lorum",
    "color": "red"
  },
  {
    "word": "ipsum",
    "color": "green"
  },
  {
    "word": "dolor",
    "color": "blue"
  },
  {
    "word": "sit",
    "color": "purple"
  },
  {
    "word": "amet",
    "color": "yellow"
  },
  {
    "word": "consectetur",
    "color": "orange"
  },
  {
    "word": "adipiscing",
    "color": "red"
  },
  {
    "word": "elit",
    "color": "purple"
  },
  {
    "word": "sed",
    "color": "blue"
  },
  {
    "word": "eiusmod",
    "color": "blue"
  },
  {
    "word": "tempor",
    "color": "green"
  }
];

const a = svg.append("foreignObject")
  .attr("width", 300)
  .attr("height", 200)
  .append("xhtml:body")
  .append('div')
  .attr('id', 'foriegnBody')
  .style("font", "14px 'Helvetica Neue'")

for (const data of dat) {
  const value = document.getElementById('foriegnBody').innerHTML;
  if (value) {
    a.html(`${value} <span style="color: ${data.color}">${data.word}</span>`)
  } else {
    a.html(`<span style="color: ${data.color}">${data.word}</span>`)
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>


Source: stackoverflow