1 package org.opentrafficsim.draw.graphs;
2
3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener;
5
6 import javax.swing.JCheckBoxMenuItem;
7 import javax.swing.JPopupMenu;
8
9 import org.djunits.value.vdouble.scalar.Duration;
10 import org.djunits.value.vdouble.scalar.Length;
11 import org.djunits.value.vdouble.scalar.Time;
12 import org.jfree.chart.JFreeChart;
13 import org.jfree.chart.event.AxisChangeEvent;
14 import org.jfree.chart.event.AxisChangeListener;
15 import org.jfree.chart.plot.XYPlot;
16 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
17
18
19
20
21
22
23
24
25
26
27
28
29
30 public abstract class AbstractSpaceTimePlot extends AbstractBoundedPlot
31 {
32
33
34 private static final long serialVersionUID = 20181014L;
35
36
37 private final Time initialEnd;
38
39
40 private boolean autoBoundAxes = true;
41
42
43 private boolean virtualAutoBounds = false;
44
45
46 private Double fixedDomainRange = null;
47
48
49
50
51
52
53
54
55
56 public AbstractSpaceTimePlot(final String caption, final Duration updateInterval, final OTSSimulatorInterface simulator,
57 final Duration delay, final Time initialEnd)
58 {
59 super(caption, updateInterval, simulator, delay);
60 this.initialEnd = initialEnd;
61 }
62
63
64 @Override
65 protected void setChart(final JFreeChart chart)
66 {
67 super.setChart(chart);
68 XYPlot xyPlot = chart.getXYPlot();
69 setLowerRangeBound(0.0);
70 setUpperRangeBound(getEndLocation().si);
71 setLowerDomainBound(0.0);
72 setUpperDomainBound(this.initialEnd.si);
73 setAutoBounds(xyPlot);
74
75 xyPlot.getDomainAxis().addChangeListener(new AxisChangeListener()
76 {
77
78 @SuppressWarnings("synthetic-access")
79 @Override
80 public void axisChanged(final AxisChangeEvent event)
81 {
82 if (!AbstractSpaceTimePlot.this.virtualAutoBounds)
83 {
84
85 AbstractSpaceTimePlot.this.autoBoundAxes = false;
86 }
87 }
88 });
89 }
90
91
92 @Override
93 protected void addPopUpMenuItems(final JPopupMenu popupMenu)
94 {
95 JCheckBoxMenuItem fixedDomainCheckBox = new JCheckBoxMenuItem("Fix time range", false);
96 fixedDomainCheckBox.addActionListener(new ActionListener()
97 {
98
99 @SuppressWarnings("synthetic-access")
100 @Override
101 public void actionPerformed(final ActionEvent e)
102 {
103 boolean fix = ((JCheckBoxMenuItem) e.getSource()).isSelected();
104 AbstractSpaceTimePlot.this.fixedDomainRange =
105 fix ? getChart().getXYPlot().getDomainAxis().getRange().getLength() : null;
106 notifyPlotChange();
107 }
108 });
109 popupMenu.insert(fixedDomainCheckBox, 0);
110 popupMenu.insert(new JPopupMenu.Separator(), 1);
111 }
112
113
114 @Override
115 protected void update()
116 {
117 if (getUpdateTime() != null && this.initialEnd != null)
118 {
119 setUpperDomainBound(Math.max(getUpdateTime().si, this.initialEnd.si));
120 }
121 if (this.autoBoundAxes && getChart() != null)
122 {
123 setAutoBounds(getChart().getXYPlot());
124 }
125 super.update();
126 }
127
128
129
130
131
132
133 private void setAutoBounds(final XYPlot plot)
134 {
135
136
137 this.virtualAutoBounds = true;
138 if (this.fixedDomainRange != null && getUpdateTime().si > 0.0)
139 {
140 plot.getDomainAxis().setRange(Math.max(getUpdateTime().si - this.fixedDomainRange, 0.0), getUpdateTime().si);
141 }
142 else
143 {
144 super.setAutoBoundDomain(plot);
145 }
146 super.setAutoBoundRange(plot);
147 this.virtualAutoBounds = false;
148 }
149
150
151 @Override
152 protected final void setAutoBoundDomain(final XYPlot plot)
153 {
154 super.setAutoBoundDomain(plot);
155 this.autoBoundAxes = true;
156 }
157
158
159 @Override
160 protected final void setAutoBoundRange(final XYPlot plot)
161 {
162 super.setAutoBoundRange(plot);
163 this.autoBoundAxes = true;
164 }
165
166
167
168
169
170 protected abstract Length getEndLocation();
171
172 }