Multiple area charts
In this recipe, we're going to visualize multiple sets of data on one chart.
Getting ready
As usual, create a Recipe7
document class. We'll start with the code from the previous recipe. Only now, we've slightly changed the data set to demonstrate some of the items covered better. There's also an added set of data. We've chosen to store it in the same array for simplicity, but there are other ways of course.
The following is the starting class:
package { import flash.display.Sprite; public class Recipe7 extends Sprite { private var graph:Graph; private var data:Array = [[0, 20, 50], [50, 70, 40], [100, 0, 100], [150, 150, 150], [200, 300, 200], [250, 200, 170], [300, 170, 160], [350, 20, 120], [400, 60, 80], [450, 250, 150], [500, 90, 20], [550, 50, 40], [600, 110, 90], [650, 150, 150], [700, 320, 200]]; public function Recipe7() { graph = new Graph( -50, 550, 750, -50); addChild(graph); graph.drawHorizontalAxis(0, 0, 700, 50, ["0", "700"]); graph.drawVerticalAxis(0, 0, 500, 50, ["0", "250", "500"]); for (var i:Number = 1; i < data.length; i++) { graph.drawArea(data[i-1][0], data[i-1][1], data[i][0], data[i][1]); } } } }
How to do it...
There are two ways to show multiple area charts. You can stack the charts on top of each other or you can make them transparent and have them overlaid.
We'll cover the transparent overlay first, because it's the easiest.
- Rewrite the
drawArea
method as follows:public function drawArea(x1:Number, y1:Number, x2:Number, y2:Number, colour:uint = 0xff9933, alpha:Number = 1):void { var transformedLocation1:Point = matrix.transformPoint(new Point(x1, y1)); var transformedLocation2:Point = matrix.transformPoint(new Point(x2, y2)); var transformedOrigin:Point = matrix.transformPoint(new Point(0, 0)); var area:Shape = new Shape(); area.graphics.beginFill(colour, alpha); area.graphics.moveTo(transformedLocation1.x, transformedLocation1.y); area.graphics.lineTo(transformedLocation2.x, transformedLocation2.y); area.graphics.lineTo(transformedLocation2.x, transformedOrigin.y); area.graphics.lineTo(transformedLocation1.x, transformedOrigin.y); area.graphics.endFill(); addChild(area); }
- If we now rewrite the main loop, we can draw multiple area charts with transparency:
for (var i:Number = 1; i < data.length; i++) { graph.drawArea(data[i - 1][0], data[i - 1][1], data[i][0], data[i][1], 0xff9933, 0.5); graph.drawArea(data[i - 1][0], data[i - 1][2], data[i][0], data[i][2], 0x3399ff, 0.5); }
Creating stacked charts is a little more complicated. Once again, we start by expanding the
drawArea
method. We add two more parameters that define the bottom y-coordinates of the area. In the previous graphs, they've always been zero, so we leave that in as the default:public function drawArea(x1:Number, y1:Number, x2:Number, y2:Number, colour:uint = 0xff9933, alpha:Number = 1, y3:Number = 0, y4:Number = 0):void { var transformedLocation1:Point = matrix.transformPoint(new Point(x1, y1)); var transformedLocation2:Point = matrix.transformPoint(new Point(x2, y2)); var transformedLocation3:Point = matrix.transformPoint(new Point(x1, y3)); var transformedLocation4:Point = matrix.transformPoint(new Point(x2, y4)); var area:Shape = new Shape(); area.graphics.beginFill(colour, alpha); area.graphics.moveTo(transformedLocation1.x, transformedLocation1.y); area.graphics.lineTo(transformedLocation2.x, transformedLocation2.y); area.graphics.lineTo(transformedLocation4.x, transformedLocation4.y); area.graphics.lineTo(transformedLocation3.x, transformedLocation3.y); area.graphics.endFill(); addChild(area); }
Use the following code:
for (var i:Number = 1; i < data.length; i++) { graph.drawArea(data[i - 1][0], data[i - 1][1], data[i][0], data[i][1]); graph.drawArea(data[i - 1][0], data[i - 1][1] + data[i - 1][2], data[i][0], data[i][1] + data[i][2], 0x3399ff, 1, data[i - 1][1], data[i][1]); }
How it works...
Areas are drawn by moving from one point to the other, either clockwise or counter-clockwise. We rushed over this important point in the previous recipe, but it is important in this one.
Because the areas are a little more complex, you need to be extra careful to get the order right. Otherwise you'll run into some strange phenomena.
When overlaying multiple charts, we use the alpha
property of the fills. The alpha
value controls the transparency of the fill. By making the fill translucent, we can see both areas behind each other.
When stacking multiple charts, we need to use the sum of both coordinates to properly place the different data sets. The bottom coordinates of the second data set are given by the first area chart, while the top coordinates are the sum of two data sets.
There's more...
We've seen the basics of drawing multiple data sets on one chart. In later chapters, there will be many more ways of displaying this information. In the meantime, here are a few ways to expand this recipe.
The drawArea
method's parameters can be improved upon. In particular if you want to draw a third or fourth set of data points, this is going to become unwieldy.
One option is to accept arrays of y-coordinates.