1 package org.opentrafficsim.draw.graphs;
2
3 import org.djunits.value.vdouble.scalar.Duration;
4 import org.djutils.exceptions.Throw;
5 import org.jfree.chart.JFreeChart;
6 import org.jfree.chart.axis.ValueAxis;
7 import org.jfree.chart.event.AxisChangeEvent;
8 import org.jfree.chart.event.AxisChangeListener;
9 import org.jfree.chart.plot.XYPlot;
10 import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
11
12
13
14
15
16
17
18
19
20
21
22
23 public abstract class AbstractBoundedPlot extends AbstractPlot
24 {
25
26
27 private Double lowerDomainBound = null;
28
29
30 private Double upperDomainBound = null;
31
32
33 private Double lowerRangeBound = null;
34
35
36 private Double upperRangeBound = null;
37
38
39
40
41
42
43
44
45 public AbstractBoundedPlot(final OtsSimulatorInterface simulator, final String caption, final Duration updateInterval,
46 final Duration delay)
47 {
48 super(simulator, caption, updateInterval, delay);
49 }
50
51
52 @Override
53 protected void setChart(final JFreeChart chart)
54 {
55 Throw.when(!(chart.getPlot() instanceof XYPlot), IllegalArgumentException.class,
56 "AbstractBoundedPlot can only work with XYPlot.");
57
58 super.setChart(chart);
59
60 XYPlot xyPlot = chart.getXYPlot();
61 xyPlot.getDomainAxis().addChangeListener(new AxisChangeListener()
62 {
63
64 private boolean listen = true;
65
66
67 @SuppressWarnings("synthetic-access")
68 @Override
69 public void axisChanged(final AxisChangeEvent event)
70 {
71 if (!this.listen)
72 {
73 return;
74 }
75 this.listen = false;
76 constrainAxis(xyPlot.getDomainAxis(), AbstractBoundedPlot.this.lowerDomainBound,
77 AbstractBoundedPlot.this.upperDomainBound);
78 this.listen = true;
79 }
80 });
81 xyPlot.getRangeAxis().addChangeListener(new AxisChangeListener()
82 {
83
84 private boolean listen = true;
85
86
87 @SuppressWarnings("synthetic-access")
88 @Override
89 public void axisChanged(final AxisChangeEvent event)
90 {
91 if (!this.listen)
92 {
93 return;
94 }
95 this.listen = false;
96 constrainAxis(xyPlot.getRangeAxis(), AbstractBoundedPlot.this.lowerRangeBound,
97 AbstractBoundedPlot.this.upperRangeBound);
98 this.listen = true;
99 }
100 });
101 }
102
103
104
105
106
107 public void setLowerDomainBound(final Double bound)
108 {
109 this.lowerDomainBound = bound;
110 constrainAxis(getChart().getXYPlot().getDomainAxis(), this.lowerDomainBound, this.upperDomainBound);
111 }
112
113
114
115
116
117 public void setUpperDomainBound(final Double bound)
118 {
119 this.upperDomainBound = bound;
120 constrainAxis(getChart().getXYPlot().getDomainAxis(), this.lowerDomainBound, this.upperDomainBound);
121 }
122
123
124
125
126
127 public void setLowerRangeBound(final Double bound)
128 {
129 this.lowerRangeBound = bound;
130 constrainAxis(getChart().getXYPlot().getRangeAxis(), this.lowerRangeBound, this.upperRangeBound);
131 }
132
133
134
135
136
137 public void setUpperRangeBound(final Double bound)
138 {
139 this.upperRangeBound = bound;
140 constrainAxis(getChart().getXYPlot().getRangeAxis(), this.lowerRangeBound, this.upperRangeBound);
141 }
142
143
144
145
146
147
148
149 private void constrainAxis(final ValueAxis axis, final Double min, final Double max)
150 {
151 double xLow = axis.getLowerBound();
152 double xUpp = axis.getUpperBound();
153 if (min != null && max != null && xUpp - xLow > max - min)
154 {
155 axis.setLowerBound(min);
156 axis.setUpperBound(max);
157 }
158 else if (min != null && xLow < min)
159 {
160 axis.setLowerBound(min);
161 axis.setUpperBound(xUpp + (min - xLow));
162 }
163 else if (max != null && xUpp > max)
164 {
165 axis.setLowerBound(xLow - (xUpp - max));
166 axis.setUpperBound(max);
167 }
168 }
169
170
171 @Override
172 public void setAutoBoundDomain(final XYPlot plot)
173 {
174 if (this.lowerDomainBound != null)
175 {
176 plot.getDomainAxis().setLowerBound(this.lowerDomainBound);
177 }
178 if (this.upperDomainBound != null)
179 {
180 plot.getDomainAxis().setUpperBound(this.upperDomainBound);
181 }
182 }
183
184
185 @Override
186 public void setAutoBoundRange(final XYPlot plot)
187 {
188 if (this.lowerRangeBound != null)
189 {
190 plot.getRangeAxis().setLowerBound(this.lowerRangeBound);
191 }
192 if (this.upperRangeBound != null)
193 {
194 plot.getRangeAxis().setUpperBound(this.upperRangeBound);
195 }
196 }
197
198 }