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 *******************************************************************************/
11package org.eclipse.test.performance.ui;
12
13import java.util.*;
14
15import org.eclipse.swt.graphics.Color;
16import org.eclipse.swt.graphics.GC;
17import org.eclipse.swt.graphics.Image;
18import org.eclipse.swt.graphics.Point;
19import org.eclipse.swt.graphics.Rectangle;
20import org.eclipse.test.internal.performance.data.Dim;
21
22public class LineGraph {
23
24    StringBuffer fAreaBuffer;
25
26    private static class GraphItem {
27
28        String title;
29        String description=null;
30        double value;
31        Color color;
32        boolean displayDescription=false;
33
34        GraphItem(String title, String description,double value, Color color,boolean display) {
35        	this(title, description, value, color);
36        	this.displayDescription=display;
37        }
38
39        GraphItem(String title, String description, double value, Color color) {
40            this.title= title;
41            this.value= value;
42            this.color= color;
43            this.description= description;
44        }
45
46        Point getSize(GC g) {
47            Point e1= g.stringExtent(this.description);
48            Point e2= g.stringExtent(this.title);
49            return new Point(Math.max(e1.x, e2.x), e1.y+e2.y);
50        }
51    }
52
53    static final int PADDING= 15;
54
55
56    String fTitle;
57    List fItems;
58    Dim fDimension;
59
60
61    public LineGraph(String title, Dim dim) {
62        this.fTitle= title;
63        this.fItems= new ArrayList();
64        this.fDimension= dim;
65    }
66
67    public void paint(Image im) {
68
69        Rectangle bounds= im.getBounds();
70
71        GC g= new GC(im);
72
73        Point ee= g.stringExtent(this.fTitle);
74        int titleHeight= ee.y;
75
76        double maxItem= getMaxItem();
77        double minItem= getMinItem();
78
79        int max= (int) (Math.ceil(maxItem * (maxItem < 0 ? 0.9 : 1.2)));
80        int min= (int) (Math.floor(minItem * (minItem < 0 ? 1.2 : 0.9)));
81
82        String smin= this.fDimension.getDisplayValue(min);
83        Point emin= g.stringExtent(smin);
84
85        String smax= this.fDimension.getDisplayValue(max);
86        Point emax= g.stringExtent(smax);
87
88        int labelWidth= Math.max(emin.x, emax.x) + 2;
89
90        int top= PADDING;
91        int bottom= bounds.height - titleHeight - PADDING;
92        int left= PADDING + labelWidth;
93
94        GraphItem lastItem= (GraphItem) this.fItems.get(this.fItems.size()-1);
95        int right= bounds.width - lastItem.getSize(g).x - PADDING/2;
96
97        // draw the title
98        //g.drawString(fTitle, (bounds.width - titleWidth) / 2, titleHeight, true);
99
100        // draw the max and min values
101        g.drawString(smin, PADDING/2+labelWidth-emin.x, bottom-titleHeight, true);
102        g.drawString(smax, PADDING/2+labelWidth-emax.x, top, true);
103
104        // draw the vertical and horizontal lines
105        g.drawLine(left, top, left, bottom);
106        g.drawLine(left, bottom, right, bottom);
107
108        Color oldbg= g.getBackground();
109        Color oldfg= g.getForeground();
110
111        int n= this.fItems.size();
112        int xincrement= n > 1 ? (right-left) / (n-1) : 0;
113
114        int graduations= max - min;
115        if (graduations == 0)
116            graduations= 1;
117
118        int lastx= 0;
119        int lasty= 0;
120
121        int xposition= left;
122
123        for (int i= 0; i < n; i++) {
124            GraphItem thisItem= (GraphItem) this.fItems.get(i);
125
126            int yposition= (int) (bottom - (((thisItem.value-min) * (bottom-top)) / graduations));
127
128            if (i > 0)	// don't draw for first segment
129                g.drawLine(lastx, lasty, xposition, yposition);
130
131            g.setBackground(thisItem.color);
132            g.setForeground(thisItem.color);
133            g.fillOval(xposition-2, yposition-2, 5, 5);
134
135            if (this.fAreaBuffer == null)
136                this.fAreaBuffer= new StringBuffer();
137
138            this.fAreaBuffer.append("\r<area shape=\"CIRCLE\" coords=\""+(xposition-2)+','+(yposition-2)+','+5+" alt=\""+ thisItem.title+": "+thisItem.description+"\""+ " title=\""+ thisItem.title+": "+thisItem.description+"\">");
139
140
141            int shift;
142            if (i > 0 && yposition < lasty)
143                shift= 3;	 // below dot
144            else
145                shift= -(2*titleHeight+3);	// above dot
146            if (thisItem.displayDescription){
147            	g.drawString(thisItem.title, xposition+2, yposition+shift, true);
148            	g.drawString(thisItem.description, xposition+2, yposition+shift+titleHeight, true);
149            }
150            g.setBackground(oldbg);
151            g.setForeground(oldfg);
152
153            lastx= xposition;
154            lasty= yposition;
155            xposition+= xincrement;
156        }
157
158        g.dispose();
159    }
160
161    public void addItem(String name, String description, double value, Color col) {
162    	addItem(name, description, value, col,false);
163    }
164
165    public void addItem(String name, String description, double value, Color col, boolean display) {
166        this.fItems.add(new GraphItem(name, description, value, col,display));
167    }
168
169    public double getMaxItem() {
170        double maxItem= 0;
171        for (int i= 0; i < this.fItems.size(); i++) {
172            GraphItem graphItem= (GraphItem) this.fItems.get(i);
173            if (graphItem.value > maxItem)
174                maxItem= graphItem.value;
175        }
176        if (maxItem == 0)
177            return 1;
178        return maxItem;
179    }
180
181    public double getMinItem() {
182        double minItem= getMaxItem();
183        for (int i= 0; i < this.fItems.size(); i++) {
184            GraphItem graphItem= (GraphItem) this.fItems.get(i);
185            if (graphItem.value < minItem)
186                minItem= graphItem.value;
187        }
188        if (minItem == 0)
189            return -1;
190        return minItem;
191    }
192    public String getAreas() {
193        if (this.fAreaBuffer != null) {
194            String s= this.fAreaBuffer.toString();
195            this.fAreaBuffer= null;
196            return s;
197        }
198        return null;
199    }
200}
201