1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
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
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
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
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
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
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);
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
135 y1 = y0;
136 g.drawLine(x0,y0,x1,y1);
137
138
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
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
169 v = 0;
170 for(int i = 0; (!isZero(dy) || i == 0) && v + dy <= max_y; i++ ) {
171
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
181 if ( min_y < 0.0 ) {
182 v = -1*dy;
183 for(int i = 1; !isZero(dy) && v - dy >= min_y; i++ ) {
184
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
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
205 g.setColor(Color.black);
206 v = 0;
207 for(int i = 0; (!isZero(dx) || i == 0) && v + dx <= max_x; i++ ) {
208
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
218 if ( min_x < 0.0 ) {
219 v = -1*dx;
220 for(int i = 1; !isZero(dx) && v - dx >= min_x; i++ ) {
221
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
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
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 }