1 | /* |
---|
2 | * $Id: DataGroupLayer.java,v 1.4 2003/09/17 20:32:10 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.beans; |
---|
14 | |
---|
15 | import java.util.List; |
---|
16 | import java.util.Vector; |
---|
17 | import java.util.Iterator; |
---|
18 | |
---|
19 | import java.awt.Dimension; |
---|
20 | import java.awt.Rectangle; |
---|
21 | import java.awt.Point; |
---|
22 | import java.awt.Graphics; |
---|
23 | |
---|
24 | import javax.swing.JOptionPane; |
---|
25 | |
---|
26 | import gov.noaa.pmel.sgt.Layer; |
---|
27 | import gov.noaa.pmel.sgt.Graph; |
---|
28 | import gov.noaa.pmel.sgt.CartesianGraph; |
---|
29 | import gov.noaa.pmel.sgt.AxisTransform; |
---|
30 | import gov.noaa.pmel.sgt.LinearTransform; |
---|
31 | import gov.noaa.pmel.sgt.LogTransform; |
---|
32 | import gov.noaa.pmel.sgt.Axis; |
---|
33 | import gov.noaa.pmel.sgt.PlainAxis; |
---|
34 | import gov.noaa.pmel.sgt.TimeAxis; |
---|
35 | import gov.noaa.pmel.sgt.LogAxis; |
---|
36 | import gov.noaa.pmel.sgt.AxisNotFoundException; |
---|
37 | import gov.noaa.pmel.sgt.Attribute; |
---|
38 | import gov.noaa.pmel.sgt.GridAttribute; |
---|
39 | import gov.noaa.pmel.sgt.SGLabel; |
---|
40 | import gov.noaa.pmel.sgt.dm.SGTData; |
---|
41 | import gov.noaa.pmel.sgt.dm.SGTGrid; |
---|
42 | import gov.noaa.pmel.sgt.CartesianRenderer; |
---|
43 | import gov.noaa.pmel.sgt.PaneNotFoundException; |
---|
44 | import gov.noaa.pmel.sgt.DataKey; |
---|
45 | import gov.noaa.pmel.sgt.ColorMap; |
---|
46 | import gov.noaa.pmel.sgt.TransformAccess; |
---|
47 | import gov.noaa.pmel.sgt.ContourLevelsAccess; |
---|
48 | import gov.noaa.pmel.sgt.ContourLevels; |
---|
49 | |
---|
50 | import gov.noaa.pmel.util.SoTPoint; |
---|
51 | import gov.noaa.pmel.util.SoTValue; |
---|
52 | import gov.noaa.pmel.util.SoTRange; |
---|
53 | import gov.noaa.pmel.util.SoTDomain; |
---|
54 | import gov.noaa.pmel.util.Range2D; |
---|
55 | import gov.noaa.pmel.util.Dimension2D; |
---|
56 | import gov.noaa.pmel.util.Point2D; |
---|
57 | import gov.noaa.pmel.util.Rectangle2D; |
---|
58 | |
---|
59 | /** |
---|
60 | * A holder for <code>DataGroup</code> and <code>Layer</code> associated with |
---|
61 | * axes and <code>Graph</code>. Multiple sets of data can be added to a DataGroupLayer, |
---|
62 | * but each will share the same <code>DataGroup</code>. I.e., the same axes and |
---|
63 | * transforms. |
---|
64 | * |
---|
65 | * @author Donald Denbo |
---|
66 | * @version $Revision: 1.4 $, $Date: 2003/09/17 20:32:10 $ |
---|
67 | * @since 3.0 |
---|
68 | * @see Page Page for UML diagram |
---|
69 | * @stereotype container |
---|
70 | **/ |
---|
71 | public class DataGroupLayer extends Layer { |
---|
72 | private List dataLayers_ = new Vector(); |
---|
73 | |
---|
74 | /** |
---|
75 | * @label dg |
---|
76 | */ |
---|
77 | private DataGroup dg_ = null; |
---|
78 | |
---|
79 | /** |
---|
80 | * @label pHolder |
---|
81 | */ |
---|
82 | private PanelHolder pHolder_ = null; |
---|
83 | private Panel panel_ = null; |
---|
84 | private SoTRange xRange_ = null; |
---|
85 | private SoTRange yRange_ = null; |
---|
86 | private boolean clipping_ = false; |
---|
87 | private SoTDomain clipDomain_ = null; |
---|
88 | // |
---|
89 | private SoTRange xZoomRange_ = null; |
---|
90 | private SoTRange yZoomRange_ = null; |
---|
91 | private boolean inZoom_ = false; |
---|
92 | // |
---|
93 | private SGLabel xLabel_ = null; |
---|
94 | private SGLabel yLabel_ = null; |
---|
95 | |
---|
96 | /** |
---|
97 | * Default constructor. <code>Panel</code> and <code>DataGroup</code> must |
---|
98 | * be specified. |
---|
99 | */ |
---|
100 | public DataGroupLayer() { |
---|
101 | this(null, null); |
---|
102 | } |
---|
103 | |
---|
104 | /** |
---|
105 | * Construct <code>DataGroupLayer</code>. |
---|
106 | * @param panel parent |
---|
107 | * @param dg datagroup |
---|
108 | */ |
---|
109 | public DataGroupLayer(Panel panel, DataGroup dg) { |
---|
110 | super(); |
---|
111 | panel_ = panel; |
---|
112 | setPane(panel.getPane()); |
---|
113 | pHolder_ = dg.getPanelHolder(); |
---|
114 | setGraph(new CartesianGraph("Graph")); |
---|
115 | dg_ = dg; |
---|
116 | setId(dg_.getId()); |
---|
117 | update(); |
---|
118 | } |
---|
119 | |
---|
120 | /** |
---|
121 | * Get the <code>Panel</code> parent. |
---|
122 | * @return panel |
---|
123 | */ |
---|
124 | public Panel getPanel() { |
---|
125 | return panel_; |
---|
126 | } |
---|
127 | |
---|
128 | /** |
---|
129 | * Get <code>DataGroup</code> |
---|
130 | * @return the datagroup |
---|
131 | */ |
---|
132 | public DataGroup getDataGroup() { |
---|
133 | return dg_; |
---|
134 | } |
---|
135 | |
---|
136 | /** |
---|
137 | * Get <code>Layer</code> <code>Iterator</code>. |
---|
138 | * @return iterator of Layers |
---|
139 | */ |
---|
140 | public Iterator getLayerIterator() { |
---|
141 | return dataLayers_.iterator(); |
---|
142 | } |
---|
143 | |
---|
144 | /** |
---|
145 | * Get a <code>List</code> of the <code>Layer</code>s. |
---|
146 | * @return layer list |
---|
147 | */ |
---|
148 | public List getLayerList() { |
---|
149 | return dataLayers_; |
---|
150 | } |
---|
151 | |
---|
152 | private String getNextLayerId() { |
---|
153 | int count = dataLayers_.size() + 1; |
---|
154 | return getId() + "_" + count; |
---|
155 | } |
---|
156 | |
---|
157 | /** |
---|
158 | * Add data to the <code>DataGroupLayer</code>. |
---|
159 | * @param data SGTData |
---|
160 | * @param attr Attribute associated with data |
---|
161 | * @param key DataKey |
---|
162 | * @throws DataTargetMismatchException |
---|
163 | */ |
---|
164 | public void addData(SGTData data, Attribute attr, DataKey key) throws DataTargetMismatchException { |
---|
165 | if(Page.DEBUG) { |
---|
166 | System.out.println("DataGroupLayer.addData: data = " + data.toString()); |
---|
167 | System.out.println("DataGroupLayer.addData: xTime = " + data.isXTime() + ", yTime = " + data.isYTime()); |
---|
168 | System.out.println("DataGroupLayer.addData: attr = " + attr.toString()); |
---|
169 | System.out.println("DataGroupLayer.addData: key = " + key); |
---|
170 | System.out.println("DataGroupLayer.addData: xRange = " + data.getXRange()); |
---|
171 | System.out.println("DataGroupLayer.addData: yRange = " + data.getYRange()); |
---|
172 | if(data instanceof SGTGrid) |
---|
173 | System.out.println("DataGroupLayer.addData: zRange = " + ((SGTGrid)data).getZRange()); |
---|
174 | else |
---|
175 | System.out.println("DataGroupLayer.addData: zRange = <no zRange>"); |
---|
176 | } |
---|
177 | /** @todo add data check */ |
---|
178 | CartesianGraph graph = (CartesianGraph)getGraph(); |
---|
179 | if((graph.getXTransform().isTime() != data.isXTime()) || |
---|
180 | graph.getYTransform().isTime() != data.isYTime()) { |
---|
181 | JOptionPane.showMessageDialog(this, "Added data does not have the\n" + |
---|
182 | "same axis types as the DataGroup\n\n" + |
---|
183 | "Time or Space axis does not match.", |
---|
184 | "DataGroup Error", JOptionPane.ERROR_MESSAGE); |
---|
185 | throw new DataTargetMismatchException("Data - Axis Mismatch"); |
---|
186 | } |
---|
187 | |
---|
188 | CartesianRenderer rend = graph.getRenderer(); |
---|
189 | if(rend == null) { // first data on DataGroupLayer |
---|
190 | xRange_ = data.getXRange(); |
---|
191 | yRange_ = data.getYRange(); |
---|
192 | graph.setData(data, attr); |
---|
193 | dataLayers_.add(this); |
---|
194 | |
---|
195 | StringBuffer label = new StringBuffer(data.getXMetaData().getName()); |
---|
196 | String units = data.getXMetaData().getUnits(); |
---|
197 | if(units != null && units.length() > 0) { |
---|
198 | label.append(" (").append(units).append(")"); |
---|
199 | } |
---|
200 | xLabel_ = new SGLabel("X Axis Label", label.toString(), new Point2D.Double(0.0, 0.0)); |
---|
201 | |
---|
202 | label = new StringBuffer(data.getYMetaData().getName()); |
---|
203 | units = data.getYMetaData().getUnits(); |
---|
204 | if(units != null && units.length() > 0) { |
---|
205 | label.append(" (").append(units).append(")"); |
---|
206 | } |
---|
207 | yLabel_ = new SGLabel("Y Axis Label", label.toString(), new Point2D.Double(0.0, 0.0)); |
---|
208 | } else { // adding data to DataGroupLayer |
---|
209 | xRange_.add(data.getXRange()); |
---|
210 | yRange_.add(data.getYRange()); |
---|
211 | // more data, create new layer |
---|
212 | Layer ly = new Layer(getNextLayerId()); |
---|
213 | CartesianGraph cg = new CartesianGraph("Graph_"+ly.getId(), |
---|
214 | graph.getXTransform(), graph.getYTransform()); |
---|
215 | ly.setPane(getPane()); |
---|
216 | ly.setSizeP(getSizeP()); |
---|
217 | ly.setBounds(getBounds()); |
---|
218 | ly.setGraph(cg); |
---|
219 | cg.setData(data, attr); |
---|
220 | dataLayers_.add(ly); |
---|
221 | if(clipping_) cg.setClip(clipDomain_.getXRange(), clipDomain_.getYRange()); |
---|
222 | graph = cg; |
---|
223 | } |
---|
224 | |
---|
225 | if(dg_.isZAutoScale() && attr != null && attr instanceof GridAttribute) { |
---|
226 | Range2D zRange = ((SGTGrid)data).getZRange(); |
---|
227 | ColorMap cmap = ((GridAttribute)attr).getColorMap(); |
---|
228 | if(cmap instanceof TransformAccess) { |
---|
229 | ((TransformAccess)cmap).setRange(zRange); |
---|
230 | } else if(cmap instanceof ContourLevelsAccess) { |
---|
231 | ContourLevels cl = ((ContourLevelsAccess)cmap).getContourLevels(); |
---|
232 | int levels = dg_.getNumberAutoContourLevels(); |
---|
233 | Range2D newRange = Graph.computeRange(zRange, levels); |
---|
234 | ((ContourLevelsAccess)cmap).setContourLevels(ContourLevels.getDefault(newRange)); |
---|
235 | } |
---|
236 | } |
---|
237 | |
---|
238 | if(key != null) { |
---|
239 | rend = graph.getRenderer(); |
---|
240 | SGLabel label = getLabel(data, key); |
---|
241 | key.addGraph(rend, label); |
---|
242 | } |
---|
243 | update(); |
---|
244 | } |
---|
245 | |
---|
246 | private SGLabel getLabel(SGTData data, DataKey key) { |
---|
247 | SGLabel lineTitle = data.getKeyTitle(); |
---|
248 | if(lineTitle == null) { |
---|
249 | lineTitle = xLabel_; |
---|
250 | } |
---|
251 | Legend lg = pHolder_.findLegend(key.getId()); |
---|
252 | lineTitle.setHeightP(lg.getKeyLabelHeightP()); |
---|
253 | return lineTitle; |
---|
254 | } |
---|
255 | |
---|
256 | /** |
---|
257 | * Update <code>DataGroupLayer</code>. Used internally. |
---|
258 | */ |
---|
259 | public void update() { |
---|
260 | Rectangle bnds = pHolder_.getBounds(); |
---|
261 | double dpi = pHolder_.getPanelModel().getDpi(); |
---|
262 | double width = bnds.width/dpi; |
---|
263 | double height = bnds.height/dpi; |
---|
264 | SoTRange xRange = null; |
---|
265 | SoTRange yRange = null; |
---|
266 | SoTPoint xOrig = null; |
---|
267 | SoTPoint yOrig = null; |
---|
268 | |
---|
269 | boolean batch = getPane().isBatch(); |
---|
270 | getPane().setBatch(true); |
---|
271 | |
---|
272 | AxisHolder xAxHolder = dg_.getXAxisHolder(); |
---|
273 | AxisHolder yAxHolder = dg_.getYAxisHolder(); |
---|
274 | CartesianGraph gr = (CartesianGraph)getGraph(); |
---|
275 | |
---|
276 | this.setSizeP(new Dimension2D(width, height)); |
---|
277 | // determine correct range |
---|
278 | if(inZoom_) { |
---|
279 | xRange = xZoomRange_; |
---|
280 | yRange = yZoomRange_; |
---|
281 | } else { |
---|
282 | if(!xAxHolder.isAutoRange() || xRange_ == null) { |
---|
283 | xRange = xAxHolder.getUserRange(); |
---|
284 | } else { |
---|
285 | xRange = xRange_; |
---|
286 | } |
---|
287 | if(!yAxHolder.isAutoRange() || yRange_ == null) { |
---|
288 | yRange = yAxHolder.getUserRange(); |
---|
289 | } else { |
---|
290 | yRange = yRange_; |
---|
291 | } |
---|
292 | } |
---|
293 | // transform setup |
---|
294 | updateTransform(DataGroup.X_DIR, xRange); |
---|
295 | updateTransform(DataGroup.Y_DIR, yRange); |
---|
296 | // determine axes origins |
---|
297 | // xaxis |
---|
298 | Margin marg = dg_.getMargin(); |
---|
299 | if(xAxHolder.getAxisPosition() == DataGroup.MANUAL) { |
---|
300 | xOrig = new SoTPoint(gr.getXPtoSoT(xAxHolder.getAxisOriginP().x), |
---|
301 | gr.getYPtoSoT(xAxHolder.getAxisOriginP().y)); |
---|
302 | } else { |
---|
303 | SoTValue yloc = null; |
---|
304 | SoTRange range = null; |
---|
305 | if(yAxHolder.getAxisPosition() == DataGroup.MANUAL) { |
---|
306 | if(gr.getYTransform().isTime()) { |
---|
307 | range = new SoTRange.Time(gr.getYPtoLongTime(marg.bottom), |
---|
308 | gr.getYPtoLongTime(marg.top)); |
---|
309 | } else { |
---|
310 | range = new SoTRange.Double(gr.getYPtoU(marg.bottom), gr.getYPtoU(marg.top)); |
---|
311 | } |
---|
312 | } else { |
---|
313 | range = yRange; |
---|
314 | } |
---|
315 | switch(xAxHolder.getAxisPosition()) { |
---|
316 | case DataGroup.BOTTOM: |
---|
317 | yloc = range.getStart(); |
---|
318 | break; |
---|
319 | case DataGroup.TOP: |
---|
320 | yloc = range.getEnd(); |
---|
321 | break; |
---|
322 | } |
---|
323 | xOrig = new SoTPoint(xRange.getStart(), yloc); |
---|
324 | } |
---|
325 | // yaxis |
---|
326 | if(yAxHolder.getAxisPosition() == DataGroup.MANUAL) { |
---|
327 | yOrig = new SoTPoint(gr.getXPtoSoT(yAxHolder.getAxisOriginP().x), |
---|
328 | gr.getYPtoSoT(yAxHolder.getAxisOriginP().y)); |
---|
329 | } else { |
---|
330 | SoTValue xloc = null; |
---|
331 | SoTRange range = null; |
---|
332 | if(xAxHolder.getAxisPosition() == DataGroup.MANUAL) { |
---|
333 | if(gr.getXTransform().isTime()) { |
---|
334 | range = new SoTRange.Time(gr.getXPtoLongTime(marg.left), |
---|
335 | gr.getXPtoLongTime(marg.right)); |
---|
336 | } else { |
---|
337 | range = new SoTRange.Double(gr.getXPtoU(marg.left), gr.getXPtoU(marg.right)); |
---|
338 | } |
---|
339 | } else { |
---|
340 | range = xRange; |
---|
341 | } |
---|
342 | switch(yAxHolder.getAxisPosition()) { |
---|
343 | case DataGroup.LEFT: |
---|
344 | xloc = range.getStart(); |
---|
345 | break; |
---|
346 | case DataGroup.RIGHT: |
---|
347 | xloc = range.getEnd(); |
---|
348 | break; |
---|
349 | } |
---|
350 | yOrig = new SoTPoint(xloc, yRange.getStart()); |
---|
351 | } |
---|
352 | |
---|
353 | updateAxis(DataGroup.X_DIR, xRange, xOrig, xLabel_); |
---|
354 | updateAxis(DataGroup.Y_DIR, yRange, yOrig, yLabel_); |
---|
355 | |
---|
356 | getPane().setBatch(batch); |
---|
357 | |
---|
358 | if(Page.DEBUG) { |
---|
359 | System.out.println("layer: " + getSize() + ", " + getSizeP()); |
---|
360 | System.out.println("xTrans: " + gr.getXTransform().getRangeP() + ", " + |
---|
361 | gr.getXTransform().getSoTRangeU()); |
---|
362 | System.out.println("yTrans: " + gr.getYTransform().getRangeP() + ", " + |
---|
363 | gr.getYTransform().getSoTRangeU()); |
---|
364 | } |
---|
365 | } |
---|
366 | |
---|
367 | private void updateTransform(int dir, SoTRange range) { |
---|
368 | AxisTransform at; |
---|
369 | AxisHolder ah; |
---|
370 | CartesianGraph gr = (CartesianGraph)getGraph(); |
---|
371 | |
---|
372 | if(dir == DataGroup.X_DIR) { |
---|
373 | ah = dg_.getXAxisHolder(); |
---|
374 | at = gr.getXTransform(); |
---|
375 | } else { |
---|
376 | ah = dg_.getYAxisHolder(); |
---|
377 | at = gr.getYTransform(); |
---|
378 | } |
---|
379 | |
---|
380 | switch(ah.getTransformType()) { |
---|
381 | case DataGroup.LINEAR: |
---|
382 | if(at instanceof LinearTransform) { |
---|
383 | at.setRangeU(range); |
---|
384 | at.setRangeP(ah.getRangeP()); |
---|
385 | } else { |
---|
386 | at = new LinearTransform(ah.getRangeP(), range); |
---|
387 | gr.setXTransform(at); |
---|
388 | } |
---|
389 | break; |
---|
390 | case DataGroup.LOG: |
---|
391 | if(at instanceof LogTransform) { |
---|
392 | at.setRangeU(range); |
---|
393 | at.setRangeP(ah.getRangeP()); |
---|
394 | } else { |
---|
395 | at = new LogTransform(ah.getRangeP(), range); |
---|
396 | gr.setXTransform(at); |
---|
397 | } |
---|
398 | break; |
---|
399 | case DataGroup.REFERENCE: |
---|
400 | at = getReferenceTransform(DataGroup.X_DIR, ah.getTransformGroup()); |
---|
401 | gr.setXTransform(at); |
---|
402 | } |
---|
403 | } |
---|
404 | |
---|
405 | private void updateAxis(int dir, SoTRange range, |
---|
406 | SoTPoint origin, SGLabel title) { |
---|
407 | String axis; |
---|
408 | Axis ax = null; |
---|
409 | AxisTransform at; |
---|
410 | AxisHolder ah; |
---|
411 | boolean newAxis = true; |
---|
412 | CartesianGraph gr = (CartesianGraph)getGraph(); |
---|
413 | |
---|
414 | if(dir == DataGroup.X_DIR) { |
---|
415 | axis = "X Axis"; |
---|
416 | ah = dg_.getXAxisHolder(); |
---|
417 | at = gr.getXTransform(); |
---|
418 | } else { |
---|
419 | axis = "Y Axis"; |
---|
420 | ah = dg_.getYAxisHolder(); |
---|
421 | at = gr.getYTransform(); |
---|
422 | } |
---|
423 | |
---|
424 | try { |
---|
425 | ax = gr.getXAxis(axis); |
---|
426 | } catch (AxisNotFoundException anfe) { |
---|
427 | ax = null; |
---|
428 | } |
---|
429 | newAxis = false; |
---|
430 | switch(ah.getAxisType()) { |
---|
431 | case DataGroup.PLAIN: |
---|
432 | PlainAxis pax = null; |
---|
433 | if(ax != null) { |
---|
434 | if(ax instanceof PlainAxis) { |
---|
435 | pax = (PlainAxis)ax; |
---|
436 | } else { |
---|
437 | pax = new PlainAxis(axis); |
---|
438 | newAxis = true; |
---|
439 | } |
---|
440 | } else { |
---|
441 | pax = new PlainAxis(axis); |
---|
442 | newAxis = true; |
---|
443 | } |
---|
444 | ax = pax; |
---|
445 | pax.setRangeP(ah.getRangeP()); |
---|
446 | pax.setRangeU(range); |
---|
447 | pax.setLabelFormat(ah.getLabelFormat()); |
---|
448 | pax.setLabelInterval(ah.getLabelInterval()); |
---|
449 | pax.setSignificantDigits(ah.getLabelSignificantDigits()); |
---|
450 | break; |
---|
451 | case DataGroup.TIME: |
---|
452 | TimeAxis tax = null; |
---|
453 | if(ax != null) { |
---|
454 | if(ax instanceof TimeAxis) { |
---|
455 | tax = (TimeAxis)ax; |
---|
456 | } else { |
---|
457 | tax = new TimeAxis(axis, ah.getTimeAxisStyle()); |
---|
458 | newAxis = true; |
---|
459 | } |
---|
460 | } else { |
---|
461 | tax = new TimeAxis(axis, ah.getTimeAxisStyle()); |
---|
462 | newAxis = true; |
---|
463 | } |
---|
464 | ax = tax; |
---|
465 | tax.setRangeP(ah.getRangeP()); |
---|
466 | tax.setRangeU(range); |
---|
467 | if(ah.getTimeAxisStyle() != TimeAxis.AUTO) { |
---|
468 | tax.setLabelFormat(ah.getMinorFormat(), |
---|
469 | ah.getMajorFormat()); |
---|
470 | tax.setLabelInterval(ah.getMinorInterval(), |
---|
471 | ah.getMajorInterval()); |
---|
472 | } |
---|
473 | break; |
---|
474 | case DataGroup.LOG: |
---|
475 | LogAxis lax = null; |
---|
476 | if(ax != null) { |
---|
477 | if(ax instanceof LogAxis) { |
---|
478 | lax = (LogAxis)ax; |
---|
479 | } else { |
---|
480 | lax = new LogAxis(axis); |
---|
481 | newAxis = true; |
---|
482 | } |
---|
483 | } else { |
---|
484 | lax = new LogAxis(axis); |
---|
485 | newAxis = true; |
---|
486 | } |
---|
487 | ax = lax; |
---|
488 | lax.setRangeP(ah.getRangeP()); |
---|
489 | lax.setRangeU(range); |
---|
490 | lax.setLabelFormat(ah.getLabelFormat()); |
---|
491 | lax.setLabelInterval(ah.getLabelInterval()); |
---|
492 | lax.setSignificantDigits(ah.getLabelSignificantDigits()); |
---|
493 | } |
---|
494 | if(dir == DataGroup.X_DIR) { |
---|
495 | ax.setOrientation(Axis.HORIZONTAL); |
---|
496 | } else { |
---|
497 | ax.setOrientation(Axis.VERTICAL); |
---|
498 | } |
---|
499 | ax.setLocationU(origin); |
---|
500 | ax.setLineColor(ah.getAxisColor()); |
---|
501 | ax.setTicPosition(ah.getTicPosition()); |
---|
502 | ax.setLabelColor(ah.getLabelColor()); |
---|
503 | ax.setLabelFont(ah.getLabelFont()); |
---|
504 | ax.setLabelHeightP(ah.getLabelHeightP()); |
---|
505 | ax.setLargeTicHeightP(ah.getLargeTicHeightP()); |
---|
506 | ax.setNumberSmallTics(ah.getNumSmallTics()); |
---|
507 | ax.setSmallTicHeightP(ah.getSmallTicHeightP()); |
---|
508 | ax.setThickTicWidthP(ah.getThickTicWidth()); |
---|
509 | ax.setLabelPosition(ah.getLabelPosition()); |
---|
510 | ax.setVisible(ah.isVisible()); |
---|
511 | if(title != null && ah.isTitleAuto()) { |
---|
512 | SGLabel def = ah.getTitle(); |
---|
513 | title.setColor(def.getColor()); |
---|
514 | title.setFont(def.getFont()); |
---|
515 | title.setHeightP(def.getHeightP()); |
---|
516 | title.setVisible(def.isVisible()); |
---|
517 | ax.setTitle(title); |
---|
518 | } else { |
---|
519 | ax.setTitle(ah.getTitle()); |
---|
520 | } |
---|
521 | ax.register(at); |
---|
522 | if(dir == DataGroup.X_DIR) { |
---|
523 | if(gr.getNumberXAxis() > 0 && newAxis) { |
---|
524 | gr.removeAllXAxes(); |
---|
525 | } |
---|
526 | if(newAxis) gr.addXAxis(ax); |
---|
527 | } else { |
---|
528 | if(gr.getNumberYAxis() > 0 && newAxis) { |
---|
529 | gr.removeAllYAxes(); |
---|
530 | } |
---|
531 | if(newAxis) gr.addYAxis(ax); |
---|
532 | } |
---|
533 | } |
---|
534 | |
---|
535 | // |
---|
536 | // replicate Layer methods and pass on to |
---|
537 | // all children Layer's |
---|
538 | // |
---|
539 | public void draw(Graphics g) throws PaneNotFoundException { |
---|
540 | super.draw(g); |
---|
541 | for(int i=1; i < dataLayers_.size(); i++) { |
---|
542 | ((Layer)dataLayers_.get(i)).draw(g); |
---|
543 | } |
---|
544 | } |
---|
545 | |
---|
546 | public void drawDraggableItems(Graphics g) throws PaneNotFoundException { |
---|
547 | super.drawDraggableItems(g); |
---|
548 | for(int i=1; i < dataLayers_.size(); i++) { |
---|
549 | ((Layer)dataLayers_.get(i)).drawDraggableItems(g); |
---|
550 | } |
---|
551 | } |
---|
552 | |
---|
553 | public void setBounds(int x, int y, int w, int h) { |
---|
554 | super.setBounds(x, y, w, h); |
---|
555 | for(int i=1; i < dataLayers_.size(); i++) { |
---|
556 | ((Layer)dataLayers_.get(i)).setBounds(x, y, w, h); |
---|
557 | } |
---|
558 | } |
---|
559 | |
---|
560 | public void setBounds(Rectangle rect) { |
---|
561 | super.setBounds(rect); |
---|
562 | for(int i=1; i < dataLayers_.size(); i++) { |
---|
563 | ((Layer)dataLayers_.get(i)).setBounds(rect); |
---|
564 | } |
---|
565 | } |
---|
566 | |
---|
567 | public void setLocation(int x, int y) { |
---|
568 | super.setLocation(x, y); |
---|
569 | for(int i=1; i < dataLayers_.size(); i++) { |
---|
570 | ((Layer)dataLayers_.get(i)).setLocation(x, y); |
---|
571 | } |
---|
572 | } |
---|
573 | |
---|
574 | public void setLocation(Point pt) { |
---|
575 | super.setLocation(pt); |
---|
576 | for(int i=1; i < dataLayers_.size(); i++) { |
---|
577 | ((Layer)dataLayers_.get(i)).setLocation(pt); |
---|
578 | } |
---|
579 | } |
---|
580 | |
---|
581 | public void setSize(Dimension size) { |
---|
582 | super.setSize(size); |
---|
583 | for(int i=1; i < dataLayers_.size(); i++) { |
---|
584 | ((Layer)dataLayers_.get(i)).setSize(size); |
---|
585 | } |
---|
586 | } |
---|
587 | |
---|
588 | public void setSize(int w, int h) { |
---|
589 | super.setSize(w, h); |
---|
590 | for(int i=1; i < dataLayers_.size(); i++) { |
---|
591 | ((Layer)dataLayers_.get(i)).setSize(w, h); |
---|
592 | } |
---|
593 | } |
---|
594 | |
---|
595 | public void setSizeP(Dimension2D size) { |
---|
596 | super.setSizeP(size); |
---|
597 | for(int i=1; i < dataLayers_.size(); i++) { |
---|
598 | ((Layer)dataLayers_.get(i)).setSizeP(size); |
---|
599 | } |
---|
600 | } |
---|
601 | |
---|
602 | private AxisTransform getReferenceTransform(int dir, String datagroup) { |
---|
603 | // PanelHolder ph = dg_.getPanelHolder(); |
---|
604 | String dgLast = datagroup; |
---|
605 | boolean stillLooking = true; |
---|
606 | int tType = -1; |
---|
607 | String newDG = null; |
---|
608 | while(stillLooking) { |
---|
609 | DataGroup dg = pHolder_.findDataGroup(dgLast); |
---|
610 | if(dir == DataGroup.X_DIR) { |
---|
611 | tType = dg.getXAxisHolder().getTransformType(); |
---|
612 | } else { |
---|
613 | tType = dg.getYAxisHolder().getTransformType(); |
---|
614 | } |
---|
615 | if(tType != DataGroup.REFERENCE) { |
---|
616 | CartesianGraph graph = null; |
---|
617 | Layer dgl = null; |
---|
618 | /** @todo resolve instatiation order issue */ |
---|
619 | if(dir == DataGroup.X_DIR) { |
---|
620 | dgl = panel_.findDataGroupLayer(dg.getXAxisHolder().getTransformGroup()); |
---|
621 | graph = (CartesianGraph)dgl.getGraph(); |
---|
622 | if(graph == null) return null; // graph and transform not yet created |
---|
623 | return graph.getXTransform(); |
---|
624 | } else { |
---|
625 | dgl = panel_.findDataGroupLayer(dg.getYAxisHolder().getTransformGroup()); |
---|
626 | graph = (CartesianGraph)dgl.getGraph(); |
---|
627 | if(graph == null) return null; |
---|
628 | return graph.getYTransform(); |
---|
629 | } |
---|
630 | } |
---|
631 | if(dir == DataGroup.X_DIR) { |
---|
632 | newDG = dg.getXAxisHolder().getTransformGroup(); |
---|
633 | } else { |
---|
634 | newDG = dg.getYAxisHolder().getTransformGroup(); |
---|
635 | } |
---|
636 | dgLast = newDG; |
---|
637 | } |
---|
638 | return null; |
---|
639 | } |
---|
640 | |
---|
641 | /** |
---|
642 | * Set clipping for <code>DataGroupLayer</code> |
---|
643 | * @param clip if true clip data to bounds. |
---|
644 | */ |
---|
645 | public void setClipping(boolean clip) { |
---|
646 | if(!dg_.isZoomable()) return; |
---|
647 | if(Page.DEBUG) System.out.println("DataGroupLayer: " + getId() + ": clip = " + clip); |
---|
648 | clipping_ = clip; |
---|
649 | setAllClipping(clipping_); |
---|
650 | } |
---|
651 | |
---|
652 | /** |
---|
653 | * Zoom <code>DataGroupLayer</code>. Zoom to <code>Rectangle</code> if zoom |
---|
654 | * operation started within bounds. |
---|
655 | * @param start start point |
---|
656 | * @param rect zoom rectangle |
---|
657 | */ |
---|
658 | void zoomTo(Point start, Rectangle rect) { |
---|
659 | if(!dg_.isZoomable()) return; |
---|
660 | CartesianGraph graph = (CartesianGraph)getGraph(); |
---|
661 | Rectangle gbnds = getGraphBounds(); |
---|
662 | Rectangle bnds = getPanelBounds(); |
---|
663 | if(!gbnds.contains(start)) return; |
---|
664 | setClipping(true); |
---|
665 | double xStartP = getXDtoP(rect.x); |
---|
666 | double yStartP = getYDtoP(rect.y + rect.height); |
---|
667 | double xEndP = getXDtoP(rect.x + rect.width); |
---|
668 | double yEndP = getYDtoP(rect.y); |
---|
669 | SoTRange xRangeU = null; |
---|
670 | SoTRange yRangeU = null; |
---|
671 | if(graph.getXTransform().isTime()) { |
---|
672 | xRangeU = new SoTRange.Time(graph.getXPtoLongTime(xStartP), graph.getXPtoLongTime(xEndP)); |
---|
673 | } else { |
---|
674 | xRangeU = new SoTRange.Double(graph.getXPtoU(xStartP), graph.getXPtoU(xEndP)); |
---|
675 | } |
---|
676 | if(graph.getYTransform().isTime()) { |
---|
677 | yRangeU = new SoTRange.Time(graph.getYPtoLongTime(yStartP), graph.getYPtoLongTime(yEndP)); |
---|
678 | } else { |
---|
679 | yRangeU = new SoTRange.Double(graph.getYPtoU(yStartP), graph.getYPtoU(yEndP)); |
---|
680 | } |
---|
681 | inZoom_ = true; |
---|
682 | setDomain(new SoTDomain(xRangeU, yRangeU)); |
---|
683 | } |
---|
684 | |
---|
685 | /** |
---|
686 | * Reset the zoom for this <code>DataGroupLayer</code> if it contains the point. |
---|
687 | * @param x x device coordinate |
---|
688 | * @param y y device coordinate |
---|
689 | */ |
---|
690 | void resetZoom(int x, int y) { |
---|
691 | if(!dg_.isZoomable()) return; |
---|
692 | Rectangle bnds = getGraphBounds(); |
---|
693 | if(!bnds.contains(x, y)) return; |
---|
694 | if(Page.DEBUG) System.out.println("DataGroupLayer: " + getId() + ": " + x +", " + y); |
---|
695 | inZoom_ = false; |
---|
696 | xZoomRange_ = null; |
---|
697 | yZoomRange_ = null; |
---|
698 | setClipping(false); |
---|
699 | update(); |
---|
700 | } |
---|
701 | /** |
---|
702 | * Reset the zoom for this <code>DataGroupLayer</code>. |
---|
703 | */ |
---|
704 | public void resetZoom() { |
---|
705 | inZoom_ = false; |
---|
706 | xZoomRange_ = null; |
---|
707 | yZoomRange_ = null; |
---|
708 | setClipping(false); |
---|
709 | update(); |
---|
710 | } |
---|
711 | |
---|
712 | /** |
---|
713 | * Set <code>DataGroupLayer</code> domain. |
---|
714 | * @param domain domain |
---|
715 | */ |
---|
716 | public void setDomain(SoTDomain domain) { |
---|
717 | setXRange(domain.getXRange(), domain.isXReversed()); |
---|
718 | setYRange(domain.getYRange(), domain.isYReversed()); |
---|
719 | if(clipping_) { |
---|
720 | clipDomain_ = domain; |
---|
721 | setAllClip(domain); |
---|
722 | } else { |
---|
723 | clipDomain_ = null; |
---|
724 | setAllClipping(false); |
---|
725 | } |
---|
726 | update(); |
---|
727 | if(Page.DEBUG) { |
---|
728 | System.out.println("DataGroupLayer().setDomain: " + getId()); |
---|
729 | System.out.println(" domain.XRange = " + domain.getXRange()); |
---|
730 | System.out.println(" domain.YRange = " + domain.getYRange()); |
---|
731 | System.out.println(" isClipping = " + clipping_); |
---|
732 | } |
---|
733 | } |
---|
734 | |
---|
735 | private void setXRange(SoTRange range, boolean reversed) { |
---|
736 | xZoomRange_ = range.copy(); |
---|
737 | } |
---|
738 | |
---|
739 | private void setYRange(SoTRange range, boolean reversed) { |
---|
740 | yZoomRange_ = range.copy(); |
---|
741 | } |
---|
742 | |
---|
743 | private void setAllClip(SoTDomain domain) { |
---|
744 | Iterator iter = dataLayers_.iterator(); |
---|
745 | while(iter.hasNext()) { |
---|
746 | Object obj = iter.next(); |
---|
747 | if(obj instanceof Layer) { |
---|
748 | Layer ly = (Layer)obj; |
---|
749 | ((CartesianGraph)ly.getGraph()).setClip(domain.getXRange(), |
---|
750 | domain.getYRange()); |
---|
751 | } |
---|
752 | } |
---|
753 | } |
---|
754 | |
---|
755 | private void setAllClipping(boolean clip) { |
---|
756 | Iterator iter = dataLayers_.iterator(); |
---|
757 | while(iter.hasNext()) { |
---|
758 | Object obj = iter.next(); |
---|
759 | if(obj instanceof Layer) { |
---|
760 | Layer ly = (Layer)obj; |
---|
761 | ((CartesianGraph)ly.getGraph()).setClipping(clip); |
---|
762 | } |
---|
763 | } |
---|
764 | } |
---|
765 | |
---|
766 | private Rectangle getPanelBounds() { |
---|
767 | return pHolder_.getBounds(); |
---|
768 | } |
---|
769 | |
---|
770 | private Rectangle getGraphBounds() { |
---|
771 | CartesianGraph graph = (CartesianGraph)getGraph(); |
---|
772 | AxisTransform xTrans = graph.getXTransform(); |
---|
773 | AxisTransform yTrans = graph.getYTransform(); |
---|
774 | Range2D xRange = xTrans.getRangeP(); |
---|
775 | Range2D yRange = yTrans.getRangeP(); |
---|
776 | int x = getXPtoD(xRange.start); |
---|
777 | int y = getYPtoD(yRange.end); |
---|
778 | int width = getXPtoD(xRange.end) - x; |
---|
779 | int height = getYPtoD(yRange.start) - y; |
---|
780 | return new Rectangle(x, y, width, height); |
---|
781 | } |
---|
782 | } |
---|