Java/Advanced Graphics/Chart

Материал из Java эксперт
Перейти к: навигация, поиск

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);
      }

}