Wednesday, November 28, 2012

Empty String != null

For some of us out there, we might be assigning an empty string to various types of variables thinking that nothing might go wrong. However, that isn't the case. For different types of objects / components and for different types of variables or properties, by assigning an empty string might give you some unnecessary troubles. For example...

Time for some source codes: ImageSourceIssue.mxml


 
 
  
 
 
 
  
 
 
  
   
  
  
  
  
   
   
   
   
   
   
   
   
   
   
  
  
   
   
  
  
  
 


If you are using firebug or Charles or any other types of Web Developer Tools, you can easily identify the differences in the results for the 3 buttons. :)

* Click here for the demo shown in this post.
^ Click here for the source files for the demo.

Thursday, November 22, 2012

Which 1 is better 4 / 7 / 10 ?

Approximately a week ago, Google has released it's fourth Nexus-branded Android smartphone. As I was looking at the specifications of Nexus 4, I was drooling. Too bad I don't have a lot of spare money to go around purchasing it. (I probably will end up holding on to my Nexus 3 till the release of Nexus 5. :P)


Logo taken from the 'Google Nexus' website.

* Click here for the website of 'Google Nexus'.

Saturday, November 17, 2012

Creating a Favi Icon for your web site

If you are a web developer or for some reason you need to grab a favion from a website, you might encounter some cross browser issues. (Trust me, this can be quite annoying sometimes. Some Favi Icon might appear in some browsers, but on some other browsers it does not. You will be pretty amazed with the number of web sites that have this issue. =="")


Image taken from the website of 'favion.ico generator'.
Therefore, I will grab the favicon that I'm getting from website
and do a import and re-export the favicon to generate a new
favicon that can work for most of the browser.

Alternatively, you can create a new favicon for your website
through this website too.

* Click here for the website of 'favion.ico generator'.

Friday, November 9, 2012

Flex: Playing with multiple column chart

Well, I was trying to figure out how to render multiple column chart some time back. After spending a few days playing around it, I finally found a way to work around it. :)

Tim for some source files - 'SimpleMultipleColumn.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.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;
     }
    }
   }
   
  ]]>
 </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%"
           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:VGroup>
</s:Application>
* Click here for the demo shown in this post.
^ Click here for the source files for the demo.

Saturday, November 3, 2012

Android: Simple XML Parsing

Probably due to the fact that I have been playing or working with XML (e4x) for a very long period of time, therefore it makes things pretty hard when I'm jumping backwards to the old way of parsing xml. After spending a bit of time looking through numerous tutorials and my previous codes, here's a simple xml parsing project that I have created.

'Screen grab of my XML Parsing Project'
Basically, upon running the app, it will copy an XML into your android
device. Upon a successful copying of the file, I will read the contents
of the XML file and display them in a TextView.
(Because I'm combining some of my previous tutorial with this, therefore
it's difficult for me to show all the source files in this post. I would
highly suggest that you download the source files and look through the
source codes and the comments that I have added.)

* Click here for the source files of the project.
^ Click here for the 'Android XML Parsing Tutorial' that I have referenced.