Some work done on charts
This commit is contained in:
parent
3df20257b0
commit
eb30472a76
5 changed files with 221 additions and 182 deletions
|
|
@ -33,7 +33,6 @@ import java.util.logging.Logger;
|
|||
|
||||
public abstract class AbstractChart extends JPanel{
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** The offset from the borders of the panel in pixels */
|
||||
public static final int PADDING = 20;
|
||||
|
|
@ -46,72 +45,24 @@ public abstract class AbstractChart extends JPanel{
|
|||
|
||||
|
||||
protected void paintComponent(Graphics g){
|
||||
Graphics2D g2 = (Graphics2D)g;
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
|
||||
Rectangle bound = drawScale( g2 );
|
||||
Rectangle bound = drawAxis( g2, new Rectangle(0, 0, getWidth(), getHeight()));
|
||||
drawChart( g2, bound );
|
||||
}
|
||||
|
||||
protected Rectangle drawScale(Graphics2D g2){
|
||||
if( data == null )
|
||||
return null;
|
||||
|
||||
// update values
|
||||
width = this.getWidth();
|
||||
height = this.getHeight();
|
||||
Rectangle bound = new Rectangle();
|
||||
|
||||
// Values
|
||||
int stepLength = 7;
|
||||
|
||||
/////// Temp values
|
||||
// Calculate Font sizes
|
||||
FontMetrics metric = g2.getFontMetrics();
|
||||
int fontHeight = metric.getHeight();
|
||||
int fontXWidth = 0;
|
||||
int fontYWidth = 0;
|
||||
for( Point p : data.getPoints() ){
|
||||
int length = 0;
|
||||
String tmp = data.getXString( p.x );
|
||||
if( tmp != null ) length = metric.stringWidth( tmp );
|
||||
else length = metric.stringWidth( ""+p.x );
|
||||
fontXWidth = Math.max(length, fontXWidth);
|
||||
|
||||
tmp = data.getXString( p.y );
|
||||
if( tmp != null ) length = metric.stringWidth( tmp );
|
||||
else length = metric.stringWidth( ""+p.y );
|
||||
fontYWidth = Math.max(length, fontYWidth);
|
||||
}
|
||||
// Calculate origo
|
||||
Point origo = new Point( PADDING+fontYWidth+stepLength, height-PADDING-fontHeight-stepLength );
|
||||
bound.x = (int) (origo.getX()+1);
|
||||
bound.y = PADDING;
|
||||
bound.width = width-bound.x-PADDING;
|
||||
bound.height = (int) (origo.getY()-PADDING-1);
|
||||
// Calculate Axis scales
|
||||
double xScale = (double)(Math.abs(data.getMaxX())+Math.abs(data.getMinX()))/bound.width;
|
||||
double yScale = (double)(Math.abs(data.getMaxY())+Math.abs(data.getMinY()))/bound.height;
|
||||
|
||||
|
||||
/////// Draw
|
||||
// Y Axis
|
||||
g2.draw( new Line2D.Double( origo.getX(), PADDING, origo.getX(), origo.getY() ));
|
||||
// X Axis
|
||||
g2.draw( new Line2D.Double( origo.getX(), origo.getY(), width-PADDING, origo.getY() ));
|
||||
// Y Axis steps and labels
|
||||
g2.draw( new Line2D.Double( origo.getX(), origo.getY(), origo.getX()-stepLength, origo.getY() ));
|
||||
g2.draw( new Line2D.Double( origo.getX(), PADDING, origo.getX()-stepLength, PADDING ));
|
||||
|
||||
// X Axis steps and labels
|
||||
g2.draw( new Line2D.Double( width-PADDING, origo.getY(), width-PADDING, origo.getY()+stepLength ));
|
||||
|
||||
// DEBUG
|
||||
/*
|
||||
g2.setColor(Color.red);
|
||||
g2.drawRect(bound.x, bound.y, bound.width, bound.height);
|
||||
/**
|
||||
* This method will draw the axis of the chart
|
||||
*
|
||||
* @param g2 is the Graphics object that will paint the chart
|
||||
* @param bound is the bounds of the axis, the drawing should not exceed this bound
|
||||
*/
|
||||
return bound;
|
||||
}
|
||||
protected abstract Rectangle drawAxis(Graphics2D g2, Rectangle bound);
|
||||
|
||||
/**
|
||||
* This method is called after the chart scale has been drawn.
|
||||
|
|
@ -133,22 +84,34 @@ public abstract class AbstractChart extends JPanel{
|
|||
}
|
||||
|
||||
/**
|
||||
* Converts a x value to ax pixel coordinate
|
||||
* Converts a x value to a x pixel coordinate
|
||||
*
|
||||
* @param x is the x data value
|
||||
* @return pixel coordinate, or 0 if the chart have not been drawn yet.
|
||||
* @param scale is the data scale
|
||||
* @param bound is the drawing boundds
|
||||
* @return a x pixel coordinate
|
||||
*/
|
||||
protected int getXCoordinate(int x){
|
||||
return 0;
|
||||
static protected double getXCoordinate(double x, double scale, Rectangle bound){
|
||||
return bound.x + x * scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a y value to a y pixel coordinate
|
||||
*
|
||||
* @param y is the y data value
|
||||
* @return pixel coordinate, or 0 if the chart have not been drawn yet.
|
||||
* @param scale is the data scale
|
||||
* @param bound is the drawing boundds
|
||||
* @return a y pixel coordinate
|
||||
*/
|
||||
protected int getYCoordinate(int y){
|
||||
return 0;
|
||||
static protected double getYCoordinate(double y, double scale, Rectangle bound){
|
||||
return bound.y + bound.height - ( y * scale );
|
||||
}
|
||||
|
||||
static protected double getXScale(ChartData data, Rectangle bound){
|
||||
return (double) bound.width / (Math.abs(data.getMaxX()) + Math.abs(data.getMinX()));
|
||||
}
|
||||
|
||||
static protected double getYScale(ChartData data, Rectangle bound){
|
||||
return (double) bound.height / (Math.abs(data.getMaxY()) + Math.abs(data.getMinY()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@ public class ChartData {
|
|||
|
||||
private HashMap<Integer,String> xStrings;
|
||||
private HashMap<Integer,String> yStrings;
|
||||
private int maxx;
|
||||
private int minx;
|
||||
private int maxy;
|
||||
private int miny;
|
||||
private int maxX;
|
||||
private int minX;
|
||||
private int maxY;
|
||||
private int minY;
|
||||
|
||||
private ArrayList<Point> points;
|
||||
|
||||
|
|
@ -61,37 +61,37 @@ public class ChartData {
|
|||
setMaxMin(x, y);
|
||||
}
|
||||
public void addPoint(int y){
|
||||
points.add( new Point( maxx, y));
|
||||
maxx++;
|
||||
setMaxMin(maxx, y);
|
||||
points.add( new Point(maxX, y));
|
||||
maxX++;
|
||||
setMaxMin(maxX, y);
|
||||
}
|
||||
public void addPoint(String x, int y){
|
||||
xStrings.put(maxx, x);
|
||||
points.add( new Point( maxx, y));
|
||||
maxx++;
|
||||
setMaxMin(maxx, y);
|
||||
xStrings.put(maxX, x);
|
||||
points.add( new Point(maxX, y));
|
||||
maxX++;
|
||||
setMaxMin(maxX, y);
|
||||
}
|
||||
|
||||
|
||||
private void setMaxMin(int x, int y){
|
||||
if( x > maxx ) maxx = x;
|
||||
else if( x < minx ) minx = x;
|
||||
if( x > maxX) maxX = x;
|
||||
if( x < minX) minX = x;
|
||||
|
||||
if( y > maxy ) maxx = y;
|
||||
else if( y < miny ) minx = y;
|
||||
if( y > maxY) maxY = y;
|
||||
if( y < minY) minY = y;
|
||||
}
|
||||
|
||||
public int getMaxX(){
|
||||
return maxx;
|
||||
return maxX;
|
||||
}
|
||||
public int getMinX(){
|
||||
return minx;
|
||||
return minX;
|
||||
}
|
||||
public int getMaxY(){
|
||||
return maxy;
|
||||
return maxY;
|
||||
}
|
||||
public int getMinY(){
|
||||
return miny;
|
||||
return minY;
|
||||
}
|
||||
public String getXString(int x){
|
||||
return xStrings.get(x);
|
||||
|
|
|
|||
75
src/zutil/chart/LineAxis.java
Executable file
75
src/zutil/chart/LineAxis.java
Executable file
|
|
@ -0,0 +1,75 @@
|
|||
package zutil.chart;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.Line2D;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class LineAxis extends AbstractChart{
|
||||
|
||||
@Override
|
||||
protected Rectangle drawAxis(Graphics2D g2, Rectangle bound){
|
||||
if( data == null )
|
||||
return null;
|
||||
|
||||
width = bound.width;
|
||||
height = bound.height;
|
||||
chartBound = new Rectangle();
|
||||
int stepLength = 7;
|
||||
|
||||
// **********************************
|
||||
// Calculate Font sizes
|
||||
// **********************************
|
||||
|
||||
FontMetrics metric = g2.getFontMetrics();
|
||||
int fontHeight = metric.getHeight();
|
||||
int fontXWidth = 0;
|
||||
int fontYWidth = 0;
|
||||
for( Point p : data.getPoints() ){
|
||||
int length;
|
||||
String tmp = data.getXString( p.x );
|
||||
if( tmp != null ) length = metric.stringWidth( tmp );
|
||||
else length = metric.stringWidth( ""+p.x );
|
||||
fontXWidth = Math.max(length, fontXWidth);
|
||||
|
||||
tmp = data.getXString( p.y );
|
||||
if( tmp != null ) length = metric.stringWidth( tmp );
|
||||
else length = metric.stringWidth( ""+p.y );
|
||||
fontYWidth = Math.max(length, fontYWidth);
|
||||
}
|
||||
|
||||
// Calculate origo
|
||||
|
||||
Point origo = new Point(
|
||||
PADDING + fontYWidth + stepLength,
|
||||
height - PADDING - fontHeight - stepLength );
|
||||
chartBound.x = (int) (origo.getX() + 1);
|
||||
chartBound.y = PADDING;
|
||||
chartBound.width = width - chartBound.x - PADDING;
|
||||
chartBound.height = (int) (origo.getY() - PADDING - 1);
|
||||
|
||||
// **********************************
|
||||
// Draw
|
||||
// **********************************
|
||||
|
||||
g2.setColor(Color.LIGHT_GRAY);
|
||||
g2.setStroke(new BasicStroke(1.5f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND));
|
||||
|
||||
// Y Axis
|
||||
g2.draw( new Line2D.Double( origo.getX(), PADDING, origo.getX(), origo.getY() ));
|
||||
// X Axis
|
||||
g2.draw( new Line2D.Double( origo.getX(), origo.getY(), width-PADDING, origo.getY() ));
|
||||
// Y Axis steps and labels
|
||||
|
||||
// X Axis steps and labels
|
||||
|
||||
// DEBUG
|
||||
/*
|
||||
g2.setColor(Color.red);
|
||||
g2.drawRect(bound.x, bound.y, bound.width, bound.height);
|
||||
*/
|
||||
return chartBound;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -27,36 +27,36 @@ package zutil.chart;
|
|||
import java.awt.*;
|
||||
import java.awt.geom.Line2D;
|
||||
|
||||
public class LineChart extends AbstractChart{
|
||||
public class LineChart extends LineAxis{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void drawChart(Graphics2D g2, Rectangle bound) {
|
||||
// TODO Auto-generated method stub
|
||||
drawLine(g2, 50, 50,100,150);
|
||||
drawLine(g2, 100,150,150,100);
|
||||
drawLine(g2, 150,100,200,300);
|
||||
drawLine(g2, 200,300,250,40);
|
||||
}
|
||||
|
||||
private void drawLine(Graphics2D g2, float x1, float y1, float x2, float y2){
|
||||
// Shadow
|
||||
g2.setPaint(new Color(220,220,220));
|
||||
g2.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
|
||||
g2.draw( new Line2D.Float(x1, y1+2, x2, y2+2));
|
||||
// Smoth shadow
|
||||
g2.setPaint(new Color(230,230,230));
|
||||
g2.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
|
||||
g2.draw( new Line2D.Float(x1+1, y1+3, x2-1, y2+3));
|
||||
|
||||
// Line border
|
||||
g2.setPaint(new Color(255,187,187));
|
||||
g2.setStroke(new BasicStroke(4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
|
||||
g2.draw( new Line2D.Float(x1, y1, x2, y2));
|
||||
|
||||
// Line
|
||||
g2.setPaint(new Color(237,28,36));
|
||||
g2.setStroke(new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
|
||||
g2.draw( new Line2D.Float(x1, y1, x2, y2));
|
||||
|
||||
// Calculate position
|
||||
|
||||
double xScale = getXScale(data, bound);
|
||||
double yScale = getYScale(data, bound);
|
||||
|
||||
// Draw lines
|
||||
|
||||
Point prevP = null;
|
||||
for(Point p : data.getPoints()){
|
||||
if (prevP != null)
|
||||
drawLine(g2, bound, xScale, yScale, prevP.x, prevP.y, p.x, p.y);
|
||||
prevP = p;
|
||||
}
|
||||
}
|
||||
|
||||
private void drawLine(Graphics2D g2, Rectangle bound, double xScale, double yScale,
|
||||
double x1, double y1, double x2, double y2){
|
||||
// Line
|
||||
g2.draw(new Line2D.Double(
|
||||
getXCoordinate(x1, xScale, bound),
|
||||
getYCoordinate(y1, yScale, bound),
|
||||
getXCoordinate(x2, xScale, bound),
|
||||
getYCoordinate(y2, yScale, bound)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,21 +41,22 @@ public class ChartTest extends JFrame{
|
|||
|
||||
public ChartTest(){
|
||||
ChartData data = new ChartData();
|
||||
data.addPoint(0,0);
|
||||
data.addPoint(1,1);
|
||||
data.addPoint(2,1);
|
||||
data.addPoint(3,1);
|
||||
data.addPoint(4,1);
|
||||
data.addPoint(5,1);
|
||||
data.addPoint(6,1);
|
||||
data.addPoint(7,1);
|
||||
data.addPoint(8,1);
|
||||
data.addPoint(2,2);
|
||||
data.addPoint(3,3);
|
||||
data.addPoint(4,4);
|
||||
data.addPoint(5,5);
|
||||
data.addPoint(6,6);
|
||||
data.addPoint(7,7);
|
||||
data.addPoint(8,8);
|
||||
|
||||
LineChart chart = new LineChart();
|
||||
chart.setChartData( data );
|
||||
this.add( chart );
|
||||
add( chart );
|
||||
|
||||
this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
|
||||
this.setSize(600, 400);
|
||||
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
|
||||
setSize(600, 400);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue