Just a little proof-of-concept here - using an SVG <foreignObject> element as a container for a tooltip that can involve handy HTML features like text-wrapping and (semi-)dynamic sizing.
Gotchas so far:
-
Like an
<svg>element, a<foreignObject>element needs a width and a height in order to be rendered. -
However, specifying
widthand/orheightcan be delayed. Here I specify a width (foWidth) of 300px, then find the height of the contained<div>usinggetBoundingClientRect()and use that to specify the height of the containing<foreignObject>. -
If you want to provide a complex shape for the tooltip, this can be done e.g. with an SVG
<polygon>but there's a slight paradox in needing to find the dynamic dimension of the<foreignObject>before creating the<polygon>, but the<polygon>needs to appear higher than the<foreignObject>in the SVG in order to be layered underneath it. The solution here isd3.insert(el, selector). -
Chrome doesn't create the SVG
foreignObjectelements properly - they appear in the DOM asforeignobjectand can't then be selected byd3.selectAll('foreignObject')(nord3.selectAll('foreignobject')because D3 knows about the proper names of things in the SVG XML namespace). Solution: use a class to identify all<foreignObject>s.