Source Code Cross Referenced for GraphCanvas.java in  » Inversion-of-Control » carbon » org » sape » carbon » services » swing » graph » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Inversion of Control » carbon » org.sape.carbon.services.swing.graph 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * The contents of this file are subject to the Sapient Public License
003:         * Version 1.0 (the "License"); you may not use this file except in compliance
004:         * with the License. You may obtain a copy of the License at
005:         * http://carbon.sf.net/License.html.
006:         *
007:         * Software distributed under the License is distributed on an "AS IS" basis,
008:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
009:         * the specific language governing rights and limitations under the License.
010:         *
011:         * The Original Code is The Carbon Component Framework.
012:         *
013:         * The Initial Developer of the Original Code is Sapient Corporation
014:         *
015:         * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
016:         */
017:
018:        package org.sape.carbon.services.swing.graph;
019:
020:        import java.awt.BasicStroke;
021:        import java.awt.Color;
022:        import java.awt.Graphics;
023:        import java.awt.Graphics2D;
024:        import java.awt.Rectangle;
025:        import java.awt.RenderingHints;
026:        import java.awt.geom.AffineTransform;
027:        import java.awt.geom.GeneralPath;
028:        import java.awt.geom.Line2D;
029:        import java.awt.geom.PathIterator;
030:        import java.awt.geom.Point2D;
031:        import java.awt.geom.Rectangle2D;
032:        import java.text.NumberFormat;
033:        import java.util.HashMap;
034:        import java.util.Iterator;
035:        import java.util.Map;
036:
037:        import javax.swing.JFrame;
038:        import javax.swing.JPanel;
039:
040:        /** <p>This class provides a consistent space within to graph real
041:         * numbers. It provides features such as auto-centering and
042:         * real-time scaling. A user of this graph provides data by creating
043:         * one or more tracks and then adding real points to those. Calling
044:         * translate periodically allows you to create a scrolling graph as
045:         * well.</p>
046:         *
047:         * <p>This graph will also maintain tick marks that resize and
048:         * can be stuck to the sides of the screen so they are always
049:         * visible even if the origin is off-screen.</p>
050:         *
051:         * Copyright 2001 Sapient
052:         * @author Greg Hinkle
053:         * @version $Revision: 1.4 $ ($Author: dvoet $ / $Date: 2003/05/05 21:21:26 $)
054:         */
055:        public class GraphCanvas extends JPanel {
056:
057:            /** A list of  Track's that are a part of this graph */
058:            private Map tracks = new HashMap(11);
059:
060:            /** The current graph bounds that are visible */
061:            protected Rectangle2D graphBounds;
062:
063:            /** The portion of the entire height that should be researved as
064:             * a border, above and below the highest and lowest track points */
065:            private static final double BORDER_PERCENT = 0.1d;
066:
067:            /** The background color for this graph */
068:            protected Color backgroundColor = new Color(204, 204, 204);
069:
070:            protected static NumberFormat labelFormat = null;
071:            protected static NumberFormat bigNumberLabelFormat = null;
072:
073:            /**
074:             * Instantiates a graph canvas
075:             */
076:            public GraphCanvas() {
077:                super ();
078:
079:                setBackground(Color.blue);
080:
081:                this .graphBounds = new Rectangle2D.Double(-5, 0, 150, 2);
082:
083:                this .labelFormat = NumberFormat.getNumberInstance();
084:                this .labelFormat.setMaximumFractionDigits(2);
085:
086:                this .bigNumberLabelFormat = NumberFormat.getNumberInstance();
087:                this .bigNumberLabelFormat.setMaximumFractionDigits(0);
088:
089:                System.out
090:                        .println("GraphCanvas::<init> - New GraphCanvas created.");
091:            }
092:
093:            /**
094:             * <p>Sets the background color of this graph
095:             *
096:             * @param color the Color to set the background to
097:             */
098:            public void setBackgroundColor(Color color) {
099:                this .backgroundColor = color;
100:            }
101:
102:            /** Gets the bounds of the graphing space that are currently showing
103:             * on the screen.
104:             * @return Rectangle2D The bounds of the currently visible graph
105:             */
106:            public Rectangle2D getGraphBounds() {
107:                return this .graphBounds;
108:            }
109:
110:            /**
111:             * Sets the bounds that this graph is displaying
112:             *
113:             * @param rect the Rectangle2D of the desired graph points
114:             */
115:            public void setGraphBounds(Rectangle2D rect) {
116:                this .graphBounds = rect;
117:            }
118:
119:            public AffineTransform getTransform() {
120:
121:                AffineTransform affineT = new AffineTransform(1d, 0d, 0d, -1d,
122:                        0d, super .getParent().getHeight());
123:
124:                // scale to current scale
125:                affineT.concatenate(AffineTransform.getScaleInstance(this 
126:                        .getBounds().getWidth()
127:                        / this .graphBounds.getWidth(), this .getBounds()
128:                        .getHeight()
129:                        / this .graphBounds.getHeight()));
130:
131:                // translate to the current origin
132:                affineT.concatenate(AffineTransform.getTranslateInstance(
133:                        -this .graphBounds.getX(), -this .graphBounds.getY()));
134:
135:                return affineT;
136:            }
137:
138:            // CLEAR ALL CURVES FROM PLOT
139:            public void clear() {
140:
141:            }
142:
143:            public void addTrack(String trackName) {
144:                this .tracks.put(trackName, new Track(trackName));
145:            }
146:
147:            public void addTrack(String trackName, Color color) {
148:                this .tracks.put(trackName, new Track(trackName, color));
149:            }
150:
151:            // ADD CURVE TO STORAGE (DOESN'T GRAPH UNTIL REPAINT()).
152:            public void addPoint(String track, Point2D point) {
153:                ((Track) this .tracks.get(track)).addPoint(point);
154:            }
155:
156:            public Track getTrack(String trackName) {
157:                return (Track) this .tracks.get(trackName);
158:            }
159:
160:            public void clearAll() {
161:                this .getGraphics().clearRect((int) getBounds().getX(),
162:                        (int) getBounds().getY(), (int) getBounds().getWidth(),
163:                        (int) getBounds().getHeight());
164:            }
165:
166:            public void paint(Graphics gg) {
167:                Graphics2D g = (Graphics2D) gg;
168:                g.setBackground(this .backgroundColor);
169:                // What is the current graph to panel transform
170:                AffineTransform newTrans = getTransform();
171:
172:                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
173:                        RenderingHints.VALUE_ANTIALIAS_OFF);
174:
175:                // Erase this entire graph so that we can redraw it
176:                g.clearRect((int) getBounds().getX(), (int) getBounds().getY(),
177:                        (int) getBounds().getWidth(), (int) getBounds()
178:                                .getHeight());
179:
180:                // This draws the tick marks and the tick values
181:                drawLines(g, newTrans);
182:
183:                // This drawes the axeses
184:                drawAxes(g, newTrans);
185:
186:                // This draws each of tracks in this graph
187:                drawTracks(g, newTrans);
188:
189:                // This draws the keys for each graph
190:                drawKey(g, newTrans);
191:            }
192:
193:            /**
194:             * <p>Draw the key to the tracks by calling thier toString</p>
195:             *
196:             * @param graphics2D the Graphics2D to draw to
197:             * @param transform the Affine Transform to use to determine how to draw
198:             */
199:            protected void drawKey(Graphics2D g, AffineTransform transform) {
200:
201:                int start = 20;
202:
203:                Iterator trackIterator = this .tracks.values().iterator();
204:                while (trackIterator.hasNext()) {
205:
206:                    Track track = (Track) trackIterator.next();
207:
208:                    String info = track.toString();
209:                    // Will draw the key in the same color as it's line
210:                    g.setColor(track.getColor());
211:                    g.drawString(info, 50, start += 25);
212:                }
213:            }
214:
215:            protected void drawTracks(Graphics2D g, AffineTransform transform) {
216:
217:                // Store original transform to restore it later
218:                // until I figure out how to track differences only
219:                AffineTransform origTrans = g.getTransform();
220:
221:                // Transform for local drawing
222:                g.transform(transform);
223:
224:                g.setColor(Color.orange);
225:
226:                // Using a small stroke will minimize the width to a single output
227:                // level pixel up to a reasonable scaling size
228:                g.setStroke(new BasicStroke(0.001f));
229:
230:                // Draw the tracks
231:                Iterator trackIterator = this .tracks.values().iterator();
232:                while (trackIterator.hasNext()) {
233:                    Track track = (Track) trackIterator.next();
234:                    g.setColor(track.getColor());
235:                    GeneralPath path = track.getPath();
236:
237:                    g.draw(path);
238:                }
239:
240:                // Reset transformation
241:                g.setTransform(origTrans);
242:            }
243:
244:            /**
245:             * This draws the axes
246:             */
247:            protected void drawAxes(Graphics2D g, AffineTransform transform) {
248:                g.setColor(Color.white);
249:
250:                Point2D origin = transform.transform(new Point2D.Double(0, 0),
251:                        null);
252:
253:                // If you want to have rubber banding axes (always visible)
254:                Rectangle2D axesRect = new Rectangle2D.Double(5, 5, this 
255:                        .bounds().getWidth() - 10, this .bounds().getHeight());
256:                origin = floorPoint(origin, axesRect);
257:
258:                Line2D x = new Line2D.Double(getBounds().getMinX(), origin
259:                        .getY(), getBounds().getMaxX(), origin.getY());
260:
261:                Line2D y = new Line2D.Double(origin.getX(), getBounds()
262:                        .getMinY(), origin.getX(), getBounds().getMaxY());
263:
264:                g.draw(x);
265:                g.draw(y);
266:            }
267:
268:            /**
269:             * <p>This finds the closest point on a rectangle's edge to a point outside
270:             * the rectangle or if that point is within the rectangle it is returned.
271:             * </p>
272:             *
273:             * @param point The point to rectangularly floor
274:             * @param rect The rectangle to floor within
275:             */
276:            public static Point2D floorPoint(Point2D point, Rectangle2D rect) {
277:                double x = point.getX();
278:                double y = point.getY();
279:
280:                if (x < rect.getMinX())
281:                    x = rect.getMinX();
282:                if (x > rect.getMaxX())
283:                    x = rect.getMaxX();
284:                if (y < rect.getMinY())
285:                    y = rect.getMinY();
286:                if (y > rect.getMaxY())
287:                    y = rect.getMaxY();
288:
289:                return new Point2D.Double(x, y);
290:            }
291:
292:            /**
293:             * <p>This draws the tick marks in the graph
294:             *
295:             */
296:            protected void drawLines(Graphics2D g, AffineTransform transform) {
297:
298:                g.setColor(Color.white);
299:                int REAL_TICK_SPACE = 40;
300:                int REAL_TICK_HEIGHT = 10;
301:
302:                double graphTickSpaceX = (REAL_TICK_SPACE / transform
303:                        .getScaleX());
304:                double graphTickSpaceY = (REAL_TICK_SPACE / Math.abs(transform
305:                        .getScaleY()));
306:
307:                Point2D origin = transform.transform(new Point2D.Float(0, 0),
308:                        null);
309:
310:                // If you want to have rubber banding axes (always visible)
311:                Rectangle2D axesRect = new Rectangle2D.Double(5, 5, this 
312:                        .bounds().getWidth() - 10, this .bounds().getHeight());
313:                Point2D falseOrigin = floorPoint(origin, axesRect);
314:
315:                double firstX = this .graphBounds.getMinX();
316:
317:                Point2D pt = new Point2D.Float();
318:                for (double x = firstX; x <= (this .graphBounds.getMaxX() + graphTickSpaceX); x += graphTickSpaceX) {
319:                    double tx = (Math.floor(x / graphTickSpaceX))
320:                            * graphTickSpaceX;
321:                    pt.setLocation(tx, 0);
322:                    transform.transform(pt, pt);
323:                    g.drawLine((int) pt.getX(), (int) falseOrigin.getY() - 5,
324:                            (int) pt.getX(), (int) falseOrigin.getY() + 5);
325:
326:                    String label;
327:                    if (tx > 10)
328:                        label = this .bigNumberLabelFormat.format(tx);
329:                    else
330:                        label = this .labelFormat.format(tx);
331:
332:                    g.drawString(label, (float) pt.getX(), (float) falseOrigin
333:                            .getY() - 9);
334:                }
335:
336:                double firstY = this .graphBounds.getMinY();
337:                for (double y = firstY; y <= (this .graphBounds.getMaxY() + graphTickSpaceY); y += graphTickSpaceY) {
338:                    double ty = (Math.floor(y / graphTickSpaceY))
339:                            * graphTickSpaceY;
340:                    pt.setLocation(0, ty);
341:                    transform.transform(pt, pt);
342:                    g.drawLine((int) falseOrigin.getX() - 5, (int) pt.getY(),
343:                            (int) falseOrigin.getX() + 5, (int) pt.getY());
344:
345:                    String label;
346:                    if (ty > 10)
347:                        label = this .bigNumberLabelFormat.format(ty);
348:                    else
349:                        label = this .labelFormat.format(ty);
350:
351:                    g.drawString(label, (float) falseOrigin.getX() + 7,
352:                            (float) pt.getY());
353:
354:                }
355:            }
356:
357:            public static class Track {
358:                protected String name;
359:                protected Color color = Color.black; //Default to black
360:                protected GeneralPath path = new GeneralPath();
361:                protected boolean started = false;
362:                protected NumberFormat keyFormat;
363:
364:                public Track(String name) {
365:                    super ();
366:                    this .name = name;
367:
368:                    this .keyFormat = NumberFormat.getNumberInstance();
369:                    this .keyFormat.setMaximumFractionDigits(2);
370:                }
371:
372:                public Track(String name, Color color) {
373:                    this (name);
374:                    this .color = color;
375:                }
376:
377:                public void setPath(GeneralPath path) {
378:                    this .path = path;
379:                }
380:
381:                public GeneralPath getPath() {
382:                    return this .path;
383:                }
384:
385:                public void addPoint(Point2D point) {
386:                    if (path.getCurrentPoint() == null) {
387:                        this .path.moveTo((float) point.getX(), (float) point
388:                                .getY());
389:                        this .started = true;
390:                    } else {
391:                        this .path.lineTo((float) point.getX(), (float) point
392:                                .getY());
393:                    }
394:
395:                }
396:
397:                public Color getColor() {
398:                    return this .color;
399:                }
400:
401:                public void setColor(Color color) {
402:                    this .color = color;
403:                }
404:
405:                public String toString() {
406:                    String value = null;
407:                    if (this .path.getCurrentPoint() != null) {
408:                        double val = this .path.getCurrentPoint().getY();
409:
410:                        //NumberFormat nf = NumberFormat.getNumberInstance();
411:                        value = this .keyFormat.format(val);
412:                    }
413:                    return this .name + ": " + value;
414:                }
415:            }
416:
417:            /**
418:             * <p>Bounds the graph to the limits of the tracks verticaly providing a
419:             * useful scaling. A more intelligent implementation could have minimum
420:             * bounds to limit the bouncyness to startup.</p>
421:             */
422:            public void verticalBound() {
423:                Rectangle2D rect = null;
424:                Rectangle2D orig = getGraphBounds();
425:
426:                Iterator trackIterator = this .tracks.values().iterator();
427:                while (trackIterator.hasNext()) {
428:                    Track track = (Track) trackIterator.next();
429:
430:                    GeneralPath path = track.getPath();
431:
432:                    if (rect == null)
433:                        rect = path.getBounds2D();
434:                    else
435:                        Rectangle.union(rect, path.getBounds2D(), rect);
436:                }
437:                Rectangle.union(rect, new Rectangle2D.Double(orig.getX(), 0, 1,
438:                        1), rect);
439:
440:                double border = rect.getHeight() * BORDER_PERCENT;
441:
442:                setGraphBounds(new Rectangle2D.Double(orig.getMinX(), rect
443:                        .getMinY()
444:                        - border, orig.getWidth(), rect.getHeight()
445:                        + (2d * border)));
446:            }
447:
448:            public void clipOld() {
449:                Rectangle2D rect = getGraphBounds();
450:
451:                //Rectangle2D orig = AffineTransform.getScaleInstance(1.5,1.5).createTransformedShape(getGraphBounds()).getBounds();
452:
453:                Iterator trackIterator = this .tracks.values().iterator();
454:                double[] cs = new double[6];
455:                while (trackIterator.hasNext()) {
456:                    Track track = (Track) trackIterator.next();
457:
458:                    GeneralPath path = track.getPath();
459:
460:                    GeneralPath newPath = new GeneralPath();
461:
462:                    PathIterator pIter = path
463:                            .getPathIterator(new AffineTransform());
464:                    while (!pIter.isDone()) {
465:
466:                        pIter.currentSegment(cs);
467:
468:                        //Point2D pt = new Point2D.Double(cs[0],cs[1]);
469:                        if (cs[0] > rect.getMinX()) {
470:                            if (newPath.getCurrentPoint() == null)
471:                                newPath.moveTo((float) cs[0], (float) cs[1]);
472:                            else
473:                                newPath.lineTo((float) cs[0], (float) cs[1]);
474:                        }
475:
476:                        /*
477:                        System.out.println("Current Segment: " +
478:                        cs[0] + ", " +
479:                        cs[1] + ", " +
480:                        cs[2] + ", " +
481:                        cs[3] + ", " +
482:                        cs[4] + ", " +
483:                        cs[5]);
484:                         **/
485:                        pIter.next();
486:
487:                    }
488:                    track.setPath(newPath);
489:                }
490:
491:            }
492:
493:            /**
494:             * <p>Translates the main graph rect by x and y, horizontally and vertically
495:             * respectively.</p>
496:             */
497:            public void translate(double x, double y) {
498:
499:                Rectangle2D rect = getGraphBounds();
500:                setGraphBounds(new Rectangle2D.Double(rect.getMinX() + x, rect
501:                        .getMinY()
502:                        + y, rect.getWidth(), rect.getHeight()));
503:            }
504:
505:            public static void main(String[] args) throws Exception {
506:
507:                GraphCanvas gc = new GraphCanvas();
508:                gc.show();
509:
510:                JFrame frame = new JFrame("Memory Graph");
511:                frame.getContentPane().add(gc);
512:                frame.setSize(600, 200);
513:
514:                // TODO: Add window exit listener
515:
516:                frame.show();
517:                gc.repaint();
518:                gc.paint((Graphics2D) gc.getGraphics());
519:
520:                long start = System.currentTimeMillis();
521:
522:                gc.addTrack("test", Color.cyan);
523:                gc.addTrack("test2", Color.blue);
524:                gc.addTrack("test3", Color.red);
525:                gc.addTrack("test4", Color.yellow);
526:                gc.addTrack("test5", Color.green);
527:                gc.addTrack("test6", Color.orange);
528:                gc.addTrack("test7", Color.pink);
529:
530:                int i = 0;
531:                while (true) {
532:                    i++;
533:
534:                    Point2D pt = new Point2D.Float(i, ((float) Math
535:                            .cos(i / 20f) + (float) Math.sin(i / 40f)) * 3f);
536:                    gc.addPoint("test", pt);
537:
538:                    Point2D pt2 = new Point2D.Float(i, (float) Math
539:                            .cos(i / 25.0f) * 10f);
540:                    gc.addPoint("test2", pt2);
541:
542:                    Point2D pt3 = new Point2D.Float(i, Math.min((float) Math
543:                            .cos(Math.sin(i / 4f))
544:                            * 13f - (float) Math.cos(i / 80f) * 20f, 400f));
545:                    gc.addPoint("test3", pt3);
546:
547:                    Point2D pt4 = new Point2D.Float(i, (float) Math
548:                            .sin(.31 * i)
549:                            * 2f
550:                            + ((float) 2f * (float) Math.cos(.07f * i))
551:                            * 8f);
552:                    gc.addPoint("test4", pt4);
553:
554:                    Point2D pt5 = new Point2D.Float(i, (float) Math
555:                            .cos(.66 * i)
556:                            * 1f
557:                            + ((float) 2f * (float) Math.cos(.07f * i))
558:                            * 3f);
559:                    gc.addPoint("test5", pt5);
560:
561:                    Point2D pt6 = new Point2D.Float(i, (float) Math
562:                            .sin(.31 * i)
563:                            * 2f
564:                            + ((float) 2f * (float) Math
565:                                    .cos(.07f * Math.tan(i))) * 5f);
566:                    gc.addPoint("test6", pt6);
567:
568:                    Point2D pt7 = new Point2D.Float(i, (float) Math.sin(i) * 2f
569:                            + ((float) 2f * (float) Math.sin(.25f * i)) * 0.5f);
570:                    gc.addPoint("test7", pt7);
571:
572:                    if (i > 150)
573:                        gc.translate(1, 0);
574:
575:                    gc.verticalBound();
576:
577:                    //if(i%100 == 0) {
578:                    gc.clipOld();
579:                    //}
580:                    gc.repaint();
581:
582:                    Thread.sleep(10);
583:                    if (i % 100 == 0) {
584:                        System.out
585:                                .println("Framewrate: "
586:                                        + (100d / ((System.currentTimeMillis() - start) / 1000d)));
587:                        start = System.currentTimeMillis();
588:                    }
589:                }
590:
591:            }
592:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.