O Primefaces é uma biblioteca que entende o JSF, seguindo o mesmo ciclo e modelo da especificação, porém o Primefaces introduz componentes mais sofisticados que permitem tornarem as aplicações muito mais ricas. Para baixar o Primefaces basta visitar o site Prime User Interface e ir na seção downloads. Para baixar o Primefaces utilizando o Maven podemos usar a dependência presente na Listagem 1.


<dependency>
   <groupId>org.primefaces</groupId>  
   <artifactId>primefaces</artifactId>  
   <version>5.0</version>  
</dependency>
Listagem 1. Dependência do do Maven

Copie o arquivo jar do PrimeFaces para pasta WEB-INF/lib do projeto e adicione ao classpath do projeto. No site do Primefaces também encontramos a especificação completa e exemplos práticos de como utilizar a biblioteca. O Primefaces disponibiliza diversos componentes aos desenvolvedores como botões, breadcrumbs, calendários personalizados, campos de texto, campos de textos auto completar, ajax, captcha, imagens dinâmicas, menus, dialogs, tabelas, componentes drag and drop, mapas, gráficos, combos, multi-seleção e muito mais.

No restante do artigo focaremos nos componentes gráficos oferecidos pelo Primefaces introduzindo cada um deles e demonstrando um exemplo prático de como utilizar o Bar Chart e Pie Chart.

Gráficos do Primefaces

Os gráficos são utilizados para exibir informações gráficas aos usuários. Existem diversos tipos de gráficos como o Pie Chart (gráfico em forma de torta ou pizza), Bar Chart (gráfico de barras), Line Chart (gráficos de linhas) e muito mais. Veremos abaixo os gráficos que são disponibilizados pelo Primefaces aos desenvolvedores.

Pie Chart

O gráfico "Pie" ou "Torta" exibe as informações num gráfico em forma de uma torta conforme a Figura 1:

 Exemplo de um Pie Chart
Figura 1. Exemplo de um Pie Chart

Os principais atributos do Pie Chart são: id identifica unicamente o componente, rendered especifica a renderização do componente na qual se for falso não exibe o componente, value deve ser do tipo ChartModel que é definido no bean e exibe as informações no gráfico, style define informações sobre o estilo do gráfico como largura e altura, title define o título do gráfico, legendPosition define a posição da legenda no gráfico, seriesColors define as cores do gráfico no formato hexadecimal, diameter define o diâmetro do gráfico, porém se não definirmos nenhum valor ele calcula automaticamente o diâmetro mais adequado, sliceMargin define a distância entre as fatias do gráfico, showDataLabels mostra a informação em cada pedaço do gráfico, dataFormat espera um String para definir o formato das informações (o padrão é "percent"), extender define uma função no lado cliente para estender as funcionalidades do gráfico com opções de mais baixo nível.

A classe principal do Pie Chart é a org.primefaces.model.chart.PieChartModel e para exibir o gráfico na página utilizamos a tag presente na Listagem 2.


  <p:pieChart value="#{bean.model}" legendPosition=”w” />
Listagem 2. Exemplo de como exibir um Pie Chart na página

Line Chart

O gráfico de linha é utilizado para visualizarmos uma ou mais séries de informações em um gráfico de linha, conforme mostra a Figura 2.

 Exemplo de um Line Chart
Figura 2. Exemplo de um Line Chart

Os principais atributos do Line Chart são: id para identificar unicamente um componente, value deve ser do tipo ChartModel e contém as informações a serem exibidas no gráfico, title exibe o título do gráfico, legendPosition define a posição da legenda no gráfico, os atributos minY , maxY , minX e maxX definem os valores mínimos e máximos para cada um dos eixos, seriesColors define a cor das linhas do gráfico em forma hexadecimal, shadow define uma sombra no gráfico, fill é utilizado se quisermos preencher o gráfico abaixo das linhas, xaxisLabel para rotular o eixo x, yaxisLabel para rotular o eixo y, animate para animar o gráfico quando for impresso na tela.

Se definirmos os valores fill e stacked como true poderemos ter como resultado um gráfico um pouco diferente do gráfico acima. Segue na Figura 3 como ficaria o gráfico com esses dois valores definidos:

 Exemplo de um Line Chart com os atributos fill e stacked definidos
Figura 3. Exemplo de um Line Chart com os atributos fill e stacked definidos

A classe principal é a org.primefaces.model.chart.CartesianChartModel e para exibir o gráfico na página utilizamos a tag presente na Listagem 3.


  <p:lineChart value="#{bean.model}" legendPosition="e" />
Listagem 3. Exemplo de como exibir um Line Chart na página

Bar Chart

O gráfico de barras é utilizado para visualizarmos uma ou mais séries de informações usando barras conforme mostra a Figura 4:

 Exemplo de um Bar Chart
