view gnv-artifacts/src/main/java/de/intevation/gnv/chart/ChartFactory.java @ 65:8b75d01fa5b5

Insert Chart-Classes from old Repository gnv-artifacts/trunk@48 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Tim Englich <tim.englich@intevation.de>
date Wed, 09 Sep 2009 12:02:09 +0000
parents
children 0e9762ebd18d
line wrap: on
line source
/**
 * Title:           ChartFactory, $Header: /share/gdi/SDI-Suite/Repository/projekte/BSH-GDI/genericViewer/src/main/java/de/conterra/bsh/gdi/gnviewer/output/chart/ChartFactory.java,v 1.8 2007/12/21 12:31:15 blume Exp $
 * Source:          $Source: /share/gdi/SDI-Suite/Repository/projekte/BSH-GDI/genericViewer/src/main/java/de/conterra/bsh/gdi/gnviewer/output/chart/ChartFactory.java,v $
 * created by:      Stefan Blume (blume)
 * erstellt am:     06.12.2007
 * Copyright:       con terra GmbH, 2005
 *
 * modified by:     $Author: blume $
 * modified on:     $Date: 2007/12/21 12:31:15 $
 * Version:         $Revision: 1.8 $
 * TAG:             $Name:  $
 * locked from:     $Locker:  $
 * CVS State:       $State: Exp $
 * Project:         $ProjectName$
 */
package de.intevation.gnv.chart;

import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.Date;

import org.apache.log4j.Logger;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.encoders.KeypointPNGEncoderAdapter;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Minute;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.RectangleInsets;

import au.com.bytecode.opencsv.CSVReader;
import de.conterra.bsh.gdi.gnviewer.data.filter.IdValue;
import de.conterra.bsh.gdi.gnviewer.data.filter.MeasurementId;
import de.conterra.bsh.gdi.gnviewer.data.filter.ParameterId;
import de.conterra.bsh.gdi.gnviewer.datasources.ResultSet;
import de.conterra.bsh.gdi.gnviewer.datasources.Row;
import de.conterra.bsh.gdi.gnviewer.exception.TechnicalException;
import de.conterra.bsh.gdi.gnviewer.renderer.DiagramRenderer;
import de.conterra.bsh.gdi.gnviewer.util.TempFile;
import de.conterra.bsh.gdi.gnviewer.util.TemporaryFileDirectory;

/**
 * The class <code>ChartFactory</code> fulfills the following purposes:
 * <ol>
 * <li></li>
 * </ol>
 * 
 * @author blume
 * @version 1.0
 * @serial 1.0
 * @see
 * @since 06.12.2007 17:25:59
 */
public class ChartFactory {

	/**
	 * Default Logging instance
	 */
	private static Logger sLogger = Logger.getLogger(ChartFactory.class);
	private static boolean sDebug = sLogger.isDebugEnabled();
	private final TemporaryFileDirectory mTmpImageDir;

	/**
	 * 
	 */
	public ChartFactory(TemporaryFileDirectory pTmpImageDir) {
		mTmpImageDir = pTmpImageDir;
	}

