org.lmn.fc.frameworks.starbase.plugins.observatory.ui.tabs.charts.GOESChartUIComponent.java Source code

Java tutorial

Introduction

Here is the source code for org.lmn.fc.frameworks.starbase.plugins.observatory.ui.tabs.charts.GOESChartUIComponent.java

Source

// Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
//           2010, 2011, 2012, 2013, 2014
// Laurence Newell
// starbase@ukraa.com
// radio.telescope@btinternet.com
//
// This file is part of Starbase.
//
// Starbase 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.
//
// Starbase 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 Starbase.  If not, see http://www.gnu.org/licenses.

package org.lmn.fc.frameworks.starbase.plugins.observatory.ui.tabs.charts;

import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.LogarithmicAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.lmn.fc.common.datatranslators.DatasetType;
import org.lmn.fc.frameworks.starbase.plugins.observatory.MetadataDictionary;
import org.lmn.fc.frameworks.starbase.plugins.observatory.ui.instruments.ObservatoryInstrumentDAOInterface;
import org.lmn.fc.frameworks.starbase.plugins.observatory.ui.instruments.ObservatoryInstrumentHelper;
import org.lmn.fc.frameworks.starbase.plugins.observatory.ui.instruments.ObservatoryInstrumentInterface;
import org.lmn.fc.frameworks.starbase.plugins.observatory.ui.instruments.common.MetadataHelper;
import org.lmn.fc.frameworks.starbase.plugins.observatory.ui.tabs.ChannelSelectorUIComponentInterface;
import org.lmn.fc.frameworks.starbase.plugins.observatory.ui.tabs.ChartUIComponentPlugin;
import org.lmn.fc.frameworks.starbase.plugins.observatory.ui.tabs.data.DataUpdateType;
import org.lmn.fc.model.tasks.TaskPlugin;
import org.lmn.fc.model.xmlbeans.metadata.Metadata;

import javax.swing.*;
import java.text.SimpleDateFormat;
import java.util.List;

/***************************************************************************************************
 * The GOESChartUIComponent.
 */

public final class GOESChartUIComponent extends ChartUIComponent implements ChartUIComponentPlugin {
    private static final int INDEX_FLUX = 0;
    private static final int INDEX_RATIO = 1;

    // The Channel Count is the sum of the Primary and Secondary Datasets
    private static final int DAO_CHANNEL_COUNT = 3;

    /***********************************************************************************************
     * Construct a GOESChartUIComponent.
     *
     * @param task
     * @param hostinstrument
     * @param name
     * @param metadatalist
     * @param resourcekey
     * @param updatetype
     * @param displaylimit
     */

    public GOESChartUIComponent(final TaskPlugin task, final ObservatoryInstrumentInterface hostinstrument,
            final String name, final List<Metadata> metadatalist, final String resourcekey,
            final DataUpdateType updatetype, final int displaylimit) {
        super(task, hostinstrument, name, resourcekey, updatetype, displaylimit, NON_REFRESHABLE, REFRESH_NONE);

        // Indicate the capabilities of the Chart
        setLinearMode(false);
        setLogarithmicMode(false);
        setCanAutorange(false);

        setMetadata(metadatalist, null, false, LOADER_PROPERTIES.isMetadataDebug());
    }

    /***********************************************************************************************
     * Get the optional JToolBar.
     * Default is NULL, override if needed.
     *
     * @return JToolBar
     */

    public JToolBar getToolBar() {
        return (ChartUIHelper.createDefaultToolbar(getHostInstrument(), this, getChartName(),
                getHostInstrument().getFontData(), getHostInstrument().getColourData(),
                DEFAULT_COLOUR_TAB_BACKGROUND, isDebug()));
    }

    /***********************************************************************************************
     * Customise the XYPlot of a new chart, e.g. for fixed range axes.
     *
     * @param datasettype
     * @param primarydataset
     * @param secondarydatasets
     * @param updatetype
     * @param displaylimit
     * @param channelselector
     * @param debug
     *
     * @return JFreeChart
     */

