001/* Plot functions of time in oscilloscope style. 002 003 @Copyright (c) 1998-2014 The Regents of the University of California. 004 All rights reserved. 005 006 Permission is hereby granted, without written agreement and without 007 license or royalty fees, to use, copy, modify, and distribute this 008 software and its documentation for any purpose, provided that the 009 above copyright notice and the following two paragraphs appear in all 010 copies of this software. 011 012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 016 SUCH DAMAGE. 017 018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 ENHANCEMENTS, OR MODIFICATIONS. 024 025 PT_COPYRIGHT_VERSION 2 026 COPYRIGHTENDKEY 027 */ 028package ptolemy.actor.lib.gui; 029 030import ptolemy.data.DoubleToken; 031import ptolemy.data.expr.Parameter; 032import ptolemy.data.type.BaseType; 033import ptolemy.kernel.CompositeEntity; 034import ptolemy.kernel.util.Attribute; 035import ptolemy.kernel.util.IllegalActionException; 036import ptolemy.kernel.util.NameDuplicationException; 037import ptolemy.plot.Plot; 038 039/////////////////////////////////////////////////////////////////// 040//// TimedScope 041 042/** 043 <p>A signal plotter that plots in an oscilloscope style, meaning that the 044 horizontal axis is wrapped and that there is finite persistence. This 045 plotter contains an instance of the Plot class from the Ptolemy plot 046 package as a public member. Data at the input, which can consist of 047 any number of channels, are plotted on this instance. Each channel is 048 plotted as a separate data set. The input is of type DoubleToken. 049 050 </p><p>The horizontal axis represents time. The <i>width</i> parameter is 051 a double that gives the width of the plot. The horizontal axis will be 052 labeled from 0.0 to <i>width</i>. It defaults to 10.0. 053 054 </p><p>If the <i>persistence</i> parameter is positive, then it specifies 055 the amount of time into the past that points are shown. It also 056 defaults to 10.0, so any point older than 10.0 time units is erased and 057 forgotten.</p> 058 059 @author Edward A. Lee 060 @version $Id$ 061 @since Ptolemy II 1.0 062 @Pt.ProposedRating Yellow (eal) 063 @Pt.AcceptedRating Yellow (neuendor) 064 */ 065public class TimedScope extends TimedPlotter { 066 /** Construct an actor with the given container and name. 067 * @param container The container. 068 * @param name The name of this actor. 069 * @exception IllegalActionException If the actor cannot be contained 070 * by the proposed container. 071 * @exception NameDuplicationException If the container already has an 072 * actor with this name. 073 */ 074 public TimedScope(CompositeEntity container, String name) 075 throws IllegalActionException, NameDuplicationException { 076 super(container, name); 077 078 // set the parameters 079 width = new Parameter(this, "width", new DoubleToken(10.0)); 080 width.setTypeEquals(BaseType.DOUBLE); 081 persistence = new Parameter(this, "persistence", new DoubleToken(10.0)); 082 persistence.setTypeEquals(BaseType.DOUBLE); 083 } 084 085 /////////////////////////////////////////////////////////////////// 086 //// ports and parameters //// 087 088 /** The width of the X axis (a double). */ 089 public Parameter width; 090 091 /** The amount of data displayed at any one time (a double). 092 * This has units of the X axis. 093 */ 094 public Parameter persistence; 095 096 /////////////////////////////////////////////////////////////////// 097 //// public methods //// 098 099 /** Notify this that an attribute has changed. If either parameter 100 * is changed, then this actor updates the configuration of the 101 * visible plot. 102 * @param attribute The attribute that changed. 103 * @exception IllegalActionException If the expression of the 104 * attribute cannot be parsed or cannot be evaluated. 105 */ 106 @Override 107 public void attributeChanged(Attribute attribute) 108 throws IllegalActionException { 109 if (attribute == width && plot != null) { 110 double widthValue = ((DoubleToken) width.getToken()).doubleValue(); 111 plot.setXRange(0.0, widthValue); 112 } else if (attribute == persistence && plot != null) { 113 double persValue = ((DoubleToken) persistence.getToken()) 114 .doubleValue(); 115 116 // NOTE: We assume the superclass ensures this cast is safe. 117 ((Plot) plot).setXPersistence(persValue); 118 } else { 119 super.attributeChanged(attribute); 120 } 121 } 122 123 /** Initialize this actor. This method configures the plotter 124 * using the current parameter values. 125 * @exception IllegalActionException If the parent class throws it. 126 */ 127 @Override 128 public void initialize() throws IllegalActionException { 129 super.initialize(); 130 131 double widthValue = ((DoubleToken) width.getToken()).doubleValue(); 132 plot.setXRange(0.0, widthValue); 133 134 // NOTE: We assume the superclass ensures this cast is safe. 135 ((Plot) plot).setWrap(true); 136 137 double persValue = ((DoubleToken) persistence.getToken()).doubleValue(); 138 ((Plot) plot).setXPersistence(persValue); 139 plot.repaint(); 140 141 // Override the default so that there are not gaps in the lines. 142 if (((Plot) plot).getMarksStyle().equals("none")) { 143 ((Plot) plot).setMarksStyle("pixels"); 144 } 145 } 146 147 /** Call the base class postfire() method, then yield this 148 * thread so that the event thread gets a chance. This is necessary, 149 * because otherwise the swing thread may be starved and accumulate a 150 * large number of points waiting to be plotted. 151 * @exception IllegalActionException If there is no director, 152 * or if the base class throws it. 153 * @return True if it is OK to continue. 154 */ 155 @Override 156 public boolean postfire() throws IllegalActionException { 157 boolean result = super.postfire(); 158 Thread.yield(); 159 return result; 160 } 161}