Figura 4. Exemplo de um Bar Chart

Os principais atributos são: value que recebe os valores a serem exibidos no gráfico, barPadding define o preenchimentos das barras (o valor padrão é 8), barMargin define a margem das barras (o valor padrão é 10), orientation define a orientação das barras podendo ser vertical ou horizontal , stacked habilita a exibição das barras empilhadas, seriesColors define as cores separadas por vírgulas e em formato hexadecimal para cada cor das barras.

Se utilizarmos a orientação como horizontal, teríamos como resultado o gráfico da Figura 5:

 Exemplo de um Bar Chart com a orientação horizontal definida.
Figura 5. Exemplo de um Bar Chart com a orientação horizontal definida

Outra mudança no gráfico é a utilização do atributo stacked conforme mostra a Figura 6.

 Exemplo de um Bar Chart com o atributo “stacked” definido
Figura 6. Exemplo de um Bar Chart com o atributo “stacked” definido

A classe principal é a org.primefaces.model.chart.CartesianChartModel e para exibir o gráfico na página utilizamos a tag da Listagem 4:


<p:barChart value="#{bean.model}" legendPosition="ne" />
Listagem 4. Exemplo de como exibir um Bar Chart na página

Donut Chart

O Donut Chart (ou gráfico de rosquinhas em português) é uma combinação de diversos Pie Charts conforme mostra a Figura 7:

 Exemplo de um Donut Chart
Figura 7. Exemplo de um Donut Chart

Os principais atributos são: value que espera um tipo ChartModel e é responsável por exibir os dados no gráfico, o atributo sliceMargin é responsável por definir a lacuna entre as fatias (por padrão o valor é zero), fill pode ser true ou false e é responsável por renderizar fatias mais fortes (sólidas), showDataLabels pode ser true ou false e exibe informações em cada fatia.

Se quisermos customizar mais o gráfico Donut Chart poderíamos mudar a posição da legenda para e do atributo legendPosition , o sliceMaargin para o valor 5, utilizar showDataLabels com o valor true , configurar dataFormat com o valor value ao invés de percent e shadow como false . Assim, teremos o gráfico da Figura 8:

 Exemplo de um Donut Chart mais customizado
Figura 8. Exemplo de um Donut Chart mais customizado

A classe principal é a org.primefaces.model.chart.DonutChartModel e para exibir o gráfico na página utilizamos a tag da Listagem 5:


<p:donutChart value="#{bean.model}" legendPosition=”w” />
Listagem 5. Exemplo de como exibir um Donut Chart na página

Bubble Chart

Através do Bubble Chart (ou gráfico de bolhas em português) podemos visualizar entidades que são definidas em termos de três valores numéricos distintos conforme mostra a Figura 9:

 Exemplo de um Bubble Chart
Figura 9. Exemplo de um Bubble Chart

Os principais atributos são: value que espera um tipo ChartModel e é responsável por exibir os dados no gráfico, o atributo title define o título do gráfico, bubbleGradients pode ser true ou false e habilita o preenchimento gradiente ao invés de cores planas, bubbleAlpha define a transparência alfa de um bubble (o padrão é 70), showLabels pode ser true ou false e exibe rótulos nos botões, zoom pode ser true ou false e habilita zoom no gráfico (por padrão é false).

A classe principal é a org.primefaces.model.chart.BubbleChartModel e para exibir o gráfico na página utilizamos a tag da Listagem 6:


<p:bubbleChart value="#{bean.model}" xaxisLabel=”Preço” 
yaxisLabel=”Vendas” title=”Exemplo de um Bubble Chart”/>
Listagem 6. Exemplo de como exibir um Bubble Chart na página

Ohlc Chart

O gráfico Ohlc Chart (Open-High-Low-Close Chart) é um tipo de gráfico utilizado para visualizar os movimentos dos preços ao longo do tempo, por isso é muito utilizado nas ferramentas financeiras. A Figura 10 abaixo mostra um exemplo de um Ohlc Chart:

 Exemplo de um Ohlc Chart
Figura 10. Exemplo de um Ohlc Chart

Os principais atributos são: value que espera um tipo ChartModel e é responsável por exibir os dados no gráfico, o atributo title define o título do gráfico, candleStick altera o modo de visualização das informações, "zoom" permite o recurso de zoom no gráfico, "animate" habilita animação no gráfico.

Para customizar o gráfico podemos utilizar o atributo candleStick que altera o modo de exibição do gráfico, conforme podemos visualizar na Figura 11:

 Exemplo de um Ohlc Chart customizado
Figura 11. Exemplo de um Ohlc Chart customizado

A classe principal é a org.primefaces.model.chart.OhlcChartModel e para exibir o gráfico na página utilizamos a tag da Listagem 7:


<p:ohlcChart value="#{bean.model}" xaxisLabel=”Ano” 
yaxisLabel=”Preço” title=”Exemplo de um Ohlc Chart”/>
Listagem 7. Exemplo de como exibir um Ohcl Chart na página

MeterGauge Chart

O gráfico MeterGauge Chart é um tipo de gráfico utilizado para visualizar informações em um medidor de quilometragem conforme mostra a Figura 12 abaixo:

 Exemplo de um gráfico MeterGauge
Figura 12. Exemplo de um gráfico MeterGauge

Os principais atributos são: value que espera um tipo ChartModel e é responsável por exibir os dados no gráfico, o atributo title define o título do gráfico, showTickLabels mostra ticks em torno dos indicadores (por padrão é true ).

A classe principal é a org.primefaces.model.chart.MeterGaugeChartModel e para exibir o gráfico na página utilizamos a tag da Listagem 8:


<p:meterGaugeChart value="#{bean.model}" />
Listagem 8. Exemplo de como exibir um MeterGauge Chart na página

Alterando a Aparência dos Gráficos

Os gráficos são construídos sobre a biblioteca javascript jqPlot que usa canvas e pode ser estilizada através de css. Algumas das listas de classes de estilos que podemos utilizar são: .jqplot-target , .jqplot-axis , .jqplot-xaxis , .jqplot-yaxis , .jqplot-x2axis , .jqplot-x3axis , .jqplot-y2axis , .jqplot-y3axis , .jqplot-axis-tick , .jqplot-xaxis-tick , .jqplot-x2axis-tick , .jqplot-yaxis-tick , .jqplot-y2axis-tick , table.jqplot-table-legend , .jqplot-title , .jqplot-cursor-tooltip , .jqplot-highlighter-tooltip , div.jqplot-table-legend-swatch .

Uma forma de alto nível para acessar opções comumente utilizadas pelo jqPlot é utilizar o Extender que provê acesso a APIs de baixo nível para efetuarmos customizações avançadas como veremos nos exemplos a seguir.

Exemplo com Bar Chart

No exemplo da Listagem 9 mostraremos como construir um Bar Chart com Primefaces. Primeiramente na tela adicionaremos um botão que chamará um dialog . O dialog conterá o gráfico Bar Chart mostrando as cidades com o maior número de incidentes registrados num sistema:


<h:outputText value="Cidades com maior número de incidentes:" />
<p:commandButton validateClient="true" value="Mostrar"   
actionListener="#{relatoriosBean.geraRelatorioNumIncidentesMes}" 
oncomplete="dialogNumIncidentesPorCidade.show();" /> 
Listagem 9. Código com um commandButton que é responsável por chamar um método e exibir o gráfico gerado com Primefaces

No código acima temos uma chamada a um dialog que vai conter o gráfico a ser gerado. Podemos verificar também uma chamada a um método do bean, o método geraRelatorioNumIncidentesMes , que será responsável por criar os dados do gráfico. Segue na Listagem 10 como está codificado o bean com o método chamado no código acima:


package bean;

import java.io.Serializable;  
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.ChartSeries;
import dao.HibernateDAO;


@ManagedBean
@RequestScoped
public class RelatoriosBean implements Serializable {

     private CartesianChartModel model;
  
  
     public void geraRelatorioNumIncidentesMes() {
           criaModeloBarras();
     }
     
     //Método responsável por criar o gráfico de Barras
     public void criaModeloBarras() {
         model = new CartesianChartModel();

         HibernateDAO dao = new HibernateDAO();
         //Busca do Banco de Dados as cidades com o 
         número de incidentes. 
  //Filtramos apenas cidades com incidentes maior que 2.
         List<Object[]> listaNumeroDeIncidentes = 
         dao.listaNumeroDeIncidentes();
         
         ChartSeries cidadeGrafico;
         
         for (Object[] cidade : listaNumeroDeIncidentes) {
               cidadeGrafico = new ChartSeries();
               //Hibernate retorna os valores num array onde na
               //posição 0 temos o nome da cidade e na posição 1
               //temos a quantidade de incidentes.
               String label = String.valueOf(cidade[0]);
               String qtdeIncid = String.valueOf(cidade[1]);

               if (Integer.valueOf(qtdeIncid) > 1) {
                      cidadeGrafico.setLabel(label);
                      //Apenas do mês estar fixo podemos alterar para
                      //receber valor de um combo.
                      cidadeGrafico.set("Jul", Integer.
                      valueOf(qtdeIncid));
                      //Adiciona a cidade com seu valor ao gráfico
                      model.addSeries(comarca);
                  
               }
               
               cidadeGrafico = null;
         }
         
    FacesContext.getCurrentInstance().getExternalContext()
    .getSessionMap().put("model", this.model);

     }
     

     public void setModel(CartesianChartModel model) {
           this.model = model;
     }
     
