2010-03-22 12 views
5

Nel grafico flessibile, Voglio disegnare qualcosa come "linee di riferimento" che sono relative a serie specifiche, quindi queste righe non sono serie indipendenti e non dovrebbero essere mostrate nella legenda. È possibile escludere alcune serie dalla legenda del grafico? Grazie!Come escludere le serie nella legenda (Flex)

risposta

7

È possibile escludere alcune serie dalla legenda del grafico.

Ogni classe di grafico (estensione di ChartBase) ha una proprietà legend Array di dati. Questa legendaData ha una lista di LegendItem. Se crei un nuovo array basato su legendData, ma con solo il LegendItem che desideri; quindi puoi impostare quell'array come dataProvider per la tua legenda.

Inoltre, è possibile creare il proprio array di LegendItem basato su LegendItems creato da zero. E usa quella matrice come dataProvider per la legenda.

Per esempio, qui mi mostra solo la prima e la terza serie nel mio leggenda:

<mx:Script> 
    <![CDATA[ 
     private function cc(event:Event):void 
     { 
      var newArray:Array = new Array(); 
      newArray.push(myChart.legendData[0]); 
      newArray.push(myChart.legendData[2]); 

      myActionScriptLegend.dataProvider = newArray; 
     } 
    ]]> 
</mx:Script> 

<mx:ColumnChart id="myChart"> 
    <mx:series> 
     <mx:ColumnSeries id="series0"/> 
     <mx:ColumnSeries id="series1"/> 
     <mx:ColumnSeries id="series2"/> 
    </mx:series> 
</mx:ColumnChart> 
<mx:Legend dataProvider="{[myChart.legendData[0],myChart.legendData[2]]}" /> 
<mx:Legend id="myActionScriptLegend" creationComplete="cc(event)" /> 

http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/ChartBase.html#legendData
http://livedocs.adobe.com/flex/3/langref/mx/charts/LegendItem.html
http://livedocs.adobe.com/flex/3/html/charts_displayingdata_12.html#330954

+0

Grazie! È anche disponibile in ActionScript? –

+1

Ho fornito una seconda legenda (id = "myActionScriptLegend"), che fa la stessa cosa in ActionScript. Spero possa aiutare. –

+0

Grazie Luis, mi ha aiutato a risolvere il problema che stava uccidendo molto del mio tempo – Anoop

10

ho elaborato sulla risposta di Luis B per rendere questo riflettere in modo dinamico su il fornitore di dati del linechart. In questo modo la legenda mostra solo quali campi sono disponibili nel grafico. Abbastanza elegante

Ecco quello che mi è venuta, e funziona bene:

 protected function onUpdateLinechartComplete(e:FlexEvent):void 
     { 

      //empty legend for fresh display 
      var legendArray:Array = new Array(); 
      legend1.dataProvider = legendArray; 

      //filter Legend data so that only LineSeries with data can be shown 
      for(var i:int=0; i< linechart1.legendData.length; i++) { 

       //if data is found in the line series, let's add it to the chart legend data provider, so it can be displayed in the legend 
       if (linechart1.legendData[i].element.items.length != 0) { 
        legendArray.push(linechart1.legendData[i]); 
       } 

      } 
      legend1.dataProvider = legendArray; 
      legend1.direction = "vertical"; 
     } 



//in the page Initialize function, I add a listener event to the linechart component for when the legend update completes so it can filter lineseries on the legend's dataprovider in [onUpdateLegendComplete] 
linechart1.addEventListener(FlexEvent.UPDATE_COMPLETE, onUpdateLinechartComplete); 

ho finito per dover utilizzare un EventHandler e allegando un listener di eventi al Linechart stesso. Questo perché ho riscontrato "condizioni di gara" con il fornitore di dati della legenda. Qualche cosa funzionerebbe, a volte no. Utilizzando l'evento Listener ha eliminato questo problema e filtra solo la legenda quando il grafico ha completato il caricamento dei suoi dati.

SENTIRE GRATIS PER AVVIARE QUESTA RISPOSTA, FLEX FLEX !!

+1

Mi piace. Probabilmente l'altra risposta è veramente corretta per l'OP, ma questo è ciò di cui ho bisogno. – Fletch

4

OK un'altra versione della risposta di devtron, se si dispone già di una classe Linechart personalizzato in ogni caso, come ho, poi mettere questo in:

[Bindable] public var activeLegendData:Array; 

// this goes in an initialize handler 
addEventListener(FlexEvent.UPDATE_COMPLETE, onUpdateChartComplete); 

protected function onUpdateChartComplete(e:FlexEvent):void { 
    activeLegendData = new Array(); 
    for(var i:int=0; i < legendData.length; i++) { 
     if (legendData[i].element.items.length != 0) { 
      activeLegendData.push(legendData[i]); 
     } 
    } 
} 

Poi si vincolare il proprio dataprovider leggenda per linechart.activeLegendData invece di Linechart.

Il vantaggio di questa soluzione rispetto a Devtron è che non è necessario riscrivere il codice ogni volta che si inserisce un altro modulo nella propria app.

+0

Non vedo come questo sia diverso dalla mia risposta, a parte il fatto che non leghi esplicitamente la leggenda? – D3vtr0n

1

Un'altra alternativa ...

derivare una nuova classe da una delle classi serie di grafico, quindi sovrascrivere il getter per legendData() e restituire un array vuoto. Ecco un esempio per PlotSeries:

public class PlotSeriesNoLegend extends PlotSeries 
{ 
    public function PlotSeriesNoLegend() 
    { 
     super(); 
    } 

    override public function get legendData():Array /* of LegendData */ 
    { 
     return [ ]; 
    } 
} 
0

Alcuni commenti sulle risposte precedenti. Quando ci si riferisce a creare un nuovo array per usarlo come legenda, fare attenzione perché non è come descritto.Per me funziona in questo modo:

Quando si tenta di accedere a un valore esistente in pie.legendData, è necessario farlo in questo modo: pie.legendData [0] [0] o pie.legendData [0] [1] ]

Inoltre, per ottenere questi dati in un nuovo array e utilizzarlo per creare la nuova legenda, è necessario attendere che la torta sia già stata creata.

Per questo uso semplicemente l'evento di rendering della torta.

Spero che ti aiuti.

Problemi correlati