View Javadoc

1   /*
2   * The contents of this file are subject to the BT "ZEUS" Open Source 
3   * Licence (L77741), Version 1.0 (the "Licence"); you may not use this file 
4   * except in compliance with the Licence. You may obtain a copy of the Licence
5   * from $ZEUS_INSTALL/licence.html or alternatively from
6   * http://www.labs.bt.com/projects/agents/zeus/licence.htm
7   * 
8   * Except as stated in Clause 7 of the Licence, software distributed under the
9   * Licence is distributed WITHOUT WARRANTY OF ANY KIND, either express or 
10  * implied. See the Licence for the specific language governing rights and 
11  * limitations under the Licence.
12  * 
13  * The Original Code is within the package zeus.*.
14  * The Initial Developer of the Original Code is British Telecommunications
15  * public limited company, whose registered office is at 81 Newgate Street, 
16  * London, EC1A 7AJ, England. Portions created by British Telecommunications 
17  * public limited company are Copyright 1996-9. All Rights Reserved.
18  * 
19  * THIS NOTICE MUST BE INCLUDED ON ANY COPY OF THIS FILE
20  */
21  
22  
23  
24  package zeus.visualiser.statistics.charts;
25  
26  import java.util.*;
27  import java.awt.*;
28  import zeus.gui.ColorManager;
29  import zeus.util.Misc;
30  
31  public class XYGraph implements DrawObject {
32     protected static final int TYPE1 = 0;
33     protected static final int TYPE2 = 1;
34     protected static double TINY = 1E-6;
35     protected static int    LEFT = 100;
36     protected static int    STEP = 5;
37     protected static int    KEY_LINE_LENGTH = 15;
38     protected String title;
39     protected int x, y = 0;
40     protected FontMetrics fm;
41     protected Font        font;
42     protected int         gap = 10;
43     protected double      max_x = 0.0, min_x = 0.0, max_y = 0.0, min_y = 0.0;
44     protected double[][]  x_values, y_values;
45     protected String[]    keys;
46     protected int         type = -1;
47  
48     public XYGraph() {
49     }
50     public XYGraph(double[] y_values, double[] x_values, String title) {
51        setData(y_values, x_values, title);
52     }
53     public XYGraph(double[][] y_values, double[][] x_values, String[] keys,
54                    String title) {
55        setData(y_values, x_values, keys, title);
56     }
57  
58     public void setData(double[] y_values, double[] x_values, String title) {
59        type = TYPE1;
60        this.title = title;
61        this.y_values = new double[1][];
62        this.y_values[0] = y_values;
63        this.x_values = new double[1][];
64        this.x_values[0] = x_values;
65        computeMinMax();
66     }
67  
68     public void setData(double[][] y_values, double[][] x_values, String[] keys,
69                         String title) {
70        type = TYPE2;
71        this.title = title;
72        this.keys = keys;
73        this.y_values = y_values;
74        this.x_values = x_values;
75        computeMinMax();
76     }
77  
78     protected void computeMinMax() {
79        max_y = min_y = max_x = min_x = 0.0;
80        for(int i = 0; i < y_values.length; i++ ) {
81           for(int j = 0; j < y_values[i].length; j++) {
82              max_y = Math.max(max_y,y_values[i][j]);
83              min_y = Math.min(min_y,y_values[i][j]);
84              max_x = Math.max(max_x,x_values[i][j]);
85              min_x = Math.min(min_x,x_values[i][j]);
86           }
87        }
88     }
89  
90     public void drawYourSelf(Graphics g) {
91        // TEST(1);
92        font = new Font("Arial", Font.BOLD, 14);
93        fm = g.getFontMetrics(font);
94        g.setFont(font);
95        int w  = fm.stringWidth(title);
96        int h  = fm.getHeight();
97        g.drawString(title,(x-w)/2,h);
98  
99        // TEST(2);
100       if ( min_x == 0 && max_x == 0 && min_y == 0 && max_y == 0 ) return;
101 
102 
103       font = new Font("Arial", Font.PLAIN, 12);
104       fm = g.getFontMetrics(font);
105       g.setFont(font);
106       // TEST(3);
107 
108       double max_w = min_x > 0.0 ? max_x : Math.abs(max_x-min_x);
109       double max_h = min_y > 0.0 ? max_y : Math.abs(max_y-min_y);
110 
111       // enforce non-zero
112       if ( isZero(max_w) ) max_w = 1E-6;
113       if ( isZero(max_h) ) max_h = 1E-6;
114 
115       int x0 = 0, y0 = 0, x1, y1, x2, y2, xp, yp;
116       int mw = 0, x_length = 0, y_length = 0;
117       // TEST(4);
118 
119       if ( type == TYPE2 )
120       for(int j = 0; j < keys.length; j++ )
121          mw = Math.max(mw,fm.stringWidth(keys[j]));
122 
123       // TEST(5);
124       mw += 20 + 10 + KEY_LINE_LENGTH + 10;
125       x_length = x - LEFT - mw;
126       y_length = y-5*h;
127 
128       g.drawLine(LEFT,3*h,LEFT,y-2*h);  // Y-axis
129 
130       x0 = LEFT;
131       x1 = x0 + x_length;
132 
133       y0 = (int)(3*h + y_length - (0-min_y)*y_length/max_h);
134       // TEST(6);
135       y1 = y0;
136       g.drawLine(x0,y0,x1,y1); // X-axis
137 
138       // TEST(7);
139       for(int i = 0; i < y_values.length; i++ ) {
140          if ( y_values[i].length > 0 ) {
141             x0 = (int)((x_values[i][0] - min_x)*x_length/max_w + LEFT);
142             y0 = (int)(y_length - (y_values[i][0]-min_y)*y_length/max_h + 3*h);
143             g.setColor(ColorManager.getColor(i));
144             GraphicsSymbol.drawSymbol(g,i,10,x0,y0);
145             for(int j = 1; j < y_values[i].length; j++ ) {
146                x1 = (int)((x_values[i][j]-min_x)*x_length/max_w + LEFT);
147                y1 = (int)(3*h + y_length - (y_values[i][j]-min_y)*y_length/max_h);
148                GraphicsSymbol.drawSymbol(g,i,10,x1,y1);
149                g.drawLine(x0,y0,x1,y1);
150                x0 = x1;
151                y0 = y1;
152             }
153          }
154       }
155 
156       // TEST(8);
157       double v;
158       x0 = (int)(LEFT + (0-min_x)*x_length/max_w);
159       y0 = (int)(3.0*h + y_length - (0-min_y)*y_length/max_h);
160 
161       double dy = Math.max(Math.abs(max_y),Math.abs(min_y))/STEP;
162       if ( dy + 0.51  > 1 )
163          dy = (int)(dy+0.51);
164       int step = (int)(dy*y_length/max_h);
165 
166       g.setColor(Color.black);
167 
168       // TEST(9);
169       v = 0;
170       for(int i = 0; (!isZero(dy) || i == 0) && v + dy <= max_y; i++ ) {
171          // TEST(91);
172          v = i*dy;
173          String yval = Misc.decimalPlaces(v,2);
174          xp = x0;
175          yp = y0 - i*step;
176          g.drawLine(xp,yp,xp-10,yp);
177          w = fm.stringWidth(yval);
178          g.drawString(yval,xp-10-w-5,yp);
179       }
180       // TEST(10);
181       if ( min_y < 0.0 ) {
182          v = -1*dy;
183          for(int i = 1; !isZero(dy) && v - dy >= min_y; i++ ) {
184             // TEST(101);
185             v = -1*i*dy;
186             String yval = Misc.decimalPlaces(v,2);
187             xp = x0;
188             yp = y0 + i*step;
189             g.drawLine(xp,yp,xp-10,yp);
190             w = fm.stringWidth(yval);
191             g.drawString(yval,xp-10-w-5,yp);
192          }
193       }
194 
195       // TEST(11);
196       x0 = (int)(LEFT + (0-min_x)*x_length/max_w);
197       y0 = (int)(3.0*h + y_length - (0-min_y)*y_length/max_h);
198 
199       double dx = Math.max(Math.abs(max_x),Math.abs(min_x))/STEP;
200       if ( dx + 0.51  > 1 )
201          dx = (int)(dx+0.51);
202       step = (int)(dx*x_length/max_w);
203 
204       // TEST(12);
205       g.setColor(Color.black);
206       v = 0;
207       for(int i = 0; (!isZero(dx) || i == 0) && v + dx <= max_x; i++ ) {
208          // TEST(121);
209          v = i*dx;
210          String xval = Misc.decimalPlaces(v,2);
211          yp = y0;
212          xp = x0 + i*step;
213          g.drawLine(xp,yp,xp,yp+10);
214          w = fm.stringWidth(xval);
215          g.drawString(xval,xp-w/2,yp+10+h);
216       }
217       // TEST(13);
218       if ( min_x < 0.0 ) {
219          v = -1*dx;
220          for(int i = 1; !isZero(dx) && v - dx >= min_x; i++ ) {
221             // TEST(131);
222             v = -1*i*dx;
223             String xval = Misc.decimalPlaces(v,2);
224             yp = y0;
225             xp = x0 - i*step;
226             g.drawLine(xp,yp,xp,yp-10);
227             w = fm.stringWidth(xval);
228             g.drawString(xval,xp-w/2,yp-10-h);
229          }
230       }
231 
232       // TEST(14);
233       if ( type == TYPE2 ) {
234          x1 = LEFT+x_length+20; y1 = 3*h;
235          int dh = Math.max(h+10,20);
236          g.setColor(Color.black);
237          g.drawString("Key",x1,y1);
238          for(int i = 0; i < keys.length; i++ ) {
239             y1 += dh;
240             g.setColor(ColorManager.getColor(i));
241             g.drawLine(x1,y1,x1+KEY_LINE_LENGTH,y1);
242             g.setColor(Color.black);
243             g.drawString(keys[i],x1+KEY_LINE_LENGTH + 10,y1);
244          }
245       }
246       // TEST(15);
247    }
248 
249    void TEST(int num) {
250       if ( y_values[0].length == 0 || y_values[1].length == 0 )
251          System.err.println("drawYourSelf position" + num);
252    }
253 
254    boolean isZero(double num) {
255       return (Math.abs(num) < TINY);
256    }
257 
258    public void setXY(int xc, int yc) {
259       x = xc; y = yc;
260    }
261 }