view gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalProfileChartFactory.java @ 356:3eee1369c79b

Added the Unit of the Parameter to the Query for Parameters in all Parameterqueries where it was still missing. Now the Unit will be displaied in the Combobox and in the Diagramm-Axis-Description gnv-artifacts/trunk@429 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Tim Englich <tim.englich@intevation.de>
date Tue, 15 Dec 2009 14:55:42 +0000
parents e964a3d8f7bc
children
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.Transparency;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Iterator;

import org.apache.log4j.Logger;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
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.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.RectangleInsets;

import de.intevation.gnv.chart.exception.TechnicalChartException;
import de.intevation.gnv.geobackend.base.Result;
import de.intevation.gnv.state.describedata.KeyValueDescibeData;

/**
 * 
 * @author Tim Englich <tim.englich@intevation.de>
 * 
 */
public class VerticalProfileChartFactory {

    /**
     * Default Logging instance
     */
    private static Logger sLogger = Logger
            .getLogger(VerticalProfileChartFactory.class);
    private static boolean sDebug = sLogger.isDebugEnabled();
    protected PlotOrientation plotOrientation = PlotOrientation.HORIZONTAL;

    public synchronized void createProfileChart(
                                                ChartLabels pLabels,
                                                ChartStyle pStyle,
                                                Collection<KeyValueDescibeData> parameters,
                                                Collection<KeyValueDescibeData> measurements,
                                                Collection<KeyValueDescibeData> dates,
                                                OutputStream outputStream,
                                                Collection<Result> resultSet)
                                                                             throws IOException,
                                                                             TechnicalChartException {
        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 = this.createDataset(resultSet, lUpperLevel,
                lLowerLevel, parameters, measurements, dates);
        if (sDebug)
            sLogger.debug("  nach createDataset()");
        final Color[] color = { Color.black, Color.red, Color.green, Color.blue };
        NumberAxis domain = new NumberAxis(pLabels.getDomainAxisLabel());
        NumberAxis axis;
        StandardXYItemRenderer renderer = new StandardXYItemRenderer();
        XYPlot plot = new XYPlot();
        // Global settings

        plot.setOrientation(plotOrientation);
        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 (parameters.size() == 1) {
            KeyValueDescibeData parameter = parameters.iterator().next();
            axis = new NumberAxis(parameter.getValue());
            if (parameter.getValue().contains("richtung")) {
                NumberAxis axis1 = new NumberAxis((parameter
                        .getValue()));// ,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((XYSeriesCollection) 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()");

        encodeChart(chart, pStyle, outputStream);
    }

    private static XYDataset getDataset(XYSeriesCollection T, int pIndex) { // throws
                                                                            // TechnicalChartException{
        // if (T.getSeriesCount() < pIndex) throw TechnicalChartException();
        XYSeriesCollection XYSC = new XYSeriesCollection();
        XYSC.addSeries(T.getSeries(pIndex));
        return XYSC;
    }

    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());

    }

    protected XYSeries createXYSeries(String seriesName,
                                      Collection<Result> resultSet,
                                      int lUpperCut, int lLowerCut, int pStart,
                                      int pEnd, double maxGap) throws TechnicalChartException {
        if (sDebug)
            sLogger.debug("createXYSeries()");
        XYSeries series = new XYSeries(seriesName);
        try {
            double xValue = 0;
            double yValue = 0;
            int i = 0;
            Iterator<Result> resultIterator = resultSet.iterator();
            while (resultIterator.hasNext()) {
                Result lRow = resultIterator.next();
                if (i >= pStart && i <= pEnd) {
                    xValue = lRow.getDouble("XORDINATE");
                    yValue = lRow.getDouble("YORDINATE");
                    series.add(xValue, yValue);
                    sLogger.debug(seriesName + " Added Value " + xValue + " / "
                                  + yValue);

                } else if (i > pEnd) {
                    return series;
                }
                i++;
            }
        } catch (OutOfMemoryError e) {
            sLogger.error(e.getMessage(), e);
            return series;

        } catch (Exception e) { // TechnicalChartException
            sLogger.error(e.getMessage(), e);
        } finally {
        }

        return series;
    }