     public CartesianChartModel getModel() { 
           //Retorna o modelo adicionado anteriormente na sessão
            CartesianChartModel model = (CartesianChartModel) 
            FacesContext.getCurrentInstance().getExternalContext()
            .getSessionMap().get("model");

            if (model != null)
                   return model;
     
            return new CartesianChartModel();
     }
     
}
Listagem 10. Código do bean responsável por criar o gráfico

Após criar a página e o bean que é responsável por criar o gráfico adicionando valores a ele, agora deveremos efetivamente mostrar o gráfico criado acima. Para isso criamos o dialog da Listagem 11 que será chamado após o método do bean acima ser completado:


<p:dialog header="Relatório" widgetVar="dialogNumIncidentesPorCidade" 
resizable="true" width="600" showEffect="explode" hideEffect="explode" dynamic="true"> 

   <h:form>
     <h:panelGrid columns="3" cellpadding="4" 
     styleClass="estiloPadrao">
        <p:barChart value="#{relatoriosBean.model}" 
        style="height:300px; width:800px;" legendPosition="ne" 
        orientation="horizontal" extender="ext" />
     </h:panelGrid>
   </h:form>

</p:dialog>
Listagem 11. Exibindo no dialog o gráfico criado anteriormente

No código acima utilizamos a tag p:barChart do Primefaces para criarmos o nosso gráfico de barras. No atributo value referenciamos a variável “model” criada anteriormente no nosso bean. A variável model é onde adicionamos as cidades com seus respectivos valores. No atributo style definimos as dimensões do nosso gráfico. O atributo legendPosition indica onde a legenda ficará posicionada em relação ao gráfico gerado. Por fim, utilizando o atributo extender podemos definir um javascript para customizar o nosso gráfico, nesse caso estamos chamando o javascript ext que tem seu código mostrado na Listagem 12:


<script type="text/javascript">
             
function ext() {  
this.cfg.highlighter = {useAxesFormatters: false, tooltipAxes: 'x'};
this.cfg.legend = {show: true, location: 'ne', placement: 'outside'}; 
}      
</script>
Listagem 12. Definindo outras características para o gráfico exibido utilizando uma função javascript

Na função acima definimos algumas coisas para melhorar um pouco a aparência do gráfico como a legenda fora da área do gráfico gerado e a posição ne da legenda em relação ao gráfico.

Na Figura 13 mostramos um exemplo da tela que chama o gráfico a ser gerado, essa tela é referente a listagem 8 apresentada anteriormente. Podemos verificar na figura abaixo que existe um combo, que não está na listagem, mas poderíamos utiliza-lo para modificar os meses dos incidentes que ocorreram nas respectivas cidades.

 Tela responsável por chamar o gráfico em barras da aplicação
Figura 13. Tela responsável por chamar o gráfico em barras da aplicação

Ao clicar no botão Mostrar é exibido o gráfico gerado no bean e customizado na página por meio dos atributos da tag e da função javascript. Segue na Figura 14 o gráfico gerado:

 Gráfico de barras gerado com base no bean e na página
Figura 14. Gráfico de barras gerado com base no bean e na página

Exemplo com Pie Chart

Para construir um Pie Chart o procedimento é muito semelhante ao Bar Chart. Primeiramente segue na Listagem 14 o código da página que exibirá o botão que devemos clicar para gerar o gráfico. O código é o mesmo que o do Bar Chart, no entanto, agora adicionamos mais um botão que será responsável por exibir o Pie Chart:


<h:outputText value="Cidades com maior número de incidentes:" />
  <p:commandButton validateClient="true" value="Mostrar" 
  actionListener="#{relatoriosBean.geraRelatorioNumIncidentesMes}" 
  oncomplete="dialogNumIncidentesPorCidade.show();" />
<h:outputText value="Total de incidentes por região:" />
<p:commandButton validateClient="true" value="Mostrar" 
actionListener="#{relatoriosBean.geraRelatorioIncidentesPorRegiao}" 
oncomplete="dialogIncidentesPorRegiao.show();" />
Listagem 14. Adição de mais um commandButton que é responsável por chamar um método e exibir o gráfico gerado com Primefaces

No código acima temos apenas mais uma chamada a um dialog ( dialogIncidentesPorRegiao ) que vai conter o gráfico a ser gerado. O método do bean ( geraRelatorioIncidentesPorRegiao ) será responsável por criar os dados do gráfico Pie Chart que mostrará os incidentes por região. Dessa forma, cada cidade do estado do Rio Grande do Sul que possui incidente será agrupada em uma determinada região na qual ela faz parte. Após isso faremos um gráfico acumulado que mostrará a distribuição de incidentes para cada região. Segue abaixo como está codificado o bean que possui o método chamado no código acima ( geraRelatorioIncidentesPorRegiao ). Os códigos adicionados na Listagem 15 para criar o Pie Chart estão todos comentados:


