11

I need to display a multiline text in a SVG:Text using D3.js.

The sample data looks as follows and I want to display "all" the "titles" under a single node for every author and not as an individual node in a force directional layout.

Sample data

{
    {"author":"Author1", "group":"fiction", "books" : [
        {"title":"Book Title1", "rating":3},
        {"title":"Book Title2", "rating":4}
    ]},
    {"author":"Author2", "group":"non-fiction", "books" : [
        {"title":"Book Title3", "rating":3},
    ]}
}

SVG:text takes only one text entry and displays in a single line, so I have add more text and adjust the "dy"? or retractively collec node information and replace?

Thanks for the tips.

lud0h
  • 2,370
  • 6
  • 33
  • 41

1 Answers1

12

You have the following options.

  • You can, as you've mentioned, add more than one text element with the appropriate spacing.
  • You can also use multiple tspan elements within a text element to the same effect. Again, you would have to set the spacing yourself.
  • You can use foreignObject to embed a suitable HTML element (e.g. a div) that will take care of the line breaking, spacing etc. for you. For an example of that, see e.g. here.

I would go with the HTML embedding option unless you have a specific reason not to. It makes the actual text formatting so much easier than the other options.

Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204
  • The foreignObject works perfect. Thanks. How do I collect info from multiple nodes, i.e. dynamically collect all "titles" for an author? E.g. "Book Title 1
    Book Title2" etc., Thanks.
    – lud0h Nov 05 '13 at 15:27
  • Given an author, you would simply look over the books. In D3-speak, this would be something like `d3.selectAll("p").data(author.books).enter().append("p").text(function(d) { return d.title; })`. – Lars Kotthoff Nov 05 '13 at 15:35
  • 1
    In my experience, using foreignObject can result in rendering errors on Safari. One more alternative is to create a separate html layer with absolutely positioned divs whose top and left style attributes are adjusted using the force layout object. This layered approach is similar to the way many mapping libraries (such as Leaflet) handle svg and html overlays. – BenjaminGolder May 15 '14 at 05:29
  • 3
    foreignObject is not supported in IE. – dan May 28 '14 at 07:29
  • I love the third option! Thanks! – Miladiouss Jun 04 '20 at 23:36