• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright (c) 2000, 2009 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.test.performance.ui;
12 
13 import java.util.*;
14 
15 import org.eclipse.swt.graphics.Color;
16 import org.eclipse.swt.graphics.GC;
17 import org.eclipse.swt.graphics.Image;
18 import org.eclipse.swt.graphics.Point;
19 import org.eclipse.swt.graphics.Rectangle;
20 import org.eclipse.test.internal.performance.data.Dim;
21 
22 public class TimeLineGraph extends LineGraph{
23 
24     Hashtable fItemGroups;
25 
TimeLineGraph(String title, Dim dim)26     public TimeLineGraph (String title, Dim dim) {
27         super(title, dim);
28         this.fItemGroups=new Hashtable();
29     }
30 
paint(Image im)31     public void paint(Image im) {
32 
33         Rectangle bounds= im.getBounds();
34 
35         GC g= new GC(im);
36 
37         Point ee= g.stringExtent(this.fTitle);
38         int titleHeight= ee.y;
39 
40         double maxItem= getMaxItem();
41         double minItem= getMinItem();
42 
43         int max= (int) (Math.ceil(maxItem * (maxItem < 0 ? 0.8 : 1.2)));
44         int min= (int) (Math.floor(minItem * (minItem < 0 ? 1.2 : 0.8)));
45 
46         String smin= this.fDimension.getDisplayValue(min);
47         Point emin= g.stringExtent(smin);
48 
49         String smax= this.fDimension.getDisplayValue(max);
50         Point emax= g.stringExtent(smax);
51 
52         int labelWidth= Math.max(emin.x, emax.x) + 2;
53 
54         int top= PADDING;
55         int bottom= bounds.height - titleHeight - PADDING;
56         int left= PADDING + labelWidth;
57 
58         //getMostRecent
59         TimeLineGraphItem lastItem= getMostRecent(this.fItemGroups);
60         int right=bounds.width - PADDING/2;
61         if (lastItem!=null)
62         	right= bounds.width - lastItem.getSize(g).x - PADDING/2;
63 
64         // draw the max and min values
65         g.drawString(smin, PADDING/2+labelWidth-emin.x, bottom-titleHeight, true);
66         g.drawString(smax, PADDING/2+labelWidth-emax.x, top, true);
67         g.drawString("TIME (not drawn to scale)", (right-left)/3+PADDING+titleHeight,bottom-PADDING+(titleHeight*2), true);
68 
69         // draw the vertical and horizontal lines
70         g.drawLine(left, top, left, bottom);
71         g.drawLine(left, bottom, right, bottom);
72 
73         Color oldbg= g.getBackground();
74         Color oldfg= g.getForeground();
75 
76         setCoordinates(right-left,left,bottom-top,bottom,max-min);
77 
78         Enumeration _enum=this.fItemGroups.elements();
79         Comparator comparator=new TimeLineGraphItem.GraphItemComparator();
80 
81         while (_enum.hasMoreElements()) {
82  			List items = (List) _enum.nextElement();
83 			Object[] fItemsArray=items.toArray();
84 			Arrays.sort(fItemsArray,comparator);
85 			int lastx = 0;
86 			int lasty = 0;
87 
88 			int n = fItemsArray.length;
89 
90 			for (int i = 0; i < n; i++) {
91 				TimeLineGraphItem thisItem = (TimeLineGraphItem) fItemsArray[i];
92 
93 				int yposition = thisItem.y;
94 				int xposition = thisItem.x;
95 				g.setLineWidth(1);
96 
97 				g.setBackground(thisItem.color);
98 				g.setForeground(thisItem.color);
99 
100 				if (thisItem.drawAsBaseline){
101 					g.setLineWidth(0);
102 					g.drawLine(xposition, yposition,right,yposition);
103 					g.drawLine(left,yposition,xposition, yposition);
104     		    }
105 
106 				if (i > 0) // don't draw for first segment
107 					g.drawLine(lastx, lasty, xposition, yposition);
108 
109 				g.setBackground(thisItem.color);
110 				g.setForeground(thisItem.color);
111 			//	g.fillOval(xposition - 2, yposition - 2, 6, 6);
112 				g.fillRectangle(xposition - 2, yposition - 2, 5, 5);
113 
114 				if (thisItem.isSpecial)
115 					g.drawRectangle(xposition -4, yposition - 4, 8, 8);
116 
117 				if (this.fAreaBuffer == null)
118 					this.fAreaBuffer = new StringBuffer();
119 
120 				this.fAreaBuffer.append("\r<area shape=\"circle\" coords=\""
121 						+ (xposition - 2) + ',' + (yposition - 2) + ',' + 5
122 						+ " alt=\"" + thisItem.title + ": "
123 						+ thisItem.description + "\"" + " title=\""
124 						+ thisItem.title + ": " + thisItem.description + "\">");
125 
126 				int shift;
127 				if (i > 0 && yposition < lasty)
128 					shift = 3; // below dot
129 				else
130 					shift = -(2 * titleHeight + 3); // above dot
131 				if (thisItem.displayDescription) {
132 					g.drawString(thisItem.title, xposition + 2, yposition
133 							+ shift, true);
134 					g.drawString(thisItem.description, xposition + 2, yposition
135 							+ shift + titleHeight, true);
136 				}
137 				g.setBackground(oldbg);
138 				g.setForeground(oldfg);
139 
140 				lastx = xposition;
141 				lasty = yposition;
142 			}
143 		}
144 
145         g.dispose();
146     }
147 
addItem(String groupName,String name, String description, double value, Color col, boolean display, long timestamp)148     public void addItem(String groupName,String name, String description, double value, Color col, boolean display, long timestamp) {
149     	addItem(groupName, name, description, value, col, display,	timestamp,false);
150     }
151 
addItem(String groupName,String name, String description, double value, Color col, boolean display, long timestamp,boolean isSpecial)152     public void addItem(String groupName,String name, String description, double value, Color col, boolean display, long timestamp,boolean isSpecial) {
153  		addItem(groupName, name,description, value, col, display,
154  				timestamp,isSpecial,false);
155 	}
156 
addItem(String groupName,String name, String description, double value, Color col, boolean display, long timestamp,boolean isSpecial,boolean drawBaseline)157     public void addItem(String groupName,String name, String description, double value, Color col, boolean display, long timestamp,boolean isSpecial,boolean drawBaseline) {
158       	List items = (List) this.fItemGroups.get(groupName);
159   		if (this.fItemGroups.get(groupName) == null) {
160   			items=new ArrayList();
161   			this.fItemGroups.put(groupName, items);
162   		}
163   		items.add(new TimeLineGraphItem(name, description, value, col, display,
164   				timestamp,isSpecial,drawBaseline));
165     }
166 
getMaxItem()167     public double getMaxItem() {
168     	Enumeration _enum=this.fItemGroups.elements();
169         double maxItem= 0;
170     	while (_enum.hasMoreElements()) {
171 			List items = (List) _enum.nextElement();
172 			for (int i = 0; i < items.size(); i++) {
173 				TimeLineGraphItem graphItem = (TimeLineGraphItem) items.get(i);
174 				if (graphItem.value > maxItem)
175 					maxItem = graphItem.value;
176 			}
177 		}
178         if (maxItem == 0)
179             return 1;
180         return maxItem;
181     }
182 
getMinItem()183     public double getMinItem() {
184        	Enumeration _enum = this.fItemGroups.elements();
185 		double minItem = getMaxItem();
186 
187 		while (_enum.hasMoreElements()) {
188 			List items = (List) _enum.nextElement();
189 			for (int i = 0; i < items.size(); i++) {
190 				TimeLineGraphItem graphItem = (TimeLineGraphItem) items.get(i);
191 				if (graphItem.value < minItem)
192 					minItem = graphItem.value;
193 			}
194 		}
195         if (minItem == 0)
196             return -1;
197         return minItem;
198     }
199 
getMostRecent(Hashtable lineGraphGroups)200     private TimeLineGraphItem getMostRecent(Hashtable lineGraphGroups) {
201 		Enumeration _enum = lineGraphGroups.elements();
202 		long mostRecentTimestamp = 0;
203 		TimeLineGraphItem mostRecentItem = null;
204 
205 		while (_enum.hasMoreElements()) {
206 			List items = (List) _enum.nextElement();
207 			for (int i = 0; i < items.size(); i++) {
208 				if (items.size() == 1)
209 					return (TimeLineGraphItem) items.get(i);
210 				else {
211 					TimeLineGraphItem graphItem = (TimeLineGraphItem) items.get(i);
212 					if (graphItem.timestamp > mostRecentTimestamp) {
213 						mostRecentTimestamp = graphItem.timestamp;
214 						mostRecentItem = (TimeLineGraphItem) items.get(i);
215 					}
216 				}
217 			}
218 		}
219 		return mostRecentItem;
220 	}
221 
setCoordinates(int width, int xOffset, int height, int yOffset, int yValueRange)222     private void setCoordinates(int width, int xOffset, int height, int yOffset, int yValueRange){
223 
224         List mainGroup=(ArrayList)this.fItemGroups.get("main");
225         List referenceGroup=(ArrayList)this.fItemGroups.get("reference");
226 
227         Comparator comparator=new TimeLineGraphItem.GraphItemComparator();
228 
229  		Object[] fItemsArray=mainGroup.toArray();
230 		Arrays.sort(fItemsArray,comparator);
231 
232 		int n = mainGroup.size();
233 		int xIncrement=width/n;
234 		double max=getMaxItem()*1.2;
235 //		double min=getMinItem()*0.8;
236 
237 		for (int i = 0; i < n; i++) {
238 			TimeLineGraphItem thisItem = (TimeLineGraphItem) fItemsArray[i];
239 			thisItem.setX(xOffset + (i * xIncrement));
240 			thisItem.setY((int)(PADDING+((max-thisItem.value) * (height)/(yValueRange))));
241 
242 			}
243 
244 		if (referenceGroup==null)
245 			return;
246 
247 		n = referenceGroup.size();
248 		for (int i = 0; i < n; i++) {
249 			 TimeLineGraphItem thisItem = (TimeLineGraphItem) referenceGroup.get(i);
250 			 if (thisItem.timestamp==-1)
251 				 thisItem.setX(xOffset + (i * (width/n)));
252 			 else
253 				 setRelativeXPosition(thisItem,mainGroup);
254 
255 			 thisItem.setY((int)(PADDING+((max-thisItem.value) * (height)/(yValueRange))));
256 
257 		}
258     }
259 
260 
setRelativeXPosition(TimeLineGraphItem thisItem, List items)261 	private void setRelativeXPosition (TimeLineGraphItem thisItem, List items){
262 			Comparator comparator=new TimeLineGraphItem.GraphItemComparator();
263 			Object[] fItemsArray=items.toArray();
264 			Arrays.sort(fItemsArray,comparator);
265 
266 			TimeLineGraphItem closestPrecedingItem=null;
267 			long minimumTimeDiffPreceding=thisItem.timestamp;
268 
269 			TimeLineGraphItem closestFollowingItem=null;
270 			long minimumTimeDiffFollowing=thisItem.timestamp;
271 
272 			for (int i=0;i<fItemsArray.length;i++){
273 				TimeLineGraphItem anItem=(TimeLineGraphItem)fItemsArray[i];
274 				long timeDiff=thisItem.timestamp-anItem.timestamp;
275 
276 				 if (timeDiff>0&&timeDiff<minimumTimeDiffPreceding){
277 					 closestPrecedingItem=anItem;
278 				 	minimumTimeDiffPreceding=thisItem.timestamp-anItem.timestamp;
279 				 }
280 				 if (timeDiff<=0&&Math.abs(timeDiff)<=minimumTimeDiffFollowing){
281 					 closestFollowingItem=anItem;
282 					 minimumTimeDiffFollowing=thisItem.timestamp-anItem.timestamp;
283 				 }
284 			}
285 			if (closestFollowingItem==null && closestPrecedingItem!=null)
286 				thisItem.setX(closestPrecedingItem.x);
287 
288 			else if (closestFollowingItem!=null && closestPrecedingItem==null)
289 				thisItem.setX(closestFollowingItem.x);
290 			else{
291 				long timeRange=closestFollowingItem.timestamp-closestPrecedingItem.timestamp;
292 
293 				int xRange=closestFollowingItem.x-closestPrecedingItem.x;
294 				double increments=(xRange*1.0)/timeRange;
295 
296 				thisItem.setX((int)(Math.round((thisItem.timestamp-closestPrecedingItem.timestamp)*increments)+closestPrecedingItem.x));
297 			}
298 	}
299 }
300