Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extRasterTools-SE / src / org / gvsig / raster / beans / canvas / layers / GraphicHistogram.java @ 24862

History | View | Annotate | Download (8.83 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_NONE        = -1;
41
        public static final int FUNCTION_LINEAL      = 0;
42
        public static final int FUNCTION_GAUSS       = 1;
43
        public static final int FUNCTION_EXPONENT    = 2;
44
        public static final int FUNCTION_LOGARIT     = 3;
45
        public static final int FUNCTION_SQUARE_ROOT = 4;
46
        public static final int EQUALIZATION         = 5;
47
        public static final int FUNCTION_DENSITY     = 6;
48

    
49
        private int             border               = 2;
50

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

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

    
60
        private int             typeViewed           = 0;
61

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

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

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

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

    
95
                g.setColor(color);
96

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

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

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

    
186
                                return valuesAcummulated;
187

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

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

    
229
                                return valuesAcummulatedLog;
230

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

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

    
240
                                convertToPercent(valuesLineal);
241

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

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

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