1 23 24 package de.progra.charting; 25 26 import java.awt.font.FontRenderContext ; 27 import java.text.DecimalFormat ; 28 import java.awt.geom.AffineTransform ; 29 import java.awt.geom.Line2D ; 30 import java.awt.geom.Point2D ; 31 import java.awt.geom.Rectangle2D ; 32 import java.awt.Color ; 33 import java.awt.Font ; 34 import java.awt.Graphics2D ; 35 import java.awt.font.TextLayout ; 36 import de.progra.charting.model.ChartDataModelConstraints; 37 import de.progra.charting.model.ChartDataModel; 38 39 45 public class CoordSystemUtilities { 46 47 48 protected final int marginOffset = 6; 49 50 protected CoordSystem c; 51 protected ChartDataModelConstraints constraints; 52 protected ChartDataModelConstraints constraints2; 53 protected ChartDataModel model; 54 55 56 public CoordSystemUtilities(CoordSystem coord, 57 ChartDataModelConstraints constraints, 58 ChartDataModelConstraints constraints2, 59 ChartDataModel model) { 60 c = coord; 61 this.constraints = constraints; 62 this.constraints2 = constraints2; 63 this.model = model; 64 } 65 66 67 public int computeLeftMargin() { 68 double xmin = constraints.getMinimumColumnValue(); 69 double xmax = constraints.getMaximumColumnValue(); 70 71 if (xmin <= 0 && xmax > 0) { 72 xmin = Math.abs(xmin); 73 xmax = Math.abs(xmax); 74 75 TextLayout layout = new TextLayout (c.getYAxisUnit(), c.getFont(), 76 c.getFontRenderContext()); 77 78 int maxlmargin = computeYAxisLabelWidth() + marginOffset; 81 maxlmargin = Math.max(maxlmargin, (int) layout.getBounds().getWidth() + marginOffset); 83 84 85 int margin = (int)(maxlmargin - (xmin / (xmin + xmax)) * (c.getBounds().getWidth() - c.getRightMargin())); 86 87 margin += 5; 89 if(margin < c.MINIMALMARGIN) 90 margin = c.MINIMALMARGIN; 91 92 return margin; 93 } else { 94 return c.MINIMALMARGIN; 95 } 96 } 97 98 99 public int computeRightMargin() { 100 TextLayout layout = new TextLayout (c.getXAxisUnit(), c.getFont(), 101 c.getFontRenderContext()); 102 return Math.max((int)(layout.getBounds().getWidth() + (double)c.ARROWLENGTH / 3) , c.ARROWLENGTH); 103 } 104 105 106 public int computeTopMargin() { 107 TextLayout layout = new TextLayout (c.getYAxisUnit(), c.getFont(), 108 c.getFontRenderContext()); 109 return Math.max((int)(layout.getBounds().getHeight() + (double)c.ARROWLENGTH / 3 + layout.getDescent()), c.ARROWLENGTH); 110 } 111 112 113 public int computeBottomMargin() { 114 double ymin = constraints.getMinimumValue().doubleValue(); 115 double ymax = constraints.getMaximumValue().doubleValue(); 116 117 if (ymin <= 0 && ymax > 0) { 118 ymin = Math.abs(ymin); 119 ymax = Math.abs(ymax); 120 121 TextLayout layout = new TextLayout (c.getXAxisUnit(), c.getFont(), 122 c.getFontRenderContext()); 123 124 int maxbmargin = computeXAxisLabelHeight() + marginOffset; 127 maxbmargin = Math.max(maxbmargin, (int) layout.getBounds().getHeight() + marginOffset); 129 130 131 int margin = (int)(maxbmargin - (ymin / (ymin + ymax)) * (c.getBounds().getHeight() - c.getTopMargin())); 132 133 margin += 10; 135 if(margin < c.MINIMALMARGIN) 136 margin = c.MINIMALMARGIN; 137 138 return margin; 139 } else { 140 return c.MINIMALMARGIN; 141 } 142 } 143 144 145 public int computeXAxisLabelHeight() { 146 double min = constraints.getMinimumColumnValue(); 147 double max = constraints.getMaximumColumnValue(); 148 double tick = ChartUtilities.calculateTickSpacing(min, max); 149 double ypt = 0; 150 151 int height = 0; 152 153 if(constraints.getMinimumValue().doubleValue() > 0) 154 ypt = constraints.getMinimumValue().doubleValue(); 155 else if(constraints.getMaximumValue().doubleValue() < 0) 156 ypt = constraints.getMaximumValue().doubleValue(); 157 boolean paint = false; 158 159 DecimalFormat df = c.getXDecimalFormat(); 160 FontRenderContext frc = c.getFontRenderContext(); 161 Font f = c.getFont(); 162 163 for(double d = min; d <= max; d += tick) { 164 if(paint) { 165 String sb = df.format(d); 166 Rectangle2D r = f.getStringBounds(sb, frc); 167 168 height = Math.max(height, (int)r.getHeight()); 169 } 170 paint = !paint; 171 } 172 173 return height; 174 } 175 176 177 public int computeYAxisLabelWidth() { 178 double min = constraints.getMinimumValue().doubleValue(); 179 double max = constraints.getMaximumValue().doubleValue(); 180 double tick = ChartUtilities.calculateTickSpacing(min, max); 181 double xpt = 0; 182 183 int width = 0; 184 185 if(constraints.getMinimumColumnValue() > 0) 187 xpt = constraints.getMinimumColumnValue(); 188 else if(constraints.getMaximumColumnValue() < 0 && c.getSecondYAxis() != null) 189 xpt = constraints.getMaximumColumnValue(); 190 191 boolean paint = false; 192 193 DecimalFormat df = c.getYDecimalFormat(); 194 FontRenderContext frc = c.getFontRenderContext(); 195 Font f = c.getFont(); 196 197 for(double d = min; d <= max; d += tick) { 198 if(paint) { 199 String sb = df.format(d); 200 Rectangle2D r = f.getStringBounds(sb, frc); 201 202 width = Math.max((int)r.getWidth(), width); 203 } 204 paint = !paint; 205 } 206 207 return width; 208 } 209 210 214 public void drawNumericalXAxisTicks(Graphics2D g) { 215 AffineTransform at = c.getTransform(CoordSystem.FIRST_YAXIS); 216 217 double min = constraints.getMinimumColumnValue(); 218 double max = constraints.getMaximumColumnValue(); 219 double tick = ChartUtilities.calculateTickSpacing(min, max); 220 double ypt = 0; 221 222 if(constraints.getMinimumValue().doubleValue() > 0) 223 ypt = constraints.getMinimumValue().doubleValue(); 224 else if(constraints.getMaximumValue().doubleValue() < 0) 225 ypt = constraints.getMaximumValue().doubleValue(); 226 227 Point2D p = new Point2D.Double (0.0, 0.0); 228 Point2D v; 229 Line2D ticks = new Line2D.Double (0.0, 0.0, 0.0, 0.0); 230 231 DecimalFormat df = c.getXDecimalFormat(); 232 FontRenderContext frc = c.getFontRenderContext(); 233 Font f = c.getFont(); 234 235 boolean paint = false; 236 237 g.setFont(f); 238 boolean paintLabels = c.isPaintLabels(); 239 240 for(double d = min; d <= max; d += tick) { 241 p.setLocation(d, ypt); 242 v = at.transform(p, null); 243 244 ticks.setLine(v.getX(), v.getY() - marginOffset/2, v.getX(), v.getY() + marginOffset/2); 245 g.draw(ticks); 246 if(paint && paintLabels) { 247 String sb = df.format(d); 248 Rectangle2D r = f.getStringBounds(sb, frc); 249 250 g.drawString(sb, (float)(v.getX() - r.getWidth() / 2), 251 (float)(v.getY() + r.getHeight() + marginOffset)); 252 } 253 paint = !paint; 254 } 255 } 256 257 261 public void drawXAxisTicks(Graphics2D g) { 262 AffineTransform at = c.getTransform(CoordSystem.FIRST_YAXIS); 263 264 int min = (int)constraints.getMinimumColumnValue(); 265 int max = (int)constraints.getMaximumColumnValue(); 266 double tick = 1.0; 267 double ypt = 0; 268 269 if(constraints.getMinimumValue().doubleValue() > 0) 270 ypt = constraints.getMinimumValue().doubleValue(); 271 else if(constraints.getMaximumValue().doubleValue() < 0) 272 ypt = constraints.getMaximumValue().doubleValue(); 273 274 Point2D p = new Point2D.Double (0.0, 0.0); 275 Point2D v = null; 276 Point2D oldv = null; 277 278 Line2D ticks = new Line2D.Double (0.0, 0.0, 0.0, 0.0); 279 280 DecimalFormat df = c.getXDecimalFormat(); 281 FontRenderContext frc = c.getFontRenderContext(); 282 Font f = c.getFont(); 283 284 boolean paint = false; 285 boolean paintLabels = c.isPaintLabels(); 286 g.setFont(f); 287 288 for(int i = min - 1; i < max; i++) { 289 p.setLocation(i + 1, ypt); 290 291 v = at.transform(p, null); 292 293 ticks.setLine(v.getX(), v.getY() - marginOffset/2, v.getX(), v.getY() + marginOffset/2); 294 295 if(i + 1 < max) 296 g.draw(ticks); 297 298 if(oldv != null && paintLabels) { 300 String sb = (String )model.getColumnValueAt(i); 301 Rectangle2D r = f.getStringBounds(sb, frc); 302 303 g.drawString(sb, (float)(oldv.getX()+(v.getX() - oldv.getX()) / 2 - r.getWidth() / 2), 304 (float)(v.getY() + r.getHeight() + marginOffset)); 305 } 306 307 oldv = v; 308 } 309 } 310 311 315 public void drawYAxisTicks(Graphics2D g) { 316 AffineTransform at = c.getTransform(CoordSystem.FIRST_YAXIS); 317 318 double min = constraints.getMinimumValue().doubleValue(); 319 double max = constraints.getMaximumValue().doubleValue(); 320 double tick = ChartUtilities.calculateTickSpacing(min, max); 321 double xpt = 0; 322 323 if(constraints.getMinimumColumnValue() > 0) 325 xpt = constraints.getMinimumColumnValue(); 326 else if(constraints.getMaximumColumnValue() < 0 && c.getSecondYAxis() != null) 327 xpt = constraints.getMaximumColumnValue(); 328 329 Point2D p = new Point2D.Double (0.0, 0.0); 330 Point2D v; 331 Line2D ticks = new Line2D.Double (0.0, 0.0, 0.0, 0.0); 332 boolean paint = false; 333 334 DecimalFormat df = c.getYDecimalFormat(); 335 FontRenderContext frc = c.getFontRenderContext(); 336 Font f = c.getFont(); 337 338 Color backupColor = g.getColor(); 339 g.setFont(f); 340 boolean paintLabels = c.isPaintLabels(); 341 342 for(double d = min; d <= max; d += tick) { 343 p.setLocation(xpt, d); 344 v = at.transform(p, null); 345 346 ticks.setLine(v.getX() - marginOffset/2, v.getY(), v.getX() + marginOffset/2, v.getY()); 347 348 g.draw(ticks); 349 350 if (d != min && !c.isPaintOnlyTick()) { 351 Line2D xax = getXAxisLine2D(); 352 ticks.setLine(v.getX() + marginOffset/2, v.getY(), xax.getX2(), v.getY()); 353 g.setColor(Color.lightGray); 354 g.draw(ticks); 355 g.setColor(backupColor); 356 } 357 358 if(paintLabels && (paint || !c.isPaintAltTick())) { 359 String sb = df.format(d); 360 Rectangle2D r = f.getStringBounds(sb, frc); 361 362 g.drawString(sb, (float)(v.getX() - r.getWidth() - marginOffset), 363 (float)(v.getY() + r.getHeight() / 2)); 364 } 365 paint = !paint; 366 } 367 } 368 369 370 public Line2D getXAxisLine2D() { 371 double ypt = 0.0; 372 if(constraints.getMinimumValue().doubleValue() > 0) 374 ypt = constraints.getMinimumValue().doubleValue(); 375 else if(constraints.getMaximumValue().doubleValue() < 0) 376 ypt = constraints.getMaximumValue().doubleValue(); 377 378 AffineTransform at = c.getTransform(CoordSystem.FIRST_YAXIS); 379 380 Point2D l = at.transform(new Point2D.Double (constraints.getMinimumColumnValue(), ypt), null); 381 Point2D r = at.transform(new Point2D.Double (constraints.getMaximumColumnValue(), ypt), null); 382 383 return new Line2D.Double (l, r); 384 } 385 386 387 public Line2D getYAxisLine2D() { 388 double xpt = 0.0; 389 390 if(constraints.getMinimumColumnValue() > 0) 392 xpt = constraints.getMinimumColumnValue(); 393 else if(constraints.getMaximumColumnValue() < 0 && c.getSecondYAxis() != null) 394 xpt = constraints.getMaximumColumnValue(); 395 396 AffineTransform at = c.getTransform(CoordSystem.FIRST_YAXIS); 397 398 Point2D o = at.transform(new Point2D.Double (xpt, constraints.getMaximumValue().doubleValue()), null); 399 Point2D u = at.transform(new Point2D.Double (xpt, constraints.getMinimumValue().doubleValue()), null); 400 return new Line2D.Double (o, u); 402 } 403 404 405 public Line2D getSecondYAxisLine2D() { 406 double xpt = constraints2.getMaximumColumnValue(); 407 408 AffineTransform at = c.getTransform(CoordSystem.SECOND_YAXIS); 409 410 Point2D o = at.transform(new Point2D.Double (xpt, constraints2.getMaximumValue().doubleValue()), null); 411 Point2D u = at.transform(new Point2D.Double (xpt, constraints2.getMinimumValue().doubleValue()), null); 412 413 return new Line2D.Double (o, u); 414 } 415 416 } 417 | Popular Tags |