    public JFreeChart createCustomisedChart(final DatasetType datasettype, final XYDataset primarydataset,
            final List<XYDataset> secondarydatasets, final DataUpdateType updatetype, final int displaylimit,
            final ChannelSelectorUIComponentInterface channelselector, final boolean debug) {
        final JFreeChart jFreeChart;

        // A plain Chart is an XYPlot
        // with a DateAxis for the x-axis (index 0) and a NumberAxis for the y-axis (index 0).
        // The default renderer is an XYLineAndShapeRenderer
        jFreeChart = ChartHelper.createChart(primarydataset,
                ObservatoryInstrumentHelper.getCurrentObservatoryTimeZone(REGISTRY.getFramework(), getDAO(), debug),
                getMetadata(), getChannelCount(), hasTemperatureChannel(), updatetype, displaylimit,
                channelselector, debug);

        // Customise the Chart for GOES data
        // Channels 0 & 1 are Data on a LogarithmicAxis,
        // Channel 2 is Ratio on a NumberAxis
        if (jFreeChart != null) {
            final String strLabelFlux;
            final String strLabelRatio;
            final XYPlot plot;
            final LogarithmicAxis axisFlux;
            final DateAxis axisDate;

            // The set of Metadata available should include the Instrument
            // and any items from the current observation
            strLabelFlux = MetadataHelper.getMetadataValueByKey(getMetadata(),
                    MetadataDictionary.KEY_OBSERVATION_AXIS_LABEL_Y.getKey()
                            + MetadataDictionary.SUFFIX_SERIES_ZERO);
            strLabelRatio = MetadataHelper.getMetadataValueByKey(getMetadata(),
                    MetadataDictionary.KEY_OBSERVATION_AXIS_LABEL_Y.getKey()
                            + MetadataDictionary.SUFFIX_SERIES_ONE);

            plot = jFreeChart.getXYPlot();

            //----------------------------------------------------------------------------------
            // Replace the RangeAxis at index 0 NumberAxis with a LogarithmicAxis
            // The RangeAxis at index 0 is the LogarithmicAxis, to be used by Channels 0 & 1 (Data)

            axisFlux = new LogarithmicAxis(strLabelFlux);
            axisFlux.setRange(1.0E-09, 1.0E-02);
            axisFlux.setAllowNegativesFlag(false);
            axisFlux.setLog10TickLabelsFlag(true);
            plot.setRangeAxis(0, axisFlux);

            // Map the dataset to the axis
            plot.setDataset(INDEX_FLUX, primarydataset);
            plot.mapDatasetToRangeAxis(0, 0);
            plot.setRangeAxisLocation(0, AxisLocation.BOTTOM_OR_LEFT);

            //----------------------------------------------------------------------------------
            // Customise the DomainAxis at index 0

            axisDate = (DateAxis) plot.getDomainAxis();

            // Showing the YYYY-MM-DD makes a very long label...
            // ToDo Consider ThreadLocal
            axisDate.setDateFormatOverride(new SimpleDateFormat("HH:mm:ss"));

            // Now customise the Flux renderer to improve legend visibility
            // Use the same colours as on http://www.swpc.noaa.gov/
            // blue=0.5 - 4.0A red=1.0 - 8.0A
            ChartUIHelper.customisePlotRenderer(plot, INDEX_FLUX);

            //----------------------------------------------------------------------------------
            // Set the RangeAxis at index 1 to a new NumberAxis, to be used by Channel 2 (Ratio)

            if ((secondarydatasets != null) && (secondarydatasets.size() == 1)) {
                final NumberAxis axisRatio;
                final XYLineAndShapeRenderer rendererRatio;

                axisRatio = new NumberAxis(strLabelRatio);
                plot.setRangeAxis(1, axisRatio);

                // The RangeAxis at index 1 is the NumberAxis, to be used by Channel 2
                plot.setDataset(INDEX_RATIO, secondarydatasets.get(0));
                plot.mapDatasetToRangeAxis(1, 1);
                plot.setRangeAxisLocation(1, AxisLocation.TOP_OR_RIGHT);

                rendererRatio = new XYLineAndShapeRenderer();
                rendererRatio.setLinesVisible(true);
                rendererRatio.setShapesVisible(false);
                // Channel 2 is Ratio
                rendererRatio.setSeriesPaint(0, ChartUIHelper.getStandardColour(2).getColor());
                rendererRatio.setLegendLine(SHAPE_LEGEND);

                plot.setRenderer(INDEX_RATIO, rendererRatio);
                //ChartHelper.customisePlotRenderer(plot, INDEX_RATIO);
            }
        }

        return (jFreeChart);
    }

