Flex Chart – Modifier la donnée en temps réel, basculement de Series
Dans le dernier article, je montrais un exemple dans lequel on pouvait ajouter et supprimer des points de data d'un Chart. Vous pouvez aussi changer les champs associés aux Series pour changer la donnée d'un Chart en temps réel (at runtime).
Pour cela, il faut changer la valeur du champ du dataProvider (comme xField et yField) sur l'objet Series. Pour obtenir une référence vers une Series, vous pouvez utiliser son id ou y accéder par le tableau series du Chart si vous connaissez son index.
L'exemple suivant bascule entre deux data series quand l'utilisateur clique sur le bouton:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" initialize="initApp();">
<mx:Script><![CDATA[
[Bindable]
public var dataSet:Array;
public var myStates:Array =
["Wisconsin","Ohio","Arizona","Penn"];
public var curSeries:String;
public function initApp():void {
var newData:Array = [];
for(var i:int=0;i<myStates.length;i++) {
newData[i] = {
Apples: Math.floor(Math.random()*150),
Oranges: Math.floor(Math.random()*150),
myState: myStates[i]
}
}
dataSet = newData;
curSeries = "apples";
}
public function changeData():void {
var series:Object = myChart.series[0];
if (curSeries == "apples") {
curSeries="oranges";
series.yField = "Oranges";
series.displayName = "Oranges";
series.setStyle("fill",0xFF9933);
} else {
curSeries="apples";
series.yField = "Apples";
series.displayName = "Apples";
series.setStyle("fill",0xFF0000);
}
}
]]></mx:Script>
<mx:Panel title="Column Chart">
<mx:ColumnChart id="myChart"
dataProvider="{dataSet}"
showDataTips="true"
>
<mx:horizontalAxis>
<mx:CategoryAxis
dataProvider="{dataSet}"
categoryField="myState"
/>
</mx:horizontalAxis>
<mx:series>
<mx:ColumnSeries
yField="Apples"
displayName="Apples"
>
<mx:fill>
<mx:SolidColor color="0xFF0000"/>
</mx:fill>
</mx:ColumnSeries>
</mx:series>
</mx:ColumnChart>
<mx:Legend dataProvider="{myChart}"/>
</mx:Panel>
<mx:Button id="b1"
label="Basculer les Series"
click="changeData()"
/>
</mx:Application>
Flex Source Code Download: Télécharger le code source complet de l'application
Flex Chart – Modifier la donnée en temps réel, ajout de points de data à un ArrayCollection
Dans l'exemple précédent, je montrais un exemple qui permet de changer le dataProvider d'un Chart à la volée. On va maintenant voir comment conserver le dataProvider original, mais en lui ajoutant simplement des points quand l'utilisateur clique sur un bouton:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" viewSourceURL="srcview/index.html">
<mx:Script><![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var dpac:ArrayCollection = new ArrayCollection([
{A:2000},
{A:3000},
{A:4000},
{A:4000},
{A:3000},
{A:2000},
{A:6000}
]);
public function addDataItem():void {
var o:Object = {"A":2000};
dpac.addItem(o);
}
private function removeItem():void {
var i:int = dpac.length;
if (i > 0) {
dpac.removeItemAt(i - 1);
}
}
]]></mx:Script>
<mx:Panel title="Column Chart">
<mx:ColumnChart id="myChart"
showDataTips="true"
height="400"
width="600"
dataProvider="{dpac}"
>
<mx:series>
<mx:ColumnSeries yField="A" displayName="Series 1"/>
</mx:series>
</mx:ColumnChart>
<mx:Legend dataProvider="{myChart}"/>
</mx:Panel>
<mx:HBox>
<mx:Button label="Ajouter un Data Item" click="addDataItem();"/>
<mx:Button label="Supprimer un Data Item" click="removeItem();"/>
</mx:HBox>
</mx:Application>
Flex Source Code Download: Télécharger le code source complet de l'application
Flex Chart – Modifier la donnée en temps réel, changement de dataProvider
En utilisant de l'ActionScript, vous pouvez changer la data d'un Chart à l'exécution (runtime) de plusieurs manières. Vous pouvez changer le dataProvider d'un Chart ou d'une Series.
L'exemple suivant fait une correspondance (Binding) entre la propriété dataProvider et une variable locale. Un bouton permet ensuite de basculer de dataProvider en utilisant cette variable locale.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script><![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var expenses:ArrayCollection = new ArrayCollection([
{Month:"Jan", Profit:2000, Expenses:1500, Amount:450},
{Month:"Feb", Profit:1000, Expenses:200, Amount:600},
{Month:"Mar", Profit:1500, Expenses:500, Amount:300}
]);
[Bindable]
public var expenses2:ArrayCollection = new ArrayCollection([
{Month:"Jan", Profit:2400, Expenses:1509, Amount:950},
{Month:"Feb", Profit:3000, Expenses:2200, Amount:400},
{Month:"Mar", Profit:3500, Expenses:1200, Amount:200}
]);
[Bindable]
public var dp:ArrayCollection = expenses;
public function changeDataProvider():void {
if (dp==expenses) {
dp = expenses2;
} else {
dp = expenses;
}
}
]]></mx:Script>
<mx:Panel title="Line Chart">
<mx:LineChart id="myChart" dataProvider="{dp}" showDataTips="true">
<mx:horizontalAxis>
<mx:CategoryAxis
dataProvider="{dp}"
categoryField="Month"
/>
</mx:horizontalAxis>
<mx:series>
<mx:LineSeries
yField="Profit"
displayName="Profit"
/>
<mx:LineSeries
yField="Expenses"
displayName="Expenses"
/>
<mx:LineSeries
yField="Amount"
displayName="Amount"
/>
</mx:series>
</mx:LineChart>
<mx:Legend dataProvider="{myChart}"/>
</mx:Panel>
<mx:Button id="b1"
label="Changer de Data Provider"
click="changeDataProvider()"
/>
</mx:Application>
Flex Source Code Download: Télécharger le code source complet de l'application
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
Flex Chart – Générer des données aléatoires pour remplir un dataProvider
Si vous voulez tester tous les types de chart, il va vous falloir de la donnée à afficher. Pour cela, vous pouvez écrire de la donner en dur ou bien écrire quelques lignes d'ActionScript qui vont vous générer cette donnée en aléatoire.
L'exemple suivant génère de la donnée de test afin qu'elle soit utilisée avec un composant Chart. En l'occurrence, on va remplir le dataProvider d'un PlotChart avec des Object contenant des données aléatoires:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()" viewSourceURL="srcview/index.html">
<mx:Script><![CDATA[
import mx.collections.*;
// Define data provider array for the chart data.
[Bindable]
public var dataSet:ArrayCollection;
// Define the number of elements in the array.
public var dsLength:Number = 10;
public function initApp():void {
// Initialize data provider array.
dataSet = new ArrayCollection(genData());
}
public function genData():Array {
var result:Array = [];
for (var i:int=0;i<dsLength;i++) {
var localVals:Object = {
valueA:Math.random()*100,
valueB:Math.random()*100,
valueX:Math.random()*100,
valueY:Math.random()*100
};
// Push new object onto the data array.
result.push(localVals);
}
return result;
}
]]></mx:Script>
<mx:Panel title="Plot Chart">
<mx:PlotChart id="myChart" dataProvider="{dataSet}" showDataTips="true">
<mx:series>
<mx:PlotSeries
xField="valueX"
yField="valueY"
displayName="Series 1"
/>
<mx:PlotSeries
xField="valueA"
yField="valueB"
displayName="Series 2"
/>
</mx:series>
</mx:PlotChart>
<mx:Legend id="l1" dataProvider="{myChart}"/>
</mx:Panel>
</mx:Application>
Flex Source Code Download: Télécharger le code source complet de l'application





