Package jsynoptic.plugins.async

Source Code of jsynoptic.plugins.async.TimePlot

/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info:  http://jsynoptic.sourceforge.net/index.html
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2004, by :
*     Corporate:
*         EADS Astrium SAS
*         EADS CRC
*     Individual:
*         Claude Cazenave
*
* $Id: TimePlot.java,v 1.34 2008/11/27 10:53:48 ogor Exp $
*
* Changes
* -------
* 11 jan. 2005 : Initial public release (CC);
*
*/
package jsynoptic.plugins.async;

import java.awt.Rectangle;
import java.util.LinkedHashMap;
import java.util.Vector;

import javax.swing.undo.CompoundEdit;

import jsynoptic.base.DataSourceConsumer;
import jsynoptic.plugins.async.ui.TimePlotPropertiesPanel;
import jsynoptic.ui.JSynoptic;
import jsynoptic.ui.LongAction;
import simtools.data.DataException;
import simtools.data.DataInfo;
import simtools.data.DataSource;
import simtools.data.async.StreamingTSDataSource;
import simtools.data.async.TimeStampedDataSource;
import simtools.diagram.DiagramSelection;
import simtools.shapes.CurveShape;
import simtools.ui.JPropertiesPanel;
import simtools.ui.MenuResourceBundle;
import simtools.ui.ResourceFinder;

/**
* A plot dedicated to time stamped data source
* The X axis (primary and secondary) display the time source
* values of TimeStampedDataSource. Assuming the time values
* are based on the same time zone, the data sources do not need
* to belong to the same collection (they are all asynchronous).
*
* @see TimeStampedDataSource
*
* @author Claude Cazenave
*
*/
public class TimePlot extends jsynoptic.builtin.TimePlot implements DataSourceConsumer {

    public static MenuResourceBundle addedResources = ResourceFinder.getMenu(TimePlot.class);

    static final long serialVersionUID = 4978966488916450849L;

    /**
     * @deprecated see pyformat
     */
    //protected ChoiceFormat y1format;

    /**
     * @deprecated see syformat
     */
    //protected ChoiceFormat y2format;

    /**
     * diferences between time and time2
     */
    protected double time2Offset = 0 ;

    /**
     * boolean to enabled the diplay of the secondary axis
     */
    protected boolean displaySecondaryAxis = false;

    /**
     * @param ox
     * @param oy
     * @param width
     * @param height
     */
    public TimePlot(int ox, int oy, int width, int height) {
        super(ox, oy, width, height);
    }

    protected CurveShape doAddYAction(Object[] obar){
        TimeStampedDataSource ds = (TimeStampedDataSource)obar[0];
        boolean primary = ((Boolean)obar[1]).booleanValue();
        boolean usePrimaryX = ((Boolean)obar[2]).booleanValue();

        Rectangle bounds = getBounds();
        CurveShape cs;

        if (usePrimaryX) {

            cs = createCurveShape(ds.getTime(), ds);
            if (isPrimaryBounded) cs.setSlice(primaryStartIndex, primaryEndIndex);
        } else {
            cs = createCurveShape(ds.getTime(), ds);
            if (isSecondaryBounded) cs.setSlice(secondaryStartIndex, secondaryEndIndex);
        }

        String label = DEFAULT_DISPLAY_DATA_SOURCE_ID? DataInfo.getAliasOrIdwithUnit(ds) : DataInfo.getAliasOrLabelwithUnit(ds);
        if (primary) {
            if (primaryCurves==null) primaryCurves = new Vector();
            primaryCurves.add(cs);
            insertCurve(cs, !usePrimaryX, false);
       
        } else {
            setSecondaryAxis(false, true);
            if (secondaryCurves==null) secondaryCurves = new Vector();
            secondaryCurves.add(cs);
            insertCurve(cs, !usePrimaryX, true);
        }
        if (_curves.size()>0) setLegendVisible(true);
        setCurveLabel(cs, label);
        setCurveColor(cs, defaultPalette[paletteIndex++]);
        if (paletteIndex >= defaultPalette.length) paletteIndex = 0;
        repaintDiagram(bounds);

        return cs;
    }

    protected boolean add(TimeStampedDataSource ds, boolean primary, boolean background) {
        if (ds==null) return false;

        new LongAction(LongAction.LONG_ACTION_SHAPE | LongAction.LONG_ACTION_SOURCE,
                new Object[]{ds, new Boolean(primary), new Boolean(background)},
                new Object[]{ds, this} ) {

            protected void doAction() {

                doAddYAction((Object[])param);
            }
        }.start(background);
        return !background;
    }


