/******************************************************************************* * Copyright (c) 2000, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.test.performance.ui; import java.util.*; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.test.internal.performance.data.Dim; public class LineGraph { StringBuffer fAreaBuffer; private static class GraphItem { String title; String description=null; double value; Color color; boolean displayDescription=false; GraphItem(String title, String description,double value, Color color,boolean display) { this(title, description, value, color); this.displayDescription=display; } GraphItem(String title, String description, double value, Color color) { this.title= title; this.value= value; this.color= color; this.description= description; } Point getSize(GC g) { Point e1= g.stringExtent(this.description); Point e2= g.stringExtent(this.title); return new Point(Math.max(e1.x, e2.x), e1.y+e2.y); } } static final int PADDING= 15; String fTitle; List fItems; Dim fDimension; public LineGraph(String title, Dim dim) { this.fTitle= title; this.fItems= new ArrayList(); this.fDimension= dim; } public void paint(Image im) { Rectangle bounds= im.getBounds(); GC g= new GC(im); Point ee= g.stringExtent(this.fTitle); int titleHeight= ee.y; double maxItem= getMaxItem(); double minItem= getMinItem(); int max= (int) (Math.ceil(maxItem * (maxItem < 0 ? 0.9 : 1.2))); int min= (int) (Math.floor(minItem * (minItem < 0 ? 1.2 : 0.9))); String smin= this.fDimension.getDisplayValue(min); Point emin= g.stringExtent(smin); String smax= this.fDimension.getDisplayValue(max); Point emax= g.stringExtent(smax); int labelWidth= Math.max(emin.x, emax.x) + 2; int top= PADDING; int bottom= bounds.height - titleHeight - PADDING; int left= PADDING + labelWidth; GraphItem lastItem= (GraphItem) this.fItems.get(this.fItems.size()-1); int right= bounds.width - lastItem.getSize(g).x - PADDING/2; // draw the title //g.drawString(fTitle, (bounds.width - titleWidth) / 2, titleHeight, true); // draw the max and min values g.drawString(smin, PADDING/2+labelWidth-emin.x, bottom-titleHeight, true); g.drawString(smax, PADDING/2+labelWidth-emax.x, top, true); // draw the vertical and horizontal lines g.drawLine(left, top, left, bottom); g.drawLine(left, bottom, right, bottom); Color oldbg= g.getBackground(); Color oldfg= g.getForeground(); int n= this.fItems.size(); int xincrement= n > 1 ? (right-left) / (n-1) : 0; int graduations= max - min; if (graduations == 0) graduations= 1; int lastx= 0; int lasty= 0; int xposition= left; for (int i= 0; i < n; i++) { GraphItem thisItem= (GraphItem) this.fItems.get(i); int yposition= (int) (bottom - (((thisItem.value-min) * (bottom-top)) / graduations)); if (i > 0) // don't draw for first segment g.drawLine(lastx, lasty, xposition, yposition); g.setBackground(thisItem.color); g.setForeground(thisItem.color); g.fillOval(xposition-2, yposition-2, 5, 5); if (this.fAreaBuffer == null) this.fAreaBuffer= new StringBuffer(); this.fAreaBuffer.append("\r<area shape=\"CIRCLE\" coords=\""+(xposition-2)+','+(yposition-2)+','+5+" alt=\""+ thisItem.title+": "+thisItem.description+"\""+ " title=\""+ thisItem.title+": "+thisItem.description+"\">"); int shift; if (i > 0 && yposition < lasty) shift= 3; // below dot else shift= -(2*titleHeight+3); // above dot if (thisItem.displayDescription){ g.drawString(thisItem.title, xposition+2, yposition+shift, true); g.drawString(thisItem.description, xposition+2, yposition+shift+titleHeight, true); } g.setBackground(oldbg); g.setForeground(oldfg); lastx= xposition; lasty= yposition; xposition+= xincrement; } g.dispose(); } public void addItem(String name, String description, double value, Color col) { addItem(name, description, value, col,false); } public void addItem(String name, String description, double value, Color col, boolean display) { this.fItems.add(new GraphItem(name, description, value, col,display)); } public double getMaxItem() { double maxItem= 0; for (int i= 0; i < this.fItems.size(); i++) { GraphItem graphItem= (GraphItem) this.fItems.get(i); if (graphItem.value > maxItem) maxItem= graphItem.value; } if (maxItem == 0) return 1; return maxItem; } public double getMinItem() { double minItem= getMaxItem(); for (int i= 0; i < this.fItems.size(); i++) { GraphItem graphItem= (GraphItem) this.fItems.get(i); if (graphItem.value < minItem) minItem= graphItem.value; } if (minItem == 0) return -1; return minItem; } public String getAreas() { if (this.fAreaBuffer != null) { String s= this.fAreaBuffer.toString(); this.fAreaBuffer= null; return s; } return null; } }