	public synchronized TempFile createSimpleTimeSeriesChart(
			ChartLabels pLabels, ChartStyle pStyle, String pTimeSeriesName,
			TempFile tempF, IdValue[] pParameterId,
			IdValue[] pMeasurementId, IdValue[] pFeatureId
			) throws IOException, TechnicalException {
		if (sDebug)
			sLogger.debug("createSimpleTimeSeriesChart()");
		int lLowerLevel = Integer.MIN_VALUE;
		int lUpperLevel = Integer.MAX_VALUE;
		if (pStyle.isUseUpperDataLevel()
				&& pStyle.getUpperLevel() < Integer.MAX_VALUE) {
			lUpperLevel = pStyle.getUpperLevel();
		}
		if (pStyle.isUseLowerDataLevel()
				&& pStyle.getLowerLevel() > Integer.MIN_VALUE) {
			lLowerLevel = pStyle.getLowerLevel();
		}
		if (sDebug)
			sLogger.debug("  vor createDataset()");
		XYDataset lSet = createDataset(pTimeSeriesName, tempF, lUpperLevel,
				lLowerLevel,pParameterId,pMeasurementId,pFeatureId);
		if (sDebug)
			sLogger.debug("  nach createDataset()");
		final Color[] color = {Color.black, Color.red, Color.green, Color.blue};
		DateAxis domain = new DateAxis("Zeit [UTC]");
        NumberAxis axis;
        StandardXYItemRenderer renderer = new StandardXYItemRenderer();
		XYPlot plot = new XYPlot();
		//Global  settings
		
		plot.setOrientation(PlotOrientation.VERTICAL);
		plot.setBackgroundPaint(Color.lightGray);
		plot.setDomainGridlinePaint(Color.white);
		plot.setRangeGridlinePaint(Color.white);
		plot.setAxisOffset(new RectangleInsets(5.0,5.0,5.0,5.0));
		//plot.getRangeAxis().setFixedDimension(10.0);
		plot.setDomainAxis(domain);
		plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
		if (pParameterId.length == 1) {
			axis = new NumberAxis(pParameterId[0].getTitle());
			if(pParameterId[0].getTitle().contains("richtung")){
				NumberAxis axis1 = new NumberAxis(
						((String) pParameterId[0].getTitle()));//,new Range(0.0,360.0));
			    axis1.setTickUnit(new NumberTickUnit(30.0));
				axis1.setUpperBound(360.0);
				axis1.setLowerBound(0.0);
                //axis1.setDisplayRange(0.0,360.0);				    
				plot.setRangeAxis( axis1);
			}else{
			axis.setFixedDimension(10.0);
			axis.setAutoRangeIncludesZero(false);
			plot.setRangeAxis(axis);
			}
			axis.configure();
			plot.setRangeAxisLocation( AxisLocation.BOTTOM_OR_LEFT);
			plot.setRenderer(renderer);
			plot.setDataset(lSet);
		} else {
			// Individual settings for different parameters
			for (int i = 0; i < lSet.getSeriesCount(); i++) {

				plot.setDataset(i, getDataset((TimeSeriesCollection) lSet, i));
				Color mColor=color[i % color.length];  // zyklische Farbvergabe
				mColor = color[0];
				// if ( pParameterId.length==1){
				
				if(((String) lSet.getSeriesKey(i)).contains("richtung")){
					NumberAxis axis1 = new NumberAxis(((String) lSet.getSeriesKey(i)));//,new Range(0.0,360.0));
				    axis1.setTickUnit(new NumberTickUnit(30.0));
                    //axis1.setDisplayRange(0.0,360.0);				    
					axis1.setLabelPaint(mColor);
					axis1.setTickLabelPaint(mColor);
					axis1.setUpperBound(360.0);
					axis1.setLowerBound(0.0);
					plot.setRangeAxis(i, axis1);
					
			    
				}
				else {
					axis = new NumberAxis((String) lSet.getSeriesKey(i));
					axis.setFixedDimension(10.0);
					axis.setAutoRangeIncludesZero(false);
					axis.setLabelPaint(mColor);
					axis.setTickLabelPaint(mColor);
					plot.setRangeAxis(i, axis);
					axis.configure();
				}
				if (i % 2 != 0)
					plot.setRangeAxisLocation(i, AxisLocation.BOTTOM_OR_RIGHT);
				else
					plot.setRangeAxisLocation(i, AxisLocation.BOTTOM_OR_LEFT);
				plot.mapDatasetToRangeAxis(i, i);
				// }
				renderer = new StandardXYItemRenderer();
				renderer.setSeriesPaint(i, mColor);
				// renderer.setSeriesStroke(i,stroke[j]);
				plot.setRenderer(i, renderer);
			}
		}
		JFreeChart chart = new JFreeChart(
				pLabels.getTitle(),
				new Font ("SansSerif",Font.BOLD,24),
				plot,true);
		

		setStyle(chart, pStyle);
		configureRenderingOptions(chart);
		if (sDebug)
			sLogger.debug("  vor encodeChart()");
		
		return encodeChart(chart, pStyle);
	}
    private static XYDataset getDataset(TimeSeriesCollection T, int pIndex){ //throws TechnicalException{
    	//if (T.getSeriesCount() < pIndex) throw TechnicalException();
    	TimeSeriesCollection TSC = new TimeSeriesCollection();
    	TSC.addSeries(T.getSeries(pIndex));
    	return (XYDataset) TSC;
    }
	public synchronized TempFile createScatterPlot(ChartStyle pStyle,
			ResultSet pResults) throws TechnicalException, IOException {
		ScatterPlot lPlot = new ScatterPlot("ScatterPlot", pResults);
		return encodeChart(lPlot.getChart(), pStyle);
	}

	private void configureRenderingOptions(JFreeChart pJfreechart) {
		org.jfree.chart.renderer.xy.XYItemRenderer xyitemrenderer = ((XYPlot) pJfreechart
				.getPlot()).getRenderer();
		if (xyitemrenderer instanceof XYLineAndShapeRenderer) {
			XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyitemrenderer;
			xylineandshaperenderer.setBaseShapesVisible(true);
			xylineandshaperenderer.setBaseShapesFilled(true);
		}
	}

