gov.llnl.lc.infiniband.opensm.plugin.gui.chart.AdvancedXY_PlotPanel.java Source code

Java tutorial

Introduction

Here is the source code for gov.llnl.lc.infiniband.opensm.plugin.gui.chart.AdvancedXY_PlotPanel.java

Source

/************************************************************
 * Copyright (c) 2015, Lawrence Livermore National Security, LLC.
 * Produced at the Lawrence Livermore National Laboratory.
 * Written by Timothy Meier, meier3@llnl.gov, All rights reserved.
 * LLNL-CODE-673346
 *
 * This file is part of the OpenSM Monitoring Service (OMS) package.
 * 
 * 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) version 2.1 dated February 1999.
 * 
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * OUR NOTICE AND TERMS AND CONDITIONS OF THE GNU GENERAL PUBLIC LICENSE
 *
 * Our Preamble Notice
 *
 * A. This notice is required to be provided under our contract with the U.S.
 * Department of Energy (DOE). This work was produced at the Lawrence Livermore
 * National Laboratory under Contract No.  DE-AC52-07NA27344 with the DOE.
 *
 * B. Neither the United States Government nor Lawrence Livermore National
 * Security, LLC nor any of their employees, makes any warranty, express or
 * implied, or assumes any liability or responsibility for the accuracy,
 * completeness, or usefulness of any information, apparatus, product, or
 * process disclosed, or represents that its use would not infringe privately-
 * owned rights.
 *
 * C. Also, reference herein to any specific commercial products, process, or
 * services by trade name, trademark, manufacturer or otherwise does not
 * necessarily constitute or imply its endorsement, recommendation, or favoring
 * by the United States Government or Lawrence Livermore National Security,
 * LLC. The views and opinions of authors expressed herein do not necessarily
 * state or reflect those of the United States Government or Lawrence Livermore
 * National Security, LLC, and shall not be used for advertising or product
 * endorsement purposes.
 *
 *        file: AdvancedXY_PlotPanel.java
 *
 *  Created on: Aug 6, 2015
 *      Author: meier3
 ********************************************************************/
package gov.llnl.lc.infiniband.opensm.plugin.gui.chart;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.text.SimpleDateFormat;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTable;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.TableCellRenderer;

import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.event.ChartProgressEvent;
import org.jfree.chart.event.ChartProgressListener;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.Range;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.DateCellRenderer;
import org.jfree.ui.NumberCellRenderer;

public class AdvancedXY_PlotPanel extends XY_PlotPanel implements ChangeListener, ChartProgressListener {
    // this is a panel that contains a SimpleXY_PlotPanel, a table, a slider, border layout

    static final protected int MAX_DATASETS = 4;
    static final protected int MAX_DS_SIZE = 102;

    private int NumDataSets = MAX_DATASETS / 2;

    private XY_PlotPanel plotPanel;
    private XY_PlotTableModel model;

    private JSlider slider;

    private int CrossHairDomainIndex;

    /************************************************************
     * Method Name:
     *  getCrossHairDomainIndex
     **/
    /**
     * Returns the value of crossHairDomainIndex
     *
     * @return the crossHairDomainIndex
     *
     ***********************************************************/

    protected int getCrossHairDomainIndex() {
        return CrossHairDomainIndex;
    }

    /************************************************************
     * Method Name:
     *  setCrossHairDomainIndex
     **/
    /**
     * Sets the value of crossHairDomainIndex
     *
     * @param crossHairDomainIndex the crossHairDomainIndex to set
     *
     ***********************************************************/
    protected void setCrossHairDomainIndex() {
        int value = this.slider.getValue();

        if (this.chartPanel != null) {
            JFreeChart c = this.getChart();
            this.getChart();
            if (c != null) {
                XYPlot plot = (XYPlot) c.getPlot();
                XYDataset dataset = plot.getDataset();
                int itemCount = dataset.getItemCount(0);
                double ndexD = (double) itemCount * ((double) value / 100);
                int ndex = (int) ndexD;

                // the index goes from 0 to (itemCount -1)
                this.CrossHairDomainIndex = ndex >= itemCount ? itemCount - 1 : ndex;
            }
        }
    }

    /************************************************************
     * Method Name:
     *  SimpleXY_PlotPanel
    **/
    /**
     * Describe the constructor here
     *
     * @see     describe related java objects
     *
     ***********************************************************/
    public AdvancedXY_PlotPanel() {
        super();
        // TODO Auto-generated constructor stub
    }

    public AdvancedXY_PlotPanel(XY_PlotPanel pPanel) {
        this();
        this.plotPanel = pPanel;
        this.chartPanel = pPanel.getChartPanel();
        if (pPanel instanceof SimpleXY_PlotPanel) {
            this.setTitle(((SimpleXY_PlotPanel) pPanel).getTitle());
            type = ((SimpleXY_PlotPanel) pPanel).getType();
        }
        initChart(pPanel);
    }

    public AdvancedXY_PlotPanel(XY_PlotType type, Object userObject, Object userElement) {
        this(new SimpleXY_PlotPanel(type, userObject, userElement));
    }