package bean;

import java.io.Serializable;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.ChartSeries;
import org.primefaces.model.chart.PieChartModel;
import dao.HibernateDAO;


@ManagedBean
@RequestScoped
public class RelatoriosBean implements Serializable {

     private CartesianChartModel model;

     //Adicionamos a variável de instância para o Pie
private PieChartModel modelPie;
  
     
     public void geraRelatorioNumIncidentesMes() {
           criaModeloBarras();
     }

     //Método chamado pela página para criar o gráfico Pie
     public void geraRelatorioIncidentesPorRegiao() {
           criaModeloPie();
     }

     //Aqui é onde efetivamente criaremos o gráfico Pie
     public void criaModeloPie() {

         modelPie = new PieChartModel();
         
         //Buscamos o número total de incidentes para cada cidade
         HibernateDAO dao = new HibernateDAO();
         List<Object[]> listaNumeroDeIncidentes = 
         dao.listaNumeroDeIncidentes();
        
         //Instanciamos as regiões que as cidades do Rio Grande do Sul 
  //poderão pertencer.
         int centrooeste = 0;
         int centroleste = 0;
         int nordeste = 0;
         int noroeste = 0;
         int metropolitana = 0;
         int sudeste = 0;
         int sudoeste = 0;
         
         for (Object[] cidade : listaNumeroDeIncidentes) {
               
               String label = String.valueOf(cidade[0]);
               String qtdeIncid = String.valueOf(cidade[1]);

               //Regiao Centro-Oeste
               if (label.equals(Cidades.SANTAMARIA.getNome()) 
|| label.equals(Cidades.AGUDO.getNome()) 
|| label.equals(Cidades.CACEQUI.getNome())
                  || label.equals(Cidades.JULIODECASTILHOS.getNome()) 
|| label.equals(Cidades.RESTINGASECA.getNome()) 
|| label.equals(Cidades.SANTIAGO.getNome())
                  || label.equals(Cidades.SAOPEDRODOSUL.getNome()) 
|| label.equals(Cidades.SAOSEPE.getNome()) 
|| label.equals(Cidades.JAGUARI.getNome())
                  || label.equals(Cidades.SAOVICENTEDOSUL.getNome()) 
|| label.equals(Cidades.ROSARIODOSUL.getNome()) 
|| label.equals(Cidades.DONAFRANCISCA.getNome()))
                  
                        centrooeste++;
                  
                        
               
               //Regiao Centro-Leste
               else if (label.equals(Cidades.SANTACRUZDOSUL.getNome()) 
|| label.equals(Cidades.CACHOEIRADOSUL.getNome()) 
|| label.equals(Cidades.CANDELARIA.getNome())
                  || label.equals(Cidades.ESTRELA.getNome()) 
|| label.equals(Cidades.LAJEADO.getNome()) 
|| label.equals(Cidades.RIOPARDO.getNome())
                  || label.equals(Cidades.TAQUARI.getNome()) 
|| label.equals(Cidades.TEUTONIA.getNome()) 
|| label.equals(Cidades.VENANCIOAIRES.getNome()))
                  
                        centroleste++;
               
               //Nordeste
               else if (label.equals(Cidades.CAXIASDOSUL.getNome()) 
|| label.equals(Cidades.BENTOGONCALVES.getNome()) 
|| label.equals(Cidades.CAMBARADOSUL.getNome())
                  || label.equals(Cidades.FARROUPILHA.getNome()) 
|| label.equals(Cidades.LAGOAVERMELHA.getNome()) 
|| label.equals(Cidades.NOVAPADUA.getNome())
                  || label.equals(Cidades.SAOFDEPAULA.getNome()) 
|| label.equals(Cidades.VACARIA.getNome()))
                  
                        nordeste++;
               
               //Noroeste
               else if (label.equals(Cidades.ERECHIM.getNome()) 
|| label.equals(Cidades.PALMEIRADASMISSOES.getNome()) || label.
equals(Cidades.PASSOFUNDO.getNome())
                  || label.equals(Cidades.SANANDUVA.getNome()) 
|| label.equals(Cidades.SANTOANGELO.getNome()) 
|| label.equals(Cidades.SAOLUISGONZAGA.getNome())
|| label.equals(Cidades.SAOMIGUELDASMISSOES.getNome()) || label.
equals(Cidades.SANTAROSA.getNome()) 
|| label.equals(Cidades.TRESPASSOS.getNome()))
                  
                        noroeste++;
               
               //Região Metropolitana de Porto Alegre
               else if (label.equals(Cidades.PORTOALEGRE.getNome()) 
|| label.equals(Cidades.ARAMBARE.getNome()) 
|| label.equals(Cidades.CANELA.getNome())
                  || label.equals(Cidades.CANOAS.getNome()) 
|| label.equals(Cidades.GRAMADO.getNome()) 
|| label.equals(Cidades.GRAVATAI.getNome())
                  || label.equals(Cidades.GUAIBA.getNome()) 
|| label.equals(Cidades.IGREJINHA.getNome()) 
|| label.equals(Cidades.MAQUINE.getNome())
                  || label.equals(Cidades.NOVAPETROPOLIS.getNome()) 
|| label.equals(Cidades.NOVOHAMBURGO.getNome()) 
|| label.equals(Cidades.OSORIO.getNome())
                  || label.equals(Cidades.SAOLEOPOLDO.getNome()) 
|| label.equals(Cidades.TAPES.getNome()) 
|| label.equals(Cidades.TRESCOROAS.getNome())
                  || label.equals(Cidades.TORRES.getNome()) 
|| label.equals(Cidades.VIAMAO.getNome()) 
|| label.equals(Cidades.ALVORADA.getNome())) 
                  
                        metropolitana++;
               
               //Sudeste
               else if (label.equals(Cidades.CACAPAVADOSUL.getNome()) 
|| label.equals(Cidades.CANGUCU.getNome()) 
|| label.equals(Cidades.CHUI.getNome())
                  || label.equals(Cidades.JAGUARAO.getNome()) 
|| label.equals(Cidades.PELOTAS.getNome()) 
|| label.equals(Cidades.PIRATINI.getNome())
                  || label.equals(Cidades.RIOGRANDE.getNome()) 
|| label.equals(Cidades.SAOJOSEDONORTE.getNome()) 
|| label.equals(Cidades.SAOLOURENCODOSUL.getNome()))
                  
                        sudeste++;
               
               //Sudoeste
               else if (label.equals(Cidades.ACEGUA.getNome()) 
|| label.equals(Cidades.ALEGRETE.getNome()) 
|| label.equals(Cidades.BAGE.getNome())
                  || label.equals(Cidades.BARRADOQUARAI.getNome()) 
|| label.equals(Cidades.QUARAI.getNome())
                  || label.equals(Cidades.SAOBORJA.getNome()) 
|| label.equals(Cidades.URUGUAIANA.getNome()))
                  
                        sudoeste++;
               
         }
         
         //Adicionamos ao gráfico os labels e os valores.
         modelPie.set("Região Centro-Oeste", Integer.valueOf(centrooeste));
         modelPie.set("Região Centro-Leste", Integer.valueOf(centroleste));
         modelPie.set("Nordeste", Integer.valueOf(nordeste));
         modelPie.set("Noroeste", Integer.valueOf(noroeste));
         modelPie.set("Região Metropolitana de Porto Alegre", 
         Integer.valueOf(metropolitana));
         modelPie.set("Sudeste", Integer.valueOf(sudeste));
         modelPie.set("Sudoeste", Integer.valueOf(sudoeste));

         //Salvamos o gráfico criado na sessão 
FacesContext.getCurrentInstance().getExternalContext().
getSessionMap().put("modelPie", this.modelPie);

     }


