1 | /* |
---|
2 | * $Id: SpaceAxis.java,v 1.9 2003/08/22 23:02:32 dwd Exp $ |
---|
3 | * |
---|
4 | * This software is provided by NOAA for full, free and open release. It is |
---|
5 | * understood by the recipient/user that NOAA assumes no liability for any |
---|
6 | * errors contained in the code. Although this software is released without |
---|
7 | * conditions or restrictions in its use, it is expected that appropriate |
---|
8 | * credit be given to its author and to the National Oceanic and Atmospheric |
---|
9 | * Administration should the software be included by the recipient as an |
---|
10 | * element in other product development. |
---|
11 | */ |
---|
12 | |
---|
13 | package gov.noaa.pmel.sgt; |
---|
14 | |
---|
15 | import gov.noaa.pmel.util.Range2D; |
---|
16 | import gov.noaa.pmel.util.TimePoint; |
---|
17 | import gov.noaa.pmel.util.Point2D; |
---|
18 | import gov.noaa.pmel.util.Debug; |
---|
19 | import gov.noaa.pmel.util.GeoDate; |
---|
20 | import gov.noaa.pmel.util.SoTValue; |
---|
21 | import gov.noaa.pmel.util.SoTPoint; |
---|
22 | import gov.noaa.pmel.util.SoTRange; |
---|
23 | |
---|
24 | import java.util.Enumeration; |
---|
25 | import java.awt.Graphics; |
---|
26 | import java.awt.Color; |
---|
27 | import java.awt.Rectangle; |
---|
28 | // jdk1.2 |
---|
29 | //import java.awt.geom.Point2D; |
---|
30 | |
---|
31 | /** |
---|
32 | * Abstract base class for axes whose user coordinates are double values. |
---|
33 | * The following is an example of using a {@link PlainAxis}. |
---|
34 | * <A NAME="example"><!-- --></A> |
---|
35 | * <pre> |
---|
36 | * import gov.noaa.pmel.sgt.PlainAxis; |
---|
37 | * import gov.noaa.pmel.sgt.LinearTransform; |
---|
38 | * import gov.noaa.pmel.sgt.Graph; |
---|
39 | * ... |
---|
40 | * Graph graph; |
---|
41 | * PlainAxis xbot, xtop; |
---|
42 | * LinearTransform xt; |
---|
43 | * Point2D.Double lowerleft = new Point2D.Double(10.0, 100.0); |
---|
44 | * ... |
---|
45 | * // |
---|
46 | * // Instatiate xt and set it as the x transform. |
---|
47 | * // |
---|
48 | * xt = new LinearTransform(0.75, 3.5, 10.0, 100.0); |
---|
49 | * graph.setXTransform(xt); |
---|
50 | * ... |
---|
51 | * // |
---|
52 | * // Instatiate xbot and set its range, delta, and |
---|
53 | * // location. Set xbot the numberSmallTics property |
---|
54 | * // for xbot. |
---|
55 | * // |
---|
56 | * xbot = new PlainAxis("Bottom Axis"); |
---|
57 | * xbot.setRangeU(new Range2D(10.0, 100.0)); |
---|
58 | * xbot.setDeltaU(20.0); |
---|
59 | * xbot.setNumberSmallTics(4); |
---|
60 | * xbot.setLocationU(lowerleft); |
---|
61 | * // |
---|
62 | * // Create title for xbot. |
---|
63 | * // |
---|
64 | * Font xbfont = new Font("Helvetica", Font.ITALIC, 14); |
---|
65 | * xbot.setLabelFont(xbfont); |
---|
66 | * SGLabel xtitle = new SGLabel("xaxis title", |
---|
67 | * "Test X-Axis Title", |
---|
68 | * new Point2D.Double(0.0, 0.0)); |
---|
69 | * Font xtfont = new Font("Helvetica", Font.PLAIN, 14); |
---|
70 | * xtitle.setFont(xtfont); |
---|
71 | * xtitle.setHeightP(0.2); |
---|
72 | * xbot.setTitle(xtitle); |
---|
73 | * graph.setXAxis(xbot); |
---|
74 | * ... |
---|
75 | * // |
---|
76 | * // Instatiate xtop and set its range, delta, and |
---|
77 | * // location. Set xtop properties on ticPosition and |
---|
78 | * // labelPosition. |
---|
79 | * // |
---|
80 | * xtop = new PlainAxis("Top Axis"); |
---|
81 | * xtop.setRangeU(new Range2D(10.0, 100.0)); |
---|
82 | * xtop.setDeltaU(20.0); |
---|
83 | * xtop.setNumberSmallTics(0); |
---|
84 | * xtop.setLocationU(new Point2D.Double(10.0, 300.0)); |
---|
85 | * xtop.setLabelFont(xbfont); |
---|
86 | * xtop.setTicPosition(Axis.POSITIVE_SIDE); |
---|
87 | * xtop.setLabelPosition(Axis.NO_LABEL); |
---|
88 | * graph.setXAxis(xtop); |
---|
89 | * ... |
---|
90 | * // |
---|
91 | * // Register the x transform and the top x axis with the bottom x axis. |
---|
92 | * // By registering xt and xtop, any updates to the user or physical range |
---|
93 | * // of xbot will be automatically performed on xt and xtop. |
---|
94 | * // |
---|
95 | * xbot.register(xt); |
---|
96 | * xbot.register(xtop); |
---|
97 | * </pre> |
---|
98 | * |
---|
99 | * @author Donald Denbo |
---|
100 | * @version $Revision: 1.9 $, $Date: 2003/08/22 23:02:32 $ |
---|
101 | * @since 1.0 |
---|
102 | * @see Axis |
---|
103 | * @see PlainAxis |
---|
104 | * @see TimeAxis |
---|
105 | **/ |
---|
106 | public abstract class SpaceAxis extends Axis { |
---|
107 | protected Range2D uRange_; |
---|
108 | protected Point2D.Double uLocation_; |
---|
109 | protected TimePoint tLocation_; |
---|
110 | static final double TIC_GAP = 0.05; |
---|
111 | static final double TIC_RATIO = 1.3; |
---|
112 | static final double LABEL_RATIO = 1.3; |
---|
113 | // |
---|
114 | protected void updateRegisteredTransforms() { |
---|
115 | if(!registeredTransforms_.isEmpty()) { |
---|
116 | AxisTransform trns; |
---|
117 | for(Enumeration it = registeredTransforms_.elements(); |
---|
118 | it.hasMoreElements();) { |
---|
119 | trns = (AxisTransform)it.nextElement(); |
---|
120 | trns.setRangeP(pRange_); |
---|
121 | trns.setRangeU(uRange_); |
---|
122 | } |
---|
123 | } |
---|
124 | } |
---|
125 | // |
---|
126 | protected void updateRegisteredAxes() { |
---|
127 | if(!registeredAxes_.isEmpty()) { |
---|
128 | SpaceAxis ax; |
---|
129 | for(Enumeration it = registeredAxes_.elements(); |
---|
130 | it.hasMoreElements();) { |
---|
131 | ax = (SpaceAxis)it.nextElement(); |
---|
132 | ax.setRangeU(uRange_); |
---|
133 | ax.setRangeP(pRange_); |
---|
134 | } |
---|
135 | } |
---|
136 | } |
---|
137 | // |
---|
138 | protected void drawSmallXTics(Graphics g,double xu,double xtest,double del,double yp) { |
---|
139 | int x0, y0, y1, i; |
---|
140 | double yp0, yp1, smdel, xt; |
---|
141 | if(numSmallTics_ <= 0) return; |
---|
142 | // yp = graph_.getYUtoP(yu); |
---|
143 | if(ticPosition_ == BOTH_SIDES || ticPosition_ == POSITIVE_SIDE) { |
---|
144 | yp0 = yp + smallTicHeight_; |
---|
145 | } else { |
---|
146 | yp0 = yp; |
---|
147 | } |
---|
148 | if(ticPosition_ == BOTH_SIDES || ticPosition_ == NEGATIVE_SIDE) { |
---|
149 | yp1 = yp - smallTicHeight_; |
---|
150 | } else { |
---|
151 | yp1 = yp; |
---|
152 | } |
---|
153 | y0 = graph_.getLayer().getYPtoD(yp0); |
---|
154 | y1 = graph_.getLayer().getYPtoD(yp1); |
---|
155 | smdel = del/(numSmallTics_ + 1); |
---|
156 | for(i=0; i <= numSmallTics_; i++) { |
---|
157 | xt = xu + smdel*i; |
---|
158 | if((xtest - xt)/del >= 0) { |
---|
159 | x0 = graph_.getXUtoD(xt); |
---|
160 | g.drawLine(x0, y0, x0, y1); |
---|
161 | } |
---|
162 | } |
---|
163 | } |
---|
164 | // |
---|
165 | protected void drawSmallYTics(Graphics g,double xp,double yu,double ytest,double del) { |
---|
166 | int x0, x1, y0, i; |
---|
167 | double xp0, xp1, smdel, yt; |
---|
168 | if(numSmallTics_ <= 0) return; |
---|
169 | // xp = graph_.getXUtoP(xu); |
---|
170 | if(ticPosition_ == BOTH_SIDES || ticPosition_ == POSITIVE_SIDE) { |
---|
171 | xp0 = xp + smallTicHeight_; |
---|
172 | } else { |
---|
173 | xp0 = xp; |
---|
174 | } |
---|
175 | if(ticPosition_ == BOTH_SIDES || ticPosition_ == NEGATIVE_SIDE) { |
---|
176 | xp1 = xp - smallTicHeight_; |
---|
177 | } else { |
---|
178 | xp1 = xp; |
---|
179 | } |
---|
180 | x0 = graph_.getLayer().getXPtoD(xp0); |
---|
181 | x1 = graph_.getLayer().getXPtoD(xp1); |
---|
182 | smdel = del/(numSmallTics_ + 1); |
---|
183 | for(i=0; i <= numSmallTics_; i++) { |
---|
184 | yt = yu + smdel*i; |
---|
185 | if((ytest - yt)/del >= 0) { |
---|
186 | y0 = graph_.getYUtoD(yt); |
---|
187 | g.drawLine(x0, y0, x1, y0); |
---|
188 | } |
---|
189 | } |
---|
190 | } |
---|
191 | /** |
---|
192 | * Default constructor for SpaceAxis. |
---|
193 | **/ |
---|
194 | public SpaceAxis() { |
---|
195 | this(""); |
---|
196 | } |
---|
197 | /** |
---|
198 | * Constructor for Axis. Sets the axis identifier and initializes |
---|
199 | * the defaults. |
---|
200 | * |
---|
201 | * @param id axis identification |
---|
202 | **/ |
---|
203 | public SpaceAxis(String id) { |
---|
204 | super(id); |
---|
205 | space_ = true; |
---|
206 | numSmallTics_ = 0; |
---|
207 | } |
---|
208 | /** |
---|
209 | * Set the number of significant digits in the label. This is |
---|
210 | * used if a format is not specified. |
---|
211 | * |
---|
212 | * @param nsig number of significant digits |
---|
213 | **/ |
---|
214 | public void setSignificantDigits(int nsig) { |
---|
215 | if(sigDigits_ != nsig) { |
---|
216 | sigDigits_ = nsig; |
---|
217 | modified("SpaceAxis: setSignificantDigits()"); |
---|
218 | } |
---|
219 | } |
---|
220 | /** |
---|
221 | * Get the number of significant digits in the label. |
---|
222 | * |
---|
223 | * @return number of significant digits. |
---|
224 | **/ |
---|
225 | public int getSignificantDigits() { |
---|
226 | return sigDigits_; |
---|
227 | } |
---|
228 | /** |
---|
229 | * Set the label interval. |
---|
230 | * |
---|
231 | * @param lint label interval. |
---|
232 | **/ |
---|
233 | public void setLabelInterval(int lint) { |
---|
234 | if(labelInterval_ != lint) { |
---|
235 | labelInterval_ = lint; |
---|
236 | modified("SpaceAxis: setLabelInterval()"); |
---|
237 | } |
---|
238 | } |
---|
239 | /** |
---|
240 | * Get the label interval. |
---|
241 | * |
---|
242 | * @return label interval |
---|
243 | **/ |
---|
244 | public int getLabelInterval() { |
---|
245 | return labelInterval_; |
---|
246 | } |
---|
247 | /** |
---|
248 | * Set the label format. Format should be in the sprintf style. |
---|
249 | * The formating uses the Format class in the Core Java book. |
---|
250 | * A null or empty string will cause formating to use the significant |
---|
251 | * digits. |
---|
252 | * |
---|
253 | * <PRE> |
---|
254 | * Gary Cornell and Cay S. Horstmann, Core Java (Book/CD-ROM) |
---|
255 | * Published By SunSoft Press/Prentice-Hall |
---|
256 | * Copyright (C) 1996 Sun Microsystems Inc. |
---|
257 | * All Rights Reserved. ISBN 0-13-596891-7 |
---|
258 | * </PRE> |
---|
259 | * |
---|
260 | * @param frmt label format. |
---|
261 | **/ |
---|
262 | public void setLabelFormat(String frmt) { |
---|
263 | if(labelFormat_ == null || !labelFormat_.equals(frmt)) { |
---|
264 | if(frmt == null) { |
---|
265 | labelFormat_ = ""; |
---|
266 | } else { |
---|
267 | labelFormat_ = frmt; |
---|
268 | } |
---|
269 | modified("SpaceAxis: setLabelFormat()"); |
---|
270 | } |
---|
271 | } |
---|
272 | /** |
---|
273 | * Get the label format. |
---|
274 | * |
---|
275 | * @return label format |
---|
276 | **/ |
---|
277 | public String getLabelFormat() { |
---|
278 | return labelFormat_; |
---|
279 | } |
---|
280 | /** |
---|
281 | * Set the user range to draw the axis. Registered Axes and AxisTransforms |
---|
282 | * will be updated. |
---|
283 | * |
---|
284 | * @param ur range in user coordinates |
---|
285 | **/ |
---|
286 | public void setRangeU(Range2D ur) { |
---|
287 | if(uRange_ == null || !uRange_.equals(ur)) { |
---|
288 | uRange_ = ur; |
---|
289 | updateRegisteredAxes(); |
---|
290 | updateRegisteredTransforms(); |
---|
291 | modified("SpaceAxis: setRangeU()"); |
---|
292 | } |
---|
293 | } |
---|
294 | public void setRangeU(SoTRange ur) { |
---|
295 | setRangeU(new Range2D(((SoTRange.Double)ur).start, |
---|
296 | ((SoTRange.Double)ur).end, |
---|
297 | ((SoTRange.Double)ur).delta)); |
---|
298 | } |
---|
299 | /** |
---|
300 | * Get the user range. |
---|
301 | * |
---|
302 | * @return range in user coordinates |
---|
303 | **/ |
---|
304 | public Range2D getRangeU() { |
---|
305 | return uRange_; |
---|
306 | } |
---|
307 | public SoTRange getSoTRangeU() { |
---|
308 | return new SoTRange.Double(uRange_); |
---|
309 | } |
---|
310 | /** |
---|
311 | * Set the increment between large tics. |
---|
312 | * |
---|
313 | * @param delta increment in user coordinates |
---|
314 | **/ |
---|
315 | public void setDeltaU(double delta) { |
---|
316 | if(uRange_.delta != delta) { |
---|
317 | uRange_.delta = delta; |
---|
318 | modified("SpaceAxis: setDeltaU()"); |
---|
319 | } |
---|
320 | } |
---|
321 | /** |
---|
322 | * Get the increment between large tics. |
---|
323 | * |
---|
324 | * @return user coordinate increment |
---|
325 | **/ |
---|
326 | public double getDeltaU() { |
---|
327 | return uRange_.delta; |
---|
328 | } |
---|
329 | /** |
---|
330 | * Set the origin in user units of the axis. |
---|
331 | * |
---|
332 | * @param upt origin in user units |
---|
333 | **/ |
---|
334 | public void setLocationU(TimePoint uptt) { |
---|
335 | if(tLocation_ == null || !tLocation_.equals(uptt)) { |
---|
336 | tLocation_ = uptt; |
---|
337 | uLocation_ = null; |
---|
338 | modified("SpaceAxis: setLocationU(TimePoint)"); |
---|
339 | } |
---|
340 | } |
---|
341 | /** |
---|
342 | * Set the origin in user units of the axis. |
---|
343 | * |
---|
344 | * @param upt origin in user units |
---|
345 | **/ |
---|
346 | public void setLocationU(Point2D.Double upt) { |
---|
347 | if(uLocation_ == null || !uLocation_.equals(upt)) { |
---|
348 | uLocation_ = upt; |
---|
349 | tLocation_ = null; |
---|
350 | modified("SpaceAxis: setLocationU(Point2D)"); |
---|
351 | } |
---|
352 | } |
---|
353 | public void setLocationU(SoTPoint upt) { |
---|
354 | double x; |
---|
355 | double y; |
---|
356 | if(upt.isXTime() || upt.isYTime()) { |
---|
357 | long t; |
---|
358 | if(upt.isXTime()) { |
---|
359 | t = upt.getX().getLongTime(); |
---|
360 | x = ((SoTValue.Double)upt.getY()).getValue(); |
---|
361 | } else { |
---|
362 | t = upt.getY().getLongTime(); |
---|
363 | x = ((SoTValue.Double)upt.getX()).getValue(); |
---|
364 | } |
---|
365 | setLocationU(new TimePoint(x, new GeoDate(t))); |
---|
366 | } else { |
---|
367 | x = ((SoTValue.Double)upt.getX()).getValue(); |
---|
368 | y = ((SoTValue.Double)upt.getY()).getValue(); |
---|
369 | setLocationU(new Point2D.Double(x,y)); |
---|
370 | } |
---|
371 | } |
---|
372 | /** |
---|
373 | * Get the origin in user units of the axis |
---|
374 | * |
---|
375 | * @return origin |
---|
376 | **/ |
---|
377 | public Point2D.Double getLocationU() { |
---|
378 | return uLocation_; |
---|
379 | } |
---|
380 | /** |
---|
381 | * Get the origin in user units of the axis |
---|
382 | * |
---|
383 | * @return origin |
---|
384 | **/ |
---|
385 | public TimePoint getTimeLocationU() { |
---|
386 | return tLocation_; |
---|
387 | } |
---|
388 | public SoTPoint getSoTLocationU() { |
---|
389 | if(tLocation_ == null) { |
---|
390 | return new SoTPoint(uLocation_.x, uLocation_.y); |
---|
391 | } else { |
---|
392 | if(orientation_ == HORIZONTAL) { |
---|
393 | return new SoTPoint(tLocation_.t, tLocation_.x); |
---|
394 | } else { |
---|
395 | return new SoTPoint(tLocation_.x, tLocation_.t); |
---|
396 | } |
---|
397 | } |
---|
398 | } |
---|
399 | // |
---|
400 | abstract void draw(Graphics g); |
---|
401 | /** |
---|
402 | * Get the bounding box for the axis in device units. |
---|
403 | * |
---|
404 | * @return bounding box |
---|
405 | * @see Rectangle |
---|
406 | **/ |
---|
407 | public abstract Rectangle getBounds(); |
---|
408 | |
---|
409 | public void modified(String mess) { |
---|
410 | // if(Debug.EVENT) System.out.println("SpaceAxis: modified()"); |
---|
411 | if(graph_ != null) |
---|
412 | graph_.modified(mess); |
---|
413 | } |
---|
414 | } |
---|