Exploring Recharts: using foreignObject to render custom HTML

As we have already seen here, Recharts allows you to render any svg element as a child element of a chart container and only accepts a svg element when customizing Labels or ticks and other customizable elements (with the exception of Tooltip, as Tooltip is rendered outside the svg chart, so it can accept regular html), but there are a lot of things that are just way easier to render with html. svg allows this using the foreignObject svg element and since Recharts can render any svg elements, Recharts allows this as well. This can help you have custom labels which are not restricted to only svg elements.

See the below example:

This renders a custom label for a ReferenceLine using svg elements. So, we render a g, and a rect and a text inside the group. We have to explicitly set the coordinates for the rect and the text, and we have to take care of all the alignments for the text as well. To center the text inside the rect, we would need to set a width for the rect, then calculate the text position, and what not.

Enter foreignObject!

See the same example implemented using a foreignObject.

We still have to take care of a few things, but, and this is a big BUT, we get the capability to render html elements, and style them using our usual css. No more figuring out the text alignment, as easy as setting the text-align css property on the html element.

Cool, now that you are on onboard with the idea, let’s list out how to make it work:

  • when using a foreignObject inside svg, we need to explicitly specify the namespace that the foreign object is from. In this case we do that here: <div xmlns=”http://www.w3.org/1999/xhtml" … >
  • we still need to position the foreignObject container itself, similar to how we needed to do it for svg elements, but here we only need to align the container and all nested html elements would be aligned accordingly.
  • we need to set a width, height on the foreignObject container to set constraints, otherwise the children would not show up at all.

OR

  • we can set overflow: visible on foreignObject and let the height, width be default to zero. This way the html elements can decide their own width and everything. This is much better so that the HTML elements are not constrained by the width of the foreignObject container itself. This also helps with complex positioning and alignment.

This was just an example, you can of course use foreignObject anywhere you are customizing any Recharts elements.

References:

A list of all other posts in this series: