We have added amStock Flex in our application, customized it and took scrolling and zooming under control. Now let me demonstrate a more advanced feature of amStock Flex – comparison of data from multiple data sets.
It’s difficult to compare performance of multiple stocks over time by looking at their respective absolute prices. It’s way easier to do, when you see their relative percentile changes. Good news is that you don’t have to do anything with your data to implement this scenario with amStock. It does everything for you.
Let’s add more data to our application and enable this scenario.
More Datasets
First we will add more data collections to store our sample data:
1: [Bindable]2: private var chartData2:ArrayCollection = new ArrayCollection();
3: 4: [Bindable]5: private var chartData3:ArrayCollection = new ArrayCollection();
6: 7: [Bindable]8: private var chartData4:ArrayCollection = new ArrayCollection();
And generate data for these collections by modifying our generateChartData() method like this:
1: private function generateChartData():void
2: {3: var firstDate:Date = new Date();
4: firstDate.setDate(firstDate.getDate() - 1000); 5: 6: for(var i:Number = 0; i < 1000; i++)
7: {8: var newDate:Date = new Date(firstDate);
9: 10: newDate.setDate(newDate.getDate() + i); 11: 12: var a1:Number = Math.round(Math.random() * (40 + i)) + 100 + i; 13: var b1:Number = Math.round(Math.random() * (1000 + i)) + 500 + i * 2; 14: 15: var a2:Number = Math.round(Math.random() * (100 + i)) + 200 + i; 16: var b2:Number = Math.round(Math.random() * (1000 + i)) + 600 + i * 2; 17: 18: var a3:Number = Math.round(Math.random() * (100 + i)) + 200; 19: var b3:Number = Math.round(Math.random() * (1000 + i)) + 600 + i * 2; 20: 21: var a4:Number = Math.round(Math.random() * (100 + i)) + 200 + i; 22: var b4:Number = Math.round(Math.random() * (100 + i)) + 600 + i; 23: 24: chartData1.addItem({date:newDate, a:a1, b:b1}); 25: chartData2.addItem({date:newDate, a:a2, b:b2}); 26: chartData3.addItem({date:newDate, a:a3, b:b3}); 27: chartData4.addItem({date:newDate, a:a4, b:b4}); } 28: } Now let’s just add 3 more datasets to the dataSets property of our AmStockChart and bind their dataProvider property to our new data sources:
1: <!-- second data set -->
2: <amcharts:DataSet dataProvider="{chartData2}"
3: categoryField="date"
4: title="Second data set">
5: <amcharts:fieldMappings>
6: <amcharts:FieldMapping fromField="a" toField="value"/>
7: <amcharts:FieldMapping fromField="b" toField="volume"/>
8: </amcharts:fieldMappings>
9: </amcharts:DataSet>
10: 11: <!-- third data set -->
12: <amcharts:DataSet dataProvider="{chartData3}"
13: categoryField="date"
14: title="Third data set">
15: <amcharts:fieldMappings>
16: <amcharts:FieldMapping fromField="a" toField="value"/>
17: <amcharts:FieldMapping fromField="b" toField="volume"/>
18: </amcharts:fieldMappings>
19: </amcharts:DataSet>
20: 21: <!-- fourth data set -->
22: <amcharts:DataSet dataProvider="{chartData4}"
23: categoryField="date"
24: title="Fourth data set">
25: <amcharts:fieldMappings>
26: <amcharts:FieldMapping fromField="a" toField="value"/>
27: <amcharts:FieldMapping fromField="b" toField="volume"/>
28: </amcharts:fieldMappings>
29: </amcharts:DataSet>
DataSet Selector
Now that we have our data added and hooked up to data sets, lets add a final missing piece to display these data sets. By setting dataSetSelector property of our stock chart to an instance of DataSetSelector class we will make a dataset selection panel visible:
1: <amcharts:dataSetSelector>
2: <amcharts:DataSetSelector position="left" />
3: </amcharts:dataSetSelector>

Note: I’ve set width of the chart to 800 to accommodate dataset selector.
Users can now switch active dataset by selecting another one from the dropdown under “Select:”

But if you select a dataset in the “Compare to:” list box, nothing happens.
To address this we just need to set a comparable property to true on at least one of the graphs.
1: <amcharts:StockGraph id="g1" valueField="value"
2: comparable="true"
3: />
Now when user selects at least one of the datasets in “Compare to:” list, stock chart component automatically switches that chart to comparison mode, creates graphs for compared datasets and all of the values are recalculated to relative percent change values.
Now it’s easy to compare the dynamics of the price changes in multiple datasets even if absolute values differ a lot.
Conclusion
We’ve created a powerful data analysis application with ease, thanks to amStock Flex component. This tutorial covers only a part of the advanced features available in amStock. I invite you to look at the samples we have published on our site to see what else is possible with this component.
Here’s the complete source code for this tutorial:
1: <?xml version="1.0" encoding="utf-8"?>
2: <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
3: xmlns:s="library://ns.adobe.com/flex/spark"
4: xmlns:mx="library://ns.adobe.com/flex/mx"
5: xmlns:amcharts="http://www.amcharts.com/com_internal"
6: creationComplete="generateChartData()"
7: >
8: <fx:Script>
9: <![CDATA[
10: import mx.collections.ArrayCollection; 11: 12: [Bindable] 13: private var chartData1:ArrayCollection = new ArrayCollection(); 14: 15: [Bindable] 16: private var chartData2:ArrayCollection = new ArrayCollection(); 17: 18: [Bindable] 19: private var chartData3:ArrayCollection = new ArrayCollection(); 20: 21: [Bindable] 22: private var chartData4:ArrayCollection = new ArrayCollection(); 23: 24: private function generateChartData():void 25: { 26: var firstDate:Date = new Date(); 27: firstDate.setDate(firstDate.getDate() - 1000); 28: 29: for(var i:Number = 0; i < 1000; i++)
30: { 31: var newDate:Date = new Date(firstDate); 32: 33: newDate.setDate(newDate.getDate() + i); 34: 35: var a1:Number = Math.round(Math.random() * (40 + i)) + 100 + i; 36: var b1:Number = Math.round(Math.random() * (1000 + i)) + 500 + i * 2; 37: 38: var a2:Number = Math.round(Math.random() * (100 + i)) + 200 + i; 39: var b2:Number = Math.round(Math.random() * (1000 + i)) + 600 + i * 2; 40: 41: var a3:Number = Math.round(Math.random() * (100 + i)) + 200; 42: var b3:Number = Math.round(Math.random() * (1000 + i)) + 600 + i * 2; 43: 44: var a4:Number = Math.round(Math.random() * (100 + i)) + 200 + i; 45: var b4:Number = Math.round(Math.random() * (100 + i)) + 600 + i; 46: 47: chartData1.addItem({date:newDate, a:a1, b:b1}); 48: chartData2.addItem({date:newDate, a:a2, b:b2}); 49: chartData3.addItem({date:newDate, a:a3, b:b3}); 50: chartData4.addItem({date:newDate, a:a4, b:b4}); } 51: } 52: ]]>
53: </fx:Script>
54: 55: <amcharts:AmStockChart x="10" y="10"
56: width="800" height="400">
57: 58: <amcharts:dataSets>
59: 60: <amcharts:DataSet dataProvider="{chartData1}"
61: categoryField="date"
62: title="First data set">
63: <amcharts:fieldMappings>
64: <amcharts:FieldMapping fromField="a" toField="value"/>
65: <amcharts:FieldMapping fromField="b" toField="volume"/>
66: </amcharts:fieldMappings>
67: </amcharts:DataSet>
68: 69: <!-- second data set -->
70: <amcharts:DataSet dataProvider="{chartData2}"
71: categoryField="date"
72: title="Second data set">
73: <amcharts:fieldMappings>
74: <amcharts:FieldMapping fromField="a" toField="value"/>
75: <amcharts:FieldMapping fromField="b" toField="volume"/>
76: </amcharts:fieldMappings>
77: </amcharts:DataSet>
78: 79: <!-- third data set -->
80: <amcharts:DataSet dataProvider="{chartData3}"
81: categoryField="date"
82: title="Third data set">
83: <amcharts:fieldMappings>
84: <amcharts:FieldMapping fromField="a" toField="value"/>
85: <amcharts:FieldMapping fromField="b" toField="volume"/>
86: </amcharts:fieldMappings>
87: </amcharts:DataSet>
88: 89: <!-- fourth data set -->
90: <amcharts:DataSet dataProvider="{chartData4}"
91: categoryField="date"
92: title="Fourth data set">
93: <amcharts:fieldMappings>
94: <amcharts:FieldMapping fromField="a" toField="value"/>
95: <amcharts:FieldMapping fromField="b" toField="volume"/>
96: </amcharts:fieldMappings>
97: </amcharts:DataSet>
98: 99: </amcharts:dataSets>
100: 101: <amcharts:panels>
102: 103: <amcharts:StockPanel title="Value"
104: height="70%"
105: showCategoryAxis="false">
106: <amcharts:stockGraphs>
107: <amcharts:StockGraph id="g1" valueField="value"
108: comparable="true"
109: />
110: </amcharts:stockGraphs>
111: <amcharts:stockLegend>
112: <amcharts:StockLegend/>
113: </amcharts:stockLegend>
114: </amcharts:StockPanel>
115: 116: <amcharts:StockPanel title="Volume"
117: height="30%">
118: <amcharts:stockGraphs>
119: <amcharts:StockGraph valueField="volume"
120: type="column"
121: fillAlphas="[1]"
122: lineAlpha="0"
123: />
124: </amcharts:stockGraphs>
125: <amcharts:stockLegend>
126: <amcharts:StockLegend/>
127: </amcharts:stockLegend>
128: </amcharts:StockPanel>
129: 130: </amcharts:panels>
131: 132: <amcharts:dataSetSelector>
133: <amcharts:DataSetSelector position="left" />
134: </amcharts:dataSetSelector>
135: 136: <amcharts:chartScrollbarSettings>
137: <amcharts:ChartScrollbarSettings graph="{g1}"/>
138: </amcharts:chartScrollbarSettings>
139: 140: <amcharts:periodSelector>
141: <amcharts:PeriodSelector position="bottom">
142: <!-- predefined periods -->
143: <amcharts:periods>
144: <amcharts:PeriodButton label="10D" period="DD" count="10"
145: width="40" />
146: <amcharts:PeriodButton label="1M" period="MM" count="1"
147: width="40" />
148: <amcharts:PeriodButton label="6M" period="MM" count="6"
149: width="40" />
150: <amcharts:PeriodButton selected="true"
151: label="1Y" period="YYYY" count="1"
152: width="40" />
153: <amcharts:PeriodButton label="MAX" period="MAX"
154: width="40" />
155: <amcharts:PeriodButton label="YTD" period="YTD"
156: width="40" />
157: </amcharts:periods>
158: </amcharts:PeriodSelector>
159: </amcharts:periodSelector>
160: 161: </amcharts:AmStockChart>
162: </s:Application>