import java.awt.Rectangle; import java.awt.Point; import java.awt.Canvas; import java.awt.Graphics; import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.util.Vector; import java.util.Enumeration; // Based on code by Philip David Meese for creating // a bar chart component public class BarChart extends Canvas { private Vector dataSet = null; private int margin = 5; // Margin for component private int separation = 2; // space between bars private Color barFillColor = Color.blue; private Color barBorderColor = Color.black; private Font captionFont = null; private int captionSeparation = 5; public BarChart(Vector listOfNumbers, Color fill, Color border) { dataSet = listOfNumbers; //reshape(0,0,w,h); barFillColor = fill; barBorderColor = border; captionFont = new Font("Helvetica", Font.BOLD, 12); } public BarChart(Vector listOfNumbers) { this(listOfNumbers, Color.blue, Color.black); } public void setBarFillColor(Color c) { barFillColor = c; } public Color getBarFillColor() { return barFillColor; } public void setBarBorderColor(Color c) { barBorderColor = c; } public Color getBarBorderColor() { return barBorderColor; } public void setDataSet(Vector listOfNumbers) { dataSet = (Vector)listOfNumbers.clone(); repaint(); } public int getMargin() { return margin; } public void setMargin(int m) { margin = m; } public int getSeparation() { return separation; } public void setSeparation(int s) { separation = s; } public Vector getDataSet() { return ((Vector)dataSet.clone()); } public void paint(Graphics g) { paintBackground(g, Color.white); if (dataSet.size() > 0) { paintBars(g, barFillColor, barBorderColor); } } private void paintBackground(Graphics g, Color c) { Rectangle r = bounds(); Color cSave = g.getColor(); // we remember color for resetting g.setColor(c); g.fillRect(0,0,r.width, r.height); g.setColor(cSave); } private void paintBars(Graphics g, Color cFill, Color cBorder) { Color cSave = g.getColor(); // we remember color for resetting Rectangle r = bounds(); // Get the height of the font FontMetrics fm = g.getFontMetrics(captionFont); int fontHeight = fm.getHeight(); int fontAscent = fm.getAscent(); // width and height of rendered area int renderWidth = r.width - margin * 2 - (dataSet.size() - 1) * separation; // Since we will draw the value below the bar, we need the // the fontHeight in there int renderHeight = r.height - margin * 2 - fontAscent - captionSeparation; int barWidth = renderWidth/dataSet.size(); // We need a scaling factor so values fit in a given height float max = 0; for (Enumeration e = dataSet.elements(); e.hasMoreElements();) { float value = ((Float)e.nextElement()).floatValue(); if (value > max) max = value; } float scalingFactor = (float)renderHeight / max; // The following actually makes the bars Point barOrigin = new Point(margin, margin); for (Enumeration e = dataSet.elements(); e.hasMoreElements();) { float value = ((Float)e.nextElement()).floatValue(); int barHeight = (int) (value * scalingFactor); // Remember the shapes draw relative to a top left corner... so // we need to readjust the origin barOrigin.y = margin + renderHeight - barHeight; g.setColor(cBorder); g.drawRect(barOrigin.x, barOrigin.y, barWidth - separation, barHeight); int stringX = barOrigin.x; int stringY = margin + renderHeight + fontAscent + captionSeparation; g.drawString((new Float(value)).toString(), stringX, stringY); g.setColor(cFill); g.fillRect(barOrigin.x+1, barOrigin.y+1, barWidth - separation - 1, barHeight - 1); barOrigin.x += barWidth + separation; } // End of making bars g.setColor(cSave); } // end of paintBars } // end of BarChart class