KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > clif > console > lib > gui > Graph


1 /*
2 * CLIF is a Load Injection Framework
3 * Copyright (C) 2003, 2004 France Telecom R&D
4 * Copyright (C) 2003 INRIA
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * CLIF $Name: $
21 *
22 * Contact: clif@objectweb.org
23 */

24
25 package org.objectweb.clif.console.lib.gui;
26
27 import java.awt.BasicStroke JavaDoc;
28 import java.awt.Color JavaDoc;
29 import java.awt.Graphics JavaDoc;
30 import java.awt.Graphics2D JavaDoc;
31 import java.awt.FontMetrics JavaDoc;
32 import java.awt.geom.Line2D JavaDoc;
33 import java.awt.geom.Point2D JavaDoc;
34 import java.util.Vector JavaDoc;
35 import javax.swing.JPanel JavaDoc;
36
37 /**
38  *
39  * @author Julien Buret
40  * @author Nicolas Droze
41  * @author Bruno Dillenseger
42  */

43 public class Graph extends JPanel JavaDoc
44 {
45     // The area in which the curves are going to be displayed
46
public GraphArea graphArea;
47     // The X Axs
48
public XAxis xAxis;
49     // The Y Axis
50
public YAxis yAxis;
51     // Contains the list and points of all the hosts to display
52
public Vector JavaDoc hostsToDisplay = new Vector JavaDoc();
53     // Contains the list and points of all the hosts
54
public InjectorsGraph[] allHosts;
55     // Contains the list and points of one host
56
private InjectorsGraph[] oneHost;
57     // The number of data for each host
58
public int nbElements;
59     // The current view on the graph area
60
public int VIEW = 0;
61     // A limited graph means that we do not store all points for a host
62
// and that we display only a given number of points on the graph.
63
public boolean isLimited;
64     // The object that will determine colors for the graphs
65
private GraphColorChooser colorChooser = new GraphColorChooser();
66     private Point2D.Double JavaDoc newPoint = null;
67
68     /**
69      * The Graph constructor.
70      * @param injectors All the hosts to represent on this graph.
71      * @param nbElements The number of data for each host.
72      * @param isLimited True means that only a certain number of values will be stored in memory.
73      */

74     public Graph(String JavaDoc[] injectors, int nbElements, boolean isLimited) {
75
76         this.nbElements = nbElements;
77         this.isLimited = isLimited;
78
79         /* Initialize the content of the table allInjectors:
80          * For each injector, set its name,
81          * set its color (next color available)
82          * and a starting point (0,0) for each graph.
83          */

84         allHosts = new InjectorsGraph[injectors.length];
85         for (int i = 0; i < injectors.length; i++) {
86             allHosts[i] = new InjectorsGraph(nbElements, isLimited);
87             allHosts[i].name = injectors[i];
88             allHosts[i].color = colorChooser.getNextColor();
89 // for (int j = 0; j < nbElements; j++) {
90
// allHosts[i].addPoint(new Point2D.Double(0, 0), j);
91
// }
92
}
93
94         setLayout(null);
95
96         graphArea = new GraphArea(isLimited);
97         xAxis = new XAxis(graphArea);
98         yAxis = new YAxis(graphArea);
99
100         // Set the position and location of the graph panels.
101
yAxis.setSize(YAxis.width, 300);
102         xAxis.setSize(100, 20);
103         yAxis.setLocation(0, 0);
104         xAxis.setLocation(YAxis.width, 280);
105         graphArea.setLocation(YAxis.width, 0);
106
107         add(yAxis);
108         add(xAxis);
109         add(graphArea);
110         doLayout();
111     }
112
113     /**
114      * Set the current view of the graph area. This method is called each time
115      * the user choose another item in the JComboBox.
116      * @param view The number of the view (The index of the value from the JComboBox).
117      */

118     public void setView(int view) {
119         this.VIEW = view;
120         graphArea.resetScale();
121     }
122
123
124     /**
125      * Add a specific point to a specific host
126      * @param injector The name of the host the point belongs to.
127      * @param type The type of the data (cf possible values in the graph inherited)
128      * @param time The time value (x axis)
129      * @param value The value (y axis)
130      */

131     public void addPoint(String JavaDoc injector, int type, int time, long value) {
132
133         newPoint = new Point2D.Double JavaDoc(time, value);
134
135         // Add the new point to the specific host
136
for (int i = 0; i < allHosts.length; i++) {
137             if (allHosts[i].name.equals(injector)) {
138                 allHosts[i].addPoint(newPoint, type);
139                 break;
140             }
141         }
142     }
143
144     /**
145      * Sets the maximum value on the X Axis.
146      * @param totalTime
147      */

148     public void updateXAxis(int totalTime) {
149         graphArea.xMax = totalTime;
150     }
151
152     /**
153      * This method re-calculate a correct scale for the graph
154      * and repaint all the graph components
155      */

156     public void updateGraph()
157     {
158         graphArea.calculateScale(hostsToDisplay, allHosts);
159         yAxis.repaint();
160         xAxis.repaint();
161         graphArea.repaint();
162     }
163
164     /**
165      * Add the points of a specific host into the table of the hosts to display
166      * @param injector The name of the host to display in the graph area.
167      */

168     public void addPointsOnDisplay(String JavaDoc injector) {
169
170         // Find the points data of the host
171
for (int i = 0; i < allHosts.length; i++) {
172             if (allHosts[i].name.equals(injector)) {
173                 // Get the points to visualize from this host
174
oneHost = new InjectorsGraph[1];
175                 oneHost[0] = new InjectorsGraph(1, isLimited);
176                 oneHost[0].name = injector;
177                 oneHost[0].color = allHosts[i].color;
178                 oneHost[0].points[0] = allHosts[i].points[VIEW];
179                 if (isLimited)
180                     oneHost[0].maxElements = allHosts[i].getMaxElements();
181                 hostsToDisplay.addElement(oneHost);
182                 break;
183             }
184         }
185     }
186
187     /**
188      * Add the points of all the hosts into the table of the hosts to display
189      * @param injectors The list of the hosts to display in the graph area.
190      */

191     public void addAllPointsOnDisplay(Object JavaDoc[] injectors) {
192
193         for (int i = 0; i < injectors.length; i++) {
194             addPointsOnDisplay((String JavaDoc) injectors[i]);
195         }
196     }
197
198     /**
199      * Remove the points of a specific host from the table of the hosts to display
200      * @param injector The name of the host to remove from the graph area.
201      */

202     public void removePointsFromDisplay(String JavaDoc injector) {
203
204         // Find the injector name in the display list and simply remove it.
205
for (int i = 0; i < hostsToDisplay.size(); i++) {
206             oneHost = (InjectorsGraph[]) hostsToDisplay.elementAt(i);
207             if (oneHost[0].name.equals(injector)) {
208                 hostsToDisplay.removeElementAt(i);
209                 break;
210             }
211         }
212     }
213
214     /**
215      * Remove the points of all the hosts from the table of the hosts to display
216      * @param injectors The list of the hosts to remove from the graph area.
217      */

218     public void removeAllPointsFromDisplay(Object JavaDoc[] injectors) {
219
220         for (int i = 0; i < injectors.length; i++) {
221             removePointsFromDisplay((String JavaDoc) injectors[i]);
222         }
223     }
224
225     public void paintComponent(Graphics JavaDoc g) {
226         yAxis.setSize(YAxis.width, getHeight());
227         xAxis.setSize(getWidth(), 20);
228         xAxis.setLocation(YAxis.width, getHeight() - 20);
229         graphArea.setSize(getWidth() - YAxis.width, getHeight() - 20);
230         updateGraph();
231     }
232
233     /**
234      * This method adds a new host to the list of all the existing host of this graph.
235      * @param name The name of the host.
236      */

237     public void addInjector(String JavaDoc name) {
238         InjectorsGraph[] _allInjectors = allHosts;
239         int _size = allHosts.length;
240
241         // Transfer the old values into the new variables
242
allHosts = new InjectorsGraph[_size + 1];
243         for (int i = 0; i < _allInjectors.length; i++)
244         {
245             allHosts[i] = new InjectorsGraph(nbElements, isLimited);
246             allHosts[i].name = _allInjectors[i].name;
247             allHosts[i].color = _allInjectors[i].color;
248         }
249         // The last index contains the new injector
250
allHosts[_size] = new InjectorsGraph(nbElements, isLimited);
251         allHosts[_size].name = name;
252         allHosts[_size].color = colorChooser.getNextColor();
253     }
254
255     /**
256      * Clear the graph area (Clear all points)
257      */

258     public void clear() {
259         for (int i = 0; i < allHosts.length; i++) {
260             allHosts[i].clearAllPoints();
261         }
262         updateXAxis(0);
263         updateGraph();
264     }
265
266     /**
267      * Sets the maximum number of points to store.
268      * (Useful only with limited graphs)
269      * @param nbPoints The maximum number of points to store.
270      */

271     public void setNbPoints(int nbPoints) {
272         for (int i = 0; i < allHosts.length; i++) {
273             allHosts[i].setMaxElements(nbPoints);
274         }
275         updateGraph();
276     }
277
278
279     public int getGraphAreaWidth()
280     {
281         return graphArea.getWidth();
282     }
283 }
284
285 /**
286  * This is the JPanel which represents the X axis
287  */

