1 | /* |
---|
2 | * $Id: JLineProfileLayout.java,v 1.8 2003/08/22 23:02:39 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.swing; |
---|
14 | |
---|
15 | import gov.noaa.pmel.sgt.LineKey; |
---|
16 | import gov.noaa.pmel.sgt.Layer; |
---|
17 | import gov.noaa.pmel.sgt.CartesianGraph; |
---|
18 | import gov.noaa.pmel.sgt.LineCartesianRenderer; |
---|
19 | import gov.noaa.pmel.sgt.LinearTransform; |
---|
20 | import gov.noaa.pmel.sgt.PlainAxis; |
---|
21 | import gov.noaa.pmel.sgt.JPane; |
---|
22 | import gov.noaa.pmel.sgt.Logo; |
---|
23 | import gov.noaa.pmel.sgt.SGLabel; |
---|
24 | import gov.noaa.pmel.sgt.LayerNotFoundException; |
---|
25 | import gov.noaa.pmel.sgt.LineAttribute; |
---|
26 | import gov.noaa.pmel.sgt.Graph; |
---|
27 | import gov.noaa.pmel.sgt.AxisNotFoundException; |
---|
28 | import gov.noaa.pmel.sgt.CartesianGraph; |
---|
29 | import gov.noaa.pmel.sgt.SGException; |
---|
30 | import gov.noaa.pmel.sgt.StackedLayout; |
---|
31 | |
---|
32 | import gov.noaa.pmel.util.Domain; |
---|
33 | import gov.noaa.pmel.util.Dimension2D; |
---|
34 | import gov.noaa.pmel.util.Rectangle2D; |
---|
35 | import gov.noaa.pmel.util.Point2D; |
---|
36 | import gov.noaa.pmel.util.Range2D; |
---|
37 | //import gov.noaa.pmel.util.TimeRange; |
---|
38 | import gov.noaa.pmel.util.Units; |
---|
39 | |
---|
40 | import gov.noaa.pmel.sgt.dm.SGTData; |
---|
41 | import gov.noaa.pmel.sgt.dm.SGTLine; |
---|
42 | import gov.noaa.pmel.sgt.dm.SimpleLine; |
---|
43 | import gov.noaa.pmel.sgt.dm.SGTMetaData; |
---|
44 | import gov.noaa.pmel.sgt.dm.Collection; |
---|
45 | |
---|
46 | |
---|
47 | import java.util.Enumeration; |
---|
48 | import java.util.Vector; |
---|
49 | import java.awt.Dimension; |
---|
50 | import java.awt.Font; |
---|
51 | import java.awt.Color; |
---|
52 | import java.awt.Image; |
---|
53 | import java.awt.Rectangle; |
---|
54 | import java.awt.Component; |
---|
55 | |
---|
56 | import java.beans.PropertyVetoException; |
---|
57 | |
---|
58 | /** |
---|
59 | * JLineProfileLayout creates a pre-defined graphics layout for |
---|
60 | * profile data using LineCartesianGraph. This layout is application specific. |
---|
61 | * |
---|
62 | * @author Donald Denbo |
---|
63 | * @version $Revision: 1.8 $, $Date: 2003/08/22 23:02:39 $ |
---|
64 | * @see LineCartesianRenderer |
---|
65 | * @deprecated As of v2.0, replaced by {@link gov.noaa.pmel.sgt.swing.JPlotLayout} |
---|
66 | **/ |
---|
67 | /*oodE***********************************************/ |
---|
68 | public class JLineProfileLayout extends JGraphicLayout { |
---|
69 | // |
---|
70 | // save handles to unique components |
---|
71 | // |
---|
72 | Logo logo_; |
---|
73 | LineKey lineKey_; |
---|
74 | int layerCount_; |
---|
75 | boolean zUp_ = true; |
---|
76 | Layer firstLayer_; |
---|
77 | boolean inZoom_ = false; |
---|
78 | // |
---|
79 | // constants |
---|
80 | // |
---|
81 | double xSize_ = XSIZE_; |
---|
82 | double xMin_ = XMIN_; |
---|
83 | double xMax_ = XMAX_; |
---|
84 | double ySize_ = YSIZE_; |
---|
85 | double yMin_ = YMIN_; |
---|
86 | double yMax_ = YMAX_; |
---|
87 | // |
---|
88 | double mainTitleHeight_ = MAIN_TITLE_HEIGHT_; |
---|
89 | double titleHeight_ = TITLE_HEIGHT_; |
---|
90 | double labelHeight_ = LABEL_HEIGHT_; |
---|
91 | double warnHeight_ = WARN_HEIGHT_; |
---|
92 | double keyHeight_ = KEY_HEIGHT_; |
---|
93 | // |
---|
94 | double xKeySize_ = XKEYSIZE_; |
---|
95 | double yKeySize_ = YKEYSIZE_; |
---|
96 | // |
---|
97 | Color paneColor_ = PANE_COLOR; |
---|
98 | Color keyPaneColor_ = KEYPANE_COLOR; |
---|
99 | |
---|
100 | // |
---|
101 | private static final Color[] colorList_ = |
---|
102 | { Color.blue, Color.cyan, Color.green, Color.orange.darker(), |
---|
103 | Color.red, Color.magenta, Color.black, Color.gray}; |
---|
104 | // {Color.red, Color.green, Color.blue, Color.cyan, |
---|
105 | // Color.magenta, Color.yellow, Color.orange, Color.pink}; |
---|
106 | private static final int[] markList_ = |
---|
107 | {1, 2, 9, 15, 10, 24, 11, 44}; |
---|
108 | /** |
---|
109 | * Default constructor. No Logo image is used and the LineKey |
---|
110 | * will be in the same Pane. |
---|
111 | */ |
---|
112 | public JLineProfileLayout() { |
---|
113 | this("", null, false); |
---|
114 | } |
---|
115 | /** |
---|
116 | * JLineProfileLayout constructor. |
---|
117 | * |
---|
118 | * @param id identifier |
---|
119 | * @param img Logo image |
---|
120 | * @param is_key_pane if true LineKey is in separate pane |
---|
121 | */ |
---|
122 | public JLineProfileLayout(String id, Image img, boolean is_key_pane) { |
---|
123 | super(id, img, new Dimension(400,300)); |
---|
124 | Layer layer, key_layer; |
---|
125 | CartesianGraph graph; |
---|
126 | LinearTransform xt, yt; |
---|
127 | PlainAxis xbot, yleft; |
---|
128 | double xpos, ypos; |
---|
129 | int halign; |
---|
130 | // |
---|
131 | // create Pane and descendants for the LineProfile layout |
---|
132 | // |
---|
133 | setOpaque(true); |
---|
134 | setLayout(new StackedLayout()); |
---|
135 | setBackground(paneColor_); |
---|
136 | layer = new Layer("Layer 1", new Dimension2D(xSize_, ySize_)); |
---|
137 | firstLayer_ = layer; |
---|
138 | add(layer,0); |
---|
139 | // |
---|
140 | lineKey_ = new LineKey(); |
---|
141 | lineKey_.setSelectable(false); |
---|
142 | lineKey_.setId("Line Key"); |
---|
143 | lineKey_.setVAlign(LineKey.TOP); |
---|
144 | if(is_key_pane) { |
---|
145 | lineKey_.setHAlign(LineKey.LEFT); |
---|
146 | lineKey_.setBorderStyle(LineKey.NO_BORDER); |
---|
147 | lineKey_.setLocationP(new Point2D.Double(0.0, yKeySize_)); |
---|
148 | int xdim = 400; |
---|
149 | int ydim = (int)((double)xdim/xKeySize_*yKeySize_); |
---|
150 | keyPane_ = new JPane("KeyPane", new Dimension(xdim,ydim)); |
---|
151 | keyPane_.setOpaque(true); |
---|
152 | keyPane_.setLayout(new StackedLayout()); |
---|
153 | keyPane_.setBackground(keyPaneColor_); |
---|
154 | key_layer = new Layer("Key Layer", new Dimension2D(xKeySize_, yKeySize_)); |
---|
155 | keyPane_.add(key_layer); |
---|
156 | key_layer.addChild(lineKey_); |
---|
157 | } else { |
---|
158 | lineKey_.setHAlign(LineKey.RIGHT); |
---|
159 | lineKey_.setLocationP(new Point2D.Double(xSize_ - 0.01, ySize_)); |
---|
160 | layer.addChild(lineKey_); |
---|
161 | } |
---|
162 | // |
---|
163 | // add Icon |
---|
164 | // |
---|
165 | if(iconImage_ != null) { |
---|
166 | logo_ = new Logo(new Point2D.Double(0.0, ySize_), Logo.TOP, Logo.LEFT); |
---|
167 | logo_.setImage(iconImage_); |
---|
168 | layer.addChild(logo_); |
---|
169 | Rectangle bnds = logo_.getBounds(); |
---|
170 | xpos = layer.getXDtoP(bnds.x + bnds.width) + 0.05; |
---|
171 | halign = SGLabel.LEFT; |
---|
172 | } else { |
---|
173 | xpos = (xMin_ + xMax_)*0.5; |
---|
174 | halign = SGLabel.CENTER; |
---|
175 | } |
---|
176 | // |
---|
177 | // title |
---|
178 | // |
---|
179 | ypos = ySize_ - 1.2f*mainTitleHeight_; |
---|
180 | Font titleFont = new Font("Helvetica", Font.BOLD, 14); |
---|
181 | mainTitle_ = new SGLabel("Line Profile Title", |
---|
182 | "Profile Plot", |
---|
183 | mainTitleHeight_, |
---|
184 | new Point2D.Double(xpos, ypos), |
---|
185 | SGLabel.BOTTOM, |
---|
186 | halign); |
---|
187 | mainTitle_.setFont(titleFont); |
---|
188 | layer.addChild(mainTitle_); |
---|
189 | ypos = ypos - 1.2f*warnHeight_; |
---|
190 | Font title2Font = new Font("Helvetica", Font.PLAIN, 10); |
---|
191 | title2_ = new SGLabel("Warning", |
---|
192 | "Warning: Browse image only", |
---|
193 | warnHeight_, |
---|
194 | new Point2D.Double(xpos, ypos), |
---|
195 | SGLabel.BOTTOM, |
---|
196 | halign); |
---|
197 | title2_.setFont(title2Font); |
---|
198 | layer.addChild(title2_); |
---|
199 | ypos = ypos - 1.1f*warnHeight_; |
---|
200 | title3_ = new SGLabel("Warning 2", |
---|
201 | "Verify accuracy of plot before research use", |
---|
202 | warnHeight_, |
---|
203 | new Point2D.Double(xpos, ypos), |
---|
204 | SGLabel.BOTTOM, |
---|
205 | halign); |
---|
206 | title3_.setFont(title2Font); |
---|
207 | layer.addChild(title3_); |
---|
208 | // |
---|
209 | title3_.setSelectable(false); |
---|
210 | |
---|
211 | layerCount_ = 0; |
---|
212 | // |
---|
213 | // create LineCartesianGraph and transforms |
---|
214 | // |
---|
215 | graph = new CartesianGraph("Profile Graph 1"); |
---|
216 | xt = new LinearTransform(xMin_, xMax_, 10.0, 20.0); |
---|
217 | yt = new LinearTransform(yMin_, yMax_, 400.0, 0.0); |
---|
218 | graph.setXTransform(xt); |
---|
219 | graph.setYTransform(yt); |
---|
220 | // |
---|
221 | // create axes |
---|
222 | // |
---|
223 | Font axfont = new Font("Helvetica", Font.ITALIC, 14); |
---|
224 | xbot = new PlainAxis("Bottom Axis"); |
---|
225 | xbot.setRangeU(new Range2D(10.0, 20.0)); |
---|
226 | xbot.setDeltaU(2.0); |
---|
227 | xbot.setNumberSmallTics(0); |
---|
228 | xbot.setLabelHeightP(labelHeight_); |
---|
229 | xbot.setLocationU(new Point2D.Double(10.0, 400.0)); |
---|
230 | xbot.setLabelFont(axfont); |
---|
231 | graph.addXAxis(xbot); |
---|
232 | // |
---|
233 | yleft = new PlainAxis("Left Axis"); |
---|
234 | yleft.setRangeU(new Range2D(400.0, 0.0)); |
---|
235 | yleft.setDeltaU(-50.0); |
---|
236 | yleft.setNumberSmallTics(0); |
---|
237 | yleft.setLabelHeightP(labelHeight_); |
---|
238 | yleft.setLocationU(new Point2D.Double(10.0, 400.0)); |
---|
239 | yleft.setLabelFont(axfont); |
---|
240 | graph.addYAxis(yleft); |
---|
241 | // |
---|
242 | layer.setGraph(graph); |
---|
243 | } |
---|
244 | public String getLocationSummary(SGTData grid) { |
---|
245 | return ""; |
---|
246 | } |
---|
247 | public void addData(Collection lines) { |
---|
248 | addData(lines, null); |
---|
249 | } |
---|
250 | public void addData(Collection lines, String descrip) { |
---|
251 | // System.out.println("addData(Collection) called"); |
---|
252 | for(int i=0; i < lines.size(); i++) { |
---|
253 | SGTLine line = (SGTLine)lines.elementAt(i); |
---|
254 | addData(line, line.getTitle()); |
---|
255 | } |
---|
256 | } |
---|
257 | /** |
---|
258 | * Add data to the layout. LineKey descriptor will be |
---|
259 | * taken from the dependent variable name. |
---|
260 | * |
---|
261 | * @param data datum data to be added |
---|
262 | */ |
---|
263 | public void addData(SGTData datum) { |
---|
264 | addData(datum, null); |
---|
265 | } |
---|
266 | /** |
---|
267 | * Add data to the layout. Data will be added to X axis and Z_AXIS will be |
---|
268 | * assigned to Y axis. If this is not the first invocation of addData a new Layer |
---|
269 | * will be created. If overlayed, the transforms from the first layer will be |
---|
270 | * attached and <B>no</B> axes will be created. If not overlayed, new transforms |
---|
271 | * and axes will be created and adjusted so that the data is horizontally stacked. |
---|
272 | * |
---|
273 | * @param datum data to be added |
---|
274 | * @param descrip LineKey description for datum |
---|
275 | */ |
---|
276 | public void addData(SGTData datum, String descrip) { |
---|
277 | // |
---|
278 | Layer layer, newLayer; |
---|
279 | CartesianGraph graph, newGraph; |
---|
280 | PlainAxis xbot = null; |
---|
281 | PlainAxis yleft = null; |
---|
282 | LinearTransform xt, yt; |
---|
283 | SGLabel xtitle, ytitle, lineTitle; |
---|
284 | SGTData data; |
---|
285 | LineAttribute lineAttr; |
---|
286 | String xLabel, yLabel; |
---|
287 | Range2D xRange, yRange; |
---|
288 | Range2D xnRange = null, ynRange = null; |
---|
289 | Point2D.Double origin = null; |
---|
290 | boolean data_good = true; |
---|
291 | double save; |
---|
292 | // |
---|
293 | if(data_.size() == 0) setBaseUnit(Units.getBaseUnit(((SGTLine)datum).getXMetaData())); |
---|
294 | datum = Units.convertToBaseUnit(datum, getBaseUnit(), Units.X_AXIS); |
---|
295 | // |
---|
296 | if(data_.size() == 0) { |
---|
297 | super.addData(datum); |
---|
298 | // |
---|
299 | // only one data set... |
---|
300 | // determine range and titles from data |
---|
301 | // |
---|
302 | data = (SGTData)data_.firstElement(); |
---|
303 | xRange = findRange((SGTLine)data, X_AXIS); |
---|
304 | yRange = findRange((SGTLine)data, Y_AXIS); |
---|
305 | zUp_ = ((SGTLine)data).getYMetaData().isReversed(); |
---|
306 | |
---|
307 | if(Double.isNaN(xRange.start) || Double.isNaN(yRange.start)) data_good = false; |
---|
308 | |
---|
309 | if(data_good) { |
---|
310 | if(!zUp_) { |
---|
311 | save = yRange.end; |
---|
312 | yRange.end = yRange.start; |
---|
313 | yRange.start = save; |
---|
314 | } |
---|
315 | // |
---|
316 | xnRange = Graph.computeRange(xRange, 6); |
---|
317 | ynRange = Graph.computeRange(yRange, 6); |
---|
318 | // |
---|
319 | origin = new Point2D.Double(xnRange.start, ynRange.start); |
---|
320 | } |
---|
321 | // |
---|
322 | xLabel = " (" + ((SGTLine)data).getXMetaData().getUnits() + ")"; |
---|
323 | yLabel = " (" + ((SGTLine)data).getYMetaData().getUnits() + ")"; |
---|
324 | // |
---|
325 | // attach information to pane and descendents |
---|
326 | // |
---|
327 | try { |
---|
328 | layer = getLayer("Layer 1"); |
---|
329 | } catch (LayerNotFoundException e) { |
---|
330 | return; |
---|
331 | } |
---|
332 | graph = (CartesianGraph)layer.getGraph(); |
---|
333 | // |
---|
334 | // axes |
---|
335 | // |
---|
336 | try { |
---|
337 | Font tfont = new Font("Helvetica", Font.PLAIN, 14); |
---|
338 | xbot = (PlainAxis)graph.getXAxis("Bottom Axis"); |
---|
339 | if(data_good) { |
---|
340 | xbot.setRangeU(xnRange); |
---|
341 | xbot.setDeltaU(xnRange.delta); |
---|
342 | xbot.setLocationU(origin); |
---|
343 | } |
---|
344 | xtitle = new SGLabel("xaxis title", xLabel, new Point2D.Double(0.0, 0.0)); |
---|
345 | xtitle.setFont(tfont); |
---|
346 | xtitle.setHeightP(titleHeight_); |
---|
347 | xbot.setTitle(xtitle); |
---|
348 | // |
---|
349 | yleft = (PlainAxis)graph.getYAxis("Left Axis"); |
---|
350 | if(data_good) { |
---|
351 | yleft.setRangeU(ynRange); |
---|
352 | yleft.setDeltaU(ynRange.delta); |
---|
353 | yleft.setLocationU(origin); |
---|
354 | } |
---|
355 | ytitle = new SGLabel("yaxis title", yLabel, new Point2D.Double(0.0, 0.0)); |
---|
356 | ytitle.setFont(tfont); |
---|
357 | ytitle.setHeightP(titleHeight_); |
---|
358 | yleft.setTitle(ytitle); |
---|
359 | } catch (AxisNotFoundException e) {} |
---|
360 | if(data_good) { |
---|
361 | // |
---|
362 | // transforms |
---|
363 | // |
---|
364 | xt = (LinearTransform)graph.getXTransform(); |
---|
365 | xt.setRangeU(xnRange); |
---|
366 | // |
---|
367 | yt = (LinearTransform)graph.getYTransform(); |
---|
368 | yt.setRangeU(ynRange); |
---|
369 | } |
---|
370 | // |
---|
371 | // attach data |
---|
372 | // |
---|
373 | if(((SGTLine)data).getYArray().length >= 2) { |
---|
374 | lineAttr = new LineAttribute(LineAttribute.SOLID, |
---|
375 | markList_[layerCount_%8], |
---|
376 | colorList_[layerCount_%8]); |
---|
377 | } else { |
---|
378 | lineAttr = new LineAttribute(LineAttribute.MARK, |
---|
379 | markList_[layerCount_%8], |
---|
380 | colorList_[layerCount_%8]); |
---|
381 | } |
---|
382 | graph.setData(data, lineAttr); |
---|
383 | // |
---|
384 | // add to lineKey |
---|
385 | // |
---|
386 | if(descrip == null) { |
---|
387 | lineTitle = new SGLabel("line title", xLabel, new Point2D.Double(0.0, 0.0)); |
---|
388 | } else { |
---|
389 | lineTitle = new SGLabel("line title", descrip, new Point2D.Double(0.0, 0.0)); |
---|
390 | } |
---|
391 | lineTitle.setHeightP(keyHeight_); |
---|
392 | lineKey_.addLineGraph((LineCartesianRenderer)graph.getRenderer(), lineTitle); |
---|
393 | if(keyPane_ != null) { |
---|
394 | Rectangle vRect = keyPane_.getVisibleRect(); |
---|
395 | int nrow = vRect.height/lineKey_.getRowHeight(); |
---|
396 | keyPane_.setScrollableUnitIncrement(1, lineKey_.getRowHeight()); |
---|
397 | keyPane_.setScrollableBlockIncrement(vRect.width, |
---|
398 | lineKey_.getRowHeight()*nrow); |
---|
399 | } |
---|
400 | } else { |
---|
401 | // |
---|
402 | // more than one data set... |
---|
403 | // add new layer |
---|
404 | // |
---|
405 | if(((SGTLine)datum).getYMetaData().isReversed() != zUp_) { |
---|
406 | // System.out.println("New datum has reversed ZUp!"); |
---|
407 | SGTData modified = flipZ(datum); |
---|
408 | datum = modified; |
---|
409 | } |
---|
410 | super.addData(datum); |
---|
411 | |
---|
412 | data_good = false; |
---|
413 | layerCount_++; |
---|
414 | if(isOverlayed()) { |
---|
415 | try { |
---|
416 | layer = getLayer("Layer 1"); |
---|
417 | } catch (LayerNotFoundException e) { |
---|
418 | return; |
---|
419 | } |
---|
420 | graph = (CartesianGraph)layer.getGraph(); |
---|
421 | // |
---|
422 | // transforms |
---|
423 | // |
---|
424 | xt = (LinearTransform)graph.getXTransform(); |
---|
425 | yt = (LinearTransform)graph.getYTransform(); |
---|
426 | try { |
---|
427 | xbot = (PlainAxis)graph.getXAxis("Bottom Axis"); |
---|
428 | yleft = (PlainAxis)graph.getYAxis("Left Axis"); |
---|
429 | } catch (AxisNotFoundException e) {} |
---|
430 | |
---|
431 | if(!inZoom_) { |
---|
432 | // |
---|
433 | // loop over data sets, getting ranges |
---|
434 | // |
---|
435 | Range2D xTotalRange = new Range2D(); |
---|
436 | Range2D yTotalRange = new Range2D(); |
---|
437 | |
---|
438 | boolean first = true; |
---|
439 | for (Enumeration e = data_.elements() ; e.hasMoreElements() ;) { |
---|
440 | data = (SGTData)e.nextElement(); |
---|
441 | xRange = findRange((SGTLine)data, X_AXIS); |
---|
442 | yRange = findRange((SGTLine)data, Y_AXIS); |
---|
443 | if(!((SGTLine)data).getYMetaData().isReversed()) { |
---|
444 | save = yRange.start; |
---|
445 | yRange.start = yRange.end; |
---|
446 | yRange.end = save; |
---|
447 | } |
---|
448 | if(first) { |
---|
449 | if(Double.isNaN(xRange.start) || Double.isNaN(yRange.start)) { |
---|
450 | first = true; |
---|
451 | } else { |
---|
452 | first = false; |
---|
453 | data_good = true; |
---|
454 | xTotalRange = new Range2D(xRange.start, xRange.end); |
---|
455 | yTotalRange = new Range2D(yRange.start, yRange.end); |
---|
456 | } |
---|
457 | } else { |
---|
458 | if(!Double.isNaN(xRange.start) && !Double.isNaN(yRange.start)) { |
---|
459 | data_good = true; |
---|
460 | xTotalRange.start = Math.min(xTotalRange.start, xRange.start); |
---|
461 | xTotalRange.end = Math.max(xTotalRange.end, xRange.end); |
---|
462 | if(!((SGTLine)data).getYMetaData().isReversed()) { |
---|
463 | yTotalRange.start = Math.max(yTotalRange.start, yRange.start); |
---|
464 | yTotalRange.end = Math.min(yTotalRange.end, yRange.end); |
---|
465 | } else { |
---|
466 | yTotalRange.start = Math.min(yTotalRange.start, yRange.start); |
---|
467 | yTotalRange.end = Math.max(yTotalRange.end, yRange.end); |
---|
468 | } |
---|
469 | } |
---|
470 | } |
---|
471 | } |
---|
472 | if(data_good) { |
---|
473 | xnRange = Graph.computeRange(xTotalRange, 6); |
---|
474 | ynRange = Graph.computeRange(yTotalRange, 6); |
---|
475 | origin = new Point2D.Double(xnRange.start, ynRange.start); |
---|
476 | // |
---|
477 | // axes |
---|
478 | // |
---|
479 | xbot.setRangeU(xnRange); |
---|
480 | xbot.setDeltaU(xnRange.delta); |
---|
481 | xbot.setLocationU(origin); |
---|
482 | // |
---|
483 | yleft.setRangeU(ynRange); |
---|
484 | yleft.setDeltaU(ynRange.delta); |
---|
485 | yleft.setLocationU(origin); |
---|
486 | } |
---|
487 | // |
---|
488 | if(data_good) { |
---|
489 | xt.setRangeU(xnRange); |
---|
490 | yt.setRangeU(ynRange); |
---|
491 | } |
---|
492 | } |
---|
493 | // |
---|
494 | // create new layer and graph |
---|
495 | // |
---|
496 | newLayer = new Layer("Layer " + (layerCount_+1), new Dimension2D(xSize_, ySize_)); |
---|
497 | newGraph = new CartesianGraph("Graph " + (layerCount_+1), xt, yt); |
---|
498 | if(inZoom_) { |
---|
499 | Range2D xr, yr; |
---|
500 | xr = xbot.getRangeU(); |
---|
501 | yr = yleft.getRangeU(); |
---|
502 | newGraph.setClip(xr.start, xr.end, yr.start, yr.end); |
---|
503 | newGraph.setClipping(true); |
---|
504 | } |
---|
505 | add(newLayer,0); |
---|
506 | newLayer.setGraph(newGraph); |
---|
507 | newLayer.invalidate(); |
---|
508 | validate(); |
---|
509 | // |
---|
510 | // attach data |
---|
511 | // |
---|
512 | if(((SGTLine)datum).getXArray().length >= 2) { |
---|
513 | lineAttr = new LineAttribute(LineAttribute.SOLID, |
---|
514 | markList_[layerCount_%8], |
---|
515 | colorList_[layerCount_%8]); |
---|
516 | } else { |
---|
517 | lineAttr = new LineAttribute(LineAttribute.MARK, |
---|
518 | markList_[layerCount_%8], |
---|
519 | colorList_[layerCount_%8]); |
---|
520 | } |
---|
521 | newGraph.setData(datum, lineAttr); |
---|
522 | // |
---|
523 | // add to lineKey |
---|
524 | // |
---|
525 | if(descrip == null) { |
---|
526 | xLabel = ((SGTLine)datum).getXMetaData().getName(); |
---|
527 | lineTitle = new SGLabel("line title", xLabel, new Point2D.Double(0.0, 0.0)); |
---|
528 | } else { |
---|
529 | lineTitle = new SGLabel("line title", descrip, new Point2D.Double(0.0, 0.0)); |
---|
530 | } |
---|
531 | lineTitle.setHeightP(keyHeight_); |
---|
532 | lineKey_.addLineGraph((LineCartesianRenderer)newGraph.getRenderer(), lineTitle); |
---|
533 | if(keyPane_ != null) { |
---|
534 | Rectangle vRect = keyPane_.getVisibleRect(); |
---|
535 | int nrow = vRect.height/lineKey_.getRowHeight(); |
---|
536 | keyPane_.setScrollableUnitIncrement(1, lineKey_.getRowHeight()); |
---|
537 | keyPane_.setScrollableBlockIncrement(vRect.width, |
---|
538 | lineKey_.getRowHeight()*nrow); |
---|
539 | } |
---|
540 | } |
---|
541 | } |
---|
542 | } |
---|
543 | /** |
---|
544 | * Flip the zaxis. Reverse the direction of the z axis by changing the sign |
---|
545 | * of the axis values and isBackward flag. |
---|
546 | */ |
---|
547 | private SGTData flipZ(SGTData in) { |
---|
548 | SGTMetaData zmetaout; |
---|
549 | SGTMetaData zmetain; |
---|
550 | SimpleLine out = null; |
---|
551 | SGTLine line = (SGTLine) in; |
---|
552 | double[] values; |
---|
553 | double[] newValues; |
---|
554 | values = line.getYArray(); |
---|
555 | newValues = new double[values.length]; |
---|
556 | for(int i=0; i < values.length; i++) { |
---|
557 | newValues[i] = -values[i]; |
---|
558 | } |
---|
559 | out = new SimpleLine(line.getXArray(), newValues, line.getTitle()); |
---|
560 | zmetain = line.getYMetaData(); |
---|
561 | zmetaout = new SGTMetaData(zmetain.getName(), zmetain.getUnits(), |
---|
562 | !zmetain.isReversed(), zmetain.isModulo()); |
---|
563 | zmetaout.setModuloValue(zmetain.getModuloValue()); |
---|
564 | zmetaout.setModuloTime(zmetain.getModuloTime()); |
---|
565 | out.setXMetaData(line.getXMetaData()); |
---|
566 | out.setYMetaData(zmetaout); |
---|
567 | return (SGTData)out; |
---|
568 | } |
---|
569 | /** |
---|
570 | * Clear the current zoom. |
---|
571 | */ |
---|
572 | public void resetZoom() { |
---|
573 | SGTData data; |
---|
574 | Range2D xRange, yRange; |
---|
575 | boolean data_good = false; |
---|
576 | double save; |
---|
577 | |
---|
578 | inZoom_ = false; |
---|
579 | // |
---|
580 | // loop over data sets, getting ranges |
---|
581 | // |
---|
582 | Range2D xTotalRange = new Range2D(); |
---|
583 | Range2D yTotalRange = new Range2D(); |
---|
584 | |
---|
585 | boolean first = true; |
---|
586 | |
---|
587 | for (Enumeration e = data_.elements() ; e.hasMoreElements() ;) { |
---|
588 | data = (SGTData)e.nextElement(); |
---|
589 | xRange = findRange((SGTLine)data, X_AXIS); |
---|
590 | yRange = findRange((SGTLine)data, Y_AXIS); |
---|
591 | if(!((SGTLine)data).getYMetaData().isReversed()) { |
---|
592 | save = yRange.start; |
---|
593 | yRange.start = yRange.end; |
---|
594 | yRange.end = save; |
---|
595 | } |
---|
596 | if(first) { |
---|
597 | if(Double.isNaN(xRange.start) || Double.isNaN(yRange.start)) { |
---|
598 | first = true; |
---|
599 | } else { |
---|
600 | first = false; |
---|
601 | data_good = true; |
---|
602 | xTotalRange = new Range2D(xRange.start, xRange.end); |
---|
603 | yTotalRange = new Range2D(yRange.start, yRange.end); |
---|
604 | } |
---|
605 | } else { |
---|
606 | if(!Double.isNaN(xRange.start) && !Double.isNaN(yRange.start)) { |
---|
607 | data_good = true; |
---|
608 | xTotalRange.start = Math.min(xTotalRange.start, xRange.start); |
---|
609 | xTotalRange.end = Math.max(xTotalRange.end, xRange.end); |
---|
610 | if(!((SGTLine)data).getYMetaData().isReversed()) { |
---|
611 | yTotalRange.start = Math.max(yTotalRange.start, yRange.start); |
---|
612 | yTotalRange.end = Math.min(yTotalRange.end, yRange.end); |
---|
613 | } else { |
---|
614 | yTotalRange.start = Math.min(yTotalRange.start, yRange.start); |
---|
615 | yTotalRange.end = Math.max(yTotalRange.end, yRange.end); |
---|
616 | } |
---|
617 | } |
---|
618 | } |
---|
619 | } |
---|
620 | if(data_good) { |
---|
621 | try { |
---|
622 | setRange(new Domain(xTotalRange, yTotalRange), false); |
---|
623 | } catch (PropertyVetoException e) { |
---|
624 | System.out.println("zoom reset denied! " + e); |
---|
625 | } |
---|
626 | } |
---|
627 | } |
---|
628 | /** |
---|
629 | * Set the x and y range of the domain. |
---|
630 | * |
---|
631 | * @param range new domain |
---|
632 | */ |
---|
633 | public void setRange(Domain domain) throws PropertyVetoException { |
---|
634 | setRange(domain, true); |
---|
635 | } |
---|
636 | public void setRange(Domain domain, boolean testZUp) |
---|
637 | throws PropertyVetoException { |
---|
638 | CartesianGraph graph = (CartesianGraph)firstLayer_.getGraph(); |
---|
639 | LinearTransform xt = (LinearTransform)graph.getXTransform(); |
---|
640 | LinearTransform yt = (LinearTransform)graph.getYTransform(); |
---|
641 | Domain oldRange = new Domain(xt.getRangeU(), |
---|
642 | yt.getRangeU()); |
---|
643 | if(!domain.equals(oldRange)) { |
---|
644 | setBatch(true, "JLineProfileLayout: setRange"); |
---|
645 | vetos_.fireVetoableChange("domainRange", oldRange, domain); |
---|
646 | |
---|
647 | inZoom_ = true; |
---|
648 | |
---|
649 | if(!domain.isXTime()) { |
---|
650 | setXRange(domain.getXRange()); |
---|
651 | } |
---|
652 | if(!domain.isYTime()) { |
---|
653 | setYRange(domain.getYRange(), testZUp); |
---|
654 | } |
---|
655 | changes_.firePropertyChange("domainRange", oldRange, domain); |
---|
656 | setBatch(false, "JLineProfileLayout: setRange"); |
---|
657 | } |
---|
658 | } |
---|
659 | public void setRangeNoVeto(Domain domain) { |
---|
660 | CartesianGraph graph = (CartesianGraph)firstLayer_.getGraph(); |
---|
661 | LinearTransform xt = (LinearTransform)graph.getXTransform(); |
---|
662 | LinearTransform yt = (LinearTransform)graph.getYTransform(); |
---|
663 | Domain oldRange = new Domain(xt.getRangeU(), |
---|
664 | yt.getRangeU()); |
---|
665 | // |
---|
666 | // clipping? hack fix. how should clipping be done for |
---|
667 | // external range sets? |
---|
668 | // |
---|
669 | setBatch(true, "JLineProfileLayout: setRangeNoVeto"); |
---|
670 | inZoom_ = true; |
---|
671 | setClipping(true); |
---|
672 | |
---|
673 | if(!domain.isXTime()) { |
---|
674 | setXRange(domain.getXRange()); |
---|
675 | } |
---|
676 | if(!domain.isYTime()) { |
---|
677 | setYRange(domain.getYRange(),false); |
---|
678 | } |
---|
679 | setBatch(false, "JLineProfileLayout: setRangeNoVeto"); |
---|
680 | // changes_.firePropertyChange("domainRange", oldRange, domain); |
---|
681 | } |
---|
682 | /** |
---|
683 | * Reset the x range. This method is designed to provide |
---|
684 | * zooming functionality. |
---|
685 | * |
---|
686 | * @param rnge new x range |
---|
687 | */ |
---|
688 | void setXRange(Range2D rnge) { |
---|
689 | Point2D.Double origin; |
---|
690 | PlainAxis xbot, yleft; |
---|
691 | Range2D xr, yr, xnRange; |
---|
692 | CartesianGraph graph = (CartesianGraph)firstLayer_.getGraph(); |
---|
693 | LinearTransform xt = (LinearTransform)graph.getXTransform(); |
---|
694 | xnRange = Graph.computeRange(rnge, 6); |
---|
695 | xt.setRangeU(xnRange); |
---|
696 | try { |
---|
697 | xbot = (PlainAxis)graph.getXAxis("Bottom Axis"); |
---|
698 | yleft = (PlainAxis)graph.getYAxis("Left Axis"); |
---|
699 | |
---|
700 | xbot.setRangeU(xnRange); |
---|
701 | xbot.setDeltaU(xnRange.delta); |
---|
702 | |
---|
703 | xr = xbot.getRangeU(); |
---|
704 | yr = yleft.getRangeU(); |
---|
705 | origin = new Point2D.Double(xr.start, yr.start); |
---|
706 | xbot.setLocationU(origin); |
---|
707 | |
---|
708 | yleft.setLocationU(origin); |
---|
709 | // |
---|
710 | // set clipping |
---|
711 | // |
---|
712 | if(clipping_) { |
---|
713 | setAllClip(xr.start, xr.end, yr.start, yr.end); |
---|
714 | } else { |
---|
715 | setAllClipping(false); |
---|
716 | } |
---|
717 | } catch (AxisNotFoundException e) {} |
---|
718 | } |
---|
719 | /** |
---|
720 | * Reset the y range. This method is designed to provide |
---|
721 | * zooming functionality. |
---|
722 | * |
---|
723 | * @param rnge new y range |
---|
724 | */ |
---|
725 | void setYRange(Range2D rnge) { |
---|
726 | setYRange(rnge, true); |
---|
727 | } |
---|
728 | |
---|
729 | /** |
---|
730 | * Reset the y range. This method is designed to provide |
---|
731 | * zooming functionality. |
---|
732 | * |
---|
733 | * @param rnge new y range |
---|
734 | * @param testZUp test to see if Z is Up |
---|
735 | */ |
---|
736 | void setYRange(Range2D rnge, boolean testZUp) { |
---|
737 | SGTData grid; |
---|
738 | Point2D.Double origin; |
---|
739 | PlainAxis xbot, yleft; |
---|
740 | Range2D xr, yr, ynRange; |
---|
741 | double save; |
---|
742 | CartesianGraph graph = (CartesianGraph)firstLayer_.getGraph(); |
---|
743 | LinearTransform yt = (LinearTransform)graph.getYTransform(); |
---|
744 | if(testZUp && data_.size() > 0) { |
---|
745 | grid = (SGTData)data_.elements().nextElement(); |
---|
746 | if(!((SGTLine)grid).getYMetaData().isReversed()) { |
---|
747 | save = rnge.end; |
---|
748 | rnge.end = rnge.start; |
---|
749 | rnge.start = save; |
---|
750 | } |
---|
751 | } |
---|
752 | ynRange = Graph.computeRange(rnge, 6); |
---|
753 | yt.setRangeU(ynRange); |
---|
754 | try { |
---|
755 | xbot = (PlainAxis)graph.getXAxis("Bottom Axis"); |
---|
756 | yleft = (PlainAxis)graph.getYAxis("Left Axis"); |
---|
757 | |
---|
758 | yleft.setRangeU(ynRange); |
---|
759 | yleft.setDeltaU(ynRange.delta); |
---|
760 | |
---|
761 | xr = xbot.getRangeU(); |
---|
762 | yr = yleft.getRangeU(); |
---|
763 | origin = new Point2D.Double(xr.start, yr.start); |
---|
764 | yleft.setLocationU(origin); |
---|
765 | |
---|
766 | xbot.setLocationU(origin); |
---|
767 | // |
---|
768 | // set clipping |
---|
769 | // |
---|
770 | if(clipping_) { |
---|
771 | setAllClip(xr.start, xr.end, yr.start, yr.end); |
---|
772 | } else { |
---|
773 | setAllClipping(false); |
---|
774 | } |
---|
775 | } catch (AxisNotFoundException e) {} |
---|
776 | } |
---|
777 | private void setAllClip(JPane pane, double xmin, double xmax, double ymin, double ymax) { |
---|
778 | Layer ly; |
---|
779 | Component[] comps = pane.getComponents(); |
---|
780 | for(int i=0; i < comps.length; i++) { |
---|
781 | if(comps[i] instanceof Layer) { |
---|
782 | ly = (Layer)comps[i]; |
---|
783 | ((CartesianGraph)ly.getGraph()).setClip(xmin, xmax, ymin, ymax); |
---|
784 | } |
---|
785 | } |
---|
786 | } |
---|
787 | private void setAllClipping(JPane pane, boolean clip) { |
---|
788 | Layer ly; |
---|
789 | Component[] comps = pane.getComponents(); |
---|
790 | for(int i=0; i < comps.length; i++) { |
---|
791 | if(comps[i] instanceof Layer) { |
---|
792 | ly = (Layer)comps[i]; |
---|
793 | ((CartesianGraph)ly.getGraph()).setClipping(clip); |
---|
794 | } |
---|
795 | } |
---|
796 | } |
---|
797 | public void clear() { |
---|
798 | data_.removeAllElements(); |
---|
799 | ((CartesianGraph)firstLayer_.getGraph()).setRenderer(null); |
---|
800 | removeAll(); |
---|
801 | add(firstLayer_,0); // restore first layer |
---|
802 | lineKey_.clearAll(); |
---|
803 | // draw(); |
---|
804 | // if(keyPane_ != null)keyPane_.draw(); |
---|
805 | inZoom_ = false; |
---|
806 | } |
---|
807 | |
---|
808 | public void clear(String data_id) { |
---|
809 | Layer ly = null; |
---|
810 | SGTData dat; |
---|
811 | try { |
---|
812 | ly = getLayerFromDataId(data_id); |
---|
813 | remove(ly); |
---|
814 | } catch (LayerNotFoundException e) {} |
---|
815 | for(Enumeration it=data_.elements(); it.hasMoreElements();) { |
---|
816 | dat = (SGTData)it.nextElement(); |
---|
817 | if(dat.getId().equals(data_id)) { |
---|
818 | data_.removeElement(dat); |
---|
819 | } |
---|
820 | } |
---|
821 | lineKey_.clear(data_id); |
---|
822 | if(getComponentCount() <= 0 || ly.equals(firstLayer_)) { |
---|
823 | ((CartesianGraph)firstLayer_.getGraph()).setRenderer(null); |
---|
824 | add(firstLayer_,0); // restore first layer |
---|
825 | } |
---|
826 | // draw(); |
---|
827 | // if(keyPane_ != null)keyPane_.draw(); |
---|
828 | } |
---|
829 | |
---|
830 | public void setKeyBoundsP(Rectangle2D.Double bounds){ |
---|
831 | if(lineKey_ != null) { |
---|
832 | lineKey_.setBoundsP(bounds); |
---|
833 | } |
---|
834 | } |
---|
835 | public Rectangle2D.Double getKeyBoundsP() { |
---|
836 | if(lineKey_ == null) { |
---|
837 | return null; |
---|
838 | } else { |
---|
839 | return lineKey_.getBoundsP(); |
---|
840 | } |
---|
841 | } |
---|
842 | |
---|
843 | public Dimension2D getLayerSizeP() { |
---|
844 | return new Dimension2D(xSize_, ySize_); |
---|
845 | } |
---|
846 | public Layer getFirstLayer() { |
---|
847 | return firstLayer_; |
---|
848 | } |
---|
849 | public void setLayerSizeP(Dimension2D d) { |
---|
850 | Component[] comps = getComponents(); |
---|
851 | CartesianGraph graph = (CartesianGraph)firstLayer_.getGraph(); |
---|
852 | LinearTransform yt = (LinearTransform)graph.getYTransform(); |
---|
853 | LinearTransform xt = (LinearTransform)graph.getXTransform(); |
---|
854 | xMax_ = d.width - (xSize_ - xMax_); |
---|
855 | yMax_ = d.height - (ySize_ - yMax_); |
---|
856 | xSize_ = d.width; |
---|
857 | ySize_ = d.height; |
---|
858 | for(int i=0; i < comps.length; i++) { |
---|
859 | if(comps[i] instanceof Layer) { |
---|
860 | ((Layer)comps[i]).setSizeP(d); |
---|
861 | } |
---|
862 | } |
---|
863 | yt.setRangeP(new Range2D(yMin_, yMax_)); |
---|
864 | xt.setRangeP(new Range2D(xMin_, xMax_)); |
---|
865 | // |
---|
866 | double xpos; |
---|
867 | if(iconImage_ != null) { |
---|
868 | Rectangle bnds = logo_.getBounds(); |
---|
869 | xpos = firstLayer_.getXDtoP(bnds.x + bnds.width) + 0.05; |
---|
870 | } else { |
---|
871 | xpos = (xMin_ + xMax_)*0.5; |
---|
872 | } |
---|
873 | double ypos = ySize_ - 1.2f*mainTitleHeight_; |
---|
874 | mainTitle_.setLocationP(new Point2D.Double(xpos, ypos)); |
---|
875 | ypos = ypos - 1.2f*warnHeight_; |
---|
876 | title2_.setLocationP(new Point2D.Double(xpos, ypos)); |
---|
877 | ypos = ypos - 1.1f*warnHeight_; |
---|
878 | title3_.setLocationP(new Point2D.Double(xpos, ypos)); |
---|
879 | if(keyPane_ == null) { |
---|
880 | lineKey_.setLocationP(new Point2D.Double(xSize_ - 0.01, ySize_)); |
---|
881 | } |
---|
882 | |
---|
883 | } |
---|
884 | } |
---|