    /* (non-Javadoc)
     * @see jsynoptic.builtin.Plot#repaintDiagram(java.awt.Rectangle)
     */
    public void repaintDiagram(Rectangle oldBounds) {

        // Update PX axis and optionally SX axis
        computeHorizontalBoundAndStep(_curves);
      
        if (axesLimitsArray[PX].validity) {
            setX(axesLimitsArray[PX].min, axesLimitsArray[PX].max, axesLimitsArray[PX].step);
        }
        setLabel(axesLimitsArray[PX].label,true,false);

        if (axesLimitsArray[SX].validity) {
            setSecondaryX(axesLimitsArray[SX].min, axesLimitsArray[SX].max, axesLimitsArray[SX].step);
        }
        setLabel(axesLimitsArray[SX].label,true,true);

        // Update PY axis
        computeVerticalBoundAndStep(axesLimitsArray[PY], primaryCurves);
        if (axesLimitsArray[PY].validity) {
            setY(axesLimitsArray[PY].min, axesLimitsArray[PY].max, axesLimitsArray[PY].step);
        }
        setLabel(axesLimitsArray[PY].label,false,false);

        // Update SY axis
        computeVerticalBoundAndStep(axesLimitsArray[SY], secondaryCurves);
        if (axesLimitsArray[SY].validity) {
            setSecondaryY(axesLimitsArray[SY].min, axesLimitsArray[SY].max, axesLimitsArray[SY].step);
        }
        setLabel(axesLimitsArray[SY].label,false,true);

        //Store bounds.
        if (oldBounds!=null){
            oldBounds.add(getBounds());
        }
        notifyChange(oldBounds);
    }

   
   
    /**
     *
     * This method compute the bounds and the step of horizontal time axes.
     * @param curves
     */
    private void computeHorizontalBoundAndStep(Vector curves) {
       
        // update PX axe
        if ((!axesLimitsArray[PX].validity) && (curves!=null) && (curves.size()>0)) {
            axesLimitsArray[PX].min = getStartEndTime(curves, true, false);
            axesLimitsArray[PX].max = getStartEndTime(curves, false, false);

            if ( axesLimitsArray[PX].floatingAxe) {
                if (axesLimitsArray[PX].max - axesLimitsArray[PX].min > axesLimitsArray[PX].floatingAxeRange) {
                    axesLimitsArray[PX].min = axesLimitsArray[PX].max - axesLimitsArray[PX].floatingAxeRange;

                } else {
                    axesLimitsArray[PX].max =  axesLimitsArray[PX].min +  axesLimitsArray[PX].floatingAxeRange;
                }
            }
            if (axesLimitsArray[PX].min == axesLimitsArray[PX].max) {
                axesLimitsArray[PX].max = axesLimitsArray[PX].min + 1;
                axesLimitsArray[PX].step = 1;
            } else {
                axesLimitsArray[PX].computeStep(nbXGraduation);
            }
            axesLimitsArray[PX].validity=true;
        }
       

        // Get first TimeStamped data source and compute offset between time1 and time2 values
        if (!curves.isEmpty()){
            try {
                TimeStampedDataSource fisrtTsDs =(TimeStampedDataSource) ((Curve)curves.get(0)).shape.getYSource();
                if (fisrtTsDs instanceof StreamingTSDataSource){
                    if (((StreamingTSDataSource)fisrtTsDs).getTime2()!=null){
                        if (displaySecondaryAxis) {
                            if(_asx2 == null){
                                setSecondaryAxis(true,true);
                                setTimeFormat(_asx1.getMin(), _asx1.getMax(), _asx1.getStep(), true);   // set format using ax1 format
                            }

                            // Compute offset between time1 and tim2
                            long currentIndex = fisrtTsDs.getLastIndex();
                            time2Offset =
                                ((StreamingTSDataSource)fisrtTsDs).getTime2().getDoubleValue(currentIndex)-
                                fisrtTsDs.getTime().getDoubleValue(currentIndex);

                            // update SX axe
                            if(!axesLimitsArray[SX].validity){
                                axesLimitsArray[SX].min = axesLimitsArray[PX].min + time2Offset ;                                
                                axesLimitsArray[SX].max = axesLimitsArray[PX].max + time2Offset ;
                                axesLimitsArray[SX].step = axesLimitsArray[PX].step;
                                axesLimitsArray[SX].validity = true;
                            }
                        } else {            // remove the secondary axis
                            if (_asx2 != null) {   
                                super.setSecondaryAxis(true, false);
                                setDateTime(null, true);    // remove the secondary date
                            }
                        }
                    }
                }  
            } catch (DataException e) {
            }
        }
    }

