Source code: cor/gui/prf/JspmPerfHisto.java
1 /*-----------------------------------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (C) */
4 /* */
5 /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU */
6 /* General Public License as published by the Free Software Foundation; either version 2 of the */
7 /* License, or (at your option) any later version. */
8 /* */
9 /* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; */
10 /* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
11 /* PURPOSE. See the GNU General Public License for more details. */
12 /* */
13 /* You should have received a copy of the GNU General Public License along with this program; if */
14 /* not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */
15 /* 02111-1307 USA */
16 /* */
17 /*-----------------------------------------------------------------------------------------------------*/
18 /* */
19 /* $Author: strand01 $ $Revision: 1.3 $ $Date: 2001/12/20 14:23:02 $ */
20 /* */
21 /*-----------------------------------------------------------------------------------------------------*/
22
23 package cor.gui.prf;
24
25 // Java packages
26 import java.awt.event.*;
27 import java.awt.*;
28 import java.applet.*;
29 import java.util.*;
30
31 // Swing packages
32 import javax.swing.*;
33
34 /**
35 * This class generated the the histograms for the Jspm performance management GUI. Each histogram can contains
36 * several charts, which are overlayed.
37 *
38 * Options can be set by using one of the following function:
39 * - SetStrAttr: Set a string attribute. String attributes can be:
40 * -# FrameLayout: Set the frame layout (shadow or not).
41 * -# Title: Set the title of the histogram.
42 * -# Legend: Sets the legend string which describes the different charts
43 * - SetBoolAttr: Set a boolean attribute. Boolean attrbutes can be one of:
44 * -# FixedMinY: Set the YAxis minimum to a certain value.
45 * -# FixedMaxY: Set the YAxis maximum to a certain value.
46 * -# ShowThres: Set the show threshold flag.
47 * -# GridX: Set the X-Grid ON/OFF.
48 * -# GridX: Set the Y-Grid ON/OFF.
49 * - SetColor: Will set one of the colors. Color attributes can be:
50 * -# GraphColor: Sets the graph color.
51 * -# TitleColor: Sets the title color.
52 * -# LabelColor: Sets the label color.
53 * - SetFontAttr: Sets one of the fonts. Valid font attributes are:
54 * -# Title: Sets the title font.
55 * -# X-Labels: Sets the X label font.
56 * -# Y-Labels: Sets the Y label font.
57 * -# Legend: Sets the legend font.
58 * - SetIntAttr: Sets one of the integer attributes. Valid integer attributes are:
59 * -# PXSIZE: Width of the histogram.
60 * -# PYSIZE: Height of the histogram.
61 * -# XLMARGIN: Left margin of the histogram.
62 * -# XRMARGIN: Right Margin of the histogram.
63 * -# YTMARGIN: Top Y margin.
64 * -# YBMARGIN: Bottom Y margin.
65 * -# currentTime: Current time for the real time histogram.
66 * - SetDoubleAttr: Sets one of the double attributes. Valid double attributes are:
67 * -# ymin: Minimum Y axis.
68 * -# ymax: Maximum Y axis.
69 *
70 * All attributes should be given as they appear here in the list.
71 *
72 * Several options can be set for the histogram. In detail this are:
73 * - logarithmic scale. All labels, grids and values will be transformed to a logarithmic scale.
74 * - grid in X and Y in light gray.
75 * - fixed minimum Y. In case fixedMinY is switched ON the user has to give the minimum value for the
76 * display of the graphs.
77 * - fixed maximum Y. In case fixedMaxY is switched ON the user has to give the maximum value for the
78 * display of the graphs.
79 *
80 * @author Steve Randall (strand012001@yahoo.com)
81 * @version 0.0.2
82 * @date 27/08/2001
83 */
84 public class JspmPerfHisto extends JPanel implements Runnable
85 {
86 /**
87 * Width of the histogram space
88 */
89 private int PXSIZE;
90
91 /**
92 * Height of the histogram space
93 */
94 private int PYSIZE;
95
96 /**
97 * Left margin of the histogram itself
98 */
99 private int XLMARGIN;
100
101 /**
102 * Right margin of the histogram itself
103 */
104 private int XRMARGIN;
105
106 /**
107 * Top margin
108 */
109 private int YTMARGIN;
110
111 /**
112 * Bottom margin.
113 */
114 private int YBMARGIN;
115
116 /**
117 * Maximal number of overlayed histos
118 */
119 private int MAX_HISTO = 8;
120
121 /**
122 * Number of data points for the different charts.
123 */
124 private int np[];
125
126 /**
127 * Number of X-axis labels
128 */
129 private int nxLabels = 25;
130
131 /**
132 * Number of charts.
133 */
134 private int nHist = 0;
135
136 /**
137 * Total number of all points in all charts.
138 */
139 private int nt = 0;
140
141 /**
142 * Data points in X
143 */
144 private double xData[];
145
146 /**
147 * Y coordinate of all points
148 */
149 private double yData[];
150
151 /**
152 * Minimum in Y
153 */
154 private double ymin = 0.0;
155
156 /**
157 * Maximum in Y
158 */
159 private double ymax = 100.0;
160
161 /**
162 * Gap in Y.
163 */
164 private double ygap = 10.0;
165
166 /**
167 * Scale in X
168 */
169 private double xscale = 0.0;
170
171 /**
172 * Scale in X
173 */
174 private double yscale = 0.0;
175
176 /**
177 * Minimum critical thresholds
178 */
179 private double minCrit[];
180
181 /**
182 * Minimum warning thresholds
183 */
184 private double minWarn[];
185
186 /**
187 * Maximum warning thresholds
188 */
189 private double maxWarn[];
190
191 /**
192 * Maximum critical thresholds
193 */
194 private double maxCrit[];
195
196 /**
197 * Fixed minimum Y axis flag
198 */
199 private boolean fixedMinY = false;
200
201 /**
202 * Fixed maximum Y axis flag
203 */
204 private boolean fixedMaxY = false;
205
206 /**
207 * X-grid flag
208 */
209 private boolean XGRID = true;
210
211 /**
212 * Y-grid
213 */
214 private boolean YGRID = true;
215
216 /**
217 * Small X ticks.
218 */
219 private int smallTicks = 3;
220
221 /**
222 * Data initialization flag
223 */
224 private boolean dataSet = false;
225
226 /**
227 * Log scale flag
228 */
229 private boolean logScale = false;
230
231 /**
232 * Show thresholds flag
233 */
234 private boolean showThres = false;
235
236 /**
237 * Label color
238 */
239 private Color labelColor;
240
241 /**
242 * Title color
243 */
244 private Color titleColor;
245
246 /**
247 * The color table for the charts
248 */
249 private Color graphColor[] = {Color.red, Color.green, Color.magenta, Color.cyan, Color.blue, Color.pink,
250 Color.orange, Color.yellow};
251
252 /**
253 * The frame layout
254 */
255 String frameLayout = "Shadow";
256
257 /**
258 * Title
259 */
260 private String title = "Jspm Performance Management";
261
262 /**
263 * Legend vector
264 */
265 private Vector legend = new Vector();
266
267 /**
268 * X-labels
269 */
270 private String xLabels[];
271
272 /**
273 * Current time for real time view
274 */
275 int currentTime = 0;
276
277 /**
278 * Realtime flag
279 */
280 private boolean realTime = false;
281
282 /**
283 * Title font. Default is Courir, bold, 12.
284 */
285 private Font titleFont = new Font( "Courir", Font.BOLD, 12 );
286
287 /**
288 * X axis labels font
289 */
290 private Font xLabelFont = new Font( "Ariel", Font.PLAIN, 10 );
291
292 /**
293 * Y axis labels font
294 */
295 private Font yLabelFont = new Font( "Ariel", Font.PLAIN, 10 );
296
297 /**
298 * X axis labels font
299 */
300 private Font legendFont = new Font( "Ariel", Font.PLAIN, 10 );
301
302 /**
303 * Blinking thread
304 */
305 private Thread histoThread;
306
307 /**
308 * Running flag.
309 */
310 private boolean running;
311
312 /**
313 * Constructor.
314 *
315 * The following defaults will be set:
316 * - PXSIZE: 700
317 * - PYSIZE: 400
318 * - XLMARGIN: 80
319 * - XRMARGIN: 80
320 * - YTMARGIN: 30
321 * - YBMARGIN: 60
322 * - GridX: true
323 * - GridY: true
324 * - Frame: "Shadow"
325 * - TitleColor: black
326 * - LabelColor: black
327 */
328 public JspmPerfHisto() {
329 np = new int[MAX_HISTO];
330 setIntAttr("PXSIZE", 700);
331 setIntAttr("PYSIZE", 400);
332 setIntAttr("XLMARGIN", 80);
333 setIntAttr("XRMARGIN", 80);
334 setIntAttr("YTMARGIN", 30);
335 setIntAttr("YBMARGIN", 60);
336 setBoolAttr("GridX", true);
337 setBoolAttr("GridY", true);
338 setStrAttr("Frame", "Shadow");
339 setColor("TitleColor", Color.black);
340 setColor("LabelColor", Color.black);
341 setSize(PXSIZE, PYSIZE);
342 }
343
344 /**
345 * Sets an String attribute.
346 *
347 * Valid attributes are:
348 * - FrameLayout: Frame type (shadow).
349 * - Title: Histogram title.
350 * - Legend: Legend attribute.
351 *
352 * @param attr (String) attribute name.
353 * @param value (String) attribute value.
354 */
355 public void setStrAttr(String attr, String value) {
356 if(attr.equals("FrameLayout")) frameLayout = value;
357 else if(attr.equals("Title")) title = value;
358 else if(attr.equals("Legend")) legend.addElement(value);
359 }
360
361 /**
362 * Sets a boolean attribute
363 *
364 * Valid attributes are:
365 * - FixedMinY: Set the YAxis minimum to a certain value.
366 * - FixedMaxY: Set the YAxis maximum to a certain value.
367 * - ShowThres: Set the show threshold flag.
368 * - GridX: Set the X-Grid ON/OFF.
369 * - GridX: Set the Y-Grid ON/OFF.
370 * - LogScale: Set the Y-axis linear/logarithmic
371 * - RealTime: Sets the realtime flag, which displays a vertical line at the current time.
372 *
373 * @param attr (String) attribute name.
374 * @param value (boolean) attribute value.
375 */
376 public void setBoolAttr(String attr, boolean value) {
377 if(attr.equals("FixedMinY")) fixedMinY = value;
378 else if(attr.equals("FixedMaxY")) fixedMaxY = value;
379 else if(attr.equals("ShowThres")) showThres = value;
380 else if(attr.equals("GridX")) XGRID = value;
381 else if(attr.equals("GridY")) YGRID = value;
382 else if(attr.equals("RealTime")) realTime = value;
383 else if(attr.equals("LogScale")) logScale = value;
384 }
385
386 /**
387 * Sets a color attribute
388 *
389 * Valid attributes are:
390 * - GraphColor: Sets the graph color.
391 * - TitleColor: Sets the title color.
392 * - LabelColor: Sets the label color.
393 *
394 * @param attr (String) attribute name.
395 * @param col (Color) attribute color.
396 */
397 public void setColor(String attr, Color col) {
398 if(attr.equals("GraphColor")) graphColor[nHist] = col;
399 else if(attr.equals("TitleColor")) titleColor = col;
400 else if(attr.equals("LabelColor")) labelColor = col;
401 }
402
403 /**
404 * Sets an font attribute
405 *
406 * Valid attributes are
407 * - Title: Sets the title font.
408 * - X-Labels: Sets the X label font.
409 * - Y-Labels: Sets the Y label font.
410 * - Legend: Sets the legend font.
411 *
412 * @param attr (String) attribute name.
413 * @param font (Font) attribute font.
414 */
415 public void setFont(String attr, Font font) {
416 if(attr.equals("Title")) titleFont = font;
417 if(attr.equals("X-Labels")) xLabelFont = font;
418 if(attr.equals("Y-Labels")) yLabelFont = font;
419 if(attr.equals("Legend")) legendFont = font;
420 }
421
422 /**
423 * Sets an integer attribute.
424 *
425 * Valid attributes are:
426 * - PXSIZE: Width of the histogram.
427 * - PYSIZE: Height of the histogram.
428 * - XLMARGIN: Left margin of the histogram.
429 * - XRMARGIN: Right margin of the histogram.
430 * - YTMARGIN: Top Y margin.
431 * - YBMARGIN: Bottom Y margin.
432 *
433 * @param attr (String) attribute name.
434 * @param value (int) attribute value.
435 */
436 public void setIntAttr(String attr, int value) {
437 if(attr.equals("PXSIZE")) PXSIZE = value;
438 else if(attr.equals("PYSIZE")) PYSIZE = value;
439 else if(attr.equals("XLMARGIN")) XLMARGIN = value;
440 else if(attr.equals("XRMARGIN")) XRMARGIN = value;
441 else if(attr.equals("YTMARGIN")) YTMARGIN = value;
442 else if(attr.equals("YBMARGIN")) YBMARGIN = value;
443 else if(attr.equals("smallXTicks")) smallTicks = value;
444 else if(attr.equals("currentTime")) currentTime = value;
445 }
446
447 /**
448 * Sets a double attribute.
449 *
450 * Valid attribute names are:
451 * - ymin: Minimum Y axis.
452 * - ymax: Maximum Y axis.
453 *
454 * @param attr (String) attribute name.
455 * @param value (double) attribute value.
456 */
457 public void setDoubleAttr(String attr, double value) {
458 if( attr.equals( "ymin" ) ) ymin = value;
459 else if( attr.equals( "ymax" ) ) ymax = value;
460 }
461
462 /**
463 * Sets the X labels
464 *
465 * @param l (String[]) label strings.
466 * @param num (int) number of labels.
467 */
468 public void setXLabels(String l[], int num) {
469 xLabels = new String[num];
470
471 nxLabels = num;
472 for(int i = 0; i < nxLabels; i++)
473 xLabels[i] = l[i];
474 }
475
476 /**
477 * Sets the data arrays
478 *
479 * @param y (double[]) Y-values.
480 * @param n (int) number of values.
481 */
482 public void setData(double y[], int n)
483 {
484 if( nHist == 0 ) {
485 yData = new double[n];
486 for( int i = 0; i < n; i++ ) {
487 yData[i] = y[i];
488 }
489 } else {
490 double ytmp[] = new double[nt+n];
491
492 for( int i = 0; i < nt; i++ ) {
493 ytmp[i] = yData[i];
494 }
495 for( int i = 0; i < n; i++ ) {
496 ytmp[nt+i] = y[i];
497 }
498
499 yData = new double[nt+n];
500 for( int i = 0; i < nt+n; i++ ) {
501 yData[i] = ytmp[i];
502 }
503 }
504 nt += n;
505 np[nHist] = n;
506 nHist++;
507 dataSet = true;
508 }
509
510 /**
511 * Calculates the logarithm to base 10.
512 *
513 * @param x (double) value.
514 * @return x (double) log10(x)
515 */
516 double log10( double x )
517 {
518 return (Math.log(x)/Math.log(10) );
519 }
520
521 /**
522 * Sets the thresholds arrays.
523 *
524 * @param minCrit (double[]) minimum critical thresholds.
525 * @param minCrit (double[]) minimum warning thresholds.
526 * @param minCrit (double[]) maximum warning thresholds.
527 * @param minCrit (double[]) maximum critical thresholds.
528 * @param n (int) number of values.
529 */
530 public void setThres(double minC[], double minW[], double maxW[], double maxC[], int n) {
531
532 minCrit = new double[n];
533 minWarn = new double[n];
534 maxWarn = new double[n];
535 maxCrit = new double[n];
536 for(int i = 0; i < n; i++) {
537 minCrit[i] = minC[i];
538 minWarn[i] = minW[i];
539 maxWarn[i] = maxW[i];
540 maxCrit[i] = maxC[i];
541 }
542 }
543
544 /**
545 * Draws the X-ticks
546 *
547 * @param g (Graphics) Graphics device.
548 */
549 private void drawXTicks( Graphics g) {
550 for(int i = 0; i < smallTicks * (nxLabels - 1); i++)
551 g.drawLine(XLMARGIN+(int)(i*(PXSIZE-XLMARGIN-XRMARGIN)/(smallTicks*(nxLabels-1))), PYSIZE-YBMARGIN,
552 XLMARGIN+(int)(i*(PXSIZE-XLMARGIN-XRMARGIN)/(smallTicks*(nxLabels-1))), PYSIZE-YBMARGIN+4);
553 }
554
555 /**
556 * Draws the Y-ticks
557 *
558 * @param g (Graphics) Graphics device.
559 */
560 private void drawYTicks( Graphics g) {
561
562 for(int i = 0; i < 11; i++) {
563 if(logScale) {
564 double dd = log10(i*( ymax-ymin )/ygap/11);
565 if(i == 0) {
566 g.drawLine(XLMARGIN-6, PYSIZE-YBMARGIN, XLMARGIN, PYSIZE-YBMARGIN);
567 } else {
568 g.drawLine(XLMARGIN-6, PYSIZE-YBMARGIN-(int)(log10(i*10)/2*(PYSIZE-YTMARGIN-YBMARGIN)),
569 XLMARGIN, PYSIZE-YBMARGIN-(int)(log10(i*10)/2*(PYSIZE-YTMARGIN-YBMARGIN)));
570 if(dd > 0)
571 g.drawLine(XLMARGIN-4, PYSIZE-YBMARGIN-(int)(dd/2*(PYSIZE-YTMARGIN-YBMARGIN)),
572 XLMARGIN, PYSIZE-YBMARGIN-(int)(dd/2*(PYSIZE-YTMARGIN-YBMARGIN)));
573 }
574
575 if(i % 2 == 0)
576 g.drawLine(XLMARGIN-4, PYSIZE-YBMARGIN-(int)(log10(i*(( ymax - ymin )/ygap/11)+10)/2*
577 (PYSIZE-YTMARGIN-YBMARGIN)),
578 XLMARGIN, PYSIZE-YBMARGIN-(int)(log10(i*(( ymax - ymin )/ygap/11)+10)/2*
579 (PYSIZE-YTMARGIN-YBMARGIN)));
580 if(i % 3 == 0)
581 g.drawLine(XLMARGIN-4, PYSIZE-YBMARGIN-(int)(log10(i*(( ymax - ymin )/ygap/11)+20)/2*
582 (PYSIZE-YTMARGIN-YBMARGIN)),
583 XLMARGIN, PYSIZE-YBMARGIN-(int)(log10(i*(( ymax - ymin )/ygap/11)+20)/2*
584 (PYSIZE-YTMARGIN-YBMARGIN)));
585 if(i % 5 == 0)
586 g.drawLine(XLMARGIN-4, PYSIZE-YBMARGIN-(int)(log10(i*(( ymax - ymin )/ygap/11)+30)/2*
587 (PYSIZE-YTMARGIN-YBMARGIN)),
588 XLMARGIN, PYSIZE-YBMARGIN-(int)(log10(i*(( ymax - ymin )/ygap/11)+30)/2*
589 (PYSIZE-YTMARGIN-YBMARGIN)));
590
591 } else {
592 g.drawLine(XLMARGIN-4, YTMARGIN+(int)(i*((PYSIZE-YTMARGIN-YBMARGIN)/ygap)),
593 XLMARGIN, YTMARGIN+(int)(i*((PYSIZE-YTMARGIN-YBMARGIN)/ygap)));
594 }
595 }
596 }
597
598 /**
599 * Draws the X-Grid
600 *
601 * @param g (Graphics) Graphics device.
602 */
603 private void drawXGrid(Graphics g)
604 {
605 g.setColor( Color.lightGray );
606 for(int i = 0; i < smallTicks*(nxLabels-1); i++)
607 g.drawLine(XLMARGIN+(int)(i*(PXSIZE-XLMARGIN-XRMARGIN)/(smallTicks*(nxLabels-1))), PYSIZE-YBMARGIN,
608 XLMARGIN+(int)(i*(PXSIZE-XLMARGIN-XRMARGIN)/(smallTicks*(nxLabels-1))), YTMARGIN);
609 }
610
611 /**
612 * Draws the thresholds
613 *
614 * @param g (Graphics) Graphics device.
615 */
616 private void drawThres( Graphics g )
617 {
618 int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
619 for(int j = 0; j < np[0]-1; j++) {
620 x1 = XLMARGIN+(int)(j*xscale)+2;
621 x2 = XLMARGIN+(int)((j+1)*xscale)+2;
622 y1 = PYSIZE-YBMARGIN-(int)(maxCrit[j]*yscale)-1;
623 y2 = PYSIZE-YBMARGIN-(int)(maxCrit[j]*yscale)-1;
624 if(y1 < YTMARGIN) y1 = YTMARGIN+2;
625 if(y2 < YTMARGIN) y2 = YTMARGIN+2;
626 if(y1 != YTMARGIN+2 || y2 != YTMARGIN+2)
627 g.drawLine(x1, y1, x2, y2);
628 }
629 }
630
631 /**
632 * Draws the Y-Grid
633 *
634 * @param g (Graphics) Graphics device.
635 */
636 private void drawYGrid(Graphics g)
637 {
638 g.setColor(Color.lightGray);
639 for(int i = 0; i < 11; i++) {
640 if( logScale ) {
641 g.drawLine(XLMARGIN, YTMARGIN+(int)(log10(i*10)/2*(PYSIZE-YTMARGIN-YBMARGIN)),
642 PXSIZE-XRMARGIN, YTMARGIN+(int)(log10(i*10)/2*(PYSIZE-YTMARGIN-YBMARGIN)));
643 } else {
644 g.drawLine(XLMARGIN, YTMARGIN+(int)(i*((PYSIZE-YTMARGIN-YBMARGIN)/ygap)),
645 PXSIZE-XRMARGIN, YTMARGIN+(int)(i*((PYSIZE-YTMARGIN-YBMARGIN)/ygap)));
646 }
647 }
648 }
649
650 /**
651 * Paints the graphic, with all values which were set by using setData.
652 *
653 * @param g (Graphics) graphics device.
654 */
655 public void paint(Graphics g)
656 {
657 // General Background
658 g.setColor( getBackground() );
659 g.fillRect( 0, 0, PXSIZE, PYSIZE );
660
661 // Graph background
662 g.setColor(Color.white);
663 g.fill3DRect( XLMARGIN, YTMARGIN, PXSIZE-XLMARGIN-XRMARGIN, PYSIZE-YTMARGIN-YBMARGIN, true );
664
665 // Title
666 g.setColor(titleColor);
667 FontMetrics titleFontMetrics = getFontMetrics(titleFont);
668 g.setFont(titleFont);
669
670 g.drawString((String)title, PXSIZE/2 - titleFontMetrics.stringWidth(title)/2,
671 YTMARGIN - titleFont.getSize() - titleFontMetrics.getDescent()+5);
672
673 // Data points
674 if( !fixedMinY && dataSet )
675 ymin = findMinY( yData );
676
677 if( !fixedMaxY && dataSet )
678 ymax = findMaxY( yData );
679
680 xscale = (double)(PXSIZE-XLMARGIN-XRMARGIN-4)/np[0];
681 yscale = (double)(PYSIZE-YTMARGIN-YBMARGIN-4)/(ymax - ymin);
682
683 // xticks
684 drawXTicks( g );
685
686 // xgrid
687 if(XGRID)
688 drawXGrid( g );
689
690 // xlabels
691 g.setColor(labelColor);
692 FontMetrics xlabelFontMetrics = getFontMetrics(xLabelFont);
693 g.setFont(xLabelFont);
694
695 for(int i = 0; i < nxLabels; i++)
696 g.drawString((String)xLabels[i], XLMARGIN+(int)(i*3*(PXSIZE-XLMARGIN-XRMARGIN)/(3*(nxLabels-1))) -
697 xlabelFontMetrics.stringWidth(xLabels[i])/2,
698 PYSIZE-YBMARGIN + xLabelFont.getSize() + xlabelFontMetrics.getDescent());
699
700 // yticks
701 drawYTicks( g );
702
703 // yGrid
704 if( YGRID )
705 drawYGrid( g );
706
707 // ylabels
708 g.setColor(labelColor);
709 FontMetrics ylabelFontMetrics = getFontMetrics(yLabelFont);
710 g.setFont(yLabelFont);
711
712 for(int i = 0; i < 11; i++) {
713 if( logScale ) {
714 String yLabel = String.valueOf( ymax - i * ymax / ygap );
715 if(i > 0)
716 g.drawString(yLabel, XLMARGIN - ylabelFontMetrics.stringWidth(yLabel) - 5,
717 YTMARGIN+(int)(log10(i*ygap)/2*(PYSIZE-YTMARGIN-YBMARGIN)) +
718 yLabelFont.getSize() - ylabelFontMetrics.getDescent() - 4);
719 else
720 g.drawString(yLabel, XLMARGIN - ylabelFontMetrics.stringWidth(yLabel) - 5,
721 YTMARGIN + yLabelFont.getSize() - ylabelFontMetrics.getDescent() - 4);
722
723 } else {
724
725 String yLabel = String.valueOf( Math.round( ymin + i * (-ymin + ymax) / ygap) );
726 g.drawString(yLabel,
727 XLMARGIN - ylabelFontMetrics.stringWidth(yLabel) - 5,
728 PYSIZE-YBMARGIN-(int)(i*((PYSIZE-YTMARGIN-YBMARGIN)/10)) +
729 yLabelFont.getSize() - ylabelFontMetrics.getDescent() - 4);
730 }
731
732 }
733 // Legend
734 FontMetrics legendFontMetrics = getFontMetrics(legendFont);
735 g.setFont(legendFont);
736 for(int i = 0; i < nHist; i++){
737 g.setColor(graphColor[i]);
738 if(i < 4)
739 g.fillRect(XLMARGIN, PYSIZE-YBMARGIN+i*10+20, 20, 8);
740 else
741 g.fillRect(XLMARGIN+PXSIZE/2, PYSIZE-YBMARGIN+(i-4)*10+20, 20, 8);
742
743 g.setColor(Color.black);
744 if( i < 4 && i < legend.size() )
745 g.drawString((String)legend.elementAt(i), XLMARGIN+30,
746 PYSIZE-YBMARGIN + legendFont.getSize() + legendFontMetrics.getDescent()+i*10+15);
747 else if( i < legend.size() )
748 g.drawString((String)legend.elementAt(i), XLMARGIN+PXSIZE/2+30,
749 PYSIZE-YBMARGIN + legendFont.getSize() + legendFontMetrics.getDescent()+(i-4)*10+15);
750 }
751
752 // Draw the graphs
753 int k = 0;
754 int x1, x2, y1, y2, ylast = 0, xlast = 0;
755 for( int i = 0; i < nHist; i++ ){
756 g.setColor( graphColor[i] );
757 for( int j = 0; j < np[i]-1; j++, k++ ) {
758 if( j == 0 )
759 x1 = XLMARGIN+(int)(j*xscale)+2;
760 else
761 x1 = xlast;
762
763 x2 = XLMARGIN+(int)((j+1)*xscale)+2;
764 if( logScale ) {
765
766 if( j == 0 )
767 y1 = PYSIZE-YBMARGIN+(int)((log10(yData[k]/ymax))/log10(ymax)*
768 (PYSIZE-YBMARGIN-YTMARGIN));
769 else
770 y1 = ylast;
771
772 y2 = PYSIZE-YBMARGIN+(int)((log10(yData[k+1]/ymax))/log10(ymax)*
773 (PYSIZE-YBMARGIN-YTMARGIN));
774
775 g.drawLine(x1, y1, x2, y2);
776
777 } else {
778 if( j == 0 )
779 y1 = PYSIZE-YBMARGIN-(int)Math.round(((-ymin+yData[k])*yscale)+1);
780 else
781 y1 = ylast;
782
783 y2 = PYSIZE-YBMARGIN-(int)Math.round(((-ymin+yData[k+1])*yscale)+1);
784
785 if(y1 < YTMARGIN) y1 = YTMARGIN+2;
786 if(y2 < YTMARGIN) y2 = YTMARGIN+2;
787 if( y1 != YTMARGIN + 2 || y2 != YTMARGIN + 2 )
788 g.drawLine(x1, y1, x2, y2);
789 }
790 ylast = y2;
791 xlast = x2;
792 }
793 k++;
794 }
795
796 // Draw the thresholds
797 if( showThres ) {
798 g.setColor( Color.red );
799 drawThres( g );
800 }
801
802 // Realtime
803 if( realTime && np[0] > 0) {
804 g.setColor(Color.red);
805 g.drawLine(XLMARGIN+(int)(currentTime*(PXSIZE-XLMARGIN-XRMARGIN)/np[0]), YTMARGIN,
806 XLMARGIN+(int)(currentTime*(PXSIZE-XLMARGIN-XRMARGIN)/np[0]), PYSIZE-YBMARGIN);
807 }
808 }
809
810 /**
811 * Calculates the minimum Y-value. The minimum will be the next following
812 * value which can be divided by 10^x. For instance if the minimum is -1
813 * the minimum value will be -10.
814 *
815 * @param vec (double[]) value vector.
816 */
817 private double findMinY(double vec[]) {
818
819 double min = 0.0;
820
821 for(int i = 0; i < vec.length; i++)
822 if(vec[i] < min) min = vec[i];
823
824 if( min > 0 )
825 return 0.0;
826
827 for(int i = 0; i < 20; i++) {
828 if(min > -0.000001*Math.pow(10.0,(double)i)) {
829 min = -0.000001*Math.pow(10.0, (double)i);
830 break;
831 }
832 }
833
834 return min;
835 }
836
837 /**
838 * Determines the maximum Y-value. The maximum will be the next following
839 * value which can be divided by 10^x. For instance if the maximum is 4000
840 * the maximum value will be 10000.
841 *
842 * @param vec (double[]) value vector.
843 */
844 private double findMaxY(double vec[]) {
845
846 double max = 0.0;
847
848 for(int i = 0; i < vec.length; i++)
849 if(vec[i] > max) max = vec[i];
850
851 if( max < 0.9 )
852 return 1.0;
853
854 for(int i = 0; i < 20; i++) {
855 if(max < 0.000001*Math.pow(10.0,(double)i)) {
856 max = 0.000001*Math.pow(10.0, (double)i);
857 break;
858 }
859 }
860
861 return max;
862 }
863
864 /**
865 * Deletes the histogram
866 */
867 public void del() {
868
869 nt = 0;
870 nHist = 0;
871 legend.removeAllElements();
872 dataSet = false;
873 }
874
875 /**
876 * Updates the histogram
877 */
878 public void histUpdate() {
879 paint( getGraphics() );
880 if( showThres && ! running )
881 start();
882 else if( running )
883 stop();
884 }
885
886 /**
887 * Return the title string.
888 *
889 * @return title (String) histogram title
890 */
891 public String getTitle() {
892 return(title);
893 }
894
895 /**
896 * Return the X-Grid flag.
897 *
898 * @return xGrid (boolean) X-grid flag.
899 */
900 public boolean getXGrid() {
901 return(XGRID);
902 }
903
904 /**
905 * Return the Y-Grid flag.
906 *
907 * @return yGrid (boolean) Y-grid flag.
908 */
909 public boolean getYGrid() {
910 return(YGRID);
911 }
912
913 /**
914 * Return the X-size.
915 *
916 * @return xSize (int) width of the histogram.
917 */
918 public int getXSize() {
919 return(PXSIZE);
920 }
921
922 /**
923 * Return the Y-size.
924 *
925 * @return ySize (int) height of the histogram.
926 */
927 public int getYSize() { return(PYSIZE); }
928
929 /**
930 * Returns the maximum fixed-Y flag.
931 *
932 * @return fixedMaxY (boolean) fixed-Y flag.
933 */
934 public boolean getFixedMaxY() { return(fixedMaxY); }
935
936 /**
937 * Returns the minimum fixed-Y flag.
938 *
939 * @return fixedMinY (boolean) fixed minimum Y flag.
940 */
941 public boolean getFixedMinY() { return(fixedMinY); }
942
943 /**
944 * Return the minimum Y value.
945 *
946 * @return ymin (double) minimum Y value.
947 */
948 public double getYmin() { return(ymin); }
949
950 /**
951 * Return the maximum Y value.
952 *
953 * @return ymax (double) maximum Y value.
954 */
955 public double getYmax() { return(ymax); }
956
957 /**
958 * Return the log scale flag.
959 *
960 * @return logScale (boolean) logScale flag.
961 */
962 public boolean getLogScale() { return logScale; }
963
964 /**
965 * Return the show threshold flag.
966 *
967 * @return showThres (boolean) show threshold flag.
968 */
969 public boolean getShowThres() { return showThres; }
970
971 /**
972 * Return the legend.
973 *
974 * @param index (int) index of the legend string.
975 * @return legend (String) legend string.
976 */
977 public String getLegend( int index ) { return( ( String )legend.elementAt( index )); }
978
979 /**
980 * Returns a image of the current plot
981 *
982 * @return img (Image) the image of the current histogram.
983 */
984 public Image getImage()
985 {
986 Image image = createImage( PXSIZE, PYSIZE );
987 paint( image.getGraphics() );
988 return image;
989 }
990
991 public void run()
992 {
993 running = true;
994
995 Graphics g = getGraphics();
996 g.setPaintMode();
997 g.setXORMode( Color.red );
998 while( histoThread == Thread.currentThread() ) {
999
1000 drawThres( g );
1001
1002 try {
1003
1004 Thread.sleep( 1000 );
1005
1006 } catch (InterruptedException e) {
1007 }
1008 }
1009 }
1010
1011 /**
1012 * Starts the blinking thread.
1013 */
1014 public void start()
1015 {
1016 // Start the histo thread.
1017 histoThread = new Thread( this );
1018 histoThread.start();
1019 }
1020
1021 /**
1022 * Stops the thread.
1023 */
1024 public void stop()
1025 {
1026 // Stop the Chart thread.
1027 histoThread = null;
1028 }
1029}
1030
1031