3 // MultiDoubleVisComp.java
6 // Chris Gill (core graph functionality), based on
7 // DoubleVisComp.java by Seth Widoff, and Michael Kircher
11 // This is a Visualization Component for displaying multiple
12 // plots of double precision integer values.
14 // ============================================================================
20 public class MultiDoubleVisComp
extends Canvas
implements VisComp
22 private static int plot_count_default_
= 5;
24 private static final int MIN_SPACING
= 2;
25 private static final int POINT_HISTORY
= 200;
26 private static final Font FONT
= new Font ("Dialog", Font
.PLAIN
, 10);
28 private Queue plots_
[];
29 private int plot_count_
= 0;
30 private String title_
;
31 private Graphics offgraphics_
;
32 private Image offscreen_
;
33 private Dimension offscreensize_
;
34 private int max_value_
;
35 private int old_max_value_
;
37 private boolean max_increased_
= false;
38 private static boolean monotonic_scale_
= false;
40 private float local_max_
[];
41 private static float local_max_values_
[];
42 private static int local_max_value_count_
= 0;
43 private int local_max_value_index_
[];
45 public MultiDoubleVisComp ()
49 // Re-initialize the global and local arrays of local maxima.
50 local_max_init (plot_count_default_
);
52 // Set up the array of plot queues
53 plot_count_
= plot_count_default_
;
54 plots_
= new Queue
[plot_count_
];
55 for (int i
= 0; i
< plot_count_
; ++i
)
57 plots_
[i
] = new Queue ();
60 spacing_
= MIN_SPACING
;
63 old_max_value_
= max_value_
;
65 java
.util
.Random rand
= new java
.util
.Random (System
.currentTimeMillis ());
66 float hue_
= rand
.nextFloat ();
67 float brightness
= rand
.nextFloat ();
74 if (brightness
> 0.75)
77 Color new_color
= Color
.getHSBColor (hue_
, 1, brightness
);
79 this.setBackground (new_color
);
80 this.setForeground (Color
.white
);
83 public static synchronized void plot_count_default (int d
) {
84 plot_count_default_
= d
;
87 public static synchronized int plot_count_default () {
88 return plot_count_default_
;
91 public static synchronized void monotonic_scale (boolean b
) {
95 public static synchronized boolean monotonic_scale () {
96 return monotonic_scale_
;
99 public void resize (int new_plot_count
)
101 if (new_plot_count
> plot_count_
)
103 // Re-initialize the global and local arrays of local maxima.
104 local_max_init (new_plot_count
);
106 // Set up the array of plot queues
107 Queue plots_temp
[] = new Queue
[new_plot_count
];
108 for (int i
= 0; i
< new_plot_count
; ++i
)
112 plots_temp
[i
] = plots_
[i
];
116 plots_temp
[i
] = new Queue ();
123 plot_count_
= new_plot_count
;
128 public void setName (String title
) {
132 public int getProperty () {
133 return Properties
.MULTIDOUBLE
;
136 public Dimension
getMinimumSize () {
137 return new Dimension (75, 75);
140 public Dimension
getPreferredSize () {
141 return new Dimension (175, 175);
144 public String
getName () {
148 public int getMax () {
149 return old_max_value_
;
152 public void update (java
.util
.Observable observable
, java
.lang
.Object obj
)
154 Double double_array
[];
156 double_array
= (Double
[]) obj
;
158 catch (Exception excp
) {
159 double_array
= new Double
[plot_count_
];
160 for (int j
= 0; j
< plot_count_
; ++j
)
162 double_array
[j
] = new Double (0.0);
164 System
.out
.println (excp
);
165 System
.out
.println ("Multi Double Visualization Component received wrong data type!");
168 for (int i
= 0; i
< double_array
.length
&& i
< plot_count_
; ++i
)
170 float new_point
= double_array
[i
].floatValue ();
171 Float temp
= (Float
) plots_
[i
].dequeue_tail ();
172 plots_
[i
].enqueue_head (new Float (new_point
));
174 if (new_point
> local_max_
[i
])
176 local_max_
[i
] = new_point
;
177 local_max_values_
[local_max_value_index_
[i
]] = local_max_
[i
];
180 if (monotonic_scale_
)
182 float global_max
= 0;
183 global_max
= global_max_value ();
185 while (global_max
> max_value_
)
188 while ((global_max
< max_value_
/2) && (max_value_
> old_max_value_
))
193 while (local_max_
[i
] > max_value_
)
196 while ((local_max_
[i
] < max_value_
/2) && (max_value_
> old_max_value_
))
205 public void update (Graphics g
)
208 float tmp
, value_1
, value_2
;
209 Dimension d
= getSize ();
210 FontMetrics fm
= g
.getFontMetrics ();
211 int fheight
= fm
.getHeight ();
212 String value
= "Scale: " + max_value_
;
214 if ((offscreen_
== null) ||
215 (offscreensize_
.width
!= d
.width
- 8) ||
216 (offscreensize_
.height
!= d
.height
- 8))
218 offscreen_
= createImage (d
.width
- 8, d
.height
- 8);
219 offscreensize_
= new Dimension (d
.width
- 8, d
.height
- 8);
220 offgraphics_
= offscreen_
.getGraphics ();
221 offgraphics_
.setFont (FONT
);
224 g
.setColor (Color
.lightGray
);
225 g
.draw3DRect (0, 0, d
.width
- 1, d
.height
- 1, true);
226 g
.draw3DRect (1, 1, d
.width
- 3, d
.height
- 3, true);
227 g
.draw3DRect (2, 2, d
.width
- 5, d
.height
- 5, true);
229 offgraphics_
.setColor (getBackground ());
230 offgraphics_
.fillRect (0, 0, offscreensize_
.width
, offscreensize_
.height
);
231 offgraphics_
.setColor (getForeground ());
232 offgraphics_
.drawString (title_
, 5, fheight
);
233 offgraphics_
.drawString (value
, 5, offscreensize_
.height
- 5);
235 for (int i
= 0; i
< plot_count_
; ++i
)
238 Enumeration queue_iter
= plots_
[i
].forward_iterator ();
239 value_1
= ((Float
) queue_iter
.nextElement ()).floatValue ();
241 while (queue_iter
.hasMoreElements ())
243 value_2
= ((Float
) queue_iter
.nextElement ()).floatValue ();
245 if (value_1
> local_max_
[i
])
246 local_max_
[i
] = value_1
;
248 y1
= normalize (offscreensize_
.height
- fheight
, value_1
, i
);
249 y2
= normalize (offscreensize_
.height
- fheight
, value_2
, i
);
256 offgraphics_
.drawLine (x1
, y1
, x2
, y2
);
262 local_max_values_
[local_max_value_index_
[i
]] = local_max_
[i
];
265 g
.drawImage (offscreen_
, 3, 3, null);
268 public void paint (Graphics g
)
270 Dimension d
= getSize ();
272 for (int i
= 0; i
< plot_count_
; ++i
)
274 int plot_length
= plots_
[i
].length ();
275 int num_points
= d
.width
/ spacing_
;
277 if (plots_
[i
].length () < num_points
)
279 for (int j
= 0; j
< num_points
- plot_length
; j
++)
280 plots_
[i
].enqueue_tail (new Float (0));
282 else if (plots_
[i
].length () > num_points
)
284 for (int j
= 0; j
< plot_length
- num_points
; j
++)
285 plots_
[i
].dequeue_tail ();
292 private static synchronized float global_max_value () {
295 for (int i
= 0; i
< local_max_value_count_
; ++i
)
297 if (result
< local_max_values_
[i
])
299 result
= local_max_values_
[i
];
306 private synchronized void local_max_init (int new_count
) {
308 if (new_count
> plot_count_
)
310 // New larger static global array of all local maxima values
311 float local_max_values_temp
[] =
312 new float [local_max_value_count_
+ new_count
- plot_count_
];
314 // Copy the previously stored maxima (if any) into the new array.
316 i
< local_max_value_count_
+ new_count
- plot_count_
;
319 if (i
< local_max_value_count_
)
321 local_max_values_temp
[i
] = local_max_values_
[i
];
325 local_max_values_temp
[i
] = 0;
329 // Create new, larger, non-static arrays for the local maxima, indices
330 float local_max_temp
[] = new float [new_count
];
331 int local_max_value_index_temp
[] = new int [new_count
];
333 for (int j
= 0; j
< new_count
; ++j
)
337 local_max_temp
[j
] = local_max_
[j
];
338 local_max_value_index_temp
[j
] = local_max_value_index_
[j
];
342 local_max_temp
[j
] = 0;
343 local_max_value_index_temp
[j
] =
344 local_max_value_count_
+ j
- plot_count_
;
348 // Store the newly (re)allocated arrays, set the new global array count
349 local_max_values_
= local_max_values_temp
;
350 local_max_
= local_max_temp
;
351 local_max_value_index_
= local_max_value_index_temp
;
352 local_max_value_count_
+= new_count
- plot_count_
;
357 private int normalize (int height
, float coord
, int plot_index
)
359 // First, figure out the ratio of the value to the max value
360 float ratio
= (float) coord
/max_value_
;
362 // Second, compute pixel location based on which plot we're drawing
363 float pixels
= (float) (height
*(plot_index
+ ratio
))/plot_count_
;
365 // Then, subtract the pixel location
366 float location
= (float) height
- pixels
;
368 return Math
.round (location
);