    /* (non-Javadoc)
     * @see simtools.data.EndNotificationListener#notificationEnd(java.lang.Object)
     */
    public void notificationEnd(Object referer) {
        if(referer instanceof TimeStampedDataSource){
            // time sources notification are filtered
            super.notificationEnd(referer);
        }
    }


    /* (non-Javadoc)
     * @see jsynoptic.base.SelectionContextualActionProvider#getCollectiveActions()
     */
    public LinkedHashMap getCollectiveActions(DiagramSelection sel, double x, double y, Object o, int context) {
        LinkedHashMap res=new LinkedHashMap();
        if (((primaryCurves!=null) && (primaryCurves.size()!=0))
                || ((secondaryCurves!=null) && (secondaryCurves.size()!=0))) {       // do both primary and secondary
            res.put(resources.getStringValue("autoscale"), null);
            res.put(resources.getStringValue("autoscaleOnY"), null);

            res.put(resources.getStringValue("adjustOnX") + ";" +  resources.getStringValue("union"), null);
            res.put(resources.getStringValue("adjustOnX") + ";" +  resources.getStringValue("intersection"), null);
            res.put(resources.getStringValue("adjustOnX") + ";" +  resources.getStringValue("firstPlotSelected"), null);

        }

        return res;
    }

    public String[] getActions(double x, double y, Object o, int context) {

        if ((context==MOUSE_OVER_CONTEXT) ||
                (context==MOUSE_OUT_CONTEXT) ||
                (context==MOUSE_PRESSED_CONTEXT)){
            return super.getActions(x,y,o,context);
        }

        Vector v = new Vector();
        if (o instanceof TimeStampedDataSource) {
            v.add(addedResources.getStringValue("add"));
            if (primaryCurves!=null && primaryCurves.size()!=0) {
                v.add(addedResources.getStringValue("addSec"));
            }
     
        } else {
            JSynoptic.setStatus(resources.getStringValue("noSource"));
        }

        if (context==EDITOR_CONTEXT) {
        v.add(0,resources.getStringValue("properties"));
            if (_curves.size()!=0){
                v.add(0,resources.getStringValue("information"));

                if (_magnetizedCurve!=null) {
                    v.add(resources.getStringValue("selectPoint"));
                    v.add(resources.getStringValue("disableMagneticCoordinates") + _magnetizedCurve.getLabel());
                }

                for(int i=0;i<_curves.size();i++){
                    // magnetize a curve action
                    if (!((_magnetizedCurve!=null) && (((Curve)_curves.get(i)).equals(_magnetizedCurve)) ))
                        v.add(resources.getStringValue("enableMagneticCoordinates")+ ";" + ((Curve)_curves.get(i)).getLabel() )
                }

                for(int i=0;i<_curves.size();i++){
                    //  Delete curve action
                    v.add(resources.getStringValue("deleteCurve")+ ";" + ((Curve)_curves.get(i)).getLabel() );
                }
            }
        }
        return (String[])v.toArray(new String[v.size()]);
    }

    public boolean doAction(double x, double y, Object o, String action, CompoundEdit undoableEdit) {
        if (action==null) return false;

        if (action.equals("mouseOver")
                || action.equals("mouseOut")
                || action.equals("zoomTopLeft")
                || action.equals("zoomBottomRight")
                || action.equals(resources.getStringValue("zoomBox"))
                || action.equals(resources.getStringValue("zoomOut"))
                || action.equals(resources.getStringValue("autoscale"))
                || action.equals(resources.getStringValue("information"))
                || action.equals(resources.getStringValue("autoscaleOnY"))
                || action.equals(resources.getStringValue("properties"))
                || action.startsWith(resources.getStringValue("enableMagneticCoordinates"))
                || action.startsWith(resources.getStringValue("disableMagneticCoordinates"))
                || action.startsWith(resources.getStringValue("deleteCurve"))
                || action.startsWith(resources.getStringValue("adjustOnX"))
                || action.startsWith(resources.getStringValue("selectPoint"))
        ){

            return super.doAction(x,y,o,action, undoableEdit);   
        }

        if (o instanceof TimeStampedDataSource) {
            TimeStampedDataSource ds = (TimeStampedDataSource)o;
            if (action.equals(addedResources.getStringValue("add"))) {
                return add(ds, true, true);
            }
            if (action.equals(addedResources.getStringValue("addSec"))) {
                return add(ds, false, true);
            }
        }
        return false;
    }

  
    /* (non-Javadoc)
     * @see jsynoptic.builtin.TimePlot#secondaryAxisBoundComputation(java.awt.Rectangle)
     */
    protected void secondaryAxisBoundComputation(Rectangle ret){
        if(_asx2 != null){
            //Because _asx2 is not associated with a CurveShape, it is not
            //automatically taken into account in the shape Bound computing.
            Rectangle r = _asx2.getBounds();
            //add _asx2 in the shape Bounds computing
            ret.add(r);
        }
    }