    //  private void initChart(IB_Vertex vertex, OSM_Port port, PortCounterName portCounter, boolean includeExtra)
    private void initChart(XY_PlotPanel pPanel) {
        this.plotPanel = pPanel;
        this.chartPanel = pPanel.getChartPanel();
        if (pPanel instanceof SimpleXY_PlotPanel) {
            this.setTitle(((SimpleXY_PlotPanel) pPanel).getTitle());
        }

        JFreeChart chart = chartPanel.getChart();
        XYPlot plot = (XYPlot) chart.getPlot();

        // how many data sets will there be (may not exist yet, cause swing worker may still be constructing them)
        int numRows = 2; // enough for counts, and delta counts
        if ((XY_PlotType.ADV_PORT_UTIL_PLUS.equals(getType())))
            numRows = 4;
        boolean includeExtra = numRows > MAX_DATASETS / 2 ? true : false;

        int rowSize = includeExtra ? MAX_DS_SIZE : MAX_DS_SIZE / 2 + 19; // extra for padding
        NumDataSets = numRows;

        // build the table model from the data sets, then build the table and slider

        // see "chartProgress()" method
        chart.addProgressListener(this);

        this.chartPanel.setPreferredSize(new java.awt.Dimension(750, 300));
        this.chartPanel.setDomainZoomable(true);
        this.chartPanel.setRangeZoomable(true);
        Border border = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4),
                BorderFactory.createEtchedBorder());
        this.chartPanel.setBorder(border);
        add(this.chartPanel);

        JPanel dashboard = new JPanel(new BorderLayout());
        dashboard.setPreferredSize(new Dimension(400, rowSize));
        dashboard.setBorder(BorderFactory.createEmptyBorder(0, 4, 4, 4));

        this.model = new XY_PlotTableModel(numRows);

        // initialize the model, and table, here
        //    this.model.setValueAt("name", 0, 1);
        this.model.setValueAt(new Double("0.00"), 0, 1);
        this.model.setValueAt(new Double("0.00"), 0, 2);
        //    this.model.setValueAt("units", 0, 3);
        JTable table = new JTable(this.model);

        // the columns are name, time, value, units.  both name and units are strings
        // so need special renderers for time and value

        TableCellRenderer renderer1 = new DateCellRenderer(new SimpleDateFormat("HH:mm:ss"));
        TableCellRenderer renderer2 = new NumberCellRenderer();
        table.getColumnModel().getColumn(1).setCellRenderer(renderer1);
        table.getColumnModel().getColumn(2).setCellRenderer(renderer2);
        JScrollPane scroller = new JScrollPane(table);
        dashboard.add(scroller);

        this.slider = new JSlider(0, 100, 10);
        this.slider.addChangeListener(this);
        dashboard.add(this.slider, BorderLayout.SOUTH);
        add(dashboard, BorderLayout.SOUTH);

        //     XYPlot plot = (XYPlot) chart.getPlot();

        plot.setDomainCrosshairLockedOnData(true);
        plot.setRangeCrosshairVisible(false);
        plot.setDomainCrosshairVisible(true);
    }

    @Override
    public void chartProgress(ChartProgressEvent event) {
        if (event.getType() != ChartProgressEvent.DRAWING_FINISHED) {
            return;
        }

        // update the table model

        if (this.chartPanel != null) {
            JFreeChart c = this.getChart();
            if (c != null) {
                XYPlot plot = (XYPlot) c.getPlot();

                int ndex = this.getCrossHairDomainIndex();

                // update the table from the value at the crosshair

                for (int pnum = 0; pnum < NumDataSets; pnum++) {
                    XYDataset dataset = plot.getDataset(pnum);
                    String seriesName = "Unknown";
                    if ((dataset != null) && (dataset.getSeriesKey(0) != null)) {
                        int ds_size = dataset.getItemCount(0);
                        if (dataset.getSeriesKey(0) instanceof String)
                            seriesName = (String) dataset.getSeriesKey(0);

                        // the name
                        this.model.setValueAt(seriesName, pnum, 0);

                        // the deltas are one smaller than the counters, so make sure the
                        // crosshair index is valid
                        if (ndex < ds_size) {
                            // the time
                            this.model.setValueAt(dataset.getXValue(0, ndex), pnum, 1);

                            // the value
                            this.model.setValueAt(dataset.getYValue(0, ndex), pnum, 2);
                        }

                        // the units (key off the series name)
                        PortCounterAxisLabel label = PortCounterAxisLabel.getByName(seriesName);
                        if (label != null)
                            this.model.setValueAt(label.getUnits(), pnum, 3);
                        else
                            this.model.setValueAt(PortCounterAxisLabel.DELTA.getUnits(), pnum, 3);
                    }
                }
            } else
                System.err.println("Its NULL, Jim!");
        }
    }

    @Override
    public void stateChanged(ChangeEvent e) {
        int value = this.slider.getValue();
        XYPlot plot = (XYPlot) this.getChart().getPlot();

        ValueAxis domainAxis = plot.getDomainAxis();
        Range range = domainAxis.getRange();
        double c = domainAxis.getLowerBound() + (value / 100.0) * range.getLength();

        // displays the vertical crosshair in the desired position
        plot.setDomainCrosshairValue(c);

        // the cross hair is keyed to the horizontal slider - for the time domain axis
        setCrossHairDomainIndex();
    }

}