     //Método responsável por criar o gráfico de Barras
     public void criaModeloBarras() {
         model = new CartesianChartModel();

         HibernateDAO dao = new HibernateDAO();
         //Busca do Banco de Dados as cidades com o número de incidentes. 
  //Filtramos apenas cidades com incidentes maior que 2.
         List<Object[]> listaNumeroDeIncidentes = 
         dao.listaNumeroDeIncidentes();
         
         ChartSeries cidadeGrafico;
         
         for (Object[] cidade : listaNumeroDeIncidentes) {
               cidadeGrafico = new ChartSeries();
               //Hibernate retorna os valores num array onde na
               //posição 0 temos o nome da cidade e na posição 1
               //temos a quantidade de incidentes.
               String label = String.valueOf(cidade[0]);
                String qtdeIncid = String.valueOf(cidade[1]);

               if (Integer.valueOf(qtdeIncid) > 1) {
                      cidadeGrafico.setLabel(label);
                      //Apenas do mês estar fixo podemos alterar para
                      //receber valor de um combo.
                      cidadeGrafico.set("Jul", Integer.valueOf(qtdeIncid));
                      //Adiciona a cidade com seu valor ao gráfico
                      model.addSeries(comarca);
                  
               }
               
               cidadeGrafico = null;
         }
         
    FacesContext.getCurrentInstance().getExternalContext().
    getSessionMap().put("model", this.model);

     }
     

     public void setModel(CartesianChartModel model) {
           this.model = model;
     }
     
     public CartesianChartModel getModel() { 
           //Retorna o modelo adicionado anteriormente na sessão
CartesianChartModel model = (CartesianChartModel) FacesContext.
getCurrentInstance().getExternalContext().
getSessionMap().get("model");

            if (model != null)
                  return model;
     
            return new CartesianChartModel();
     }

