O Java Server Faces (JSF) é uma especificação para o desenvolvimento de aplicações Web seguindo o padrão Model View Controler (MVC) em Java. Essa especificação surgiu como uma alternativa ao Struts, que na época era o principal framework para implementar aplicações nesse padrão de projeto. Sua primeira versão foi disponibilizada em 2004 e em 2013 foi lançada a versão 2.2.
Atualmente, existem diversos frameworks para construção de interfaces ricas com o JSF, entre eles, um dos principais é o PrimeFaces que disponibiliza diversos componentes. Atualmente esse framework está na versão 5.1. e contém um grande número de componentes de formulários, listagem, menus, entre outros. Na versão 5 do framework, a API para a criação de gráficos foi toda remodelada, facilitando bastante o desenvolvimento de gráficos em diversos formatos diferentes.
Este artigo mostrará como configurar uma aplicação com JSF e PrimeFaces e também como implementar diferentes tipos de gráficos em uma aplicação. Os principais tipos de gráficos disponibilizados sãos os gráficos de barra, de pizza, de área, entre outros.
Configurando o projeto
Para facilitar a configuração do projeto será utilizado o Maven e para a criação desse projeto serão necessárias as dependências das bibliotecas do PrimeFaces e também do JSF. Para a biblioteca do PrimeFaces também é necessário adicionar as informações do repositório deste. A Listagem 1 mostra o arquivo pom.xml do projeto criado.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.devmedia</groupId>
<artifactId>primefaces</artifactId>
<version>0.0.1</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>5.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version>2.1.13</version>
<scope>compile</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>prime-repo</id>
<name>PrimeFaces Maven Repository</name>
<url>http://repository.primefaces.org</url>
<layout>default</layout>
</repository>
</repositories>
</project>Depois de configurar as dependências do projeto é necessário configurar a aplicação para usar o framework JSF. Como o projeto é de uma aplicação Web necessitamos criar o arquivo web.xml. O passo mais importante, é configurar o Faces Servlet, que utiliza a classe javax.faces.webapp.FacesServlet, e configurar o mapeamento das URL’s que serão tratadas pelo JSF, no caso, todos os endereços que terminarem com *.xhtml. Também foi configurado que caso aconteça algum erro na aplicação, a requisição seja redirecionada para a página inicial da aplicação. A Listagem 2 mostra o código do arquivo web.xml.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>com.devmedia.primefaces</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/index.xhtml</welcome-file>
</welcome-file-list>
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/index.xhtml</location>
</error-page>
</web-app>Para executar os exemplos criados neste artigo será necessário utilizar um contêiner Web, pois o PrimeFaces pode ser executado em qualquer um que seja compatível com o Java Web, entre eles o Jetty e o Tomcat. No desenvolvimento do exemplo desse artigo foi utilizado o Apache Tomcat versão 8.0.12.
Gráficos
O PrimeFaces disponibiliza diversos modelos para a construção de gráficos, mas nesse artigo será mostrado os modelos mais conhecidos, como gráficos de área, de pizza e de barras. Também existem diversas opções disponíveis para colocar nos gráficos, como exportar as imagens geradas, adicionar tooltips, dar zoom em regiões específicas do gráfico, entre outros. No PrimeFaces todos os gráficos necessitam de um ManagedBean para a recuperação dos dados e uma página XHTML, que renderiza o gráfico na tela do usuário.
O primeiro gráfico desenvolvido foi um gráfico de área, que coloca cada item um sobre o outro para que seja possível comparar a quantidade de cada item e também o total de itens que existem. Um possível exemplo de uso para esse gráfico é saber a quantidade do nível de água de cada reservatório. Além de medirmos a quantidade de cada um, também é possível saber a variação do total de água disponível. A Listagem 3 mostra o código desenvolvido para a criação desse gráfico.
package com.devmedia.graficos;
import javax.annotation.PostConstruct;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import org.primefaces.model.chart.Axis;
import org.primefaces.model.chart.AxisType;
import org.primefaces.model.chart.CategoryAxis;
import org.primefaces.model.chart.LineChartModel;
import org.primefaces.model.chart.LineChartSeries;
@ManagedBean(name="GraficoAreaMB")
public class GraficoArea implements Serializable {
private LineChartModel areaModel;
@PostConstruct
public void init() {
createAreaModel();
}
public LineChartModel getAreaModel() {
return areaModel;
}
private void createAreaModel() {
areaModel = new LineChartModel();
LineChartSeries reservatorio1 = new LineChartSeries();
reservatorio1.setFill(true);
reservatorio1.setLabel("Cantareira");
reservatorio1.set("2011", 40);
reservatorio1.set("2012", 38);
reservatorio1.set("2013", 44);
reservatorio1.set("2014", 40);
reservatorio1.set("2015", 47);
LineChartSeries reservatorio2 = new LineChartSeries();
reservatorio2.setFill(true);
reservatorio2.setLabel("Guarapiranga");
reservatorio2.set("2011", 52);
reservatorio2.set("2012", 55);
reservatorio2.set("2013", 52);
reservatorio2.set("2014", 57);
reservatorio2.set("2015", 49);
LineChartSeries reservatorio3 = new LineChartSeries();
reservatorio3.setFill(true);
reservatorio3.setLabel("Alto Tiête");
reservatorio3.set("2011", 52);
reservatorio3.set("2012", 55);
reservatorio3.set("2013", 52);
reservatorio3.set("2014", 57);
reservatorio3.set("2015", 49);
areaModel.addSeries(reservatorio1);
areaModel.addSeries(reservatorio2);
areaModel.addSeries(reservatorio3);
areaModel.setTitle("Nível");
areaModel.setLegendPosition("ne");
areaModel.setStacked(true);
areaModel.setShowPointLabels(true);
Axis xAxis = new CategoryAxis("Reservatório");
areaModel.getAxes().put(AxisType.X, xAxis);
Axis yAxis = areaModel.getAxis(AxisType.Y);
yAxis.setLabel("Nível");
yAxis.setMin(0);
yAxis.setMax(500);
}
}Todo gráfico necessita de uma classe do tipo Model, que define como serão os dados que farão parte do gráfico. Nesse exemplo foi usado o LineChartModel, que é usado para o gráfico de área. Para cada item do gráfico é criado um objeto do tipo LineChartSeries e nele são definidos os valores que aparecerão nos gráficos. A classe Axis serve para definir as opções dos eixos do gráfico, como valor mínimo e máximo e label.
A Listagem 4 mostra o código do XHTML desenvolvido para a criação do gráfico de área, onde é possível observar que o código é bastante simples, bastando adicionar o componente chart, que é o mesmo componente para todos os gráficos do PrimeFaces, e colocar os atributos type, que define o tipo de gráfico que será mostrado, além do atributo model, que define de onde virão os dados que serão apresentados no gráfico.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form>
<p:chart type="line" model="#{GraficoAreaMB.areaModel}"
style="height:300px" />
</h:form>
</h:body>
</html>A Figura 1 mostra o resultado da execução do código das Listagens 3 e 4. Como é possível observar, foi renderizado o gráfico de área com os dados definidos no ManagedBean.

