1 17 18 package org.sape.carbon.services.swing.graph; 19 20 21 import java.awt.BasicStroke ; 22 import java.awt.Color ; 23 import java.awt.Graphics ; 24 import java.awt.Graphics2D ; 25 import java.awt.Rectangle ; 26 import java.awt.RenderingHints ; 27 import java.awt.geom.AffineTransform ; 28 import java.awt.geom.GeneralPath ; 29 import java.awt.geom.Line2D ; 30 import java.awt.geom.PathIterator ; 31 import java.awt.geom.Point2D ; 32 import java.awt.geom.Rectangle2D ; 33 import java.text.NumberFormat ; 34 import java.util.HashMap ; 35 import java.util.Iterator ; 36 import java.util.Map ; 37 38 import javax.swing.JFrame ; 39 import javax.swing.JPanel ; 40 41 42 43 58 public class GraphCanvas extends JPanel { 59 60 61 private Map tracks = new HashMap (11); 62 63 64 protected Rectangle2D graphBounds; 65 66 68 private static final double BORDER_PERCENT = 0.1d; 69 70 71 protected Color backgroundColor = new Color (204,204,204); 72 73 protected static NumberFormat labelFormat = null; 74 protected static NumberFormat bigNumberLabelFormat = null; 75 76 79 public GraphCanvas() { 80 super(); 81 82 setBackground(Color.blue); 83 84 this.graphBounds = new Rectangle2D.Double (-5,0,150,2); 85 86 87 this.labelFormat = NumberFormat.getNumberInstance(); 88 this.labelFormat.setMaximumFractionDigits(2); 89 90 this.bigNumberLabelFormat = NumberFormat.getNumberInstance(); 91 this.bigNumberLabelFormat.setMaximumFractionDigits(0); 92 93 94 System.out.println("GraphCanvas::<init> - New GraphCanvas created."); 95 } 96 97 102 public void setBackgroundColor(Color color) { 103 this.backgroundColor = color; 104 } 105 106 110 public Rectangle2D getGraphBounds() { 111 return this.graphBounds; 112 } 113 114 119 public void setGraphBounds(Rectangle2D rect) { 120 this.graphBounds = rect; 121 } 122 123 124 public AffineTransform getTransform() { 125 126 AffineTransform affineT = 127 new AffineTransform (1d,0d,0d,-1d,0d,super.getParent().getHeight()); 128 129 130 131 affineT.concatenate( 133 AffineTransform.getScaleInstance( 134 this.getBounds().getWidth() / this.graphBounds.getWidth(), 135 this.getBounds().getHeight() / this.graphBounds.getHeight())); 136 137 affineT.concatenate( 139 AffineTransform.getTranslateInstance( 140 -this.graphBounds.getX(), 141 -this.graphBounds.getY())); 142 143 return affineT; 144 } 145 146 147 148 public void clear() { 150 151 } 152 153 public void addTrack(String trackName) { 154 this.tracks.put(trackName, new Track(trackName)); 155 } 156 public void addTrack(String trackName,Color color) { 157 this.tracks.put(trackName, new Track(trackName,color)); 158 } 159 160 161 public void addPoint(String track, Point2D point) { 163 ((Track)this.tracks.get(track)).addPoint(point); 164 } 165 166 public Track getTrack(String trackName) { 167 return (Track) this.tracks.get(trackName); 168 } 169 170 171 172 173 public void clearAll() { 174 this.getGraphics().clearRect( 175 (int)getBounds().getX(), 176 (int)getBounds().getY(), 177 (int)getBounds().getWidth(), 178 (int)getBounds().getHeight()); 179 } 180 181 public void paint(Graphics gg) { 182 Graphics2D g = (Graphics2D ) gg; 183 g.setBackground(this.backgroundColor); 184 AffineTransform newTrans = getTransform(); 186 187 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF); 188 189 190 g.clearRect( 192 (int)getBounds().getX(), 193 (int)getBounds().getY(), 194 (int)getBounds().getWidth(), 195 (int)getBounds().getHeight()); 196 197 198 drawLines(g,newTrans); 200 201 drawAxes(g,newTrans); 203 204 drawTracks(g,newTrans); 206 207 drawKey(g,newTrans); 209 } 210 211 217 protected void drawKey(Graphics2D g, AffineTransform transform) { 218 219 int start = 20; 220 221 Iterator trackIterator = this.tracks.values().iterator(); 222 while(trackIterator.hasNext()) { 223 224 Track track = (Track) trackIterator.next(); 225 226 String info = track.toString(); 227 g.setColor(track.getColor()); 229 g.drawString(info,50, start+=25); 230 } 231 } 232 233 protected void drawTracks(Graphics2D g, AffineTransform transform) { 234 235 AffineTransform origTrans = g.getTransform(); 238 239 240 g.transform(transform); 242 243 g.setColor(Color.orange); 244 245 g.setStroke(new BasicStroke (0.001f)); 248 249 Iterator trackIterator = this.tracks.values().iterator(); 251 while (trackIterator.hasNext()) { 252 Track track = (Track) trackIterator.next(); 253 g.setColor(track.getColor()); 254 GeneralPath path = track.getPath(); 255 256 g.draw(path); 257 } 258 259 g.setTransform(origTrans); 261 } 262 263 266 protected void drawAxes(Graphics2D g,AffineTransform transform) { 267 g.setColor(Color.white); 268 269 Point2D origin = transform.transform(new Point2D.Double (0,0),null); 270 271 Rectangle2D axesRect = new Rectangle2D.Double (5,5,this.bounds().getWidth()-10,this.bounds().getHeight()); 273 origin = floorPoint(origin,axesRect); 274 275 Line2D x = new Line2D.Double ( 276 getBounds().getMinX(), origin.getY(), 277 getBounds().getMaxX(), origin.getY()); 278 279 Line2D y = new Line2D.Double ( 280 origin.getX(), getBounds().getMinY(), 281 origin.getX(), getBounds().getMaxY()); 282 283 g.draw(x); 284 g.draw(y); 285 } 286 287 288 296 public static Point2D floorPoint(Point2D point, Rectangle2D rect) { 297 double x = point.getX(); 298 double y = point.getY(); 299 300 if (x < rect.getMinX()) 301 x = rect.getMinX(); 302 if (x > rect.getMaxX()) 303 x = rect.getMaxX(); 304 if (y < rect.getMinY()) 305 y = rect.getMinY(); 306 if (y > rect.getMaxY()) 307 y = rect.getMaxY(); 308 309 return new Point2D.Double (x,y); 310 } 311 312 313 317 protected void drawLines(Graphics2D g, AffineTransform transform) { 318 319 g.setColor(Color.white); 320 int REAL_TICK_SPACE = 40; 321 int REAL_TICK_HEIGHT = 10; 322 323 double graphTickSpaceX = (REAL_TICK_SPACE / transform.getScaleX()); 324 double graphTickSpaceY = (REAL_TICK_SPACE / Math.abs(transform.getScaleY())); 325 326 327 Point2D origin = transform.transform(new Point2D.Float (0,0),null); 328 329 Rectangle2D axesRect = new Rectangle2D.Double (5,5,this.bounds().getWidth()-10,this.bounds().getHeight()); 331 Point2D falseOrigin = floorPoint(origin,axesRect); 332 333 double firstX = this.graphBounds.getMinX(); 334 335 Point2D pt = new Point2D.Float (); 336 for (double x = firstX; x <= (this.graphBounds.getMaxX()+graphTickSpaceX); x += graphTickSpaceX) { 337 double tx = (Math.floor(x/graphTickSpaceX)) * graphTickSpaceX; 338 pt.setLocation(tx,0); 339 transform.transform(pt,pt); 340 g.drawLine((int)pt.getX(),(int)falseOrigin.getY() - 5 ,(int)pt.getX(),(int)falseOrigin.getY() + 5); 341 342 String label; 343 if (tx > 10) 344 label = this.bigNumberLabelFormat.format(tx); 345 else 346 label = this.labelFormat.format(tx); 347 348 g.drawString(label, 349 (float)pt.getX(),(float)falseOrigin.getY()-9); 350 } 351 352 353 double firstY = this.graphBounds.getMinY(); 354 for (double y = firstY; y <= (this.graphBounds.getMaxY()+graphTickSpaceY); y += graphTickSpaceY) { 355 double ty = (Math.floor(y/graphTickSpaceY)) * graphTickSpaceY; 356 pt.setLocation(0,ty); 357 transform.transform(pt,pt); 358 g.drawLine((int)falseOrigin.getX() - 5,(int)pt.getY() ,(int)falseOrigin.getX() + 5,(int)pt.getY()); 359 360 String label; 361 if (ty > 10) 362 label = this.bigNumberLabelFormat.format(ty); 363 else 364 label = this.labelFormat.format(ty); 365 366 g.drawString(label, 367 (float)falseOrigin.getX()+7,(float)pt.getY()); 368 369 } 370 } 371 372 public static class Track { 373 protected String name; 374 protected Color color = Color.black; protected GeneralPath path = new GeneralPath (); 376 protected boolean started = false; 377 protected NumberFormat keyFormat; 378 379 public Track(String name) { 380 super(); 381 this.name = name; 382 383 this.keyFormat = NumberFormat.getNumberInstance(); 384 this.keyFormat.setMaximumFractionDigits(2); 385 } 386 387 public Track(String name, Color color) { 388 this(name); 389 this.color = color; 390 } 391 392 public void setPath(GeneralPath path) { 393 this.path = path; 394 } 395 396 public GeneralPath getPath() { 397 return this.path; 398 } 399 400 public void addPoint(Point2D point) { 401 if (path.getCurrentPoint() == null) { 402 this.path.moveTo((float)point.getX(),(float)point.getY()); 403 this.started = true; 404 } else { 405 this.path.lineTo((float)point.getX(),(float)point.getY()); 406 } 407 408 } 409 410 public Color getColor() { 411 return this.color; 412 } 413 public void setColor(Color color) { 414 this.color = color; 415 } 416 417 public String toString() { 418 String value = null; 419 if (this.path.getCurrentPoint() != null) { 420 double val = this.path.getCurrentPoint().getY(); 421 422 value = this.keyFormat.format(val); 424 } 425 return this.name + ": " + value; 426 } 427 } 428 429 430 435 public void verticalBound() { 436 Rectangle2D rect = null; 437 Rectangle2D orig = getGraphBounds(); 438 439 Iterator trackIterator = this.tracks.values().iterator(); 440 while(trackIterator.hasNext()) { 441 Track track = (Track) trackIterator.next(); 442 443 GeneralPath path = track.getPath(); 444 445 if (rect == null) 446 rect = path.getBounds2D(); 447 else 448 Rectangle.union(rect,path.getBounds2D(),rect); 449 } 450 Rectangle.union(rect,new Rectangle2D.Double (orig.getX(),0,1,1),rect); 451 452 double border = rect.getHeight() * BORDER_PERCENT; 453 454 setGraphBounds(new Rectangle2D.Double ( 455 orig.getMinX(), 456 rect.getMinY()-border, 457 orig.getWidth(), 458 rect.getHeight()+(2d*border))); 459 } 460 461 public void clipOld() { 462 Rectangle2D rect = getGraphBounds(); 463 464 466 Iterator trackIterator = this.tracks.values().iterator(); 467 double[] cs = new double[6]; 468 while(trackIterator.hasNext()) { 469 Track track = (Track) trackIterator.next(); 470 471 GeneralPath path = track.getPath(); 472 473 GeneralPath newPath = new GeneralPath (); 474 475 PathIterator pIter = path.getPathIterator(new AffineTransform ()); 476 while (!pIter.isDone()) { 477 478 pIter.currentSegment(cs); 479 480 if (cs[0] > rect.getMinX()) { 482 if (newPath.getCurrentPoint() == null) 483 newPath.moveTo((float)cs[0],(float)cs[1]); 484 else 485 newPath.lineTo((float)cs[0],(float)cs[1]); 486 } 487 488 497 pIter.next(); 498 499 } 500 track.setPath(newPath); 501 } 502 503 } 504 505 509 public void translate(double x, double y) { 510 511 512 513 Rectangle2D rect = getGraphBounds(); 514 setGraphBounds( 515 new Rectangle2D.Double (rect.getMinX()+x, 516 rect.getMinY()+y,rect.getWidth(),rect.getHeight())); 517 } 518 519 public static void main(String [] args) throws Exception { 520 521 GraphCanvas gc = new GraphCanvas(); 522 gc.show(); 523 524 JFrame frame = new JFrame ("Memory Graph"); 525 frame.getContentPane().add(gc); 526 frame.setSize(600,200); 527 528 530 frame.show(); 531 gc.repaint(); 532 gc.paint((Graphics2D )gc.getGraphics()); 533 534 535 536 long start = System.currentTimeMillis(); 537 538 gc.addTrack("test", Color.cyan); 539 gc.addTrack("test2", Color.blue); 540 gc.addTrack("test3", Color.red); 541 gc.addTrack("test4", Color.yellow); 542 gc.addTrack("test5", Color.green); 543 gc.addTrack("test6", Color.orange); 544 gc.addTrack("test7", Color.pink); 545 546 547 548 int i=0; 549 while (true) { 550 i++; 551 552 Point2D pt = new Point2D.Float (i,((float)Math.cos(i/20f) + (float)Math.sin(i/40f)) * 3f); 553 gc.addPoint("test",pt); 554 555 Point2D pt2 = new Point2D.Float (i,(float)Math.cos(i/25.0f)*10f); 556 gc.addPoint("test2",pt2); 557 558 Point2D pt3 = new Point2D.Float (i,Math.min((float)Math.cos(Math.sin(i/4f))*13f - (float)Math.cos(i/80f)*20f,400f)); 559 gc.addPoint("test3",pt3); 560 561 Point2D pt4 = new Point2D.Float (i, 562 (float) Math.sin(.31*i)*2f + 563 ((float)2f*(float)Math.cos(.07f*i))*8f); 564 gc.addPoint("test4",pt4); 565 566 Point2D pt5 = new Point2D.Float (i, 567 (float) Math.cos(.66*i)*1f + 568 ((float)2f*(float)Math.cos(.07f*i))*3f); 569 gc.addPoint("test5",pt5); 570 571 Point2D pt6 = new Point2D.Float (i, 572 (float) Math.sin(.31*i)*2f + 573 ((float)2f*(float)Math.cos(.07f*Math.tan(i)))*5f); 574 gc.addPoint("test6",pt6); 575 576 Point2D pt7 = new Point2D.Float (i, 577 (float) Math.sin(i)*2f + 578 ((float)2f*(float)Math.sin(.25f*i))*0.5f); 579 gc.addPoint("test7",pt7); 580 581 582 if (i > 150) 583 gc.translate(1,0); 584 585 gc.verticalBound(); 586 587 gc.clipOld(); 589 gc.repaint(); 591 592 Thread.sleep(10); 593 if (i % 100 == 0) { 594 System.out.println("Framewrate: " + 595 (100d / ((System.currentTimeMillis()-start)/1000d))); 596 start = System.currentTimeMillis(); 597 } 598 } 599 600 } 601 } | Popular Tags |