    /* (non-Javadoc)
     * @see jsynoptic.builtin.Plot#createPanel()
     */
    public JPropertiesPanel createPanel() {
        int curvesSize =  ((primaryCurves!=null ? primaryCurves.size() : 0) (secondaryCurves!=null ? secondaryCurves.size() : 0));
        return new TimePlotPropertiesPanel(curvesSize, AsyncPlugin.resources.getString("TimePlot"));
    }
   
   
    /* (non-Javadoc)
     * @see simtools.shapes.AbstractShape#getShapeName()
     */
    public String getShapeName(){
        return AsyncPlugin.resources.getString("TimePlot");
    }


    /* (non-Javadoc)
     * @see jsynoptic.base.DataSourceConsumer#canAddDataSource(simtools.data.DataSource)
     */
    public boolean canAddDataSource(DataSource d) {
        return d instanceof TimeStampedDataSource;
    }

    /* (non-Javadoc)
     * @see jsynoptic.base.DataSourceConsumer#addDataSource(simtools.data.DataSource)
     */
    public boolean addDataSource(DataSource d) {
        return add((TimeStampedDataSource)d, true, true);
    }

    /**
     * Get start or end time related to a list of curves
     * @param curves
     * @param start - if true get start time, otherwise get end time
     * @param secondaryXaxis   - if true look on all curves whose X is defined on X secondaryXaxis
     *                          otherwise look  on all curves whose X is defined on X primary
     * @return
     */
    protected double getStartEndTime(Vector curves, boolean start, boolean secondaryXaxis){
        double res = start? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
        try{
            for (int i=0; i<curves.size(); ++i) {
                Curve curve = ((Curve) curves.get(i));

                if (curve.secondaryXaxis == secondaryXaxis) {
                    TimeStampedDataSource ySource = (TimeStampedDataSource)curve.shape.getYSource();
                    double t = (start ? ySource.getStart(): ySource.getEnd());
                    if (start && t < res){
                        res = t;
                    }
                    if (!start && t > res){
                        res = t;
                    }
                }  
            }
        } catch (DataException e){
            res = 0.0;
        }
        return res;
    }

    private void readObject(java.io.ObjectInputStream in) throws java.lang.ClassNotFoundException, java.io.IOException {
        in.defaultReadObject();

        // primaryX and secondaryX shall be null in Asynchronous Plots,
        // but old plots can still contain those data source values  -> update them.
        if (primaryX != null){
            primaryX = null;
            axesLimitsArray[PX].label = null;
        }
        if (secondaryX != null){
            secondaryX = null;
            axesLimitsArray[SX].label = null;
        }
    }  


    /*
     * (non-Javadoc)
     *
     * @see jsynoptic.builtin.ui.PlotPropertiesPanel#getPropertyNames()
     */
    public String[] getPropertyNames() {
        return createPanel().getPropertyNames();
    }

    /*
     * (non-Javadoc)
     *
     * @see jsynoptic.builtin.ui.PlotPropertiesPanel#getPropertyValue(java.lang.String)
     */
    public Object getPropertyValue(String name) {
        Object res = super.getPropertyValue(name);
        if (name.equalsIgnoreCase("DISPLAY_SEC_AXIS")) {
            res = new Boolean(displaySecondaryAxis);
        }
        return res;
    }

    /* (non-Javadoc)
     * @see jsynoptic.builtin.ui.PlotPropertiesPanel#setPropertyValue(java.lang.String, java.lang.Object)
     */
    public void setPropertyValue(String name, Object value) {
        if (name.equalsIgnoreCase("DISPLAY_SEC_AXIS")) {
            displaySecondaryAxis = ((Boolean) value).booleanValue();
        }
        super.setPropertyValue(name, value);
    }
}
TOP

Related Classes of jsynoptic.plugins.async.TimePlot

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.