Outro tipo de gráfico bastante usado é de pizza, cujo objetivo é mostrar a proporção de escolhida de cada uma das opções disponibilizadas. Esse tipo de gráfico serve para diversas análises, e um exemplo de uso é quando queremos saber a proporção de pessoas que preferem cada um dos tipos de transporte disponibilizados na cidade de São Paulo. A Listagem 5 mostra o código do ManagedBean criado para a exibição do gráfico de pizza.
package com.devmedia.graficos;
import javax.annotation.PostConstruct;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import org.primefaces.model.chart.PieChartModel;
@ManagedBean(name="GraficoPizzaMB")
public class GraficoPizza implements Serializable {
private PieChartModel pieModel1;
@PostConstruct
public void init() {
createPieModels();
}
public PieChartModel getPieModel1() {
return pieModel1;
}
private void createPieModels() {
createPieModel1();
}
private void createPieModel1() {
pieModel1 = new PieChartModel();
pieModel1.set("Carro", 1000);
pieModel1.set("Ônibus", 600);
pieModel1.set("Metrô", 1500);
pieModel1.set("Trem", 700);
pieModel1.set("Bicicleta", 100);
pieModel1.setTitle("Meio de Transporte");
pieModel1.setLegendPosition("w");
}
}Para a criação de um gráfico de pizza é necessário utilizar o PieChartModel. Nesse modelo, basta passar um nome, que será o label utilizado no gráfico, e um valor, que será utilizado para montar a proporção de cada um dos valores no gráfico.
A Listagem 6 mostra o código do XHTML criado para a criação do gráfico de pizza. O código é muito parecido com o exemplo anterior, alterando apenas o atributo type.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form>
<p:chart id="chart" type="pie" model="#{GraficoPizzaMB.pieModel1}"
style="width:400px;height:300px" widgetVar="chart" />
</h:form>
</h:body>
</html>A Figura 2 mostra o resultado da execução do código das Listagens 5 e 6, e como é possível observar, foi renderizado o gráfico de pizza com os dados definidos no ManagedBean.

