View Javadoc

1   /*
2    * TouchGraph LLC. Apache-Style Software License
3    *
4    *
5    * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without
8    * modification, are permitted provided that the following conditions
9    * are met:
10   *
11   * 1. Redistributions of source code must retain the above copyright
12   *    notice, this list of conditions and the following disclaimer. 
13   *
14   * 2. Redistributions in binary form must reproduce the above copyright
15   *    notice, this list of conditions and the following disclaimer in
16   *    the documentation and/or other materials provided with the
17   *    distribution.
18   *
19   * 3. The end-user documentation included with the redistribution,
20   *    if any, must include the following acknowledgment:  
21   *       "This product includes software developed by 
22   *        TouchGraph LLC (http://www.touchgraph.com/)."
23   *    Alternately, this acknowledgment may appear in the software itself,
24   *    if and wherever such third-party acknowledgments normally appear.
25   *
26   * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse 
27   *    or promote products derived from this software without prior written 
28   *    permission.  For written permission, please contact 
29   *    alex@touchgraph.com
30   *
31   * 5. Products derived from this software may not be called "TouchGraph",
32   *    nor may "TouchGraph" appear in their name, without prior written
33   *    permission of alex@touchgraph.com.
34   *
35   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38   * DISCLAIMED.  IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE 
39   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
40   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
41   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
42   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
43   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
44   * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
45   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46   * ====================================================================
47   *
48   */
49  
50  package com.touchgraph.graphlayout;
51  
52  import java.awt.*;
53  
54  /***  Edge.
55    *
56    * @author   Alexander Shapiro
57    * @version  1.21  $Id: Edge.java,v 1.1.1.1 2004/02/06 08:44:05 keesj Exp $
58    */
59  public class Edge {
60  
61      public static Color DEFAULT_COLOR = Color.decode("#0000B0");
62      public static Color MOUSE_OVER_COLOR = Color.pink;
63      public static int DEFAULT_LENGTH = 40;
64  
65      public Node from; //Should be private, changing from effects "from" Node
66      public Node to;   //Should be private, changing from effects "to" Node
67      protected Color col;
68      protected int length;
69      protected boolean visible;
70      protected String id = null;
71  
72    // ............
73  
74      /*** Constructor with two Nodes and a length.
75        */
76      public Edge(Node f, Node t, int len) {
77          from = f;
78          to = t;
79          length = len;
80          col = DEFAULT_COLOR;
81          visible = false;
82      }
83  
84      /*** Constructor with two Nodes, which uses a default length.
85        */
86      public Edge(Node f, Node t) {
87          this(f, t, DEFAULT_LENGTH);
88      }
89  
90     // setters and getters ...............
91     
92      public static void setEdgeDefaultColor( Color color ) { DEFAULT_COLOR = color; }
93      public static void setEdgeMouseOverColor( Color color ) { MOUSE_OVER_COLOR = color; }
94      public static void setEdgeDefaultLength( int length ) { DEFAULT_LENGTH = length; }
95  
96     /*** Returns the starting "from" node of this edge as Node. */
97      public Node getFrom() { return from; }
98      
99     /*** Returns the terminating "to" node of this edge as Node. */
100     public Node getTo() { return to; }
101     
102    /*** Returns the color of this edge as Color. */
103     public Color getColor() {
104         return col;
105     }
106 
107    /*** Set the color of this Edge to the Color <tt>color</tt>. */
108     public void setColor( Color color ) {
109         col = color;
110     }
111 
112    /*** Returns the ID of this Edge as a String. */
113     public String getID()
114     {
115         return id;
116     }
117 
118    /*** Set the ID of this Edge to the String <tt>id</tt>. */
119     public void setID( String id )
120     {
121         this.id=id;
122     }
123 
124    /*** Returns the length of this Edge as a double. */
125     public int getLength() {
126         return length;
127     }
128 
129    /*** Set the length of this Edge to the int <tt>len</tt>. */
130     public void setLength(int len) {
131         length=len;
132     }
133 
134    /*** Set the visibility of this Edge to the boolean <tt>v</tt>. */
135     public void setVisible( boolean v) {
136         visible = v;
137     } 
138 
139    /*** Return the visibility of this Edge as a boolean. */
140     public boolean isVisible() {
141         return visible;
142     } 
143 
144     public Node getOtherEndpt(Node n) { //yields false results if Node n is not an endpoint
145         if (to != n) return to;
146         else return from;
147     }
148 
149     /*** Switches the endpoints of the edge */
150     public void reverse() {
151         Node temp = to;
152         to = from;
153         from = temp;
154     }
155 
156     public boolean intersects(Dimension d) {
157         int x1 = (int) from.drawx;
158         int y1 = (int) from.drawy;
159         int x2 = (int) to.drawx;
160         int y2 = (int) to.drawy;
161 
162         return (((x1>0 || x2>0) && (x1<d.width  || x2<d.width)) &&
163                   ((y1>0 || y2>0) && (y1<d.height || y2<d.height) ));
164 
165     }
166 
167     public double distFromPoint(double px, double py) {
168         double x1= from.drawx;
169         double y1= from.drawy;
170         double x2= to.drawx;
171         double y2= to.drawy;
172 
173         if (px<Math.min(x1, x2)-8 || px>Math.max(x1, x2)+8 ||
174             py<Math.min(y1, y2)-8 || py>Math.max(y1, y2)+8)
175             return 1000;
176 
177         double dist = 1000;
178         if (x1-x2!=0) dist = Math.abs((y2-y1)/(x2-x1)*(px - x1) + (y1 - py));
179         if (y1-y2!=0) dist = Math.min(dist, Math.abs((x2-x1)/(y2-y1)*(py - y1) + (x1 - px)));
180 
181         return dist;
182     }
183 
184     public boolean containsPoint(double px, double py) {
185         return distFromPoint(px,py)<10;
186     }
187 
188     public static void paintArrow(Graphics g, int x1, int y1, int x2, int y2, Color c) {
189         //Forget hyperbolic bending for now
190 
191         g.setColor(c);
192 
193         int x3=x1;
194         int y3=y1;
195 
196         double dist=Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
197         if (dist>10) {
198             double adjustDistRatio = (dist-10)/dist;
199             x3=(int) (x1+(x2-x1)*adjustDistRatio);
200             y3=(int) (y1+(y2-y1)*adjustDistRatio);
201         }
202 
203         x3=(int) ((x3*4+x1)/5.0);
204         y3=(int) ((y3*4+y1)/5.0);
205 
206         g.drawLine(x3,   y3,   x2, y2);
207         g.drawLine(x1,   y1,   x3, y3);
208         g.drawLine(x1+1, y1,   x3, y3);
209         g.drawLine(x1+2, y1,   x3, y3);
210         g.drawLine(x1+3, y1,   x3, y3);
211         g.drawLine(x1+4, y1,   x3, y3);
212         g.drawLine(x1-1, y1,   x3, y3);
213         g.drawLine(x1-2, y1,   x3, y3);
214         g.drawLine(x1-3, y1,   x3, y3);
215         g.drawLine(x1-4, y1,   x3, y3);
216         g.drawLine(x1,   y1+1, x3, y3);
217         g.drawLine(x1,   y1+2, x3, y3);
218         g.drawLine(x1,   y1+3, x3, y3);
219         g.drawLine(x1,   y1+4, x3, y3);
220         g.drawLine(x1,   y1-1, x3, y3);
221         g.drawLine(x1,   y1-2, x3, y3);
222         g.drawLine(x1,   y1-3, x3, y3);
223         g.drawLine(x1,   y1-4, x3, y3);
224     }
225 
226     public void paint(Graphics g, TGPanel tgPanel) {
227         Color c = (tgPanel.getMouseOverE()==this) ? MOUSE_OVER_COLOR : col;
228 
229         int x1=(int) from.drawx;
230         int y1=(int) from.drawy;
231         int x2=(int) to.drawx;
232         int y2=(int) to.drawy;
233         if (intersects(tgPanel.getSize())) paintArrow(g, x1, y1, x2, y2, c);
234     }
235 
236 } // end com.touchgraph.graphlayout.Edge