     //Configurações para a variável de instância Pie
public void setModelPie(PieChartModel modelPie) {
           this.modelPie = modelPie;
     }
  
     public PieChartModel getModelPie() {
PieChartModel modelPie = (PieChartModel) FacesContext.
getCurrentInstance().getExternalContext().
getSessionMap().get("modelPie");

           if (modelPie != null)
                  return modelPie;
     
           return new PieChartModel();
     }      
     
}
Listagem 15. Bean com os códigos referentes ao gráfico Pie adicionados

Podemos verificar que as constantes referentes às cidades estão numa estrutura Enum, segue na Listagem 16 o código:


package util;
 
public enum Cidades {
 
   SANTAMARIA("Santa Maria"),
   ALVORADA("Alvorada"),
   AGUDO("Agudo"),
   CACEQUI("Cacequi"),
   JULIODECASTILHOS("Júlio de Castilhos"),
   RESTINGASECA("Restinga Seca"),
   SANTIAGO("Santiago"),
   SAOPEDRODOSUL("São Pedro do Sul"),
   SAOSEPE("São Sepé"),
   JAGUARI("Jaguari"),
   SAOVICENTEDOSUL("São Vicente do Sul"),
   ROSARIODOSUL("Rosário do Sul"),
   DONAFRANCISCA("Dona Francisca"),
   SANTACRUZDOSUL("Santa Cruz do Sul"),
   CACHOEIRADOSUL("Cachoeira do Sul"),
   CANDELARIA("Candelária"),
   ESTRELA("Estrela"),
   LAJEADO("Lajeado"),
   RIOPARDO("Rio Pardo"),
   TAQUARI("Taquari"),
   TEUTONIA("Teutônia"),
   VENANCIOAIRES("Venâncio Aires"),
   CAXIASDOSUL("Caxias do Sul"),
   BENTOGONCALVES("Bento Gonçalves"),
   CAMBARADOSUL("Cambará do Sul"),
   FARROUPILHA("Farroupilha"),
   LAGOAVERMELHA("Lagoa Vermelha"),
   NOVAPADUA("Nova Pádua"),
   SAOFRANCISCODEPAULA("São Francisco de Paula"),
   VACARIA("Vacaria"),
   ERECHIM("Erechim"),
   PALMEIRADASMISSOES("Palmeiras das Missões"),
   PASSOFUNDO("Passo Fundo"),
   SANANDUVA("Sananduva"),
   SANTOANGELO("Santo Ângelo"),
   SAOLUISGONZAGA("São Luis Gonzaga"),
   SAOMIGUELDASMISSOES("São Miguel das Missões"),
   SANTAROSA("Santa Rosa"),
   TRESPASSOS("Três Passos"),
   PORTOALEGRE("Porto Alegre"),
   ARAMBARE("Arambaré"),
   CANELA("Canela"),
   CANOAS("Canoas"),
   GRAMADO("Gramado"),
   GRAVATAI("Gravataí"),
   GUAIBA("Guaíba"),
   IGREJINHA("Igrejinha"),
   MAQUINE("Maquiné"),
   NOVAPETROPOLIS("Nova Petrópolis"),
   NOVOHAMBURGO("Novo Hamburgo"),
   OSORIO("Osório"),
   SAOLEOPOLDO("São Leopoldo"),
   TAPES("Tapes"),
   TRESCOROAS("Três Coroas"),
   TORRES("Torres"),
   VIAMAO("Viamão"),
   CACAPAVADOSUL("Caçapava do Sul"),
   CANGUCU("Canguçu"),
   CHUI("Chuí"),
   JAGUARAO("Jaguarão"),
   PELOTAS("Pelotas"),
   PIRATINI("Piratini"),
   RIOGRANDE("Rio Grande"),
   SAOJOSEDONORTE("São José do Norte"),
   SAOLOURENCODOSUL("São Lourenço do Sul"),
   ACEGUA("Aceguá"),
   ALEGRETE("Alegrete"),
   BAGE("Bagé"),
   BARRADOQUARAI("Barra do Quaraí"),
   QUARAI("Quaraí"),
   SAOBORJA("São Borja"),
   URUGUAIANA("Uruguaiana");

   
   String nome;
   
   Cidades(String nome) {
         this.nome = nome;
   }
   
   public String getNome() {
         return nome;
   }
       
}
Listagem 16. Enum com as cidades do estado do Rio Grande do Sul

As comparações também poderiam estar dentro do Enum organizadas do jeito que estão no bean ou através de switch case, fica a critério do programador escolher onde posicionar e realizar as comparações.

Finalizado o bean agora deveremos efetivamente mostrar o gráfico Pie Chart criado acima. Para isso criamos o dialog abaixo que será chamado após o método do bean acima ser completado:


