Column Chart with Item Renderer – updated

Okay, it didn’t take me long to get back and do some more fiddling with the Column Chart Item Renderer. I went ahead and changed the static ArrayCollection to a dynamic one, because I was trying to figure out something with Themes and needed a button and the button should do something. The ArrayCollection is fairly simple for this chart, so all I did was create a couple of random values from 0 to 100 and made the “date” value the counter time 10. I set it up so that you can press a button and create new data, which is helpful to see the changes to the columns.

// Create some random data for Yesterday and blank data for today
private function dataCreation():void {
	currentArray.removeAll();

	for(var h:int = 0; h < 4; h++) {
		// Generate Random Data
		var randomClose:Number = Math.floor(Math.random() * 100);
		var randomOpen:Number = Math.floor(Math.random() * 100);
		// create a temporary object and add the three values
		var tmpObject:Object = new Object();
		tmpObject.date = (h + 1) * 10;
		tmpObject.close = randomClose;
		tmpObject.open = randomOpen;

		// insert new tmpObject
		currentArray.addItem(tmpObject);
	}

	// Refresh the data
	currentArray.refresh();
}

After that was fixed, I went ahead to modify the ItemRenderer again, but this time to use a GradientFill and a BitMapFill. I had to reduce what was defined for the rectangle, to just a Graphic item as a holder.

s:Graphic id="graphicHolder" />

And then I declared three different rectangles, one for each type of fill. Again, this was to simplify things and also to make sure I was doing the right thing for each fill. As you can see in the Gradient Fill, I had to set the three GradientEntry items to create the look I need. You could do this all dynamically, but I don’t think most people will try different Gradients for each column. Which is why my Gradient fill only changes the Start, Mid and End color of the Gradient.

<fx:Declarations>
	<s:Rect id="imageRect">
		<s:stroke>
			<s:SolidColorStroke id="rectImageStroke" />
		</s:stroke>
		<s:fill>
			<s:BitmapFill id="imageRectFill" fillMode="repeat" scaleX=".70" scaleY=".70" smooth="true" />
		</s:fill>
	</s:Rect>

	<s:Rect id="gradientRect">
		<s:stroke>
			<s:SolidColorStroke id="rectLinGradStroke" />
		</s:stroke>
		<s:fill>
			<s:LinearGradient id="rectLinGrad">
				<s:entries>
					<s:GradientEntry id="linGradColorStart" ratio="0" alpha=".5" />
					<s:GradientEntry id="linGradColorMid" ratio=".25" alpha=".5" />
					<s:GradientEntry id="linGradColorEnd" ratio=".66" alpha=".5" />
				</s:entries>
			</s:LinearGradient>
		</s:fill>
	</s:Rect>

	<s:Rect id="solidRect">
		<s:stroke>
			<s:SolidColorStroke id="rectSolidStroke" />
		</s:stroke>
		<s:fill>
			<s:SolidColor id="rectSolidColor" />
		</s:fill>
	</s:Rect>	
</fx:Declarations>

From here, it was just setting the color for the Gradients and the appropriate image for the BitMap Fills. Except that it took me a while to figure out the correct syntax for the Image. I couldn’t declare it. I couldn’t just Embed it as the source. I had to Embed it as a Bindable Class and then set the BitmapAsset to that Class and finally make it the source for the BitMapFill.

// Embed the Red Apple Image
[Embed(source="../assets/images/red-apple.png")]
[Bindable]
public var imgRedApple:Class;

// Red Image Fill
var imgRedAppleObj:BitmapAsset = new imgRedApple() as BitmapAsset;
imageRectFill.source = imgRedAppleObj;

I simplified the code so that different columns do only two fills. I had columns doing all three fills, but decided that was too much code and could get really confusing. With the example below;

  • If the 1st column has more than 45, then the Red Apple Image Fill is used, else the Red Gradient Fill
  • If the 2nd column has more than 45, then the Blue Gradient Fill is used, else the Blue Solid Fill
  • If the 3rd column has more than 45, then the Green Apple Image Fill is used, else the Green Solid Fill
  • If the 4th column has more than 45, then the Purple Solid Fill is used, else the Purple Gradient Fill

I created a second file for this example, so that the first example and this example could be viewed separately.
View Source

Column Chart with Fill Function

When you have a column chart, sometimes you want to change the column colors based on the data. A question in the Flex Forum asked how to alter the column color on each column. To do this, yo need to use the fillFunction on a ColumnSeries to set the color of the fill. One issue with doing this, is how it affects the chart legend.

If you use the fills property or the fillFunction to define the fills of chart items, and you want a legend, you must manually create the Legend object for that chart.

