Mercurial > dive4elements > gnv-client
view gnv-artifacts/src/main/java/de/intevation/gnv/chart/DefaultHistogram.java @ 1071:9bb1979aabbe
Added a new output state and chart type for vertical profiles using vector data.
gnv-artifacts/trunk@1168 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Mon, 07 Jun 2010 15:00:23 +0000 |
parents | bb2679624c6a |
children | 86ca3c10523f |
line wrap: on
line source
package de.intevation.gnv.chart; import java.util.Map; import org.apache.log4j.Logger; import org.jfree.chart.ChartTheme; import org.jfree.chart.plot.XYPlot; /** * Default implementation of {@link de.intevation.gnv.chart.AbstractHistogram}. * * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> */ public class DefaultHistogram extends AbstractHistogram { /** * Default bin count. * TODO find a better default value */ public static final int DEFAULT_BINS = 15; /** * Constant field for limitating the number of bin in a single histogram. */ public static final int MAXIMAL_BINS = 20; /** * Default key to retrieve the number of bins from {@link * #requestParameter}. */ public static final String REQUEST_KEY_BIN_COUNT = "bincount"; /** * Default key to retrieve the width of a single bin from {@link * #requestParameter}. */ public static final String REQUEST_KEY_BIN_WIDTH = "binwidth"; /** * Default key to retrieve the chart width from {@link #requestParameter}. */ public static final String REQUEST_KEY_CHART_WIDTH = "width"; /** * Default key to retrieve the object from {@link #requestParameter}. It * defines which value this chart has to be used for bin calculation. You * can either adjust the number of bins or the width of a single bin. */ public static final String REQUEST_KEY_BIN_CHOICE = "bintype"; /** * Logger used for logging with log4j. */ private static Logger logger = Logger.getLogger(DefaultHistogram.class); /** * Object storing some further parameter used for chart settings. */ protected Map requestParameter; protected double[] minmax = null; /** * Constructor to create DefaultHistogram objects. * * @param labels Labels to decorate this chart. * @param data Raw data to be displayed in histogram. * @param theme Theme used to adjust the chart look. * @param requestParameter Object which serves some further settings. */ public DefaultHistogram( ChartLabels labels, Object[] data, ChartTheme theme, Map requestParameter ) { super(labels, data, theme); this.requestParameter = requestParameter; } @Override protected void applyDatasets() { XYPlot plot = (XYPlot) chart.getPlot(); // prepare data and create add them to histogram dataset String name = (String) data[0]; double[] values = toDouble((Double[]) data[1]); double binWidth = getBinWidth(values); int binCount = getBinCount(); AdvancedHistogramDataset dataset = new AdvancedHistogramDataset(binCount, binWidth); dataset.addSeries(name, values); plot.setDataset(0, dataset); } /** * Method which scans the hole bunch of values and returns an array with * contains min and max value. Min value is stored at position 0, max value * is stored at position 1 in that array. * * @param values Array which contains all values * * @return Array which contains min and max value */ protected double[] getMinMax(double[] values) { if (minmax != null) return minmax; double[] minmax = new double[2]; minmax[0] = Double.MAX_VALUE; minmax[1] = Double.MIN_VALUE; int length = values.length; for (int i = 0; i < length; i++) { minmax[0] = values[i] < minmax[0] ? values[i] : minmax[0]; minmax[1] = values[i] > minmax[1] ? values[i] : minmax[1]; } this.minmax = minmax; return minmax; } /** * Turn a Double[] into a double[]. * * @param array Doube[] * * @return double[] */ protected double[] toDouble(Double[] array) { int length = array.length; double[] values = new double[length]; for(int i = 0; i < length; i++) { values[i] = array[i].doubleValue(); } return values; } /** * Method to retrieve the number of bins. * * @return the number of bins that is specified in <i>requestParameter</i> * or -1 if the number of bins is not the dominant value to calculate the * width of a single bin. */ protected int getBinCount() { // Return -1 to trigger a calculation of the number of bins in // AdvancedHistogramDataset if the user chose the bin width as dominant // value. String choice = (String) requestParameter.get(REQUEST_KEY_BIN_CHOICE); if (choice != null && choice.equalsIgnoreCase(REQUEST_KEY_BIN_WIDTH)) { return -1; } int bins = -1; String param = (String) requestParameter.get(REQUEST_KEY_BIN_COUNT); try { bins = Integer.parseInt(param); bins = bins <= 0 ? DEFAULT_BINS : bins; bins = bins > MAXIMAL_BINS ? MAXIMAL_BINS : bins; return bins; } catch (NumberFormatException nfe) { logger.warn("Invalid number of bins for histogram chart: " + param); logger.warn("Return default bins: " + DEFAULT_BINS); return DEFAULT_BINS; } } /** * Serves width of a single bin. * * @param values All values in this histogram * * @return The bin width that is given in <i>requestParameter</i> or -1 if * the bin width is not the dominant value for calculating the number of * bins in the histogram. */ protected double getBinWidth(double[] values) { // Return -1 to trigger a calculation of the bin width in // AdvancedHistogramDataset if the user chose the number of bins as // dominant value. String choice = (String) requestParameter.get(REQUEST_KEY_BIN_CHOICE); if (choice == null || !choice.equalsIgnoreCase(REQUEST_KEY_BIN_WIDTH)) { return -1; } int bins = -1; String param = (String) requestParameter.get(REQUEST_KEY_BIN_WIDTH); double[] minmax = getMinMax(values); double totalWidth = minmax[1] - minmax[0]; double binWidth = Double.parseDouble(param); double tmpBins = totalWidth / binWidth; bins = (int) Math.round(tmpBins); bins = bins <= 0 ? DEFAULT_BINS : bins; // the calculated number of bins with the given width exceed the maximum // number of bins. if (bins > MAXIMAL_BINS) { return totalWidth / (MAXIMAL_BINS); } return binWidth; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :