be.ac.ua.comp.scarletnebula.gui.Graph.java Source code

Java tutorial

Introduction

Here is the source code for be.ac.ua.comp.scarletnebula.gui.Graph.java

Source

/*
 * Copyright (C) 2011  Ives van der Flaas
 *
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 */

package be.ac.ua.comp.scarletnebula.gui;

import java.awt.Color;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.SwingUtilities;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Millisecond;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;

import be.ac.ua.comp.scarletnebula.core.Datapoint;
import be.ac.ua.comp.scarletnebula.core.Server;
import be.ac.ua.comp.scarletnebula.core.ServerStatisticsManager;
import be.ac.ua.comp.scarletnebula.core.TimedDatapoint;

/**
 * An abstract Graph that displays streaming data.
 * 
 * @author ives
 * 
 */
public abstract class Graph implements NewDatapointListener {
    protected Map<String, TimeSeries> datastreams = new HashMap<String, TimeSeries>();
    protected final TimeSeriesCollection dataset = new TimeSeriesCollection();
    protected final XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false);
    final long maximumAge;
    private int maxSeriesID = 0;
    private final Collection<Server> serversToRefresh = new ArrayList<Server>();

    /**
     * Constructor.
     * 
     * @param maximumAge
     *            The age after which data is no longer displayed in the graph
     */
    public Graph(final long maximumAge) {
        this.maximumAge = maximumAge;

    }

    /**
     * Register a relative datastream coming from server with name streamname
     * and formal title (a displayable name) streamtitle. This stream will be
     * displayed with Color color.
     * 
     * If this datastream was already running, historical data will be taken
     * from the stream and be displayed in the graph.
     * 
     * @param server
     *            Server that generates this relative datastream
     * @param streamname
     *            The stream's short ID name (e.g. MEM)
     * @param color
     *            The color this stream will be displayed in
     */
    public final void registerRelativeDatastream(final Server server, final String streamname, final Color color) {
        final ServerStatisticsManager manager = server.getServerStatistics();
        manager.addNewDatapointListener(this, streamname);

        final TimeSeries series = new TimeSeries(streamname);
        series.setMaximumItemAge(maximumAge);
        datastreams.put(streamname, series);
        dataset.addSeries(series);

        renderer.setSeriesPaint(maxSeriesID++, color);

        addListOfDatapoints(manager.getHistoricalDatapoints(streamname));
    }

    /**
     * Returns the JFreeChart ChartPanel that will be updated as this object is
     * updated.
     * 
     * @return The ChartPanel containing the Graph
     */
    abstract ChartPanel getChartPanel();

    /**
     * Registers a new datapoint for the stream named streamname, which was
     * measured at value, at the current time.
     * 
     * @param datapoint
     *            The datapoint to add (now).
     */
    @Override
    public void newDataPoint(final Datapoint datapoint) {
        newDataPoint(new Millisecond(), datapoint);
    }

    /**
     * Adds a new server to the list of servers to be refreshed when a new
     * datapoint is received.
     * 
     * @param server
     *            Server that's refreshed.
     */
    public void addServerToRefresh(final Server server) {
        serversToRefresh.add(server);
    }

    /**
     * Adds a list of datapoints.
     * 
     * @param datapoints
     *            The timed datapoints to add.
     */
    public void addListOfDatapoints(final List<TimedDatapoint> datapoints) {
        for (final TimedDatapoint datapoint : datapoints) {
            newDataPoint(new Millisecond(new Date(datapoint.getTimeMs())), datapoint);
        }
    }

    /**
     * Registers a new datapoint for the stream named streamname, which was
     * measured at value, at time time.
     * 
     * @param datapoint
     *            The datapoint to add.
     * @param time
     *            The time at which this measurement was made
     */
    @Override
    public void newDataPoint(final RegularTimePeriod time, final Datapoint datapoint) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                final String dataStreamName = datapoint.getDatastream();
                if (datastreams.containsKey(dataStreamName)) {
                    datastreams.get(dataStreamName).addOrUpdate(time, datapoint.getValue());
                }

                for (final Server server : serversToRefresh) {
                    server.serverChanged();
                }
            }
        });
    }
}