Highcharts, SVG, VML, and Auto-Sizing for Legends 16 Sep 2011
Recently we hit a limitation with Highcharts: it has no way of dynamically resizing itself or its parent container to ensure that you see the legend and the full chart at the same time. Here’s the issue at hand: http://jsfiddle.net/KYfHM/2/

This isn’t a problem if you know in advance how many data series you’ll be showing, because you can specify the proper width and height when you create the chart. We’re populating the charts on a lot of dynamic factors, so we don’t know how many series will always be displayed upfront and we don’t know how long the labels will be. For us, this meant that our legend could easily grow beyond the bounds the chart.

No one wants to see a cut-off legend.

Determined to resolve the problem we created a chart-resizing.js file which would unobtrusively define the ability for charts to automatically resize. Modern browsers support SVG, but IE7 and IE8 do not, and IE9 even has its own quirks.

We decided to start with an SVGChartResizing object which would be used to define the strategy for how the charts should be resized. This worked great in Chrome, Safari, and Firefox.


Initially our SVGChartResizing object relied on the following code to determine y position of our legend:

Liquid error: No such file or directory - posix_spawnp

Unfortunately, IE9 returns the offset from the document rather than relative to its parent. To fix that we changed the code to work along with IE9:

Liquid error: No such file or directory - posix_spawnp

For SVG supporting browsers we were set. Now onto non-SVG supporting browsers.

IE/7 IE8

IE7 and IE8 don’t support SVG, they supports VML, which they are both equally finicky about.

Breaking jQuery

When VML is present on the page IE breaks jQuery when using pure pseudo-selectors:

Liquid error: No such file or directory - posix_spawnp

The feedback you get from IE not very helpful. Fortunately, a similar issue was discovered way back in April 2010 when integrating Cufon, jQuery, and IE. There were only a few places where a pure pseudo selector was used so we updated them to be slightly more specific:

Liquid error: No such file or directory - posix_spawnp

Adding the input makes it more specific so jQuery won’t try to select certain VML elements.

Getting computed heights on VML objects

A Highcharts legend is a container which groups all of the individual legend items themselves. With the SVG-capable browsers you could ask the legend for its height and it would return its computed height. This was reliable enough to get the actual height needed to display the legend.

It seems that IEs DOM interface to VML objects doesn’t quite work the same way. It seems practically impossible to determine the computed height of a VML container. So rather than asking for the legend’s height we had to find alternative paths.

In IE8 we were able to use scrollHeight:

Liquid error: No such file or directory - posix_spawnp

IE7’s scrollHeight didn’t work the same way so we had to resort finding the largest child node and then rely on that to determine the legend’s height:

Liquid error: No such file or directory - posix_spawnp

The End

For all of the complexities that Highcharts supports it was surprising that it didn’t surprise gracefully resizing the chart and re-positioning the legend. From many Google searches it appears we aren’t alone in this feature request, although most users seem to have found their own type of work around. Until it gets resolved there will be an open issue for this.

At the end end of the day the code is cleaner than we thought would have thought given the oddities we initially hit and the time it took to sort through the problems related to IE7 and IE8.

I remember walking away from work thinking I can’t wait until I get coffee-script on this project.

You can find the full code of what it took in this source code.

This post was featured on Mutually Human’s blog.

blog comments powered by Disqus