Filtering unique values in a Flex Chart

19. December 2008 22:59

Continuing my discussion on filtering, I would like to talk about complex Flex Chart filtering/grouping at runtime.  Now the majority of ASDoc docmentation, and other examples do a great job of demonstrating the filtering of chart series wheneach series is based on a different value in the array collection or xmlListcolelction.  But what happens when you need to create series based on a single filed but want eeach series to be of a unique value in the data set?  Not many examples demonstrating means of accomplishing this.  Hence.. this post.

So here is the scenario.  You have a generic data structure where a given property can hold different values.  Instead of creating your series on the entire collection, you want to break your set into individual groups by unique values in one of the properties.  For example:

private var ac:ArrayCollection = new ArrayCollection([
{id=1, year:"2005", color:"Red", value:2},
{id=2, year:"2005", color:"Green", value:5},
{id=3, year:"2005", color:"Blue", value:5},
{id=4, year:"2006", color:"Red", value:4},
{id=5, year:"2006", color:"Green", value:10},
{id=6, year:"2006", color:"Blue", value:5}]);

Now, what we want to display are 2 (or more) iterated series grouped together by color. 




The biggest issue I ran into was dealing with the series creation when you didnt know how many series are needed at runtime.  If you know the number of series, you can easily create them at compile time, but when your data is unknown, it is a little more complicated.  In this case, you need to loop through the data provider to determine the number of ColumnSeries needed and create/modify them at runtime.

Here is an example of how to do this.  This isn't the only way, but merely one way to accomplish the creation of the series by group at runtime.  You can also use a grouping collection, but I had trouble actually implementing the grouping collection.  There is a property on the groupingcollection called newCollection that would be PERFECT for this action but it is private so you can't extend it or access it.  Bummer.  Anyway, this is one solution.

private function buildSeries():void
            {

                var serArray:Array = new Array();
                var tempInterval:ArrayCollection = new ArrayCollection();
                var tempCats:ArrayCollection = new ArrayCollection();
                try
                {
                    for each(var item:Object in myColl)
                    {
                        if(tempInterval.contains(item.year))
                        {

                           // Do nothing here.  The item already exists in the temporary collection.

                         }
                        else
                        {
                            tempInterval.addItem(item.year);  // This is the field you are using to create the series

                            var itemColl:Array = new Array();
                            var series:ColumnSeries = new ColumnSeries();
                            series.yField = "value";
                            series.displayName = item.year;
                            series.setStyle("showDataEffect", slideIn);
                            series.setStyle("rollOverEffect", glowIn);
                            series.setStyle("rollOutEffect", glowOut);
                            series.interactive = true;
                           
                            for each(var obj:Object in myCollection)
                            {
                                if(obj.year == item.year)
                                {
                                    itemColl.push(obj);
                                }
                            }
                            series.dataProvider = itemColl;
                            serArray.push(series);                   
                        }
                       
                        if(tempCats.contains(item.Color))
                        {}
                        else
                        {
                            tempCats.addItem(item.Color);
                        }
                    }                   
                    chtColumn.series = serArray;
                   
                    var aStroke:Stroke = new Stroke(0x666666, 1);
                    aStroke.alpha = 0.6;
                   
                    var hAxis:CategoryAxis = new CategoryAxis();
                    hAxis.dataProvider = tempCats;
                    hAxis.title = "Competencies";
                   
                   
                    var vAxis:LinearAxis = new LinearAxis();
                    vAxis.baseAtZero = true;
                    vAxis.title = "Quantatative Value";                   
                   
                    chtColumn.horizontalAxis = hAxis;
                    chtColumn.verticalAxis = vAxis;
                }catch(e:Error)
                {
                    trace(e.message);
                    throw new Error("Error building series: "+e.message);
                }           
            }



 that's it.  Basically you are looping through the values in the collection and adding the unique value to a temporary collection.  You then create the series for that item in the colelction.  So for each year, you create the series and set the properties/styles for that series, then you create the individual data providers for the series by looping agin to extract the values that match each unique value in the temporary collection.  Push each series into the chart.series property and you are golden.

Good luck.

Currently rated 3.5 by 2 people

  • Currently 3.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments


Log in