Probably there' a requirement that requires you to place an icon for both the highest and lowest y value of a chart, but how do you do it?
And here's my answer to the above question. :P Time for some coding... Here's my main application file - "SimpleChartPositionOfAPoint.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:Script>
<![CDATA[
import flashx.textLayout.conversion.TextConverter;
import mx.charts.HitData;
import mx.charts.chartClasses.IChartElement2;
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 spark.events.IndexChangeEvent;
//Records used in the chart
[Bindable]
private var myData:XML =
<records>
<record>
<date>16/11/2012</date>
<people>74</people>
</record>
<record>
<date>24/07/2013</date>
<people>99</people>
</record>
<record>
<date>05/04/2013</date>
<people>79</people>
</record>
<record>
<date>08/07/2012</date>
<people>54</people>
</record>
<record>
<date>22/11/2012</date>
<people>42</people>
</record>
<record>
<date>10/04/2012</date>
<people>42</people>
</record>
<record>
<date>17/03/2012</date>
<people>57</people>
</record>
<record>
<date>16/10/2011</date>
<people>63</people>
</record>
<record>
<date>06/02/2012</date>
<people>80</people>
</record>
<record>
<date>09/01/2012</date>
<people>2</people>
</record>
<record>
<date>18/11/2011</date>
<people>100</people>
</record>
<record>
<date>25/11/2011</date>
<people>88</people>
</record>
<record>
<date>29/05/2012</date>
<people>94</people>
</record>
<record>
<date>30/03/2013</date>
<people>99</people>
</record>
<record>
<date>08/09/2012</date>
<people>33</people>
</record>
<record>
<date>26/01/2012</date>
<people>33</people>
</record>
<record>
<date>12/11/2012</date>
<people>48</people>
</record>
<record>
<date>17/05/2013</date>
<people>57</people>
</record>
<record>
<date>13/04/2012</date>
<people>57</people>
</record>
<record>
<date>18/07/2013</date>
<people>81</people>
</record>
<record>
<date>09/08/2012</date>
<people>60</people>
</record>
<record>
<date>04/09/2012</date>
<people>49</people>
</record>
<record>
<date>29/12/2012</date>
<people>15</people>
</record>
<record>
<date>17/08/2011</date>
<people>1</people>
</record>
<record>
<date>09/10/2012</date>
<people>76</people>
</record>
<record>
<date>20/02/2012</date>
<people>62</people>
</record>
<record>
<date>24/06/2013</date>
<people>70</people>
</record>
<record>
<date>17/07/2013</date>
<people>17</people>
</record>
<record>
<date>21/04/2012</date>
<people>32</people>
</record>
<record>
<date>11/04/2013</date>
<people>92</people>
</record>
<record>
<date>02/08/2013</date>
<people>97</people>
</record>
<record>
<date>27/12/2011</date>
<people>5</people>
</record>
<record>
<date>01/05/2012</date>
<people>90</people>
</record>
<record>
<date>20/04/2013</date>
<people>75</people>
</record>
<record>
<date>26/10/2012</date>
<people>60</people>
</record>
<record>
<date>02/01/2012</date>
<people>31</people>
</record>
<record>
<date>04/02/2013</date>
<people>17</people>
</record>
<record>
<date>17/04/2013</date>
<people>16</people>
</record>
<record>
<date>22/03/2013</date>
<people>94</people>
</record>
<record>
<date>10/09/2011</date>
<people>97</people>
</record>
<record>
<date>27/11/2012</date>
<people>18</people>
</record>
<record>
<date>15/03/2013</date>
<people>94</people>
</record>
<record>
<date>17/10/2011</date>
<people>85</people>
</record>
<record>
<date>18/03/2012</date>
<people>12</people>
</record>
<record>
<date>09/10/2011</date>
<people>92</people>
</record>
<record>
<date>08/09/2012</date>
<people>17</people>
</record>
<record>
<date>22/10/2012</date>
<people>45</people>
</record>
<record>
<date>09/11/2012</date>
<people>40</people>
</record>
<record>
<date>06/09/2012</date>
<people>75</people>
</record>
<record>
<date>13/08/2012</date>
<people>2</people>
</record>
<record>
<date>04/03/2012</date>
<people>20</people>
</record>
<record>
<date>17/11/2012</date>
<people>34</people>
</record>
<record>
<date>01/02/2012</date>
<people>51</people>
</record>
<record>
<date>29/08/2011</date>
<people>35</people>
</record>
<record>
<date>11/02/2012</date>
<people>35</people>
</record>
<record>
<date>02/06/2012</date>
<people>26</people>
</record>
<record>
<date>20/01/2013</date>
<people>98</people>
</record>
<record>
<date>07/02/2013</date>
<people>4</people>
</record>
<record>
<date>27/08/2012</date>
<people>44</people>
</record>
<record>
<date>12/12/2012</date>
<people>29</people>
</record>
<record>
<date>18/03/2012</date>
<people>96</people>
</record>
<record>
<date>01/09/2012</date>
<people>40</people>
</record>
<record>
<date>09/02/2013</date>
<people>34</people>
</record>
<record>
<date>22/09/2012</date>
<people>86</people>
</record>
<record>
<date>28/02/2012</date>
<people>14</people>
</record>
<record>
<date>02/02/2012</date>
<people>94</people>
</record>
<record>
<date>08/06/2013</date>
<people>16</people>
</record>
<record>
<date>23/03/2012</date>
<people>32</people>
</record>
<record>
<date>21/03/2013</date>
<people>10</people>
</record>
<record>
<date>07/04/2013</date>
<people>10</people>
</record>
<record>
<date>11/03/2013</date>
<people>28</people>
</record>
<record>
<date>02/11/2012</date>
<people>28</people>
</record>
<record>
<date>14/11/2011</date>
<people>3</people>
</record>
<record>
<date>05/02/2013</date>
<people>12</people>
</record>
<record>
<date>21/03/2013</date>
<people>41</people>
</record>
<record>
<date>30/09/2012</date>
<people>96</people>
</record>
<record>
<date>19/02/2013</date>
<people>29</people>
</record>
<record>
<date>09/07/2013</date>
<people>86</people>
</record>
<record>
<date>30/04/2013</date>
<people>35</people>
</record>
<record>
<date>21/01/2012</date>
<people>4</people>
</record>
<record>
<date>26/06/2013</date>
<people>88</people>
</record>
<record>
<date>17/04/2013</date>
<people>55</people>
</record>
<record>
<date>04/10/2011</date>
<people>38</people>
</record>
<record>
<date>20/03/2013</date>
<people>38</people>
</record>
<record>
<date>19/05/2013</date>
<people>91</people>
</record>
<record>
<date>28/08/2011</date>
<people>73</people>
</record>
<record>
<date>31/08/2011</date>
<people>65</people>
</record>
<record>
<date>11/03/2013</date>
<people>88</people>
</record>
<record>
<date>10/06/2013</date>
<people>78</people>
</record>
<record>
<date>03/07/2013</date>
<people>8</people>
</record>
<record>
<date>08/10/2012</date>
<people>16</people>
</record>
<record>
<date>19/03/2012</date>
<people>74</people>
</record>
<record>
<date>28/09/2012</date>
<people>49</people>
</record>
<record>
<date>29/07/2013</date>
<people>51</people>
</record>
<record>
<date>05/10/2012</date>
<people>60</people>
</record>
<record>
<date>18/02/2012</date>
<people>63</people>
</record>
<record>
<date>03/09/2011</date>
<people>45</people>
</record>
<record>
<date>30/12/2011</date>
<people>76</people>
</record>
<record>
<date>11/04/2013</date>
<people>96</people>
</record>
<record>
<date>15/06/2012</date>
<people>55</people>
</record>
</records>;
private var localSeries:LineSeries = new LineSeries();
//This function will show a text box which is positioned
//above the selected point
protected function cb1ChangeEvent(event:IndexChangeEvent):void
{
//We will need the date, the date in numerical format
//and the number of people during that date
var tempDate:Date = event.currentTarget.selectedItem.date;
var xPos:Number = tempDate.time;
var yPos:Number = event.currentTarget.selectedItem.people;
//Next, create a point withe the date in numerical format
//and the number of people, which is used to create the
//x and y axis of the chart
var myPoint:Point = new Point(xPos,yPos);
//Next, check it against the line series to find the
//and y postion of the point on the chart
//Note: dataToLocal didn't calculate the gutters around
//the chart, you need to calculate yrself.
myPoint = localSeries.dataToLocal(xPos, yPos);
//Next, offset the gutters on the left and top of the point
myPoint.x += lineChart.getStyle("gutterLeft");
myPoint.y += lineChart.getStyle("gutterTop");
//find the global position of the point
myPoint = lineChart.localToGlobal(myPoint);
//followed by the step of mapping the point into the
//layer abouve the chart
myPoint = canvas.globalToLocal(myPoint);
//We will position the textfield above the selected point
txtResult.visible = true;
txtResult.x = myPoint.x - txtResult.width / 2;
txtResult.y = myPoint.y - txtResult.height - 5;
//Let's populate the textfield with some data.
var tempStr:String = "";
tempStr += "Date: " + dateFormatter(tempDate) + "<br>";
tempStr += "No. of People: " + yPos;
txtResult.textFlow = TextConverter.importToFlow(tempStr,
TextConverter.TEXT_FIELD_HTML_FORMAT);
}
protected function creationCompleteEvent(event:FlexEvent):void
{
// 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);
}
//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];
objArray.sort = numericDataSort;
objArray.refresh();
//Create the new series and set its properties.
localSeries.dataProvider = objArray;
localSeries.yField = "people";
localSeries.xField = "date";
//Back up the current series on the chart.
var currentSeries:Array = lineChart.series;
//Add the new series to the current Array of
//series.
currentSeries.push(localSeries);
//Add the new Array of series to the chart.
lineChart.series = currentSeries;
cb1.dataProvider = objArray;
}
//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>";
s += "No. of People: " + e.item.people;
return s;
}
]]>
</fx:Script>
<s:VGroup width="100%"
height="100%"
verticalAlign="middle"
horizontalAlign="center">
<s:BorderContainer width="100%"
height="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:LineChart id="lineChart"
gutterTop="0"
gutterLeft="50"
showDataTips="true"
width="80%"
height="80%"
dataTipFunction="myDataTipFunction">
<mx:horizontalAxis>
<mx:DateTimeAxis dataUnits="days" id="dateAxis"
alignLabelsToUnits="true"/>
</mx:horizontalAxis>
</mx:LineChart>
</s:HGroup>
<s:BorderContainer width="100%"
height="100%"
id="canvas"
mouseEnabled="false"
backgroundAlpha="0"
borderVisible="false"
mouseChildren="false">
<s:TextArea width="150"
height="50"
visible="false"
id="txtResult"/>
</s:BorderContainer>
</s:BorderContainer>
<s:HGroup width="100%"
verticalAlign="middle"
horizontalAlign="center">
<s:Label text="Select a Date:"/>
<s:ComboBox id="cb1"
change="cb1ChangeEvent(event)"/>
</s:HGroup>
</s:VGroup>
</s:Application>
* Click here for the demo shown in this post.^ Click here for the source files for the demo.
No comments:
Post a Comment