Friday, August 24, 2012

Flex: The not so global ToolTipManager...

I was playing around the ToolTipManager class today and I realised that the ToolTipManager class isn't so global after all. Although you can use ToolTipManager.enabled to show/hide all the tooltips but...

Here the source codes of my main application - NotReallyGlobalTooltip.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"
      creationComplete="creationCompleteHandler(event)"> 
 <fx:Script>
  <![CDATA[
   import mx.charts.series.ColumnSeries;
   import mx.collections.ArrayCollection;
   import mx.events.FlexEvent;
   import mx.managers.ToolTipManager;
   
   
   //Records used in the chart
   [Bindable]
   private var myData:XML = 
    <records>
     <record>
      <month>Jan</month>
      <car>73</car>
     </record>
     <record>
      <month>Feb</month>
      <car>72</car>
     </record>
     <record>
      <month>Mar</month>
      <car>79</car>
     </record>
     <record>
      <month>Apr</month>
      <car>80</car>
     </record>
     <record>
      <month>May</month>
      <car>51</car>
     </record>
    </records>;
   
   protected function btnGlobalToolTipEvent(event:MouseEvent):void
   {
    //Toggle the visibility of the Tooltips for all the 
    //components except the charts 
    ToolTipManager.enabled = !ToolTipManager.enabled;
    updateBtns();
   }
   
   protected function btnChartToolTipEvent(event:MouseEvent):void
   {
    //Toggle the visibility of the Tooltips for all the 
    //items in the charts
    chartMain.showDataTips = !chartMain.showDataTips;
    updateBtns();
   }
   
   protected function btnSuperToolTipEvent(event:MouseEvent):void
   {
    //Toggle the visibility of the Tooltips for all the 
    //components and the charts and sync them
    if(ToolTipManager.enabled == chartMain.showDataTips)
    {
     ToolTipManager.enabled = !ToolTipManager.enabled;
     chartMain.showDataTips = !chartMain.showDataTips;
    }else{
     ToolTipManager.enabled = false;
     chartMain.showDataTips = false;
    }
    updateBtns();
   }
   
   protected function creationCompleteHandler(event:FlexEvent):void
   {
    updateBtns();
   }
   
   //This function will updates all the labels of the buttons.
   private function updateBtns():void
   {
    if(ToolTipManager.enabled == chartMain.showDataTips)
    {
     if(ToolTipManager.enabled)
     {
      btnSuperToolTip.label = 
       "All ToolTips Enabled";
     }else{
      btnSuperToolTip.label = 
       "All ToolTips Disabled";
     }
    }else{
     btnSuperToolTip.label = 
      "All ToolTips Mixed";
    }
    
    if(ToolTipManager.enabled)
    {
     btnGlobalToolTip.label = 
      "Global ToolTip Enabled";
    }else{
     btnGlobalToolTip.label = 
      "Global ToolTip Disabled";
    }
    
    if(chartMain.showDataTips)
    {
     btnChartToolTip.label = 
      "Chart ToolTip Enabled";
    }else{
     btnChartToolTip.label = 
      "Chart ToolTip Disabled"; 
    }
   }
  ]]>
 </fx:Script>
 <s:VGroup width="100%" height="100%" gap="10" 
     horizontalAlign="center" verticalAlign="middle">
  <mx:ColumnChart id="chartMain" dataProvider="{myData.record}">
   <mx:horizontalAxis>
    <mx:CategoryAxis 
     categoryField="month"/>
   </mx:horizontalAxis>
   <mx:verticalAxis>
    <mx:LinearAxis 
     minorInterval="10"
      maximum="100"/>
   </mx:verticalAxis>
   <mx:series>
    <mx:ColumnSeries 
     yField="car" 
     displayName="No Of Cars."/>
   </mx:series>  
  </mx:ColumnChart>
  <s:HGroup gap="10">
   <mx:Text text="Some Dummy Text with Tooltip" 
      toolTip="A empty tooltip"/>
   <s:Button label="Button"
       toolTip="that does nothing"/>
  </s:HGroup>
  <s:Spacer height="10"/>
  <mx:Text htmlText="Click on the buttons below and rollover
     <br>the components in the above to see the differences."
     textAlign="center"/>
  <s:HGroup gap="10">
   <s:Button id="btnGlobalToolTip"
       width="200" 
       click="btnGlobalToolTipEvent(event)"/>
   <s:Button id="btnChartToolTip"
       width="200" 
       click="btnChartToolTipEvent(event)"/>
   <s:Button id="btnSuperToolTip"
       width="200" 
       click="btnSuperToolTipEvent(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.

Wednesday, August 15, 2012

Generating Dummy Data for Testing

Sometimes it can be a quite troublesome coming up with a set of dummy data for testing out a set of programming codes. It can be even much more tiring where you wanted to test out a large quantity of data. I was googling around and I found...


'generatedata.com'
This sites seems to be pretty useful in generating dummy data.
You can also choose your desired Result Type (html, sql, xml, etc...)
and the type of Data Type that you are using (date, string,
auto incrementing number, postal codes, etc...). Lesser time needed
in entering or generating dummy data in the future. Woohoo~~~

* Click here to find out more about 'generatedata.com'.
^ Click here to generate your first set of dummy data now.

Sunday, August 12, 2012

Flex: Playing with the horizontal axis of a chart

I was playing with charts the other day and there was a requirement which requires me to find the minimum and the maximum points of the chart. Therefore, I have came up with this demo to help you is understanding charts better. :D

