Changing chart series color at run time with a ColorPicker

A recent thread in the Flex support forums resulted in a couple of new charting examples. Specifically, a user was trying to use a ColorPicker component to change the color of a series in a chart at run time. Turns out, it was a little tricky, so I figured I should share the examples.

The first example shows a LineChart. You can click on an item in the chart, which brings up a ColorPicker. You select a color and Flex applies that color to the selected series.

The meat of the example is in the itemClick handler. This is where you get a reference to the LineSeries by accessing the LineSeriesItem’s element property. Here’s the code:

private function selectItemHandler(e:ChartItemEvent):void {
var hitData:HitData = e.hitData;
csi = LineSeriesItem(hitData.chartItem);
el = ChartElement(csi.element);

cp = new ColorPicker();
cp.addEventListener(ColorPickerEvent.CHANGE, changeItemColor);
cp.x = e.localX;
cp.y = e.localY;;

The changeItemColor() method is pretty straightforward. For a LineChart’s series, you define a new Stroke and then apply that Stroke to the series’ lineStroke style. You then remove the ColorPicker from the display list so it doesn’t pollute the chart’s appearance. Here’s the code for that:

private function changeItemColor(e:ColorPickerEvent):void {
var s1:Stroke = new Stroke(cp.selectedColor, 4, 1);
el.setStyle("lineStroke", s1);

Here’s a running example:

To change the color of a series like a ColumnSeries or a BarSeries, you have to apply the style a little bit differently. In this case, you define a SolidColor and then apply that to the series’ fill property.

var c:SolidColor = new SolidColor(cp.selectedColor);
el.setStyle("fill", c);

Here’s the running example:

The final example is a little different in that it applies the color to a single item in the series and not the entire series. I thought it was interesting, so I figure I’d share it.

Instead of applying a style to the series, you set the fill property on the ColumnSeriesItem:

var c:SolidColor = new SolidColor(cp.selectedColor);
csi.fill = c;

In addition, to get it to work requires a little workaround: You have to trigger a call to the series’ updateDisplayList(). To do that, you just set a property on the itemRenderer, like this:

csi.itemRenderer.height = csi.itemRenderer.height;

Here’s the running example:

Here is a ZIP file of the 3 running examples and the source code:
Download file (985KB)

You might notice that these examples also use the live data that I blogged about recently.