O PrimeFaces permite também a criação de gráficos de linha, que são aqueles para comparar a diferença entre itens em diversos períodos diferentes. Um exemplo onde o gráfico de linha é muito utilizado é nas pesquisas eleitorais, onde cada candidato é representado por uma linha e os dados são atualizados a cada pesquisa. A Listagem 7 mostra o código desenvolvido para a criação de um gráfico de linha que compara o desempenho de três candidatos em cinco pesquisas diferentes.
package com.devmedia.graficos;
import javax.annotation.PostConstruct;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import org.primefaces.model.chart.Axis;
import org.primefaces.model.chart.AxisType;
import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.CategoryAxis;
import org.primefaces.model.chart.ChartSeries;
import org.primefaces.model.chart.LineChartModel;
import org.primefaces.model.chart.LineChartSeries;
@ManagedBean(name="GraficoLinhaMB")
public class GraficoLinha implements Serializable {
private LineChartModel lineModel1;
@PostConstruct
public void init() {
createLineModels();
}
public CartesianChartModel getLineModel1() {
return lineModel1;
}
private void createLineModels() {
lineModel1 = initLinearModel();
lineModel1.setTitle("Pesquisa de Opinião");
lineModel1.setLegendPosition("e");
lineModel1.setShowPointLabels(true);
lineModel1.getAxes().put(AxisType.X, new CategoryAxis("Pesquisas"));
Axis yAxis = lineModel1.getAxis(AxisType.Y);
yAxis.setLabel("% de votos");
yAxis.setMin(0);
yAxis.setMax(100);
}
private LineChartModel initLinearModel() {
LineChartModel model = new LineChartModel();
ChartSeries series1 = new ChartSeries();
series1.setLabel("Candidato 1");
series1.set("Pesquisa 1", 40);
series1.set("Pesquisa 2", 42);
series1.set("Pesquisa 3", 47);
series1.set("Pesquisa 4", 44);
series1.set("Pesquisa 5", 40);
ChartSeries series2 = new ChartSeries();
series2.setLabel("Candidato 2");
series2.set("Pesquisa 1", 20);
series2.set("Pesquisa 2", 22);
series2.set("Pesquisa 3", 26);
series2.set("Pesquisa 4", 25);
series2.set("Pesquisa 5", 29);
ChartSeries series3 = new ChartSeries();
series3.setLabel("Candidato 3");
series3.set("Pesquisa 1", 10);
series3.set("Pesquisa 2", 12);
series3.set("Pesquisa 3", 16);
series3.set("Pesquisa 4", 15);
series3.set("Pesquisa 5", 19);
model.addSeries(series1);
model.addSeries(series2);
model.addSeries(series3);
return model;
}
}Para a criação do gráfico de linhas é utilizado o modelo LineChartModel. Nesse modelo é necessário criar ChartSeries, que representa cada uma das linhas do gráfico. Nas séries são passados os dados que serão mostrados no gráfico, normalmente um label para o eixo X e um valor para o eixo Y.
A Listagem 8 mostra o código do XHTML criado para a criação do gráfico de linha.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form>
<p:chart type="line" model="#{GraficoLinhaMB.lineModel1}"
style="height:300px;width:800px;" />
</h:form>
</h:body>
</html>A Figura 3 mostra o resultado da execução do código das Listagens 7 e 8.