288 class XAxis extends JPanel JavaDoc
289 {
290     private GraphArea graphArea;
291     private FontMetrics JavaDoc fontMet;
292
293     public XAxis(GraphArea graph)
294     {
295         this.graphArea = graph;
296         fontMet = getFontMetrics(getFont());
297     }
298
299     public void paint(Graphics JavaDoc g)
300     {
301         g.clearRect(0, 0, getWidth(), getHeight());
302         g.drawLine(0, 1, getWidth(), 1);
303         String JavaDoc time = String.valueOf(graphArea.xMax);
304         g.drawString(
305             time,
306             getWidth() - fontMet.stringWidth(time) - YAxis.width,
307             fontMet.getHeight());
308     }
309 }
310
311 /**
312  * This is the JPanel which represents the Y axis
313  */

314 class YAxis extends JPanel JavaDoc
315 {
316     static final int width = 90;
317     private GraphArea graphArea;
318     private FontMetrics JavaDoc fontMet;
319
320     public YAxis(GraphArea graphArea)
321     {
322         this.graphArea = graphArea;
323         fontMet = getFontMetrics(getFont());
324     }
325
326     public void paint(Graphics JavaDoc g)
327     {
328         g.clearRect(0, 0, getWidth(), getHeight());
329         g.drawLine(YAxis.width - 1, 0, YAxis.width - 1, getHeight() - 20);
330         if (graphArea.maxValue > graphArea.minValue)
331         {
332             long middleValue = (graphArea.maxValue + graphArea.minValue) / 2;
333             // Display the max value
334
g.drawString(
335                 String.valueOf(graphArea.maxValue),
336                 1,
337                 fontMet.getAscent());
338             // Display the middle value
339
g.drawString(
340                 String.valueOf(middleValue),
341                 1,
342                 (graphArea.getHeight() - fontMet.getLeading() )/ 2);
343             // Display the first quart value
344
long quartDiff = (middleValue - graphArea.minValue) / 2;
345             g.drawString(
346                 String.valueOf(graphArea.minValue + quartDiff),
347                 1,
348                 (3*graphArea.getHeight()) / 4);
349             // Display the third quart value
350
g.drawString(
351                 String.valueOf(graphArea.maxValue - quartDiff),
352                 1,
353                 graphArea.getHeight() / 4);
354             // Display the minimum value
355
g.drawString(
356                 String.valueOf(graphArea.minValue),
357                 1,
358                 graphArea.getHeight());
359         }
360     }
361 }
362
363 /**
364  * This is the JPanel containing the graph
365  */