But, this just gives me the opportunity to test out two different charting options.

I alter the stacked column chart that I created to answer another question on the forum. Since the column chart in this example is created dynamically, I had to add the fillFunction parameter when creating the column series for the green and red apple columns.

columnSeries1.fillFunction = greenAppleFillFunction;

Then I just created a simple function to change the color of the column if the count was less than 50.

private function greenAppleFillFunction(element:ChartItem, index:Number):IFill {
	var item:ColumnSeriesItem = ColumnSeriesItem(element);
	var count:Number = Number(item.yValue);

	if (count < 50) {
		return scFadeGreen;
	} else {
		return scGreen;,
	}
}

To make things easier, I had already defined my SolidColor values, this makes it easier to keep it consistent throughout the chart. In this example, I am only getting the yValue, but you could also get the xValue, if you wanted to change the column colors based on that.

Next I need to update the legend to reflect the new fillFunctions, which is fairly straight forward and I can also use the defined SolidColor parameters.

<mx:Legend  direction="horizontal" >
	<mx:LegendItem label="Red Apples" fill="{scRed}" />
	<mx:LegendItem label="Red under 50" fill="{scFadeRed}" />
	<mx:LegendItem label="Yellow Apples" fill="{scYellow}" />
	<mx:LegendItem label="Green Apples" fill="{scGreen}" />
	<mx:LegendItem label="Green under 50" fill="{scFadeGreen}" />
</mx:Legend>

I also added a Refresh Data button so that the data can be cycled and the column color changes can be seen.
View Source

Stacked Column Chart with Line Series

On the Flex Forum, I was attempting to help someone find their issue to a Stacked Column Chart with a Line Series. The y-axes values were not corresponding with the data being provided. This seemed like a glitch and I even attempted a work around by finding the minimum and maximum values. Finally, after looking at the Stacking Columns example and the Multiple Axis Example, reconstructed the chart using the static objects instead of dynamically creating the chart. From there, I recreated the chart items in a function and determined that the first issue the poster was having was building the column series incorrectly into a column set.

// add column series to column set
columnset.series = [columnSeries1, columnSeries2];

The second issues is that the created column set and the line series would be the two series added to the chart, not the individual column series.

myChart.verticalAxisRenderers = [verticalAxisRendererRight, verticalAxisRendererLeft];
// column set and linear series to Chart
myChart.series = [columnset, lineSeries];

I also added both x-axis and y-axis data column information, so that there would be no mistake as to were the data was coming from. These small changes apparently were the key to getting the axis values to match the column and charts.

var columnSeries1:ColumnSeries = new ColumnSeries();
columnSeries1.dataProvider = acChartData;
columnSeries1.xField = "hourOfDay";
columnSeries1.yField = "greenAppleCount";
columnSeries1.displayName = "Green";
columnSeries1.setStyle("fill", 0x009900);
columnSeries1.verticalAxis = verticalAxisLeft;

I used my apples data creator for this chart, since I already had that available on the other chart.
Another side note of obviousness, you fill columns and stroke lines.

View Source

Meter with Percentage Thresholds

While going over a project at work, one of the graphs that the project used was a meter that had different threshold levels along with the indicator. Luckily for me, the Degrafa site had a similar meter as an example. However, the example wouldn’t be pretty enough for the project. I don’t know what the real name of this meter is, so I am calling it a Percentage Threshold Meter.

After looking into the example a little more, I also updated it by using a line repeater for the ticks and scaling the item based on 100%. Each tick would represent 10 percent of the total. The space between the ticks is determined by the height of the meter (component) divided by 10. This gives me the 10 sections for the 100% reading. I guess I would have to alter the meter is someone wanted to show something being over 100%. If the meter has the space, any value above the maximum number will shoot it out of the meter. I guess that would be good if you wanted to show busting through some number or something. But, they could always have 100% be one of the thresholds and then have the maximum number be over 100%. I also added a low, high and medium number to the ticks.

Another thing I changed was just the general look. I used another meter (capacity indicator) and a previous bar chart that I had created as guidelines for figuring out shades and highlights to make the indicator and the background more roundish. The key was to use RoundedRectangleComplex, which allowed me to round some corners, but not others.

By figuring out the height and maximum and minimum values, I was able to set the threshold percentages relative to the component size. This makes sure that the meter is a certain percentage of the entire graph based on the values. To add a nice little touch, I added the threshold percentages at the spot where the color changes.

The user can pass in the minimum value, the maximum value and the current value. The meter will grow (not animated) to the percentage based off of the values. The user can also pass in the percentage thresholds to show that the meter has reached a certain percentage of the total. The user can also change the threshold colors.