SVG foreignObject tooltips in D3
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.