22 Replies Latest reply on Jul 2, 2008 1:58 PM by Developer504

    Using NumberFormatter with Charts

    Developer504 Level 1
      I'm trying to use the NumberFormatter with Charts, (with data source from HTTPService)

      Numbers are used for Category Axis or Linear Axis, coming from an XMLList, i.e.

      <mx:BarSeries displayName="Project" xField="@hours"

      How can I put a formatted version of @hours instead of just the raw unformatted number? For example I want to insert a comma so it displays "12,000" instead of "12000"

      I have figured out how to make a function to format / change the string variables such as the names etc., to some extent, but can't get the numberFormatter to work.

      I created this function:

      <mx:NumberFormatter id="numForm" useThousandsSeparator="true"/>

      But I can't figure out how to incorporate it into the numbers on my Charts, or in my DataGrid.

      I have found a few web examples which cover NumberFormatter...

      http://livedocs.adobe.com/flex/3/html/help.html?content=charts_formatting_13.html
      http://livedocs.adobe.com/flex/3/html/help.html?content=formatters_4.html
      http://blog.flexexamples.com/2007/12/13/rounding-numbers-in-flex-using-the-numberformatter -class/

      ...but they aren't accessing the data from external sources and I can't adapt the code to work with Charts.

      Any help would be highly appreciated.

      M.
        • 1. Re: Using NumberFormatter with Charts
          Developer504 Level 1
          The problem I'm running into seems to be related to having to use the XMLList data which is referred to via @ followed by the variable name.
          • 2. Re: Using NumberFormatter with Charts
            matthew horn Level 3
            For charting data, you'll need to create a data tip function to format the data. You've got the NumberFormatter syntax correct. So all you have to do in your data tip function is something like this:

            s = numForm.format(hd.item.hours);
            return s;

            There are examples of using data functions here:

            http://livedocs.adobe.com/flex/3/html/charts_displayingdata_08.html

            hth,
            matt horn
            flex docs
            • 3. Re: Using NumberFormatter with Charts
              matthew horn Level 3
              You could try using an XMLListCollection instead.
              • 4. Using NumberFormatter with Charts
                Developer504 Level 1
                Thanks,

                In this case I'm not talking about a datatip funtion, I'm already using that, (though still unable to use numberformatter there either)

                But I'm actually talking about formatting the numbers of the data in the Vertical or Horizontal Axis of a Bar Chart or a Column Chart. I want these to display using the ThousandsSeparator.
                • 5. Using NumberFormatter with Charts
                  Developer504 Level 1
                  So are you basically suggesting there isn't a simple way to format the numbers on a chart ?
                  • 6. Re: Using NumberFormatter with Charts
                    VarioPegged Level 2
                    Use a labelFunction for the axis:

                    <mx:CategoryAxis categoryField="@hours" labelFunction="formatNumber"/>

                    private function formatNumber(catValue:Object, prevCategoryValue:Object, axis:CategoryAxis, catItem:Object):String
                    {
                    return numForm.format(catValue).toString();
                    }

                    TS
                    • 7. Using NumberFormatter with Charts
                      Developer504 Level 1
                      Ok Vario, I tried that and it compiles and runs but I'm still not getting any formatting.

                      Maybe the difference is I'm not trying to format the CategoryAxis which is a string (a name) but rather the BarSeries which is showing the numbers, I put it in as follows:

                      <mx:BarSeries displayName="Project" xField="@hours" labelFunction="formatNumber" />
                      • 8. Re: Using NumberFormatter with Charts
                        Developer504 Level 1
                        Can you think of any reason why I wouldn't get formatting? I'm still getting numbers with no thousands separator.
                        • 9. Re: Using NumberFormatter with Charts
                          Developer504 Level 1
                          I'm really getting frustrated with Flex, in some ways it's elegant but it seems so unecessarily complicated to do simple things. All I want to do here is format some ruddy numeric data with a comma. In most languages I've used this would be trivial. I've been fooling around with this for almost an entire day now. I have five books on Flex and none of them adequately cover this issue ... I'm not sure if the official Flex documentation covers it because it doesn't even have an index so it's basically impossible to find anything in there.

                          Yes, there is a lot of material available online - BUT

                          I'm running into a lot of cases with Flex where there is some kind of code example explaining how to do a relatively simple thing like this numeric formatting I'm wrestling with, but the sample code is always based on having your data hard-coded within your flex App. If you are getting data from an external source, which I can't be the only one doing, the examples don't work and usually require a completely different rewrite.

                          I also don't understand why every single component in Flex seems to require a different special method, usually involving importing a special component, just to do something as simple as using a formula in place of a variable in some object on your display.

                          M.
                          • 10. Re: Using NumberFormatter with Charts
                            VarioPegged Level 2
                            I'll give you that some things are unecessarily difficult in Flex, but how long have you used it? The API is VERY extensive. It may take you a long time to get a grasp all aspects of the program.

                            If it's not the CategoryAxis, then it's the LinearAxis.... add the following to that BarChart

                            <mx:horizontalAxis>
                            <mx:LinearAxis labelFunction="formatNumber" />
                            </mx:horizontalAxis>

                            TS
                            • 11. Re: Using NumberFormatter with Charts
                              VarioPegged Level 2
                              quote:

                              I also don't understand why every single component in Flex seems to require a different special method, usually involving importing a special component, just to do something as simple as using a formula in place of a variable in some object on your display.


                              I think that the Flex Team has done a very good job in creating a fairly unified environment in which to develop. At the surface, many of these components appear like they should use the same input, manipulation, or whatever, but there's no way that they can be uniform. Have you looked at the source? It may give you a greater understanding about what's going on underneath it all.

                              What you're experiencing in developing with Flex is the initial ease with which almost anyone can build a half-decent app, but you can't honestly expect that you're going to start customizing your app without having thorough knowledge of the API. This knowledge may only come through your own trials and errors. Certainly, you can understand that it's impossible for the documentation to include all use-cases.

                              TS
                              • 12. Using NumberFormatter with Charts
                                matthew horn Level 3
                                I'm sorry you're getting frustrated with Flex. It's easy to get overwhelmed by the docs and other resources available. There's a reason behind the madness. . . The charting apps have hard-coded data for two reasons:

                                1) We wanted to have running apps on livedocs. We didn't have a server we could put data on, so to have functioning apps, we needed to embed the data. Pretty soon, we'll have a server with MySQL that we'll be able to use with the sample Flex apps, so I'll probably be converting some of the examples to use HTTPService or some other classes to get the data.

                                2) It's easier to see what's going on with apps with embedded data. If (and when) we use apps with external data, there's additional information that we then have to put in the doc along with the sample code. By having a single app with its data embedded in it, users can also cut and paste it into Flex Builder and run the sample code immediately. Without that, users would have to set up their own data sources.

                                Now let's get down to business. Here's an example that uses an HTTPService to get data, and converts it to an XMLList. You should be able to just copy and paste this into Flex Builder and run it as is. Once you're comfortable with what's going on in this app, you can then change the source URL and remove most of the result handler logic, to use it with your own data source. That's in there because I only had an HTML data page to get data from, and not raw output.

                                Anyway, this example creates a NumberFormatter, and then uses that NumberFormatter to add thousands separators to all the values in the Y axis and the data tips by using the axis's labelFunction and the chart's dataTipFunction.

                                hth,
                                matt horn
                                flex docs

                                <?xml version="1.0"?>
                                <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" creationComplete="initApp();" height="300" width="300">
                                <mx:Script><![CDATA[
                                import mx.events.FlexEvent;
                                import mx.rpc.events.ResultEvent;
                                import mx.rpc.events.FaultEvent;
                                import mx.charts.chartClasses.IAxis;
                                import mx.charts.HitData;

                                [Bindable]
                                public var dataPage:String;

                                [Bindable]
                                public var chartData:XMLList;

                                private function initApp():void {
                                dataPage = Application.application.parameters.dataPage;

                                serviceInput.addEventListener(ResultEvent.RESULT, resultHandler);
                                serviceInput.addEventListener(FaultEvent.FAULT, faultHandler);
                                serviceInput.send();
                                }

                                public function resultHandler(evt:Event):void {
                                // Extract the XML data from the HTML page.
                                var htmlBlob:String = serviceInput.lastResult.toString();

                                htmlBlob = htmlBlob.slice( htmlBlob.indexOf("&lt;!-- data starts here --&gt;", 0) + 25, htmlBlob.length );
                                htmlBlob = htmlBlob.slice( 0, htmlBlob.indexOf("&lt;!-- data ends here --&gt;", 0) );

                                var tagPattern:RegExp = /<[^<>]*>/g;
                                htmlBlob = htmlBlob.replace(tagPattern, "");

                                var ltPattern:RegExp = /&lt;/g;
                                htmlBlob = htmlBlob.replace(ltPattern, "<");

                                var gtPattern:RegExp = /&gt;/g;
                                htmlBlob = htmlBlob.replace(gtPattern, ">");

                                // Create an XMLList from the extracted XML data.
                                chartData = new XMLList(htmlBlob);
                                }

                                public function faultHandler(evt:Event):void {
                                trace(evt.toString());
                                }

                                private function myLabelFunction(catValue:Object, prevCategoryValue:Object, axis:IAxis):String {
                                return nf1.format(catValue).toString();
                                }

                                private function dtFunc(hd:HitData):String {
                                return nf1.format(hd.item.misc);
                                }
                                ]]></mx:Script>

                                <mx:NumberFormatter id="nf1" useThousandsSeparator="true"/>

                                <mx:HTTPService id="serviceInput"
                                resultFormat="text"
                                url=" http://examples.adobe.com/flex3/exchangingdata/html/dataPage.html"
                                />

                                <mx:LineChart id="chart" dataProvider="{chartData}" dataTipFunction="dtFunc" showDataTips="true" height="100%" width="100%">
                                <mx:series>
                                <mx:LineSeries id="series1" yField="misc" xField="month"/>
                                </mx:series>

                                <mx:horizontalAxis>
                                <mx:CategoryAxis categoryField="month"/>
                                </mx:horizontalAxis>

                                <mx:verticalAxis>
                                <mx:LinearAxis labelFunction="myLabelFunction"/>
                                </mx:verticalAxis>

                                </mx:LineChart>
                                </mx:Application>
                                • 13. Re: Using NumberFormatter with Charts
                                  Developer504 Level 1
                                  Thanks Vario, thats not working, for some reason it won't let me put a horizontalAxis on this control as I've set it up.

                                  <mx:BarChart x="{this.width * 0.0125}" y="{this.height * 0.45}" id="TopProjects" height="50%" dataProvider="{tpDs}" width="50%" showDataTips="True" fontSize="10" dataTipFunction="dtFunc2">
                                  <mx:verticalAxis>
                                  <mx:CategoryAxis categoryField="@prName" />
                                  </mx:verticalAxis>
                                  <mx:series>
                                  <mx:BarSeries displayName="Project" xField="@hours" labelFunction="formatNumber" fill="{sc1}"
                                  stroke="{s1}">
                                  </mx:BarSeries>
                                  </mx:series>
                                  </mx:BarChart>

                                  I've tried inserting linearAxis but it doesn't seem to like it.


                                  As for Flex, you make a good point, I'm still very new to it, and I've been able (with a lot of help from this forum) to get some nice Apps up and running very quickly. It's just wierd how some major things can be done so swiftly but simple things like this are so tricky.

                                  But you are right it's probably just a matter of familiarity with the immense API.

                                  M.
                                  • 14. Using NumberFormatter with Charts
                                    Developer504 Level 1
                                    Thanks a lot Matt I'll digest this

                                    I certainly understand why you made the examples as they are, I think all you really need to do is put in some sections with a brief review of the changes needed for reading data from HTTSerrvice, external XML file or coldfusion or whatever, a little text box with five or six lines would probably be sufficient.

                                    I do agree the online documentaiton of Flex has been very extensive, it has been quite helpful to me since I've been using Flex. It's a lot better than the printed documentation. I am just a little frustrated at the complexity of certain aspects of the environment.

                                    M.
                                    • 15. Re: Using NumberFormatter with Charts
                                      matthew horn Level 3
                                      I want to be sure you've seen this page:

                                      http://livedocs.adobe.com/flex/3/html/help.html?content=charts_intro_8.html

                                      It's a big page, but it has just about every way I could think of to include data in a charting app.

                                      Like I said, we hope to convert some of the charting examples to use real time data, but these things take tim. But, you're voicing your concerns adds that much more leverage I'll have to make the case. :)

                                      matt horn
                                      flex docs
                                      • 16. Using NumberFormatter with Charts
                                        VarioPegged Level 2
                                        This works for me. The fact that you're getting your data via a service shouldn't make any difference.

                                        TS
                                        • 17. Re: Using NumberFormatter with Charts
                                          Developer504 Level 1
                                          Thanks guys that works.

                                          M.
                                          • 18. Re: Using NumberFormatter with Charts
                                            Developer504 Level 1
                                            So what if you want to format a number in a datagrid? Can you do something similar?
                                            • 19. Re: Using NumberFormatter with Charts
                                              VarioPegged Level 2
                                              Why yes you can... and it's also using a labelFunction, but this time of the DataGridColumn. Look at the specific requirements for the function in the docs, but for the most part the principle is exactly the same as what we've shown you for the charts.

                                              TS
                                              • 21. Re: Using NumberFormatter with Charts
                                                VarioPegged Level 2
                                                Not a problem.

                                                TS