	private void setStyle(JFreeChart pJfreechart, ChartStyle pStyle) {
		if (sDebug)
			sLogger.debug("setStyle()");
		pJfreechart.setBackgroundPaint(pStyle.getCanvasColor());
		XYPlot xyplot = (XYPlot) pJfreechart.getPlot();
		xyplot.setBackgroundPaint(pStyle.getPlotBackgroundColor());
		xyplot.setDomainGridlinePaint(pStyle.getDomainGridlineColor());
		xyplot.setRangeGridlinePaint(pStyle.getRangeGridlineColor());

		Insets lOffsets = pStyle.getAxisOffset();
		RectangleInsets lRectangleInsets = new RectangleInsets(lOffsets.mUpper,
				lOffsets.mLeft, lOffsets.mLower, lOffsets.mRight);
		xyplot.setAxisOffset(lRectangleInsets);
		xyplot.setDomainCrosshairVisible(pStyle.isDomainCrosshairVisible());
		xyplot.setRangeCrosshairVisible(pStyle.isRangeCrosshairVisible());

	}
	
	
	private TimeSeries createTimeSeries(String pTimeSeriesName, TempFile tempF, 
			int lUpperCut, int lLowerCut,int pStart,int pEnd, Date dStart, Date dEnd) throws TechnicalException{
		if (sDebug)
			sLogger.debug("createTimeSeries()");
		Row lRow0, lRow1, lRowVorEnd;
		
		Date lDate=null, lDate0=null;
        DiagramRenderer mDiagramRenderer = new DiagramRenderer();
        
        CSVReader reader = null;
		TimeSeries lTimeseries = new TimeSeries(pTimeSeriesName,   
				org.jfree.data.time.Minute.class);
		try {
			reader = new CSVReader (new FileReader(tempF.getFile()), ';');
			
			
			
			long maxGap=0, lDateDiff=0;
			double lValue=0;
			String [] lRow = null;

			int i = 0;
            while ((lRow = reader.readNext()) != null){
            	
            	if (i >= pStart+1 && i <= pEnd){
            		if (i == pStart+1){
                		lRow0 = new Row(lRow);//
            			
            			// Handle Gaps > 0.5% timeserieslength, i.e do not draw here
            			// +TODO mache maxGap variabel �ber diagram options
            			maxGap = (dEnd.getTime() - dStart.getTime()) / 200; // 0,5 prozent der L�nge
            			if (maxGap < 3600000) maxGap=3600010;
            			if (maxGap <(dEnd.getTime() - dStart.getTime())/(pEnd-pStart))
            				maxGap = (dEnd.getTime() - dStart.getTime())/(pEnd-pStart) + 1000;
            			
            			if (sDebug)
            				sLogger.debug("MaxGap : "+maxGap/1000+" L�nge : "+(dEnd.getTime() - dStart.getTime())/1000+
            						      "Intervall "+(dEnd.getTime() - dStart.getTime())/(pEnd-pStart)/1000);
            			lDate = lRow0.getDateValue(0);
            			lDate0 = lDate;
            			lValue = lRow0.getDoubleValue(1);
            			if (lValue > lLowerCut && lValue < lUpperCut){
            				//lTimeseries.addOrUpdate(new Minute(lDate), lValue);
            				lTimeseries.add(new Minute(lDate), lValue);
            			}
                	}
				//for (int i = pStart+1; i <= pEnd; i++) {
					lRow1 = new Row (lRow);
					lDate = lRow1.getDateValue(0);
					lValue = lRow1.getDoubleValue(1);
					lDateDiff = lDate.getTime() - lDate0.getTime();
					if (lDateDiff > maxGap) {
						// add 1 minute in millisecs to left hand side Date
						// and insert Dummy to break line
						lDate0.setTime((lDate0.getTime() + 60000)); 
						lTimeseries.addOrUpdate(new Minute(lDate0), null);						 
						lTimeseries.addOrUpdate(new Minute(lDate), lValue);
						//lTimeseries.add(new Minute(lDate0), null);
					} else if (lDateDiff == 0) {
						if (sDebug)
								sLogger.debug("Datediff: "+lDateDiff+" bei index : "+i+" Datum : "+lDate+" "+lDate0);
					}
					 else if (lValue > lLowerCut && lValue < lUpperCut) {
						lTimeseries.addOrUpdate(new Minute(lDate), lValue);
						//lTimeseries.add(new Minute(lDate), lValue);
					 }
					lRow0 = lRow1;
					lDate0 = lDate;
				}
				i++;
            }
			

		} catch (OutOfMemoryError e) { 
			sLogger.error(e.getMessage(), e);
			return lTimeseries;
		
		} catch (Exception e) { //TechnicalException
			sLogger.error(e.getMessage(), e);
		}
		finally {
			try{
				reader.close();
			}
			catch (Exception e){
				sLogger.error(e.getMessage(), e);
			}
		}
		
		return lTimeseries;
	}

