TGGraphLayout/0000755000175000017500000000000011325566115015271 5ustar starswifterstarswifterTGGraphLayout/com/0000755000175000017500000000000007561554546016063 5ustar starswifterstarswifterTGGraphLayout/com/touchgraph/0000755000175000017500000000000007561554546020227 5ustar starswifterstarswifterTGGraphLayout/com/touchgraph/graphlayout/0000755000175000017500000000000007561563420022555 5ustar starswifterstarswifterTGGraphLayout/com/touchgraph/graphlayout/interaction/0000755000175000017500000000000007561561342025075 5ustar starswifterstarswifterTGGraphLayout/com/touchgraph/graphlayout/graphelements/0000755000175000017500000000000007561561434025416 5ustar starswifterstarswifterTGGraphLayout/TGGraphLayout.html0000644000175000017500000000055607561472516020667 0ustar starswifterstarswifter TouchGraph GraphLayout TGGraphLayout/TGGL ReleaseNotes.txt0000644000175000017500000000671307561561516021157 0ustar starswifterstarswifter ***************************** * * * TouchGraph GraphLayout * * V 1.22-jre11 * * (c) 2001-2002 * * Alexander Shapiro, * * TouchGraph LLC * * * ***************************** Release Notes: V 1.22 (11/04/02): Reverted the code back to a jre1.1 compatible version -jre11 Lutz Dornbusch of www.clicktivities.net performed the reversion when customizing the applet for www.planet-wissen.de Enhaced locality stwitching at radius 1. Now at radius 1 fresh nodes get added before those marked for removal get taken away. This allows more connections to be seen during the transition. Modified layout to improve fade out of freshly added nodes and nodes that are about to be removed. Improved node scrolling to center. Reactivated hyperbolic lens. V 1.21 (04/04/02): Fixed copyright date from 2002 to 2001-2002 Added a collapseNode method, which has the opposite effect of expandNode. Fixed the hide node method so that hiding is independent of selection. Simplified getting and setting the zoom, rotation, and horizontal + vertical scrollbar values so that these can be saved/retrieved more easily. Added new parameters to the set locality method to support the extension of the GraphLayout code by the TGWikiBrowser. Now one can prevent nodes with high edge degrees from being shown or expanded, or chose to follow only outgoing edges. V 1.20 (01/02/02): Changed License to TouchGraph LLC. Apache-Style Software License. Began code cleanup + addition of javadoc hooks to comply with Sun's coding standards. Changes to suport the extension of the GraphLayout code by the TGLinkBrowser: Nodes are now given unique node id's. Nodes can be rectangular, rounded-rectangles, or eliptical. V 1.07 (10/28/01): Switched to Swing. Added locality navigation tools. Implemented edge Selection. Began toolbar improvements. V 1.06 (9/30/01): Implemented locality. V 1.05 (9/09/01): Made interfaces (such as moving nodes by dragging) plugable. V 1.04 (8/19/01): Fixed Horiz + Vert Scrollbars. V 1.03 (8/04/01): Made design more modular. Implemented a hyperbolic lens. V 1.02 (7/22/01): Added comments ================================================================================ Contributors Clicktivities & Lutz Dornbusch: www.clicktivities.net Lutz.Dornbusch@clicktivities.net Murray Altheim: http://www.altheim.com/murray/ This software includes code from: Sun's graph layout applet: java.sun.com/applets/jdk/1.2/demo/applets/GraphLayout/example1.html TGGraphLayout/TG-APACHE-LICENSE.txt0000644000175000017500000000445707452702002020346 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ TGGraphLayout/com/touchgraph/graphlayout/TGScrollPane.java0000644000175000017500000001134207561561050025713 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout; import com.touchgraph.graphlayout.interaction.*; import java.awt.Point; /** TGScrollPane is a Java interface for a user interface using scrollbars * to set TouchGraph navigation and editing properties such as zoom, rotate * and locality. If a particular UI doesn't use a specific scrollbar, the * corresponding method should return a null. * * @author Murray Altheim * @author Alex Shapiro * @version 1.22-jre1.1 $Id: TGScrollPane.java,v 1.1 2002/09/19 15:58:08 ldornbusch Exp $ */ public interface TGScrollPane { /** Return the TGPanel used with this TGScrollPane. */ public TGPanel getTGPanel(); // navigation ................. /** Return the HVScroll used with this TGScrollPane. */ public HVScroll getHVScroll(); /** Return the HyperScroll used with this TGScrollPane. */ public HyperScroll getHyperScroll(); /** Sets the horizontal offset to p.x, and the vertical offset to p.y * given a Point p. */ public void setOffset( Point p ); /** Return the horizontal and vertical offset position as a Point. */ public Point getOffset(); // rotation ................... /** Return the RotateScroll used with this TGScrollPane. */ public RotateScroll getRotateScroll(); /** Set the rotation angle of this TGScrollPane (allowable values between 0 to 359). */ public void setRotationAngle( int angle ); /** Return the rotation angle of this TGScrollPane. */ public int getRotationAngle(); // locality ................... /** Return the LocalityScroll used with this TGScrollPane. */ public LocalityScroll getLocalityScroll(); /** Set the locality radius of this TGScrollPane * (allowable values between 0 to 4, or LocalityUtils.INFINITE_LOCALITY_RADIUS). */ public void setLocalityRadius( int radius ); /** Return the locality radius of this TGScrollPane. */ public int getLocalityRadius(); // zoom ....................... /** Return the ZoomScroll used with this TGScrollPane. */ public ZoomScroll getZoomScroll(); /** Set the zoom value of this TGScrollPane (allowable values between -100 to 100). */ public void setZoomValue( int zoomValue ); /** Return the zoom value of this TGScrollPane. */ public int getZoomValue(); } // end com.touchgraph.graphlayout.TGScrollPane TGGraphLayout/com/touchgraph/graphlayout/TGPoint2D.java0000644000175000017500000000603707561561056025143 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout; /** TGPoint2D is only needed for java 1.1. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: TGPoint2D.java,v 1.1 2002/09/19 15:58:08 ldornbusch Exp $ */ public class TGPoint2D { public double x,y; public TGPoint2D( double xpos, double ypos ) { x=xpos; y=ypos; } public TGPoint2D( TGPoint2D p ) { x=p.x; y=p.y; } public void setLocation( double xpos,double ypos ) { x=xpos; y=ypos; } public void setX( double xpos ) { x=xpos; } public void setY( double ypos ) { y=ypos; } } // end com.touchgraph.graphlayout.TGPoint2D TGGraphLayout/com/touchgraph/graphlayout/TGPanel.java0000644000175000017500000007300007561561056024715 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout; import com.touchgraph.graphlayout.interaction.*; import com.touchgraph.graphlayout.graphelements.*; import java.awt.*; import java.awt.event.*; //import javax.swing.*; import java.util.*; /** TGPanel contains code for drawing the graph, and storing which nodes * are selected, and which ones the mouse is over. * * It houses methods to activate TGLayout, which performs dynamic layout. * Whenever the graph is moved, or repainted, TGPanel fires listner * methods on associated objects. * *

* Parts of this code build upon Sun's Graph Layout example. * http://java.sun.com/applets/jdk/1.1/demo/GraphLayout/Graph.java *

