1:
41:
42: package ;
43:
44: import ;
45:
46: import ;
47: import ;
48: import ;
49:
50:
54: public class ModuloAxis extends NumberAxis {
55:
56:
60: private Range fixedRange;
61:
62:
66: private double displayStart;
67:
68:
71: private double displayEnd;
72:
73:
79: public ModuloAxis(String label, Range fixedRange) {
80: super(label);
81: this.fixedRange = fixedRange;
82: this.displayStart = 270.0;
83: this.displayEnd = 90.0;
84: }
85:
86:
91: public double getDisplayStart() {
92: return this.displayStart;
93: }
94:
95:
100: public double getDisplayEnd() {
101: return this.displayEnd;
102: }
103:
104:
111: public void setDisplayRange(double start, double end) {
112: this.displayStart = mapValueToFixedRange(start);
113: this.displayEnd = mapValueToFixedRange(end);
114: if (this.displayStart < this.displayEnd) {
115: setRange(this.displayStart, this.displayEnd);
116: }
117: else {
118: setRange(this.displayStart, this.fixedRange.getUpperBound()
119: + (this.displayEnd - this.fixedRange.getLowerBound()));
120: }
121: notifyListeners(new AxisChangeEvent(this));
122: }
123:
124:
128: protected void autoAdjustRange() {
129: setRange(this.fixedRange, false, false);
130: }
131:
132:
141: public double valueToJava2D(double value, Rectangle2D area,
142: RectangleEdge edge) {
143: double result = 0.0;
144: double v = mapValueToFixedRange(value);
145: if (this.displayStart < this.displayEnd) {
146: result = trans(v, area, edge);
147: }
148: else {
149: double cutoff = (this.displayStart + this.displayEnd) / 2.0;
150: double length1 = this.fixedRange.getUpperBound()
151: - this.displayStart;
152: double length2 = this.displayEnd - this.fixedRange.getLowerBound();
153: if (v > cutoff) {
154: result = transStart(v, area, edge, length1, length2);
155: }
156: else {
157: result = transEnd(v, area, edge, length1, length2);
158: }
159: }
160: return result;
161: }
162:
163:
172: private double trans(double value, Rectangle2D area, RectangleEdge edge) {
173: double min = 0.0;
174: double max = 0.0;
175: if (RectangleEdge.isTopOrBottom(edge)) {
176: min = area.getX();
177: max = area.getX() + area.getWidth();
178: }
179: else if (RectangleEdge.isLeftOrRight(edge)) {
180: min = area.getMaxY();
181: max = area.getMaxY() - area.getHeight();
182: }
183: if (isInverted()) {
184: return max - ((value - this.displayStart)
185: / (this.displayEnd - this.displayStart)) * (max - min);
186: }
187: else {
188: return min + ((value - this.displayStart)
189: / (this.displayEnd - this.displayStart)) * (max - min);
190: }
191:
192: }
193:
194:
206: private double transStart(double value, Rectangle2D area,
207: RectangleEdge edge,
208: double length1, double length2) {
209: double min = 0.0;
210: double max = 0.0;
211: if (RectangleEdge.isTopOrBottom(edge)) {
212: min = area.getX();
213: max = area.getX() + area.getWidth() * length1 / (length1 + length2);
214: }
215: else if (RectangleEdge.isLeftOrRight(edge)) {
216: min = area.getMaxY();
217: max = area.getMaxY() - area.getHeight() * length1
218: / (length1 + length2);
219: }
220: if (isInverted()) {
221: return max - ((value - this.displayStart)
222: / (this.fixedRange.getUpperBound() - this.displayStart))
223: * (max - min);
224: }
225: else {
226: return min + ((value - this.displayStart)
227: / (this.fixedRange.getUpperBound() - this.displayStart))
228: * (max - min);
229: }
230:
231: }
232:
233:
245: private double transEnd(double value, Rectangle2D area, RectangleEdge edge,
246: double length1, double length2) {
247: double min = 0.0;
248: double max = 0.0;
249: if (RectangleEdge.isTopOrBottom(edge)) {
250: max = area.getMaxX();
251: min = area.getMaxX() - area.getWidth() * length2
252: / (length1 + length2);
253: }
254: else if (RectangleEdge.isLeftOrRight(edge)) {
255: max = area.getMinY();
256: min = area.getMinY() + area.getHeight() * length2
257: / (length1 + length2);
258: }
259: if (isInverted()) {
260: return max - ((value - this.fixedRange.getLowerBound())
261: / (this.displayEnd - this.fixedRange.getLowerBound()))
262: * (max - min);
263: }
264: else {
265: return min + ((value - this.fixedRange.getLowerBound())
266: / (this.displayEnd - this.fixedRange.getLowerBound()))
267: * (max - min);
268: }
269:
270: }
271:
272:
279: private double mapValueToFixedRange(double value) {
280: double lower = this.fixedRange.getLowerBound();
281: double length = this.fixedRange.getLength();
282: if (value < lower) {
283: return lower + length + ((value - lower) % length);
284: }
285: else {
286: return lower + ((value - lower) % length);
287: }
288: }
289:
290:
299: public double java2DToValue(double java2DValue, Rectangle2D area,
300: RectangleEdge edge) {
301: double result = 0.0;
302: if (this.displayStart < this.displayEnd) {
303: result = super.java2DToValue(java2DValue, area, edge);
304: }
305: else {
306:
307: }
308: return result;
309: }
310:
311:
316: private double getDisplayLength() {
317: if (this.displayStart < this.displayEnd) {
318: return (this.displayEnd - this.displayStart);
319: }
320: else {
321: return (this.fixedRange.getUpperBound() - this.displayStart)
322: + (this.displayEnd - this.fixedRange.getLowerBound());
323: }
324: }
325:
326:
331: private double getDisplayCentralValue() {
332: return mapValueToFixedRange(
333: this.displayStart + (getDisplayLength() / 2)
334: );
335: }
336:
337:
347: public void resizeRange(double percent) {
348: resizeRange(percent, getDisplayCentralValue());
349: }
350:
351:
362: public void resizeRange(double percent, double anchorValue) {
363:
364: if (percent > 0.0) {
365: double halfLength = getDisplayLength() * percent / 2;
366: setDisplayRange(anchorValue - halfLength, anchorValue + halfLength);
367: }
368: else {
369: setAutoRange(true);
370: }
371:
372: }
373:
374:
384: public double lengthToJava2D(double length, Rectangle2D area,
385: RectangleEdge edge) {
386: double axisLength = 0.0;
387: if (this.displayEnd > this.displayStart) {
388: axisLength = this.displayEnd - this.displayStart;
389: }
390: else {
391: axisLength = (this.fixedRange.getUpperBound() - this.displayStart)
392: + (this.displayEnd - this.fixedRange.getLowerBound());
393: }
394: double areaLength = 0.0;
395: if (RectangleEdge.isLeftOrRight(edge)) {
396: areaLength = area.getHeight();
397: }
398: else {
399: areaLength = area.getWidth();
400: }
401: return (length / axisLength) * areaLength;
402: }
403:
404:
411: public boolean equals(Object obj) {
412: if (obj == this) {
413: return true;
414: }
415: if (!(obj instanceof ModuloAxis)) {
416: return false;
417: }
418: ModuloAxis that = (ModuloAxis) obj;
419: if (this.displayStart != that.displayStart) {
420: return false;
421: }
422: if (this.displayEnd != that.displayEnd) {
423: return false;
424: }
425: if (!this.fixedRange.equals(that.fixedRange)) {
426: return false;
427: }
428: return super.equals(obj);
429: }
430:
431: }