366 class GraphArea extends JPanel JavaDoc {
367
368     private BasicStroke JavaDoc defaultStroke = new BasicStroke JavaDoc();
369     private BasicStroke JavaDoc dash;
370     private Point2D.Double JavaDoc first = null;
371     private Point2D.Double JavaDoc last = null;
372     private Point2D.Double JavaDoc firstTransf = null;
373     private Point2D.Double JavaDoc lastTransf = null;
374     // The maximum value for each axis
375
protected long yMax = 0;
376     protected long yMin = 0;
377     public int xMax = 0;
378     // The scale of each axis, used for the drawing
379
public double xScale;
380     public double yScale;
381     public boolean isLimited;
382     private Vector JavaDoc injectorsToDisplay = new Vector JavaDoc();
383     private InjectorsGraph[] oneInjector;
384     protected long maxValue;
385     protected long minValue;
386
387     public GraphArea(boolean isLimited) {
388         this.isLimited = isLimited;
389         xScale = 0;
390         yScale = 0;
391         dash =
392             new BasicStroke JavaDoc(
393                 defaultStroke.getLineWidth(),
394                 defaultStroke.getEndCap(),
395                 defaultStroke.getLineJoin(),
396                 defaultStroke.getMiterLimit(),
397                 new float[] { 8, 8 },
398                 0);
399         oneInjector = new InjectorsGraph[1];
400         oneInjector[0] = new InjectorsGraph(1, isLimited);
401     }
402
403     public void paint(Graphics JavaDoc g)
404     {
405         Graphics2D JavaDoc g2 = (Graphics2D JavaDoc) g;
406         g2.setStroke(defaultStroke);
407         g2.setBackground(Color.WHITE);
408
409         // Clear the graph area
410
g2.clearRect(0, 0, getWidth(), getHeight());
411
412         if (yMax > yMin)
413         {
414             // For each injector to display
415
for (int i = 0; i < injectorsToDisplay.size(); i++) {
416                 oneInjector = (InjectorsGraph[]) injectorsToDisplay.elementAt(i);
417                 g2.setColor(oneInjector[0].color);
418
419                 /*
420                  * We get all the points of this injector ...
421                  * then we translate the coordinates into pixels format
422                  * and finally draw a line between these 2 new points.
423                  */

424                 for (int j = 0; j < oneInjector[0].points[0].size() - 1; j++) {
425                     first = (Point2D.Double JavaDoc) oneInjector[0].points[0].elementAt(j);
426                     last =
427                         (Point2D.Double JavaDoc) oneInjector[0].points[0].elementAt(j + 1);
428
429                     firstTransf = (Point2D.Double JavaDoc) first.clone();
430                     lastTransf = (Point2D.Double JavaDoc) last.clone();
431
432                     // If the graph is limited, the calculation of the scale is a little
433
// different than if the graph is not limited.
434
if (!isLimited) {
435                         firstTransf.setLocation(
436                             first.getX() * xScale,
437                             getHeight() - ((first.getY() - yMin) * yScale));
438                         lastTransf.setLocation(
439                             last.getX() * xScale,
440                             getHeight() - ((last.getY() - yMin) * yScale));
441                     } else {
442                         firstTransf.setLocation(
443                             j * xScale,
444                             getHeight() - ((first.getY() - yMin) * yScale));
445                         lastTransf.setLocation(
446                             (j + 1) * xScale,
447                             getHeight() - ((last.getY() - yMin) * yScale));
448                     }
449                     g2.draw(new Line2D.Double JavaDoc(firstTransf, lastTransf));
450                 }
451             }
452             // display a grid.
453
maxValue = yMax;
454             minValue = yMin;
455             g2.setStroke(dash);
456             g2.setColor(Color.BLACK);
457             g2.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);
458             g2.drawLine(0, getHeight() / 4, getWidth(), getHeight() / 4);
459             g2.drawLine(0, 3 * getHeight() / 4, getWidth(), 3 * getHeight() / 4);
460         }
461     }
462
463
464     /**
465      * Called when the view has changed and the scale on the Y Axis has to be adjusted
466      */

