Customizing the layout of legend items

This question came up in a recent forum posting:

You can make the LegendItems in a Legend display horizontally in a long line or vertically in a long list, but how do I customize the layout of these LegendItems?

The answer took me a little while to figure out, so I’ll post it here so others can benefit from it… Yes, the answer is also posted as a response in the forums, but I can put running examples here so you can see what I mean.

First, an app that shows the problem. The ColumnChart control in the following app has 7 separate series, each with a separate entry in the legend. If you lay out the LegendItems vertically, you get a lot of extra white space to the right of the legend, below the chart, as the following example shows:

If you lay the LegendItems out horizontally, you get scroll bars at the bottom of the application, as the following example shows:

There’s no way (that I could figure out) to eliminate those scroll bars without clipping the LegendItems.

One solution, which can be adapted to any number of layout techniques, is to build the list of LegendItems in ActionScript and add them to a dynamic grid layout. I did this in a single loop that takes into account the preferred number of items per row:

for (var j:int = 0; j < numRows; j++) {
var gr:GridRow = new GridRow();
for (var k:int = 0; k < rowSize; k++) {
if (z < myChart.series.length) {
var gi:GridItem = new GridItem();
var li:LegendItem = new LegendItem();
// Apply the current series' displayName to the LegendItem's label.
// Get the current series' fill.
// Apply the current series' fill to the corresponding LegendItem.
// Add the LegendItem to the GridItem.
// Increment any time a LegendItem is added.

Before you do any of this, you have to remove all the existing GridRows and GridItems. You do this with a call to the removeAllChildren() method, like this:


There are a couple of gotchas in this approach: you have to be sure to grab the right labels so that your dynamic LegendItems match the series’ display names that show up in the chart. You do this by accessing the chart’s series array’s displayName property, as the following example shows:

li.label = myChart.series[z].displayName;

You also have to get the color (actually, it’s the “fill” property) from the series, and apply it to the corresponding LegendItem’s fill, as the following example shows:

var sc:SolidColor = myChart.series[z].getStyle("fill");
li.setStyle("fill", sc);

Here’s a running example that lays out the LegendItems in the selected number of rows. I also took the opportunity to apply some styles to make the LegendItems a little more attractive. They are of uniform width and their background colors are the same as the marker color, as the following example shows:

li.setStyle("textIndent", 5);
li.setStyle("labelPlacement", "left");
li.setStyle("fontSize", 9);
gi.setStyle("backgroundAlpha", "1");
gi.setStyle("backgroundColor", sc.color);
gi.width = 80;

Here’s the running example:

Here’s the source code:
Download ZIP (9K)

5 Responses to Customizing the layout of legend items

  1. Thanks for the great post, really helped me get out of a bind!I was trying to set the Legend DP dynamically and was running into this bug: used your work around instead, thanks again!

  2. This was indeed a great post! Thank you for the great amount of detail as well as the example code included in the source.

  3. Joe Burns says:

    How would you modify this example for use with a line chart? I have a custom line chart and the series names are built in action script. I can get the standard MXML legend to display, but I’m having a heck of a time figuring out how to get the color for the line series instead of the bar chart as in your example.I’m trying to get the color of the line series stroke with something like this:ls = myLineChart.series[z];lstroke = ls.getStyle(“lineStroke”);sc = lstroke.color;But getting either black legends or an null error. Any ideas for the switch to line chart?Great example and thanks for posting.

    • Fayaz says:

      I am also looking to extend this feature to LineChart, but not able to figure out how to do that.

      @Joe Burns, Were you able to resolve it,

      Please let me know, if you have any solution.

  4. Dragovian says:

    Thanks a lot for this ! 😀