View Javadoc
1   package org.opentrafficsim.graphs;
2   
3   import java.awt.event.ActionListener;
4   import java.io.ByteArrayOutputStream;
5   import java.io.IOException;
6   import java.util.List;
7   import java.util.UUID;
8   
9   import javax.swing.JFrame;
10  import javax.swing.event.EventListenerList;
11  
12  import org.jfree.chart.ChartUtilities;
13  import org.jfree.chart.JFreeChart;
14  import org.jfree.data.general.Dataset;
15  import org.jfree.data.general.DatasetChangeEvent;
16  import org.jfree.data.general.DatasetChangeListener;
17  import org.opentrafficsim.base.immutablecollections.Immutable;
18  import org.opentrafficsim.base.immutablecollections.ImmutableArrayList;
19  import org.opentrafficsim.base.immutablecollections.ImmutableList;
20  import org.opentrafficsim.road.network.lane.Lane;
21  
22  import nl.tudelft.simulation.event.EventType;
23  
24  /**
25   * Basics of all plots in the Open Traffic Simulator.
26   * <p>
27   * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
28   * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
29   * <p>
30   * @version $Revision$, $LastChangedDate$, by $Author$, initial version Sep 16, 2016 <br>
31   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
32   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
33   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
34   */
35  public abstract class AbstractOTSPlot extends JFrame
36          implements Dataset, ActionListener, MultipleViewerChart, LaneBasedGTUSampler
37  {
38  
39      /** */
40      private static final long serialVersionUID = 20160916L;
41  
42      /**
43       * The (regular, not timed) event type for pub/sub indicating the addition of a graph. <br>
44       * Payload: String graph caption (not an array, just a String)
45       */
46      public static final EventType GRAPH_ADD_EVENT = new EventType("GRAPH.ADD");
47  
48      /**
49       * The (regular, not timed) event type for pub/sub indicating the removal of a graph. <br>
50       * Payload: String Graph caption (not an array, just a String)
51       */
52      public static final EventType GRAPH_REMOVE_EVENT = new EventType("GRAPH.REMOVE");
53  
54      /** unique ID of the chart. */
55      private final UUID uniqueId = UUID.randomUUID();
56  
57      /** Name of the chart. */
58      private final String caption;
59  
60      /** List of parties interested in changes of this ContourPlot. */
61      private transient EventListenerList listenerList = new EventListenerList();
62  
63      /** The graph. */
64      private JFreeChart chart;
65      
66      /** The series of Lanes that provide the data for this TrajectoryPlot. */
67      private final ImmutableList<Lane> path;
68  
69      /**
70       * Construct a new AbstractOTSPlot.
71       * @param caption String; the caption of the graph window
72       * @param path List&lt;Lane&gt; the lanes for which the plot is made  
73       */
74      public AbstractOTSPlot(final String caption, final List<Lane> path)
75      {
76          this.caption = caption;
77          this.path = new ImmutableArrayList<Lane>(path, Immutable.COPY);
78      }
79  
80      /**
81       * Save the chart.
82       * @param chart JFreeChart; the chart
83       */
84      protected final void setChart(final JFreeChart chart)
85      {
86          this.chart = chart;
87      }
88  
89      /**
90       * Create the visualization.
91       * @param container JFrame; the JFrame that will be filled with chart and the status label
92       * @return JFreeChart; the visualization
93       */
94      protected abstract JFreeChart createChart(JFrame container);
95  
96      /**
97       * Force redrawing of the graph.
98       */
99      public abstract void reGraph();
100 
101     /** {@inheritDoc} */
102     @Override
103     public final JFrame addViewer()
104     {
105         JFrame result = new JFrame(this.caption);
106         result.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
107         JFreeChart newChart = createChart(result);
108         newChart.setTitle((String) null);
109         addChangeListener(newChart.getPlot());
110         return result;
111     }
112 
113     /** {@inheritDoc} */
114     @Override
115     public final void addChangeListener(final DatasetChangeListener listener)
116     {
117         this.listenerList.add(DatasetChangeListener.class, listener);
118     }
119 
120     /** {@inheritDoc} */
121     @Override
122     public final void removeChangeListener(final DatasetChangeListener listener)
123     {
124         this.listenerList.remove(DatasetChangeListener.class, listener);
125     }
126 
127     /**
128      * Notify interested parties of an event affecting this TrajectoryPlot.
129      * @param event DatasetChangedEvent
130      */
131     protected final void notifyListeners(final DatasetChangeEvent event)
132     {
133         for (DatasetChangeListener dcl : this.listenerList.getListeners(DatasetChangeListener.class))
134         {
135             dcl.datasetChanged(event);
136         }
137     }
138 
139     /**
140      * @return listenerList.
141      */
142     protected final EventListenerList getListenerList()
143     {
144         return this.listenerList;
145     }
146 
147     /**
148      * Return the caption of this graph.
149      * @return String; the caption of this graph
150      */
151     public final String getCaption()
152     {
153         return this.caption;
154     }
155     
156     /**
157      * Provide a unique ID for this graph. In this case based on a generated UUID.
158      * @return String; a unique ID. 
159      */
160     public final String getId()
161     {
162         return this.uniqueId.toString();
163     }
164     
165     /**
166      * @return path List&lt;Lane&gt; the path
167      */
168     public final ImmutableList<Lane> getPath()
169     {
170         return this.path;
171     }
172 
173     /**
174      * Return the graph type.
175      * @return GraphType: the graph type.
176      */
177     public abstract GraphType getGraphType();
178 
179     /**
180      * Make a snapshot of the graph and return it encoded as a PNG image.
181      * @param width int; the width of the PNG in pixels
182      * @param height int; the height of the PNG in pixels
183      * @return byte[]; the PNG encoded graph
184      * @throws IOException when there are IO
185      */
186     public final byte[] generatePNG(final int width, final int height) throws IOException
187     {
188         ByteArrayOutputStream result = new ByteArrayOutputStream();
189         ChartUtilities.writeChartAsPNG(result, this.chart, width, height);
190         return result.toByteArray();
191     }
192 
193 }