Source of the main application file - SimpleChartHorizontalAxis.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="absolute" 
    minWidth="800"
     creationComplete="completeHandler(event)">
 <mx:Script>
  <![CDATA[
   import mx.charts.HitData;
   import mx.charts.series.LineSeries;
   import mx.collections.ArrayCollection;
   import mx.collections.Sort;
   import mx.collections.SortField;
   import mx.events.FlexEvent;
   import mx.events.ListEvent;
   import mx.formatters.DateFormatter;
   
   //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 minDate:Date = null;
   private var maxDate:Date = null;
   
   private var minSelDate:Date = null;
   private var maxSelDate:Date = null;
   
   private var dateCollection:ArrayCollection;
   
   protected function completeHandler(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]);
     parseDate(tempDate);
     tempObj.date = tempDate;
     tempObj.time = tempDate.time;
     tempObj.people = myData.record[i].people;
     objArray.addItem(tempObj);
    }
     
    // Create the new series and set its properties.
    var localSeries:LineSeries = new LineSeries();
    localSeries.dataProvider = objArray;
    localSeries.yField = "people";
    localSeries.xField = "date";
    
    // Back up the current series on the chart.
    var currentSeries:Array = mainChart.series;
    // Add the new series to the current Array of series.
    currentSeries.push(localSeries);
    // Add the new Array of series to the chart.
    mainChart.series = currentSeries;
    
    //We are creating the options for the combo box or
    //drop down menu over here.
    dateCollection = new ArrayCollection();
    tempDate.time = minDate.time;
    var tempDate2:Date = new Date();
    tempDate2.time = maxDate.time;
    tempDate2.date = 1;
    tempDate2.month += 1;
    while (tempDate.time <= tempDate2.time)
    {
     tempObj = new Object;
     tempObj.label = dateFormatter(tempDate);
     tempObj.date = tempDate.time;
     dateCollection.addItem(tempObj);
     tempDate.month += 1;
    }
    cb1.dataProvider = dateCollection;
    cb1.selectedIndex = 0;
    cb2.dataProvider = dateCollection;
    cb2.selectedIndex = dateCollection.length - 1;
    
    //Assigning the Minimum and the Maximum value
    //of the horizontal axis
    dateAxis.minimum = minDate;
    dateAxis.maximum = maxDate;
   }
   
   //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);
   }
   
   //This function will be used in finding the minimum
   //and the maximum Date of the data. And based on the
   //minimum Date, we will round off to the first day
   //of the month and last day of the month for the
   //maximum date.
   private function parseDate(tempDate:Date):void
   {
    if(minDate == null)
    {
     minDate = new Date();
     minDate.time = tempDate.time;
     minDate.date = 1;
    }else{
     if(minDate.time > tempDate.time)
     {
      minDate.time = tempDate.time;
      minDate.date = 1;
     }
    }
    if(maxDate == null)
    {
     maxDate = new Date();
     maxDate.time = tempDate.time;
     maxDate.date = 1;
     maxDate.month += 1;
     maxDate.date = 0;
    }else{
     if(maxDate.time < tempDate.time)
     {
      maxDate.time = tempDate.time;
      maxDate.date = 1;
      maxDate.month += 1;
      maxDate.date = 0;
     }
    }
   }
   
   //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;
   }
   
   //Upon changing the values of the combobox, we will
   //set the minimum and maximum data of the chart 
   //based on the combobox selections
   protected function changeHandler(event:ListEvent):void
   {
    minSelDate = new Date();
    minSelDate.time = cb1.selectedItem.date;
    maxSelDate = new Date();
    maxSelDate.time = cb2.selectedItem.date;
    if(minSelDate.time < maxSelDate.time)
    {
     dateAxis.minimum = minSelDate;
     dateAxis.maximum = maxSelDate;
    }else{
     dateAxis.minimum = maxSelDate;
     dateAxis.maximum = minSelDate;
    }
   }
   
   //Upon clicking on the 'Reset' button, we will
   //update the values of the comboxbox and the chart.
   protected function clickHandler(event:MouseEvent):void
   {
    cb1.selectedIndex = 0;
    cb2.selectedIndex = dateCollection.length - 1;
    dateAxis.minimum = minDate;
    dateAxis.maximum = maxDate;
   }
   
  ]]>
 </mx:Script>
 <mx:VBox verticalGap="5" width="100%" height="100%" 
    verticalAlign="middle">
  <mx:HBox width="100%" horizontalAlign="center">
   <mx:LineChart id="mainChart" 
        showDataTips="true" 
        width="95%" 
        dataTipFunction="myDataTipFunction" >
    <mx:horizontalAxis>
     <mx:DateTimeAxis dataUnits="days" id="dateAxis" 
          alignLabelsToUnits="true"/> 
    </mx:horizontalAxis>
   </mx:LineChart>
  </mx:HBox>
  <mx:HBox width="100%" horizontalAlign="center">
   <mx:Label text="Display Data between"/>
   <mx:ComboBox id="cb1" change="changeHandler(event)"/>
   <mx:Label text="and"/>
   <mx:ComboBox id="cb2" change="changeHandler(event)"/>
  </mx:HBox>
  <mx:HBox width="100%" horizontalAlign="center">
   <mx:Button label="Reset" click="clickHandler(event)"/>
  </mx:HBox>
 </mx:VBox>
</mx:Application>
* Click here for the demo shown in this post.
^ Click here for the source files for the demo.

Saturday, August 4, 2012

Flex: Mac OS X, Mouse Wheel Detection

For some reason, mouse wheel scrolling doesn't really work on a Mac. Therefore after doing a bit of Googling or searching on the Internet, I finally found an ideal solution to my troubles.

* Click here for the demo that was created by pixelbreaker.
^ Click here for the post on Mac OS X, Mouse Wheel Detection by pixelbreaker.