Uma funcionalidade interessante e que pode ser utilizada em qualquer gráfico é o zoom. Com ele é possível selecionar uma área específica do gráfico e aumentar a imagem, apenas na parte desejada. A Listagem 9 mostra como utilizar o zoom em um gráfico de linhas. A única modificação significativa em relação ao exemplo anterior é a chamada do método setZoom, pois apenas com isso é possível utilizar o zoom no gráfico. Isso pode ser feito para qualquer gráfico do PrimeFaces. O código do XHTML não é apresentado porque não existem nenhuma alteração em relação ao exemplo anterior.
package com.devmedia.graficos;
import javax.annotation.PostConstruct;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import org.primefaces.model.chart.Axis;
import org.primefaces.model.chart.AxisType;
import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.CategoryAxis;
import org.primefaces.model.chart.ChartSeries;
import org.primefaces.model.chart.LineChartModel;
import org.primefaces.model.chart.LineChartSeries;
@ManagedBean(name="GraficoLinhaMB")
public class GraficoLinha implements Serializable {
private LineChartModel lineModel1;
@PostConstruct
public void init() {
createLineModels();
}
public CartesianChartModel getLineModel1() {
return lineModel1;
}
private void createLineModels() {
lineModel1 = initLinearModel();
lineModel1.setTitle("Pesquisa de Opinião");
lineModel1.setLegendPosition("e");
lineModel1.setShowPointLabels(true);
lineModel1.getAxes().put(AxisType.X, new CategoryAxis("Pesquisas"));
lineModel1.setZoom(true);
Axis yAxis = lineModel1.getAxis(AxisType.Y);
yAxis.setLabel("% de votos");
yAxis.setMin(0);
yAxis.setMax(100);
}
private LineChartModel initLinearModel() {
LineChartModel model = new LineChartModel();
ChartSeries series1 = new ChartSeries();
series1.setLabel("Candidato 1");
series1.set("Pesquisa 1", 40);
series1.set("Pesquisa 2", 42);
series1.set("Pesquisa 3", 47);
series1.set("Pesquisa 4", 44);
series1.set("Pesquisa 5", 40);
ChartSeries series2 = new ChartSeries();
series2.setLabel("Candidato 2");
series2.set("Pesquisa 1", 20);
series2.set("Pesquisa 2", 22);
series2.set("Pesquisa 3", 26);
series2.set("Pesquisa 4", 25);
series2.set("Pesquisa 5", 29);
ChartSeries series3 = new ChartSeries();
series3.setLabel("Candidato 3");
series3.set("Pesquisa 1", 10);
series3.set("Pesquisa 2", 12);
series3.set("Pesquisa 3", 16);
series3.set("Pesquisa 4", 15);
series3.set("Pesquisa 5", 19);
model.addSeries(series1);
model.addSeries(series2);
model.addSeries(series3);
return model;
}
}A Figura 4 mostra o resultado da execução do código da Listagem 9. Como é possível observar, foi renderizado o gráfico de linha com os dados definidos no ManagedBean, mas aplicado um zoom, que mostra apenas parte do gráfico.

Com isso este artigo mostrou como criar diversos tipos de gráficos com o PrimeFaces e o JavaServer Faces. O projeto utilizou a versão mais recente do PrimeFaces, que é hoje um dos principais frameworks para a criação de interfaces ricas do JSF.