    /***********************************************************************************************
     * Update the existing Chart referenced by the DAO, by applying the specified datasets,
     * using all existing channel selections and range selections.
     *
     * @param dao
     * @param datasettype
     * @param primarydataset
     * @param secondarydatasets
     * @param displaylimit
     * @param domainstartpoint
     * @param domainendpoint
     * @param channelselector
     * @param debug
     */

    public void updateChartForSelection(final ObservatoryInstrumentDAOInterface dao, final DatasetType datasettype,
            final XYDataset primarydataset, final List<XYDataset> secondarydatasets, final int displaylimit,
            final int domainstartpoint, final int domainendpoint,
            final ChannelSelectorUIComponentInterface channelselector, final boolean debug) {
        LOGGER.warn("GOESChartUIComponent.updateChartForSelection() ToDo implement!");
    }

    //                if ((getHostInstrument() instanceof ObservatoryMonitor)
    //                    && (((ObservatoryMonitor)getHostInstrument()).isMemoryMonitorRunning()))

    //                if ((getPrimaryXYDataset() != null)
    //                    && (getSecondaryXYDatasets() != null)
    //                    && (getSecondaryXYDatasets().size() == 1))
    //                    {
    //                    // We have some data, but do we have a Chart?
    //                    if ((getChart() == null)
    //                        || (dao.isRawDataChanged()))
    //                        {
    //                        // We need to make a new Chart
    //                        }
    //                    else
    //                        {
    //                        // We already have a chart (on a panel),
    //                        // we just need to update the data it displays...
    //                        if ((getChart().getXYPlot() != null)
    //                            && (getPrimaryXYDataset() != null)
    //                            && (getPrimaryXYDataset().getSeriesCount() == 2)
    //                            && (getSecondaryXYDatasets() != null)
    //                            && (getSecondaryXYDatasets().size() == 1))

    /***********************************************************************************************
     * Set the XYDatasets for the Data and Ratio to be shown on the GOESChartUIComponent.
     * These data are produced by the DAO, and contain two channels plus ratio, i.e. Count = 3.
     *
     * @param dataset
     */

    public void setDatasetsAndMetadata(final XYDataset dataset) {
        if ((dataset != null) && (dataset instanceof TimeSeriesCollection)
                && (dataset.getSeriesCount() == DAO_CHANNEL_COUNT)) {
            final TimeSeriesCollection seriesData;

            // Get the DAO's Metadata for use by this Chart
            if ((getHostInstrument() != null) && (getHostInstrument().getDAO() != null)) {
                // The Metadata came from the Instrument DAO, so don't re-apply
                setMetadata(MetadataHelper.collectMetadataForChartFromDAO(getHostInstrument().getDAO()),
                        getHostInstrument().getDAO(), false, LOADER_PROPERTIES.isMetadataDebug());
            } else {
                setMetadata(null, getHostInstrument().getDAO(), false, LOADER_PROPERTIES.isMetadataDebug());
            }

            // Set the ChannelCount and Temperature flag first, because setPrimaryXYDataset() uses them
            setChannelCount(DAO_CHANNEL_COUNT);
            setTemperatureChannel(false);

            seriesData = new TimeSeriesCollection(((TimeSeriesCollection) dataset).getSeries(0));
            seriesData.addSeries(((TimeSeriesCollection) dataset).getSeries(1));

            // This sets the PrimaryDatasetType and RawDataChannelCount
            setPrimaryXYDataset(getHostInstrument().getDAO(), seriesData);

            // Do the secondary Ratio dataset only in this class
            getSecondaryXYDatasets().clear();
            getSecondaryXYDatasets().add(new TimeSeriesCollection(((TimeSeriesCollection) dataset).getSeries(2)));
        } else {
            // Set the ChannelCount and Temperature flag first, because setPrimaryXYDataset() uses them
            setChannelCount(0);
            setTemperatureChannel(false);
            setPrimaryXYDataset(getHostInstrument().getDAO(), null);
            getSecondaryXYDatasets().clear();

            setMetadata(null, getHostInstrument().getDAO(), false, LOADER_PROPERTIES.isMetadataDebug());
        }
    }
}