Java/Advanced Graphics/Chart
Версия от 18:01, 31 мая 2010; (обсуждение)
Содержание
Animation Line Chart
import java.awt.*;
import java.applet.*;
import java.net.URL;
import java.util.*;
import graph.*;
/*************************************************************************
**
** Applet example2
** Version 1.0 January 1996
**
**************************************************************************
** Copyright (C) 1996 Leigh Brookshaw
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**************************************************************************
**
** This is a simple applet that creates a Scroll Chart using the
** Graph2D class library
**
*************************************************************************/
public class example2 extends Applet {
Graph2D graph;
Label title;
DataSet data1 = new DataSet();
CalculateData cd1;
Axis yaxis_right;
/*
** In milliseconds how often do we want to add a new data point.
*/
int period = 500;
/*
** Maximum number of points to display before scrolling the data
*/
int maximum = 25;
URL markersURL;
/*
** Initialize the applet. The Parameters passed are the title of the plot
** the marker file to use and the update period in milliseconds
*/
public void init() {
int i;
int j;
/*
** Get the passed parameters
*/
String st = "TITLE";
String mfile = "marker.txt";
period = 10;//Integer.parseInt(getParameter("PERIOD"));
/*
** Create the Graph instance and modify the default behaviour
*/
graph = new Graph2D();
graph.zerocolor = new Color(0,255,0);
graph.borderTop = 50;
graph.borderBottom = 50;
/*
** Create the Title
*/
title = new Label(st, Label.CENTER);
title.setFont(new Font("TimesRoman",Font.PLAIN,25));
setLayout( new BorderLayout() );
add("North", title);
add("Center", graph);
/*
** Load a file containing Marker definitions
*/
try {
markersURL = this.getClass().getResource(mfile);
graph.setMarkers(new Markers(markersURL));
} catch(Exception e) {
System.out.println("Failed to create Marker URL!");
}
/*
** Modify the default Data behaviour
*/
data1.linecolor = new Color(255,0,0);
data1.marker = 1;
data1.markercolor = new Color(100,100,255);
/*
** Setup the Axis. Attach it to the Graph2D instance, and attach the data
** to it.
*/
yaxis_right = graph.createAxis(Axis.RIGHT);
yaxis_right.attachDataSet(data1);
yaxis_right.setLabelFont(new Font("Helvetica",Font.PLAIN,20));
graph.attachDataSet(data1);
/*
** Calculate the data asynchronously using a new Thread.
*/
cd1 = new CalculateData(data1,graph,period,maximum);
cd1.start();
}
public static void main(String[] a){
javax.swing.JFrame f = new javax.swing.JFrame();
Applet app = new example2();
app.init();
f.getContentPane().add (app);
f.pack();
f.setSize (new Dimension (500, 500));
f.setVisible(true);
}
}
/*
** Here is the Thread class to calculate the data and append it to the existing
** data set.
** This class is easily modified to get the data from a server
** or the local machine. Currently the data is Random.
*/
class CalculateData extends Thread {
// local copy of the update period in milliseconds
int p = 1000;
DataSet d;
Graph2D g;
// local copy of the maximum number of points.
int m = 25;
Random random = new Random();
public CalculateData(DataSet ds, Graph2D g, int p, int m)
{
this.d = ds;
this.g = g;
if(p > 100 ) this.p = p;
if(m > 0 ) this.m = m;
}
public void run() {
int i =0;
double data[] = new double[2];
int count = 0;
if(d == null) return;
setPriority(Thread.MIN_PRIORITY);
while(true) {
count++;
if(count >= m) d.delete(0,0);
data[1] = (2.0*random.nextDouble() - 1.0)*15.0;
data[0] = count;
try {
d.append(data,1);
}
catch (Exception e) {
System.out.println("Error appending Data!");
}
d.yaxis.maximum = 15.0;
d.yaxis.minimum = -15.0;
// To avoid flashing try and repaint halfway through the sleep
g.repaint(p/2);
try { sleep(p); }
catch(Exception e) { }
}
}
}
A rudimentary bar chart class
import java.awt.*;
import java.util.*;
import javax.swing.*;
import no.geosoft.cc.geometry.Geometry;
import no.geosoft.cc.graphics.*;
/**
* G demo program. Demonstrates:
*
* <ul>
* <li>A rudimentory bar chart class
* <li>Rendering techniques
* </ul>
*
* @author
== A rudimentary chart library ==
<!-- start source code -->
<source lang="java">
import java.util.Iterator;
import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;
import javax.swing.*;
import no.geosoft.cc.geometry.Geometry;
import no.geosoft.cc.util.NiceNumbers;
import no.geosoft.cc.util.NiceNumber;
import no.geosoft.cc.graphics.*;
/**
* G demo program. Demonstrates:
*
* <ul>
* <li>A rudimentary chart library
* <li>The use of multiple scenes
* <li>World extent usage
* <li>Zooming and scrolling
* <li><em>Nice number</em> generation
* </ul>
*
* @author
== bar-graph drawable ==
<!-- start source code -->
<source lang="java">
/**
*
* LibSparkline : a free Java sparkline chart library
*
*
* Project Info: http://reporting.pentaho.org/libsparkline/
*
* (C) Copyright 2008, by Larry Ogrodnek, Pentaho Corporation and Contributors.
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the Apache License 2.0.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the Apache License 2.0 along with this library;
* if not, a online version is available at http://www.apache.org/licenses/
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------
* BarGraphDrawable.java
* ------------
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
/**
* A very fast and very simple bar-graph drawable. This code is based on the BarGraph class writen by Larry Ogrodnek
* but instead of producing a low-resolution image, this class writes the content into a Graphics2D context.
*
* @author Thomas Morgner
*/
public class BarGraphDrawable
{
private static final int DEFAULT_SPACING = 2;
private static final Color DEFAULT_COLOR = Color.gray;
private static final Color DEFAULT_HIGH_COLOR = Color.black;
private static final Color DEFAULT_LAST_COLOR = Color.red;
private Number[] data;
private Color color;
private Color highColor;
private Color lastColor;
private Color background;
private int spacing;
/**
* Creates a default bargraph drawable with some sensible default colors and spacings.
*/
public BarGraphDrawable()
{
this.highColor = BarGraphDrawable.DEFAULT_HIGH_COLOR;
this.lastColor = BarGraphDrawable.DEFAULT_LAST_COLOR;
this.color = BarGraphDrawable.DEFAULT_COLOR;
this.spacing = BarGraphDrawable.DEFAULT_SPACING;
}
/**
* Returns the numeric data for the drawable or null, if the drawable has no data.
*
* @return the data.
*/
public Number[] getData()
{
return data;
}
/**
* Defines the numeric data for the drawable or null, if the drawable has no data.
*
* @param data the data (can be null).
*/
public void setData(final Number[] data)
{
this.data = data;
}
/**
* Returns the main color for the bars.
*
* @return the main color for the bars, never null.
*/
public Color getColor()
{
return color;
}
/**
* Defines the main color for the bars.
*
* @param color the main color for the bars, never null.
*/
public void setColor(final Color color)
{
if (color == null)
{
throw new NullPointerException();
}
this.color = color;
}
/**
* Returns the color for the highest bars. This property is optional and the high-color can be null.
*
* @return the color for the higest bars, or null if high bars should not be marked specially.
*/
public Color getHighColor()
{
return highColor;
}
/**
* Defines the color for the highest bars. This property is optional and the high-color can be null.
*
* @param highColor the color for the higest bars, or null if high bars should not be marked specially.
*/
public void setHighColor(final Color highColor)
{
this.highColor = highColor;
}
/**
* Returns the color for the last bar. This property is optional and the last-bar-color can be null.
*
* @return the color for the last bar in the graph, or null if last bars should not be marked specially.
*/
public Color getLastColor()
{
return lastColor;
}
/**
* Defines the color for the last bar. This property is optional and the last-bar-color can be null.
*
* @param lastColor the color for the last bar in the graph, or null if last bars should not be marked specially.
*/
public void setLastColor(final Color lastColor)
{
this.lastColor = lastColor;
}
/**
* Returns the color for the background of the graph. This property can be null, in which case the bar
* will have a transparent background.
*
* @return color for the background or null, if the graph has a transparent background color.
*/
public Color getBackground()
{
return background;
}
/**
* Defines the color for the background of the graph. This property can be null, in which case the bar
* will have a transparent background.
*
* @param background the background or null, if the graph has a transparent background color.
*/
public void setBackground(final Color background)
{
this.background = background;
}
/**
* Returns the spacing between the bars.
*
* @return the spacing between the bars.
*/
public int getSpacing()
{
return spacing;
}
/**
* Defines the spacing between the bars.
*
* @param spacing the spacing between the bars.
*/
public void setSpacing(final int spacing)
{
this.spacing = spacing;
}
/**
* Draws the bar-graph into the given Graphics2D context in the given area. This method will not draw a graph
* if the data given is null or empty.
*
* @param g2 the graphics context on which the bargraph should be rendered.
* @param drawArea the area on which the bargraph should be drawn.
*/
public void draw(Graphics2D g2, Rectangle2D drawArea)
{
if (g2 == null)
{
throw new NullPointerException();
}
if (drawArea == null)
{
throw new NullPointerException();
}
final int height = (int) drawArea.getHeight();
if (height <= 0)
{
return;
}
Graphics2D g = (Graphics2D) g2.create();
g.translate(drawArea.getX(), drawArea.getY());
if (background != null)
{
g.setBackground(background);
g.clearRect(0, 0, (int) drawArea.getWidth(), height);
}
if (data == null || data.length == 0)
{
g.dispose();
return;
}
final float d = getDivisor(data, height);
final int a = computeAverage(data);
final int spacing1 = getSpacing();
final int w = ((int) drawArea.getWidth() - (spacing1 * data.length)) / data.length;
int x = 0;
final int y = 0;
final double vHeight = drawArea.getHeight();
final Rectangle2D.Double bar = new Rectangle2D.Double();
for (int index = 0; index < data.length; index++)
{
Number i = data[index];
if (i == null)
{
continue;
}
final int h = (int) (i.floatValue() / d);
final int intVal = i.intValue();
if (index == (data.length - 1) && lastColor != null)
{
g.setPaint(lastColor);
}
else if (intVal < a || (highColor == null))
{
g.setPaint(color);
}
else
{
g.setPaint(highColor);
}
bar.setRect(x, y + (vHeight - h), w, intVal / d);
g.fill(bar);
x += (w + spacing1);
}
g.dispose();
}
/**
* Computes the average for all numbers in the array.
*
* @param data the numbers for which the average should be computed.
* @return the average.
*/
private static int computeAverage(final Number[] data)
{
int total = 0;
int length = 0;
for (int index = 0; index < data.length; index++)
{
Number i = data[index];
if (i == null)
{
continue;
}
total += i.intValue();
length += 1;
}
return (total / length);
}
/**
* Computes the scale factor to scale the given numeric data into the target
* height.
*
* @param data
* the numeric data.
* @param height
* the target height of the graph.
* @return the scale factor.
*/
public static float getDivisor(final Number[] data, final int height) {
if (data == null) {
throw new NullPointerException("Data array must not be null.");
}
if (height < 1) {
throw new IndexOutOfBoundsException("Height must be greater or equal to 1");
}
float max = Float.MIN_VALUE;
float min = Float.MAX_VALUE;
for (int index = 0; index < data.length; index++) {
Number i = data[index];
if (i == null) {
continue;
}
final float numValue = i.floatValue();
if (numValue < min) {
min = numValue;
}
if (numValue > max) {
max = numValue;
}
}
if (max <= min) {
return 1.0f;
}
if (height == 1) {
return 0;
}
return (max - min) / (height - 1);
}
}
Chart based on Graph library
import java.awt.*;
import java.applet.*;
import java.net.URL;
import java.util.*;
import graph.*;
/*************************************************************************
**
** Applet example3
** Version 1.0 January 1996
**
**************************************************************************
** Copyright (C) 1996 Leigh Brookshaw
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**************************************************************************
**
** This applet demonstrates the interactive event handling of
** the G2Dint class
**
*************************************************************************/
public class example3 extends Applet {
LoadData dynamic;
G2Dint graph;
Label title;
DataSet data1;
Axis xaxis;
Axis yaxis;
public void init() {
int i;
int j;
/*
** Get the title of the plot and the data URL as parsed parameters
*/
String st = "TITLE";
String data = "elliptical.data";
/*
** Instantiate the Graph class and the LoadData class
*/
graph = new G2Dint();
dynamic = new LoadData();
graph.borderTop = 30;
graph.borderBottom = 10;
graph.borderRight = 40;
graph.setDataBackground(new Color(50,50,200));
graph.setGraphBackground(new Color(0,200,255));
/*
** Build the title and place it at the top of the graph
*/
graph.setFont(new Font("TimesRoman",Font.PLAIN,25));
title = new Label(st, Label.CENTER);
title.setFont(new Font("TimesRoman",Font.PLAIN,25));
setLayout( new BorderLayout() );
add("North", title);
add("Center", graph);
/*
** Start a new thread and load the data
*/
try {
data1 = dynamic.loadDataSet(this.getClass().getResource(data), graph);
} catch (Exception e) {
System.out.println("Failed to load data file!");
}
/*
** Specify the data line color
*/
data1.linecolor = new Color(255,255,0);
/*
** Instantiate the xaxis and attach the dataset.
*/
xaxis = graph.createXAxis();
xaxis.attachDataSet(data1);
xaxis.setTitleText("Wavelength_(angstroms)");
xaxis.setTitleColor(Color.magenta);
xaxis.setTitleFont(new Font("TimesRoman",Font.ITALIC,25));
xaxis.setLabelFont(new Font("Helvetica",Font.PLAIN,20));
/*
** Instantiate the yaxis and attach the dataset.
*/
yaxis = graph.createYAxis();
yaxis.attachDataSet(data1);
yaxis.setTitleText("Flux");
yaxis.setTitleColor(Color.magenta);
yaxis.setTitleFont(new Font("TimesRoman",Font.ITALIC,25));
yaxis.setLabelFont(new Font("Helvetica",Font.PLAIN,20));
}
public static void main(String[] a){
javax.swing.JFrame f = new javax.swing.JFrame();
Applet app = new example3();
app.init();
f.getContentPane().add (app);
f.pack();
f.setSize (new Dimension (500, 500));
f.setVisible(true);
}
}
Pie Chart
import java.awt.*;
import java.util.*;
import javax.swing.*;
import no.geosoft.cc.geometry.Geometry;
import no.geosoft.cc.graphics.*;
/**
* G demo program. Demonstrates:
*
* <ul>
* <li>A rudimentary pie chart class
* <li>Annotation techniques
* <li>Example geometry generation
* </ul>
*
* @author
== Scroll Chart ==
<!-- start source code -->
<source lang="java">
import java.awt.*;
import java.applet.*;
import java.net.URL;
import java.util.*;
import graph.*;
/*************************************************************************
**
** Applet example2a
** Version 1.0 August 1996
**
**************************************************************************
** Copyright (C) 1996 Leigh Brookshaw
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**************************************************************************
**
** This is a simple applet that creates a Scroll Chart using the
** Graph2D class library and double buffering
**
*************************************************************************/
public class example2a extends Applet implements Runnable {
Graph2D graph;
Label title;
DataSet data1 = new DataSet();
Axis yaxis_right;
Image osi = null;
Graphics osg = null;
int iwidth = 0;
int iheight = 0;
Thread runner = null;
Random random = new Random();
int count = 0;
/*
** In milliseconds how often do we want to add a new data point.
*/
int period = 500;
/*
** Maximum number of points to display before scrolling the data
*/
int maximum = 25;
URL markersURL;
/*
** Initialize the applet. The Parameters passed are the title of the plot
** the marker file to use and the update period in milliseconds
*/
public void init() {
int i;
int j;
/*
** Get the passed parameters
*/
String st = "TITLE";
String mfile = "marker.txt";
period = 10;
/*
** Create the Graph instance and modify the default behaviour
*/
graph = new Graph2D();
graph.zerocolor = new Color(0,255,0);
graph.borderTop = 50;
graph.borderBottom = 50;
graph.setDataBackground(Color.black);
/*
** Create the Title
*/
title = new Label(st, Label.CENTER);
title.setFont(new Font("TimesRoman",Font.PLAIN,25));
setLayout( new BorderLayout() );
add("North", title);
add("Center", graph);
/*
** Load a file containing Marker definitions
*/
try {
markersURL = this.getClass().getResource(mfile);
graph.setMarkers(new Markers(markersURL));
} catch(Exception e) {
System.out.println("Failed to create Marker URL!");
}
/*
** Modify the default Data behaviour
*/
data1.linecolor = new Color(255,0,0);
data1.marker = 1;
data1.markercolor = new Color(100,100,255);
/*
** Setup the Axis. Attach it to the Graph2D instance, and attach the data
** to it.
*/
yaxis_right = graph.createAxis(Axis.RIGHT);
yaxis_right.attachDataSet(data1);
yaxis_right.setLabelFont(new Font("Helvetica",Font.PLAIN,20));
graph.attachDataSet(data1);
}
public void start() {
if(runner == null) {
runner = new Thread(this);
runner.start();
}
}
public void stop() {
if(runner != null) {
runner.stop();
runner = null;
}
}
public void run() {
int i =0;
double data[] = new double[2];
Graphics g;
while(true) {
count++;
if(count >= maximum) data1.delete(0,0);
data[1] = (2.0*random.nextDouble()-1.0)*50.0;
data[0] = count;
try {
data1.append(data,1);
}
catch (Exception e) {
System.out.println("Error appending Data!");
}
data1.yaxis.maximum = 50.0;
data1.yaxis.minimum = -50.0;
g = graph.getGraphics();
if( osi == null || iwidth != graph.size().width
|| iheight != graph.size().height ) {
iwidth = graph.size().width;
iheight = graph.size().height;
osi = graph.createImage(iwidth,iheight);
osg = osi.getGraphics();
}
osg.setColor(this.getBackground());
osg.fillRect(0,0,iwidth,iheight);
osg.setColor(g.getColor());
osg.clipRect(0,0,iwidth,iheight);
graph.update(osg);
g.drawImage(osi,0,0,graph);
try { Thread.sleep(period); }
catch(Exception e) { }
}
}
public static void main(String[] a){
javax.swing.JFrame f = new javax.swing.JFrame();
Applet app = new example2();
app.init();
f.getContentPane().add (app);
f.pack();
f.setSize (new Dimension (500, 500));
f.setVisible(true);
}
}