There might be numerous situations where you have to interact with a chart data and at the same time, perform some type of actions. Therefore, I'm going to show you how you can perform a simple action upon clicking on a chart data.
Here's the source code of my main application - SimpleChartDataClick.mxml<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" backgroundColor="#CDCDCD" creationComplete="creationCompleteEvent(event)"> <fx:Declarations> <!-- We need to specify the types of animations over here --> <s:Parallel id="parallelEffect"> <s:Fade duration="1000" alphaFrom="0" alphaTo="1"/> <mx:SeriesSlide duration="1000" direction="up"/> </s:Parallel> <s:Parallel id="parallelCarEffect"> <s:Fade duration="1000" alphaFrom="0" alphaTo="1"/> </s:Parallel> </fx:Declarations> <fx:Script> <![CDATA[ import flashx.textLayout.conversion.TextConverter; import mx.charts.HitData; import mx.charts.chartClasses.IChartElement2; import mx.charts.chartClasses.Series; import mx.charts.events.ChartItemEvent; import mx.charts.series.ColumnSeries; import mx.charts.series.LineSeries; import mx.collections.ArrayCollection; import mx.collections.Sort; import mx.collections.SortField; import mx.events.FlexEvent; import mx.formatters.DateFormatter; import mx.graphics.Stroke; import spark.events.IndexChangeEvent; //Records used in the chart [Bindable] private var myData:XML = <records> <record> <date>01/09/2013</date> <people>63</people> <car>23</car> </record> <record> <date>02/09/2013</date> <people>61</people> <car>81</car> </record> <record> <date>03/09/2013</date> <people>67</people> <car>47</car> </record> <record> <date>04/09/2013</date> <people>75</people> <car>95</car> </record> <record> <date>05/09/2013</date> <people>65</people> <car>45</car> </record> <record> <date>06/09/2013</date> <people>32</people> <car>52</car> </record> <record> <date>07/09/2013</date> <people>66</people> <car>46</car> </record> <record> <date>08/09/2013</date> <people>85</people> <car>105</car> </record> <record> <date>09/09/2013</date> <people>37</people> <car>57</car> </record> <record> <date>10/09/2013</date> <people>80</people> <car>100</car> </record> </records>; private var localSeries:ColumnSeries = new ColumnSeries(); private var localCarSeries:ColumnSeries = new ColumnSeries(); protected function creationCompleteEvent(event:FlexEvent):void { //Create the SortField object for the "time" field in //the ArrayCollection object, and make sure we do a //numeric sort. var dataSortField:SortField = new SortField(); dataSortField.name = "time"; dataSortField.numeric = true; //Create the Sort object and add the SortField object //created earlier to the array of fields to sort on. var numericDataSort:Sort = new Sort(); numericDataSort.fields = [dataSortField]; // Parsing the xml data into ArrayCollection var objArray:ArrayCollection = new ArrayCollection(); var tempObj:Object; var dateArray:Array; var tempDate:Date; for(var i:int = 0; i < myData.record.length(); i ++) { tempObj = new Object(); dateArray = String(myData.record[i].date).split("/"); //Convert the date data into a Date Object tempDate = new Date(dateArray[2], Number(dateArray[1]) - 1, dateArray[0]); tempObj.date = tempDate; tempObj.time = tempDate.time; tempObj.people = myData.record[i].people; tempObj.label = dateFormatter(tempDate); objArray.addItem(tempObj); } objArray.sort = numericDataSort; objArray.refresh(); //Create the new series and set its properties. localSeries.dataProvider = objArray; localSeries.yField = "people"; localSeries.xField = "date"; //Create alternate colors for the columns localSeries.setStyle("fill", 0xCDFFCD); //Create the strokes for the columns localSeries.setStyle("stroke", new Stroke(0xFFFFFF, 0.1, 0.5)); localSeries.displayName = "col_people"; //Set the width(%) of the column localSeries.columnWidthRatio = 0.3; //Set the offset localSeries.offset = -0.15; objArray = new ArrayCollection(); for(i = 0; i < myData.record.length(); i ++) { tempObj = new Object(); dateArray = String(myData.record[i].date).split("/"); //Convert the date data into a Date Object tempDate = new Date(dateArray[2], Number(dateArray[1]) - 1, dateArray[0]); tempObj.date = tempDate; tempObj.time = tempDate.time; tempObj.car = myData.record[i].car; tempObj.label = dateFormatter(tempDate); objArray.addItem(tempObj); } objArray.sort = numericDataSort; objArray.refresh(); //Create the new series and set its properties. localCarSeries.dataProvider = objArray; localCarSeries.yField = "car"; localCarSeries.xField = "date"; //Create alternate colors for the columns localCarSeries.setStyle("fill", 0xCDCDFF); //Create the strokes for the columns localCarSeries.setStyle("stroke", new Stroke(0xFFFFFF, 0.1, 0.5)); localCarSeries.displayName = "line_car"; //Set the width(%) of the column localCarSeries.columnWidthRatio = 0.3; //Set the offset localCarSeries.offset = 0.15; //We will remove all the series attach to the chart //first chart.series = null; //End all the effects first, else some glich will //appear. parallelEffect.end(); parallelCarEffect.end(); //Base on the type of animation selected, attach //the effect to the column localSeries.setStyle("creationCompleteEffect", parallelEffect); localCarSeries.setStyle("creationCompleteEffect", parallelCarEffect); // Back up the current series on the chart. var currentSeries:Array = chart.series; // Add the new series to the current Array of series. currentSeries.push(localCarSeries); currentSeries.push(localSeries); // Add the new Array of series to the chart. chart.series = currentSeries; } //This function will return a string based on the //Date format DD/MM/YYYY. private function dateFormatter(tempDate:Date):String { var fmt:DateFormatter = new DateFormatter(); fmt.formatString = "DD/MM/YYYY"; return fmt.format(tempDate); } //We are customizing the datatip / tool tip of the //chart data. public function myDataTipFunction(e:HitData):String { var s:String = ""; var tempDate:Date = e.item.date as Date; s += "Date: " + dateFormatter(tempDate) + "<br>"; if(Series(e.element).displayName == "col_people") { s += "No. of People: " + e.item.people; }else{ s += "No. of Cars: " + e.item.car; } return s; } //This function will be used to change the date labels of //the chart to match the data. public function createDate(s:Date):Date { var newDate:Date = new Date(); newDate.time = s.time; //We need to increase a day to the labels. newDate.date += 1; return newDate; } //This function will toggle the visibility of the chart //Data based on the values of the respective check boxes. protected function chkChartChangeEvent(event:Event):void { var showCarData:Boolean = chkCar.selected; var showPeopleData:Boolean = chkPeople.selected; for(var i:int = 0; i < chart.series.length; i ++) { if(chart.series[i].displayName == "line_car") { chart.series[i].visible = showCarData; } if(chart.series[i].displayName == "col_people") { chart.series[i].visible = showPeopleData; } } } //Upon clicking on one of the columns, this function //will update the label 'lblResult' based on the data //from the selected chart item. protected function itemClickEvent(e:ChartItemEvent):void { var str:String = "You have click on the item on "; var tempDate:Date = new Date(); tempDate.time = e.hitData.item.date.time; str += dateFormatter(tempDate) + " with the data "; var tempValue:String = ""; if(Series(e.hitData.element).displayName == "col_people") { str += "People: "; tempValue = e.hitData.item.people; }else{ str += "Car: "; tempValue = e.hitData.item.car; } str += tempValue; lblResult.text = str; } ]]> </fx:Script> <s:VGroup width="100%" height="100%" verticalAlign="middle" horizontalAlign="center"> <s:BorderContainer width="100%" backgroundAlpha="0" borderVisible="false"> <s:HGroup verticalAlign="middle" horizontalAlign="center" width="100%" height="100%"> <!-- Need to set the gutterLeft and gutterTop of the chart --> <mx:CartesianChart id="chart" gutterTop="0" gutterLeft="50" showDataTips="true" width="80%" height="80%" itemClick="itemClickEvent(event)" dataTipFunction="myDataTipFunction"> <mx:horizontalAxis> <mx:DateTimeAxis dataUnits="days" id="dateAxis" alignLabelsToUnits="false" parseFunction="createDate"/> </mx:horizontalAxis> </mx:CartesianChart> </s:HGroup> </s:BorderContainer> <s:HGroup width="100%" horizontalAlign="center" verticalAlign="middle"> <s:CheckBox id="chkCar" change="chkChartChangeEvent(event)" selected="true" label="Show Car Data"/> <s:CheckBox id="chkPeople" change="chkChartChangeEvent(event)" selected="true" label="Show People Data"/> </s:HGroup> <s:Spacer height="10"/> <s:HGroup width="100%" horizontalAlign="center" verticalAlign="middle"> <s:Label text="For your info:"/> </s:HGroup> <s:HGroup width="100%" horizontalAlign="center" verticalAlign="middle"> <s:Label id="lblResult"/> </s:HGroup> </s:VGroup> </s:Application>* Click here for the demo shown in this post.
^ Click here for the source files for the demo.
~ Click here to find out more about Chart Data Interactions in Flex.