1:
42:
43: package ;
44:
45: import ;
46:
47: import ;
48: import ;
49: import ;
50:
51:
55: public class ModuloAxis extends NumberAxis {
56:
57:
61: private Range fixedRange;
62:
63:
67: private double displayStart;
68:
69:
72: private double displayEnd;
73:
74:
80: public ModuloAxis(String label, Range fixedRange) {
81: super(label);
82: this.fixedRange = fixedRange;
83: this.displayStart = 270.0;
84: this.displayEnd = 90.0;
85: }
86:
87:
92: public double getDisplayStart() {
93: return this.displayStart;
94: }
95:
96:
101: public double getDisplayEnd() {
102: return this.displayEnd;
103: }
104:
105:
112: public void setDisplayRange(double start, double end) {
113: this.displayStart = mapValueToFixedRange(start);
114: this.displayEnd = mapValueToFixedRange(end);
115: if (this.displayStart < this.displayEnd) {
116: setRange(this.displayStart, this.displayEnd);
117: }
118: else {
119: setRange(
120: this.displayStart,
121: this.fixedRange.getUpperBound()
122: + (this.displayEnd - this.fixedRange.getLowerBound())
123: );
124: }
125: notifyListeners(new AxisChangeEvent(this));
126: }
127:
128:
132: protected void autoAdjustRange() {
133: setRange(this.fixedRange, false, false);
134: }
135:
136:
145: public double valueToJava2D(double value, Rectangle2D area,
146: RectangleEdge edge) {
147: double result = 0.0;
148: double v = mapValueToFixedRange(value);
149: if (this.displayStart < this.displayEnd) {
150: result = trans(v, area, edge);
151: }
152: else {
153: double cutoff = (this.displayStart + this.displayEnd) / 2.0;
154: double length1 = this.fixedRange.getUpperBound()
155: - this.displayStart;
156: double length2 = this.displayEnd - this.fixedRange.getLowerBound();
157: if (v > cutoff) {
158: result = transStart(v, area, edge, length1, length2);
159: }
160: else {
161: result = transEnd(v, area, edge, length1, length2);
162: }
163: }
164: return result;
165: }
166:
167:
176: private double trans(double value, Rectangle2D area, RectangleEdge edge) {
177: double min = 0.0;
178: double max = 0.0;
179: if (RectangleEdge.isTopOrBottom(edge)) {
180: min = area.getX();
181: max = area.getX() + area.getWidth();
182: }
183: else if (RectangleEdge.isLeftOrRight(edge)) {
184: min = area.getMaxY();
185: max = area.getMaxY() - area.getHeight();
186: }
187: if (isInverted()) {
188: return max - ((value - this.displayStart)
189: / (this.displayEnd - this.displayStart)) * (max - min);
190: }
191: else {
192: return min + ((value - this.displayStart)
193: / (this.displayEnd - this.displayStart)) * (max - min);
194: }
195:
196: }
197:
198:
210: private double transStart(double value, Rectangle2D area,
211: RectangleEdge edge,
212: double length1, double length2) {
213: double min = 0.0;
214: double max = 0.0;
215: if (RectangleEdge.isTopOrBottom(edge)) {
216: min = area.getX();
217: max = area.getX() + area.getWidth() * length1 / (length1 + length2);
218: }
219: else if (RectangleEdge.isLeftOrRight(edge)) {
220: min = area.getMaxY();
221: max = area.getMaxY() - area.getHeight() * length1
222: / (length1 + length2);
223: }
224: if (isInverted()) {
225: return max - ((value - this.displayStart)
226: / (this.fixedRange.getUpperBound() - this.displayStart))
227: * (max - min);
228: }
229: else {
230: return min + ((value - this.displayStart)
231: / (this.fixedRange.getUpperBound() - this.displayStart))
232: * (max - min);
233: }
234:
235: }
236:
237:
249: private double transEnd(double value, Rectangle2D area, RectangleEdge edge,
250: double length1, double length2) {
251: double min = 0.0;
252: double max = 0.0;
253: if (RectangleEdge.isTopOrBottom(edge)) {
254: max = area.getMaxX();
255: min = area.getMaxX() - area.getWidth() * length2
256: / (length1 + length2);
257: }
258: else if (RectangleEdge.isLeftOrRight(edge)) {
259: max = area.getMinY();
260: min = area.getMinY() + area.getHeight() * length2
261: / (length1 + length2);
262: }
263: if (isInverted()) {
264: return max - ((value - this.fixedRange.getLowerBound())
265: / (this.displayEnd - this.fixedRange.getLowerBound()))
266: * (max - min);
267: }
268: else {
269: return min + ((value - this.fixedRange.getLowerBound())
270: / (this.displayEnd - this.fixedRange.getLowerBound()))
271: * (max - min);
272: }
273:
274: }
275:
276:
283: private double mapValueToFixedRange(double value) {
284: double lower = this.fixedRange.getLowerBound();
285: double length = this.fixedRange.getLength();
286: if (value < lower) {
287: return lower + length + ((value - lower) % length);
288: }
289: else {
290: return lower + ((value - lower) % length);
291: }
292: }
293:
294:
303: public double java2DToValue(double java2DValue, Rectangle2D area,
304: RectangleEdge edge) {
305: double result = 0.0;
306: if (this.displayStart < this.displayEnd) {
307: result = super.java2DToValue(java2DValue, area, edge);
308: }
309: else {
310:
311: }
312: return result;
313: }
314:
315:
320: private double getDisplayLength() {
321: if (this.displayStart < this.displayEnd) {
322: return (this.displayEnd - this.displayStart);
323: }
324: else {
325: return (this.fixedRange.getUpperBound() - this.displayStart)
326: + (this.displayEnd - this.fixedRange.getLowerBound());
327: }
328: }
329:
330:
335: private double getDisplayCentralValue() {
336: return mapValueToFixedRange(
337: this.displayStart + (getDisplayLength() / 2)
338: );
339: }
340:
341:
351: public void resizeRange(double percent) {
352: resizeRange(percent, getDisplayCentralValue());
353: }
354:
355:
366: public void resizeRange(double percent, double anchorValue) {
367:
368: if (percent > 0.0) {
369: double halfLength = getDisplayLength() * percent / 2;
370: setDisplayRange(anchorValue - halfLength, anchorValue + halfLength);
371: }
372: else {
373: setAutoRange(true);
374: }
375:
376: }
377:
378:
388: public double lengthToJava2D(double length, Rectangle2D area,
389: RectangleEdge edge) {
390: double axisLength = 0.0;
391: if (this.displayEnd > this.displayStart) {
392: axisLength = this.displayEnd - this.displayStart;
393: }
394: else {
395: axisLength = (this.fixedRange.getUpperBound() - this.displayStart)
396: + (this.displayEnd - this.fixedRange.getLowerBound());
397: }
398: double areaLength = 0.0;
399: if (RectangleEdge.isLeftOrRight(edge)) {
400: areaLength = area.getHeight();
401: }
402: else {
403: areaLength = area.getWidth();
404: }
405: return (length / axisLength) * areaLength;
406: }
407:
408: }