1 package org.opentrafficsim.animation.graphs;
2
3 import org.djunits.value.vdouble.scalar.Duration;
4 import org.djunits.value.vdouble.scalar.Length;
5 import org.jfree.chart.JFreeChart;
6 import org.jfree.chart.event.AxisChangeEvent;
7 import org.jfree.chart.event.AxisChangeListener;
8 import org.jfree.chart.plot.XYPlot;
9 import org.opentrafficsim.animation.graphs.AbstractPlot.PaintState;
10
11
12
13
14
15
16
17
18
19
20
21
22
23 public abstract class AbstractSpaceTimePlot<S extends PaintState> extends AbstractBoundedPlot<S>
24 {
25
26
27 private final Duration initialEnd;
28
29
30 private boolean autoBoundAxes = true;
31
32
33 private boolean programmaticBoundChanges = false;
34
35
36 private Double fixedDomainRange = null;
37
38
39
40
41
42
43
44
45
46 public AbstractSpaceTimePlot(final String caption, final Duration updateInterval, final PlotScheduler scheduler,
47 final Duration delay, final Duration initialEnd)
48 {
49 super(scheduler, caption, updateInterval, delay);
50 this.initialEnd = initialEnd;
51 }
52
53 @Override
54 protected void setChart(final JFreeChart chart)
55 {
56 super.setChart(chart);
57 XYPlot xyPlot = chart.getXYPlot();
58 setLowerRangeBound(0.0);
59 setUpperRangeBound(getEndLocation().si);
60 setLowerDomainBound(0.0);
61 setUpperDomainBound(this.initialEnd.si);
62 setAutoBounds(xyPlot);
63
64 xyPlot.getDomainAxis().addChangeListener(new AxisChangeListener()
65 {
66 @Override
67 public void axisChanged(final AxisChangeEvent event)
68 {
69 if (!AbstractSpaceTimePlot.this.programmaticBoundChanges)
70 {
71
72 AbstractSpaceTimePlot.this.autoBoundAxes = false;
73 }
74 }
75 });
76 }
77
78 @Override
79 protected void setPaintState()
80 {
81 super.setPaintState();
82 this.programmaticBoundChanges = true;
83 setUpperDomainBound(Math.max(getAvailableTime().si, this.initialEnd.si));
84 this.programmaticBoundChanges = false;
85 if (this.autoBoundAxes && getChart() != null)
86 {
87 setAutoBounds(getChart().getXYPlot());
88 }
89 }
90
91
92
93
94
95
96 public void updateFixedDomainRange(final boolean fixed)
97 {
98 this.fixedDomainRange = fixed ? getChart().getXYPlot().getDomainAxis().getRange().getLength() : null;
99 notifyPlotChange();
100 }
101
102
103
104
105
106
107 private void setAutoBounds(final XYPlot plot)
108 {
109
110 this.programmaticBoundChanges = true;
111 if (this.fixedDomainRange != null && getAvailableTime().si > 0.0)
112 {
113 setLowerDomainBound(Math.max(getAvailableTime().si - this.fixedDomainRange, 0.0));
114 setUpperDomainBound(Math.max(getAvailableTime().si, this.initialEnd.si));
115 }
116 else
117 {
118 super.setAutoBoundDomain(plot);
119 }
120 super.setAutoBoundRange(plot);
121 this.programmaticBoundChanges = false;
122 }
123
124
125 @Override
126 public final void setAutoBoundDomain(final XYPlot plot)
127 {
128 super.setAutoBoundDomain(plot);
129 this.autoBoundAxes = true;
130 }
131
132
133 @Override
134 public final void setAutoBoundRange(final XYPlot plot)
135 {
136 super.setAutoBoundRange(plot);
137 this.autoBoundAxes = true;
138 }
139
140
141
142
143
144 protected abstract Length getEndLocation();
145
146 }