    private XYDataset createDataset(Collection<Result> resultSet,
                                    int lUpperCut, int lLowerCut,
                                    Collection<KeyValueDescibeData> parameters,
                                    Collection<KeyValueDescibeData> measurements,
                                    Collection<KeyValueDescibeData> dates)
                                                                                 throws TechnicalChartException {

        XYSeriesCollection xyDataset = new XYSeriesCollection();

        try {
            String break1, break2, break3;
            int mStart = 0;
            int mEnd = 0;

            Iterator<Result> resultIterator = resultSet.iterator();
            Result firstRow = null, lastRow = null;
            
            double maxGap;
            if (resultIterator.hasNext()) {
                // Row row = new Row(sArrayStrLine);
                Result row = resultIterator.next();
                
                firstRow = row;
                lastRow = row;
                
                break1 = row.getString("GROUP1"); // 2
                break2 = row.getString("GROUP2"); // 3
                break3 = row.getString("GROUP3"); // 4
                int i = 1;
                while (resultIterator.hasNext()) {
                    row = resultIterator.next();
                    
                    if (!break1.equals(row.getString("GROUP1"))
                        || !break2.equals(row.getString("GROUP2"))
                        || !break3.equals(row.getString("GROUP3"))) {
                        String seriesName = this.createSeriesName(parameters, measurements, dates, break1, break2, break3);
                        sLogger.debug("Neuer Datensatz " + seriesName
                                      + "von Datens�tzen " + mStart + " / "
                                      + mEnd);
                        
                        maxGap = this.calculateMaxGap(firstRow, lastRow, mEnd-mStart);
                        
                        xyDataset.addSeries(createXYSeries(seriesName,
                                resultSet, lUpperCut, lLowerCut, mStart, mEnd,maxGap));
                        firstRow = row;
                        mStart = i;

                        break1 = row.getString("GROUP1");
                        break2 = row.getString("GROUP2"); // 3
                        break3 = row.getString("GROUP3"); // 4

                    }
                    lastRow = row;
                    mEnd = i;
                    // mEnd ++;
                    i = i + 1;
                }

                String seriesName = this.createSeriesName(parameters, measurements, dates, break1, break2, break3);
                sLogger.debug("Neuer Datensatz " + seriesName
                              + "von Datens�tzen " + mStart + " / " + mEnd);
                
                maxGap = this.calculateMaxGap(firstRow, lastRow, mEnd-mStart);
                xyDataset.addSeries(createXYSeries(seriesName, resultSet,
                        lUpperCut, lLowerCut, mStart, mEnd,maxGap));
            }else{
                xyDataset.addSeries(createXYSeries("",
                        resultSet, lUpperCut, lLowerCut, mStart, mEnd,9999));
            }
        } catch (Exception e) {
            sLogger.error(e.getMessage(), e);
        } finally {
        }
        return xyDataset;
    }
    
    
    protected double calculateMaxGap(Result firstRow, Result lastRow, int numResults){
        
        double firstValue = firstRow.getDouble("YORDINATE"); 
        // TODO Implement me. Hier ist die zentrale Frage wie wir zwischen Netzen und
        // anderen Datenquellen unterscheiden.
        return 0;
    }

    /**
     * @param parameters
     * @param measurements
     * @param break1
     * @param break2
     * @return
     */
    protected String createSeriesName(
                                    Collection<KeyValueDescibeData> break1Candidates,
                                    Collection<KeyValueDescibeData> break2Candidates,
                                    Collection<KeyValueDescibeData> break3Candidates,
                                    String break1, String break2, String break3) {
        String seriesName = findValueTitle(break1Candidates, break1)
                            + " "
                            + findValueTitle(break2Candidates,
                                    break2);
        return seriesName.trim();
    }

    private void encodeChart(JFreeChart pChart, ChartStyle pStyle,
                             OutputStream outputStream) 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();

        BufferedImage lImage = pChart.createBufferedImage(lWidth, lHeight,
                Transparency.BITMASK, null);

        lEncoder.encode(lImage, outputStream);

    }

    protected String findValueTitle(Collection<KeyValueDescibeData> values,
                                  String id) {
        if (values != null) {
            Iterator<KeyValueDescibeData> it = values.iterator();
            while (it.hasNext()) {
                KeyValueDescibeData data = it.next();
                if (id.equals(data.getKey())) {
                    return data.getValue();
                }
            }
        }
        return "";
    }
}

http://dive4elements.wald.intevation.org