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