alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*******************************************************************************
 * Copyright (c) 2000, 2007 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.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;

public class BarGraph {

	private static final int MARGIN= 5; // margin on all four sides
	private static final int BARHEIGHT= 8; // height of bar
	private static final int GAP= 10; // gap between bars
	private static final int TGAP= 5; // gap between lines and labels

	private static final boolean NO_SCALE= true; // 

	// if NO_SCALE is true the following values are used:
	private static final double RATIO= 0.6; // fraction of width reserved for bar graph; needs tweaking
	private static final int FROM_END= 20; // a break (//) is shown this far from end of bar
	private static final int SLANT= 8; // slant of break
	private static final int GAP2= 5; // width of break

	private StringBuffer fAreaBuffer;

	private static class BarItem {

		String title;
		double value, error;
		String url;
		String slowdownExpected;
		boolean significant;

		BarItem(String t, double[] stats, String u, String slow, boolean sig) {
			title= t;
			value= stats[0]==0 ? 0 : -stats[0] * 100;
			error = stats[1] * 100;
			url= u;
			slowdownExpected= slow;
			significant= sig;
		}
	}

	private String fTitle;
	private List fItems;

	BarGraph(String title) {
		fTitle= title;
		fItems= new ArrayList();
	}

	public void addItem(String name, double[] stats, String url, String slow, boolean significant) {
		fItems.add(new BarItem(name, stats, url, slow, significant));
	}

	public int getHeight() {
		int n= fItems.size();
		int textHeight= 16;
		int titleHeight= 0;
		if (fTitle != null)
			titleHeight= textHeight + GAP;
		return MARGIN + titleHeight + n * (GAP + BARHEIGHT) + GAP + textHeight + MARGIN;
	}