<p:dialog header="Relatório" widgetVar="dialogIncidentesPorRegiao" 
resizable="true" width="600" showEffect="explode" hideEffect="explode" 
dynamic="true">  

   <h:form>
                       
     <h:panelGrid columns="3" cellpadding="4" styleClass="estiloPadrao">
        <p:pieChart value="#{relatoriosBean.modelPie}" style="height:300px; 
        width:800px;" legendPosition="ne" showDataLabels="true" 
        seriesColors="FC5560, CA04F1, FBFB18, B7FB09, 04C1FB, 034ED8, AAAAAA" />
     </h:panelGrid>
                   
     <h:panelGrid columns="1" cellpadding="1" style="font-family: Arial,
     Helvetica,sans-serif; font-size: 8px; color: rgb(0, 0, 0); text-align: left;">
        <h:outputText value="Região Centro-Oeste: Santa Maria, Agudo, 
        Cacequi, Júlio de Castilhos, Restinga Seca, Santiago, 
        São Pedro do Sul, São Sepé, Jaguari, São Vicente do Sul, 
        Rosário do Sul, Dona Francisca." />
        <h:outputText value="Região Centro-Leste: Santa Cruz do Sul, 
        Cachoeira do Sul, Candelária, Estrela, Lajeado, Rio Pardo, Taquari, 
        Teutônia, Venâncio Aires." />
        <h:outputText value="Nordeste: Caxias do Sul, Bento Gonçalves, 
        Cambará do Sul, Farroupilha, Lagoa Vermelha, Nova Pádua, 
        São Francisco de Paula, Vacaria." />
        <h:outputText value="Noroeste: Erechim, Palmeiras das Missões, 
        Passo Fundo, Sananduva, Santo Ângelo, São Luis Gonzaga, São Miguel 
        das Missões, Santa Rosa, Três Passos." />
        <h:outputText value="Região Metropolitana de Porto Alegre: Porto 
        Alegre, Arambaré, Canela, Canoas, Gramado, Gravataí, Guaíba, Igrejinha, 
        Maquiné, Nova Petrópolis, Novo Hamburgo, Osório, São Leopoldo, Tapes." />
        <h:outputText value="Sudeste: Caçapava do Sul, Canguçu, Chuí, Jaguarão, 
        Pelotas, Piratini, Rio Grande, São José do Norte, São Lourenço do Sul." />
        <h:outputText value="Sudoeste: Aceguá, Alegrete, Bagé, Barra do Quaraí, 
        Quaraí, Rosário do Sul, São Borja, Uruguaiana." />
     </h:panelGrid>
                       
   </h:form>
                
</p:dialog>
Listagem 17. Exibindo o gráfico criado anteriormente

No primeiro panelGrid é onde de fato exibiremos o gráficos Pie Chart com os resultados obtidos pelo bean. Podemos verificar que o atributo value chama a variável de instância ( relatoriosBean.modelPie ) configurada no bean e o atributo “style” define o estilo do gráfico como a altura e a largura do gráfico. O atributo legendPosition define a posição da legenda em relação ao gráfico. O atributo showDataLabels quando configurado como true mostra no gráfico as porcentagens de cada pedaço do gráfico. Por fim, o atributo seriesColors define as cores (em hexadecimal) para cada parte do gráfico.

No segundo panelGrid definimos apenas as cidades pertencentes a cada uma das regiões exibidas no gráfico.

Segue na Figura 15 a tela que chama os dialogs e os beans para geração dos gráficos. Nesta tela é exibido o botão e o label adicionado para o gráfico de incidentes por região.

 Tela responsável por chamar os gráficos da aplicação
Figura 15. Tela responsável por chamar os gráficos da aplicação

Ao clicar no botão Mostrar ao lado do rótulo Total de incidentes por Região é exibido o gráfico gerado no bean e customizado na página. Segue na Figura 16 o gráfico gerado:

 Gráfico Pie gerado com base no bean e na página
Figura 16. Gráfico Pie gerado com base no bean e na página

Podemos verificar quanto é simples e poderosa a geração de gráficos do Primefaces. Além de permitir uma boa customização os gráficos gerados pelo Primefaces possuem uma aparência bastante agradável, informativa e bem que podem ser utilizados para diferentes propósitos. Agora basta que os distribuída. Além disso, existe uma quantidade relativamente grande de gráficos desenvolvedores e os analistas coletem os dados necessários, gerem formas de consolidar esses dados e utilizem o Primefaces para gerar os gráficos de forma bastante intuitiva e visual.


Bibliografia

  1. Primefaces Official Web Site.
  2. Oleg Varaksin, Mert Çalışkan. Primefaces Cookbook. Editora O'Reilly, 1º edição.