view gnv-artifacts/src/main/java/de/intevation/gnv/histogram/HistogramHelper.java @ 1087:92fce3b3d07f

Centered histograms in pdf exports. gnv-artifacts/trunk@1189 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Thu, 10 Jun 2010 09:23:33 +0000
parents 846b2b70b2e0
children f953c9a559d8
line wrap: on
line source
package de.intevation.gnv.histogram;

import de.intevation.artifacts.CallContext;

import de.intevation.gnv.artifacts.ressource.RessourceFactory;

import de.intevation.gnv.chart.ChartLabels;

import de.intevation.gnv.geobackend.base.Result;
import de.intevation.gnv.geobackend.base.ResultDescriptor;

import de.intevation.gnv.state.describedata.KeyValueDescibeData;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.apache.log4j.Logger;

/**
 * This class supports some helper methods for histogram charts.
 *
 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
 */
public class HistogramHelper {

    /**
     * Logger used for logging with log4j.
     */
    private static Logger logger = Logger.getLogger(HistogramHelper.class);


    /**
     * Disabled HistogramHelper constructor. This is a helper class and no
     * instance should be instantiated from this class.
     */
    private HistogramHelper() {
    }


    /**
     * This function prepare some input data and turns it into an array which is
     * taken by {@link de.intevation.gnv.chart.DefaultHistogram}.
     *
     * @param input A collection with the data used to be displayed in a
     * histogram
     * @param parameters A collection with a bunch of parameters
     * @param measurements A collection with a bunch of measurements
     * @param dates A collection with a bunch of dates
     *
     * @return Object[][] containing raw data which can be used to create
     * histograms
     */
    public static Object[][] prepareHistogramData(
        Collection input,
        Collection parameters,
        Collection measurements,
        Collection dates
    ) {
        List names = new ArrayList<String>();
        List data  = new ArrayList<Double[]>();

        if (logger.isDebugEnabled()) {
            logger.debug("############ prepare histogram data ##########");
            logger.debug("Input data size: " + input.size());
        }

        if (input == null) {
            return new Object[0][0];
        }

        String break1, break2, break3;
        int b1Idx = -1;
        int b2Idx = -1;
        int b3Idx = -1;
        int yIdx  = -1;
        try {
            Iterator iter = input.iterator();

            if (iter.hasNext()) {
                Result row = (Result) iter.next();
                Result previousRow = row;

                if (b1Idx == -1) {
                    ResultDescriptor rd = row.getResultDescriptor();
                    b1Idx = rd.getColumnIndex("GROUP1");
                    b2Idx = rd.getColumnIndex("GROUP2");
                    b3Idx = rd.getColumnIndex("GROUP3");
                    yIdx  = rd.getColumnIndex("YORDINATE");

                    if (b1Idx == -1 || b2Idx == -1 || b3Idx == -1 || yIdx == -1) {
                        return new Object[0][0];
                    }
                }
                break1 = row.getString(b1Idx);
                break2 = row.getString(b2Idx);
                break3 = row.getString(b3Idx);

                List values = new ArrayList<Double>();
                while (iter.hasNext()) {

                    // found new series
                    if (!break1.equals(row.getString(b1Idx))
                        || !break2.equals(row.getString(b2Idx))
                        || !break3.equals(row.getString(b3Idx))
                        ) {

                        // get parameter name
                        String name = generateName(
                            break1, break2, break3,
                            parameters, measurements, dates
                        );

                        // add values and parameter name
                        data.add((Double[]) values.toArray(new Double[values.size()]));
                        names.add(name);

                        if (logger.isDebugEnabled()) {
                            logger.debug(" --- series name: " + name);
                            logger.debug(" --- series items: " + values.size());
                        }

                        values.clear();

                        Double yValue = row.getDouble(yIdx);
                        if (yValue != null)
                            values.add(yValue);

                        // set new conditions to find new series
                        break1 = row.getString(b1Idx);
                        break2 = row.getString(b2Idx);
                        break3 = row.getString(b3Idx);

                        previousRow = row;
                        row         = (Result) iter.next();
                    } else {

                        Double value = row.getDouble(yIdx);
                        if (value != null)
                            values.add(value);

                        row = (Result) iter.next();
                    }
                }

                Double yValue = row.getDouble(yIdx);
                if (yValue != null)
                    values.add(yValue);

                String name = generateName(
                    break1, break2, break3, parameters, measurements, dates);

                if (logger.isDebugEnabled()) {
                    logger.debug(" --- series name: " + name);
                    logger.debug(" --- series items: " + values.size());
                }

                data.add((Double[]) values.toArray(new Double[values.size()]));
                names.add(name);
            }
        }
        catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        int series = data.size();
        logger.debug(" === Found total: " + series);
        Object[][] obj = new Object[series][2];
        for (int i = 0; i < series; i++) {
            obj[i][0] = names.get(i);
            obj[i][1] = (Double[]) data.get(i);
        }

        return obj;
    }


