Initial opendaylight infrastructure commit!!
[controller.git] / third-party / net.sf.jung2 / src / main / java / edu / uci / ics / jung / algorithms / layout / SpringLayout2.java
diff --git a/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/SpringLayout2.java b/third-party/net.sf.jung2/src/main/java/edu/uci/ics/jung/algorithms/layout/SpringLayout2.java
new file mode 100644 (file)
index 0000000..e62a30c
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2003, the JUNG Project and the Regents of the University of
+ * California All rights reserved.
+ * 
+ * This software is open-source under the BSD license; see either "license.txt"
+ * or http://jung.sourceforge.net/license.txt for a description.
+ */
+package edu.uci.ics.jung.algorithms.layout;
+
+import java.awt.Dimension;
+import java.awt.geom.Point2D;
+import java.util.ConcurrentModificationException;
+
+import org.apache.commons.collections15.Transformer;
+
+import edu.uci.ics.jung.graph.Graph;
+
+/**
+ * The SpringLayout package represents a visualization of a set of nodes. The
+ * SpringLayout, which is initialized with a Graph, assigns X/Y locations to
+ * each node. When called <code>relax()</code>, the SpringLayout moves the
+ * visualization forward one step.
+ * 
+ * 
+ * 
+ * @author Danyel Fisher
+ * @author Joshua O'Madadhain
+ */
+public class SpringLayout2<V, E> extends SpringLayout<V,E> 
+{
+    protected int currentIteration;
+    protected int averageCounter;
+    protected int loopCountMax = 4;
+    protected boolean done;
+    
+    protected Point2D averageDelta = new Point2D.Double();
+    
+    /**
+     * Constructor for a SpringLayout for a raw graph with associated
+     * dimension--the input knows how big the graph is. Defaults to the unit
+     * length function.
+     */
+    @SuppressWarnings("unchecked")
+    public SpringLayout2(Graph<V,E> g) {
+        super(g);
+    }
+
+    /**
+     * Constructor for a SpringLayout for a raw graph with associated component.
+     *
+     * @param g the {@code Graph} to lay out
+     * @param length_function provides a length for each edge
+     */
+    public SpringLayout2(Graph<V,E> g, Transformer<E, Integer> length_function)
+    {
+        super(g, length_function);
+    }
+
+    /**
+     * Relaxation step. Moves all nodes a smidge.
+     */
+    @Override
+    public void step() {
+        super.step();
+       currentIteration++;
+       testAverageDeltas();
+    }
+    
+    private void testAverageDeltas() {
+       double dx = this.averageDelta.getX();
+       double dy = this.averageDelta.getY();
+       if(Math.abs(dx) < .001 && Math.abs(dy) < .001) {
+               done = true;
+               System.err.println("done, dx="+dx+", dy="+dy);
+       }
+        if(currentIteration > loopCountMax) {
+               this.averageDelta.setLocation(0,0);
+               averageCounter = 0;
+               currentIteration = 0;
+        }
+    }
+
+    @Override
+    protected void moveNodes() {
+        synchronized (getSize()) {
+            try {
+                for (V v : getGraph().getVertices()) {
+                    if (isLocked(v)) continue;
+                    SpringVertexData vd = springVertexData.get(v);
+                    if(vd == null) continue;
+                    Point2D xyd = transform(v);
+                    
+                    vd.dx += vd.repulsiondx + vd.edgedx;
+                    vd.dy += vd.repulsiondy + vd.edgedy;
+                    
+//                    int currentCount = currentIteration % this.loopCountMax;
+//                    System.err.println(averageCounter+" --- vd.dx="+vd.dx+", vd.dy="+vd.dy);
+//                    System.err.println("averageDelta was "+averageDelta);
+
+                    averageDelta.setLocation(
+                               ((averageDelta.getX() * averageCounter) + vd.dx) / (averageCounter+1),
+                               ((averageDelta.getY() * averageCounter) + vd.dy) / (averageCounter+1)
+                               );
+//                    System.err.println("averageDelta now "+averageDelta);
+//                    System.err.println();
+                    averageCounter++;
+                    
+                    // keeps nodes from moving any faster than 5 per time unit
+                    xyd.setLocation(xyd.getX()+Math.max(-5, Math.min(5, vd.dx)),
+                               xyd.getY()+Math.max(-5, Math.min(5, vd.dy)));
+                    
+                    Dimension d = getSize();
+                    int width = d.width;
+                    int height = d.height;
+                    
+                    if (xyd.getX() < 0) {
+                        xyd.setLocation(0, xyd.getY());//                     setX(0);
+                    } else if (xyd.getX() > width) {
+                        xyd.setLocation(width, xyd.getY());             //setX(width);
+                    }
+                    if (xyd.getY() < 0) {
+                        xyd.setLocation(xyd.getX(),0);//setY(0);
+                    } else if (xyd.getY() > height) {
+                        xyd.setLocation(xyd.getX(), height);      //setY(height);
+                    }
+                    
+                }
+            } catch(ConcurrentModificationException cme) {
+                moveNodes();
+            }
+        }
+    }
+
+    @Override
+    public boolean done() {
+        return done;
+    }
+
+}
\ No newline at end of file