2 Replies Latest reply on Jun 24, 2010 8:51 PM by rootsounds

    Multiple axes scaling in PlotChart (or any CartesianChart)

    DHM 23

      When I programmatically create a PlotChart starting w/ no series and adding series w/ own scaling and verticalAxes (and Renderers but not necessary for behavior error), the axes and data show, but the default axis controls all scaling and the other axes are erroneous. Thus, the yValue magnitudes do not correspond to their associated axes and mixing series w/ grossly different orders of magnitude squishes all but the largest into indistinguishable floor values. I cannot null out the default vertical axis as it gets an null pointer error. [Click anywhere on the chart to add the next series.]

       

      What am I doing wrong?

       

      package
      {
           /*
           * Attempt to dynamically create graph w/ varying series. Having difficulty getting scaling per dimension 
           * on sets of series. 
           *
           */
           import flash.events.MouseEvent;
           
           import mx.charts.AxisRenderer;
           import mx.charts.DateTimeAxis;
           import mx.charts.LinearAxis;
           import mx.charts.PlotChart;
           import mx.charts.chartClasses.Series;
           import mx.charts.events.ChartEvent;
           import mx.charts.series.PlotSeries;
           import mx.collections.ArrayCollection;
      
           public class GraphSample extends PlotChart
           {
                public function GraphSample()
                {
                     super();
                     this.selectionMode = "single";
                     this.percentWidth = 80;
                     this.series = new Array();
                     this.verticalAxisRenderers = new Array();
                     this.showDataTips = true;
                }
      
                protected override function createChildren():void {
                     super.createChildren();
                     
                     // Create the horizontal axis
                     var hAxis:DateTimeAxis = new DateTimeAxis();
                     hAxis.dataUnits = "days";
                     this.horizontalAxis = hAxis; 
                     
                     // NOTE: I do not want an automatically created verticalAxis, but can't seem to avoid it
                                    // Add vertical axis renderer
                     var axis:AxisRenderer = new AxisRenderer();
                     axis.axis = this.verticalAxis;
                     axis.horizontal = false;
                     axis.setStyle("showLabels", true);
                     axis.setStyle("showLine", true);
                     this.verticalAxisRenderers.push(axis);
                     this.verticalAxisRenderers = this.verticalAxisRenderers;
                     
                     this.addEventListener(ChartEvent.CHART_CLICK, addSeries);
                }
      
                private var seriesColors:Array = [0x888888, 0xFFC833, 0xFF6433, 0xE73399, 
                     0x8133CC, 0x346B9B, 0x33C399, 0x98F133];
                private var seriesColorCursor:int = 0;
                
                private const ONE_DAY:Number = (1000 * 60 * 60 * 24);
                private const TODAY:Date = new Date();
      
                private function addSeries(event:MouseEvent):void {
                     var dimension:Object = newDimension();
                     
                     var series:Series = new PlotSeries(); 
                     series.displayName = dimension.name;
                     series.dataFunction = genericFieldRetriever;
                     series.setStyle("fill", seriesColors[seriesColorCursor++]);
                     if (seriesColorCursor > seriesColors.length) seriesColorCursor %= seriesColors.length;
      
                     series.dataProvider = dimension.elements;
                     this.series.push(series);
                     
                     
                     var seriesAxis:LinearAxis = new LinearAxis();
                     series.setAxis("verticalAxis", seriesAxis);
                     var min:Number = Number.MAX_VALUE, max:Number = 0;
                     for each (var ele:Object in series.dataProvider) {
                          if (ele.value > max) max = ele.value;
                          if (ele.value < min) min = ele.value;
                     }
                     seriesAxis.minimum = min * 0.85;
                     seriesAxis.maximum = max * 1.2;
                     seriesAxis.displayName = series.displayName;
                     seriesAxis.title = series.displayName;
                     
                     // Add vertical axis renderer
                     var axis:AxisRenderer = new AxisRenderer();
                     axis.axis = seriesAxis;
                     axis.horizontal = false;
                     axis.setStyle("color", series.getStyle("fill"));
                     axis.setStyle("showLabels", true);
                     axis.setStyle("showLine", true);
                     this.verticalAxisRenderers.push(axis);
                     //AxisRenderer(this.verticalAxisRenderers[0]).setStyle("showLine", false);
                     //AxisRenderer(this.verticalAxisRenderers[0]).setStyle("showLabels", false);
                     this.verticalAxisRenderers = this.verticalAxisRenderers;
                     // also strokes?
                     
                     
                     
                     // http://www.flexdeveloper.eu/forums/flex-charting/creating-linecolumn-series-dynamically/
                     this.series = this.series;
                     this.invalidateSeriesStyles();
                     
                     if (names.length == 0) this.removeEventListener(ChartEvent.CHART_CLICK, addSeries);
                }
                
                /**
                 * A fake of the server data retrieval mechanism. 
                 * @return wrapper w/ name and elements set where each element has a data and value.
                 */
                private function newDimension():Object {
                     var result:Object = new Object();
                     result['name'] = names.shift();
                     var elements:ArrayCollection = new ArrayCollection();
                     var thisBase:int = base.shift();
                     var thisMax:int = maxAdd.shift();
                     for (var date:Date = new Date(TODAY.getTime() - 10 * ONE_DAY); date.getTime() <= TODAY.getTime(); date = new Date(date.getTime() + ONE_DAY)) {
                          var element:Object = new Object();
                          element['date'] = date;
                          element['value'] = thisBase + Math.random() * thisMax;
                          elements.addItem(element);
                     }
                     result['elements'] = elements;
                     return result;
                }
                private var names:Array = ['fat', 'carbs', 'steps', 'walking miles', 'pounds', 'cycling miles', 'running miles', 'skiing hours', 'lifting mins'];
                private var base:Array = [0, 20, 1000, 0, 100, 0, 0, 0, 0];
                private var maxAdd:Array = [100, 200, 9000, 4, 200, 40, 8, 3, 75];
                
      
                private function genericFieldRetriever(series:Series, item:Object, fieldName:String):Object {
                      if(fieldName == 'yValue')
                          return(item.value);
                      else if(fieldName == "xValue")
                          return(item.date);
                      else
                          return null;
                }     
      
      /*
      * Test graphColor
      * Test various graph types as series
      */
      
           }
      }