1 42 43 package org.jfree.chart.axis; 44 45 import java.awt.geom.Rectangle2D ; 46 47 import org.jfree.chart.event.AxisChangeEvent; 48 import org.jfree.data.Range; 49 import org.jfree.ui.RectangleEdge; 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) { result = trans(v, area, edge); 151 } 152 else { 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) { result = super.java2DToValue(java2DValue, area, edge); 308 } 309 else { 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 } 409 | Popular Tags |