comparison gnv-artifacts/src/main/java/de/intevation/gnv/chart/DefaultHistogram.java @ 1119:7c4f81f74c47

merged gnv-artifacts
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:00 +0200
parents f953c9a559d8
children
comparison
equal deleted inserted replaced
1027:fca4b5eb8d2f 1119:7c4f81f74c47
1 /*
2 * Copyright (c) 2010 by Intevation GmbH
3 *
4 * This program is free software under the LGPL (>=v2.1)
5 * Read the file LGPL.txt coming with the software for details
6 * or visit http://www.gnu.org/licenses/ if it does not exist.
7 */
8
9 package de.intevation.gnv.chart;
10
11 import java.util.Locale;
12 import java.util.Map;
13
14 import org.apache.log4j.Logger;
15
16 import org.jfree.chart.ChartTheme;
17
18 import org.jfree.chart.plot.XYPlot;
19
20 /**
21 * Default implementation of {@link de.intevation.gnv.chart.AbstractHistogram}.
22 *
23 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
24 */
25 public class DefaultHistogram
26 extends AbstractHistogram
27 {
28 /**
29 * Default bin count.
30 * TODO find a better default value
31 */
32 public static final int DEFAULT_BINS = 15;
33
34 /**
35 * Constant field for limitating the number of bin in a single histogram.
36 */
37 public static final int MAXIMAL_BINS = 20;
38
39 /**
40 * Default key to retrieve the number of bins from {@link
41 * #requestParameter}.
42 */
43 public static final String REQUEST_KEY_BIN_COUNT = "bincount";
44
45 /**
46 * Default key to retrieve the width of a single bin from {@link
47 * #requestParameter}.
48 */
49 public static final String REQUEST_KEY_BIN_WIDTH = "binwidth";
50
51 /**
52 * Default key to retrieve the chart width from {@link #requestParameter}.
53 */
54 public static final String REQUEST_KEY_CHART_WIDTH = "width";
55
56 /**
57 * Default key to retrieve the object from {@link #requestParameter}. It
58 * defines which value this chart has to be used for bin calculation. You
59 * can either adjust the number of bins or the width of a single bin.
60 */
61 public static final String REQUEST_KEY_BIN_CHOICE = "bintype";
62
63 /**
64 * Logger used for logging with log4j.
65 */
66 private static Logger logger = Logger.getLogger(DefaultHistogram.class);
67
68 /**
69 * Object storing some further parameter used for chart settings.
70 */
71 protected Map requestParameter;
72
73 protected double[] minmax = null;
74
75
76 /**
77 * Constructor to create DefaultHistogram objects.
78 *
79 * @param labels Labels to decorate this chart.
80 * @param data Raw data to be displayed in histogram.
81 * @param theme Theme used to adjust the chart look.
82 * @param requestParameter Object which serves some further settings.
83 */
84 public DefaultHistogram(
85 ChartLabels labels, Object[] data, ChartTheme theme, Map requestParameter
86 ) {
87 super(labels, data, theme);
88 this.requestParameter = requestParameter;
89 this.locale = (Locale) requestParameter.get("locale");
90 }
91
92
93 @Override
94 protected void applyDatasets() {
95 XYPlot plot = (XYPlot) chart.getPlot();
96
97 // prepare data and create add them to histogram dataset
98 String name = (String) data[0];
99 double[] values = toDouble((Double[]) data[1]);
100
101 double binWidth = getBinWidth(values);
102 int binCount = getBinCount();
103
104 AdvancedHistogramDataset dataset =
105 new AdvancedHistogramDataset(binCount, binWidth);
106 dataset.addSeries(name, values);
107
108 plot.setDataset(0, dataset);
109 }
110
111
112 /**
113 * Method which scans the hole bunch of values and returns an array with
114 * contains min and max value. Min value is stored at position 0, max value
115 * is stored at position 1 in that array.
116 *
117 * @param values Array which contains all values
118 *
119 * @return Array which contains min and max value
120 */
121 protected double[] getMinMax(double[] values) {
122 if (minmax != null)
123 return minmax;
124
125 double[] minmax = new double[2];
126 minmax[0] = Double.MAX_VALUE;
127 minmax[1] = Double.MIN_VALUE;
128
129 int length = values.length;
130 for (int i = 0; i < length; i++) {
131 minmax[0] = values[i] < minmax[0] ? values[i] : minmax[0];
132 minmax[1] = values[i] > minmax[1] ? values[i] : minmax[1];
133 }
134
135 this.minmax = minmax;
136
137 return minmax;
138 }
139
140
141 /**
142 * Turn a Double[] into a double[].
143 *
144 * @param array Doube[]
145 *
146 * @return double[]
147 */
148 protected double[] toDouble(Double[] array) {
149 int length = array.length;
150 double[] values = new double[length];
151
152 for(int i = 0; i < length; i++) {
153 values[i] = array[i].doubleValue();
154 }
155
156 return values;
157 }
158
159
160 /**
161 * Method to retrieve the number of bins.
162 *
163 * @return the number of bins that is specified in <i>requestParameter</i>
164 * or -1 if the number of bins is not the dominant value to calculate the
165 * width of a single bin.
166 */
167 protected int getBinCount() {
168 // Return -1 to trigger a calculation of the number of bins in
169 // AdvancedHistogramDataset if the user chose the bin width as dominant
170 // value.
171 String choice = (String) requestParameter.get(REQUEST_KEY_BIN_CHOICE);
172 if (choice != null && choice.equalsIgnoreCase(REQUEST_KEY_BIN_WIDTH)) {
173 return -1;
174 }
175
176 int bins = -1;
177 String param = (String) requestParameter.get(REQUEST_KEY_BIN_COUNT);
178
179 try {
180 bins = Integer.parseInt(param);
181 bins = bins <= 0 ? DEFAULT_BINS : bins;
182 bins = bins > MAXIMAL_BINS ? MAXIMAL_BINS : bins;
183
184 return bins;
185 }
186 catch (NumberFormatException nfe) {
187 logger.warn("Invalid number of bins for histogram chart: " + param);
188 logger.warn("Return default bins: " + DEFAULT_BINS);
189
190 return DEFAULT_BINS;
191 }
192 }
193
194
195 /**
196 * Serves width of a single bin.
197 *
198 * @param values All values in this histogram
199 *
200 * @return The bin width that is given in <i>requestParameter</i> or -1 if
201 * the bin width is not the dominant value for calculating the number of
202 * bins in the histogram.
203 */
204 protected double getBinWidth(double[] values) {
205 // Return -1 to trigger a calculation of the bin width in
206 // AdvancedHistogramDataset if the user chose the number of bins as
207 // dominant value.
208 String choice = (String) requestParameter.get(REQUEST_KEY_BIN_CHOICE);
209 if (choice == null || !choice.equalsIgnoreCase(REQUEST_KEY_BIN_WIDTH)) {
210 return -1;
211 }
212
213 int bins = -1;
214 String param = (String) requestParameter.get(REQUEST_KEY_BIN_WIDTH);
215
216 double[] minmax = getMinMax(values);
217 double totalWidth = minmax[1] - minmax[0];
218 double binWidth = Double.parseDouble(param);
219
220 double tmpBins = totalWidth / binWidth;
221
222 bins = (int) Math.round(tmpBins);
223 bins = bins <= 0 ? DEFAULT_BINS : bins;
224
225 // the calculated number of bins with the given width exceed the maximum
226 // number of bins.
227 if (bins > MAXIMAL_BINS) {
228 return totalWidth / (MAXIMAL_BINS);
229 }
230
231 return binWidth;
232 }
233 }
234 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org