Mercurial > dive4elements > gnv-client
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 : |