467     public void resetScale()
468     {
469         yMax = Integer.MIN_VALUE;
470         yMin = Integer.MAX_VALUE;
471     }
472
473
474     /**
475      * Calculate a correct scale for a proper drawing.
476      * @param injectorsToDisplay
477      * @param allInjectors
478      */

479     public void calculateScale(
480         Vector JavaDoc injectorsToDisplay,
481         InjectorsGraph[] allInjectors) {
482
483         this.injectorsToDisplay = injectorsToDisplay;
484
485         // For each injector to display
486
for (int i = 0; i < injectorsToDisplay.size(); i++) {
487             oneInjector = (InjectorsGraph[]) injectorsToDisplay.elementAt(i);
488
489             // We get each point of this injector
490
for (int j = 0; j < oneInjector[0].points[0].size(); j++)
491             {
492                 Point2D.Double JavaDoc currPoint = (Point2D.Double JavaDoc) oneInjector[0].points[0].elementAt(j);
493                 if (currPoint.getY() > yMax)
494                 {
495                     yMax = new Double JavaDoc(currPoint.getY()).longValue();
496                 }
497                 if (currPoint.getY() < yMin)
498                 {
499                     yMin = new Double JavaDoc(currPoint.getY()).longValue();
500                 }
501                 if (yMax - yMin < 4)
502                 {
503                     yMax = yMin + 4;
504                 }
505             }
506         }
507
508         // Find a good scale on the X axis and Y axis
509
if (xMax != 0) {
510             if (isLimited) {
511                 xScale =
512                     new Double JavaDoc(getWidth()).doubleValue()
513                         / (oneInjector[0].getMaxElements() - 1);
514             } else {
515                 xScale =
516                     new Double JavaDoc(getWidth()).doubleValue()
517                         / (new Double JavaDoc(xMax).doubleValue());
518             }
519         } else
520             xScale = 0;
521
522         yScale =
523             new Double JavaDoc(getHeight()).doubleValue()
524                 / new Double JavaDoc(yMax - yMin).doubleValue();
525     }
526 }
527
Popular Tags