Statistics
| Revision:

root / trunk / extensions / extRasterTools-SE / src / org / gvsig / raster / beans / canvas / layers / GraphicHistogram.java @ 21135

History | View | Annotate | Download (8.78 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2007 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.raster.beans.canvas.layers;
20

    
21
import java.awt.Color;
22
import java.awt.Graphics;
23

    
24
import org.gvsig.raster.beans.canvas.DrawableElement;
25
/**
26
 * Gr?fica que representa un histograma con los valores pasados en el constructor 
27
 *
28
 * 14-oct-2007
29
 * @author Nacho Brodin (nachobrodin@gmail.com)
30
 */
31
public class GraphicHistogram extends DrawableElement {
32
        public static final int TYPE_LINE            = 1;
33
        public static final int TYPE_FILL            = 2;
34

    
35
        public static final int VIEW_LINEAL          = 0;
36
        public static final int VIEW_ACUMMULATED     = 1;
37
        public static final int VIEW_LOGARITHMIC     = 2;
38
        public static final int VIEW_ACUMMULATEDLOG  = 3;
39
        
40
        public static final int FUNCTION_LINEAL      = 0;
41
        public static final int FUNCTION_GAUSS       = 1;
42
        public static final int FUNCTION_EXPONENT    = 2;
43
        public static final int FUNCTION_LOGARIT     = 3;
44
        public static final int FUNCTION_SQUARE_ROOT = 4;
45
        public static final int EQUALIZATION         = 5;
46
        public static final int FUNCTION_DENSITY     = 6;
47

    
48
        private int             border               = 2;
49

    
50
        // Valores de la funci?n original
51
        private double[]        histogramValues      = null;
52

    
53
        // Valores que se pintan en la gr?fica
54
        private double[]        valuesLineal         = null;
55
        private double[]        valuesAcummulated    = null;
56
        private double[]        valuesLogarithmic    = null;
57
        private double[]        valuesAcummulatedLog = null;
58

    
59
        private int             typeViewed           = 0;
60

    
61
        private int             type                 = TYPE_LINE;
62
        
63
        /**
64
         * Constructor. Asigna el color
65
         * @param c
66
         */
67
        public GraphicHistogram(Color c) {
68
                setColor(c);
69
        }
70

    
71
        /**
72
         * Constructor. Asigna el color y los valores
73
         * @param c
74
         */
75
        public GraphicHistogram(double[] values, Color c) {
76
                setColor(c);
77
                setHistogramDrawed(values);
78
        }
79

    
80
        private int valueToPixelY(double value) {
81
                value = 1.0D - value;
82
                return (int) Math.round(canvas.getCanvasMinY() + border + ((canvas.getCanvasMaxY() - canvas.getCanvasMinY() - (border * 2)) * value));
83
        }
84

    
85
        /**
86
         * Dibujado de la l?nea de incremento exponencial sobre el canvas.
87
         */
88
        protected void paint(Graphics g) {
89
                double[] valuesToDraw = recalcHistogram(typeViewed);
90
                
91
                if (valuesToDraw == null)
92
                        return;
93

    
94
                g.setColor(color);
95

    
96
                double width;
97
                switch (type) {
98
                        case TYPE_FILL:
99
                                width = canvas.getCanvasMaxX() - canvas.getCanvasMinX();
100
                                for (int i = 0; i < valuesToDraw.length; i++) {
101
                                        int x1 = (int) Math.round(((double) i - 0.5D) * (width / (valuesToDraw.length - 1.0D)));
102
                                        int x2 = (int) Math.round(((double) i + 0.5D) * (width / (valuesToDraw.length - 1.0D)));
103
                                        x1 += canvas.getCanvasMinX();
104
                                        x2 += canvas.getCanvasMinX();
105
                                        int y1 = valueToPixelY(valuesToDraw[i]);
106
                                        if (x1 < (canvas.getCanvasMinX() + border))
107
                                                x1 = canvas.getCanvasMinX() + border;
108
                                        if (x2 > (canvas.getCanvasMaxX() - border))
109
                                                x2 = canvas.getCanvasMaxX() - border;
110
                                        g.setColor(color);
111
                                        g.fillRect(x1, y1, x2 - x1, canvas.getCanvasMaxY() - border - y1);
112
                                }
113
                                break;
114
                        default:
115
                                width = canvas.getCanvasMaxX() - canvas.getCanvasMinX();
116
                                for (int i = 1; i < valuesToDraw.length; i++) {
117
                                        int x1 = (int) Math.round(canvas.getCanvasMinX() + ((i - 1.0D) * (width / (valuesToDraw.length - 1.0D))));
118
                                        int x2 = (int) Math.round(canvas.getCanvasMinX() + (i * (width / (valuesToDraw.length - 1.0D))));
119
                                        g.drawLine(x1, valueToPixelY(valuesToDraw[i - 1]), x2, valueToPixelY(valuesToDraw[i]));
120
                                }
121
                                break;
122
                }
123
        }
124

    
125
        /**
126
         * Asigna el tipo de gr?fica a mostrar. El tipo de gr?fica est? definida por las constantes TYPE 
127
         * definidas en esta clase. Por defecto siempre se muestra el tipo LINE
128
         * @param type
129
         */
130
        public void setType(int type) {
131
                this.type = type;
132
        }
133
        
134
        /**
135
         * Asigna el tipo de vista para el histograma a mostrar. No hace un repintado
136
         * @param type
137
         */
138
        public void setTypeViewed(int type) {
139
                this.typeViewed = type;
140
        }
141
        
142
        /**
143
         * Convertimos los valores del histograma a visualizar a una escala de
144
         * porcentajes que es lo que representa visualmente el componente
145
         * @param values
146
         */
147
        private void convertToPercent(double[] values) {
148
                double max = Double.NEGATIVE_INFINITY;
149
                for (int i = 0; i < values.length; i++)
150
                        if (values[i] > max)
151
                                max = values[i];
152
                
153
                for (int i = 0; i < values.length; i++)
154
                        values[i] = values[i] / max;
155
        }
156
        
157
        /**
158
         * Calculamos el histograma a dibujar en cuestion. Los tipos son:<p>
159
         *         VIEW_LINEAL<br>
160
         *         VIEW_ACUMMULATED<br>
161
         *         VIEW_LOGARITHMIC
162
         * 
163
         * @param type
164
         * @return
165
         */
166
        private double[] recalcHistogram(int type) {
167
                double min;
168
                if (histogramValues == null)
169
                        histogramValues = new double[0];
170
                switch (type) {
171
                        // Calcular la grafica acumulada
172
                        case VIEW_ACUMMULATED:
173
                                // Si ya estan calculados, no los vuelve a calcular
174
                                if (valuesAcummulated != null) return valuesAcummulated;
175

    
176
                                valuesAcummulated = new double[histogramValues.length];
177
                                if (valuesAcummulated.length >= 1) {
178
                                        valuesAcummulated[0] = histogramValues[0];
179
                                        for (int i = 1; i < histogramValues.length; i++)
180
                                                valuesAcummulated[i] = histogramValues[i] + valuesAcummulated[i - 1];
181
                                }
182
                                
183
                                convertToPercent(valuesAcummulated);
184

    
185
                                return valuesAcummulated;
186

    
187
                        // Calcular la grafica logaritmica
188
                        case VIEW_LOGARITHMIC:
189
                                // Si ya estan calculados, no los vuelve a calcular
190
                                if (valuesLogarithmic != null) return valuesLogarithmic;
191
                                
192
                                min = Double.MAX_VALUE;
193
                                for (int i = 0; i < histogramValues.length; i++)
194
                                        if (histogramValues[i] < min)
195
                                                min = histogramValues[i];
196
                                
197
                                valuesLogarithmic = new double[histogramValues.length];
198
                                for (int i = 0; i < histogramValues.length; i++)
199
                                        valuesLogarithmic[i] = java.lang.Math.log(histogramValues[i] - min + 1.0);
200
                                
201
                                convertToPercent(valuesLogarithmic);
202
                                
203
                                return valuesLogarithmic;
204
                                
205
                                
206
                                // Calcular la grafica acumulada
207
                        case VIEW_ACUMMULATEDLOG:
208
                                // Si ya estan calculados, no los vuelve a calcular
209
                                if (valuesAcummulatedLog != null) return valuesAcummulatedLog;
210

    
211
                                valuesAcummulatedLog = new double[histogramValues.length];
212
                                if (valuesAcummulatedLog.length >= 1) {
213
                                        valuesAcummulatedLog[0] = histogramValues[0];
214
                                        for (int i = 1; i < histogramValues.length; i++)
215
                                                valuesAcummulatedLog[i] = histogramValues[i] + valuesAcummulatedLog[i - 1];
216
                                }
217
                                
218
                                min = Double.MAX_VALUE;
219
                                for (int i = 0; i < valuesAcummulatedLog.length; i++)
220
                                        if (valuesAcummulatedLog[i] < min)
221
                                                min = valuesAcummulatedLog[i];
222
                                
223
                                for (int i = 0; i < valuesAcummulatedLog.length; i++)
224
                                        valuesAcummulatedLog[i] = java.lang.Math.log(valuesAcummulatedLog[i] - min + 1.0);
225
                                
226
                                convertToPercent(valuesAcummulatedLog);
227

    
228
                                return valuesAcummulatedLog;
229

    
230
                        // Si no es logaritmica ni acumulada, lo tratamos como si fuera lineal
231
                        default:
232
                                // Si ya estan calculados, no los vuelve a calcular
233
                                if (valuesLineal != null) return valuesLineal;
234

    
235
                                valuesLineal = new double[histogramValues.length];
236
                                for (int i = 0; i < histogramValues.length; i++)
237
                                        valuesLineal[i] = histogramValues[i];
238

    
239
                                convertToPercent(valuesLineal);
240

    
241
                                return valuesLineal;
242
                }
243
        }
244
        
245
        /**
246
         * Asigna el histograma a visualizar
247
         * @param histogramDrawed
248
         */
249
        public void setHistogramDrawed(double[] histogramDrawed) {
250
                histogramValues = histogramDrawed;
251

    
252
                valuesLineal = null;
253
                valuesAcummulated = null;
254
                valuesLogarithmic = null;
255
                valuesAcummulatedLog = null;
256
                
257
                if (canvas != null)
258
                        canvas.repaint();
259
        }
260

    
261
        /**
262
         * Devuelve la forma en la que se dibujara el histograma. Posibilidades:<br>
263
         * TYPE_LINE<br>
264
         * TYPE_FILL
265
         * @return the type
266
         */
267
        public int getType() {
268
                return type;
269
        }
270
        
271
        /**
272
         * Devuelve la forma que tendr? la grafica del histograma. Posibilidades:<br>
273
         * VIEW_LINEAL<br>
274
         * VIEW_ACUMMULATED<br>
275
         * VIEW_LOGARITHMIC<br>
276
         * VIEW_ACUMMULATEDLOG<br>
277
         * 
278
         * @return the typeViewed
279
         */
280
        public int getTypeViewed() {
281
                return typeViewed;
282
        }
283
        
284
        /**
285
         * @return the histogramValues
286
         */
287
        public double[] getHistogramValues() {
288
                return histogramValues;
289
        }
290
        
291
        public void firstActions() {}
292
        public void firstDrawActions() {}
293
}