	private XYDataset createDataset(String pTimeseriesName, TempFile tempF,
			int lUpperCut, int lLowerCut,IdValue[] pParameterId,
			IdValue[] pMeasurementId, IdValue[] pFeatureID) throws TechnicalException {
		
		CSVReader reader=null;
		TimeSeriesCollection lTimeSeriesCollection = new TimeSeriesCollection();
		try{
			for (int i=0;i<pMeasurementId.length;i++) System.out.println("Measurement Depth "+
				            pMeasurementId[i].getTitle() );
			for (int i=0;i<pParameterId.length;i++) System.out.println("Parameter "+
		            pParameterId[i].getTitle() );
			
			Date dStart = null, dEnd= null;
			int break1, break2, break3;
			int mStart = 0;
			int mEnd = 0;
			
			reader = new CSVReader (new FileReader(tempF.getFile()), ';');
	
			String [] sArrayStrLine = reader.readNext();
			
			Row row = new Row(sArrayStrLine);
			
			break1 = new Integer (sArrayStrLine[2]).intValue();
			break2 = new Integer (sArrayStrLine[3]).intValue();
			break3 = new Integer (sArrayStrLine[4]).intValue();
			dStart = row.getDateValue(0);
			int i = 1;
			while ((sArrayStrLine = reader.readNext()) != null) {
				row = new Row(sArrayStrLine);
				if (break1 != new Integer (sArrayStrLine[2]).intValue()
						|| break2 != new Integer (sArrayStrLine[3]).intValue()
					    || break3 != new Integer (sArrayStrLine[4]).intValue()){
					String mTimeSeriesName = findValueTitle(pParameterId,break1)+" "+
					                         findValueTitle(pMeasurementId,break2)+"m";
					
					lTimeSeriesCollection.addSeries(createTimeSeries(mTimeSeriesName,
							tempF, lUpperCut, lLowerCut, mStart, mEnd, dStart, dEnd));
					mStart = i;
					dStart = row.getDateValue(0);
					break1 = new Integer (sArrayStrLine[2]).intValue();
					break2 = new Integer (sArrayStrLine[3]).intValue();
					break3 = new Integer (sArrayStrLine[4]).intValue();
	
				}
				mEnd = i;
				//mEnd ++;
				dEnd = row.getDateValue(0);
				i = i + 1;
			}
			String mTimeSeriesName = findValueTitle(pParameterId,break1)+" "+
	                                 findValueTitle(pMeasurementId,break2)+"m";
			lTimeSeriesCollection.addSeries(createTimeSeries(mTimeSeriesName,
					tempF, lUpperCut, lLowerCut, mStart, mEnd, dStart, dEnd));
			
		}
		catch (Exception e){
			sLogger.error(e.getMessage(), e);
		}
		finally{
			try{
			reader.close();
			}
			catch (Exception e){
				sLogger.error(e.getMessage(), e);
			}
		}
		return lTimeSeriesCollection;
	}



	private TempFile encodeChart(JFreeChart pChart, ChartStyle pStyle)
			throws IOException {
		if (sDebug)
			sLogger.debug("encodeChart()");
		KeypointPNGEncoderAdapter lEncoder = new KeypointPNGEncoderAdapter();
		lEncoder.setEncodingAlpha(true);

		int lWidth = (int) pStyle.getChartSize().getWidth();
		int lHeight = (int) pStyle.getChartSize().getHeight();

		FileOutputStream lFileOutputStream = null;
		BufferedOutputStream lBufferedOutputStream = null;

		TempFile lImageFile = mTmpImageDir.createFile(".png");

		BufferedImage lImage = pChart.createBufferedImage(lWidth, lHeight,
				BufferedImage.BITMASK, null);
		lFileOutputStream = new FileOutputStream(lImageFile.getFile());
		lBufferedOutputStream = new BufferedOutputStream(lFileOutputStream);
		lEncoder.encode(lImage, lBufferedOutputStream);
		lBufferedOutputStream.close();
		lFileOutputStream.close();

		return lImageFile;

	}

    private String findValueTitle(IdValue[] pValueId,int pMmtId){
    	for (int i=0;i<pValueId.length;i++){
    		if ((long) pMmtId ==pValueId[i].getValue())return pValueId[i].getTitle();
    	}
    	return "";
    }
    private String findValueTitle(IdValue[] pValueId,long pMmtId){
    	for (int i=0;i<pValueId.length;i++){
    		if ( pMmtId ==pValueId[i].getValue())return pValueId[i].getTitle();
    	}
    	return "";
    }
}

http://dive4elements.wald.intevation.org