/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package CPS.Core.CropPlanStats;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.ToolTipManager;
public class ChartPanel extends JPanel {
private List<Double> values;
private List<String> names;
private String title;
private int titleHeight = 0;
private int headerHeight = 0;
private int barWidth = 0;
public ChartPanel( List<Double> v, List<String> n, String t ) {
names = n;
values = v;
title = t;
ToolTipManager.sharedInstance().registerComponent(this);
}
@Override
public String getToolTipText(MouseEvent event) {
if ( barWidth < 1 || event.getY() < headerHeight )
return "";
int i = ( event.getY() - headerHeight ) / ( barWidth );
if ( i >= names.size() )
return "";
String s = "" + names.get(i) + ": " + values.get(i) + "";
return s;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (values == null || values.isEmpty() )
return;
//************************************************************************//
// find smallest & largest values, also longest label
//************************************************************************//
double minValue = 0;
double maxValue = 0;
int longestLabelIndex = 0;
for (int i = 0; i < values.size(); i++) {
if ( names.get(i).length() > names.get(longestLabelIndex).length() )
longestLabelIndex = i;
if (minValue > values.get(i))
minValue = values.get(i);
if (maxValue < values.get(i))
maxValue = values.get(i);
}
//************************************************************************//
// Find some sizes
//************************************************************************//
Dimension d = getSize();
int clientWidth = d.width;
int clientHeight = d.height;
// Setup the fonts
Font titleFont = new Font("SansSerif", Font.BOLD, 20);
FontMetrics titleFontMetrics = g.getFontMetrics(titleFont);
Font labelFont = new Font("SansSerif", Font.PLAIN, 10);
FontMetrics labelFontMetrics = g.getFontMetrics(labelFont);
int labelWidth = labelFontMetrics.stringWidth( names.get(longestLabelIndex) );
int labelHeight = labelFontMetrics.getHeight();
//************************************************************************//
// Draw the title
//************************************************************************//
if ( ! title.equals("") ) {
int titleWidth = titleFontMetrics.stringWidth(title);
titleHeight = titleFontMetrics.getHeight();
g.setFont(titleFont);
g.drawString( title,
(clientWidth - titleWidth) / 2,
titleFontMetrics.getAscent() );
}
headerHeight = titleHeight + labelHeight;
// determine bar thickness
barWidth = ( clientHeight - headerHeight ) / values.size();
// and a scale factor to make the bars fill the window
double scale = ( clientWidth - labelWidth - 3 ) / ( maxValue - minValue );
// set the font (we're only drawing labels from here on
g.setFont(labelFont);
//************************************************************************//
// draw the vertical guides and top labels
//************************************************************************//
g.setColor(Color.black);
String s = "" + Math.ceil( maxValue * 4 ) / 4;
g.drawString( s, clientWidth - labelFontMetrics.stringWidth( s ), headerHeight - 1);
g.drawLine( clientWidth - 2, headerHeight + 1,
clientWidth - 2, clientHeight - 2 );
s = "" + Math.ceil( maxValue * .66 * 4 ) / 4;
g.drawString( s,
(int) ((( clientWidth - labelWidth ) * .66 ) + labelWidth -
( labelFontMetrics.stringWidth( s ) / 2 )),
headerHeight - 1);
g.drawLine( (int) (( clientWidth - labelWidth ) * .66 ) + labelWidth, headerHeight + 1,
(int) (( clientWidth - labelWidth ) * .66 ) + labelWidth, clientHeight - 2 );
s = "" + Math.ceil( maxValue * .33 * 4 ) / 4;
g.drawString( s,
(int) ((( clientWidth - labelWidth ) * .33 ) + labelWidth -
( labelFontMetrics.stringWidth( s ) / 2 )),
headerHeight - 1);
g.drawLine( (int) (( clientWidth - labelWidth ) * .33 ) + labelWidth, headerHeight + 1,
(int) (( clientWidth - labelWidth ) * .33 ) + labelWidth, clientHeight - 2 );
//************************************************************************//
// draw the actual bars
//************************************************************************//
for (int i = 0; i < values.size(); i++) {
int y = i * ( barWidth ) + headerHeight;
int x = labelWidth + 1;
int length = (int) ( values.get(i) * scale );
g.setColor(Color.red);
g.fillRect( x, y+1, length, barWidth - 2 );
g.setColor(Color.black);
g.drawRect( x, y+1, length, barWidth - 2 );
g.drawString( names.get(i), 1, y - 1 + labelHeight / 2 + barWidth / 2 );
}
}
public static void main(String[] argv) {
JFrame f = new JFrame();
f.setSize(400, 300);
int size = 30;
List<Double> values = new ArrayList<Double>( size );
List<String> names = new ArrayList<String>( size );
for ( int i = 0; i < size; i++ ) {
values.add( i * 1d );
names.add( "Item " + i );
}
f.getContentPane().add(new ChartPanel( values,
names, "A title"));
WindowListener wndCloser = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
f.addWindowListener(wndCloser);
f.setVisible(true);
}
}