Flex Chart – Utiliser une dataFunction pour les structures de données complexes
Dans la plupart des cas, la data utilisée comme dataProvider d'un chart est assez plate. Par exemple, des objets contenant une seule série de champs:
{month: "Aug", close: 45.87, open:25.19}
Ou un XML contenant simplement un seul niveau de nœuds enfants dans une structure à plat:
<stock> <month>Aug</month> <close>45.87</close> <open>25.19</open> </stock>
Dans ces cas-là, vous assignez les champs du dataProvider aux items dans le Chart en utilisant les propriétés xField et yField pour les series, ou le categoryField pour les axes, comme par exemple:
<mx:ColumnSeries yField="close"/> <mx:CategoryAxis categoryField="month"/>
Cependant, la structure de donnée de votre chart peut être faîtes d'objets plus complexes, comme des objets à l'intérieur d'objets ou un XML avec plusieurs niveaux d'enfants. Par exemple, vous pourriez avoir des Object à l'intérieur d'un Object:
{month: "Aug", close: {High:45.87,Low:12.2}, open:25.19}
Ou utiliser des tags nested dans un objet XML:
<stock> <date> <month>Aug</month> </date> <price> <close>45.87</close> <open>25.19</open> </price> </stock>
Dans ces cas-là, vous ne pouvez pas faire référence à la data en utilisant une notation à plat comme yField="close". Vous ne pouvez pas non plus utilisant la notation point "dot notation". Par exemple, yField="values.close" ou categoryField="data.month" ne sont pas valides.
A la place, vous devez utiliser une méthode dataFunction pour définir quel champ de ChartItem sera peuplé par le dataProvider.
Pour la classe CategoryAxis, la dataFunction a la signature suivante:
function_name(axis:AxisBase, item:Object):Object
Où axis est la classe de base pour l'axe courant, et item est l'item du dataProvider.
Pour une classe Series, la dataFunction a la signature suivante:
function_name(series:Series, item:Object, fieldName:String):Object
Où series est une référence vers la series courante, item est l'item du dataProvider, et fieldName est le champ dans le ChartItem courant qui va être peuplé.
L'exemple suivant crée deux fonctions qui vont accéder à une donnée complexe à la fois pour les axes que pour les series:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%">
<mx:Script><![CDATA[
import mx.charts.chartClasses.AxisBase;
import mx.charts.chartClasses.Series;
import mx.charts.CategoryAxis;
import mx.charts.chartClasses.IAxis;
import mx.charts.chartClasses.ChartBase;
import mx.charts.chartClasses.CartesianTransform;
// This data provider contains complex, nested objects.
[Bindable]
public var SMITH:Array = [
{month: "Aug", close: {High:45.87,Low:12.2}, open:25.19},
{month: "Sep", close: {High:45.74,Low:10.23}, open:35.29},
{month: "Oct", close: {High:45.77,Low:12.13}, open:45.19},
{month: "Nov", close: {High:46.06,Low:10.45}, open:15.59},
];
private function dataFunc(series:Series, item:Object, fieldName:String):Object {
trace("fieldName: " + fieldName);
if(fieldName == "yValue" && series.id=="highClose"){
return(item.close.High);
}
else if(fieldName == "yValue" && series.id=="lowClose"){
return(item.close.Low);
}
else if(fieldName == "xValue"){
return(item.month);
}
else{
return null;
}
}
private function catFunc(axis:AxisBase, item:Object):Object {
for (var s:String in item) {
trace(s + ":" + item[s]);
}
return(item.month);
}
]]></mx:Script>
<mx:ColumnChart id="chart"
dataProvider="{SMITH}"
showDataTips="true"
width="100%"
height="100%"
>
<mx:horizontalAxis>
<!-- The dataFunction replaces "categoryField='month'. -->
<mx:CategoryAxis id="h1" dataFunction="catFunc"/>
</mx:horizontalAxis>
<mx:series>
<!-- The dataFunction replaces yField value, which cannot drill
down into an object (close.High is not valid). -->
<mx:ColumnSeries id="highClose"
displayName="Close (High)"
dataFunction="dataFunc"
/>
<!-- The dataFunction replaces yField value, which cannot drill
down into an object (close.Low is not valid). -->
<mx:ColumnSeries id="lowClose"
displayName="Close (Low)"
dataFunction="dataFunc"
/>
</mx:series>
</mx:ColumnChart>
</mx:Application>
Flex Source Code Download: Télécharger le code source complet de l'application
Articles similaires
- Flex Chart – Créer des Charts en ActionScript
- Flex Chart – Ajouter des Series à la volée en ActionScript
- Flex Chart – Comprendre l'utilisation des dataProvider
- Flex Chart – Utiliser un Array d'Object comme dataProvider (MXML)
- Flex Chart – Utiliser un Array d'Object comme dataProvider (ActionScript)
Aucun trackbacks pour l'instant






27 novembre 2009
Bonjour,
J'ai un petit problème :
J'ai 2 LineSeries à afficher dans un LineChart, et je veux donc afficher 2 courbes, à partir des valeurs provenant d'un fichier XML, mais sur lesquelles j'effectue des opérations préalablement.
Donc je crée ma propre dataFunction qui effectue les traitements sur les données.
Ensuite je l'assigne à mes lineSeries :
myLocalSeries1.dataFunction=myDataFunction;
myLocalSeries2.dataFunction=myDataFunction;
Seulement à l'exécution rien ne s'affiche dans le graphe, pourtant quand je trace ce que renvoie myDataFunction, tout va bien elle se déclenche et renvoie bien les bonnes données.
Des idées ?
Merci beaucoup
AnSo
27 novembre 2009
Un peu de code peut etre ? ici si tu veux ou par email (voir en bas de la page)
Fabien
30 novembre 2009
(je recommence avec les balises, ce sera peut-être plus lisible)
Voilà une partie de mon code :
Donc les courbes ne s'affichent pas, pourtant les traces de la dataFunction sont les bonnes.
Merci !!
1 décembre 2009
J'ai trouvé la solution : mon code est bon, il s'agissait d'un problème dans le fichier de données XML, qui était mal formé.