    /**
     * This method generates a string made up of parameter name and a
     * measurement.
     *
     * @param break1 Id of a parameter.
     * @param break2 Id of a measurement.
     * @param break3 Id of a date.
     * @param parameters A collection with a bunch of parameters.
     * @param measurements A collection with a bunch of measurements.
     * @param dates A collection with a bunch of dates.
     *
     * @return Concatenated string (${parametername} + ${measurement} + m).
     */
    protected static String generateName(
        String break1, String break2, String break3,
        Collection parameters, Collection measurements, Collection dates)
    {
        return findValueTitle(parameters,break1) + " " +
               findValueTitle(measurements,break2) + "m";
    }


    /**
     * Find a value with the given <code>id</code> and return its description.
     *
     * @param values A collection which contains the value we are searching for
     * @param id Id of the value
     *
     * @return String representation of the value. An empty string is returned
     * if no value have been found with the given id.
     */
    protected static String findValueTitle(Collection values, String id) {
        if (values != null) {
            Iterator it = values.iterator();

            while (it.hasNext()) {
                KeyValueDescibeData data = (KeyValueDescibeData) it.next();

                if (id.equals(data.getKey())) {
                    return data.getValue();
                }
            }
        }
        return "";
    }


    /**
     * Creates and returns labels to decorate histograms.
     *
     * @param uuid The UUID of the current artifact.
     * @param context The CallContext object.
     * @param data An array storing strings.
     * @return A ChartLabels object with the 1st string in <i>data</i> as title.
     */
    public static ChartLabels createHistogramLabels(
        String uuid, CallContext context, Locale locale, Object[] data)
    {
        RessourceFactory fac = RessourceFactory.getInstance();

        return new ChartLabels(
            (String) data[0],
            "",
            "",
            fac.getRessource(locale, "histogram.axis.range.title", ""));
    }


    public static Object[][] prepareVectorialHistogramData(Collection input) {
        List names = new ArrayList<String>();
        List data  = new ArrayList<Double[]>();

        if (logger.isDebugEnabled()) {
            logger.debug("######### prepare vectorial histogram data #######");
            logger.debug("Input data size: " + input.size());
        }

        if (input == null) {
            return new Object[0][0];
        }

        int sIdx = -1;
        int yIdx = -1;

        String series = null;

        try {
            Iterator iter = input.iterator();

            if (iter.hasNext()) {
                Result row = (Result) iter.next();
                Result previousRow = row;

                if (sIdx == -1 || yIdx == -1) {
                    ResultDescriptor rd = row.getResultDescriptor();
                    sIdx = rd.getColumnIndex("SERIES");
                    yIdx = rd.getColumnIndex("YORDINATE");

                    if (sIdx == -1 || yIdx == -1) {
                        return new Object[0][0];
                    }
                }

                List values = new ArrayList<Double>();
                while (iter.hasNext()) {
                    row = (Result) iter.next();

                    // found new series
                    if (series != null && !series.equals(row.getString(sIdx))) {

                        // add values and parameter name
                        data.add((Double[])
                            values.toArray(new Double[values.size()]));
                        names.add(series);

                        if (logger.isDebugEnabled()) {
                            logger.debug(" --- series name: " + series);
                            logger.debug(" --- series items: " + values.size());
                        }

                        values.clear();
                    }

                    Double value = row.getDouble(yIdx);
                    if (value != null)
                        values.add(value);

                    series = row.getString(sIdx);
                }

                if (logger.isDebugEnabled()) {
                    logger.debug(" --- series name: " + series);
                    logger.debug(" --- series items: " + values.size());
                }

                data.add((Double[]) values.toArray(new Double[values.size()]));
                names.add(series);
            }
        }
        catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        int count = data.size();
        logger.debug(" === Found total: " + count);
        Object[][] obj = new Object[count][2];
        for (int i = 0; i < count; i++) {
            obj[i][0] = names.get(i);
            obj[i][1] = (Double[]) data.get(i);
        }

        return obj;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org