• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 AndroidPlot.com
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 
17 package com.androidplot.xy;
18 
19 import android.content.Context;
20 import android.graphics.Canvas;
21 import android.graphics.Color;
22 import android.graphics.Paint;
23 import android.graphics.PointF;
24 import android.util.AttributeSet;
25 import com.androidplot.Plot;
26 import com.androidplot.ui.*;
27 import com.androidplot.ui.TextOrientationType;
28 import com.androidplot.ui.widget.TextLabelWidget;
29 import com.androidplot.util.PixelUtils;
30 
31 import java.text.Format;
32 import java.util.ArrayList;
33 import java.util.List;
34 
35 /**
36  * A View to graphically display x/y coordinates.
37  */
38 public class XYPlot extends Plot<XYSeries, XYSeriesFormatter, XYSeriesRenderer> {
39 
40     private BoundaryMode domainOriginBoundaryMode;
41     private BoundaryMode rangeOriginBoundaryMode;
42 
43     // widgets
44     private XYLegendWidget legendWidget;
45     private XYGraphWidget graphWidget;
46     private TextLabelWidget domainLabelWidget;
47     private TextLabelWidget rangeLabelWidget;
48 
49     private XYStepMode domainStepMode = XYStepMode.SUBDIVIDE;
50     private double domainStepValue = 10;
51 
52     private XYStepMode rangeStepMode = XYStepMode.SUBDIVIDE;
53     private double rangeStepValue = 10;
54 
55     // user settable min/max values
56     private Number userMinX;
57     private Number userMaxX;
58     private Number userMinY;
59     private Number userMaxY;
60 
61     // these are the final min/max used for dispplaying data
62     private Number calculatedMinX;
63     private Number calculatedMaxX;
64     private Number calculatedMinY;
65     private Number calculatedMaxY;
66 
67     // previous calculated min/max vals.
68     // primarily used for GROW/SHRINK operations.
69     private Number prevMinX;
70     private Number prevMaxX;
71     private Number prevMinY;
72     private Number prevMaxY;
73 
74     // uses set boundary min and max values
75     // should be null if not used.
76     private Number rangeTopMin = null;
77     private Number rangeTopMax = null;
78     private Number rangeBottomMin = null;
79     private Number rangeBottomMax = null;
80     private Number domainLeftMin = null;
81     private Number domainLeftMax = null;
82     private Number domainRightMin = null;
83     private Number domainRightMax = null;
84 
85     // used for  calculating the domain/range extents that will be displayed on the plot.
86     // using boundaries and origins are mutually exclusive.  because of this,
87     // setting one will disable the other.  when only setting the FramingModel,
88     // the origin or boundary is set to the current value of the plot.
89     private XYFramingModel domainFramingModel = XYFramingModel.EDGE;
90     private XYFramingModel rangeFramingModel = XYFramingModel.EDGE;
91 
92     private Number userDomainOrigin;
93     private Number userRangeOrigin;
94 
95     private Number calculatedDomainOrigin;
96     private Number calculatedRangeOrigin;
97 
98     @SuppressWarnings("FieldCanBeLocal")
99     private Number domainOriginExtent = null;
100     @SuppressWarnings("FieldCanBeLocal")
101     private Number rangeOriginExtent = null;
102 
103     private BoundaryMode domainUpperBoundaryMode = BoundaryMode.AUTO;
104     private BoundaryMode domainLowerBoundaryMode = BoundaryMode.AUTO;
105     private BoundaryMode rangeUpperBoundaryMode = BoundaryMode.AUTO;
106     private BoundaryMode rangeLowerBoundaryMode = BoundaryMode.AUTO;
107 
108     private boolean drawDomainOriginEnabled = true;
109     private boolean drawRangeOriginEnabled = true;
110 
111     private ArrayList<YValueMarker> yValueMarkers;
112     private ArrayList<XValueMarker> xValueMarkers;
113 
114     private RectRegion defaultBounds;
115 
116 
117     private static final int DEFAULT_LEGEND_WIDGET_H_DP = 10;
118     private static final int DEFAULT_LEGEND_WIDGET_ICON_SIZE_DP = 7;
119     private static final int DEFAULT_GRAPH_WIDGET_H_DP = 18;
120     private static final int DEFAULT_GRAPH_WIDGET_W_DP = 10;
121     private static final int DEFAULT_DOMAIN_LABEL_WIDGET_H_DP = 10;
122     private static final int DEFAULT_DOMAIN_LABEL_WIDGET_W_DP = 80;
123     private static final int DEFAULT_RANGE_LABEL_WIDGET_H_DP = 50;
124     private static final int DEFAULT_RANGE_LABEL_WIDGET_W_DP = 10;
125 
126     private static final int DEFAULT_LEGEND_WIDGET_Y_OFFSET_DP = 0;
127     private static final int DEFAULT_LEGEND_WIDGET_X_OFFSET_DP = 40;
128     private static final int DEFAULT_GRAPH_WIDGET_Y_OFFSET_DP = 0;
129     private static final int DEFAULT_GRAPH_WIDGET_X_OFFSET_DP = 0;
130     private static final int DEFAULT_DOMAIN_LABEL_WIDGET_Y_OFFSET_DP = 0;
131     private static final int DEFAULT_DOMAIN_LABEL_WIDGET_X_OFFSET_DP = 20;
132     private static final int DEFAULT_RANGE_LABEL_WIDGET_Y_OFFSET_DP = 0;
133     private static final int DEFAULT_RANGE_LABEL_WIDGET_X_OFFSET_DP = 0;
134 
135     private static final int DEFAULT_GRAPH_WIDGET_TOP_MARGIN_DP = 3;
136     private static final int DEFAULT_GRAPH_WIDGET_RIGHT_MARGIN_DP = 3;
137     private static final int DEFAULT_PLOT_LEFT_MARGIN_DP = 2;
138     private static final int DEFAULT_PLOT_RIGHT_MARGIN_DP = 2;
139     private static final int DEFAULT_PLOT_BOTTOM_MARGIN_DP = 2;
140 
XYPlot(Context context, String title)141     public XYPlot(Context context, String title) {
142         super(context, title);
143     }
144 
XYPlot(Context context, String title, RenderMode mode)145     public XYPlot(Context context, String title, RenderMode mode) {
146         super(context, title, mode);
147     }
148 
XYPlot(Context context, AttributeSet attributes)149     public XYPlot(Context context, AttributeSet attributes) {
150         super(context, attributes);
151     }
152 
XYPlot(Context context, AttributeSet attrs, int defStyle)153     public XYPlot(Context context, AttributeSet attrs, int defStyle) {
154         super(context, attrs, defStyle);
155 
156     }
157 
158     @Override
onPreInit()159     protected void onPreInit() {
160         legendWidget = new XYLegendWidget(
161                 getLayoutManager(),
162                 this,
163                 new SizeMetrics(
164                         PixelUtils.dpToPix(DEFAULT_LEGEND_WIDGET_H_DP),
165                         SizeLayoutType.ABSOLUTE, 0.5f, SizeLayoutType.RELATIVE),
166                 new DynamicTableModel(0, 1),
167                 new SizeMetrics(
168                         PixelUtils.dpToPix(DEFAULT_LEGEND_WIDGET_ICON_SIZE_DP),
169                         SizeLayoutType.ABSOLUTE,
170                         PixelUtils.dpToPix(DEFAULT_LEGEND_WIDGET_ICON_SIZE_DP),
171                         SizeLayoutType.ABSOLUTE));
172 
173         graphWidget = new XYGraphWidget(
174                 getLayoutManager(),
175                 this,
176                 new SizeMetrics(
177                         PixelUtils.dpToPix(DEFAULT_GRAPH_WIDGET_H_DP),
178                         SizeLayoutType.FILL,
179                         PixelUtils.dpToPix(DEFAULT_GRAPH_WIDGET_W_DP),
180                         SizeLayoutType.FILL));
181 
182         Paint backgroundPaint = new Paint();
183         backgroundPaint.setColor(Color.DKGRAY);
184         backgroundPaint.setStyle(Paint.Style.FILL);
185         graphWidget.setBackgroundPaint(backgroundPaint);
186 
187 
188         domainLabelWidget = new TextLabelWidget(
189                 getLayoutManager(),
190                 new SizeMetrics(
191                         PixelUtils.dpToPix(DEFAULT_DOMAIN_LABEL_WIDGET_H_DP),
192                         SizeLayoutType.ABSOLUTE,
193                         PixelUtils.dpToPix(DEFAULT_DOMAIN_LABEL_WIDGET_W_DP),
194                         SizeLayoutType.ABSOLUTE),
195                 TextOrientationType.HORIZONTAL);
196         rangeLabelWidget = new TextLabelWidget(
197                 getLayoutManager(),
198                 new SizeMetrics(
199                         PixelUtils.dpToPix(DEFAULT_RANGE_LABEL_WIDGET_H_DP),
200                         SizeLayoutType.ABSOLUTE,
201                         PixelUtils.dpToPix(DEFAULT_RANGE_LABEL_WIDGET_W_DP),
202                         SizeLayoutType.ABSOLUTE),
203                 TextOrientationType.VERTICAL_ASCENDING);
204 
205         legendWidget.position(
206                 PixelUtils.dpToPix(DEFAULT_LEGEND_WIDGET_X_OFFSET_DP),
207                 XLayoutStyle.ABSOLUTE_FROM_RIGHT,
208                 PixelUtils.dpToPix(DEFAULT_LEGEND_WIDGET_Y_OFFSET_DP),
209                 YLayoutStyle.ABSOLUTE_FROM_BOTTOM,
210                 AnchorPosition.RIGHT_BOTTOM);
211 
212         graphWidget.position(
213                 PixelUtils.dpToPix(DEFAULT_GRAPH_WIDGET_X_OFFSET_DP),
214                 XLayoutStyle.ABSOLUTE_FROM_RIGHT,
215                 PixelUtils.dpToPix(DEFAULT_GRAPH_WIDGET_Y_OFFSET_DP),
216                 YLayoutStyle.ABSOLUTE_FROM_CENTER,
217                 AnchorPosition.RIGHT_MIDDLE);
218 
219         domainLabelWidget.position(
220                 PixelUtils.dpToPix(DEFAULT_DOMAIN_LABEL_WIDGET_X_OFFSET_DP),
221                 XLayoutStyle.ABSOLUTE_FROM_LEFT,
222                 PixelUtils.dpToPix(DEFAULT_DOMAIN_LABEL_WIDGET_Y_OFFSET_DP),
223                 YLayoutStyle.ABSOLUTE_FROM_BOTTOM,
224                 AnchorPosition.LEFT_BOTTOM);
225 
226         rangeLabelWidget.position(
227                 PixelUtils.dpToPix(DEFAULT_RANGE_LABEL_WIDGET_X_OFFSET_DP),
228                 XLayoutStyle.ABSOLUTE_FROM_LEFT,
229                 PixelUtils.dpToPix(DEFAULT_RANGE_LABEL_WIDGET_Y_OFFSET_DP),
230                 YLayoutStyle.ABSOLUTE_FROM_CENTER,
231                 AnchorPosition.LEFT_MIDDLE);
232 
233         getLayoutManager().moveToTop(getTitleWidget());
234         getLayoutManager().moveToTop(getLegendWidget());
235         graphWidget.setMarginTop(PixelUtils.dpToPix(DEFAULT_GRAPH_WIDGET_TOP_MARGIN_DP));
236         graphWidget.setMarginRight(PixelUtils.dpToPix(DEFAULT_GRAPH_WIDGET_RIGHT_MARGIN_DP));
237 
238         getDomainLabelWidget().pack();
239         getRangeLabelWidget().pack();
240         setPlotMarginLeft(PixelUtils.dpToPix(DEFAULT_PLOT_LEFT_MARGIN_DP));
241         setPlotMarginRight(PixelUtils.dpToPix(DEFAULT_PLOT_RIGHT_MARGIN_DP));
242         setPlotMarginBottom(PixelUtils.dpToPix(DEFAULT_PLOT_BOTTOM_MARGIN_DP));
243 
244         xValueMarkers = new ArrayList<XValueMarker>();
245         yValueMarkers = new ArrayList<YValueMarker>();
246 
247         setDefaultBounds(new RectRegion(-1, 1, -1, 1));
248     }
249 
250 
setGridPadding(float left, float top, float right, float bottom)251     public void setGridPadding(float left, float top, float right, float bottom) {
252         getGraphWidget().setGridPaddingTop(top);
253         getGraphWidget().setGridPaddingBottom(bottom);
254         getGraphWidget().setGridPaddingLeft(left);
255         getGraphWidget().setGridPaddingRight(right);
256     }
257 
258     @Override
notifyListenersBeforeDraw(Canvas canvas)259     protected void notifyListenersBeforeDraw(Canvas canvas) {
260         super.notifyListenersBeforeDraw(canvas);
261 
262         // this call must be AFTER the notify so that if the listener
263         // is a synchronized series, it has the opportunity to
264         // place a read lock on it's data.
265         calculateMinMaxVals();
266     }
267 
268     /**
269      * Checks whether the point is within the plot's graph area.
270      *
271      * @param x
272      * @param y
273      * @return
274      */
containsPoint(float x, float y)275     public boolean containsPoint(float x, float y) {
276         if (getGraphWidget().getGridRect() != null) {
277             return getGraphWidget().getGridRect().contains(x, y);
278         }
279         return false;
280     }
281 
282 
283     /**
284      * Convenience method - wraps containsPoint(PointF).
285      *
286      * @param point
287      * @return
288      */
containsPoint(PointF point)289     public boolean containsPoint(PointF point) {
290         return containsPoint(point.x, point.y);
291     }
292 
setCursorPosition(PointF point)293     public void setCursorPosition(PointF point) {
294         getGraphWidget().setCursorPosition(point);
295     }
296 
setCursorPosition(float x, float y)297     public void setCursorPosition(float x, float y) {
298         getGraphWidget().setCursorPosition(x, y);
299     }
300 
getYVal(PointF point)301     public Number getYVal(PointF point) {
302         return getGraphWidget().getYVal(point);
303     }
304 
getXVal(PointF point)305     public Number getXVal(PointF point) {
306         return getGraphWidget().getXVal(point);
307     }
308 
isXValWithinView(double xVal)309     private boolean isXValWithinView(double xVal) {
310         return (userMinY == null || xVal >= userMinY.doubleValue()) &&
311                 userMaxY == null || xVal <= userMaxY.doubleValue();
312     }
313 
isPointVisible(Number x, Number y)314     private boolean isPointVisible(Number x, Number y) {
315         // values without both an x and y val arent visible
316         if (x == null || y == null) {
317             return false;
318         }
319         return isValWithinRange(y.doubleValue(), userMinY, userMaxY) &&
320                 isValWithinRange(x.doubleValue(), userMinX, userMaxX);
321     }
322 
isValWithinRange(double val, Number min, Number max)323     private boolean isValWithinRange(double val, Number min, Number max) {
324         boolean isAboveMinThreshold = min == null || val >= min.doubleValue();
325         boolean isBelowMaxThreshold = max == null || val <= max.doubleValue();
326         return isAboveMinThreshold &&
327                 isBelowMaxThreshold;
328     }
329 
calculateMinMaxVals()330     public void calculateMinMaxVals() {
331         prevMinX = calculatedMinX;
332         prevMaxX = calculatedMaxX;
333         prevMinY = calculatedMinY;
334         prevMaxY = calculatedMaxY;
335 
336         calculatedMinX = userMinX;
337         calculatedMaxX = userMaxX;
338         calculatedMinY = userMinY;
339         calculatedMaxY = userMaxY;
340 
341         // next we go through each series to update our min/max values:
342         for (final XYSeries series : getSeriesSet()) {
343             // step through each point in each series:
344             for (int i = 0; i < series.size(); i++) {
345                 Number thisX = series.getX(i);
346                 Number thisY = series.getY(i);
347                 if (isPointVisible(thisX, thisY)) {
348                     // only calculate if a static value has not been set:
349                     if (userMinX == null) {
350                         if (thisX != null && (calculatedMinX == null ||
351                                 thisX.doubleValue() < calculatedMinX.doubleValue())) {
352                             calculatedMinX = thisX;
353                         }
354                     }
355 
356                     if (userMaxX == null) {
357                         if (thisX != null && (calculatedMaxX == null ||
358                                 thisX.doubleValue() > calculatedMaxX.doubleValue())) {
359                             calculatedMaxX = thisX;
360                         }
361                     }
362 
363                     if (userMinY == null) {
364                         if (thisY != null && (calculatedMinY == null ||
365                                 thisY.doubleValue() < calculatedMinY.doubleValue())) {
366                             calculatedMinY = thisY;
367                         }
368                     }
369 
370                     if (userMaxY == null) {
371                         if (thisY != null && (calculatedMaxY == null || thisY.doubleValue() > calculatedMaxY.doubleValue())) {
372                             calculatedMaxY = thisY;
373                         }
374                     }
375                 }
376             }
377         }
378 
379         // at this point we now know what points are going to be visible on our
380         // plot, but we still need to make corrections based on modes being used:
381         // (grow, shrink etc.)
382         switch (domainFramingModel) {
383             case ORIGIN:
384                 updateDomainMinMaxForOriginModel();
385                 break;
386             case EDGE:
387                 updateDomainMinMaxForEdgeModel();
388                 calculatedMinX = ApplyUserMinMax(calculatedMinX, domainLeftMin,
389                         domainLeftMax);
390                 calculatedMaxX = ApplyUserMinMax(calculatedMaxX,
391                         domainRightMin, domainRightMax);
392                 break;
393             default:
394                 throw new UnsupportedOperationException(
395                         "Domain Framing Model not yet supported: " + domainFramingModel);
396         }
397 
398         switch (rangeFramingModel) {
399             case ORIGIN:
400                 updateRangeMinMaxForOriginModel();
401                 break;
402             case EDGE:
403             	if (getSeriesSet().size() > 0) {
404 	                updateRangeMinMaxForEdgeModel();
405 	                calculatedMinY = ApplyUserMinMax(calculatedMinY,
406 	                        rangeBottomMin, rangeBottomMax);
407 	                calculatedMaxY = ApplyUserMinMax(calculatedMaxY, rangeTopMin,
408 	                        rangeTopMax);
409             	}
410                 break;
411             default:
412                 throw new UnsupportedOperationException(
413                         "Range Framing Model not yet supported: " + domainFramingModel);
414         }
415 
416         calculatedDomainOrigin = userDomainOrigin != null ? userDomainOrigin : getCalculatedMinX();
417         calculatedRangeOrigin = this.userRangeOrigin != null ? userRangeOrigin : getCalculatedMinY();
418     }
419 
420     /**
421      * Should ONLY be called from updateMinMax.
422      * Results are undefined otherwise.
423      */
updateDomainMinMaxForEdgeModel()424     private void updateDomainMinMaxForEdgeModel() {
425         switch (domainUpperBoundaryMode) {
426             case FIXED:
427                 break;
428             case AUTO:
429                 break;
430             case GROW:
431                 if (!(prevMaxX == null || (calculatedMaxX.doubleValue() > prevMaxX.doubleValue()))) {
432                     calculatedMaxX = prevMaxX;
433                 }
434                 break;
435             case SHRINNK:
436                 if (!(prevMaxX == null || calculatedMaxX.doubleValue() < prevMaxX.doubleValue())) {
437                     calculatedMaxX = prevMaxX;
438                 }
439                 break;
440             default:
441                 throw new UnsupportedOperationException(
442                         "DomainUpperBoundaryMode not yet implemented: " + domainUpperBoundaryMode);
443         }
444 
445         switch (domainLowerBoundaryMode) {
446             case FIXED:
447                 break;
448             case AUTO:
449                 break;
450             case GROW:
451                 if (!(prevMinX == null || calculatedMinX.doubleValue() < prevMinX.doubleValue())) {
452                     calculatedMinX = prevMinX;
453                 }
454                 break;
455             case SHRINNK:
456                 if (!(prevMinX == null || calculatedMinX.doubleValue() > prevMinX.doubleValue())) {
457                     calculatedMinX = prevMinX;
458                 }
459                 break;
460             default:
461                 throw new UnsupportedOperationException(
462                         "DomainLowerBoundaryMode not supported: " + domainLowerBoundaryMode);
463         }
464     }
465 
updateRangeMinMaxForEdgeModel()466     public void updateRangeMinMaxForEdgeModel() {
467         switch (rangeUpperBoundaryMode) {
468             case FIXED:
469                 break;
470             case AUTO:
471                 break;
472             case GROW:
473                 if (!(prevMaxY == null || calculatedMaxY.doubleValue() > prevMaxY.doubleValue())) {
474                     calculatedMaxY = prevMaxY;
475                 }
476                 break;
477             case SHRINNK:
478                 if (!(prevMaxY == null || calculatedMaxY.doubleValue() < prevMaxY.doubleValue())) {
479                     calculatedMaxY = prevMaxY;
480                 }
481                 break;
482             default:
483                 throw new UnsupportedOperationException(
484                         "RangeUpperBoundaryMode not supported: " + rangeUpperBoundaryMode);
485         }
486 
487         switch (rangeLowerBoundaryMode) {
488             case FIXED:
489                 break;
490             case AUTO:
491                 break;
492             case GROW:
493                 if (!(prevMinY == null || calculatedMinY.doubleValue() < prevMinY.doubleValue())) {
494                     calculatedMinY = prevMinY;
495                 }
496                 break;
497             case SHRINNK:
498                 if (!(prevMinY == null || calculatedMinY.doubleValue() > prevMinY.doubleValue())) {
499                     calculatedMinY = prevMinY;
500                 }
501                 break;
502             default:
503                 throw new UnsupportedOperationException(
504                         "RangeLowerBoundaryMode not supported: " + rangeLowerBoundaryMode);
505         }
506     }
507 
508     /**
509      * Apply user supplied min and max to the calculated boundary value.
510      *
511      * @param value
512      * @param min
513      * @param max
514      */
ApplyUserMinMax(Number value, Number min, Number max)515     private Number ApplyUserMinMax(Number value, Number min, Number max) {
516         value = (((min == null) || (value.doubleValue() > min.doubleValue()))
517                 ? value
518                 : min);
519         value = (((max == null) || (value.doubleValue() < max.doubleValue()))
520                 ? value
521                 : max);
522         return value;
523     }
524 
525     /**
526      * Centers the domain axis on origin.
527      *
528      * @param origin
529      */
centerOnDomainOrigin(Number origin)530     public void centerOnDomainOrigin(Number origin) {
531         centerOnDomainOrigin(origin, null, BoundaryMode.AUTO);
532     }
533 
534     /**
535      * Centers the domain on origin, calculating the upper and lower boundaries of the axis
536      * using mode and extent.
537      *
538      * @param origin
539      * @param extent
540      * @param mode
541      */
centerOnDomainOrigin(Number origin, Number extent, BoundaryMode mode)542     public void centerOnDomainOrigin(Number origin, Number extent, BoundaryMode mode) {
543         if (origin == null) {
544             throw new NullPointerException("Origin param cannot be null.");
545         }
546         domainFramingModel = XYFramingModel.ORIGIN;
547         setUserDomainOrigin(origin);
548         domainOriginExtent = extent;
549         domainOriginBoundaryMode = mode;
550 
551         if (domainOriginBoundaryMode == BoundaryMode.FIXED) {
552             double domO = userDomainOrigin.doubleValue();
553             double domE = domainOriginExtent.doubleValue();
554             userMaxX = domO + domE;
555             userMinX = domO - domE;
556         } else {
557             userMaxX = null;
558             userMinX = null;
559         }
560     }
561 
562     /**
563      * Centers the range axis on origin.
564      *
565      * @param origin
566      */
centerOnRangeOrigin(Number origin)567     public void centerOnRangeOrigin(Number origin) {
568         centerOnRangeOrigin(origin, null, BoundaryMode.AUTO);
569     }
570 
571     /**
572      * Centers the domain on origin, calculating the upper and lower boundaries of the axis
573      * using mode and extent.
574      *
575      * @param origin
576      * @param extent
577      * @param mode
578      */
579     @SuppressWarnings("SameParameterValue")
centerOnRangeOrigin(Number origin, Number extent, BoundaryMode mode)580     public void centerOnRangeOrigin(Number origin, Number extent, BoundaryMode mode) {
581         if (origin == null) {
582             throw new NullPointerException("Origin param cannot be null.");
583         }
584         rangeFramingModel = XYFramingModel.ORIGIN;
585         setUserRangeOrigin(origin);
586         rangeOriginExtent = extent;
587         rangeOriginBoundaryMode = mode;
588 
589         if (rangeOriginBoundaryMode == BoundaryMode.FIXED) {
590             double raO = userRangeOrigin.doubleValue();
591             double raE = rangeOriginExtent.doubleValue();
592             userMaxY = raO + raE;
593             userMinY = raO - raE;
594         } else {
595             userMaxY = null;
596             userMinY = null;
597         }
598     }
599 
600     /**
601      * Returns the distance between x and y.
602      * Result is never a negative number.
603      *
604      * @param x
605      * @param y
606      * @return
607      */
distance(double x, double y)608     private double distance(double x, double y) {
609         if (x > y) {
610             return x - y;
611         } else {
612             return y - x;
613         }
614     }
615 
updateDomainMinMaxForOriginModel()616     public void updateDomainMinMaxForOriginModel() {
617         double origin = userDomainOrigin.doubleValue();
618         double maxXDelta = distance(calculatedMaxX.doubleValue(), origin);
619         double minXDelta = distance(calculatedMinX.doubleValue(), origin);
620         double delta = maxXDelta > minXDelta ? maxXDelta : minXDelta;
621         double dlb = origin - delta;
622         double dub = origin + delta;
623         switch (domainOriginBoundaryMode) {
624             case AUTO:
625                 calculatedMinX = dlb;
626                 calculatedMaxX = dub;
627 
628                 break;
629             // if fixed, then the value already exists within "user" vals.
630             case FIXED:
631                 break;
632             case GROW: {
633 
634                 if (prevMinX == null || dlb < prevMinX.doubleValue()) {
635                     calculatedMinX = dlb;
636                 } else {
637                     calculatedMinX = prevMinX;
638                 }
639 
640                 if (prevMaxX == null || dub > prevMaxX.doubleValue()) {
641                     calculatedMaxX = dub;
642                 } else {
643                     calculatedMaxX = prevMaxX;
644                 }
645             }
646             break;
647             case SHRINNK:
648                 if (prevMinX == null || dlb > prevMinX.doubleValue()) {
649                     calculatedMinX = dlb;
650                 } else {
651                     calculatedMinX = prevMinX;
652                 }
653 
654                 if (prevMaxX == null || dub < prevMaxX.doubleValue()) {
655                     calculatedMaxX = dub;
656                 } else {
657                     calculatedMaxX = prevMaxX;
658                 }
659                 break;
660             default:
661                 throw new UnsupportedOperationException("Domain Origin Boundary Mode not yet supported: " + domainOriginBoundaryMode);
662         }
663     }
664 
updateRangeMinMaxForOriginModel()665     public void updateRangeMinMaxForOriginModel() {
666         switch (rangeOriginBoundaryMode) {
667             case AUTO:
668                 double origin = userRangeOrigin.doubleValue();
669                 double maxYDelta = distance(calculatedMaxY.doubleValue(), origin);
670                 double minYDelta = distance(calculatedMinY.doubleValue(), origin);
671                 if (maxYDelta > minYDelta) {
672                     calculatedMinY = origin - maxYDelta;
673                     calculatedMaxY = origin + maxYDelta;
674                 } else {
675                     calculatedMinY = origin - minYDelta;
676                     calculatedMaxY = origin + minYDelta;
677                 }
678                 break;
679             case FIXED:
680             case GROW:
681             case SHRINNK:
682             default:
683                 throw new UnsupportedOperationException(
684                         "Range Origin Boundary Mode not yet supported: " + rangeOriginBoundaryMode);
685         }
686     }
687 
688     /**
689      * Convenience method - wraps XYGraphWidget.getTicksPerRangeLabel().
690      * Equivalent to getGraphWidget().getTicksPerRangeLabel().
691      *
692      * @return
693      */
getTicksPerRangeLabel()694     public int getTicksPerRangeLabel() {
695         return graphWidget.getTicksPerRangeLabel();
696     }
697 
698     /**
699      * Convenience method - wraps XYGraphWidget.setTicksPerRangeLabel().
700      * Equivalent to getGraphWidget().setTicksPerRangeLabel().
701      *
702      * @param ticksPerRangeLabel
703      */
setTicksPerRangeLabel(int ticksPerRangeLabel)704     public void setTicksPerRangeLabel(int ticksPerRangeLabel) {
705         graphWidget.setTicksPerRangeLabel(ticksPerRangeLabel);
706     }
707 
708     /**
709      * Convenience method - wraps XYGraphWidget.getTicksPerDomainLabel().
710      * Equivalent to getGraphWidget().getTicksPerDomainLabel().
711      *
712      * @return
713      */
getTicksPerDomainLabel()714     public int getTicksPerDomainLabel() {
715         return graphWidget.getTicksPerDomainLabel();
716     }
717 
718     /**
719      * Convenience method - wraps XYGraphWidget.setTicksPerDomainLabel().
720      * Equivalent to getGraphWidget().setTicksPerDomainLabel().
721      *
722      * @param ticksPerDomainLabel
723      */
setTicksPerDomainLabel(int ticksPerDomainLabel)724     public void setTicksPerDomainLabel(int ticksPerDomainLabel) {
725         graphWidget.setTicksPerDomainLabel(ticksPerDomainLabel);
726     }
727 
getDomainStepMode()728     public XYStepMode getDomainStepMode() {
729         return domainStepMode;
730     }
731 
setDomainStepMode(XYStepMode domainStepMode)732     public void setDomainStepMode(XYStepMode domainStepMode) {
733         this.domainStepMode = domainStepMode;
734     }
735 
getDomainStepValue()736     public double getDomainStepValue() {
737         return domainStepValue;
738     }
739 
setDomainStepValue(double domainStepValue)740     public void setDomainStepValue(double domainStepValue) {
741         this.domainStepValue = domainStepValue;
742     }
743 
setDomainStep(XYStepMode mode, double value)744     public void setDomainStep(XYStepMode mode, double value) {
745         setDomainStepMode(mode);
746         setDomainStepValue(value);
747     }
748 
getRangeStepMode()749     public XYStepMode getRangeStepMode() {
750         return rangeStepMode;
751     }
752 
setRangeStepMode(XYStepMode rangeStepMode)753     public void setRangeStepMode(XYStepMode rangeStepMode) {
754         this.rangeStepMode = rangeStepMode;
755     }
756 
getRangeStepValue()757     public double getRangeStepValue() {
758         return rangeStepValue;
759     }
760 
setRangeStepValue(double rangeStepValue)761     public void setRangeStepValue(double rangeStepValue) {
762         this.rangeStepValue = rangeStepValue;
763     }
764 
setRangeStep(XYStepMode mode, double value)765     public void setRangeStep(XYStepMode mode, double value) {
766         setRangeStepMode(mode);
767         setRangeStepValue(value);
768     }
769 
getDomainLabel()770     public String getDomainLabel() {
771         return getDomainLabelWidget().getText();
772     }
773 
setDomainLabel(String domainLabel)774     public void setDomainLabel(String domainLabel) {
775         getDomainLabelWidget().setText(domainLabel);
776     }
777 
getRangeLabel()778     public String getRangeLabel() {
779         return getRangeLabelWidget().getText();
780     }
781 
setRangeLabel(String rangeLabel)782     public void setRangeLabel(String rangeLabel) {
783         getRangeLabelWidget().setText(rangeLabel);
784     }
785 
getLegendWidget()786     public XYLegendWidget getLegendWidget() {
787         return legendWidget;
788     }
789 
setLegendWidget(XYLegendWidget legendWidget)790     public void setLegendWidget(XYLegendWidget legendWidget) {
791         this.legendWidget = legendWidget;
792     }
793 
getGraphWidget()794     public XYGraphWidget getGraphWidget() {
795         return graphWidget;
796     }
797 
setGraphWidget(XYGraphWidget graphWidget)798     public void setGraphWidget(XYGraphWidget graphWidget) {
799         this.graphWidget = graphWidget;
800     }
801 
getDomainLabelWidget()802     public TextLabelWidget getDomainLabelWidget() {
803         return domainLabelWidget;
804     }
805 
setDomainLabelWidget(TextLabelWidget domainLabelWidget)806     public void setDomainLabelWidget(TextLabelWidget domainLabelWidget) {
807         this.domainLabelWidget = domainLabelWidget;
808     }
809 
getRangeLabelWidget()810     public TextLabelWidget getRangeLabelWidget() {
811         return rangeLabelWidget;
812     }
813 
setRangeLabelWidget(TextLabelWidget rangeLabelWidget)814     public void setRangeLabelWidget(TextLabelWidget rangeLabelWidget) {
815         this.rangeLabelWidget = rangeLabelWidget;
816     }
817 
818     /**
819      * Convenience method - wraps XYGraphWidget.getRangeValueFormat().
820      *
821      * @return
822      */
getRangeValueFormat()823     public Format getRangeValueFormat() {
824         return graphWidget.getRangeValueFormat();
825     }
826 
827     /**
828      * Convenience method - wraps XYGraphWidget.setRangeValueFormat().
829      *
830      * @param rangeValueFormat
831      */
setRangeValueFormat(Format rangeValueFormat)832     public void setRangeValueFormat(Format rangeValueFormat) {
833         graphWidget.setRangeValueFormat(rangeValueFormat);
834     }
835 
836     /**
837      * Convenience method - wraps XYGraphWidget.getDomainValueFormat().
838      *
839      * @return
840      */
getDomainValueFormat()841     public Format getDomainValueFormat() {
842         return graphWidget.getDomainValueFormat();
843     }
844 
845     /**
846      * Convenience method - wraps XYGraphWidget.setDomainValueFormat().
847      *
848      * @param domainValueFormat
849      */
setDomainValueFormat(Format domainValueFormat)850     public void setDomainValueFormat(Format domainValueFormat) {
851         graphWidget.setDomainValueFormat(domainValueFormat);
852     }
853 
854     /**
855      * Setup the boundary mode, boundary values only applicable in FIXED mode.
856      *
857      * @param lowerBoundary
858      * @param upperBoundary
859      * @param mode
860      */
setDomainBoundaries(Number lowerBoundary, Number upperBoundary, BoundaryMode mode)861     public synchronized void setDomainBoundaries(Number lowerBoundary, Number upperBoundary, BoundaryMode mode) {
862         setDomainBoundaries(lowerBoundary, mode, upperBoundary, mode);
863     }
864 
865     /**
866      * Setup the boundary mode, boundary values only applicable in FIXED mode.
867      *
868      * @param lowerBoundary
869      * @param lowerBoundaryMode
870      * @param upperBoundary
871      * @param upperBoundaryMode
872      */
setDomainBoundaries(Number lowerBoundary, BoundaryMode lowerBoundaryMode, Number upperBoundary, BoundaryMode upperBoundaryMode)873     public synchronized void setDomainBoundaries(Number lowerBoundary, BoundaryMode lowerBoundaryMode,
874                                                  Number upperBoundary, BoundaryMode upperBoundaryMode) {
875         setDomainLowerBoundary(lowerBoundary, lowerBoundaryMode);
876         setDomainUpperBoundary(upperBoundary, upperBoundaryMode);
877     }
878 
879     /**
880      * Setup the boundary mode, boundary values only applicable in FIXED mode.
881      *
882      * @param lowerBoundary
883      * @param upperBoundary
884      * @param mode
885      */
setRangeBoundaries(Number lowerBoundary, Number upperBoundary, BoundaryMode mode)886     public synchronized void setRangeBoundaries(Number lowerBoundary, Number upperBoundary, BoundaryMode mode) {
887         setRangeBoundaries(lowerBoundary, mode, upperBoundary, mode);
888     }
889 
890     /**
891      * Setup the boundary mode, boundary values only applicable in FIXED mode.
892      *
893      * @param lowerBoundary
894      * @param lowerBoundaryMode
895      * @param upperBoundary
896      * @param upperBoundaryMode
897      */
setRangeBoundaries(Number lowerBoundary, BoundaryMode lowerBoundaryMode, Number upperBoundary, BoundaryMode upperBoundaryMode)898     public synchronized void setRangeBoundaries(Number lowerBoundary, BoundaryMode lowerBoundaryMode,
899                                                 Number upperBoundary, BoundaryMode upperBoundaryMode) {
900         setRangeLowerBoundary(lowerBoundary, lowerBoundaryMode);
901         setRangeUpperBoundary(upperBoundary, upperBoundaryMode);
902     }
903 
setDomainUpperBoundaryMode(BoundaryMode mode)904     protected synchronized void setDomainUpperBoundaryMode(BoundaryMode mode) {
905         this.domainUpperBoundaryMode = mode;
906     }
907 
setUserMaxX(Number boundary)908     protected synchronized void setUserMaxX(Number boundary) {
909         // Ifor 12/10/2011
910         // you want null for auto grow and shrink
911         //if(boundary == null) {
912         //    throw new NullPointerException("Boundary value cannot be null.");
913         //}
914         this.userMaxX = boundary;
915     }
916 
917     /**
918      * Setup the boundary mode, boundary values only applicable in FIXED mode.
919      *
920      * @param boundary
921      * @param mode
922      */
setDomainUpperBoundary(Number boundary, BoundaryMode mode)923     public synchronized void setDomainUpperBoundary(Number boundary, BoundaryMode mode) {
924         setUserMaxX((mode == BoundaryMode.FIXED) ? boundary : null);
925         setDomainUpperBoundaryMode(mode);
926         setDomainFramingModel(XYFramingModel.EDGE);
927     }
928 
setDomainLowerBoundaryMode(BoundaryMode mode)929     protected synchronized void setDomainLowerBoundaryMode(BoundaryMode mode) {
930         this.domainLowerBoundaryMode = mode;
931     }
932 
setUserMinX(Number boundary)933     protected synchronized void setUserMinX(Number boundary) {
934         // Ifor 12/10/2011
935         // you want null for auto grow and shrink
936         //if(boundary == null) {
937         //    throw new NullPointerException("Boundary value cannot be null.");
938         //}
939         this.userMinX = boundary;
940     }
941 
942     /**
943      * Setup the boundary mode, boundary values only applicable in FIXED mode.
944      *
945      * @param boundary
946      * @param mode
947      */
setDomainLowerBoundary(Number boundary, BoundaryMode mode)948     public synchronized void setDomainLowerBoundary(Number boundary, BoundaryMode mode) {
949         setUserMinX((mode == BoundaryMode.FIXED) ? boundary : null);
950         setDomainLowerBoundaryMode(mode);
951         setDomainFramingModel(XYFramingModel.EDGE);
952         //updateMinMaxVals();
953     }
954 
setRangeUpperBoundaryMode(BoundaryMode mode)955     protected synchronized void setRangeUpperBoundaryMode(BoundaryMode mode) {
956         this.rangeUpperBoundaryMode = mode;
957     }
958 
setUserMaxY(Number boundary)959     protected synchronized void setUserMaxY(Number boundary) {
960         // Ifor 12/10/2011
961         // you want null for auto grow and shrink
962         //if(boundary == null) {
963         //    throw new NullPointerException("Boundary value cannot be null.");
964         //}
965         this.userMaxY = boundary;
966     }
967 
968     /**
969      * Setup the boundary mode, boundary values only applicable in FIXED mode.
970      *
971      * @param boundary
972      * @param mode
973      */
setRangeUpperBoundary(Number boundary, BoundaryMode mode)974     public synchronized void setRangeUpperBoundary(Number boundary, BoundaryMode mode) {
975         setUserMaxY((mode == BoundaryMode.FIXED) ? boundary : null);
976         setRangeUpperBoundaryMode(mode);
977         setRangeFramingModel(XYFramingModel.EDGE);
978     }
979 
setRangeLowerBoundaryMode(BoundaryMode mode)980     protected synchronized void setRangeLowerBoundaryMode(BoundaryMode mode) {
981         this.rangeLowerBoundaryMode = mode;
982     }
983 
setUserMinY(Number boundary)984     protected synchronized void setUserMinY(Number boundary) {
985         // Ifor 12/10/2011
986         // you want null for auto grow and shrink
987         //if(boundary == null) {
988         //    throw new NullPointerException("Boundary value cannot be null.");
989         //}
990         this.userMinY = boundary;
991     }
992 
993     /**
994      * Setup the boundary mode, boundary values only applicable in FIXED mode.
995      *
996      * @param boundary
997      * @param mode
998      */
setRangeLowerBoundary(Number boundary, BoundaryMode mode)999     public synchronized void setRangeLowerBoundary(Number boundary, BoundaryMode mode) {
1000         setUserMinY((mode == BoundaryMode.FIXED) ? boundary : null);
1001         setRangeLowerBoundaryMode(mode);
1002         setRangeFramingModel(XYFramingModel.EDGE);
1003     }
1004 
getUserMinX()1005     private Number getUserMinX() {
1006         return userMinX;
1007     }
1008 
getUserMaxX()1009     private Number getUserMaxX() {
1010         return userMaxX;
1011     }
1012 
getUserMinY()1013     private Number getUserMinY() {
1014         return userMinY;
1015     }
1016 
getUserMaxY()1017     private Number getUserMaxY() {
1018         return userMaxY;
1019     }
1020 
getDomainOrigin()1021     public Number getDomainOrigin() {
1022         return calculatedDomainOrigin;
1023     }
1024 
getRangeOrigin()1025     public Number getRangeOrigin() {
1026         return calculatedRangeOrigin;
1027     }
1028 
getDomainUpperBoundaryMode()1029     protected BoundaryMode getDomainUpperBoundaryMode() {
1030         return domainUpperBoundaryMode;
1031     }
1032 
getDomainLowerBoundaryMode()1033     protected BoundaryMode getDomainLowerBoundaryMode() {
1034         return domainLowerBoundaryMode;
1035     }
1036 
getRangeUpperBoundaryMode()1037     protected BoundaryMode getRangeUpperBoundaryMode() {
1038         return rangeUpperBoundaryMode;
1039     }
1040 
getRangeLowerBoundaryMode()1041     protected BoundaryMode getRangeLowerBoundaryMode() {
1042         return rangeLowerBoundaryMode;
1043     }
1044 
setUserDomainOrigin(Number origin)1045     public synchronized void setUserDomainOrigin(Number origin) {
1046         if (origin == null) {
1047             throw new NullPointerException("Origin value cannot be null.");
1048         }
1049         this.userDomainOrigin = origin;
1050     }
1051 
setUserRangeOrigin(Number origin)1052     public synchronized void setUserRangeOrigin(Number origin) {
1053         if (origin == null) {
1054             throw new NullPointerException("Origin value cannot be null.");
1055         }
1056         this.userRangeOrigin = origin;
1057     }
1058 
getDomainFramingModel()1059     public XYFramingModel getDomainFramingModel() {
1060         return domainFramingModel;
1061     }
1062 
1063     @SuppressWarnings("SameParameterValue")
setDomainFramingModel(XYFramingModel domainFramingModel)1064     protected void setDomainFramingModel(XYFramingModel domainFramingModel) {
1065         this.domainFramingModel = domainFramingModel;
1066     }
1067 
getRangeFramingModel()1068     public XYFramingModel getRangeFramingModel() {
1069 
1070         return rangeFramingModel;
1071     }
1072 
1073     @SuppressWarnings("SameParameterValue")
setRangeFramingModel(XYFramingModel rangeFramingModel)1074     protected void setRangeFramingModel(XYFramingModel rangeFramingModel) {
1075         this.rangeFramingModel = rangeFramingModel;
1076     }
1077 
1078     /**
1079      * CalculatedMinX value after the the framing model has been applied.
1080      *
1081      * @return
1082      */
getCalculatedMinX()1083     public Number getCalculatedMinX() {
1084         return calculatedMinX != null ? calculatedMinX : getDefaultBounds().getMinX();
1085     }
1086 
1087     /**
1088      * CalculatedMaxX value after the the framing model has been applied.
1089      *
1090      * @return
1091      */
getCalculatedMaxX()1092     public Number getCalculatedMaxX() {
1093         return calculatedMaxX != null ? calculatedMaxX : getDefaultBounds().getMaxX();
1094     }
1095 
1096     /**
1097      * CalculatedMinY value after the the framing model has been applied.
1098      *
1099      * @return
1100      */
getCalculatedMinY()1101     public Number getCalculatedMinY() {
1102         return calculatedMinY != null ? calculatedMinY : getDefaultBounds().getMinY();
1103     }
1104 
1105     /**
1106      * CalculatedMaxY value after the the framing model has been applied.
1107      *
1108      * @return
1109      */
getCalculatedMaxY()1110     public Number getCalculatedMaxY() {
1111         return calculatedMaxY != null ? calculatedMaxY : getDefaultBounds().getMaxY();
1112     }
1113 
isDrawDomainOriginEnabled()1114     public boolean isDrawDomainOriginEnabled() {
1115         return drawDomainOriginEnabled;
1116     }
1117 
setDrawDomainOriginEnabled(boolean drawDomainOriginEnabled)1118     public void setDrawDomainOriginEnabled(boolean drawDomainOriginEnabled) {
1119         this.drawDomainOriginEnabled = drawDomainOriginEnabled;
1120     }
1121 
isDrawRangeOriginEnabled()1122     public boolean isDrawRangeOriginEnabled() {
1123         return drawRangeOriginEnabled;
1124     }
1125 
setDrawRangeOriginEnabled(boolean drawRangeOriginEnabled)1126     public void setDrawRangeOriginEnabled(boolean drawRangeOriginEnabled) {
1127         this.drawRangeOriginEnabled = drawRangeOriginEnabled;
1128     }
1129 
1130     /**
1131      * Appends the specified marker to the end of plot's yValueMarkers list.
1132      *
1133      * @param marker The YValueMarker to be added.
1134      * @return true if the object was successfully added, false otherwise.
1135      */
addMarker(YValueMarker marker)1136     public boolean addMarker(YValueMarker marker) {
1137         if (yValueMarkers.contains(marker)) {
1138             return false;
1139         } else {
1140             return yValueMarkers.add(marker);
1141         }
1142     }
1143 
1144     /**
1145      * Removes the specified marker from the plot.
1146      *
1147      * @param marker
1148      * @return The YValueMarker removed if successfull,  null otherwise.
1149      */
removeMarker(YValueMarker marker)1150     public YValueMarker removeMarker(YValueMarker marker) {
1151         int markerIndex = yValueMarkers.indexOf(marker);
1152         if (markerIndex == -1) {
1153             return null;
1154         } else {
1155             return yValueMarkers.remove(markerIndex);
1156         }
1157     }
1158 
1159     /**
1160      * Convenience method - combines removeYMarkers() and removeXMarkers().
1161      *
1162      * @return
1163      */
removeMarkers()1164     public int removeMarkers() {
1165         int removed = removeXMarkers();
1166         removed += removeYMarkers();
1167         return removed;
1168     }
1169 
1170     /**
1171      * Removes all YValueMarker instances from the plot.
1172      *
1173      * @return
1174      */
removeYMarkers()1175     public int removeYMarkers() {
1176         int numMarkersRemoved = yValueMarkers.size();
1177         yValueMarkers.clear();
1178         return numMarkersRemoved;
1179     }
1180 
1181     /**
1182      * Appends the specified marker to the end of plot's xValueMarkers list.
1183      *
1184      * @param marker The XValueMarker to be added.
1185      * @return true if the object was successfully added, false otherwise.
1186      */
addMarker(XValueMarker marker)1187     public boolean addMarker(XValueMarker marker) {
1188         return !xValueMarkers.contains(marker) && xValueMarkers.add(marker);
1189     }
1190 
1191     /**
1192      * Removes the specified marker from the plot.
1193      *
1194      * @param marker
1195      * @return The XValueMarker removed if successfull,  null otherwise.
1196      */
removeMarker(XValueMarker marker)1197     public XValueMarker removeMarker(XValueMarker marker) {
1198         int markerIndex = xValueMarkers.indexOf(marker);
1199         if (markerIndex == -1) {
1200             return null;
1201         } else {
1202             return xValueMarkers.remove(markerIndex);
1203         }
1204     }
1205 
1206     /**
1207      * Removes all XValueMarker instances from the plot.
1208      *
1209      * @return
1210      */
removeXMarkers()1211     public int removeXMarkers() {
1212         int numMarkersRemoved = xValueMarkers.size();
1213         xValueMarkers.clear();
1214         return numMarkersRemoved;
1215     }
1216 
getYValueMarkers()1217     protected List<YValueMarker> getYValueMarkers() {
1218         return yValueMarkers;
1219     }
1220 
getXValueMarkers()1221     protected List<XValueMarker> getXValueMarkers() {
1222         return xValueMarkers;
1223     }
1224 
getDefaultBounds()1225     public RectRegion getDefaultBounds() {
1226         return defaultBounds;
1227     }
1228 
setDefaultBounds(RectRegion defaultBounds)1229     public void setDefaultBounds(RectRegion defaultBounds) {
1230         this.defaultBounds = defaultBounds;
1231     }
1232 
1233     /**
1234      * @return the rangeTopMin
1235      */
getRangeTopMin()1236     public Number getRangeTopMin() {
1237         return rangeTopMin;
1238     }
1239 
1240     /**
1241      * @param rangeTopMin the rangeTopMin to set
1242      */
setRangeTopMin(Number rangeTopMin)1243     public synchronized void setRangeTopMin(Number rangeTopMin) {
1244         this.rangeTopMin = rangeTopMin;
1245     }
1246 
1247     /**
1248      * @return the rangeTopMax
1249      */
getRangeTopMax()1250     public Number getRangeTopMax() {
1251         return rangeTopMax;
1252     }
1253 
1254     /**
1255      * @param rangeTopMax the rangeTopMax to set
1256      */
setRangeTopMax(Number rangeTopMax)1257     public synchronized void setRangeTopMax(Number rangeTopMax) {
1258         this.rangeTopMax = rangeTopMax;
1259     }
1260 
1261     /**
1262      * @return the rangeBottomMin
1263      */
getRangeBottomMin()1264     public Number getRangeBottomMin() {
1265         return rangeBottomMin;
1266     }
1267 
1268     /**
1269      * @param rangeBottomMin the rangeBottomMin to set
1270      */
setRangeBottomMin(Number rangeBottomMin)1271     public synchronized void setRangeBottomMin(Number rangeBottomMin) {
1272         this.rangeBottomMin = rangeBottomMin;
1273     }
1274 
1275     /**
1276      * @return the rangeBottomMax
1277      */
getRangeBottomMax()1278     public Number getRangeBottomMax() {
1279         return rangeBottomMax;
1280     }
1281 
1282     /**
1283      * @param rangeBottomMax the rangeBottomMax to set
1284      */
setRangeBottomMax(Number rangeBottomMax)1285     public synchronized void setRangeBottomMax(Number rangeBottomMax) {
1286         this.rangeBottomMax = rangeBottomMax;
1287     }
1288 
1289     /**
1290      * @return the domainLeftMin
1291      */
getDomainLeftMin()1292     public Number getDomainLeftMin() {
1293         return domainLeftMin;
1294     }
1295 
1296     /**
1297      * @param domainLeftMin the domainLeftMin to set
1298      */
setDomainLeftMin(Number domainLeftMin)1299     public synchronized void setDomainLeftMin(Number domainLeftMin) {
1300         this.domainLeftMin = domainLeftMin;
1301     }
1302 
1303     /**
1304      * @return the domainLeftMax
1305      */
getDomainLeftMax()1306     public Number getDomainLeftMax() {
1307         return domainLeftMax;
1308     }
1309 
1310     /**
1311      * @param domainLeftMax the domainLeftMax to set
1312      */
setDomainLeftMax(Number domainLeftMax)1313     public synchronized void setDomainLeftMax(Number domainLeftMax) {
1314         this.domainLeftMax = domainLeftMax;
1315     }
1316 
1317     /**
1318      * @return the domainRightMin
1319      */
getDomainRightMin()1320     public Number getDomainRightMin() {
1321         return domainRightMin;
1322     }
1323 
1324     /**
1325      * @param domainRightMin the domainRightMin to set
1326      */
setDomainRightMin(Number domainRightMin)1327     public synchronized void setDomainRightMin(Number domainRightMin) {
1328         this.domainRightMin = domainRightMin;
1329     }
1330 
1331     /**
1332      * @return the domainRightMax
1333      */
getDomainRightMax()1334     public Number getDomainRightMax() {
1335         return domainRightMax;
1336     }
1337 
1338     /**
1339      * @param domainRightMax the domainRightMax to set
1340      */
setDomainRightMax(Number domainRightMax)1341     public synchronized void setDomainRightMax(Number domainRightMax) {
1342         this.domainRightMax = domainRightMax;
1343     }
1344 }