Author: ghuck
Date: 2011-06-25 15:39:21 -0700 (Sat, 25 Jun 2011)
New Revision: 25942
Added:
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/CircleLayout.java.nocompile
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/layouts/
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/layouts/AbstractIgraphLayout.java
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/layouts/CircleLayout.java
Removed:
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/CircleLayout.java
Modified:
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/IgraphPlugin.java
Log:
Layouts now created by extending an abstract parent class
Deleted:
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/CircleLayout.java
===================================================================
---
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/CircleLayout.java
2011-06-25 06:09:03 UTC (rev 25941)
+++
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/CircleLayout.java
2011-06-25 22:39:21 UTC (rev 25942)
@@ -1,390 +0,0 @@
-/**************************************************************************************
-Copyright (C) Gerardo Huck, 2011
-
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************************/
-
-package cytoscape.plugins.igraph;
-
-import cytoscape.Cytoscape;
-import cytoscape.layout.AbstractLayout;
-import cytoscape.layout.LayoutProperties;
-import cytoscape.layout.Tunable;
-import cytoscape.CyNode;
-import cytoscape.logger.CyLogger;
-
-import cytoscape.view.CyNetworkView;
-import cytoscape.data.CyAttributes;
-
-import csplugins.layout.LayoutPartition;
-import csplugins.layout.LayoutEdge;
-import csplugins.layout.LayoutNode;
-import csplugins.layout.EdgeWeighter;
-import csplugins.layout.algorithms.graphPartition.*;
-
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-
-import java.awt.Dimension;
-import java.awt.GridLayout;
-import java.util.*;
-
-public class CircleLayout extends AbstractGraphPartition
-{
- private String message;
- private LayoutProperties layoutProperties;
-
-
- /**
- * Creates a new layout object.
- */
- public CircleLayout() {
- super();
-
- logger = CyLogger.getLogger(CircleLayout.class);
- // logger.setDebug(true);
-
- layoutProperties = new LayoutProperties(getName());
- initialize_properties();
- }
-
- /**
- * This plugin supports laying out only selected nodes
- */
- public boolean supportsSelectedOnly() {
- return true;
- }
-
- /**
- * Adds tunable objects for adjusting plugin parameters
- * Initializes default values for those parameters
- */
- protected void initialize_properties() {
-
- // Add new properties to layout
-
- // Initialize layout properties
- layoutProperties.initializeProperties();
-
- // Force the settings update
- updateSettings(true);
- }
-
- /**
- * getName is used to construct property strings
- * for this layout.
- */
- public String getName() {
- return "Igraph Circle Layout";
- }
-
- /**
- * toString is used to get the user-visible name
- * of the layout
- */
- public String toString(){
- return "Circle Layout";
- }
-
- /**
- * Overload updateSettings for using it without arguments
- */
- public void updateSettings() {
- updateSettings(false);
- }
-
- /**
- * Get new values from tunables and update parameters
- */
- public void updateSettings(boolean force) {
- layoutProperties.updateValues();
- }
-
- /**
- * Get the settings panel for this layout
- */
- public JPanel getSettingsPanel() {
- JPanel panel = new JPanel(new GridLayout(1, 1));
- panel.add(layoutProperties.getTunablePanel());
-
- return panel;
- }
-
- /**
- * Revert previous settings
- */
- public void revertSettings() {
- layoutProperties.revertProperties();
- }
-
- /**
- * Get layout properties
- */
- public LayoutProperties getSettings() {
- return layoutProperties;
- }
-
-
- /**
- *
- */
- public void layoutPartition (LayoutPartition part) {
-
- // Check whether it has been canceled by the user
- if (canceled)
- return;
-
- // Show message on the task monitor
- taskMonitor.setStatus("Initializing: Partition: " +
part.getPartitionNumber());
-
- // The completed percentage is indeterminable
- taskMonitor.setPercentCompleted(-1);
-
- // Figure out our starting point if we are only laying out selected
nodes
- Dimension initialLocation = null;
- if (selectedOnly) {
- initialLocation = part.getAverageLocation();
- }
-
- // Get the number of edges and nodes
- int numNodes = part.nodeCount();
-
- // Allocate memory for storing graph edges information (to be used as
arguments for JNI call)
- double[] x = new double[numNodes];
- double[] y = new double[numNodes];
-
- // Load graph into native library
- HashMap<Integer,Integer> mapping = loadGraphPartition(part,
selectedOnly);
-
- // Check whether it has been canceled by the user
- if (canceled)
- return;
-
- // Show message on the task monitor
- taskMonitor.setStatus("Calling native code: Partition: " +
part.getPartitionNumber());
-
- // Simplify graph
- IgraphInterface.simplify();
-
- // Make native method call
- IgraphInterface.layoutCircle(x, y);
-
- // Check whether it has been canceled by the user
- if (canceled)
- return;
-
- // Show message on the task monitor
- taskMonitor.setStatus("Updating display");
-
-
- // Find which ratio is required to 'scale up' the node positions so
that nodes don't overlap
- double upRatio = 0.0;
- double actualRatio = 0.0;
-
- for (LayoutEdge edge: part.getEdgeList()) {
- LayoutNode n1 = edge.getSource();
- LayoutNode n2 = edge.getTarget();
-
- if (n1.isLocked() || n2.isLocked())
- continue;
-
- double n1Size = Math.max(n1.getHeight(), n1.getWidth());
- double n2Size = Math.max(n2.getHeight(), n2.getWidth());
-
- double edgeSize = Math.sqrt( Math.pow(x[mapping.get(n1.getIndex())]
- x[mapping.get(n2.getIndex())], 2)
- + Math.pow(y[mapping.get(n1.getIndex())]
- y[mapping.get(n2.getIndex())], 2)
- );
- // Check if edgeSize is not zero
- if (edgeSize > 0.0){
-
- // actualRatio = minimun_desired_length / actual_length
- actualRatio = (n1Size + n2Size) / edgeSize;
-
- // Update upRatio if necessary
- if (actualRatio > upRatio)
- upRatio = actualRatio;
- }
-
- }
-
- // Check whether the ratio is not zero
- if (upRatio < 1.0){
- upRatio = 1.0;
- }
-
- double oldUpRatio = upRatio;
-
- // logger.info("upRatio = " + upRatio);
- // message = "upRatio = " + upRatio;
- // JOptionPane.showMessageDialog(Cytoscape.getDesktop(), message);
-
-
- // Move nodes to their position
- boolean success = false;
- while (!success){
-
- try{
- // We will keep track of the offset of the whole part so that
we can eliminate it
- double minX = x[0];
- double minY = y[0];
-
- // Get the 'offset' of the whole partition, so that we can
eliminate it
- for (int i = 1; i < mapping.size(); i++) {
-
- if (x[i] < minX)
- minX = x[i];
-
- if (y[i] < minY)
- minY = y[i];
- }
-
- minX = upRatio * minX;
- minY = upRatio * minY;
-
- // Reset the nodes so we get the new average location
- part.resetNodes();
-
- // Create an iterator for processing the nodes
- Iterator<LayoutNode> iterator2 = part.getNodeList().iterator();
-
- while (iterator2.hasNext()){
-
- // Get next node
- LayoutNode node = (LayoutNode) iterator2.next();
-
- // If it is locked, skip it
- if (!node.isLocked()) {
-
- // Set node's X and Y positions
- node.setX(upRatio * x[mapping.get(node.getIndex())] -
minX);
- node.setY(upRatio * y[mapping.get(node.getIndex())] -
minY);
-
- // Move node to desired location
- part.moveNodeToLocation(node);
- }
- }
-
-
- // Not quite done, yet. If we're only laying out selected
nodes, we need
- // to migrate the selected nodes back to their starting position
- if (selectedOnly) {
- double xDelta = 0.0;
- double yDelta = 0.0;
- Dimension finalLocation = part.getAverageLocation();
- xDelta = finalLocation.getWidth() -
initialLocation.getWidth();
- yDelta = finalLocation.getHeight() -
initialLocation.getHeight();
- for (LayoutNode v: part.getNodeList()) {
- if (!v.isLocked()) {
- v.decrement(xDelta, yDelta);
- part.moveNodeToLocation(v);
- }
- }
- }
-
- success = true;
-
- }
- catch(Exception excep){
-
- upRatio = upRatio / 10.0;
- if (upRatio <= 0.0){
- message = "Sorry, cannot produce layout";
- JOptionPane.showMessageDialog(Cytoscape.getDesktop(),
message);
- return;
- }
- success = false;
- }
-
- }//while(!success)
-
- }// layoutPartion(LayoutPartition part)
-
-
- /**
- * This function loads a partition into igraph
- *
- */
- public static HashMap<Integer,Integer> loadGraphPartition(LayoutPartition
part, boolean selectedOnly){
-
- CyLogger logger = CyLogger.getLogger(CircleLayout.class);
-
- // Create a reverse mapping
- int nodeCount = part.nodeCount();
-
- HashMap<Integer, Integer> nodeIdMapping;
- if (selectedOnly)
- nodeIdMapping = new HashMap<Integer, Integer>(nodeCount -
part.lockedNodeCount());
- else
- nodeIdMapping = new HashMap<Integer, Integer>(nodeCount);
- int j = 0;
-
- Iterator<LayoutNode> nodeIt = part.nodeIterator();
- if (selectedOnly) {
- while(nodeIt.hasNext()) {
- LayoutNode node = (LayoutNode) nodeIt.next();
- if (!node.isLocked()) {
- nodeIdMapping.put(node.getIndex(), j);
- j++;
- }
- }
- } else {
- while(nodeIt.hasNext()) {
- LayoutNode node = (LayoutNode) nodeIt.next();
- nodeIdMapping.put(node.getIndex(), j);
- j++;
- }
- }
-
- // Write edges (as pairs of consecutive nodes) in edgeArray
- int[] edgeArray = new int[part.edgeCount() * 2];
- int i = 0;
-
- Iterator<LayoutEdge> it = part.getEdgeList().iterator();
-
- if (selectedOnly) {
- while (it.hasNext()) {
- LayoutEdge e = (LayoutEdge) it.next();
-
- LayoutNode source = e.getSource();
- LayoutNode target = e.getTarget();
-
- if (source.isLocked() || target.isLocked())
- continue;
-
- edgeArray[i] = nodeIdMapping.get(source.getIndex());
- edgeArray[i + 1] = nodeIdMapping.get(target.getIndex());
- i += 2;
- }
- } else {
- while (it.hasNext()) {
- LayoutEdge e = (LayoutEdge) it.next();
-
- LayoutNode source = e.getSource();
- LayoutNode target = e.getTarget();
-
- edgeArray[i] = nodeIdMapping.get(source.getIndex());
- edgeArray[i + 1] = nodeIdMapping.get(target.getIndex());
- i += 2;
- }
- }
-
- IgraphInterface.createGraph(edgeArray, i);
-
- return nodeIdMapping;
- } // loadGraphPartition()
-
-
-}
\ No newline at end of file
Copied:
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/CircleLayout.java.nocompile
(from rev 25874,
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/CircleLayout.java)
===================================================================
---
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/CircleLayout.java.nocompile
(rev 0)
+++
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/CircleLayout.java.nocompile
2011-06-25 22:39:21 UTC (rev 25942)
@@ -0,0 +1,393 @@
+/**************************************************************************************
+Copyright (C) Gerardo Huck, 2011
+
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+**************************************************************************************/
+
+package cytoscape.plugins.igraph;
+
+import cytoscape.Cytoscape;
+import cytoscape.layout.AbstractLayout;
+import cytoscape.layout.LayoutProperties;
+import cytoscape.layout.Tunable;
+import cytoscape.CyNode;
+import cytoscape.logger.CyLogger;
+
+import cytoscape.view.CyNetworkView;
+import cytoscape.data.CyAttributes;
+
+import csplugins.layout.LayoutPartition;
+import csplugins.layout.LayoutEdge;
+import csplugins.layout.LayoutNode;
+import csplugins.layout.EdgeWeighter;
+import csplugins.layout.algorithms.graphPartition.*;
+
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.util.*;
+
+public class CircleLayout extends AbstractGraphPartition
+{
+ private String message;
+ private LayoutProperties layoutProperties;
+
+
+ /**
+ * Creates a new layout object.
+ */
+ public CircleLayout() {
+ super();
+
+ logger = CyLogger.getLogger(CircleLayout.class);
+ // logger.setDebug(true);
+
+ layoutProperties = new LayoutProperties(getName());
+ initialize_properties();
+ }
+
+
+ /**
+ * This plugin supports laying out only selected nodes
+ */
+ public boolean supportsSelectedOnly() {
+ return true;
+ }
+
+ /**
+ * Adds tunable objects for adjusting plugin parameters
+ * Initializes default values for those parameters
+ */
+ protected void initialize_properties() {
+
+ // Add new properties to layout
+
+ // Initialize layout properties
+ layoutProperties.initializeProperties();
+
+ // Force the settings update
+ updateSettings(true);
+ }
+
+ /**
+ * getName is used to construct property strings
+ * for this layout.
+ */
+ public String getName() {
+ return "Igraph Circle Layout";
+ }
+
+ /**
+ * toString is used to get the user-visible name
+ * of the layout
+ */
+ public String toString(){
+ return "Circle Layout";
+ }
+
+ /**
+ * Overload updateSettings for using it without arguments
+ */
+ public void updateSettings() {
+ updateSettings(false);
+ }
+
+ /**
+ * Get new values from tunables and update parameters
+ */
+ public void updateSettings(boolean force) {
+ layoutProperties.updateValues();
+ }
+
+ /**
+ * Get the settings panel for this layout
+ */
+ public JPanel getSettingsPanel() {
+ JPanel panel = new JPanel(new GridLayout(1, 1));
+ panel.add(layoutProperties.getTunablePanel());
+
+ return panel;
+ }
+
+ /**
+ * Revert previous settings
+ */
+ public void revertSettings() {
+ layoutProperties.revertProperties();
+ }
+
+ /**
+ * Get layout properties
+ */
+ public LayoutProperties getSettings() {
+ return layoutProperties;
+ }
+
+
+ /**
+ *
+ */
+ public void layoutPartition (LayoutPartition part) {
+
+ // Check whether it has been canceled by the user
+ if (canceled)
+ return;
+
+ // Show message on the task monitor
+ taskMonitor.setStatus("Initializing: Partition: " +
part.getPartitionNumber());
+
+ // The completed percentage is indeterminable
+ taskMonitor.setPercentCompleted(-1);
+
+ // Figure out our starting point if we are only laying out selected
nodes
+ Dimension initialLocation = null;
+ if (selectedOnly) {
+ initialLocation = part.getAverageLocation();
+ }
+
+ // Get the number of edges and nodes
+ int numNodes = part.nodeCount();
+
+ // Allocate memory for storing graph edges information (to be used as
arguments for JNI call)
+ double[] x = new double[numNodes];
+ double[] y = new double[numNodes];
+
+ // Load graph into native library
+ HashMap<Integer,Integer> mapping = loadGraphPartition(part,
selectedOnly);
+
+ // Check whether it has been canceled by the user
+ if (canceled)
+ return;
+
+ // Show message on the task monitor
+ taskMonitor.setStatus("Calling native code: Partition: " +
part.getPartitionNumber());
+
+ // Simplify graph
+ IgraphInterface.simplify();
+
+ // Make native method call
+ IgraphInterface.layoutCircle(x, y);
+
+ // Check whether it has been canceled by the user
+ if (canceled)
+ return;
+
+ // Show message on the task monitor
+ taskMonitor.setStatus("Updating display");
+
+ updateDisplay(part, mapping, x, y, initialLocation, selectedOnly);
+
+ }// layoutPartion(LayoutPartition part)
+
+
+
+ protected void updateDisplay(LayoutPartition part,
HashMap<Integer,Integer> mapping, double[] x, double[] y, Dimension
initialLocation, boolean selectedOnly) {
+ // Find which ratio is required to 'scale up' the node positions so
that nodes don't overlap
+ double upRatio = 0.0;
+ double actualRatio = 0.0;
+
+ for (LayoutEdge edge: part.getEdgeList()) {
+ LayoutNode n1 = edge.getSource();
+ LayoutNode n2 = edge.getTarget();
+
+ if (n1.isLocked() || n2.isLocked())
+ continue;
+
+ double n1Size = Math.max(n1.getHeight(), n1.getWidth());
+ double n2Size = Math.max(n2.getHeight(), n2.getWidth());
+
+ double edgeSize = Math.sqrt( Math.pow(x[mapping.get(n1.getIndex())]
- x[mapping.get(n2.getIndex())], 2)
+ + Math.pow(y[mapping.get(n1.getIndex())]
- y[mapping.get(n2.getIndex())], 2)
+ );
+ // Check if edgeSize is not zero
+ if (edgeSize > 0.0){
+
+ // actualRatio = minimun_desired_length / actual_length
+ actualRatio = (n1Size + n2Size) / edgeSize;
+
+ // Update upRatio if necessary
+ if (actualRatio > upRatio)
+ upRatio = actualRatio;
+ }
+
+ }
+
+ // Check whether the ratio is not zero
+ if (upRatio < 1.0){
+ upRatio = 1.0;
+ }
+
+ double oldUpRatio = upRatio;
+
+
+ // Move nodes to their position
+ boolean success = false;
+ while (!success){
+
+ try{
+ // We will keep track of the offset of the whole part so that
we can eliminate it
+ double minX = x[0];
+ double minY = y[0];
+
+ // Get the 'offset' of the whole partition, so that we can
eliminate it
+ for (int i = 1; i < mapping.size(); i++) {
+
+ if (x[i] < minX)
+ minX = x[i];
+
+ if (y[i] < minY)
+ minY = y[i];
+ }
+
+ minX = upRatio * minX;
+ minY = upRatio * minY;
+
+ // Reset the nodes so we get the new average location
+ part.resetNodes();
+
+ // Create an iterator for processing the nodes
+ Iterator<LayoutNode> iterator2 = part.getNodeList().iterator();
+
+ while (iterator2.hasNext()){
+
+ // Get next node
+ LayoutNode node = (LayoutNode) iterator2.next();
+
+ // If it is locked, skip it
+ if (!node.isLocked()) {
+
+ // Set node's X and Y positions
+ node.setX(upRatio * x[mapping.get(node.getIndex())] -
minX);
+ node.setY(upRatio * y[mapping.get(node.getIndex())] -
minY);
+
+ // Move node to desired location
+ part.moveNodeToLocation(node);
+ }
+ }
+
+
+ // Not quite done, yet. If we're only laying out selected
nodes, we need
+ // to migrate the selected nodes back to their starting position
+ if (selectedOnly) {
+ double xDelta = 0.0;
+ double yDelta = 0.0;
+ Dimension finalLocation = part.getAverageLocation();
+ xDelta = finalLocation.getWidth() -
initialLocation.getWidth();
+ yDelta = finalLocation.getHeight() -
initialLocation.getHeight();
+ for (LayoutNode v: part.getNodeList()) {
+ if (!v.isLocked()) {
+ v.decrement(xDelta, yDelta);
+ part.moveNodeToLocation(v);
+ }
+ }
+ }
+
+ success = true;
+
+ }
+ catch(Exception excep){
+
+ upRatio = upRatio / 10.0;
+ if (upRatio <= 0.0){
+ message = "Sorry, cannot produce layout";
+ JOptionPane.showMessageDialog(Cytoscape.getDesktop(),
message);
+ return;
+ }
+ success = false;
+ }
+
+ }//while(!success)
+
+ } //updateDisplay
+
+
+ /**
+ * This function loads a partition into igraph
+ *
+ */
+ public static HashMap<Integer,Integer> loadGraphPartition(LayoutPartition
part, boolean selectedOnly){
+
+ CyLogger logger = CyLogger.getLogger(CircleLayout.class);
+
+ // Create a reverse mapping
+ int nodeCount = part.nodeCount();
+
+ HashMap<Integer, Integer> nodeIdMapping;
+ if (selectedOnly)
+ nodeIdMapping = new HashMap<Integer, Integer>(nodeCount -
part.lockedNodeCount());
+ else
+ nodeIdMapping = new HashMap<Integer, Integer>(nodeCount);
+ int j = 0;
+
+ Iterator<LayoutNode> nodeIt = part.nodeIterator();
+ if (selectedOnly) {
+ while(nodeIt.hasNext()) {
+ LayoutNode node = (LayoutNode) nodeIt.next();
+ if (!node.isLocked()) {
+ nodeIdMapping.put(node.getIndex(), j);
+ j++;
+ }
+ }
+ } else {
+ while(nodeIt.hasNext()) {
+ LayoutNode node = (LayoutNode) nodeIt.next();
+ nodeIdMapping.put(node.getIndex(), j);
+ j++;
+ }
+ }
+
+ // Write edges (as pairs of consecutive nodes) in edgeArray
+ int[] edgeArray = new int[part.edgeCount() * 2];
+ int i = 0;
+
+ Iterator<LayoutEdge> it = part.getEdgeList().iterator();
+
+ if (selectedOnly) {
+ while (it.hasNext()) {
+ LayoutEdge e = (LayoutEdge) it.next();
+
+ LayoutNode source = e.getSource();
+ LayoutNode target = e.getTarget();
+
+ if (source.isLocked() || target.isLocked())
+ continue;
+
+ edgeArray[i] = nodeIdMapping.get(source.getIndex());
+ edgeArray[i + 1] = nodeIdMapping.get(target.getIndex());
+ i += 2;
+ }
+ } else {
+ while (it.hasNext()) {
+ LayoutEdge e = (LayoutEdge) it.next();
+
+ LayoutNode source = e.getSource();
+ LayoutNode target = e.getTarget();
+
+ edgeArray[i] = nodeIdMapping.get(source.getIndex());
+ edgeArray[i + 1] = nodeIdMapping.get(target.getIndex());
+ i += 2;
+ }
+ }
+
+ IgraphInterface.createGraph(edgeArray, i);
+
+ return nodeIdMapping;
+ } // loadGraphPartition()
+
+
+}
\ No newline at end of file
Modified:
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/IgraphPlugin.java
===================================================================
---
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/IgraphPlugin.java
2011-06-25 06:09:03 UTC (rev 25941)
+++
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/IgraphPlugin.java
2011-06-25 22:39:21 UTC (rev 25942)
@@ -19,6 +19,7 @@
package cytoscape.plugins.igraph;
+import cytoscape.plugins.igraph.layout.*;
import cytoscape.plugin.CytoscapePlugin;
import cytoscape.Cytoscape;
import cytoscape.util.CytoscapeAction;
@@ -53,12 +54,6 @@
checkLib("igraphWrapper");
checkLib("igraph.0");
- // Load igraph
- //loadIgraph();
-
- // Use JNA to print a simple message
- //HelloWorld.hello();
-
String userDir = System.getProperty("user.dir");
// JOptionPane.showMessageDialog( Cytoscape.getDesktop(), "user dir:"+
userDir);
NativeLibrary.addSearchPath("igraphWrapper", userDir + "/plugins");
@@ -77,6 +72,7 @@
// Layouts
CyLayouts.addLayout(new CircleLayout(), "Igraph");
+
}
Added:
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/layouts/AbstractIgraphLayout.java
===================================================================
---
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/layouts/AbstractIgraphLayout.java
(rev 0)
+++
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/layouts/AbstractIgraphLayout.java
2011-06-25 22:39:21 UTC (rev 25942)
@@ -0,0 +1,396 @@
+/**************************************************************************************
+Copyright (C) Gerardo Huck, 2011
+
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+**************************************************************************************/
+
+package cytoscape.plugins.igraph.layout;
+
+import cytoscape.plugins.igraph.*;
+import cytoscape.Cytoscape;
+import cytoscape.layout.AbstractLayout;
+import cytoscape.layout.LayoutProperties;
+import cytoscape.layout.Tunable;
+import cytoscape.CyNode;
+import cytoscape.logger.CyLogger;
+
+import cytoscape.view.CyNetworkView;
+import cytoscape.data.CyAttributes;
+
+import csplugins.layout.LayoutPartition;
+import csplugins.layout.LayoutEdge;
+import csplugins.layout.LayoutNode;
+import csplugins.layout.EdgeWeighter;
+import csplugins.layout.algorithms.graphPartition.*;
+
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.util.*;
+
+
+public abstract class AbstractIgraphLayout extends AbstractGraphPartition {
+
+ private String message;
+ protected LayoutProperties layoutProperties;
+
+
+ public AbstractIgraphLayout() {
+ super();
+
+ logger = CyLogger.getLogger(AbstractIgraphLayout.class);
+ // logger.setDebug(true);
+
+// layoutProperties = new LayoutProperties(getName());
+// initialize_properties();
+ }
+
+ // METHODS WHICH MUST BE OVERRIDEN IN CHILD CLASS
+
+ /**
+ * Do the layout on a graph alrealy loaded into igraph
+ */
+ public abstract int layout(double[] x, double[] y);
+
+ /**
+ * getName is used to construct property strings
+ * for this layout.
+ */
+ public abstract String getName();
+
+ /**
+ * toString is used to get the user-visible name
+ * of the layout
+ */
+ public abstract String toString();
+
+ // END OF METHODS WHICH MUST BE OVERRIDEN
+
+ // METHODS WHICH MAY BE OVERRIDEN IN CHILD CLASS
+
+ /**
+ * By default, igraph layouts support laying out only selected nodes
+ */
+ public boolean supportsSelectedOnly() {
+ return true;
+ }
+
+ /**
+ * Adds tunable objects for adjusting plugin parameters
+ * Initializes default values for those parameters
+ */
+ protected void initialize_properties() {
+
+ // Add new properties to layout
+
+ // Initialize layout properties
+ layoutProperties.initializeProperties();
+
+ // Force the settings update
+ updateSettings(true);
+ }
+
+ /**
+ * Overload updateSettings for using it without arguments
+ */
+ public void updateSettings() {
+ updateSettings(false);
+ }
+
+ /**
+ * Get the settings panel for this layout
+ */
+ public JPanel getSettingsPanel() {
+ JPanel panel = new JPanel(new GridLayout(1, 1));
+ panel.add(layoutProperties.getTunablePanel());
+
+ return panel;
+ }
+
+ // END OF METHODS WHICH MAY BE OVERRIDEN
+
+ /**
+ * Get new values from tunables and update parameters
+ */
+ public void updateSettings(boolean force) {
+ layoutProperties.updateValues();
+ }
+
+ /**
+ * Revert previous settings
+ */
+ public void revertSettings() {
+ layoutProperties.revertProperties();
+ }
+
+ /**
+ * Get layout properties
+ */
+ public LayoutProperties getSettings() {
+ return layoutProperties;
+ }
+
+ /**
+ *
+ */
+ public void layoutPartition (LayoutPartition part) {
+
+ // Check whether it has been canceled by the user
+ if (canceled)
+ return;
+
+ // Show message on the task monitor
+ taskMonitor.setStatus("Initializing: Partition: " +
part.getPartitionNumber());
+
+ // The completed percentage is indeterminable
+ taskMonitor.setPercentCompleted(-1);
+
+ // Figure out our starting point if we are only laying out selected
nodes
+ Dimension initialLocation = null;
+ if (selectedOnly) {
+ initialLocation = part.getAverageLocation();
+ }
+
+ // Get the number of edges and nodes
+ int numNodes = part.nodeCount();
+
+ // Allocate memory for storing graph edges information (to be used as
arguments for JNI call)
+ double[] x = new double[numNodes];
+ double[] y = new double[numNodes];
+
+ // Load graph into native library
+ HashMap<Integer,Integer> mapping = loadGraphPartition(part,
selectedOnly);
+
+ // Check whether it has been canceled by the user
+ if (canceled)
+ return;
+
+ // Show message on the task monitor
+ taskMonitor.setStatus("Calling native code: Partition: " +
part.getPartitionNumber());
+
+ // Do Layout
+ layout(x,y);
+
+ // Check whether it has been canceled by the user
+ if (canceled)
+ return;
+
+ // Show message on the task monitor
+ taskMonitor.setStatus("Updating display");
+
+ updateDisplay(part, mapping, x, y, initialLocation, selectedOnly);
+
+ }// layoutPartion(LayoutPartition part)
+
+
+
+ protected void updateDisplay(LayoutPartition part,
HashMap<Integer,Integer> mapping, double[] x, double[] y, Dimension
initialLocation, boolean selectedOnly) {
+ // Find which ratio is required to 'scale up' the node positions so
that nodes don't overlap
+ double upRatio = 0.0;
+ double actualRatio = 0.0;
+
+ for (LayoutEdge edge: part.getEdgeList()) {
+ LayoutNode n1 = edge.getSource();
+ LayoutNode n2 = edge.getTarget();
+
+ if (n1.isLocked() || n2.isLocked())
+ continue;
+
+ double n1Size = Math.max(n1.getHeight(), n1.getWidth());
+ double n2Size = Math.max(n2.getHeight(), n2.getWidth());
+
+ double edgeSize = Math.sqrt( Math.pow(x[mapping.get(n1.getIndex())]
- x[mapping.get(n2.getIndex())], 2)
+ + Math.pow(y[mapping.get(n1.getIndex())]
- y[mapping.get(n2.getIndex())], 2)
+ );
+ // Check if edgeSize is not zero
+ if (edgeSize > 0.0){
+
+ // actualRatio = minimun_desired_length / actual_length
+ actualRatio = (n1Size + n2Size) / edgeSize;
+
+ // Update upRatio if necessary
+ if (actualRatio > upRatio)
+ upRatio = actualRatio;
+ }
+
+ }
+
+ // Check whether the ratio is not zero
+ if (upRatio < 1.0){
+ upRatio = 1.0;
+ }
+
+ double oldUpRatio = upRatio;
+
+
+ // Move nodes to their position
+ boolean success = false;
+ while (!success){
+
+ try{
+ // We will keep track of the offset of the whole part so that
we can eliminate it
+ double minX = x[0];
+ double minY = y[0];
+
+ // Get the 'offset' of the whole partition, so that we can
eliminate it
+ for (int i = 1; i < mapping.size(); i++) {
+
+ if (x[i] < minX)
+ minX = x[i];
+
+ if (y[i] < minY)
+ minY = y[i];
+ }
+
+ minX = upRatio * minX;
+ minY = upRatio * minY;
+
+ // Reset the nodes so we get the new average location
+ part.resetNodes();
+
+ // Create an iterator for processing the nodes
+ Iterator<LayoutNode> iterator2 = part.getNodeList().iterator();
+
+ while (iterator2.hasNext()){
+
+ // Get next node
+ LayoutNode node = (LayoutNode) iterator2.next();
+
+ // If it is locked, skip it
+ if (!node.isLocked()) {
+
+ // Set node's X and Y positions
+ node.setX(upRatio * x[mapping.get(node.getIndex())] -
minX);
+ node.setY(upRatio * y[mapping.get(node.getIndex())] -
minY);
+
+ // Move node to desired location
+ part.moveNodeToLocation(node);
+ }
+ }
+
+
+ // Not quite done, yet. If we're only laying out selected
nodes, we need
+ // to migrate the selected nodes back to their starting position
+ if (selectedOnly) {
+ double xDelta = 0.0;
+ double yDelta = 0.0;
+ Dimension finalLocation = part.getAverageLocation();
+ xDelta = finalLocation.getWidth() -
initialLocation.getWidth();
+ yDelta = finalLocation.getHeight() -
initialLocation.getHeight();
+ for (LayoutNode v: part.getNodeList()) {
+ if (!v.isLocked()) {
+ v.decrement(xDelta, yDelta);
+ part.moveNodeToLocation(v);
+ }
+ }
+ }
+
+ success = true;
+
+ }
+ catch(Exception excep){
+
+ upRatio = upRatio / 10.0;
+ if (upRatio <= 0.0){
+ message = "Sorry, cannot produce layout";
+ JOptionPane.showMessageDialog(Cytoscape.getDesktop(),
message);
+ return;
+ }
+ success = false;
+ }
+
+ }//while(!success)
+
+ } //updateDisplay
+
+
+ /**
+ * This function loads a partition into igraph
+ *
+ */
+ public static HashMap<Integer,Integer> loadGraphPartition(LayoutPartition
part, boolean selectedOnly){
+
+ CyLogger logger = CyLogger.getLogger(AbstractIgraphLayout.class);
+
+ // Create a reverse mapping
+ int nodeCount = part.nodeCount();
+
+ HashMap<Integer, Integer> nodeIdMapping;
+ if (selectedOnly)
+ nodeIdMapping = new HashMap<Integer, Integer>(nodeCount -
part.lockedNodeCount());
+ else
+ nodeIdMapping = new HashMap<Integer, Integer>(nodeCount);
+ int j = 0;
+
+ Iterator<LayoutNode> nodeIt = part.nodeIterator();
+ if (selectedOnly) {
+ while(nodeIt.hasNext()) {
+ LayoutNode node = (LayoutNode) nodeIt.next();
+ if (!node.isLocked()) {
+ nodeIdMapping.put(node.getIndex(), j);
+ j++;
+ }
+ }
+ } else {
+ while(nodeIt.hasNext()) {
+ LayoutNode node = (LayoutNode) nodeIt.next();
+ nodeIdMapping.put(node.getIndex(), j);
+ j++;
+ }
+ }
+
+ // Write edges (as pairs of consecutive nodes) in edgeArray
+ int[] edgeArray = new int[part.edgeCount() * 2];
+ int i = 0;
+
+ Iterator<LayoutEdge> it = part.getEdgeList().iterator();
+
+ if (selectedOnly) {
+ while (it.hasNext()) {
+ LayoutEdge e = (LayoutEdge) it.next();
+
+ LayoutNode source = e.getSource();
+ LayoutNode target = e.getTarget();
+
+ if (source.isLocked() || target.isLocked())
+ continue;
+
+ edgeArray[i] = nodeIdMapping.get(source.getIndex());
+ edgeArray[i + 1] = nodeIdMapping.get(target.getIndex());
+ i += 2;
+ }
+ } else {
+ while (it.hasNext()) {
+ LayoutEdge e = (LayoutEdge) it.next();
+
+ LayoutNode source = e.getSource();
+ LayoutNode target = e.getTarget();
+
+ edgeArray[i] = nodeIdMapping.get(source.getIndex());
+ edgeArray[i + 1] = nodeIdMapping.get(target.getIndex());
+ i += 2;
+ }
+ }
+
+ IgraphInterface.createGraph(edgeArray, i);
+
+ return nodeIdMapping;
+ } // loadGraphPartition()
+
+}
+
Added:
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/layouts/CircleLayout.java
===================================================================
---
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/layouts/CircleLayout.java
(rev 0)
+++
csplugins/trunk/soc/ghuck/IgraphPlugin/src/cytoscape/plugins/igraph/layouts/CircleLayout.java
2011-06-25 22:39:21 UTC (rev 25942)
@@ -0,0 +1,66 @@
+/**************************************************************************************
+Copyright (C) Gerardo Huck, 2011
+
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+**************************************************************************************/
+
+package cytoscape.plugins.igraph.layout;
+
+import cytoscape.plugins.igraph.*;
+import cytoscape.logger.CyLogger;
+import cytoscape.layout.LayoutProperties;
+
+
+public class CircleLayout extends AbstractIgraphLayout {
+
+ public CircleLayout() {
+ super();
+ logger = CyLogger.getLogger(CircleLayout.class);
+
+ layoutProperties = new LayoutProperties(getName());
+ initialize_properties();
+ }
+
+ /**
+ * Do the layout on a graph alrealy loaded into igraph
+ */
+ public int layout(double[] x, double[] y) {
+ // Simplify graph
+ IgraphInterface.simplify();
+
+ // Make native method call
+ IgraphInterface.layoutCircle(x, y);
+
+ return 1;
+ }
+
+ /**
+ * getName is used to construct property strings
+ * for this layout.
+ */
+ public String getName() {
+ return "Igraph Circle Layout";
+ }
+
+ /**
+ * toString is used to get the user-visible name
+ * of the layout
+ */
+ public String toString() {
+ return "Circle Layout";
+ }
+
+}
\ No newline at end of file
--
You received this message because you are subscribed to the Google Groups
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/cytoscape-cvs?hl=en.