edu.gmu.cs.sim.util.media.chart.ScatterPlotSeriesAttributes.java Source code

Java tutorial

Introduction

Here is the source code for edu.gmu.cs.sim.util.media.chart.ScatterPlotSeriesAttributes.java

Source

/*
  Copyright 2006 by Sean Luke and George Mason University
  Licensed under the Academic Free License version 3.0
  See the file "LICENSE" for more information
*/

package edu.gmu.cs.sim.util.media.chart;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.util.Arrays;

import edu.gmu.cs.sim.util.gui.ColorWell;
import edu.gmu.cs.sim.util.gui.NumberTextField;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.general.SeriesChangeListener;

// From JFreeChart

public class ScatterPlotSeriesAttributes extends SeriesAttributes {
    static Shape[] buildShapes() {
        Shape[] s = new Shape[7];
        GeneralPath g = null;

        // Circle
        s[0] = new Ellipse2D.Double(-3, -3, 6, 6);

        // Rectangle
        Rectangle2D.Double r = new Rectangle2D.Double(-3, -3, 6, 6);
        s[1] = r;

        // Diamond
        s[2] = AffineTransform.getRotateInstance(Math.PI / 4.0).createTransformedShape(r);

        // Cross +
        g = new GeneralPath();
        g.moveTo(-0.5f, -3);
        g.lineTo(-0.5f, -0.5f);
        g.lineTo(-3, -0.5f);
        g.lineTo(-3, 0.5f);
        g.lineTo(-0.5f, 0.5f);
        g.lineTo(-0.5f, 3);
        g.lineTo(0.5f, 3);
        g.lineTo(0.5f, 0.5f);
        g.lineTo(3, 0.5f);
        g.lineTo(3, -0.5f);
        g.lineTo(0.5f, -0.5f);
        g.lineTo(0.5f, -3);
        g.closePath();
        s[3] = g;

        // X 
        s[4] = g.createTransformedShape(AffineTransform.getRotateInstance(Math.PI / 4.0));

        // Up Triangle
        g = new GeneralPath();
        g.moveTo(0f, -3);
        g.lineTo(-3, 3);
        g.lineTo(3, 3);
        g.closePath();
        s[5] = g;

        // Down Triangle
        s[6] = g.createTransformedShape(AffineTransform.getRotateInstance(Math.PI));

        return s;
    }

    final static Shape[] shapes = buildShapes();
    final static String[] shapeNames = new String[] { "Circle", "Square", "Diamond", "Cross", "X", "Up Triangle",
            "Down Triangle" };

    double[][] values;

    public double[][] getValues() {
        return values;
    }

    public void setValues(double[][] vals) {
        if (vals != null) {
            vals = (double[][]) (vals.clone());
            for (int i = 0; i < vals.length; i++) {
                vals[i] = (double[]) (vals[i].clone());
            }
        }
        values = vals;
    }

    Color color;
    ColorWell colorWell;
    double opacity;
    NumberTextField opacityField;

    public void setSymbolOpacity(double value) {
        opacityField.setValue(opacityField.newValue(value));
    }

    public double getSymbolOpacity() {
        return opacityField.getValue();
    }

    public void setSymbolColor(Color value) {
        colorWell.setColor(color = value);
    }

    public Color getSymbolColor() {
        return color;
    }

    int shapeNum = 0;
    Shape shape = shapes[shapeNum];
    JComboBox shapeList;

    public void setShapeNum(int value) {
        if (value >= 0 && value < shapes.length) {
            shapeList.setSelectedIndex(value);
            shapeNum = value;
            shape = shapes[shapeNum];
        }
    }

    public int getShapeNum() {
        return shapeNum;
    }

    public Shape getShape() {
        return shape;
    }

    /** Produces a ScatterPlotSeriesAttributes object with the given generator, series name, series index,
     and desire to display margin options. */
    public ScatterPlotSeriesAttributes(ChartGenerator generator, String name, int index, double[][] values,
            SeriesChangeListener stoppable) {
        super(generator, name, index, stoppable);

        setValues(values);
        super.setSeriesName(name); // just set the name, don't update.  Bypasses standard method below.

        // increment shape counter
        ((ScatterPlotGenerator) generator).shapeCounter++;
        if (((ScatterPlotGenerator) generator).shapeCounter >= shapes.length) {
            ((ScatterPlotGenerator) generator).shapeCounter = 0;
        }

        // set the shape
        shapeNum = ((ScatterPlotGenerator) generator).shapeCounter;
        shape = shapes[shapeNum];
        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) (((XYPlot) getPlot()).getRenderer());
        renderer.setSeriesShape(getSeriesIndex(), shape);
        renderer.setAutoPopulateSeriesShape(false);
    }

    public void setSeriesName(String val) {
        super.setSeriesName(val);
        ((ScatterPlotGenerator) generator).update();
    }

    public void rebuildGraphicsDefinitions() {
        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) (((XYPlot) getPlot()).getRenderer());
        renderer.setSeriesPaint(getSeriesIndex(), reviseColor(color, opacity));
        // shape may be null at this point, that's fine
        renderer.setSeriesShape(getSeriesIndex(), shape);
        renderer.setAutoPopulateSeriesShape(false);
        repaint();
    }

    public void buildAttributes() {
        // The following three variables aren't defined until AFTER construction if
        // you just define them above.  So we define them below here instead.
        opacity = 1.0;

        // NOTE:
        // Paint paint = renderer.getSeriesPaint(getSeriesIndex());        
        // In JFreeChart 1.0.6 getSeriesPaint returns null!!!
        // You need lookupSeriesPaint(), but that's not backward compatible.
        // The only thing consistent in all versions is getItemPaint 
        // (which looks like a gross miss-use, but gets the job done)

        color = (Color) ((((XYPlot) getPlot()).getRenderer()).getItemPaint(getSeriesIndex(), -1));

        colorWell = new ColorWell(color) {
            public Color changeColor(Color c) {
                color = c;
                rebuildGraphicsDefinitions();
                return c;
            }
        };

        addLabelled("Color", colorWell);

        opacityField = new NumberTextField("Opacity ", opacity, 1.0, 0.125) {
            public double newValue(double newValue) {
                if (newValue < 0.0 || newValue > 1.0) {
                    newValue = currentValue;
                }
                opacity = (float) newValue;
                rebuildGraphicsDefinitions();
                return newValue;
            }
        };
        addLabelled("", opacityField);

        shapeList = new JComboBox();
        shapeList.setEditable(false);
        shapeList.setModel(new DefaultComboBoxModel(new java.util.Vector(Arrays.asList(shapeNames))));
        shapeList.setSelectedIndex(shapeNum);
        shapeList.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                shapeNum = shapeList.getSelectedIndex();
                shape = shapes[shapeNum];
                rebuildGraphicsDefinitions();
            }
        });
        addLabelled("Shape", shapeList);
    }
}