comparison gnv-artifacts/src/main/java/de/intevation/gnv/chart/DefaultHistogram.java @ 629:d08b9ba148c5

Implemented logic to adjust number of bins corresponding to user input. gnv-artifacts/trunk@706 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 24 Feb 2010 14:30:52 +0000
parents 65f09139e9b3
children 79401c871da4
comparison
equal deleted inserted replaced
628:bfe33e658576 629:d08b9ba148c5
1 package de.intevation.gnv.chart; 1 package de.intevation.gnv.chart;
2
3 import java.text.NumberFormat;
4 import java.text.ParseException;
5 import java.util.Locale;
6 import java.util.Map;
2 7
3 import org.apache.log4j.Logger; 8 import org.apache.log4j.Logger;
4 9
5 import org.jfree.chart.ChartTheme; 10 import org.jfree.chart.ChartTheme;
6 11
14 public class DefaultHistogram 19 public class DefaultHistogram
15 extends AbstractHistogram 20 extends AbstractHistogram
16 { 21 {
17 // TODO take a better default value 22 // TODO take a better default value
18 public static final int DEFAULT_BINS = 15; 23 public static final int DEFAULT_BINS = 15;
24 public static final int MAXIMAL_BINS = 20;
25 public static final String REQUEST_KEY_BIN_COUNT = "bincount";
26 public static final String REQUEST_KEY_BIN_WIDTH = "binwidth";
27 public static final String REQUEST_KEY_CHART_WIDTH = "width";
28 public static final String REQUEST_KEY_LOCALE = "locale";
29 public static final String REQUEST_KEY_BIN_CHOICE = "bintype";
19 30
20 private static Logger logger = Logger.getLogger(DefaultHistogram.class); 31 private static Logger logger = Logger.getLogger(DefaultHistogram.class);
21 32
33 protected Map requestParameter;
34
22 35
23 public DefaultHistogram( 36 public DefaultHistogram(
24 ChartLabels labels, Object[] data, ChartTheme theme 37 ChartLabels labels, Object[] data, ChartTheme theme, Map requestParameter
25 ) { 38 ) {
26 super(labels, data, theme); 39 super(labels, data, theme);
40 this.requestParameter = requestParameter;
27 } 41 }
28 42
29 43
30 protected void applyDatasets() { 44 protected void applyDatasets() {
31 XYPlot plot = (XYPlot) chart.getPlot(); 45 XYPlot plot = (XYPlot) chart.getPlot();
32 46
33 // prepare data and create add them to histogram dataset 47 // prepare data and create add them to histogram dataset
34 String name = (String) data[0]; 48 String name = (String) data[0];
35 double[] values = toDouble((Double[]) data[1]); 49 double[] values = toDouble((Double[]) data[1]);
50 int bins = getBinCount(values);
36 51
37 HistogramDataset dataset = new HistogramDataset(); 52 HistogramDataset dataset = new HistogramDataset();
38 dataset.addSeries(name, values, DEFAULT_BINS); 53 dataset.addSeries(name, values, bins);
39 54
40 plot.setDataset(0, dataset); 55 plot.setDataset(0, dataset);
56 }
57
58
59 protected double[] getMinMax(double[] values) {
60 double[] minmax = new double[2];
61 minmax[0] = Double.MAX_VALUE;
62 minmax[1] = Double.MIN_VALUE;
63
64 int length = values.length;
65 for (int i = 0; i < length; i++) {
66 minmax[0] = values[i] < minmax[0] ? values[i] : minmax[0];
67 minmax[1] = values[i] > minmax[1] ? values[i] : minmax[1];
68 }
69
70 return minmax;
41 } 71 }
42 72
43 73
44 protected double[] toDouble(Double[] array) { 74 protected double[] toDouble(Double[] array) {
45 int length = array.length; 75 int length = array.length;
49 values[i] = array[i].doubleValue(); 79 values[i] = array[i].doubleValue();
50 } 80 }
51 81
52 return values; 82 return values;
53 } 83 }
84
85
86 protected int getBinCount(double[] values) {
87 String param = (String) requestParameter.get(REQUEST_KEY_BIN_CHOICE);
88
89 if (param != null && param.equalsIgnoreCase(REQUEST_KEY_BIN_WIDTH)) {
90 return getBinCountByWidth(values);
91 }
92 else {
93 return getBinCountByNumber();
94 }
95 }
96
97
98 protected int getBinCountByNumber() {
99 int bins = -1;
100 String param = (String) requestParameter.get(REQUEST_KEY_BIN_COUNT);
101
102 try {
103 bins = Integer.parseInt(param);
104 bins = bins <= 0 ? DEFAULT_BINS : bins;
105 bins = bins > MAXIMAL_BINS ? MAXIMAL_BINS : bins;
106
107 return bins;
108 }
109 catch (NumberFormatException nfe) {
110 logger.warn("Invalid number of bins for histogram chart: " + param);
111 logger.warn("Return default bins: " + DEFAULT_BINS);
112
113 return DEFAULT_BINS;
114 }
115 }
116
117
118 protected int getBinCountByWidth(double[] values) {
119 int bins = -1;
120 String param = (String) requestParameter.get(REQUEST_KEY_BIN_WIDTH);
121 Locale locale = (Locale) requestParameter.get(REQUEST_KEY_LOCALE);
122 NumberFormat format = NumberFormat.getInstance(locale);
123
124 try {
125 double[] minmax = getMinMax(values);
126 double totalWidth = minmax[1] - minmax[0];
127 Number number = format.parse(param);
128 double binWidth = -1d;
129
130 if (number instanceof Double) {
131 binWidth = ((Double) number).doubleValue();
132 }
133 else if (number instanceof Long) {
134 binWidth = ((Long) number).doubleValue();
135 }
136 else if (number instanceof Integer) {
137 binWidth = ((Integer) number).doubleValue();
138 }
139 else {
140 logger.warn("Invalid bin width for histogram chart: " + param);
141 logger.warn("Return default bins: " + DEFAULT_BINS);
142
143 return DEFAULT_BINS;
144 }
145
146 double tmpBins = totalWidth / binWidth;
147
148 bins = (int) Math.round(tmpBins);
149 bins = bins <= 0 ? DEFAULT_BINS : bins;
150 bins = bins > MAXIMAL_BINS ? MAXIMAL_BINS : bins;
151
152 return bins;
153 }
154 catch (ParseException pe) {
155 logger.warn("Invalid bin width for histogram chart: " + param);
156 logger.warn("Return default bins: " + DEFAULT_BINS);
157
158 return DEFAULT_BINS;
159 }
160 catch (NumberFormatException nfe) {
161 logger.warn("Invalid bin width for histogram chart: " + param);
162 logger.warn("Return default bins: " + DEFAULT_BINS);
163
164 return DEFAULT_BINS;
165 }
166 }
54 } 167 }
55 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : 168 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org