.NET

30 mar, 2009

Adobe Flex – Como colocar gráficos em repeater

Publicidade

Estou desenvolvendo um modelo de Dashboard de Indicadores de Performace (KPI) utilizando o Adobe Flex, Asp.NET e SQL Server 2000.

Nesse Dashboard eu precisava exibir vários gráficos de acordo com o
perfil de cada usuário. Por isso, construir um modelo fixo não seria
possível. Então busquei maneiras de fazer isso utilizando o mx:Tile e o
mx:Repeater.

Na busca encontrei apenas um exemplo de
Datagrid em um Repeater, com isso foi possível construir o modelo para
utilizar com Gráficos.

Primeiro é preciso entender a estrutura de DataProvider, necessária para que tudo funcione como o esperado.

Como na figura acima, o DataProvider é um ArrayCollection composto
de um ArrayCollection para cada gráfico que será exibido no Repeater,
cada um desse segundo ArrayCollection é composto por objetos que serão
os pontos dos gráficos.

Abaixo está o código responsável pela configuração do ArrayCollection, que será o DataProvider do mx:Repeater.

<mx:Script>
<![CDATA[
import mx.utils.ObjectProxy;
import mx.core.Application;
import mx.utils.ObjectUtil;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.collections.ArrayCollection;
 
//ArrayCollection que será o DataProvider do Repeater
[Bindable]
private var arDadosGraficoTotal:ArrayCollection = new ArrayCollection();
 
private function load():void
{
var arDadosGrafico:ArrayCollection;
var obDadosGrafico:ObjectProxy;
 
//Gráfico 1
//arDadosGrafico recebe um novo ArrayCollection
arDadosGrafico = new ArrayCollection();
//obDadosGrafico recebe um novo ObjectProxy
obDadosGrafico = new ObjectProxy();
//Cria a propriedade data1 e atribiu o 10, data1 será uma série no gráfico
obDadosGrafico.data1 = 10;
//Cria a propriedade data2 e atribiu o 5, data2 será outra série no gráfico
obDadosGrafico.data2 = 05;
//Cria a propriedade label e atribiu 'Jan', label será o eixo X do gráfico
obDadosGrafico.label = 'Jan';

//Cria a propriedade titulo e atribiu 'Vendas', titulo será o titulo do
gráfico, só existirá essa propriedade no primeiro ObjectProxy
obDadosGrafico.titulo = 'Vendas';
//Adiciona o ObjectProxy obDadosGrafico ao ArrayCollection arDadosGrafico
arDadosGrafico.addItem(obDadosGrafico);
 

//obDadosGrafico recebe um novo ObjectProxy e receberá os mesmas
propriedades porém com valores distintos e também é inserido ao
ArrayCollection arDadosGrafico
obDadosGrafico = new ObjectProxy();
obDadosGrafico.data1 = 05;
obDadosGrafico.data2 = 05;
obDadosGrafico.label = 'Fev';
arDadosGrafico.addItem(obDadosGrafico);
 
obDadosGrafico = new ObjectProxy();
obDadosGrafico.data1 = 03;
obDadosGrafico.data2 = 05;
obDadosGrafico.label = 'Mar';
arDadosGrafico.addItem(obDadosGrafico);
 
obDadosGrafico = new ObjectProxy();
obDadosGrafico.data1 = 06;
obDadosGrafico.data2 = 05;
obDadosGrafico.label = 'Abr';
arDadosGrafico.addItem(obDadosGrafico);
 

//Quando terminam os pontos do gráfico é necessário inserir o
ArrayCollection arDadosGrafico ao ArrayCollection arDadosGraficoTotal
arDadosGraficoTotal.addItem(arDadosGrafico);
 

//Os passos anteriores devem ser feitos para cada gráfico que se deseja
exibir no Dashboard, abaixo estão identificos como Gráfico 2 e Gráfico 3
//Gráfico 2
arDadosGrafico = new ArrayCollection();
obDadosGrafico = new ObjectProxy();
obDadosGrafico.data1 = 07;
obDadosGrafico.data2 = 02;
obDadosGrafico.label = 'Jan';
obDadosGrafico.titulo = 'Custos';
arDadosGrafico.addItem(obDadosGrafico);
 
obDadosGrafico = new ObjectProxy();
obDadosGrafico.data1 = 08;
obDadosGrafico.data2 = 02;
obDadosGrafico.label = 'Fev';
arDadosGrafico.addItem(obDadosGrafico);
 
obDadosGrafico = new ObjectProxy();
 
 
 
 
obDadosGrafico.data1 = 05;
obDadosGrafico.data2 = 02;
obDadosGrafico.label = 'Mar';
arDadosGrafico.addItem(obDadosGrafico);
 
obDadosGrafico = new ObjectProxy();
obDadosGrafico.data1 = 04;
obDadosGrafico.data2 = 02;
obDadosGrafico.label = 'Abr';
arDadosGrafico.addItem(obDadosGrafico);
 
arDadosGraficoTotal.addItem(arDadosGrafico);
 
//Gráfico 3
arDadosGrafico = new ArrayCollection();
obDadosGrafico = new ObjectProxy();
obDadosGrafico.data1 = 10;
obDadosGrafico.data2 = 08;
obDadosGrafico.label = 'Jan';
obDadosGrafico.titulo = 'Produção';
arDadosGrafico.addItem(obDadosGrafico);
 
obDadosGrafico = new ObjectProxy();
obDadosGrafico.data1 = 12;
obDadosGrafico.data2 = 08;
obDadosGrafico.label = 'Fev';
arDadosGrafico.addItem(obDadosGrafico);
 
obDadosGrafico = new ObjectProxy();
obDadosGrafico.data1 = 06;
obDadosGrafico.data2 = 08;
obDadosGrafico.label = 'Mar';
arDadosGrafico.addItem(obDadosGrafico);
 
obDadosGrafico = new ObjectProxy();
obDadosGrafico.data1 = 08;
obDadosGrafico.data2 = 08;
obDadosGrafico.label = 'Abr';
arDadosGrafico.addItem(obDadosGrafico);
 
arDadosGraficoTotal.addItem(arDadosGrafico);
 

//Ao terminado de incluir todos os arDadosGrafico ao
arDadosGraficoTotal, é necessário declarar arDadosGraficoTotal como
dataProvider do repeater
rpGrafico.dataProvider = arDadosGraficoTotal;
}
 
]]>
</mx:Script>

