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

Java tutorial

Introduction

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

Source

/*
  Copyright 2014 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 org.jfree.chart.ChartFactory;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.xy.XYBubbleRenderer;
import org.jfree.data.xy.DefaultXYZDataset;

// From JFreeChart
// from iText (www.lowagie.com/iText/)

/*  // looks like we'll have to move to these soon
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
*/

public class BubbleChartGenerator extends XYChartGenerator {
    public void removeSeries(int index) {
        super.removeSeries(index);
        update();
    }

    public void moveSeries(int index, boolean up) {
        super.moveSeries(index, up);
        update();
    }

    protected void buildChart() {
        DefaultXYZDataset dataset = new DefaultXYZDataset();
        chart = ChartFactory.createBubbleChart("Untitled Chart", "Untitled X Axis", "Untitled Y Axis", dataset,
                PlotOrientation.VERTICAL, false, true, false);
        chart.setAntiAlias(true);
        chartPanel = buildChartPanel(chart);
        setChartPanel(chartPanel);

        // most irritating: you can't change the scale type once you've
        // constructed the renderer.  :-(
        chart.getXYPlot().setRenderer(new XYBubbleRenderer(XYBubbleRenderer.SCALE_ON_DOMAIN_AXIS));

        // this must come last because the chart must exist for us to set its dataset
        setSeriesDataset(dataset);
    }

    protected void update() {
        // we'll rebuild the plot from scratch

        SeriesAttributes[] sa = getSeriesAttributes();
        //XYPlot xyplot = (XYPlot)(chart.getPlot());
        DefaultXYZDataset dataset = new DefaultXYZDataset();

        for (int i = 0; i < sa.length; i++) {
            BubbleChartSeriesAttributes attributes = (BubbleChartSeriesAttributes) (sa[i]);
            double scale = attributes.getScale();

            // copy over values, and square-root the z-value.
            // A bug in JFreeChart means that z-values are not shown by
            // area but rather by (ugh) diameter.
            // Also we'll take advantage of this situation to allow
            // for user-defined scaling of the bubbles on a per-series basis.

            double[][] values = attributes.getValues();
            double[][] v2 = new double[values.length][values[0].length];
            for (int k = 0; k < v2.length; k++) {
                for (int j = 0; j < v2[k].length; j++) {
                    v2[k][j] = values[k][j];
                }
            }
            for (int j = 0; j < v2[2].length; j++) {
                v2[2][j] = Math.sqrt(scale * v2[2][j]);
            }

            dataset.addSeries(new UniqueString(attributes.getSeriesName()), v2);
        }

        setSeriesDataset(dataset);
    }

    public SeriesAttributes addSeries(double[][] values, String name,
            final org.jfree.data.general.SeriesChangeListener stopper) {
        DefaultXYZDataset dataset = (DefaultXYZDataset) (getSeriesDataset());
        int i = dataset.getSeriesCount();
        dataset.addSeries(new UniqueString(name), values);

        // need to have added the dataset BEFORE calling this since it'll try to change the name of the series
        BubbleChartSeriesAttributes csa = new BubbleChartSeriesAttributes(this, name, i, values, stopper);
        seriesAttributes.add(csa, name);

        revalidate();
        update();

        // won't update properly unless I force it here by letting all the existing scheduled events to go through.  Dumb design.  :-(
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                update();
            }
        });

        return csa;
    }

    public void updateSeries(int index, double[][] vals) {
        if (index < 0) // this happens when we're a dead chart but the inspector doesn't know
        {
            return;
        }

        if (index >= getNumSeriesAttributes()) // this can happen when we close a window if we use the Histogram in a display
        {
            return;
        }

        BubbleChartSeriesAttributes series = (BubbleChartSeriesAttributes) (getSeriesAttribute(index));
        series.setValues(vals);
    }
}