	public void paint(Display display, int width, int height, GC gc) {

		NumberFormat nf= NumberFormat.getInstance();

		BarItem[] bars= (BarItem[]) fItems.toArray(new BarItem[fItems.size()]);

		// draw white background
		Color bg= display.getSystemColor(SWT.COLOR_WHITE);
		gc.setBackground(bg);
		gc.fillRectangle(0, 0, width, height);

		// determine the widths of the bar and the label areas
		int w;
		if (NO_SCALE) {
			// we use a fixed width
			w= (int) (RATIO * width);
		} else {
			// we calculate the max width
			int maxNameLength= 0;
			for (int i= 0; i < bars.length; i++) {
				Point es= gc.stringExtent(bars[i].title);
				maxNameLength= Math.max(maxNameLength, es.x);
			}
			w= width - maxNameLength - TGAP - 2 * MARGIN;
		}

		Color fg= display.getSystemColor(SWT.COLOR_BLACK);

		int vstart= 0; // start rows here
		if (fTitle != null) {
			vstart= gc.stringExtent(fTitle).y + GAP;
			gc.drawString(fTitle, MARGIN, MARGIN, true); // draw title left aligned
		}

		int center= MARGIN + w / 2;
		int w2= w / 2 - gc.stringExtent("-999.9").x - TGAP; // reserve space //$NON-NLS-1$

		// determine maximum of values
		double max= 0.0;
		for (int i= 0; i < bars.length; i++)
			max= Math.max(max, Math.abs(bars[i].value));

		double d;
		if (NO_SCALE) {
			d= 25;
			max= 125;
		} else {
			if (max > 400.0) {
				d= 200;
			} else if (max > 200.0) {
				d= 100;
			} else if (max > 100.0) {
				d= 50;
			} else if (max > 50) {
				d= 25;
			} else if (max > 25) {
				d= 10;
			} else if (max > 10) {
				d= 5;
			} else if (max > 5) {
				d= 2.5;
			} else {
				d= 1.0;
			}
		}

		// draw striped background
		int y= MARGIN + vstart;
		Color lightblue= new Color(display, 237, 243, 254);
		gc.setBackground(lightblue);
		for (int i= 0; i < bars.length; i++)
			if (i % 2 == 0)
				gc.fillRectangle(0, y + i * (BARHEIGHT + GAP), width, BARHEIGHT + GAP);

		// draw grid
		int yy= y + bars.length * (BARHEIGHT + GAP);
		gc.drawLine(center, y, center, yy + TGAP);
		Color grey= display.getSystemColor(SWT.COLOR_GRAY);
		for (int i= 1; d * i < max; i++) {

			double xx= d * i;
			int x= (int) ((xx / max) * w2);

			gc.setForeground(grey);
			gc.drawLine(center - x, y, center - x, yy + TGAP);
			gc.drawLine(center + x, y, center + x, yy + TGAP);

			gc.setForeground(fg);

			String s3= nf.format(-xx) + "%"; //$NON-NLS-1$
			Point es3= gc.stringExtent(s3);
			gc.drawString(s3, center - x - es3.x / 2, yy + TGAP, true);

			String s4= nf.format(xx) + "%"; //$NON-NLS-1$
			Point es4= gc.stringExtent(s4);
			gc.drawString(s4, center + x - es4.x / 2, yy + TGAP, true);
		}
		gc.drawLine(0, yy, w, yy);

		nf.setMaximumFractionDigits(1);

		// link color
		Color blue= display.getSystemColor(SWT.COLOR_BLUE);
		// draw bars
		Color green= display.getSystemColor(SWT.COLOR_GREEN);
		Color red= display.getSystemColor(SWT.COLOR_RED);
		Color gray= display.getSystemColor(SWT.COLOR_GRAY);
		Color yellow= display.getSystemColor(SWT.COLOR_YELLOW);
		Color white= display.getSystemColor(SWT.COLOR_WHITE);
		for (int i= 0; i < bars.length; i++) {

			BarItem bar= bars[i];
			double delta = bar.value;
			double orgDelta= delta;
			
			boolean clamped= false;
			if (NO_SCALE) {
				if (delta > max) {
					delta= max;
					clamped= true;
				} else if (delta < -max) {
					delta= -max;
					clamped= true;
				}
			}

			int barLength= (int) (delta / max * w2);

			if (delta < 0) {
				if (bar.slowdownExpected != null) {
					gc.setBackground(gray);
				} else if (!bar.significant) {
					gc.setBackground(yellow);
				} else  {
					gc.setBackground(red);
				}
			} else if (!bar.significant) {
				gc.setBackground(yellow);
			} else {
				gc.setBackground(green);
			}

			if (barLength > 0) {
				gc.fillRectangle(center, y + (GAP / 2), barLength, BARHEIGHT);
				gc.drawRectangle(center, y + (GAP / 2), barLength, BARHEIGHT);
			} else if (barLength < 0) {
				gc.fillRectangle(center+barLength, y + (GAP / 2), -barLength, BARHEIGHT);
				gc.drawRectangle(center+barLength, y + (GAP / 2), -barLength, BARHEIGHT);
			}

			if (clamped) {

				int h2= (BARHEIGHT + GAP);
				int x= center + barLength;
				if (barLength > 0)
					x-= FROM_END;
				else
					x+= FROM_END - GAP2 - SLANT;
				int[] pts= new int[] { x, y + h2 - 1, x + SLANT, y + 1, x + SLANT + GAP2, y + 1, x + GAP2, y + h2 - 1};
				if (i % 2 == 0)
					gc.setBackground(lightblue);
				else
					gc.setBackground(white);
				gc.fillPolygon(pts);
				gc.drawLine(pts[0], pts[1], pts[2], pts[3]);
				gc.drawLine(pts[4], pts[5], pts[6], pts[7]);
			}

			String label= nf.format(orgDelta);
			Point labelExtent= gc.stringExtent(label);
			int labelxpos= center + barLength;
			int labelvpos= y + (BARHEIGHT + GAP - labelExtent.y) / 2;
			if (orgDelta > 0.0) {
				gc.drawString(label, labelxpos + TGAP, labelvpos, true);
			} else {
				gc.drawString(label, labelxpos - TGAP - labelExtent.x, labelvpos, true);
			}

			int x= MARGIN + w + TGAP;
			String title= bar.title;
			boolean hasURL= bar.url != null;
			Color oldfg= gc.getForeground();
			if (hasURL) {
				gc.setForeground(blue);
				Point e= gc.stringExtent(title);
				gc.drawLine(x, labelvpos + e.y - 1, x + e.x, labelvpos + e.y - 1);
			}
			gc.drawString(title, x, labelvpos, true);
			if (hasURL)
				gc.setForeground(oldfg);

			int y0= y;
			y+= BARHEIGHT + GAP;

			if (hasURL) {
				if (fAreaBuffer == null)
					fAreaBuffer= new StringBuffer();
				fAreaBuffer.append("<area shape=\"RECT\" coords=\"0," + y0 + ',' + width + ',' + y + "\" href=\"" + bar.url + "\">\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			}
		}

		lightblue.dispose();
	}

	public String getAreas() {
		if (fAreaBuffer != null) {
			String s= fAreaBuffer.toString();
			fAreaBuffer= null;
			return s;
		}
		return null;
	}
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.