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