* Visite o ALJUG - http://aljug.blogspot.com - Noticias sobre a comunidade java alagoana e do mundo * Visite o blog Mundo Gamificado www.mundogamificado.com.br - E vamos mudar o mundo! *

quinta-feira, 27 de junho de 2013

PieChart PrimeFaces com Hibernate

Post atualizado para versão mais nova do Primefaces 

  Olá pessoal, venho mais uma vez deixar uma bela dica de programação e como sempre dica de JSF2 + Primefaces. Agora estou com um pouco de tempo devido aos projetos e também por que conseguir realizar um sonho de ser professor, o que é raro nos dias atuais, em uma faculdade, mas lecionando Banco de dados que também faz parte do meu dia a dia, muito bom por sinal.
  Como diz o título deste post, vou falar sobre como realizar a montagem de um pieChart com o hibernate, logo já aviso que vamos rodar um pouco, mas vou fazer de tudo para que todos entendam o que estou fazendo.
  Primeiro de tudo tenho duas classes, andamento e status do andamento, na primeira tenho informações como: id,observação, status,data e justificativa, na outra tenho apenas id e descrição. Qual o objetivo? O objetivo é mostra no gráfico quantos andamentos existem para cada descrição do status, por exemplo, o status "Em andamento" possui 32 registros de andamentos o status "Em análise" existe 5 registros de andamentos, e assim por diante. Então com isso temos um cenário para fazer a lógica e brincarmos com os dados, pois bem nos Objetos de acesso a dados(Data Object Acess - DAO´s) faremos nossa pesquisa, primeiro iremos pegar todas as descrições dos status existentes no banco de dados:
Código 0:
 public List <Status> Search() {  
     return findAll(Status.class);  
   }  
Na classe do piechart que é igual ao bean de exemplo do site primefaces adicionei no método private void createPieModel() a variável da classe andamentos da seguinte maneira:
Código 1:
  private List<String> status;
  statusdescricao = stDAO.Search();  
     for (int z = 0; z < statusdescricao.size();z++){  
     status.add(statusdescricao.get(z).getDescricao());  
     }  
Com isso vai ser adicionada neste list todas as descrições existentes como pode ver abaixo:
Código 2:
 System.out.println("Lista do Status "+status);  
     >> Lista do Status [Em Andamento, Análise, Em avaliação]  

Concluímos o primeiro passo, o seguinte passo é trazer os números relativos às essas descrições, então fica fácil quando sabemos quem é a descrição, pois só precisaremos de uma clausula where descricao = váriavel String. Como faremos a seguir:
Código 3:
  public int numberTotalOfAndamento(String status) throws NoResultException  

Fazendo a lógica com inner join, já que neste caso estou lidando com duas tabelas diferentes, procuraremos pela quantidade de andamentos quando o id do status é igual o id do campo id_status na tabela andamento, por exemplo:
Código 4:
 Query query = manager.createQuery("SELECT count(*) FROM "  
         + "andamento a inner join status s"  
         + " on(a.status = s.id) where s.descricao=:descricao");  
     query.setParameter("descricao", status);  

Neste caso dispensaria o Group by. Feito isso adicionaríamos ao método createPieModel o seguinte trecho de código:

Código 5:
  for (int i = 0;i < status.size();i++){  
       pieModel.set(status.get(i), andDAO.numberTotalOfAndamento(status.get(i)));  
     }  

Veja que com a lista, neste caso, com três dados teremos que passear, então com o for pegaremos cada linha com o método get(index), pois o método pieModel.set exige uma string e uma variável numeral , por isso no código acima a descrição "Em Andamento", representado no código 2, seria a variável que o método numberTotalOfAndamento irá procurar e retornar um inteiro para compor esse método. Com isso ficaria pieModel.set("Em Andamento",5); Cinco foi o resultado que foi retornado.

E para concluir o método ficaria desta maneira:
Código 6:
 private void createPieProcesso() {   
     pieModel = new PieChartModel();   
     statusdescricao = stDAO.Search();   
     for (int z = 0; z &lt; statusdescricao.size();z++){  
     status.add(statusdescricao.get(z).getDescricao());  
     }  
     System.out.println("Lista do Status "+status);  
     for (int i = 0;i &lt; status.size();i++){  
       pieModel.set(status.get(i), andDAO.numberTotalOfAndamento(status.get(i))); 
     }  

E na página JSF seria representado pelo código:
Código 7:
  <p:pieChart value="#{charts.pieModel}" legendPosition="e" fill="false" showDataLabels="true"   
         title="Estatística dos Andamentos" style="width:400px; height:300px" sliceMargin="5" diameter="150" />  

O resultado seria:
Espero ter ajudado com mais esta dica, até qualquer dia.

7 comentários:

Cleverson Jizreel disse...

Bom dia,

Miguel, sou novo em java e estou tentando carregar um line chart a partir de dados do mysql com hibernate, o problema é que não consigo montar a lógica a partir do hibernate.
Se fosse possível, gostaria que fizesse uma análise no meu código, posso te encaminhar por e-mail, se possível me manda um e-mail em jizreell@gmail.com
Desde já, grato pela atenção.

Miguel SCJ disse...

Cara desculpa pela demora, acho e espero que você já tenha resolvido seu problema, mas qualquer coisa é só postar que agora estou mais atento aos comentários.

mauroslucios disse...

Boa tarde Miguel!
Tenho uma tabela de consultas onde tenho seguintes campos:
idconsulta,idmedico_fk,idpaciente_fk e dataconsulta.
Sendo que tenho relacionamentos onde entram como FK o idPaciente, idMedico.

Como faria um gráfico da quantidade de pacientes atendidas por médicos?
Obrigado desde já!

Miguel SCJ disse...

Qual a ideia que você tem em mente?

Poderia fazer um gráfico de consulta por paciente, tipo o paciente X no dia Y foi para o médico Z.
Ou um gráfico de quantas vezes o paciente foi para um mesmo médico, com o count no sql.

mauroslucios disse...

Obrigado pela resposta consegui fazer!

medicoMB...
private void criarModeloGrafico(){
List consultas = new ArrayList();
consultas = new ConsultaDao().getList();

/* Adquirindo a Lista de Medicos sem repetição. Lembre-se de Implementar Hash e Equals na Classe de Dominio (Medico) */
List medicos = new ArrayList();
for (Consulta consulta : consultas) {
if(!medicos.contains(consulta.getMedico()))
medicos.add(consulta.getMedico());
}

/* Contabilizando o numero de Consultas para Cada Medico e Inserindo em um Map que deverá Ser Utilizado para o Plot do Grafico*/
Map mapConsulta = new HashMap();
for (Medico medico : medicos) {
int qtdConsulta = 0;
for (Consulta consulta : consultas) {
if(consulta.getMedico().equals(medico))
qtdConsulta++;
}
mapConsulta.put(medico.getNome_medico(), qtdConsulta);
}

/* Criando a Serie Quantidade Consulta Vs Medico para Plotar o Grafico */
ChartSeries serie = new ChartSeries();
for (String key : mapConsulta.keySet())
serie.set(key, mapConsulta.get(key));

/* Plotando o Grafico com os dados Trabalhados de Medico e Numero de Consultas */
modelo = new BarChartModel();
modelo.addSeries(serie);
}

Chmando na listarMedico.xhtml




Se tiver alguma melhora que você consiga visualizar no meu código e puder citar te agradeço!

Fica com DEUS e muito obrigado!

Miguel SCJ disse...

Visualizar alguma melhoria assim é bastante difícil. Mas está de parabéns! É isso aí!

mauroslucios disse...

Abraços e muito obrigado pela ajuda!