View Javadoc

1   /*
2    * Criado em 26/04/2005
3    *
4    */
5   package ecar.servlet.grafico;
6   
7   import java.io.IOException;
8   import java.text.SimpleDateFormat;
9   import java.util.ArrayList;
10  import java.util.HashSet;
11  import java.util.Iterator;
12  import java.util.List;
13  import java.util.Set;
14  
15  import javax.servlet.ServletException;
16  import javax.servlet.http.HttpServlet;
17  import javax.servlet.http.HttpServletRequest;
18  import javax.servlet.http.HttpServletResponse;
19  
20  import org.apache.log4j.Logger;
21  import org.jfree.chart.ChartFactory;
22  import org.jfree.chart.ChartUtilities;
23  import org.jfree.chart.JFreeChart;
24  import org.jfree.chart.axis.DateAxis;
25  import org.jfree.chart.axis.DateTickUnit;
26  import org.jfree.chart.plot.XYPlot;
27  import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
28  import org.jfree.chart.renderer.xy.XYItemRenderer;
29  import org.jfree.data.time.Month;
30  import org.jfree.data.time.TimeSeries;
31  import org.jfree.data.time.TimeSeriesCollection;
32  
33  import comum.util.Pagina;
34  import comum.util.Util;
35  
36  import ecar.dao.AcompRealFisicoDao;
37  import ecar.dao.AcompReferenciaDao;
38  import ecar.dao.AcompReferenciaItemDao;
39  import ecar.dao.ExercicioDao;
40  import ecar.dao.ItemEstrtIndResulDao;
41  import ecar.pojo.AcompReferenciaItemAri;
42  import ecar.pojo.ExercicioExe;
43  import ecar.pojo.ItemEstrtIndResulIettr;
44  
45  /**
46   * @author felipev
47   *
48   */
49  public class GraficoPrevisaoIndicadoresResultado extends HttpServlet{
50  
51  	/**
52  	 * 
53  	 */
54  	private static final long serialVersionUID = -8640912786694377079L;
55  	private Logger logger = null;
56  	
57      public GraficoPrevisaoIndicadoresResultado() {
58          this.logger = Logger.getLogger(this.getClass());
59       }
60      
61      /**
62       * Gera Grafico de Previsao dos Indicadores de Resultado.<br>
63       * 
64       * @author N/C
65       * @since N/C
66       * @version N/C
67       * @param HttpServletRequest request
68       * @param HttpServletResponse response
69       * @throws ServletException
70       * @throws IOException
71       */
72      public final void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
73          
74      try {
75  		
76  		JFreeChart grafico;
77  		
78  		List sMeses = new ArrayList();
79  		List sRealizado = new ArrayList();
80  		
81  		ExercicioDao exercicioDao = new ExercicioDao(null);
82  		AcompReferenciaDao acompReferenciaDao = new AcompReferenciaDao(null);
83  		ItemEstrtIndResulDao itemEstrtIndResulDao = new ItemEstrtIndResulDao(null);
84  		
85  		AcompReferenciaItemDao acompReferenciaItemDao = new AcompReferenciaItemDao(null);
86  		//Descobrir Meses
87  		ItemEstrtIndResulIettr indicador = (ItemEstrtIndResulIettr) itemEstrtIndResulDao.buscar(ItemEstrtIndResulIettr.class, Long.valueOf(Pagina.getParamStr(request,"codIndicador")));
88  		AcompReferenciaItemAri ari = (AcompReferenciaItemAri) acompReferenciaItemDao.buscar(AcompReferenciaItemAri.class, Long.valueOf(Pagina.getParamStr(request,"codAri")));
89  		
90  		boolean comQtde = ("S".equals(Pagina.getParamStr(request, "comQtde")) ? true : false);
91  		boolean soPrevisao = ("S".equals(Pagina.getParamStr(request, "soPrevisao")) ? true : false);
92  		
93  		int[] meses = acompReferenciaItemDao.getMesAnoInicioFimMatrizProjecao(indicador, comQtde, soPrevisao);
94  		
95  		int mesInicio = meses[0];
96  		int anoInicio = meses[1];
97  		
98  		if(soPrevisao){
99  			mesInicio = Integer.valueOf(Pagina.getParamStr(request, "mesIni")).intValue();
100 			anoInicio = Integer.valueOf(Pagina.getParamStr(request, "anoIni")).intValue();
101 		}
102 		else {
103 			mesInicio = meses[0];
104 			anoInicio = meses[1];
105 		}
106 		
107 		int mesFimRealizado = Integer.valueOf(ari.getAcompReferenciaAref().getMesAref()).intValue(); ;
108 		int anoFimRealizado = Integer.valueOf(ari.getAcompReferenciaAref().getAnoAref()).intValue(); ;
109 		
110 		TimeSeriesCollection data = new TimeSeriesCollection();
111 
112 		TimeSeries serie1 = new TimeSeries("Realizado", Month.class);
113 		TimeSeries serie2 = new TimeSeries("Projetado", Month.class);
114 		TimeSeries serie3 = new TimeSeries("Previsto", Month.class);
115 
116 		//TODO: Retirar do gráfico as series abaixo quando o protótipo for implementado.
117 //		TimeSeries serieIdh = new TimeSeries("IDH", Month.class);
118 //		TimeSeries serieSaneamento = new TimeSeries("Inv. Saneamento", Month.class);
119 //		TimeSeries serieEsgoto = new TimeSeries("Estrutura Esgoto", Month.class);
120 //		TimeSeries seriePosto = new TimeSeries("Posto Saúde", Month.class);
121 		
122 		int auxMes = mesInicio;
123 		int auxAno = anoInicio;
124 		
125 		int i = 1;
126 		double qtdeAnterior = 0;		
127 		//while((auxAno != anoFimRealizado) || (auxAno == anoFimRealizado && auxMes <= mesFimRealizado)){
128 //		double qtdeIdh = 100;
129 //		double qtdeSan = 500;
130 
131 		while(auxAno < anoFimRealizado || (auxAno == anoFimRealizado && auxMes <= mesFimRealizado)){
132 			String strMesInicio = Integer.valueOf(auxMes).toString();
133 			if(strMesInicio.length() == 1)
134 				strMesInicio = "0" + strMesInicio;
135 			String strAnoInicio = Integer.valueOf(auxAno).toString();
136 			Double qtde = new AcompRealFisicoDao(null).getQtdRealizadaMesAno(indicador, Long.valueOf(strMesInicio), Long.valueOf(strAnoInicio));
137 			double qtdeSerie = 0;
138 			
139 			//utilizar o valor referência para o início da projeção [por Thaise].
140 			if (indicador.getIndiceMaisRecenteIettr()!= null && qtdeAnterior==0) {
141 				qtdeAnterior = indicador.getIndiceMaisRecenteIettr().doubleValue();
142 			}
143 			
144 			if(qtde != null){
145 				//qtdeSerie = qtdeAnterior + qtde.doubleValue();
146 				//FIXME: Verificar regra do não-acumulável: Está pegando o valor pq não tem uma lista de valores para compara o último/maior.
147 				if("S".equals(indicador.getIndAcumulavelIettr())){
148 					qtdeSerie = qtdeAnterior + qtde.doubleValue();
149 				}else {
150 					qtdeSerie = qtde.doubleValue();
151 				}
152 				qtdeAnterior = qtdeSerie;
153 			} else 
154 				qtdeSerie = qtdeAnterior;
155 			serie1.add(new Month(auxMes, auxAno), qtdeSerie);
156 			
157 //			serieIdh.add(new Month(auxMes, auxAno), qtdeIdh);
158 //			serieSaneamento.add(new Month(auxMes, auxAno), qtdeSan);
159 //			serieEsgoto.add(new Month(auxMes, auxAno), ((qtdeIdh - qtdeSan) * 2)/3);
160 //			seriePosto.add(new Month(auxMes, auxAno), qtdeIdh + qtdeSan * 2);
161 			
162 //			qtdeIdh += qtdeAnterior + 1000;
163 //			qtdeSan -= qtdeAnterior + 500;
164 			
165 			sMeses.add(Integer.valueOf(i));
166 			
167 			sRealizado.add(new Double(qtdeSerie));
168 			auxMes++;
169 			if(auxMes == 13){
170 				auxMes = 1;
171 				auxAno++;
172 			}
173 			i++;
174 		}
175 		//Avança 1 mes
176 		int mesAnt = auxMes;
177 		int anoAnt = auxAno;
178 		if(mesAnt - 1 == 0){
179 			mesAnt = 12;
180 			anoAnt--;
181 		} else {
182 			mesAnt--;
183 		}
184 
185 		int mesFimProjecao = mesFimRealizado;
186 		int anoFimProjecao = anoFimRealizado;
187 		int xProjetado = 0;
188 		
189 		if(comQtde){
190 			serie2.add(new Month(mesAnt, anoAnt), qtdeAnterior);
191 			qtdeAnterior += acompReferenciaItemDao.calcularPrevistoMes(sMeses, sRealizado, i) - acompReferenciaItemDao.calcularPrevistoMes(sMeses, sRealizado, i-1) ;
192 			serie2.add(new Month(auxMes, auxAno), qtdeAnterior);
193 			
194 			int[] fimProjecao = acompReferenciaItemDao.getMesAnoFimProjecao(indicador);
195 			mesFimProjecao = fimProjecao[0];
196 			anoFimProjecao = fimProjecao[1];
197 			
198 			//Descobrir o xProjetado (índice que mesFimProjecao/anoFimProjecao teria na matriz de realizados)
199 			if(anoFimProjecao == anoFimRealizado){
200 				xProjetado = i + (mesFimProjecao - mesFimRealizado);
201 			} else {
202 				while(anoFimProjecao > anoFimRealizado){ // Correção Thaise [antes era um !=]
203 					mesFimRealizado++;
204 					if(mesFimRealizado == 13){
205 						anoFimRealizado++;
206 						mesFimRealizado = 1;
207 					}
208 					xProjetado++;
209 				}
210 				xProjetado += i + mesFimProjecao;
211 			}
212 		}
213 		//Descobrir até onde vai o PREVISTO
214 		String strMesInicio = Integer.valueOf(mesInicio).toString();
215 		if(strMesInicio.length() == 1)
216 			strMesInicio = "0" + strMesInicio;
217 		String strMesFim = Integer.valueOf(mesFimProjecao).toString();
218 		if(strMesFim.length() == 1)
219 			strMesFim = "0" + strMesFim;
220 
221 		String strAnoInicio = Integer.valueOf(anoInicio).toString();
222 		String strAnoFim = Integer.valueOf(anoFimProjecao).toString();
223 
224 		ExercicioExe exercicioInicial = acompReferenciaDao.getExercicio(strAnoInicio, strMesInicio);
225 		ExercicioExe exercicioFinal = acompReferenciaDao.getExercicio(strAnoFim, strMesFim);
226 		
227 		List exerciciosAnteriores = exercicioDao.getExerciciosAnteriores(exercicioFinal);
228 		List exerciciosPosteriores = exercicioDao.getExerciciosPosteriores(exercicioInicial);
229 		
230 		Set exerciciosDoPeriodo = new HashSet();
231 		exerciciosDoPeriodo.addAll(Util.intersecao(exerciciosAnteriores, exerciciosPosteriores));
232 		exerciciosDoPeriodo.add(exercicioInicial);
233 		exerciciosDoPeriodo.add(exercicioFinal);
234 		
235 
236 		int k = 1;
237 		double previstoFinal = 0;
238 
239 		serie3.add(new Month(mesInicio, anoInicio), 0); // INSERINDO PRIMEIRO VALOR PREVISTO = 0
240 		
241 		//Descobrir o ultimo valor do previsto de cada exercício
242 		List ultimosValoresPrevistos = new ArrayList();
243 		
244 		while((anoInicio != anoFimProjecao) || (anoInicio == anoFimProjecao && mesInicio < mesFimProjecao)){
245 			String strMes = Integer.valueOf(mesInicio).toString();
246 			String strAno = Integer.valueOf(anoInicio).toString();
247 			
248 			Iterator itEx = exerciciosDoPeriodo.iterator();
249 			
250 			while(itEx.hasNext()){
251 				ExercicioExe exercicio = (ExercicioExe) itEx.next();
252 				if(exercicioDao.getMesesDentroDoExercicio(exercicio).contains(strMes+"-"+strAno)){
253 					previstoFinal = itemEstrtIndResulDao.getQtdPrevistoExercicio(indicador, exercicio);
254 				}
255 				k++;
256 			}
257 
258 			mesInicio++;
259 			if(mesInicio == 13){
260 				String[] val = {strMes, strAno, String.valueOf(previstoFinal)};
261 				ultimosValoresPrevistos.add(val);
262 				mesInicio = 1;
263 				anoInicio++;
264 			}
265 		}
266 		
267 		//plotar valores projetados até ultimo mes de projecao, ou então até que projetado > previstoFinal 
268 		double ultimoProjetado = 0;
269 		double projetadoAnterior = acompReferenciaItemDao.calcularPrevistoMes(sMeses, sRealizado, i);
270 		while(i <= xProjetado){				
271 			i++;
272 			auxMes++;
273 			if(auxMes==13){
274 				auxMes = 1;
275 				auxAno++;
276 			}
277 			ultimoProjetado = acompReferenciaItemDao.calcularPrevistoMes(sMeses, sRealizado, i);
278 			
279 			qtdeAnterior += (ultimoProjetado - projetadoAnterior);
280 			projetadoAnterior = ultimoProjetado;
281 			
282 			if(i+1 == xProjetado && qtdeAnterior > previstoFinal) //se falta um mes para acabar (já foi plotado) e qtdeAnterior jah é maior que previsto final, break it!
283 				break;
284 			
285 			serie2.add(new Month(auxMes, auxAno), qtdeAnterior);
286 		}
287 		
288 		//Plotar ponto de previstoFinal
289 		//serie3.add(new Month(mesInicio, anoInicio), previstoFinal); //Linha descomentada para testes - INSERINDO ULTIMO VALOR
290 		
291 		
292 		if(comQtde){
293 			//Continua a segunda série até ultrapassar previstoFinal (caso já não tenha ultrapassado)
294 			while(qtdeAnterior < previstoFinal){
295 				i++;
296 				auxMes++;
297 				if(auxMes > 12){
298 					auxMes = 1;
299 					auxAno++;
300 				}
301 				ultimoProjetado = acompReferenciaItemDao.calcularPrevistoMes(sMeses, sRealizado, i);
302 				
303 				qtdeAnterior += (ultimoProjetado - projetadoAnterior);
304 				projetadoAnterior = ultimoProjetado;
305 				serie2.add(new Month(auxMes, auxAno), qtdeAnterior);					
306 			}
307 		}
308 		
309 		boolean inserirUlimoValorPrevisto = true;
310 		Iterator itValPrevistosFinais = ultimosValoresPrevistos.iterator();
311 		while(itValPrevistosFinais.hasNext()){
312 			String[] valores = (String[]) itValPrevistosFinais.next();
313 
314 			int mes = Integer.parseInt(valores[0]);
315 			int ano = Integer.parseInt(valores[1]);
316 			
317 			if(mesInicio == mes && anoInicio == ano){
318 				inserirUlimoValorPrevisto = false;
319 			}
320 		}
321 		
322 		if(inserirUlimoValorPrevisto){
323 			String[] val = {String.valueOf(mesInicio), String.valueOf(anoInicio), String.valueOf(previstoFinal)};
324 			ultimosValoresPrevistos.add(val);
325 		}
326 		
327 		itValPrevistosFinais = ultimosValoresPrevistos.iterator();
328 		double ultimoValorPrevistoPlotado = 0;
329 		while(itValPrevistosFinais.hasNext()){
330 			String[] valores = (String[]) itValPrevistosFinais.next();
331 			int mes = Integer.parseInt(valores[0]);
332 			int ano = Integer.parseInt(valores[1]);
333 			double valor = Double.parseDouble(valores[2]);
334 			
335 			
336 			//FIXME: Verificar regra do não-acumulável: se não for acumulável, está plotando o último valor de cada exercício.
337 			if("S".equals(indicador.getIndAcumulavelIettr()))
338 				valor = valor + ultimoValorPrevistoPlotado;
339 			
340 			
341 			ultimoValorPrevistoPlotado = valor;
342 			serie3.add(new Month(mes, ano), valor);
343 		}
344 
345 		if(!soPrevisao)
346 			data.addSeries(serie1);
347 		
348 		if(comQtde)
349 			data.addSeries(serie2);
350 		
351 		data.addSeries(serie3);
352 		
353 //		if("S".equals(request.getParameter("exibirIdh")))
354 //			data.addSeries(serieIdh);
355 //		if("S".equals(request.getParameter("exibirIsa")))
356 //			data.addSeries(serieSaneamento);
357 //		if("S".equals(request.getParameter("exibirEes")))
358 //			data.addSeries(serieEsgoto);
359 //		if("S".equals(request.getParameter("exibirPsa")))
360 //			data.addSeries(seriePosto);
361 		
362 		data.setDomainIsPointsInTime(true);
363  
364 		grafico = ChartFactory.createTimeSeriesChart(
365 				indicador.getNomeIettir(),
366 				"Meses",
367 				"Quantidade Realizada", 
368 				data,
369 				true,
370 				true,
371 				true
372 				);
373 		
374 		// coloca os marcadores nas linhas
375 		XYPlot plot = grafico.getXYPlot();
376 		XYItemRenderer renderer = plot.getRenderer();
377 		if(renderer instanceof StandardXYItemRenderer){
378 			StandardXYItemRenderer rr = (StandardXYItemRenderer) renderer;
379 			//rr.setPlotShapes(true);
380 			rr.setBaseShapesVisible(true);
381 			rr.setShapesFilled(true);
382 		} 
383 		
384 		DateAxis axis = (DateAxis) plot.getDomainAxis();
385 		axis.setAutoRange(false);
386 		axis.setVerticalTickLabels(true);
387 		
388 		axis.setTickUnit(new DateTickUnit(DateTickUnit.MONTH, 1));
389 		axis.setDateFormatOverride(new SimpleDateFormat("MMM-yyyy"));
390 		
391 	    response.setContentType("image/jpeg");	        
392 	    ChartUtilities.writeChartAsPNG(response.getOutputStream(), grafico, i * 35, 470);
393 	    response.getOutputStream().flush();
394 	    response.getOutputStream().close();
395 			        
396     } catch (Exception e) {     
397     	this.logger.error(e);
398     }
399 }
400 
401 
402     
403 
404 }