3 Replies Latest reply on Dec 28, 2009 8:04 PM by Gregory Lafrance

    Manipulation of Line Series in Line Chart at runtime

    klmanion Level 1

      I'm using Flex Builder 3 and I'm having trouble identifying chart objects in ActionScript at runtime.

       

      I have a line chart that contains 1 curve that doesn't change (referred to as StaticCurve in code below), and a variable number of other curves (referred to as RealTimeCurves in code below).  I run this chart from a ColdFusion application.  The user selects which dynamic curves they want to display before running the chart.  The chart displays all series just fine when I first run it, but I'm having trouble dynamically updating the real-time curves on subsequent refreshes.

       

      The init() function populates the chart when it first runs.  I'm then attempting to update the chart by pressing the "Update Data" button.  This button calls the getRealTimeCurveList() function of my CFC file in order to retrieve the updated curve list and their datapoints.  I then loop through this array of curves.  If the curve already exists in the chart, I only want to update its data.  If it doesn't exist, it will create a new one. 

       

      My problem is that the ActionScript never finds the curves that already exist.  It always creates new copies of the curve.  I think my problem is caused by the way I'm trying to refer to the existing curve:

            if (myLineChart.series[curve.ID]) {

      This IF condition always drops into the ELSE portion, as I never see the "curve FOUND" message.  It always displays "curve NOT FOUND" and proceeds to create a new line.

       

      I want to be able to either delete the existing line OR better yet, update the existing line's dataProvider.  Would appreciate any advice you guys have!

       

      Thanks,

      Kevin

       

      Here is my code:

      <?xml version=”1.0” encoding=”utf-8”?>

      <mx:Application xmlns:mx=http://adobe.com/2006/mxml layout=”absolute” creationComplete=”init()”>

       

                  <mx:Script source=”../src/commonFunctions.as”/>

                  <mx:Script>

                              <![CDATA[

                                          import mx.rpc.events.ResultEvent;

                                          import mx.charts.renderers.*;

                                          import mx.collections.*;

                                          import mx.charts.*;

       

                                          [Bindable]

                                          public var staticCurveList:ArrayCollection;

       

                                          private function init():void

                                          {

                                                      myCfc.getStaticCurveData();

                                                      myCfc.getRealTimeCurveList();

                                          }

       

                                          private function getRealTimeCurveListHandler(event:ResultEvent):void

                                          {

                                                      var i:int;

                                                      var curveList:ArrayCollection;

                                                      var newSeries:LineSeries;

                                                      curveList = new ArrayCollection(event.result as Array);

                                                      for (var idx:Object in curveList)

                                                      {

                                                                  try {

                                                                              //Loop through the array of curves retrieved from the ColdFusion Session.CurveList var, populated by remote object call.

                                                                              //Need to get displayName and datapoints for each curve selected by user for display in chart

                                                                              var curve:Object = curveList[idx];

                                                                              if (curve.DATAPOINTS.length > 0)

                                                                              {

                                                                                          if (myLineChart.series[curve.ID]) {

                                                                                                       Alert.show(“Curve FOUND”);

                                                                                                       //if this curve already exists in chart, update its data by resetting the dataProvider

                                                                                                       myLineChart.series[curve.ID].dataProvider = curve.DATAPOINTS;

                                                                                          }

                                                                                          else {

                                                                                                       Alert.show(“Curve NOT FOUND”);

                                                                                                       //define new line series based on current curve in the array

                                                                                                       newSeries = new LineSeries();

                                                                                                       newSeries.id = curve.ID;

                                                                                                       newSeries.name = curve.ID;

                                                                                                       newSeries.displayName = curve.NAME;

                                                                                                       //set data source to the new datapoint array found in remote object

                                                                                                       newSeries.dataProvider = curve.DATAPOINTS;

                                                                                                      //map y-axis data to yData column of remote object DATAPOINT array

                                                                                                       newSeries.yField = “YDATA”

                                                                                                       //map x-axis data to xData column of remote object DATAPOINT array

                                                                                                       newSeries.xField = “XDATA”

                                                                                                       //add the new series to the chart

                                                                                                       var currentSeries:Array = myLineChart.series;

                                                                                                       currentSeries.push(newSeries);

                                                                                                       myLineChart.series = currentSeries;

                                                                                                       application.addChild(newSeries);  //ad object to DisplayList

                                                                                          }

                                                                              }

                                                                  } catch (e:Error) {

                                                                              Alert.show(“An error occurred: “ + e.message);

                                                                  }

                                                      }

                                          }

       

                                          private function getStaticCurveDataHandler(event:ResultEvent):void {

                                                      staticCurveList = new ArrayCollection(event.result as Array);

                                          }

                              ]]>

                  </mx:Script>

       

                  <mx:RemoteObject id=”myCfc” destination=”Coldfusion” source=”webroot.FlexData”>

                              <mx:method name=”getRealTimeCurveList” result=”getRealTimeCurveListHandler(event)” fault=”myFaultHandler(event)”/>

                              <mx:method name=”getStaticCurveData” result=”getStaticCurveDataHandler(event)” fault=”myFaultHandler(event)”/>

                  </mx:RemoteObject>

       

                  <mx:Legend dataProvider=”{myLineChart}”/>

       

                  <mx:LineChart id=”myLineChart”>

                              <mx:series>

                                          <mx:LineSeries id=”StaticCurve” displayName=”Static Curve”

                                                                  dataProvider=”{staticCurveList}”

                                                                  yField=”yData” xField=”xData” />

                              </mx:series>

                  </mx:LineChart>

                  <mx:Button label=”Update Data” click=”myCfc.getRealTimeCurveList();”/>

      </mx:Application>

       

       

        • 1. Re: Manipulation of Line Series in Line Chart at runtime
          Gregory Lafrance Level 6

          What is curve.ID in the data coming from the server?

           

          It might be good to use hard coded data for the update, eliminating the server call, and boil this down into a simpler test case posted here so we can actually see the issue in running code.

           

          If this post answers your question or helps, please mark it as such.


          Greg Lafrance
          www.ChikaraDev.com

          Flex Development, Training, and Support Services

           

          1 person found this helpful
          • 2. Re: Manipulation of Line Series in Line Chart at runtime
            klmanion Level 1

            Thanks for the response Greg.  Curve.ID translates to a string identifier being set on the ColdFusion side, where the curve is being selected for display.  For my test case, I have 2 curves in the array coming over from the server.  Their ID's are "curve1' and "curve2".  I've verified this to be true on the Flex side by displaying the value of curve.ID via an Alert statement.

             

            I've only been working with Flex for about a month.  I should probably ask a couple more general questions here without focusing on the specifics of my code:

            1) How do you refer to an object in ActionScript when you don't know what its id is until runtime? As you can see, I'm trying to dynamically do it with myLineChart.series[curve.ID] but I'm not sure if this is right.  In ColdFusion, I do it with the EVALUATE function, but I can't find anything comparable in ActionScript.  It looks like there used to be an eval() function in ActionScript that might have done it, but it was deprecated.  So how do I ensure that [curve.ID] is getting translated into the value of that variable?

             

            2) Should I be attempting to remove the existing curves (that I want to update) from the movie displayList and then recreate them?  Like I said, I'm pretty new to Flex and I'm not very familiar with displayList manipulation.  It seems to me like I should be able to work directly with the object though.

             

            Again, thank you for the help!

            • 3. Re: Manipulation of Line Series in Line Chart at runtime
              Gregory Lafrance Level 6

              Hi there,

               

              I'm not exactly sure how you would access the series via something like

              myLineChart.series[curve.ID]. You might need to create a lookup hash table

              to get the series index.

               

              Regarding removing the curves, I guess it depends. If they are just

              children of the displayList, I guess you could just edit their properties.

              I think it is best to as this in the forum so others can comment as well.

              I'll check there for more context.

               

              Greg