* * @author Alexander Shapiro * @author Murray Altheim (2001-11-06; 2002-01-14 cleanup) * @version 1.22-jre1.1 $Id: TGPanel.java,v 1.2 2002/09/20 14:26:17 ldornbusch Exp $ */ public class TGPanel extends Panel { // static variables for use within the package public static Color BACK_COLOR = Color.white; // .... private GraphEltSet completeEltSet; private VisibleLocality visibleLocality; private LocalityUtils localityUtils; public TGLayout tgLayout; protected BasicMouseMotionListener basicMML; protected Edge mouseOverE; //mouseOverE is the edge the mouse is over protected Node mouseOverN; //mouseOverN is the node the mouse is over protected boolean maintainMouseOver = false; //If true, then don't change mouseOverN or mouseOverE protected Node select; Node dragNode; //Node currently being dragged protected Point mousePos; //Mouse location, updated in the mouseMotionListener Image offscreen; Dimension offscreensize; Graphics offgraphics; private Vector graphListeners; private Vector paintListeners; TGLensSet tgLensSet; // Converts between a nodes visual position (drawx, drawy), // and its absolute position (x,y). AdjustOriginLens adjustOriginLens; SwitchSelectUI switchSelectUI; /** Default constructor. */ public TGPanel() { setLayout(null); setGraphEltSet(new GraphEltSet()); addMouseListener(new BasicMouseListener()); basicMML = new BasicMouseMotionListener(); addMouseMotionListener(basicMML); graphListeners=new Vector(); paintListeners=new Vector(); adjustOriginLens = new AdjustOriginLens(); switchSelectUI = new SwitchSelectUI(); TGLayout tgLayout = new TGLayout(this); setTGLayout(tgLayout); tgLayout.start(); setGraphEltSet(new GraphEltSet()); } public void setLensSet( TGLensSet lensSet ) { tgLensSet = lensSet; } public void setTGLayout( TGLayout tgl ) { tgLayout = tgl; } public void setGraphEltSet( GraphEltSet ges ) { completeEltSet = ges; visibleLocality = new VisibleLocality(completeEltSet); localityUtils = new LocalityUtils(visibleLocality, this); } public AdjustOriginLens getAdjustOriginLens() { return adjustOriginLens; } public SwitchSelectUI getSwitchSelectUI() { return switchSelectUI; } // color and font setters ...................... public void setBackColor( Color color ) { BACK_COLOR = color; } // Node manipulation ........................... /** Returns an Iterator over all nodes in the complete graph. */ /* public Iterator getAllNodes() { return completeEltSet.getNodes(); } */ /** Return the current visible locality. */ public ImmutableGraphEltSet getGES() { return visibleLocality; } /** Returns the current node count. */ public int getNodeCount() { return completeEltSet.nodeCount(); } /** Returns the current node count within the VisibleLocality. * @deprecated this method has been replaced by the visibleNodeCount() method. */ public int nodeNum() { return visibleLocality.nodeCount(); } /** Returns the current node count within the VisibleLocality. */ public int visibleNodeCount() { return visibleLocality.nodeCount(); } /** Return the Node whose ID matches the String id, null if no match is found. * * @param id The ID identifier used as a query. * @return The Node whose ID matches the provided 'id', null if no match is found. */ public Node findNode( String id ) { if ( id == null ) return null; // ignore return completeEltSet.findNode(id); } /** Return the Node whose URL matches the String strURL, null if no match is found. * * @param strURL The URL identifier used as a query. * @return The Node whose URL matches the provided 'URL', null if no match is found. */ public Node findNodeByURL( String strURL ) { if ( strURL == null ) return null; // ignore return completeEltSet.findNodeByURL(strURL); } /** Return a Collection of all Nodes whose label matches the String label, * null if no match is found. */ /* public Collection findNodesByLabel( String label ) { if ( label == null ) return null; // ignore return completeEltSet.findNodesByLabel(label); } */ /** Return the first Nodes whose label contains the String substring, * null if no match is found. * @param substring The Substring used as a query. */ public Node findNodeLabelContaining( String substring ) { if ( substring == null ) return null; //ignore return completeEltSet.findNodeLabelContaining(substring); } /** Adds a Node, with its ID and label being the current node count plus 1. * @see com.touchgraph.graphlayout.Node */ public Node addNode() throws TGException { String id = String.valueOf(getNodeCount()+1); return addNode(id,null); } /** Adds a Node, provided its label. The node is assigned a unique ID. * @see com.touchgraph.graphlayout.graphelements.GraphEltSet */ public Node addNode( String label ) throws TGException { return addNode(null,label); } /** Adds a Node, provided its ID and label. * @see com.touchgraph.graphlayout.Node */ public Node addNode( String id, String label ) throws TGException { Node node; if (label==null) node = new Node(id); else node = new Node(id, label); updateDrawPos(node); // The addNode() call should probably take a position, this just sets it at 0,0 addNode(node); return node; } /** Add the Node node to the visibleLocality, checking for ID uniqueness. */ public void addNode( final Node node ) throws TGException { synchronized (localityUtils) { visibleLocality.addNode(node); resetDamper(); } } /** Remove the Node object matching the ID id, returning true if the * deletion occurred, false if a Node matching the ID does not exist (or if the ID * value was null). * * @param id The ID identifier used as a query. * @return true if the deletion occurred. */ public boolean deleteNodeById( String id ) { if ( id == null ) return false; // ignore Node node = findNode(id); if ( node == null ) return false; else return deleteNode(node); } public boolean deleteNode( Node node ) { synchronized (localityUtils) { if (visibleLocality.deleteNode(node)) { // delete from visibleLocality, *AND completeEltSet if ( node == select ) clearSelect(); resetDamper(); return true; } return false; } } public void clearAll() { synchronized (localityUtils) { visibleLocality.clearAll(); } } public Node getSelect() { return select; } public Node getMouseOverN() { return mouseOverN; } public synchronized void setMouseOverN( Node node ) { if ( dragNode != null || maintainMouseOver ) return; // So you don't accidentally switch nodes while dragging if ( mouseOverN != node ) { Node oldMouseOverN = mouseOverN; mouseOverN=node; } if (mouseOverN==null) setCursor(new Cursor(Cursor.MOVE_CURSOR)); else setCursor(new Cursor(Cursor.HAND_CURSOR)); } // Edge manipulation ........................... /** Returns an Iterator over all edges in the complete graph. */ /* public Iterator getAllEdges() { return completeEltSet.getEdges(); } */ public void deleteEdge( Edge edge ) { synchronized (localityUtils) { visibleLocality.deleteEdge(edge); resetDamper(); } } public void deleteEdge( Node from, Node to ) { synchronized (localityUtils) { visibleLocality.deleteEdge(from,to); } } /** Returns the current edge count in the complete graph. */ public int getEdgeCount() { return completeEltSet.edgeCount(); } /** Return the number of Edges in the Locality. * @deprecated this method has been replaced by the visibleEdgeCount() method. */ public int edgeNum() { return visibleLocality.edgeCount(); } /** Return the number of Edges in the Locality. */ public int visibleEdgeCount() { return visibleLocality.edgeCount(); } public Edge findEdge( Node f, Node t ) { return visibleLocality.findEdge(f, t); } public void addEdge(Edge e) { synchronized (localityUtils) { visibleLocality.addEdge(e); resetDamper(); } } public Edge addEdge( Node f, Node t, int tens ) { synchronized (localityUtils) { return visibleLocality.addEdge(f, t, tens); } } public Edge getMouseOverE() { return mouseOverE; } public synchronized void setMouseOverE( Edge edge ) { if ( dragNode != null || maintainMouseOver ) return; // No funny business while dragging if ( mouseOverE != edge ) { Edge oldMouseOverE = mouseOverE; mouseOverE = edge; } } // miscellany .................................. protected class AdjustOriginLens extends TGAbstractLens { protected void applyLens(TGPoint2D p) { p.x=p.x+TGPanel.this.getSize().width/2; p.y=p.y+TGPanel.this.getSize().height/2; } protected void undoLens(TGPoint2D p) { p.x=p.x-TGPanel.this.getSize().width/2; p.y=p.y-TGPanel.this.getSize().height/2; } } public class SwitchSelectUI extends TGAbstractClickUI { public void mouseClicked(MouseEvent e) { if ( mouseOverN != null ) { if ( mouseOverN != select ) setSelect(mouseOverN); else clearSelect(); } } } void fireMovedEvent() { Vector listeners; synchronized(this) { listeners = (Vector)graphListeners.clone(); } for (int i=0;i to.x ) { maxX = from.x; minX = to.x; } else { minX = from.x; maxX = to.x; } if ( from.y > to.y ) { maxY = from.y; minY = to.y; } else { minY = from.y; maxY = to.y; } final Vector selectedNodes = new Vector(); TGForEachNode fen = new TGForEachNode() { public void forEachNode( Node node ) { double x = node.drawx; double y = node.drawy; if ( x > minX && x < maxX && y > minY && y < maxY ) { selectedNodes.addElement(node); } } }; visibleLocality.forAllNodes(fen); if ( selectedNodes.size() > 0 ) { int r = (int)( Math.random()*selectedNodes.size() ); setSelect((Node)selectedNodes.elementAt(r)); } else { clearSelect(); } } public void updateLocalityFromVisibility() throws TGException { visibleLocality.updateLocalityFromVisibility(); } public void setLocale( Node node, int radius, int maxAddEdgeCount, int maxExpandEdgeCount, boolean unidirectional ) throws TGException { localityUtils.setLocale(node,radius, maxAddEdgeCount, maxExpandEdgeCount, unidirectional); } public void fastFinishAnimation() { //Quickly wraps up the add node animation localityUtils.fastFinishAnimation(); } public void setLocale( Node node, int radius ) throws TGException { localityUtils.setLocale(node,radius); } public void expandNode( Node node ) { localityUtils.expandNode(node); } public void hideNode( Node hideNode ) { localityUtils.hideNode(hideNode ); } public void collapseNode( Node collapseNode ) { localityUtils.collapseNode(collapseNode ); } public void hideEdge( Edge hideEdge ) { visibleLocality.removeEdge(hideEdge); if ( mouseOverE == hideEdge ) setMouseOverE(null); resetDamper(); } public void setDragNode( Node node ) { dragNode = node; tgLayout.setDragNode(node); } public Node getDragNode() { return dragNode; } void setMousePos( Point p ) { mousePos = p; } public Point getMousePos() { return mousePos; } /** Start and stop the damper. Should be placed in the TGPanel too. */ public void startDamper() { if (tgLayout!=null) tgLayout.startDamper(); } public void stopDamper() { if (tgLayout!=null) tgLayout.stopDamper(); } /** Makes the graph mobile, and slowly slows it down. */ public void resetDamper() { if (tgLayout!=null) tgLayout.resetDamper(); } /** Gently stops the graph from moving */ public void stopMotion() { if (tgLayout!=null) tgLayout.stopMotion(); } class BasicMouseListener extends MouseAdapter { public void mouseEntered(MouseEvent e) { addMouseMotionListener(basicMML); } public void mouseExited(MouseEvent e) { removeMouseMotionListener(basicMML); mousePos = null; setMouseOverN(null); setMouseOverE(null); repaint(); } } class BasicMouseMotionListener implements MouseMotionListener { public void mouseDragged(MouseEvent e) { mousePos = e.getPoint(); findMouseOver(); try { Thread.currentThread().sleep(6); //An attempt to make the cursor flicker less } catch (InterruptedException ex) { //break; } } public void mouseMoved( MouseEvent e ) { mousePos = e.getPoint(); synchronized (this) { Edge oldMouseOverE = mouseOverE; Node oldMouseOverN = mouseOverN; findMouseOver(); if (oldMouseOverE!=mouseOverE || oldMouseOverN!=mouseOverN) { repaint(); } // Replace the above lines with the commented portion below to prevent whole graph // from being repainted simply to highlight a node On mouseOver. // This causes some annoying flickering though. /* if(oldMouseOverE!=mouseOverE) { if (oldMouseOverE!=null) { synchronized(oldMouseOverE) { oldMouseOverE.paint(TGPanel.this.getGraphics(),TGPanel.this); oldMouseOverE.from.paint(TGPanel.this.getGraphics(),TGPanel.this); oldMouseOverE.to.paint(TGPanel.this.getGraphics(),TGPanel.this); } } if (mouseOverE!=null) { synchronized(mouseOverE) { mouseOverE.paint(TGPanel.this.getGraphics(),TGPanel.this); mouseOverE.from.paint(TGPanel.this.getGraphics(),TGPanel.this); mouseOverE.to.paint(TGPanel.this.getGraphics(),TGPanel.this); } } } if(oldMouseOverN!=mouseOverN) { if (oldMouseOverN!=null) oldMouseOverN.paint(TGPanel.this.getGraphics(),TGPanel.this); if (mouseOverN!=null) mouseOverN.paint(TGPanel.this.getGraphics(),TGPanel.this); } */ } } } protected synchronized void findMouseOver() { if ( mousePos == null ) { setMouseOverN(null); setMouseOverE(null); return; } final int mpx=mousePos.x; final int mpy=mousePos.y; final Node[] monA = new Node[1]; final Edge[] moeA = new Edge[1]; TGForEachNode fen = new TGForEachNode() { double minoverdist = 100; //Kind of a hack (see second if statement) //Nodes can be as wide as 200 (=2*100) public void forEachNode( Node node ) { double x = node.drawx; double y = node.drawy; double dist = Math.sqrt((mpx-x)*(mpx-x)+(mpy-y)*(mpy-y)); if ( ( dist < minoverdist ) && node.containsPoint(mpx,mpy) ) { minoverdist = dist; monA[0] = node; } } }; visibleLocality.forAllNodes(fen); TGForEachEdge fee = new TGForEachEdge() { double minDist = 8; // Tangential distance to the edge double minFromDist = 1000; // Distance to the edge's "from" node public void forEachEdge( Edge edge ) { double x = edge.from.drawx; double y = edge.from.drawy; double dist = edge.distFromPoint(mpx,mpy); if ( dist < minDist ) { // Set the over edge to the edge with the minimun tangential distance minDist = dist; minFromDist = Math.sqrt((mpx-x)*(mpx-x)+(mpy-y)*(mpy-y)); moeA[0] = edge; } else if ( dist == minDist ) { // If tangential distances are identical, chose // the edge whose "from" node is closest. double fromDist = Math.sqrt((mpx-x)*(mpx-x)+(mpy-y)*(mpy-y)); if ( fromDist < minFromDist ) { minFromDist = fromDist; moeA[0] = edge; } } } }; visibleLocality.forAllEdges(fee); setMouseOverN(monA[0]); if ( monA[0] == null ) setMouseOverE(moeA[0]); else setMouseOverE(null); } TGPoint2D topLeftDraw = null; TGPoint2D bottomRightDraw = null; public TGPoint2D getTopLeftDraw() { return new TGPoint2D(topLeftDraw); } public TGPoint2D getBottomRightDraw() { return new TGPoint2D(bottomRightDraw); } public TGPoint2D getCenter() { return tgLensSet.convDrawToReal(getSize().width/2,getSize().height/2); } public TGPoint2D getDrawCenter() { return new TGPoint2D(getSize().width/2,getSize().height/2); } public void updateGraphSize() { if ( topLeftDraw == null ) topLeftDraw=new TGPoint2D(0,0); if ( bottomRightDraw == null ) bottomRightDraw=new TGPoint2D(0,0); TGForEachNode fen = new TGForEachNode() { boolean firstNode=true; public void forEachNode( Node node ) { if ( firstNode ) { //initialize topRight + bottomLeft topLeftDraw.setLocation(node.drawx,node.drawy); bottomRightDraw.setLocation(node.drawx,node.drawy); firstNode=false; } else { //Standard max and min finding topLeftDraw.setLocation(Math.min(node.drawx,topLeftDraw.x), Math.min(node.drawy,topLeftDraw.y)); bottomRightDraw.setLocation(Math.max(node.drawx, bottomRightDraw.x), Math.max(node.drawy, bottomRightDraw.y)); } } }; visibleLocality.forAllNodes(fen); } public synchronized void processGraphMove() { updateDrawPositions(); updateGraphSize(); } public synchronized void repaintAfterMove() { // Called by TGLayout + others to indicate that graph has moved processGraphMove(); findMouseOver(); fireMovedEvent(); repaint(); } public void updateDrawPos( Node node ) { //sets the visual position from the real position TGPoint2D p = tgLensSet.convRealToDraw(node.x,node.y); node.drawx = p.x; node.drawy = p.y; } public void updatePosFromDraw( Node node ) { //sets the real position from the visual position TGPoint2D p = tgLensSet.convDrawToReal(node.drawx,node.drawy); node.x = p.x; node.y = p.y; } public void updateDrawPositions() { TGForEachNode fen = new TGForEachNode() { public void forEachNode( Node node ) { updateDrawPos(node); } }; visibleLocality.forAllNodes(fen); } Color myBrighter( Color c ) { int r = c.getRed(); int g = c.getGreen(); int b = c.getBlue(); r=Math.min(r+96, 255); g=Math.min(g+96, 255); b=Math.min(b+96, 255); return new Color(r,g,b); } public synchronized void paint( Graphics g ) { update(g); } public synchronized void update( Graphics g ) { Dimension d = getSize(); if ( (offscreen == null) || ( d.width != offscreensize.width ) || ( d.height != offscreensize.height )) { offscreen = createImage(d.width, d.height); offscreensize = d; offgraphics = offscreen.getGraphics(); processGraphMove(); findMouseOver(); fireMovedEvent(); } offgraphics.setColor(BACK_COLOR); offgraphics.fillRect(0, 0, d.width, d.height); synchronized(this) { paintListeners = (Vector)paintListeners.clone(); } for ( int i = 0; i < paintListeners.size(); i++ ) { TGPaintListener pl = (TGPaintListener) paintListeners.elementAt(i); pl.paintFirst(offgraphics); } TGForEachEdge fee = new TGForEachEdge() { public void forEachEdge( Edge edge ) { edge.paint(offgraphics, TGPanel.this); } }; visibleLocality.forAllEdges(fee); for ( int i = 0; i < paintListeners.size() ; i++ ) { TGPaintListener pl = (TGPaintListener) paintListeners.elementAt(i); pl.paintAfterEdges(offgraphics); } TGForEachNode fen = new TGForEachNode() { public void forEachNode( Node node ) { node.paint(offgraphics,TGPanel.this); } }; visibleLocality.forAllNodes(fen); if ( mouseOverE != null ) { //Make the edge the mouse is over appear on top. mouseOverE.paint(offgraphics, this); mouseOverE.from.paint(offgraphics, this); mouseOverE.to.paint(offgraphics, this); } if ( select != null ) { //Make the selected node appear on top. select.paint(offgraphics, this); } if ( mouseOverN != null ) { //Make the node the mouse is over appear on top. mouseOverN.paint(offgraphics, this); } for ( int i = 0; i < paintListeners.size(); i++ ) { TGPaintListener pl = (TGPaintListener)paintListeners.elementAt(i); pl.paintLast(offgraphics); } paintComponents(offgraphics); //Paint any components that have been added to this panel g.drawImage(offscreen, 0, 0, null); } public static void main( String[] args ) { Frame frame; frame = new Frame("TGPanel"); TGPanel tgPanel = new TGPanel(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); TGLensSet tgls = new TGLensSet(); tgls.addLens(tgPanel.getAdjustOriginLens()); tgPanel.setLensSet(tgls); try { tgPanel.addNode(); //Add a starting node. } catch ( TGException tge ) { System.err.println(tge.getMessage()); } tgPanel.setVisible(true); new GLEditUI(tgPanel).activate(); frame.add("Center", tgPanel); frame.setSize(500,500); frame.setVisible(true); } } // end com.touchgraph.graphlayout.TGPanel TGGraphLayout/com/touchgraph/graphlayout/TGPaintListener.java0000644000175000017500000000557607561561056026454 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout; import java.awt.*; import java.util.EventListener; /** TGPaintListener. Implemented by any plugin that needs to do its own * painting. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: TGPaintListener.java,v 1.1 2002/09/19 15:58:08 ldornbusch Exp $ */ public interface TGPaintListener extends EventListener{ void paintFirst(Graphics g); void paintAfterEdges(Graphics g); void paintLast(Graphics g); } // end com.touchgraph.graphlayout.TGPaintListener TGGraphLayout/com/touchgraph/graphlayout/TGLensSet.java0000644000175000017500000001011207561561054025224 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout; import java.util.Vector; /** TGLensSet: A collection of lenses, where each lens is a function that * warps 2D space. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: TGLensSet.java,v 1.1 2002/09/19 15:58:08 ldornbusch Exp $ */ public class TGLensSet { Vector lenses=new Vector(); public void addLens( TGAbstractLens l ) { lenses.addElement(l); } public void applyLens( TGPoint2D p ) { if (lenses.isEmpty()) return; //else for (int i=0; i=0; i--) { ((TGAbstractLens) lenses.elementAt(i)).undoLens(p); } } /** Convert draw position to real position. */ public TGPoint2D convRealToDraw( TGPoint2D p ) { TGPoint2D newp = new TGPoint2D(p); applyLens(newp); return newp; } /** Convert draw position to real position. */ public TGPoint2D convRealToDraw( double x, double y ) { TGPoint2D newp = new TGPoint2D(x,y); applyLens(newp); return newp; } /** Convert real position to draw position. */ public TGPoint2D convDrawToReal( TGPoint2D p ) { TGPoint2D newp = new TGPoint2D(p); undoLens(newp); return newp; } /** Convert real position to draw position. */ public TGPoint2D convDrawToReal(double x, double y) { TGPoint2D newp = new TGPoint2D(x, y); undoLens(newp); return newp; } } // end com.touchgraph.graphlayout.TGLensSet TGGraphLayout/com/touchgraph/graphlayout/TGLayout.java0000644000175000017500000003766707561561054025154 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout; import com.touchgraph.graphlayout.graphelements.*; /** TGLayout is the thread responsible for graph layout. It updates * the real coordinates of the nodes in the graphEltSet object. * TGPanel sends it resetDamper commands whenever the layout needs * to be adjusted. After every adjustment cycle, TGLayout triggers * a repaint of the TGPanel. * * ******************************************************************** * This is the heart of the TouchGraph application. Please provide a * Reference to TouchGraph.com if you are influenced by what you see * below. Your cooperation will insure that this code remains * opensource * ******************************************************************** * *

* Parts of this code build upon Sun's Graph Layout example. * http://java.sun.com/applets/jdk/1.1/demo/GraphLayout/Graph.java *

* * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: TGLayout.java,v 1.1 2002/09/19 15:58:08 ldornbusch Exp $ */ public class TGLayout implements Runnable { //private ImmutableGraphEltSet graphEltSet; private TGPanel tgPanel; private Thread relaxer; private double damper=0.0; // A low damper value causes the graph to move slowly private double maxMotion=0; // Keep an eye on the fastest moving node to see if the graph is stabilizing private double lastMaxMotion=0; private double motionRatio = 0; // It's sort of a ratio, equal to lastMaxMotion/maxMotion-1 private boolean damping = true; // When damping is true, the damper value decreases private double rigidity = 1; // Rigidity has the same effect as the damper, except that it's a constant // a low rigidity value causes things to go slowly. // a value that's too high will cause oscillation private double newRigidity = 1; Node dragNode=null; // ............ /** Constructor with a supplied TGPanel tgp. */ public TGLayout( TGPanel tgp ) { tgPanel = tgp; //graphEltSet = tgPanel.getGES(); relaxer = null; } void setRigidity(double r) { newRigidity = r; //update rigidity at the end of the relax() thread } void setDragNode(Node n) { dragNode = n; } //relaxEdges is more like tense edges up. All edges pull nodes closes together; private synchronized void relaxEdges() { TGForEachEdge fee = new TGForEachEdge() { public void forEachEdge(Edge e) { double vx = e.to.x - e.from.x; double vy = e.to.y - e.from.y; double len = Math.sqrt(vx * vx + vy * vy); double dx=vx*rigidity; //rigidity makes edges tighter double dy=vy*rigidity; dx /=(e.getLength()*100); dy /=(e.getLength()*100); // Edges pull directly in proportion to the distance between the nodes. This is good, // because we want the edges to be stretchy. The edges are ideal rubberbands. They // They don't become springs when they are too short. That only causes the graph to // oscillate. if (e.to.justMadeLocal || e.to.markedForRemoval || (!e.from.justMadeLocal && !e.from.markedForRemoval)) { e.to.dx -= dx*len; e.to.dy -= dy*len; } else { double massfade = (e.from.markedForRemoval ? e.from.massfade : 1-e.from.massfade); massfade*=massfade; e.to.dx -= dx*len*massfade; e.to.dy -= dy*len*massfade; } if (e.from.justMadeLocal || e.from.markedForRemoval || (!e.to.justMadeLocal && !e.to.markedForRemoval)) { e.from.dx += dx*len; e.from.dy += dy*len; } else { double massfade = (e.to.markedForRemoval ? e.to.massfade : 1-e.to.massfade); massfade*=massfade; e.from.dx += dx*len*massfade; e.from.dy += dy*len*massfade; } } }; tgPanel.getGES().forAllEdges(fee); } /* private synchronized void avoidLabels() { for (int i = 0 ; i < graphEltSet.nodeNum() ; i++) { Node n1 = graphEltSet.nodeAt(i); double dx = 0; double dy = 0; for (int j = 0 ; j < graphEltSet.nodeNum() ; j++) { if (i == j) { continue; // It's kind of dumb to do things this way. j should go from i+1 to nodeNum. } Node n2 = graphEltSet.nodeAt(j); double vx = n1.x - n2.x; double vy = n1.y - n2.y; double len = vx * vx + vy * vy; // so it's length squared if (len == 0) { dx += Math.random(); // If two nodes are right on top of each other, randomly separate dy += Math.random(); } else if (len <600*600) { //600, because we don't want deleted nodes to fly too far away dx += vx / len; // If it was sqrt(len) then a single node surrounded by many others will dy += vy / len; // always look like a circle. This might look good at first, but I think // it makes large graphs look ugly + it contributes to oscillation. A // linear function does not fall off fast enough, so you get rough edges // in the 'force field' } } n1.dx += dx*100*rigidity; // rigidity makes nodes avoid each other more. n1.dy += dy*100*rigidity; // I was surprised to see that this exactly balances multiplying edge tensions // by the rigidity, and thus has the effect of slowing the graph down, while // keeping it looking identical. } } */ private synchronized void avoidLabels() { TGForEachNodePair fenp = new TGForEachNodePair() { public void forEachNodePair(Node n1, Node n2) { double dx=0; double dy=0; double vx = n1.x - n2.x; double vy = n1.y - n2.y; double len = vx * vx + vy * vy; //so it's length squared if (len == 0) { dx = Math.random(); //If two nodes are right on top of each other, randomly separate dy = Math.random(); } else if (len <600*600) { //600, because we don't want deleted nodes to fly too far away dx = vx / len; // If it was sqrt(len) then a single node surrounded by many others will dy = vy / len; // always look like a circle. This might look good at first, but I think // it makes large graphs look ugly + it contributes to oscillation. A // linear function does not fall off fast enough, so you get rough edges // in the 'force field' } int repSum = n1.repulsion * n2.repulsion/100; if(n1.justMadeLocal || n1.markedForRemoval || (!n2.justMadeLocal && !n2.markedForRemoval)) { n1.dx += dx*repSum*rigidity; n1.dy += dy*repSum*rigidity; } else { double massfade = (n2.markedForRemoval ? n2.massfade : 1-n2.massfade); massfade*=massfade; n1.dx += dx*repSum*rigidity*massfade; n1.dy += dy*repSum*rigidity*massfade; } if (n2.justMadeLocal || n2.markedForRemoval || (!n1.justMadeLocal && !n1.markedForRemoval)) { n2.dx -= dx*repSum*rigidity; n2.dy -= dy*repSum*rigidity; } else { double massfade = (n1.markedForRemoval ? n1.massfade : 1-n1.massfade); massfade*=massfade; n2.dx -= dx*repSum*rigidity*massfade; n2.dy -= dy*repSum*rigidity*massfade; } } }; tgPanel.getGES().forAllNodePairs(fenp); } public void startDamper() { damping = true; } public void stopDamper() { damping = false; damper = 1.0; //A value of 1.0 means no damping } public void resetDamper() { //reset the damper, but don't keep damping. damping = true; damper = 1.0; } public void stopMotion() { // stabilize the graph, but do so gently by setting the damper to a low value damping = true; if (damper>0.3) damper = 0.3; else damper = 0; } public void damp() { if (damping) { if(motionRatio<=0.001) { //This is important. Only damp when the graph starts to move faster //When there is noise, you damp roughly half the time. (Which is a lot) // //If things are slowing down, then you can let them do so on their own, //without damping. //If max motion<0.2, damp away //If by the time the damper has ticked down to 0.9, maxMotion is still>1, damp away //We never want the damper to be negative though if ((maxMotion<0.2 || (maxMotion>1 && damper<0.9)) && damper > 0.01) damper -= 0.01; //If we've slowed down significanly, damp more aggresively (then the line two below) else if (maxMotion<0.4 && damper > 0.003) damper -= 0.003; //If max motion is pretty high, and we just started damping, then only damp slightly else if(damper>0.0001) damper -=0.0001; } } if(maxMotion<0.001 && damping) { damper=0; } } private synchronized void moveNodes() { lastMaxMotion = maxMotion; final double[] maxMotionA = new double[1]; maxMotionA[0]=0; TGForEachNode fen = new TGForEachNode() { public void forEachNode(Node n) { double dx = n.dx; double dy = n.dy; dx*=damper; //The damper slows things down. It cuts down jiggling at the last moment, and optimizes dy*=damper; //layout. As an experiment, get rid of the damper in these lines, and make a //long straight line of nodes. It wiggles too much and doesn't straighten out. n.dx=dx/2; //Slow down, but don't stop. Nodes in motion store momentum. This helps when the force n.dy=dy/2; //on a node is very low, but you still want to get optimal layout. double distMoved = Math.sqrt(dx*dx+dy*dy); //how far did the node actually move? if (!n.fixed && !(n==dragNode) ) { n.x += Math.max(-30, Math.min(30, dx)); //don't move faster then 30 units at a time. n.y += Math.max(-30, Math.min(30, dy)); //I forget when this is important. Stopping severed nodes from //flying away? } maxMotionA[0]=Math.max(distMoved,maxMotionA[0]); if(!n.justMadeLocal && !n.markedForRemoval) { n.massfade=1; } else { if(n.massfade>=0.004) n.massfade-=0.004; } } }; tgPanel.getGES().forAllNodes(fen); maxMotion=maxMotionA[0]; if (maxMotion>0) motionRatio = lastMaxMotion/maxMotion-1; //subtract 1 to make a positive value mean that else motionRatio = 0; //things are moving faster damp(); } private synchronized void relax() { for (int i=0;i<10;i++) { relaxEdges(); avoidLabels(); moveNodes(); } if(rigidity!=newRigidity) rigidity= newRigidity; //update rigidity tgPanel.repaintAfterMove(); } private void myWait() { //I think it was Netscape that caused me not to use Wait, or was it java 1.1? try { Thread.sleep(100); } catch (InterruptedException e) { //break; } } public void run() { Thread me = Thread.currentThread(); // me.setPriority(1); //Makes standard executable look better, but the applet look worse. while (relaxer == me) { relax(); try { relaxer.sleep(20); //Delay to wait for the prior repaint command to finish. while(damper<0.1 && damping && maxMotion<0.001) myWait(); //System.out.println("damping " + damping + " damp " + damper + " maxM " + maxMotion + " motR " + motionRatio ); } catch (InterruptedException e) { break; } } } public void start() { relaxer = new Thread(this); relaxer.start(); } public void stop() { relaxer = null; } } // end com.touchgraph.graphlayout.TGLayout TGGraphLayout/com/touchgraph/graphlayout/TGException.java0000644000175000017500000001077707561561054025626 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout; /**

An class for exceptions thrown during TouchGraph processing.

* * @author Alexander Shapiro * @author Murray Altheim * @version 1.22-jre1.1 $Id: TGException.java,v 1.1 2002/09/19 15:58:08 ldornbusch Exp $ */ public class TGException extends Exception { /** An exception occurring when a Node already exists. */ public final static int NODE_EXISTS = 1; /** An exception occurring when a Node doesn't exist. */ public final static int NODE_DOESNT_EXIST = 2; /** An exception occurring when a Node is missing its required ID. */ public final static int NODE_NO_ID = 3; /** An int containing an exception type identifier (ID). */ protected int id = -1; /** The embedded Exception if tunnelling. * @serial The embedded exception if tunnelling, or null. */ public Exception exception = null; // ............. /** Constructor for TGException with Exception ID. * * @param id The unique message identifier. */ public TGException( int id ) { super(); this.id = id; } /** Constructor for TGException with Exception ID and error message String. * * @param id The unique message identifier. * @param message The Exception message. */ public TGException( int id, String message ) { super(message); this.id = id; } /** Constructor for TGException with an error message String. * * @param message The Exception message. */ public TGException( String message ) { super(message); } /** Constructor for TGException tunnelling the original Exception. * * @param exception The original Exception. */ public TGException( Exception exception ) { super(); this.exception = exception; } /** If the message was expressed as a MessageId, return the original * id (e.g. "45"). * * @return the exception identifier. */ public int getId() { return id; } } // end com.touchgraph.graphlayout.TGException TGGraphLayout/com/touchgraph/graphlayout/TGAbstractLens.java0000644000175000017500000000540607561561054026246 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout; /** TGAbstractLens. A lens warps 2D space. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: TGAbstractLens.java,v 1.1 2002/09/19 15:58:07 ldornbusch Exp $ */ public abstract class TGAbstractLens { protected void applyLens( TGPoint2D p ) {} protected void undoLens( TGPoint2D p ) {} } // end com.touchgraph.graphlayout.TGAbstractLens TGGraphLayout/com/touchgraph/graphlayout/Node.java0000644000175000017500000004106707561561052024314 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Point; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.util.Date; import java.util.Vector; //import java.util.Iterator; /** Node. * * @author Alexander Shapiro * @author Murray Altheim (2001-11-06; added support for round rects and alternate Node colors) * @version 1.22-jre1.1 $Id: Node.java,v 1.2 2002/09/20 14:00:22 ldornbusch Exp $ */ public class Node { /** This Node's type is a Rectangle. */ public final static int TYPE_RECTANGLE = 1; /** This Node's type is a Round Rectangle. */ public final static int TYPE_ROUNDRECT = 2; /** This Node's type is an Ellipse. */ public final static int TYPE_ELLIPSE = 3; /** This Node's type is a Circle. */ public final static int TYPE_CIRCLE = 4; public static final Font SMALL_TAG_FONT = new Font("Courier",Font.PLAIN,9); // Variables that store default values for colors + fonts + node type public Color BACK_FIXED_COLOR = new Color(255, 32, 20); public Color BACK_SELECT_COLOR = new Color(225, 164, 0); public Color BACK_DEFAULT_COLOR = Color.decode("#4080A0"); public Color BACK_HILIGHT_COLOR = new Color(205, 192, 166); public Color BACK_MRF_COLOR = new Color(2,35,81); public Color BACK_JML_COLOR = new Color(58, 176, 255); public Color BORDER_DRAG_COLOR = new Color(130,130,180); public Color BORDER_MOUSE_OVER_COLOR = new Color(160,160,180); public Color BORDER_INACTIVE_COLOR = new Color(30,50,160); public Color TEXT_COLOR = Color.white; public static Font TEXT_FONT = new Font("Verdana",Font.PLAIN,10); public static int DEFAULT_TYPE = 1; /** an int indicating the Node type. * @see TYPE_RECTANGLE * @see TYPE_ROUNDRECT * @see TYPE_ELLIPSE */ protected int typ = TYPE_RECTANGLE; private String id; public double drawx; public double drawy; protected FontMetrics fontMetrics; protected Font font; protected String lbl; protected Color backColor = BACK_DEFAULT_COLOR; protected Color textColor = TEXT_COLOR; public double x; public double y; public double massfade=1; //Used by layout protected double dx; //Used by layout protected double dy; //Used by layout protected boolean fixed; protected int repulsion; //Used by layout public boolean justMadeLocal = false; public boolean markedForRemoval = false; public int visibleEdgeCnt; //Should only be modified by graphelements.VisibleLocality protected boolean visible; private Vector edges; // ............ // Modification by Lutz private String strUrl; /** Minimal constructor which will generate an ID value from Java's Date class. * Defaults will be used for type and color. The label will be taken from the ID value. */ public Node() { initialize(null); lbl = id; } /** Constructor with the required ID id, using defaults * for type (rectangle), color (a static variable from TGPanel). * The Node's label will be taken from the ID value. */ public Node( String id ) { initialize(id); lbl = id; } /** Constructor with Strings for ID id and label, using defaults * for type (rectangle) and color (a static variable from TGPanel). * If the label is null, it will be taken from the ID value. */ public Node( String id, String label ) { initialize(id); if ( label == null ) lbl = id; else lbl = label; } /** Constructor with a String ID id, an int type, Background Color bgColor, * and a String label. If the label is null, it will be taken from the ID value. * @see TYPE_RECTANGLE * @see TYPE_ROUNDRECT */ public Node( String id, int type, Color color, String label ) { initialize(id); typ = type; backColor = color; if ( label == null ) lbl = id; else lbl = label; } private void initialize( String identifier ) { this.id = identifier; edges = new Vector(); x = Math.random()*2-1; // If multiple nodes are added without repositioning, y = Math.random()*2-1; // randomizing starting location causes them to spread out nicely. repulsion = 100; font = TEXT_FONT; fixed = false; typ = DEFAULT_TYPE; visibleEdgeCnt=0; visible = false; } // setters and getters ............... public void setNodeBackFixedColor( Color color ) { BACK_FIXED_COLOR = color; } public void setNodeBackSelectColor( Color color ) { BACK_SELECT_COLOR = color; } public void setNodeBackDefaultColor( Color color ) { BACK_DEFAULT_COLOR = color; } public void setNodeBackHilightColor( Color color ) { BACK_HILIGHT_COLOR = color; } public void setNodeBorderDragColor( Color color ) { BORDER_DRAG_COLOR = color; } public void setNodeBorderMouseOverColor( Color color ) { BORDER_MOUSE_OVER_COLOR = color; } public void setNodeBorderInactiveColor( Color color ) { BORDER_INACTIVE_COLOR = color; } public void setNodeTextColor( Color color ) { TEXT_COLOR = color; } public void setNodeTextFont( Font font ) { TEXT_FONT = font; } public void setNodeType( int type ) { DEFAULT_TYPE = type; } /** Set the ID of this Node to the String id. */ public void setID( String id ) { this.id = id; } /** Return the ID of this Node as a String. */ public String getID() { return id; } /** Set the location of this Node provided the Point p. */ public void setLocation( Point p ) { this.x = p.x; this.y = p.y; } /** Return the location of this Node as a Point. */ public Point getLocation() { return new Point((int)x,(int)y); } /** Set the visibility of this Node to the boolean v. */ public void setVisible( boolean v) { visible = v; } /** Return the visibility of this Node as a boolean. */ public boolean isVisible() { return visible; } /** Set the type of this Node to the int type. * @see TYPE_RECTANGLE * @see TYPE_ROUNDRECT * @see TYPE_ELLIPSE * @see TYPE_CIRCLE */ public void setType( int type ) { typ = type; } /** Return the type of this Node as an int. * @see TYPE_RECTANGLE * @see TYPE_ROUNDRECT * @see TYPE_ELLIPSE * @see TYPE_CIRCLE */ public int getType() { return typ; } /** Set the font of this Node to the Font font. */ public void setFont( Font font ) { this.font = font; } /** Returns the font of this Node as a Font*/ public Font getFont() { return font; } /** Set the background color of this Node to the Color bgColor. */ public void setBackColor( Color bgColor ) { backColor = bgColor; } /** Return the background color of this Node as a Color. */ public Color getBackColor() { return backColor; } /** Set the text color of this Node to the Color txtColor. */ public void setTextColor( Color txtColor ) { textColor = txtColor; } /** Return the text color of this Node as a Color. */ public Color getTextColor() { return textColor; } /** Set the label of this Node to the String label. */ public void setLabel( String label ) { lbl = label; } /** Return the label of this Node as a String. */ public String getLabel() { return lbl; } /** Set the fixed status of this Node to the boolean fixed. */ public void setFixed( boolean fixed ) { this.fixed = fixed; } /** Returns true if this Node is fixed (in place). */ public boolean getFixed() { return fixed; } // .... /** Return the number of Edges in the cumulative Vector. * @deprecated this method has been replaced by the edgeCount() method. */ public int edgeNum() { return edges.size(); } /** Return the number of Edges in the cumulative Vector. */ public int edgeCount() { return edges.size(); } /** Return an iterator over the Edges in the cumulative Vector, null if it is empty. */ /* public Iterator getEdges() { if ( edges.size() == 0 ) return null; else return edges.iterator(); } */ /** Returns the local Edge count. */ public int visibleEdgeCount() { return visibleEdgeCnt; } /** Return the Edge at int index. */ public Edge edgeAt( int index ) { return (Edge)edges.elementAt(index); } /** Add the Edge edge to the graph. */ public void addEdge( Edge edge ) { if ( edge == null ) return; edges.addElement(edge); } /** Remove the Edge edge from the graph. */ public void removeEdge( Edge edge ) { edges.removeElement(edge); } /** Return the width of this Node. */ public int getWidth() { if ( fontMetrics != null && lbl != null ) { return fontMetrics.stringWidth(lbl) + 12; } else { return 10; } } /** Return the height of this Node. */ public int getHeight() { if ( fontMetrics != null ) { return fontMetrics.getHeight() + 6; } else { return 6; } } /** Returns true if this Node intersects Dimension d. */ public boolean intersects( Dimension d ) { return ( drawx > 0 && drawx < d.width && drawy>0 && drawy < d.height ); } /** Returns true if this Node contains the Point px,py. */ public boolean containsPoint( double px, double py ) { return (( px > drawx-getWidth()/2) && ( px < drawx+getWidth()/2) && ( py > drawy-getHeight()/2) && ( py < drawy+getHeight()/2)); } /** Returns true if this Node contains the Point p. */ public boolean containsPoint( Point p ) { return (( p.x > drawx-getWidth()/2) && ( p.x < drawx+getWidth()/2) && ( p.y > drawy-getHeight()/2) && ( p.y < drawy+getHeight()/2)); } /** Paints the Node. */ public void paint( Graphics g, TGPanel tgPanel ) { if (!intersects(tgPanel.getSize()) ) return; paintNodeBody(g, tgPanel); if ( visibleEdgeCount()1) Thread.currentThread().sleep(100); } if(radius!=1) { addNearNodes(distHash,radius); for (int i=0;i<4&&!fastFinishShift;i++) { Thread.currentThread().sleep(100); } unmarkNewAdditions(); } } catch ( TGException tge ) { System.err.println("TGException: " + tge.getMessage()); } catch (InterruptedException ex) {} tgPanel.resetDamper(); } } } public void setLocale(Node n, final int radius, final int maxAddEdgeCount, final int maxExpandEdgeCount, final boolean unidirectional) throws TGException { if (n==null || radius<0) return; if(shiftLocaleThread!=null && shiftLocaleThread.isAlive()) { fastFinishShift=true; //This should cause last locale shift to finish quickly while(shiftLocaleThread.isAlive()) try { Thread.currentThread().sleep(100); } catch (InterruptedException ex) {} } if (radius == INFINITE_LOCALITY_RADIUS || n==null) { addAllGraphElts(); tgPanel.resetDamper(); return; } fastFinishShift=false; shiftLocaleThread=new ShiftLocaleThread(n, radius, maxAddEdgeCount, maxExpandEdgeCount, unidirectional); } public void setLocale(Node n, final int radius) throws TGException { setLocale(n,radius,1000,1000, false); } public synchronized void addAllGraphElts() throws TGException { locality.addAll(); } /** Add to locale nodes that are one edge away from a given node. * This method does not utilize "fastFinishShift" so it's likely that * synchronization errors will occur. */ public void expandNode(final Node n) { new Thread() { public void run() { synchronized (LocalityUtils.this) { if (!locality.getCompleteEltSet().contains(n)) return; tgPanel.stopDamper(); for(int i=0;ip. */ public void setOffset( Point p ) { hvScroll.setOffset(p); }; /** Return the horizontal and vertical offset position as a Point. */ public Point getOffset() { return hvScroll.getOffset(); }; // rotation ................... /** Return the RotateScroll used with this GLPanel. */ public RotateScroll getRotateScroll() { return rotateScroll; } /** Set the rotation angle of this GLPanel (allowable values between 0 to 359). */ public void setRotationAngle( int angle ) { rotateScroll.setRotationAngle(angle); } /** Return the rotation angle of this GLPanel. */ public int getRotationAngle() { return rotateScroll.getRotationAngle(); } // locality ................... /** Return the LocalityScroll used with this GLPanel. */ public LocalityScroll getLocalityScroll() { return localityScroll; } /** Set the locality radius of this TGScrollPane * (allowable values between 0 to 4, or LocalityUtils.INFINITE_LOCALITY_RADIUS). */ public void setLocalityRadius( int radius ) { localityScroll.setLocalityRadius(radius); } /** Return the locality radius of this GLPanel. */ public int getLocalityRadius() { return localityScroll.getLocalityRadius(); } // zoom ....................... /** Return the ZoomScroll used with this GLPanel. */ public ZoomScroll getZoomScroll() { return zoomScroll; } /** Set the zoom value of this GLPanel (allowable values between -100 to 100). */ public void setZoomValue( int zoomValue ) { zoomScroll.setZoomValue(zoomValue); } /** Return the zoom value of this GLPanel. */ public int getZoomValue() { return zoomScroll.getZoomValue(); } // .... public PopupMenu getGLPopup() { return glPopup; } public void buildLens() { tgLensSet.addLens(hvScroll.getLens()); tgLensSet.addLens(zoomScroll.getLens()); tgLensSet.addLens(hyperScroll.getLens()); tgLensSet.addLens(rotateScroll.getLens()); tgLensSet.addLens(tgPanel.getAdjustOriginLens()); } public void buildPanel() { final Scrollbar horizontalSB = hvScroll.getHorizontalSB(); final Scrollbar verticalSB = hvScroll.getVerticalSB(); final Scrollbar zoomSB = zoomScroll.getZoomSB(); final Scrollbar rotateSB = rotateScroll.getRotateSB(); final Scrollbar localitySB = localityScroll.getLocalitySB(); final Scrollbar hyperSB = hyperScroll.getHyperSB(); setLayout(new BorderLayout()); Panel scrollPanel = new Panel(); scrollPanel.setBackground(defaultBackColor); scrollPanel.setForeground(defaultForeColor); scrollPanel.setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); Panel modeSelectPanel = new Panel(); modeSelectPanel.setBackground(defaultBackColor); modeSelectPanel.setForeground(defaultForeColor); modeSelectPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0,0)); final Panel topPanel = new Panel(); topPanel.setBackground(defaultBorderBackColor); topPanel.setForeground(defaultForeColor); topPanel.setLayout(new GridBagLayout()); c.gridy=0; c.fill=GridBagConstraints.HORIZONTAL; c.gridx=0;c.weightx=0; c.insets=new Insets(0,0,0,0); c.gridy=0;c.weightx=1; scrollBarHash.put(zoomLabel, zoomSB); scrollBarHash.put(rotateLabel, rotateSB); scrollBarHash.put(localityLabel, localitySB); scrollBarHash.put(hyperLabel, hyperSB); Panel scrollselect = scrollSelectPanel(new String[] {zoomLabel, rotateLabel /*, localityLabel*/, hyperLabel}); scrollselect.setBackground(defaultBorderBackColor); scrollselect.setForeground(defaultForeColor); topPanel.add(scrollselect,c); add(topPanel, BorderLayout.SOUTH); c.fill = GridBagConstraints.BOTH; c.gridwidth = 1; c.gridx = 0; c.gridy = 1; c.weightx = 1; c.weighty = 1; scrollPanel.add(tgPanel,c); c.gridx = 1; c.gridy = 1; c.weightx = 0; c.weighty = 0; // scrollPanel.add(verticalSB,c); // For WDR We do not need scrollbars c.gridx = 0; c.gridy = 2; // scrollPanel.add(horizontalSB,c); // For WDR We do not need scrollbars add(scrollPanel,BorderLayout.CENTER); glPopup = new PopupMenu(); add(glPopup); // needed by JDK11 Popupmenu.. MenuItem menuItem = new MenuItem("Toggle Controls"); ActionListener toggleControlsAction = new ActionListener() { boolean controlsVisible = true; public void actionPerformed(ActionEvent e) { controlsVisible = !controlsVisible; horizontalSB.setVisible(controlsVisible); verticalSB.setVisible(controlsVisible); topPanel.setVisible(controlsVisible); GLPanel.this.doLayout(); } }; menuItem.addActionListener(toggleControlsAction); glPopup.add(menuItem); } protected Panel scrollSelectPanel(final String[] scrollBarNames) { final Panel sbp = new Panel(new GridBagLayout()); // UI: Scrollbarselector via Radiobuttons................................. sbp.setBackground(defaultBorderBackColor); sbp.setForeground(defaultForeColor); Panel firstRow=new Panel(new GridBagLayout()); final CheckboxGroup bg = new CheckboxGroup(); int cbNumber = scrollBarNames.length; Checkbox checkboxes[] = new Checkbox[cbNumber]; GridBagConstraints c = new GridBagConstraints(); c.anchor=GridBagConstraints.WEST; c.gridy = 0; c.weightx= 0; c.fill = GridBagConstraints.HORIZONTAL; for (int i=0;icolor. */ public void setColor( Color color ) { col = color; } /** Returns the ID of this Edge as a String. */ public String getID() { return id; } /** Set the ID of this Edge to the String id. */ public void setID( String id ) { this.id=id; } /** Returns the length of this Edge as a double. */ public int getLength() { return length; } /** Set the length of this Edge to the int len. */ public void setLength(int len) { length=len; } /** Set the visibility of this Edge to the boolean v. */ public void setVisible( boolean v) { visible = v; } /** Return the visibility of this Edge as a boolean. */ public boolean isVisible() { return visible; } public Node getOtherEndpt(Node n) { //yields false results if Node n is not an endpoint if (to != n) return to; else return from; } /** Switches the endpoints of the edge */ public void reverse() { Node temp = to; to = from; from = temp; } public boolean intersects(Dimension d) { int x1 = (int) from.drawx; int y1 = (int) from.drawy; int x2 = (int) to.drawx; int y2 = (int) to.drawy; return (((x1>0 || x2>0) && (x10 || y2>0) && (y1Math.max(x1, x2)+8 || pyMath.max(y1, y2)+8) return 1000; double dist = 1000; if (x1-x2!=0) dist = Math.abs((y2-y1)/(x2-x1)*(px - x1) + (y1 - py)); if (y1-y2!=0) dist = Math.min(dist, Math.abs((x2-x1)/(y2-y1)*(py - y1) + (x1 - px))); return dist; } public boolean containsPoint(double px, double py) { return distFromPoint(px,py)<10; } public static void paintArrow(Graphics g, int x1, int y1, int x2, int y2, Color c) { //Forget hyperbolic bending for now g.setColor(c); int x3=x1; int y3=y1; double dist=Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)); if (dist>10) { double adjustDistRatio = (dist-10)/dist; x3=(int) (x1+(x2-x1)*adjustDistRatio); y3=(int) (y1+(y2-y1)*adjustDistRatio); } x3=(int) ((x3*4+x1)/5.0); y3=(int) ((y3*4+y1)/5.0); g.drawLine(x3, y3, x2, y2); g.drawLine(x1, y1, x3, y3); g.drawLine(x1+1, y1, x3, y3); g.drawLine(x1+2, y1, x3, y3); g.drawLine(x1+3, y1, x3, y3); g.drawLine(x1+4, y1, x3, y3); g.drawLine(x1-1, y1, x3, y3); g.drawLine(x1-2, y1, x3, y3); g.drawLine(x1-3, y1, x3, y3); g.drawLine(x1-4, y1, x3, y3); g.drawLine(x1, y1+1, x3, y3); g.drawLine(x1, y1+2, x3, y3); g.drawLine(x1, y1+3, x3, y3); g.drawLine(x1, y1+4, x3, y3); g.drawLine(x1, y1-1, x3, y3); g.drawLine(x1, y1-2, x3, y3); g.drawLine(x1, y1-3, x3, y3); g.drawLine(x1, y1-4, x3, y3); } public void paint(Graphics g, TGPanel tgPanel) { Color c = (tgPanel.getMouseOverE()==this) ? MOUSE_OVER_COLOR : col; int x1=(int) from.drawx; int y1=(int) from.drawy; int x2=(int) to.drawx; int y2=(int) to.drawy; if (intersects(tgPanel.getSize())) paintArrow(g, x1, y1, x2, y2, c); } } // end com.touchgraph.graphlayout.Edge TGGraphLayout/com/touchgraph/graphlayout/interaction/ZoomScroll.java0000644000175000017500000001105007543651514030041 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import java.awt.event.*; import java.awt.*; //import javax.swing.*; /** ZoomScroll: Contains code for enlarging the graph by zooming in. * * @author Alexander Shapiro * @version 1.21 $Id: ZoomScroll.java,v 1.2 2002/09/23 18:45:48 ldornbusch Exp $ */ public class ZoomScroll implements GraphListener { protected ZoomLens zoomLens; private Scrollbar zoomSB; private TGPanel tgPanel; // ............ /** Constructor with TGPanel tgp. */ public ZoomScroll( TGPanel tgp ) { tgPanel=tgp; zoomSB = new Scrollbar(Scrollbar.HORIZONTAL, -4, 7, -31, 19); zoomSB.addAdjustmentListener(new zoomAdjustmentListener()); zoomLens=new ZoomLens(); tgPanel.addGraphListener(this); } public Scrollbar getZoomSB() { return zoomSB; } public ZoomLens getLens() { return zoomLens; } public void graphMoved() {} //From GraphListener interface public void graphReset() { zoomSB.setValue(-10); } //From GraphListener interface public int getZoomValue() { double orientedValue = zoomSB.getValue()-zoomSB.getMinimum(); double range = zoomSB.getMaximum()-zoomSB.getMinimum()-zoomSB.getVisibleAmount(); return (int) ((orientedValue/range)*200-100); } public void setZoomValue(int value) { double range = zoomSB.getMaximum()-zoomSB.getMinimum()-zoomSB.getVisibleAmount(); zoomSB.setValue((int) ((value+100)/200.0 * range+0.5)+zoomSB.getMinimum()); } private class zoomAdjustmentListener implements AdjustmentListener { public void adjustmentValueChanged(AdjustmentEvent e) { tgPanel.repaintAfterMove(); } } class ZoomLens extends TGAbstractLens { protected void applyLens(TGPoint2D p) { p.x=p.x*Math.pow(2,zoomSB.getValue()/10.0); p.y=p.y*Math.pow(2,zoomSB.getValue()/10.0); } protected void undoLens(TGPoint2D p) { p.x=p.x/Math.pow(2,zoomSB.getValue()/10.0); p.y=p.y/Math.pow(2,zoomSB.getValue()/10.0); } } } // end com.touchgraph.graphlayout.interaction.ZoomScroll TGGraphLayout/com/touchgraph/graphlayout/interaction/TGUserInterface.java0000644000175000017500000000711707561561342030740 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import java.awt.*; import java.awt.event.*; import java.util.Vector; /** TGUserInterface. A user interface that can be activated or deactivated, * much like a listener can be added or removed. * * If a parent UI is specified as a parameter to activate() then the parent UI * is temporarily disabled while the current UI is active. Classes that extend * TGUserInterface must call super.deactivate() if they override this method. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: TGUserInterface.java,v 1.1 2002/09/19 15:58:21 ldornbusch Exp $ */ public abstract class TGUserInterface { private TGUserInterface parentUI; public abstract void activate(); /** Each user interface is responsible for properly setting this variable. */ boolean active; public boolean isActive() { return active; } public void activate( TGUserInterface parent ) { parentUI = parent; parentUI.deactivate(); activate(); } public void deactivate() { if (parentUI!=null) parentUI.activate(); parentUI = null; } } // end com.touchgraph.graphlayout.interaction.TGUserInterface TGGraphLayout/com/touchgraph/graphlayout/interaction/TGUIManager.java0000644000175000017500000001067007561561342030007 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import java.awt.*; import java.awt.event.*; import java.util.Vector; /** TGUIManager switches between major user interfaces, and allows * them to be referred to by name. This will probably come in handy * when switching user interfaces from menus. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: TGUIManager.java,v 1.1 2002/09/19 15:58:21 ldornbusch Exp $ */ public class TGUIManager { Vector userInterfaces; // ............ /** Default constructor. */ public TGUIManager() { userInterfaces = new Vector(); } class NamedUI { TGUserInterface ui; String name; NamedUI( TGUserInterface ui, String n ) { this.ui = ui; name = n; } } public void addUI( TGUserInterface ui, String name ) { userInterfaces.addElement(new NamedUI(ui,name)); } public void addUI( TGUserInterface ui ) { addUI(ui,null); } public void removeUI( String name ) { for (int i=0;itgp
. */ public TGAbstractMousePausedUI( TGPanel tgp ) { // Instantiate this way to keep listening // for clicks until deactivate is called tgPanel=tgp; ml = new AMPUIMouseListener(); mml = new AMPUIMouseMotionListener(); } public final void activate() { preActivate(); tgPanel.addMouseMotionListener(mml); tgPanel.addMouseListener(ml); } public final void deactivate() { tgPanel.removeMouseMotionListener(mml); tgPanel.removeMouseListener(ml); postDeactivate(); super.deactivate(); //To activate parentUI from TGUserInterface } public void preActivate() {} public void postDeactivate() {} public abstract void mousePaused(MouseEvent e); public abstract void mouseMoved(MouseEvent e); public abstract void mouseDragged(MouseEvent e); class PauseThread extends Thread{ boolean resetSleep; boolean cancelled; PauseThread() { cancelled = false; start(); } void reset() { resetSleep = true; cancelled = false; } void cancel() { cancelled = true; } public void run() { try { do { resetSleep=false; sleep(250); } while (resetSleep); if (!cancelled) { MouseEvent pausedEvent = new MouseEvent(tgPanel,MouseEvent.MOUSE_ENTERED, 0,0, mousePos.x,mousePos.y,0,false); mousePaused(pausedEvent); } } catch (Exception e) {e.printStackTrace();} } } public void resetPause() { if (pauseThread!=null && pauseThread.isAlive()) pauseThread.reset(); else pauseThread = new PauseThread(); } public void cancelPause() { if (pauseThread!=null && pauseThread.isAlive()) pauseThread.cancel(); } private class AMPUIMouseMotionListener implements MouseMotionListener { public void mouseMoved(MouseEvent e) { mousePos=e.getPoint(); resetPause(); TGAbstractMousePausedUI.this.mouseMoved(e); } public void mouseDragged(MouseEvent e) { mousePos=e.getPoint(); resetPause(); TGAbstractMousePausedUI.this.mouseDragged(e); } } private class AMPUIMouseListener extends MouseAdapter { public void mousePressed(MouseEvent e) { cancelPause(); } public void mouseReleased(MouseEvent e) { cancelPause(); } public void mouseExited(MouseEvent e) { //cancelPause(); } } } // end com.touchgraph.graphlayout.interaction.TGAbstractMousePauseUI TGGraphLayout/com/touchgraph/graphlayout/interaction/TGAbstractMouseMotionUI.java0000644000175000017500000000731207561561340032374 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import java.awt.*; import java.awt.event.*; /** TGAbstractMouseMotionUI allows one to write user interfaces that handle * what happends when a mouse is moved over the screen * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: TGAbstractMouseMotionUI.java,v 1.1 2002/09/19 15:58:21 ldornbusch Exp $ */ public abstract class TGAbstractMouseMotionUI extends TGUserInterface{ TGPanel tgPanel; private AMMUIMouseMotionListener mml; // ............ /** Constructor with TGPanel tgp. */ public TGAbstractMouseMotionUI( TGPanel tgp ) { tgPanel=tgp; mml=new AMMUIMouseMotionListener(); } public final void activate() { tgPanel.addMouseMotionListener(mml); } public final void deactivate() { tgPanel.removeMouseMotionListener(mml); super.deactivate(); //To activate parentUI from TGUserInterface } public abstract void mouseMoved(MouseEvent e); public abstract void mouseDragged(MouseEvent e); private class AMMUIMouseMotionListener extends MouseMotionAdapter { public void mouseMoved(MouseEvent e) { TGAbstractMouseMotionUI.this.mouseMoved(e); } public void mouseDragged(MouseEvent e) { TGAbstractMouseMotionUI.this.mouseMoved(e); } } } // end com.touchgraph.graphlayout.interaction.TGAbstractMouseMotionUI TGGraphLayout/com/touchgraph/graphlayout/interaction/TGAbstractDragUI.java0000644000175000017500000001116207561561340030771 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import java.awt.*; import java.awt.event.*; /** TGAbstractDragUI allows one to write user interfaces that handle * what happends when a mouse is pressed, dragged, and released. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: TGAbstractDragUI.java,v 1.1 2002/09/19 15:58:21 ldornbusch Exp $ */ public abstract class TGAbstractDragUI extends TGSelfDeactivatingUI { public TGPanel tgPanel; private ADUIMouseListener ml; private ADUIMouseMotionListener mml; public boolean mouseWasDragged; //To differentiate between mouse pressed+dragged, and mouseClicked // ............ /** Constructor with TGPanel tgp. */ public TGAbstractDragUI(TGPanel tgp) { tgPanel=tgp; ml =new ADUIMouseListener(); mml=new ADUIMouseMotionListener(); } public final void activate() { preActivate(); tgPanel.addMouseListener(ml); tgPanel.addMouseMotionListener(mml); mouseWasDragged=false; } public final void activate(MouseEvent e) { activate(); mousePressed(e); } public final void deactivate() { preDeactivate(); tgPanel.removeMouseListener(ml); tgPanel.removeMouseMotionListener(mml); super.deactivate(); //To activate parentUI from TGUserInterface } public abstract void preActivate(); public abstract void preDeactivate(); public abstract void mousePressed( MouseEvent e ); public abstract void mouseDragged( MouseEvent e ); public abstract void mouseReleased( MouseEvent e ); private class ADUIMouseListener extends MouseAdapter { public void mousePressed(MouseEvent e) { TGAbstractDragUI.this.mousePressed(e); } public void mouseReleased(MouseEvent e) { TGAbstractDragUI.this.mouseReleased(e); if (selfDeactivate) deactivate(); } } private class ADUIMouseMotionListener extends MouseMotionAdapter { public void mouseDragged(MouseEvent e) { mouseWasDragged=true; TGAbstractDragUI.this.mouseDragged(e); } } } // end com.touchgraph.graphlayout.interaction.TGAbstractDragUI TGGraphLayout/com/touchgraph/graphlayout/interaction/TGAbstractClickUI.java0000644000175000017500000001000607561561340031135 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import java.awt.*; import java.awt.event.*; /** TGAbstractClickUI allows one to write interfaces that deal with * mouse clicks. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: TGAbstractClickUI.java,v 1.1 2002/09/19 15:58:21 ldornbusch Exp $ */ public abstract class TGAbstractClickUI extends TGSelfDeactivatingUI { private ACUIMouseListener ml; private TGPanel tgPanel; public TGAbstractClickUI() { // Instantiate this way if you want to finish after one click tgPanel=null; ml= null; } public TGAbstractClickUI(TGPanel tgp) { // Instantiate this way to keep listening for clicks until // deactivate is called tgPanel=tgp; ml = new ACUIMouseListener(); } public final void activate() { if (tgPanel!=null && ml!=null) tgPanel.addMouseListener(ml); } public final void activate(MouseEvent e) { mouseClicked(e); } public final void deactivate() { if (tgPanel!=null && ml!=null) tgPanel.removeMouseListener(ml); super.deactivate(); //To activate parentUI from TGUserInterface } public abstract void mouseClicked(MouseEvent e); private class ACUIMouseListener extends MouseAdapter { public void mouseClicked(MouseEvent e) { TGAbstractClickUI.this.mouseClicked(e); if (selfDeactivate) deactivate(); } } } // end com.touchgraph.graphlayout.interaction.TGAbstractClickUI TGGraphLayout/com/touchgraph/graphlayout/interaction/RotateScroll.java0000644000175000017500000001720507561561340030360 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import java.awt.event.*; import java.awt.*; //import javax.swing.*; /** RotateScroll. Allows one to rotate the graph by clicking+dragging * The rotate lens won't work properly unless it's the top lens, because it * does not account for distortion from above lenses. Methods for getting * lenses above the current one need to be added to TGLensSet to solve this problem. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: RotateScroll.java,v 1.2 2002/09/23 18:45:48 ldornbusch Exp $ */ public class RotateScroll implements GraphListener { RotateLens rotateLens; double rotateAngle; RotateDragUI rotateDragUI; private DScrollBar rotateSB; boolean adjustmentIsInternal; private TGPanel tgPanel; // ............ /** Constructor with TGPanel tgp. */ public RotateScroll(TGPanel tgp) { tgPanel=tgp; rotateAngle=0; rotateLens=new RotateLens(); rotateDragUI = new RotateDragUI(); rotateSB = new DScrollBar(Scrollbar.HORIZONTAL, 0, 80, -314, 318); rotateSB.addAdjustmentListener(new rotateAdjustmentListener()); adjustmentIsInternal=false; tgPanel.addGraphListener(this); } public RotateLens getLens() { return rotateLens; } public Scrollbar getRotateSB() { return rotateSB; } public RotateDragUI getRotateDragUI() { return rotateDragUI; } public int getRotationAngle() { double orientedValue = rotateSB.getValue()-rotateSB.getMinimum(); double range = rotateSB.getMaximum()-rotateSB.getMinimum()-rotateSB.getVisibleAmount(); return (int) ((orientedValue/range)*359); } public void setRotationAngle(int angle) { double range = rotateSB.getMaximum()-rotateSB.getMinimum()-rotateSB.getVisibleAmount(); rotateSB.setValue((int) (angle/359.0 * range+0.5)+rotateSB.getMinimum()); } public void graphMoved() {} //From GraphListener interface public void graphReset() { rotateAngle=0; rotateSB.setValue(0); } //From GraphListener interface private class rotateAdjustmentListener implements AdjustmentListener { public void adjustmentValueChanged(AdjustmentEvent e) { if(!adjustmentIsInternal) { rotateAngle = rotateSB.getDValue()/100.0; tgPanel.repaintAfterMove(); } } } class DScrollBar extends Scrollbar { private double doubleValue; DScrollBar(int orient, int val, int vis, int min, int max){ super(orient, val, vis, min, max); doubleValue=val; } public void setValue(int v) { doubleValue = v; super.setValue(v); } public void setIValue(int v) { super.setValue(v); } public void setDValue(double v) { doubleValue = Math.max(getMinimum(),Math.min(getMaximum(),v)); setIValue((int) v); } public double getDValue() { return doubleValue;} } double computeAngle( double x, double y ) { double angle=Math.atan(y/x); if (x==0) //There is probably a better way of hangling boundary conditions, but whatever if(y>0) angle=Math.PI/2; else angle=-Math.PI/2; if (x<0) angle+=Math.PI; return angle; } class RotateLens extends TGAbstractLens { protected void applyLens(TGPoint2D p) { double currentAngle=computeAngle(p.x,p.y); double dist=Math.sqrt((p.x*p.x)+(p.y*p.y)); p.x=dist*Math.cos(currentAngle+rotateAngle); p.y=dist*Math.sin(currentAngle+rotateAngle); } protected void undoLens(TGPoint2D p) { double currentAngle=computeAngle(p.x,p.y); double dist=Math.sqrt((p.x*p.x)+(p.y*p.y)); p.x=dist*Math.cos(currentAngle-rotateAngle); p.y=dist*Math.sin(currentAngle-rotateAngle); } } public void incrementRotateAngle(double inc) { rotateAngle+=inc; if (rotateAngle>Math.PI) rotateAngle-=Math.PI*2; if (rotateAngle<-Math.PI) rotateAngle+=Math.PI*2; adjustmentIsInternal=true; rotateSB.setDValue(rotateAngle*100); adjustmentIsInternal=false; } class RotateDragUI extends TGAbstractDragUI { // Will work best if rotate lens is top lens RotateDragUI() { super(RotateScroll.this.tgPanel); } double lastAngle; double getMouseAngle(double x, double y) { return computeAngle(x-this.tgPanel.getDrawCenter().x, y-this.tgPanel.getDrawCenter().y); } public void preActivate() {} public void preDeactivate() {} public void mousePressed( MouseEvent e ) { lastAngle = getMouseAngle(e.getX(), e.getY()); } public void mouseReleased( MouseEvent e ) {} public void mouseDragged( MouseEvent e ) { double currentAngle = getMouseAngle(e.getX(), e.getY()); incrementRotateAngle(currentAngle-lastAngle); lastAngle=currentAngle; this.tgPanel.repaintAfterMove(); } } } // end com.touchgraph.graphlayout.interaction.RotateScroll TGGraphLayout/com/touchgraph/graphlayout/interaction/LocalityScroll.java0000644000175000017500000001074707561561336030713 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import com.touchgraph.graphlayout.graphelements.*; import java.awt.event.*; import java.awt.*; //import javax.swing.*; /** LocalityScroll. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: LocalityScroll.java,v 1.2 2002/09/23 18:45:48 ldornbusch Exp $ */ public class LocalityScroll implements GraphListener { private Scrollbar localitySB; private TGPanel tgPanel; public LocalityScroll(TGPanel tgp) { tgPanel=tgp; localitySB = new Scrollbar(Scrollbar.HORIZONTAL, 1, 1, 0, 7); localitySB.setBlockIncrement(1); localitySB.setUnitIncrement(1); localitySB.addAdjustmentListener(new localityAdjustmentListener()); tgPanel.addGraphListener(this); } public Scrollbar getLocalitySB() { return localitySB; } public int getLocalityRadius() { int locVal = localitySB.getValue(); if(locVal>=6) return LocalityUtils.INFINITE_LOCALITY_RADIUS; else return locVal; } public void setLocalityRadius(int radius) { if (radius <= 0 ) localitySB.setValue(0); else if (radius <= 5) //and > 0 localitySB.setValue(radius); else // radius > 5 localitySB.setValue(6); } public void graphMoved() {} //From GraphListener interface public void graphReset() { localitySB.setValue(1); } //From GraphListener interface private class localityAdjustmentListener implements AdjustmentListener { public void adjustmentValueChanged(AdjustmentEvent e) { Node select = tgPanel.getSelect(); if (select!=null || getLocalityRadius() == LocalityUtils.INFINITE_LOCALITY_RADIUS) try { tgPanel.setLocale(select, getLocalityRadius()); } catch (TGException ex) { System.out.println("Error setting locale"); ex.printStackTrace(); } } } } // end com.touchgraph.graphlayout.interaction.LocalityScroll TGGraphLayout/com/touchgraph/graphlayout/interaction/HyperScroll.java0000644000175000017500000001606407561561336030220 0ustar starswifterstarswifter/* * TouchGraph Software License * * * Copyright (c) 2001 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The name "TouchGraph" must not be used to endorse or promote * products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of TouchGraph. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ===================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import java.awt.event.*; import java.awt.*; //import javax.swing.*; /** HyperScroll. Responsible for producing that neat hyperbolic effect. * (Which isn't really hyperbolic, but just non-linear). * Demonstrates the usefulness of Lenses. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id$ */ public class HyperScroll implements GraphListener { private Scrollbar hyperSB; private TGPanel tgPanel; HyperLens hyperLens; double inverseArray[]=new double[200]; //Helps calculate the inverse of the Hyperbolic function double width; //Initially was intended to change the function of the lens depending on screen size, //but now functions as a constant. public HyperScroll(TGPanel tgp) { tgPanel=tgp; hyperSB = new Scrollbar(Scrollbar.HORIZONTAL, 100, 8, 0, 108); hyperSB.addAdjustmentListener(new hyperAdjustmentListener()); hyperLens = new HyperLens(); width= 2000;//tgPanel.getSize().width/2; updateInverseArray(); tgPanel.addGraphListener(this); } public Scrollbar getHyperSB() { return hyperSB; } public HyperLens getLens() { return hyperLens; } public void graphMoved() {} //From GraphListener interface public void graphReset() { hyperSB.setValue(0); } //From GraphListener interface private class hyperAdjustmentListener implements AdjustmentListener { public void adjustmentValueChanged(AdjustmentEvent e) { updateInverseArray(); tgPanel.repaintAfterMove(); } } double rawHyperDist (double dist) { //The hyperbolic transform if(hyperSB.getValue()==0) return dist; double hyperV=hyperSB.getValue(); return Math.log(dist/(Math.pow(1.5,(70-hyperV)/40)*80) +1); /* double hyperD = Math.sqrt(dist+(10.1-Math.sqrt(hyperV)))-Math.sqrt(10.1-Math.sqrt(hyperV)); */ } double hyperDist (double dist) { double hyperV=hyperSB.getValue(); //Points that are 250 away from the center stay fixed. double hyperD= rawHyperDist(dist)/rawHyperDist(250)*250; double fade=hyperV; double fadeAdjust=100; hyperD=hyperD*fade/fadeAdjust+dist*(fadeAdjust-fade)/fadeAdjust; return hyperD; } void updateInverseArray(){ double x; for(int i=0;i<200;i++) { x=width*i/200; //Points within a radius of 'width' will have exact inverses. inverseArray[i]=hyperDist(x); } }; int findInd(int min, int max, double dist) { int mid=(min+max)/2; if (inverseArray[mid]0) { p.x=p.x/dist*hyperDist(dist); p.y=p.y/dist*hyperDist(dist); } else { p.x =0; p.y=0;} } protected void undoLens(TGPoint2D p) { double dist=Math.sqrt(p.x*p.x+p.y*p.y); if(dist>0) { p.x=p.x/dist*invHyperDist(dist); p.y=p.y/dist*invHyperDist(dist); } else { p.x =0; p.y=0;} } } //Things can't get much more complex then this, if you don't use an inverse function /* class HyperLens extends TGAbstractLens { protected void applyLens(TGPoint2D p) { if(p.x!=0) p.x=p.x/Math.sqrt(Math.abs(p.x))*Math.sqrt(tgPanel.getSize().width/2); if(p.y!=0) p.y=p.y/Math.sqrt(Math.abs(p.y))*Math.sqrt(tgPanel.getSize().height/2); } protected void undoLens(TGPoint2D p) { p.x=(p.x/Math.sqrt(tgPanel.getSize().width/2)); p.x=p.x*Math.abs(p.x); p.y=(p.y/Math.sqrt(tgPanel.getSize().height/2)); p.y=p.y*Math.abs(p.y); } } */ } // end com.touchgraph.graphlayout.interaction.HyperScroll TGGraphLayout/com/touchgraph/graphlayout/interaction/HVScroll.java0000644000175000017500000003474207561561336027451 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import java.awt.event.*; import java.awt.*; //import javax.swing.*; /** HVScroll: Allows for scrolling horizontaly+vertically. This can be * done in all sorts of ways, for instance by using the scrollbars, or by * dragging. * *

* This code is more complex then it would seem it should be, because scrolling * has to be independent of the screen being warped by lenses. HVScroll needs * to use the tgLensSet object because the offset is recorded in real coordinates, while * the user interacts with the drawn coordinates. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: HVScroll.java,v 1.1 2002/09/19 15:58:21 ldornbusch Exp $ */ public class HVScroll implements GraphListener { private DScrollbar horizontalSB; private DScrollbar verticalSB; HVLens hvLens; HVDragUI hvDragUI; HVScrollToCenterUI hvScrollToCenterUI; public boolean scrolling; private boolean adjustmentIsInternal; private TGPanel tgPanel; private TGLensSet tgLensSet; TGPoint2D offset; // ............ /** Constructor with a TGPanel tgp and TGLensSet tgls. */ public HVScroll(TGPanel tgp, TGLensSet tgls) { tgPanel=tgp; tgLensSet=tgls; offset=new TGPoint2D(0,0); scrolling = false; adjustmentIsInternal = false; horizontalSB = new DScrollbar(Scrollbar.HORIZONTAL, 0, 100, -1000, 1100); horizontalSB.setBlockIncrement(100); horizontalSB.setUnitIncrement(20); horizontalSB.addAdjustmentListener(new horizAdjustmentListener()); verticalSB = new DScrollbar(Scrollbar.VERTICAL, 0, 100, -1000, 1100); verticalSB.setBlockIncrement(100); verticalSB.setUnitIncrement(20); verticalSB.addAdjustmentListener(new vertAdjustmentListener()); hvLens=new HVLens(); hvDragUI = new HVDragUI(); //Hopefully this approach won't eat too much memory hvScrollToCenterUI = new HVScrollToCenterUI(); tgPanel.addGraphListener(this); } public Scrollbar getHorizontalSB() { return horizontalSB; } public Scrollbar getVerticalSB() { return verticalSB; } public HVDragUI getHVDragUI() { return hvDragUI; } public HVLens getLens() { return hvLens; } public TGAbstractClickUI getHVScrollToCenterUI() { return hvScrollToCenterUI; } public TGPoint2D getTopLeftDraw() { TGPoint2D tld = tgPanel.getTopLeftDraw(); tld.setLocation(tld.x-tgPanel.getSize().width/4,tld.y-tgPanel.getSize().height/4); return tld; } public TGPoint2D getBottomRightDraw() { TGPoint2D brd = tgPanel.getBottomRightDraw(); brd.setLocation(brd.x+tgPanel.getSize().width/4,brd.y+tgPanel.getSize().height/4); return brd; } public TGPoint2D getDrawCenter() { //Should probably be called from tgPanel return new TGPoint2D(tgPanel.getSize().width/2,tgPanel.getSize().height/2); } Thread noRepaintThread; public void graphMoved() { //From GraphListener interface if (tgPanel.getDragNode()==null && tgPanel.getSize().height>0) { TGPoint2D drawCenter = getDrawCenter(); TGPoint2D tld = getTopLeftDraw(); TGPoint2D brd = getBottomRightDraw(); double newH = (-(tld.x-drawCenter.x)/(brd.x-tld.x)*2000-1000); double newV = (-(tld.y-drawCenter.y)/(brd.y-tld.y)*2000-1000); boolean beyondBorder; beyondBorder = true; if(newHhorizontalSB.getMinimum() && newVverticalSB.getMinimum() ) beyondBorder=false; adjustmentIsInternal = true; horizontalSB.setDValue(newH); verticalSB.setDValue(newV); adjustmentIsInternal = false; if (beyondBorder) { adjustHOffset(); adjustVOffset(); tgPanel.repaint(); } } if (noRepaintThread!=null && noRepaintThread.isAlive()) noRepaintThread.interrupt(); noRepaintThread = new Thread() { public void run() { try { Thread.currentThread().sleep(40); //Wait 40 milliseconds before repainting } catch (InterruptedException ex) {} } }; noRepaintThread.start(); } public void graphReset() { //From GraphListener interface horizontalSB.setDValue(0); verticalSB.setDValue(0); adjustHOffset(); adjustVOffset(); } class DScrollbar extends Scrollbar { private double doubleValue; DScrollbar(int orient, int val, int vis, int min, int max){ super(orient, val, vis, min, max); doubleValue=val; } public void setValue(int v) { doubleValue = v; super.setValue(v); } public void setIValue(int v) { super.setValue(v); } public void setDValue(double v) { doubleValue = Math.max(getMinimum(),Math.min(getMaximum(),v)); setIValue((int) v); } public double getDValue() { return doubleValue;} } private void adjustHOffset() { //The inverse of the "graphMoved" function. //System.out.println(horizontalSB.getDValue()); for(int iterate=0;iterate<3;iterate++) { // Iteration needed to yeild cerrect results depite warping lenses TGPoint2D center= tgPanel.getCenter(); TGPoint2D tld = getTopLeftDraw(); TGPoint2D brd = getBottomRightDraw(); double newx = ((horizontalSB.getDValue()+1000.0)/2000)*(brd.x-tld.x)+tld.x; double newy = tgPanel.getSize().height/2; TGPoint2D newCenter = tgLensSet.convDrawToReal(newx,newy); offset.setX(offset.x+(newCenter.x-center.x)); offset.setY(offset.y+(newCenter.y-center.y)); tgPanel.processGraphMove(); } } private void adjustVOffset() { //The inverse of the "graphMoved" function. for(int iterate=0;iterate<10;iterate++) { // Iteration needed to yeild cerrect results depite warping lenses TGPoint2D center= tgPanel.getCenter(); TGPoint2D tld = getTopLeftDraw(); TGPoint2D brd = getBottomRightDraw(); double newx = tgPanel.getSize().width/2; double newy = ((verticalSB.getDValue()+1000.0)/2000)*(brd.y-tld.y)+tld.y; TGPoint2D newCenter = tgLensSet.convDrawToReal(newx,newy); offset.setX(offset.x+(newCenter.x-center.x)); offset.setY(offset.y+(newCenter.y-center.y)); tgPanel.processGraphMove(); } } private class horizAdjustmentListener implements AdjustmentListener { public void adjustmentValueChanged(AdjustmentEvent e) { if(!adjustmentIsInternal) { adjustHOffset(); tgPanel.repaintAfterMove(); } } } private class vertAdjustmentListener implements AdjustmentListener { public void adjustmentValueChanged(AdjustmentEvent e) { if(!adjustmentIsInternal) { adjustVOffset(); tgPanel.repaintAfterMove(); } } } class HVLens extends TGAbstractLens { protected void applyLens(TGPoint2D p) { p.x=p.x-offset.x; p.y=p.y-offset.y; } protected void undoLens(TGPoint2D p) { p.x=p.x+offset.x; p.y=p.y+offset.y; } } public void setOffset(Point p) { offset.setLocation(p.x,p.y); tgPanel.processGraphMove(); //Adjust draw coordinates to include new offset graphMoved(); //adjusts scrollbars to fit draw coordinates } public Point getOffset() { return new Point((int) offset.x,(int) offset.y); } public void scrollAtoB(TGPoint2D drawFrom, TGPoint2D drawTo) { TGPoint2D from = tgLensSet.convDrawToReal(drawFrom); TGPoint2D to = tgLensSet.convDrawToReal(drawTo); offset.setX(offset.x+(from.x-to.x)); offset.setY(offset.y+(from.y-to.y)); } Thread scrollThread; public void slowScrollToCenter(final Node n) { final TGPoint2D drawFrom =new TGPoint2D(n.drawx,n.drawy); final TGPoint2D drawTo = getDrawCenter(); scrolling = true; if (scrollThread!=null && scrollThread.isAlive()) scrollThread.interrupt(); scrollThread = new Thread() { public void run() { double nx=-999; double ny=-999; double cx; double cy; double distFromCenter; boolean keepScrolling = true; int stopScrollingAttempt = 0; int scrollSteps=0; while(keepScrolling && scrollSteps++<250) { nx= n.drawx; ny= n.drawy; cx= getDrawCenter().x; cy= getDrawCenter().y; distFromCenter = Math.sqrt((nx-cx)*(nx-cx)+(ny-cy)*(ny-cy)); double newx, newy; if(distFromCenter>5) { newx = cx + (nx-cx)*((distFromCenter-5)/distFromCenter); newy = cy + (ny-cy)*((distFromCenter-5)/distFromCenter); } else { newx = cx; newy = cy; } scrollAtoB(new TGPoint2D(nx,ny), new TGPoint2D(newx,newy)); if (noRepaintThread==null || !noRepaintThread.isAlive()) { tgPanel.repaintAfterMove(); //only repaint if 40 milliseconds have not ellapsed since last repaint } else { tgPanel.processGraphMove(); //otherwise, register scroll internally } try { Thread.currentThread().sleep(20); } catch (InterruptedException ex) { keepScrolling=false; } if(distFromCenter<3) { try { Thread.currentThread().sleep(200); //Wait a little to make sure } catch (InterruptedException ex) { keepScrolling=false; } nx= n.drawx; ny= n.drawy; cx= getDrawCenter().x; cy= getDrawCenter().y; distFromCenter = Math.sqrt((nx-cx)*(nx-cx)+(ny-cy)*(ny-cy)); if (distFromCenter<3) keepScrolling=false; } } scrollAtoB(new TGPoint2D(n.drawx,n.drawy),getDrawCenter()); //for good measure tgPanel.repaintAfterMove(); HVScroll.this.scrolling = false; } }; scrollThread.start(); } class HVScrollToCenterUI extends TGAbstractClickUI { public void mouseClicked(MouseEvent e) { /* Node mouseOverN=tgPanel.getMouseOverN(); if(!scrolling && mouseOverN!=null) slowScrollToCenter(mouseOverN); */ } } class HVDragUI extends TGAbstractDragUI{ TGPoint2D lastMousePos; HVDragUI() { super(HVScroll.this.tgPanel); } public void preActivate() {} public void preDeactivate() {} public void mousePressed(MouseEvent e) { lastMousePos = new TGPoint2D(e.getX(), e.getY()); } public void mouseReleased(MouseEvent e) {} public void mouseDragged(MouseEvent e) { if(!scrolling) scrollAtoB(lastMousePos, new TGPoint2D(e.getX(), e.getY())); lastMousePos.setLocation(e.getX(),e.getY()); this.tgPanel.repaintAfterMove(); } } } // end com.touchgraph.graphlayout.interaction.HVScroll TGGraphLayout/com/touchgraph/graphlayout/interaction/HVRotateDragUI.java0000644000175000017500000001723607523455410030475 0ustar starswifterstarswifter/* * TouchGraph Software License * * * Copyright (c) 2001 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The name "TouchGraph" must not be used to endorse or promote * products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of TouchGraph. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ===================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import java.awt.*; import java.awt.event.*; /** HVRotateDragUI. A combination of HVScrolling + rotating. * The graph is rotated, but the mouse is always kept on the same point * on the graph. * * @author Alexander Shapiro * @version 1.06 */ public class HVRotateDragUI extends TGAbstractDragUI implements TGPaintListener { HVScroll hvScroll; RotateScroll rotateScroll; Node mouseOverN; Node tempNode; TGPoint2D lastMousePos; double lastAngle; // ............ /** Constructor with TGPanel tgp, HVScroll hvs * and a RotateScroll rs. */ public HVRotateDragUI( TGPanel tgp, HVScroll hvs, RotateScroll rs ) { super(tgp); hvScroll = hvs; rotateScroll = rs; } double graphDist(double x, double y) { double adjx=(x-this.tgPanel.getDrawCenter().x); double adjy=(y-this.tgPanel.getDrawCenter().y); return Math.sqrt(adjx*adjx+adjy*adjy); } double getMouseAngle(double x, double y) { double adjx=(x-this.tgPanel.getDrawCenter().x); double adjy=(y-this.tgPanel.getDrawCenter().y); double ang = Math.atan(adjy/adjx); if (adjx==0) if(adjy>0) ang=Math.PI/2; else ang=-Math.PI/2; if(adjx<0) ang=ang+Math.PI; return ang; } public void preActivate() { tgPanel.addPaintListener(this); } public void preDeactivate() { tgPanel.removePaintListener(this); tgPanel.repaint(); } public void mousePressed(MouseEvent e) { mouseOverN=tgPanel.getMouseOverN(); if (mouseOverN!=null) { lastMousePos = new TGPoint2D(mouseOverN.drawx, mouseOverN.drawy); lastAngle = getMouseAngle(mouseOverN.drawx, mouseOverN.drawy); } else { tempNode=new Node(); //A hack, until lenses are better implemented //One should keep track of a real position on the graph //As opposed to having a temporary node do this task. tempNode.drawx = e.getX(); tempNode.drawy = e.getY(); tgPanel.updatePosFromDraw(tempNode); lastMousePos = new TGPoint2D(tempNode.drawx, tempNode.drawy); lastAngle = getMouseAngle(tempNode.drawx, tempNode.drawy); } } public void mouseReleased( MouseEvent e ) {} public void mouseDragged( MouseEvent e ) { double currX = e.getX(); double currY = e.getY(); double currDist = graphDist(currX,currY); if (mouseOverN!=null) lastAngle = getMouseAngle(mouseOverN.drawx, mouseOverN.drawy); else lastAngle = getMouseAngle(tempNode.drawx, tempNode.drawy); double currentAngle = getMouseAngle(currX, currY); if(lastAngle>currentAngle+Math.PI) currentAngle+=Math.PI*2; //Avoids bug at x==0 else if(currentAngle>lastAngle+Math.PI) lastAngle+=Math.PI*2; if (currDist>60) rotateScroll.incrementRotateAngle((currentAngle-lastAngle)); tgPanel.updateDrawPositions(); //Rotate, but don't redraw tgPanel.updateGraphSize(); //Just in case. Mostly effects H+V Scrollbars if(tempNode!=null) tgPanel.updateDrawPos(tempNode); //The temporary node is not part of the graph, //So it needs to be updated individually TGPoint2D lastMousePos; if(mouseOverN!=null) lastMousePos = new TGPoint2D(mouseOverN.drawx, mouseOverN.drawy); else lastMousePos = new TGPoint2D(tempNode.drawx, tempNode.drawy); TGPoint2D newPos = new TGPoint2D(currX,currY); if (!hvScroll.scrolling) hvScroll.scrollAtoB(lastMousePos, newPos); //Scroll the node to the mouse this.tgPanel.repaintAfterMove(); if(tempNode!=null) tgPanel.updateDrawPos(tempNode); //The temporary node is not part of the graph, //So it needs to be updated individually } public void paintFirst( Graphics g ) { TGPoint2D drawCenter = tgPanel.getDrawCenter(); g.setColor(Color.lightGray); for(int i=0;i<16;i++) { double ang = Math.PI*2*i/16; double rayX = 1000*Math.cos(ang); double rayY = 1000*Math.sin(ang); g.drawLine((int) drawCenter.x, (int) drawCenter.y, (int) (rayX+drawCenter.x),(int) (rayY+drawCenter.y)); g.drawLine((int) drawCenter.x+1, (int) drawCenter.y, (int) (rayX+drawCenter.x+1),(int) (rayY+drawCenter.y)); g.drawLine((int) drawCenter.x, (int) drawCenter.y+1, (int) (rayX+drawCenter.x),(int) (rayY+drawCenter.y+1)); g.drawLine((int) drawCenter.x+1, (int) drawCenter.y+1, (int) (rayX+drawCenter.x+1),(int) (rayY+drawCenter.y+1)); } g.fillOval((int)drawCenter.x-60, (int) drawCenter.y-60, 120,120); g.setColor(tgPanel.BACK_COLOR); g.fillOval((int)drawCenter.x-58, (int) drawCenter.y-58, 116,116); } public void paintLast( Graphics g ) {} public void paintAfterEdges( Graphics g ) {} } // end com.touchgraph.graphlayout.interaction.HVRotateDragUI TGGraphLayout/com/touchgraph/graphlayout/interaction/GLNavigateUI.java0000644000175000017500000002454307561561336030172 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import java.awt.event.*; import java.awt.*; //import javax.swing.*; //import javax.swing.event.*; /** GLNavigateUI. User interface for moving around the graph, as opposed * to editing. * * @author Alexander Shapiro * @author Murray Altheim (abstracted GLPanel to TGScrollPane interface) * @version 1.22-jre1.1 $Id: GLNavigateUI.java,v 1.1 2002/09/19 15:58:21 ldornbusch Exp $ */ public class GLNavigateUI extends TGUserInterface { GLPanel glPanel; TGPanel tgPanel; GLNavigateMouseListener ml; TGAbstractDragUI hvDragUI; TGAbstractDragUI rotateDragUI; //TGAbstractDragUI hvRotateDragUI; DragNodeUI dragNodeUI; LocalityScroll localityScroll; PopupMenu nodePopup; PopupMenu edgePopup; Node popupNode; Edge popupEdge; public GLNavigateUI( GLPanel glp ) { glPanel = glp; tgPanel = glPanel.getTGPanel(); localityScroll = glPanel.getLocalityScroll(); hvDragUI = glPanel.getHVScroll().getHVDragUI(); rotateDragUI = glPanel.getRotateScroll().getRotateDragUI(); //hvRotateDragUI = new HVRotateDragUI(tgPanel, // glPanel.getHVScroll(), glPanel.getRotateScroll()); dragNodeUI = new DragNodeUI(tgPanel); ml = new GLNavigateMouseListener(); setUpNodePopup(glp); setUpEdgePopup(glp); } public void activate() { tgPanel.addMouseListener(ml); } public void deactivate() { tgPanel.removeMouseListener(ml); } class GLNavigateMouseListener extends MouseAdapter { public void mousePressed(MouseEvent e) { Node mouseOverN = tgPanel.getMouseOverN(); if (e.getModifiers() == MouseEvent.BUTTON1_MASK) { if (mouseOverN == null) hvDragUI.activate(e); else dragNodeUI.activate(e); } } public void mouseClicked(MouseEvent e) { Node mouseOverN = tgPanel.getMouseOverN(); if (e.getModifiers() == MouseEvent.BUTTON1_MASK) { if ( mouseOverN != null) { tgPanel.setSelect(mouseOverN); glPanel.getHVScroll().slowScrollToCenter(mouseOverN); try { tgPanel.setLocale(mouseOverN, localityScroll.getLocalityRadius()); } catch (TGException ex) { System.out.println("Error setting locale"); ex.printStackTrace(); } } } } public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) { popupNode = tgPanel.getMouseOverN(); popupEdge = tgPanel.getMouseOverE(); if (popupNode!=null) { tgPanel.setMaintainMouseOver(true); // nodePopup.show(e.getComponent(), e.getX(), e.getY()); nodePopup.show(tgPanel, e.getX(), e.getY()); } else if (popupEdge!=null) { tgPanel.setMaintainMouseOver(true); // edgePopup.show(e.getComponent(), e.getX(), e.getY()); edgePopup.show(tgPanel, e.getX(), e.getY()); } else { // glPanel.glPopup.show(e.getComponent(), e.getX(), e.getY()); glPanel.glPopup.show(tgPanel, e.getX(), e.getY()); } } else tgPanel.setMaintainMouseOver(false); } } private void setUpNodePopup( GLPanel glp) { nodePopup = new PopupMenu(); glp.add(nodePopup); MenuItem menuItem; menuItem = new MenuItem("Expand Node"); ActionListener expandAction = new ActionListener() { public void actionPerformed(ActionEvent e) { if(popupNode!=null) { tgPanel.expandNode(popupNode); } // JDK11 Change .. because of MenuBecomesInvisible tgPanel.setMaintainMouseOver(false); tgPanel.setMouseOverN(null); tgPanel.repaint(); // JDK11 Change .. because of MenuBecomesInvisible } }; menuItem.addActionListener(expandAction); nodePopup.add(menuItem); menuItem = new MenuItem("Collapse Node"); ActionListener collapseAction = new ActionListener() { public void actionPerformed(ActionEvent e) { if(popupNode!=null) { tgPanel.collapseNode(popupNode ); } // JDK11 Change .. because of MenuBecomesInvisible tgPanel.setMaintainMouseOver(false); tgPanel.setMouseOverN(null); tgPanel.repaint(); // JDK11 Change .. because of MenuBecomesInvisible } }; menuItem.addActionListener(collapseAction); nodePopup.add(menuItem); menuItem = new MenuItem("Hide Node"); ActionListener hideAction = new ActionListener() { public void actionPerformed(ActionEvent e) { if(popupNode!=null) { tgPanel.hideNode(popupNode ); } // JDK11 Change .. because of MenuBecomesInvisible tgPanel.setMaintainMouseOver(false); tgPanel.setMouseOverN(null); tgPanel.repaint(); // JDK11 Change .. because of MenuBecomesInvisible } }; menuItem.addActionListener(hideAction); nodePopup.add(menuItem); menuItem = new MenuItem("Center Node"); ActionListener centerAction = new ActionListener() { public void actionPerformed(ActionEvent e) { if(popupNode!=null) { glPanel.getHVScroll().slowScrollToCenter(popupNode); } // JDK11 Change .. because of MenuBecomesInvisible tgPanel.setMaintainMouseOver(false); tgPanel.setMouseOverN(null); tgPanel.repaint(); // JDK11 Change .. because of MenuBecomesInvisible } }; menuItem.addActionListener(centerAction); nodePopup.add(menuItem); /* nodePopup.addPopupMenuListener(new PopupMenuListener() { public void popupMenuCanceled(PopupMenuEvent e) {} public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { tgPanel.setMaintainMouseOver(false); tgPanel.setMouseOverN(null); tgPanel.repaint(); } public void popupMenuWillBecomeVisible(PopupMenuEvent e) {} });*/ } private void setUpEdgePopup( GLPanel glp) { edgePopup = new PopupMenu(); glp.add(edgePopup); MenuItem menuItem; menuItem = new MenuItem("Hide Edge"); ActionListener hideAction = new ActionListener() { public void actionPerformed(ActionEvent e) { if(popupEdge!=null) { tgPanel.hideEdge(popupEdge); } // JDK11 Change .. because of MenuBecomesInvisible tgPanel.setMaintainMouseOver(false); tgPanel.setMouseOverN(null); tgPanel.repaint(); // JDK11 Change .. because of MenuBecomesInvisible } }; menuItem.addActionListener(hideAction); edgePopup.add(menuItem); /* edgePopup.addPopupMenuListener(new PopupMenuListener() { public void popupMenuCanceled(PopupMenuEvent e) {} public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { tgPanel.setMaintainMouseOver(false); tgPanel.setMouseOverE(null); tgPanel.repaint(); } public void popupMenuWillBecomeVisible(PopupMenuEvent e) {} });*/ } } // end com.touchgraph.graphlayout.interaction.GLNavigateUI TGGraphLayout/com/touchgraph/graphlayout/interaction/GLEditUI.java0000644000175000017500000003156707561561334027323 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; //import javax.swing.*; //import javax.swing.event.*; import java.awt.*; import java.awt.event.*; import java.applet.*; import java.io.*; import java.util.*; /** GLEditUI: User Interface for editing the graph. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: GLEditUI.java,v 1.1 2002/09/19 15:58:21 ldornbusch Exp $ */ public class GLEditUI extends TGUserInterface { /** True when the current UI is active. */ TGPanel tgPanel; DragAddUI dragAddUI; DragNodeUI dragNodeUI; DragMultiselectUI dragMultiselectUI; TGAbstractClickUI switchSelectUI; TGAbstractDragUI hvDragUI; GLEditMouseListener ml; GLEditMouseMotionListener mml; PopupMenu nodePopup; PopupMenu edgePopup; PopupMenu backPopup; Node popupNode; Edge popupEdge; // AbstractAction deleteSelectAction; // final KeyStroke deleteKey = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0); // ............ /** Constructor with TGPanel tgp. */ public GLEditUI( TGPanel tgp ) { active = false; tgPanel = tgp; ml = new GLEditMouseListener(); mml = new GLEditMouseMotionListener(); /* deleteSelectAction = new AbstractAction("DeleteSelect") { public void actionPerformed(ActionEvent e) { Node select = tgPanel.getSelect(); if(select!=null) { tgPanel.deleteNode(select); tgPanel.repaint(); } } }; */ dragAddUI = new DragAddUI(tgPanel); dragNodeUI = new DragNodeUI(tgPanel); dragMultiselectUI = new DragMultiselectUI(tgPanel); switchSelectUI = tgPanel.getSwitchSelectUI(); setUpNodePopup(tgp); setUpEdgePopup(tgp); setUpBackPopup(tgp); } public GLEditUI( GLPanel glPanel ) { this(glPanel.getTGPanel()); hvDragUI = glPanel.hvScroll.getHVDragUI(); } public void activate() { tgPanel.addMouseListener(ml); tgPanel.addMouseMotionListener(mml); // tgPanel.getActionMap().put("DeleteSelect", deleteSelectAction); // ComponentInputMap cim = new ComponentInputMap(tgPanel); // cim.put(deleteKey, "DeleteSelect"); // tgPanel.setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, cim); active = true; } public void deactivate() { //A hack. Want to prevent dragMultiselect from remaining active when user switches to //navigate mode. Keeping an "active" variable resolves some comlex issues with the flow //of controll, caused by dragMultiselect calling it's parents deactivate method when it //is activated. if (!active) dragMultiselectUI.deactivate(); tgPanel.removeMouseListener(ml); tgPanel.removeMouseMotionListener(mml); // tgPanel.getInputMap().put(deleteKey, null); // tgPanel.getActionMap().put("DeleteSelect", null); active = false; } class GLEditMouseListener extends MouseAdapter { public void mousePressed(MouseEvent e) { Node mouseOverN = tgPanel.getMouseOverN(); Node select = tgPanel.getSelect(); if (e.getModifiers() == MouseEvent.BUTTON1_MASK) { if (mouseOverN != null) { if(mouseOverN!=select) dragNodeUI.activate(e); else dragAddUI.activate(e); } else if(hvDragUI!=null) hvDragUI.activate(e); } } public void mouseClicked(MouseEvent e) { if (e.getModifiers() == MouseEvent.BUTTON1_MASK) switchSelectUI.activate(e); } public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) { popupNode = tgPanel.getMouseOverN(); popupEdge = tgPanel.getMouseOverE(); if (popupNode!=null) { tgPanel.setMaintainMouseOver(true); nodePopup.show(e.getComponent(), e.getX(), e.getY()); } else if (popupEdge!=null) { tgPanel.setMaintainMouseOver(true); edgePopup.show(e.getComponent(), e.getX(), e.getY()); } else { backPopup.show(e.getComponent(), e.getX(), e.getY()); } } } } class GLEditMouseMotionListener extends MouseMotionAdapter { public void mouseMoved(MouseEvent e) { //tgPanel.startDamper(); } } private void setUpNodePopup( TGPanel tgp ) { nodePopup = new PopupMenu(); // For JDK1.1 Compatibility... tgp.add(nodePopup); MenuItem menuItem; Menu navigateMenu = new Menu("Navigate"); menuItem = new MenuItem("Delete Node"); ActionListener deleteNodeAction = new ActionListener() { public void actionPerformed(ActionEvent e) { if(popupNode!=null) { tgPanel.deleteNode(popupNode); } } }; menuItem.addActionListener(deleteNodeAction); nodePopup.add(menuItem); menuItem = new MenuItem("Expand Node"); ActionListener expandAction = new ActionListener() { public void actionPerformed(ActionEvent e) { if(popupNode!=null) { tgPanel.expandNode(popupNode); } } }; menuItem.addActionListener(expandAction); navigateMenu.add(menuItem); menuItem = new MenuItem("Collapse Node"); ActionListener collapseAction = new ActionListener() { public void actionPerformed(ActionEvent e) { if(popupNode!=null) { tgPanel.collapseNode(popupNode ); } } }; menuItem.addActionListener(collapseAction); navigateMenu.add(menuItem); menuItem = new MenuItem("Hide Node"); ActionListener hideAction = new ActionListener() { public void actionPerformed(ActionEvent e) { Node select = tgPanel.getSelect(); if(popupNode!=null) { tgPanel.hideNode(popupNode); } } }; menuItem.addActionListener(hideAction); navigateMenu.add(menuItem); nodePopup.add(navigateMenu); /* nodePopup.addPopupMenuListener(new PopupMenuListener() { public void popupMenuCanceled(PopupMenuEvent e) {} public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { tgPanel.setMaintainMouseOver(false); tgPanel.setMouseOverN(null); tgPanel.repaint(); } public void popupMenuWillBecomeVisible(PopupMenuEvent e) {} }); */ } private void setUpEdgePopup( TGPanel tgp ) { edgePopup = new PopupMenu(); // JDK1.1 Compatibility tgp.add(edgePopup); MenuItem menuItem; menuItem = new MenuItem("Relax Edge"); ActionListener relaxEdgeAction = new ActionListener() { public void actionPerformed(ActionEvent e) { if(popupEdge!=null) { popupEdge.setLength(popupEdge.getLength()*4); tgPanel.resetDamper(); } } }; menuItem.addActionListener(relaxEdgeAction); edgePopup.add(menuItem); menuItem = new MenuItem("Tighten Edge"); ActionListener tightenEdgeAction = new ActionListener() { public void actionPerformed(ActionEvent e) { if(popupEdge!=null) { popupEdge.setLength(popupEdge.getLength()/4); tgPanel.resetDamper(); } } }; menuItem.addActionListener(tightenEdgeAction); edgePopup.add(menuItem); menuItem = new MenuItem("Delete Edge"); ActionListener deleteEdgeAction = new ActionListener() { public void actionPerformed(ActionEvent e) { if(popupEdge!=null) { tgPanel.deleteEdge(popupEdge); } } }; menuItem.addActionListener(deleteEdgeAction); edgePopup.add(menuItem); /* edgePopup.addPopupMenuListener(new PopupMenuListener() { public void popupMenuCanceled(PopupMenuEvent e) {} public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { tgPanel.setMaintainMouseOver(false); tgPanel.setMouseOverE(null); tgPanel.repaint(); } public void popupMenuWillBecomeVisible(PopupMenuEvent e) {} }); */ } private void setUpBackPopup( TGPanel tgp ) { backPopup = new PopupMenu(); // For JDK1.1 Compatibility... tgp.add(backPopup); MenuItem menuItem; menuItem = new MenuItem("Multi-Select"); ActionListener multiselectAction = new ActionListener() { public void actionPerformed(ActionEvent e) { dragMultiselectUI.activate(GLEditUI.this); } }; menuItem.addActionListener(multiselectAction); backPopup.add(menuItem); menuItem = new MenuItem("Start Over"); ActionListener startOverAction = new ActionListener() { public void actionPerformed( ActionEvent e ) { tgPanel.clearAll(); tgPanel.clearSelect(); try { tgPanel.addNode(); } catch ( TGException tge ) { System.err.println(tge.getMessage()); tge.printStackTrace(System.err); } tgPanel.fireResetEvent(); tgPanel.repaint(); } }; menuItem.addActionListener(startOverAction); backPopup.add(menuItem); } } // end com.touchgraph.graphlayout.interaction.GLEditUI TGGraphLayout/com/touchgraph/graphlayout/interaction/DragNodeUI.java0000644000175000017500000001121607561561334027663 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import java.awt.*; import java.applet.*; import java.awt.event.*; /** DragNodeUI contains code for dragging nodes. * *

* Parts of this code build upon Sun's Graph Layout example. * http://java.sun.com/applets/jdk/1.1/demo/GraphLayout/Graph.java *

* * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: DragNodeUI.java,v 1.2 2002/09/20 19:41:06 ldornbusch Exp $ */ public class DragNodeUI extends TGAbstractDragUI{ /** Stores the distance between the cursor and the center of the node * when dragging occurs so that the cursor remains at the same position * on the node otherwise, the cursor jumps to the center of the node. */ public Point dragOffs; // ............ /** Constructor with TGPanel tgp. */ public DragNodeUI( TGPanel tgp ) { super(tgp); } public void preActivate() { if (dragOffs ==null) dragOffs=new Point(0,0); } public void preDeactivate() {}; public void mousePressed( MouseEvent e ) { Node mouseOverN = tgPanel.getMouseOverN(); Point mousePos; if (e!=null) mousePos = e.getPoint(); //e can be null if the wrong activate() method was used else mousePos= new Point((int) mouseOverN.drawx,(int) mouseOverN.drawy); if ( mouseOverN != null) { //Should never be null if TGUIManager works properly tgPanel.setDragNode(mouseOverN); dragOffs.setLocation((int) (mouseOverN.drawx-mousePos.x), //For when you click to the side of (int)(mouseOverN.drawy-mousePos.y));//the node, but you still want to drag it } } public void mouseReleased( MouseEvent e ) { tgPanel.setDragNode(null); tgPanel.repaintAfterMove(); tgPanel.startDamper(); } public synchronized void mouseDragged( MouseEvent e ) { Node dragNode = tgPanel.getDragNode(); dragNode.drawx = e.getX()+dragOffs.x; dragNode.drawy = e.getY()+dragOffs.y; tgPanel.updatePosFromDraw(dragNode); tgPanel.repaintAfterMove(); tgPanel.stopDamper(); //Keep the graph alive while dragging. e.consume(); } } // end com.touchgraph.graphlayout.interaction.DragNodeUI TGGraphLayout/com/touchgraph/graphlayout/interaction/DragMultiselectUI.java0000644000175000017500000001152207561561334031270 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.interaction; import com.touchgraph.graphlayout.*; import java.awt.*; import java.applet.*; import java.awt.event.*; /** DragMultiselectUI contains code for selecting a group on nodes * by enclosing them in a dotted box. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: DragMultiselectUI.java,v 1.1 2002/09/19 15:58:21 ldornbusch Exp $ */ public class DragMultiselectUI extends TGAbstractDragUI implements TGPaintListener { TGPoint2D mousePos=null; TGPoint2D startPos = null; DragMultiselectUI( TGPanel tgp ) { super(tgp); } public void preActivate() { startPos = null; mousePos = null; tgPanel.addPaintListener(this); } public void preDeactivate() { tgPanel.removePaintListener(this); tgPanel.repaint(); }; public void mousePressed(MouseEvent e) { startPos = new TGPoint2D(e.getX(), e.getY()); mousePos = new TGPoint2D(startPos); } public void mouseReleased(MouseEvent e) {} public void mouseDragged(MouseEvent e) { mousePos.setLocation(e.getX(), e.getY()); tgPanel.multiSelect(startPos,mousePos); tgPanel.repaint(); } public void paintFirst(Graphics g) {}; public void paintAfterEdges(Graphics g) {}; public void paintLast(Graphics g) { if(mousePos==null) return; g.setColor(Color.black); int x,y,w,h; if (startPos.xtgp
. */ public DragAddUI( TGPanel tgp ) { super(tgp); } public void preActivate() { mousePos=null; tgPanel.addPaintListener(this); } public void preDeactivate() { tgPanel.removePaintListener(this); }; public void mousePressed( MouseEvent e ) { dragAddNode = tgPanel.getMouseOverN(); } public void mouseReleased( MouseEvent e ) { Node mouseOverN = tgPanel.getMouseOverN(); if (mouseOverN!=null && dragAddNode!=null && mouseOverN!=dragAddNode) { Edge ed=tgPanel.findEdge(dragAddNode,mouseOverN); if (ed==null) tgPanel.addEdge(dragAddNode,mouseOverN, Edge.DEFAULT_LENGTH); else tgPanel.deleteEdge(ed); } else if ( mouseOverN == null && dragAddNode != null ) { try { Node n =tgPanel.addNode(); tgPanel.addEdge(dragAddNode,n, Edge.DEFAULT_LENGTH); n.drawx = tgPanel.getMousePos().x; n.drawy = tgPanel.getMousePos().y; tgPanel.updatePosFromDraw(n); } catch ( TGException tge ) { System.err.println(tge.getMessage()); tge.printStackTrace(System.err); } } if (mouseWasDragged) { //Don't reset the damper on a mouseClicked tgPanel.resetDamper(); tgPanel.startDamper(); } dragAddNode=null; } public void mouseDragged(MouseEvent e) { mousePos=e.getPoint(); tgPanel.repaint(); } public void paintFirst(Graphics g) {}; public void paintLast(Graphics g) {}; public void paintAfterEdges(Graphics g) { if(mousePos==null) return; Node mouseOverN = tgPanel.getMouseOverN(); if (mouseOverN==null) { // g.setColor(Node.BACK_DEFAULT_COLOR); g.drawRect(mousePos.x-7, mousePos.y-7, 14, 14); } Color c; if (mouseOverN==dragAddNode) c = Color.darkGray; else c = Color.blue; Edge.paintArrow(g, (int) dragAddNode.drawx, (int) dragAddNode.drawy, mousePos.x, mousePos.y, c); } } // end com.touchgraph.graphlayout.interaction.DragAddUI TGGraphLayout/com/touchgraph/graphlayout/graphelements/VisibleLocality.java0000644000175000017500000001304607561561434031363 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.graphelements; import com.touchgraph.graphlayout.Node; import com.touchgraph.graphlayout.Edge; import com.touchgraph.graphlayout.TGException; import java.util.Vector; /** VisibleLocality: Extends Locality to spefically handle the * Nodes + Edges that are visible on screen. The visible attribute * of the nodes + edges is set to true when they appear on screen, and * false when they are removed from screen. * * Locality is used in conjunction with LocalityUtils, which handle * locality shift animations. * * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: VisibleLocality.java,v 1.1 2002/09/19 15:58:32 ldornbusch Exp $ */ public class VisibleLocality extends Locality { public VisibleLocality(GraphEltSet ges) { super(ges); } public synchronized void addNode( Node node ) throws TGException { super.addNode(node); node.setVisible(true); } public void addEdge( Edge edge ) { if(!contains(edge)) { super.addEdge(edge); edge.from.visibleEdgeCnt++; edge.to.visibleEdgeCnt++; } } public boolean removeEdge( Edge edge ) { boolean removed = super.removeEdge(edge); if (removed) { edge.setVisible(false); edge.from.visibleEdgeCnt--; edge.to.visibleEdgeCnt--; } return removed; } public boolean removeNode( Node node ) { boolean removed = super.removeNode(node); if (removed) { node.setVisible(false); } return removed; } public synchronized void removeAll() { for (int i = 0 ; i < nodeCount(); i++) { nodeAt(i).setVisible(false); } for (int i = 0 ; i < edgeCount(); i++) { edgeAt(i).setVisible(false); } super.removeAll(); } public void updateLocalityFromVisibility() throws TGException { //for (int i = 0 ; i < completeEltSet.nodeCount(); i++) { // Node n = nodeAt(i); TGForEachNode fen = new TGForEachNode() { public void forEachNode( Node node ) { try { if (node.isVisible() && !contains(node)) addNode(node); else if (!node.isVisible() && contains(node)) removeNode(node); } catch (TGException ex) { ex.printStackTrace(); } } }; completeEltSet.forAllNodes(fen); //for (int i = 0 ; i < edgeCount(); i++) { // Edge e = edgeAt(i); TGForEachEdge fee = new TGForEachEdge() { public void forEachEdge( Edge edge ) { if (edge.isVisible() && !contains(edge)) addEdge(edge); else if (!edge.isVisible() && contains(edge)) removeEdge(edge); } }; completeEltSet.forAllEdges(fee); } } // end com.touchgraph.graphlayout.graphelements.VisibleLocality TGGraphLayout/com/touchgraph/graphlayout/graphelements/TGNodeQueue.java0000644000175000017500000000644507561561434030417 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.graphelements; import com.touchgraph.graphlayout.Node; import java.util.Vector; /** TGNodeQueue: a very simple queue implementation for doing a breadth * first search. Should probably be implemented with linked lists. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: TGNodeQueue.java,v 1.1 2002/09/19 15:58:32 ldornbusch Exp $ */ public class TGNodeQueue { Vector queue; public TGNodeQueue() { queue=new Vector(); } public void push( Node n ) { queue.addElement(n); } public Node pop() { Node n = (Node)queue.elementAt(0); queue.removeElementAt(0); return n; } public boolean isEmpty() { return queue.size() == 0; } public boolean contains( Node n ) { return queue.contains(n); } } // end com.touchgraph.graphlayout.graphelements.TGNodeQueue TGGraphLayout/com/touchgraph/graphlayout/graphelements/TGForEachNodePair.java0000644000175000017500000000565707561561434031462 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.graphelements; import com.touchgraph.graphlayout.Node; /** TGForEachNodePair: A dummy object for iterating through pairs of nodes * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: TGForEachNodePair.java,v 1.1 2002/09/19 15:58:32 ldornbusch Exp $ */ public abstract class TGForEachNodePair { public void beforeInnerLoop( Node n1 ) {}; public void afterInnerLoop( Node n1 ) {}; public abstract void forEachNodePair( Node n1, Node n2 ); } // end com.touchgraph.graphlayout.graphelements.TGForEachNodePair TGGraphLayout/com/touchgraph/graphlayout/graphelements/TGForEachNode.java0000644000175000017500000000544507561561434030641 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.graphelements; import com.touchgraph.graphlayout.Node; /** TGForEachNode: A dummy object for iterating through nodes * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: TGForEachNode.java,v 1.1 2002/09/19 15:58:32 ldornbusch Exp $ */ public abstract class TGForEachNode { public abstract void forEachNode( Node n ); } // end com.touchgraph.graphlayout.graphelements.TGForEachNode TGGraphLayout/com/touchgraph/graphlayout/graphelements/TGForEachEdge.java0000644000175000017500000000544607561561432030617 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.graphelements; import com.touchgraph.graphlayout.Edge; /** TGForEachEdge: A dummy object for iterating through edges * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: TGForEachEdge.java,v 1.1 2002/09/19 15:58:32 ldornbusch Exp $ */ public abstract class TGForEachEdge { public abstract void forEachEdge( Edge e ); } // end com.touchgraph.graphlayout.graphelements.TGForEachEdge TGGraphLayout/com/touchgraph/graphlayout/graphelements/Locality.java0000644000175000017500000001575707561561432030056 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.graphelements; import com.touchgraph.graphlayout.Node; import com.touchgraph.graphlayout.Edge; import com.touchgraph.graphlayout.TGException; import java.util.Vector; /** Locality: A way of representing a subset of a larger set of nodes. * Allows for both manipulation of the subset, and manipulation of the * larger set. For instance, one can call removeNode to delete it from * the subset, or deleteNode to remove it from the larger set. * * Locality is used in conjunction with LocalityUtils, which handle * locality shift animations. * * More synchronization will almost definitely be required. * * @author Alexander Shapiro * @version 1.22-jre1.1 $Id: Locality.java,v 1.1 2002/09/19 15:58:32 ldornbusch Exp $ */ public class Locality extends GraphEltSet { protected GraphEltSet completeEltSet; // ............ /** Constructor with GraphEltSet ges. */ public Locality(GraphEltSet ges) { super(); completeEltSet = ges; } public GraphEltSet getCompleteEltSet() { return completeEltSet; } public synchronized void addNode( Node n ) throws TGException { if (!contains(n)) { super.addNode(n); //If a new Node is created, and then added to Locality, then add the new edge //to completeEltSet as well. if (!completeEltSet.contains(n)) completeEltSet.addNode(n); } } public void addEdge( Edge e ) { if(!contains(e)) { edges.addElement(e); //If a new Edge is created, and then added to Locality, then add the new edge //to completeEltSet as well. if (!completeEltSet.contains(e)) completeEltSet.addEdge(e); } } public synchronized void addNodeWithEdges( Node n ) throws TGException { addNode(n); for (int i = 0 ; i < n.edgeCount(); i++) { Edge e=n.edgeAt(i); if(contains(e.getOtherEndpt(n))) addEdge(e); } } public synchronized void addAll() throws TGException { synchronized (completeEltSet) { for (int i = 0 ; inodeCount() method. */ public int nodeNum(); /** Return an iterator over the Nodes in the cumulative Vector, null if it is empty. */ // public Iterator getNodes(); /** Return the number of Edges in the cumulative Vector. */ public int edgeCount(); /** Return the current Edge count. * @deprecated this method has been replaced by the edgeCount() method. */ public int edgeNum(); /** Return an iterator over the Edges in the cumulative Vector, null if it is empty. */ // public Iterator getEdges(); /** Return the Node whose ID matches the String id, null if no match is found. */ public Node findNode( String id ); /** Return a Collection of all Nodes whose label matches the String label, * null if no match is found. */ // public Collection findNodesByLabel( String label ); /** Return the first Nodes whose label contains the String substring, * null if no match is found. */ public Node findNodeLabelContaining( String substring ); /** Return an Edge spanning Node from to Node to. */ public Edge findEdge( Node from, Node to ); /** Returns a random node, or null if none exist (for making random graphs). */ public Node getRandomNode(); /** Return the first Node, null if none exist. */ public Node getFirstNode(); /** iterates through all the nodes. */ public void forAllNodes( TGForEachNode fen ); /** iterates through pairs of Nodes. */ public void forAllNodePairs( TGForEachNodePair fenp ); /** iterates through Edges. */ public void forAllEdges( TGForEachEdge fee ); } // end com.touchgraph.graphlayout.graphelements.ImmutableGraphEltSet TGGraphLayout/com/touchgraph/graphlayout/graphelements/GraphEltSet.java0000644000175000017500000003364607561561432030455 0ustar starswifterstarswifter/* * TouchGraph LLC. Apache-Style Software License * * * Copyright (c) 2001-2002 Alexander Shapiro. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * TouchGraph LLC (http://www.touchgraph.com/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse * or promote products derived from this software without prior written * permission. For written permission, please contact * alex@touchgraph.com * * 5. Products derived from this software may not be called "TouchGraph", * nor may "TouchGraph" appear in their name, without prior written * permission of alex@touchgraph.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * */ package com.touchgraph.graphlayout.graphelements; import com.touchgraph.graphlayout.Node; import com.touchgraph.graphlayout.Edge; import com.touchgraph.graphlayout.TGException; //import java.util.Collection; //import java.util.Iterator; import java.util.Vector; import java.util.Hashtable; import java.util.Enumeration; //import java.util.Iterator; //import java.util.Collection; /** GraphEltSet contains data about the graph's components. Currently * the only components are edges and nodes. * * @author Alexander Shapiro * @author Murray Altheim (added support for IDs) * @version 1.22-jre1.1 $Id: GraphEltSet.java,v 1.2 2002/09/20 14:03:29 ldornbusch Exp $ */ public class GraphEltSet implements ImmutableGraphEltSet { protected Vector nodes; protected Vector edges; /** The Hashtable containing references to the Node IDs of the current graph. */ protected Hashtable nodeIDRegistry = null; // ........... /** Default constructor. */ public GraphEltSet() { nodes = new Vector(); edges = new Vector(); nodeIDRegistry = new Hashtable(); // registry of Node IDs } // Node manipulation ........................... /** Return the Node at int index, null if none are available. */ protected Node nodeAt( int i ) { if ( nodes.size() == 0 ) return null; return (Node)nodes.elementAt(i); } /** Return the number of Nodes in the cumulative Vector. * @deprecated this method has been replaced by the nodeCount() method. */ public int nodeNum() { return nodes.size(); } /** Return the number of Nodes in the cumulative Vector. */ public int nodeCount() { return nodes.size(); } /** Return an iterator over the Nodes in the cumulative Vector, null if it is empty. */ /* public Iterator getNodes() { if ( nodes.size() == 0 ) return null; return nodes.iterator(); }*/ /** Registers the Node node via its ID String id. * * @param id the ID of the object. * @param node the Node to be registered. */ //protected void registerNode( String id, Node node ) { // FIXME //} /** Add the Node node to the graph, and * registers the Node via its ID. If no ID exists, no registration occurs. */ public synchronized void addNode( Node node ) throws TGException { String id = node.getID(); if ( id != null ) { if ( findNode(id) == null ) { // doesn't already exist nodeIDRegistry.put(id,node); nodes.addElement(node); } else throw new TGException(TGException.NODE_EXISTS,"node ID '"+id+"' already exists."); } else { String label = node.getLabel().trim(); if (label == null) label = ""; if (!label.equals("") && findNode(node.getLabel()) == null ) { id = label; } else { int i; for( i = 1; findNode( label +"-"+ i ) != null; i++ ); id = label + "-" + i; } node.setID(id); nodeIDRegistry.put(id,node); nodes.addElement(node); } //} else throw new TGException(TGException.NODE_NO_ID,"node has no ID."); // could be ignored? } /** Returns true if the graph contains the Node node. */ public boolean contains( Node node ) { return nodes.contains(node); } // Edge manipulation ........................... /** Return the Edge at int index, null if none are available. */ protected Edge edgeAt( int index ) { if ( edges.size() == 0 ) return null; return (Edge)edges.elementAt(index); } /** Return the number of Edges in the cumulative Vector. * @deprecated this method has been replaced by the edgeCount() method. */ public int edgeNum() { return edges.size(); } /** Return the number of Edges in the cumulative Vector. */ public int edgeCount() { return edges.size(); } /** Return an iterator over the Edges in the cumulative Vector, null if it is empty. */ /* public Iterator getEdges() { if ( edges.size() == 0 ) return null; else return edges.iterator(); } */ /** Add the Edge edge to the graph. */ public void addEdge( Edge edge ) { if ( edge == null ) return; if(!contains(edge)) { edges.addElement(edge); edge.from.addEdge(edge); edge.to.addEdge(edge); } } /** Add an Edge from Node from to Node to, * with tension of int tension, returning the Edge. */ public Edge addEdge( Node from, Node to, int tension ) { Edge edge = null; if ( from != null && to != null ) { edge = new Edge(from,to,tension); addEdge(edge); } return edge; } /** Returns true if the graph contains the Edge edge. */ public boolean contains( Edge edge ) { return edges.contains(edge); } /** Return the Node whose ID matches the String id, null if no match is found. */ public Node findNode( String id ) { if ( id == null ) return null; // ignore return (Node)nodeIDRegistry.get(id); } /** Return the Node whose URL matches the String strURL, null if no match is found. */ public Node findNodeByURL( String strURL ) { Node retVal=null; if ( strURL == null ) return null; // ignore Enumeration myEnum=nodeIDRegistry.elements(); while (myEnum.hasMoreElements()) { Node node = (Node) myEnum.nextElement(); if (node.getURL().equalsIgnoreCase(strURL)){ retVal=node; break; } } return retVal; } /** Return a Collection of all Nodes whose label matches the String label, * null if no match is found. */ /* public Collection findNodesByLabel( String label ) { Vector nodelist = new Vector(); for ( int i = 0 ; i < nodeCount() ; i++) { if (nodeAt(i)!=null && nodeAt(i).getLabel().equals(label)) { nodelist.add(nodeAt(i)); } } if ( nodelist.size() == 0 ) return null; else return (Collection)nodelist; }*/ /** Return the first Nodes whose label contains the String substring, * null if no match is found. */ public Node findNodeLabelContaining( String substring ) { for ( int i = 0 ; i < nodeCount() ; i++) { if (nodeAt(i)!=null && nodeAt(i).getLabel().toLowerCase().equals(substring.toLowerCase())) { return nodeAt(i); } } for ( int i = 0 ; i < nodeCount() ; i++) { if (nodeAt(i)!=null && nodeAt(i).getLabel().toLowerCase().indexOf( substring.toLowerCase())>-1) { return nodeAt(i); } } return null; } /** Return an Edge spanning Node from to Node to. */ public Edge findEdge( Node from, Node to ) { for ( int i = 0 ; i < from.edgeCount(); i++ ) { Edge e = from.edgeAt(i); if (e.to == to) return e; } return null; } /** Delete the Edge edge. */ public boolean deleteEdge( Edge edge ) { synchronized(edges) { if ( edge == null ) return false; if (!edges.removeElement(edge)) return false; edge.from.removeEdge(edge); edge.to.removeEdge(edge); return true; } } /** Delete the Edges contained within the Vector edgedToDelete. */ public void deleteEdges( Vector edgesToDelete ) { synchronized(edges) { for (int i=0;ifrom to Node to, * returning true if successful. */ public boolean deleteEdge( Node from, Node to ) { synchronized(edges) { Edge e = findEdge(from,to); if (e!=null) return deleteEdge(e); return false; } } /** Delete the Node node, returning true if successful. */ public boolean deleteNode( Node node ) { synchronized (nodes) { if ( node == null ) return false; if ( !nodes.removeElement(node) ) return false; String id = node.getID(); if ( id != null ) nodeIDRegistry.remove(id); // remove from registry for ( int i = 0 ; i < node.edgeCount(); i++ ) { Edge e = node.edgeAt(i); if ( e.from == node ) { edges.removeElement(e); // Delete edge not used, because it would change the node's edges e.to.removeEdge(e); // vector which is being iterated on. } else if ( e.to == node ) { edges.removeElement(e); e.from.removeEdge(e); } //No edges are deleted from node. Hopefully garbage collection will pick them up. } } return true; } /** Delete the Nodes contained within the Vector nodesToDelete. */ public void deleteNodes( Vector nodesToDelete ) { synchronized (nodes) { for (int i=0;i=radius) break; for (int i = 0 ; i < n.edgeCount(); i++) { Edge e=n.edgeAt(i); if(n!=n.edgeAt(i).getFrom() && unidirectional) continue; Node adjNode = e.getOtherEndpt(n); if(ges.contains(e) && !distHash.containsKey(adjNode) && adjNode.edgeCount()<=maxAddEdgeCount) { if (adjNode.edgeCount()<=maxExpandEdgeCount) nodeQ.push(adjNode); distHash.put(adjNode,new Integer(currDist+1)); } } } return distHash; } public static Hashtable calculateDistances(GraphEltSet ges, Node focusNode, int radius ) { return calculateDistances(ges, focusNode, radius, 1000, 1000, false); } /** A temporary function that returns the largest connected subgraph in a GraphEltSet. */ // public static Collection getLargestConnectedSubgraph(GraphEltSet ges) { public static Hashtable getLargestConnectedSubgraph(GraphEltSet ges) { int nodeCount = ges.nodeCount(); if(nodeCount==0) return null; Vector subgraphVector = new Vector(); for(int i=0; inodeCount/2) return subgraph; //We are done if (!skipNode) subgraphVector.addElement(subgraph); } int maxSize=0; int maxIndex=0; for (int j = 0; jmaxSize) { maxSize = ((Hashtable) subgraphVector.elementAt(j)).size(); maxIndex = j; } } return (Hashtable) subgraphVector.elementAt(maxIndex); } } // end com.touchgraph.graphlayout.graphelements.GraphEltSet