Abaixo está o código necessário para exibir os gráficos. Inicialmente foi utilizado um Tile e dentro um Repeater. Dentro do
Repeater há um Panel e dentro do Panel está o gráfico que deve ser
exibido de acordo com o dataProvider.

Como demonstrado acima, o dataProvider é associado ao término da
função load(). Após a associação, o Repeater começará a renderizar o
primeiro gráfico, e já no título do Panel o valor atribuído será a
propriedade título definida no primeiro objeto do arDadosGrafico.

Para isso é utilizada a instrução:
{rpGrafico.currentItem.getItemAt(0).titulo}, ou seja, rpGrafico é o
Repeater, a propriedade currentItem contém o arDadosGrafico do laço em
questão e getItemAt(0) assegura que só buscará a propriedade título no
primeiro objeto dentro do arDadosGrafico.

Para o gráfico, só resta associar um dataProvider a ele para que
sejam exibidos os seus pontos. O dataProvider em questão será o
currentItem do Repeater rpGrafico, pois como dito acima, a propriedade
currentItem contém o arDadosGrafico do laço em questão.

No eixo X, horizontalAxis, é definido label como o campo fonte dos
dados. No eixo Y, verticalAxis, está configurado para não começar em
zero. Logo abaixo estão as duas séries, uma para o data1 (Indicador
Técnico) e outra para data2 (Meta).

<mx:Tile left="10" right="10" top="10" bottom="10" direction="horizontal">
<mx:Repeater id="rpGrafico" width="100%">
<mx:Panel width="250" height="200" layout="absolute" id="pnGrafico" title="{rpGrafico.currentItem.getItemAt(0).titulo}">

<mx:LineChart id="grIndicador" dataTipMode="single"
showDataTips="true" dataProvider="{rpGrafico.currentItem}" width="95%"
height="95%" horizontalCenter="0" verticalCenter="0">
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="label" />
</mx:horizontalAxis>
<mx:verticalAxis>
<mx:LinearAxis baseAtZero="false"/>
</mx:verticalAxis>
<mx:series>
<mx:LineSeries form="segment" yField="data2" displayName="Meta"/>
 
<mx:LineSeries form="segment" yField="data1" displayName="Indicador Técnico"/>
</mx:series>
</mx:LineChart>
</mx:Panel>
</mx:Repeater>
</mx:Tile>

Antes de executar o projeto e ver tudo funcionando legal, é
necessário adicionar o código abaixo na segunda linha do código dentro
da tag mx:Application

creationComplete=”load()”

Deixando-a assim:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="load();">

Execute o projeto, você deve obter um resultado igual a imagem abaixo.

Complementando?

Para incluir as legendas basta adicionar logo após o gráfico o código abaixo:

<mx:Legend dataProvider="{grIndicador[0]}" bottom="10" left="10" right="10" height="25"/>

Divirta-se!