diff --git a/pom.xml b/pom.xml index 36149f4ac0018cdaa6f665c5c5e97624bc4b8bfd..1ef32a4f72c9c5f3af0ea3a5f2ae54a835f166df 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ <properties> <bundle.symbolicName>de.hhu.ba.yoshikoWrapper</bundle.symbolicName> <bundle.namespace>de.hhu.ba.yoshikoWrapper</bundle.namespace> - <cytoscape.api.version>3.0.0</cytoscape.api.version> + <cytoscape.api.version>3.0.1</cytoscape.api.version> <maven-bundle-plugin.version>2.3.4</maven-bundle-plugin.version> <osgi.api.version>4.2.0</osgi.api.version> @@ -12,7 +12,7 @@ <groupId>de.hhu.ba</groupId> <artifactId>yoshikoWrapper</artifactId> - <version>0.0.2</version> + <version>0.0.3</version> <name>YoshikoWrapper</name> @@ -125,6 +125,12 @@ <type>test-jar</type> <scope>test</scope> </dependency> + <dependency> + <groupId>org.cytoscape</groupId> + <artifactId>layout-api</artifactId> + <version>${cytoscape.api.version}</version> + <type>bundle</type> + </dependency> </dependencies> <description>A Cytoscape plugin for graph-based clustering that wraps the yoshiko algorithm.</description> diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java b/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java index 8512ade4cf00b1180679a1c0b0d46a38c1f1e60f..d7dd81cf1a0d9cf468d62ef61dce5d5dfecb999c 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/CyActivator.java @@ -6,6 +6,7 @@ import org.cytoscape.application.CyApplicationManager; import org.cytoscape.application.swing.CySwingApplication; import org.cytoscape.application.swing.CytoPanelComponent; import org.cytoscape.model.CyNetworkFactory; +import org.cytoscape.model.CyNetworkManager; import org.cytoscape.model.events.AddedEdgesListener; import org.cytoscape.model.events.ColumnCreatedListener; import org.cytoscape.model.events.ColumnDeletedListener; @@ -15,6 +16,11 @@ import org.cytoscape.service.util.AbstractCyActivator; import org.cytoscape.service.util.CyServiceRegistrar; import org.cytoscape.session.events.SessionLoadedListener; import org.cytoscape.view.model.CyNetworkViewFactory; +import org.cytoscape.view.layout.CyLayoutAlgorithmManager; +import org.cytoscape.view.model.CyNetworkViewManager; +import org.cytoscape.view.vizmap.VisualMappingFunctionFactory; +import org.cytoscape.view.vizmap.VisualMappingManager; +import org.cytoscape.view.vizmap.VisualStyleFactory; import org.cytoscape.work.swing.DialogTaskManager; import org.osgi.framework.BundleContext; @@ -47,7 +53,12 @@ public class CyActivator extends AbstractCyActivator { CyCore.networkViewFactory = getService(context, CyNetworkViewFactory.class); CyCore.networkFactory = getService(context, CyNetworkFactory.class); CyCore.swing = getService(context, CySwingApplication.class); - + CyCore.networkViewManager = getService(context,CyNetworkViewManager.class); + CyCore.networkManager = getService(context,CyNetworkManager.class); + CyCore.layoutAlgorithmManager = getService(context,CyLayoutAlgorithmManager.class); + CyCore.visualMappingManager = getService(context,VisualMappingManager.class); + CyCore.visualStyleFactory = getService(context,VisualStyleFactory.class); + CyCore.continuousMappingFactory = getService(context,VisualMappingFunctionFactory.class, "(mapping.type=continuous)"); //Set language according to settings LocalizationManager.switchLanguage(cm.getProperties().getProperty("locale", "enUS")); diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/AlgorithmTask.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/AlgorithmTask.java index 9ce0ad48935bbc222fa3ede8fee08d9184e0da59..d6ca606e47540c2998139fea4a2f5b3ed24eb47c 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/AlgorithmTask.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/AlgorithmTask.java @@ -137,7 +137,7 @@ public class AlgorithmTask extends AbstractTask { for (long i=0;i<numberOfSolutions;i++) { taskMonitor.setStatusMessage("Processing solution "+(i+1)+" of "+numberOfSolutions); - YoshikoSolution solution = new YoshikoSolution(); + YoshikoSolution solution = new YoshikoSolution(net); String columnName = "YOSHIKO_SOLUTION_"+(i+1); net.getDefaultNodeTable().deleteColumn(columnName); diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java b/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java index 48e10473143add793c89b78cbe6d12044eb8e680..984f59c0a92cb3e4fa13540059534aab6a4ffcbf 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/core/CyCore.java @@ -3,11 +3,18 @@ package de.hhu.ba.yoshikoWrapper.core; import org.cytoscape.application.CyApplicationManager; import org.cytoscape.application.swing.CySwingApplication; import org.cytoscape.model.CyNetworkFactory; +import org.cytoscape.model.CyNetworkManager; import org.cytoscape.service.util.CyServiceRegistrar; +import org.cytoscape.view.layout.CyLayoutAlgorithmManager; import org.cytoscape.view.model.CyNetworkViewFactory; +import org.cytoscape.view.model.CyNetworkViewManager; +import org.cytoscape.view.vizmap.VisualMappingFunctionFactory; +import org.cytoscape.view.vizmap.VisualMappingManager; +import org.cytoscape.view.vizmap.VisualStyleFactory; import org.cytoscape.work.swing.DialogTaskManager; import org.osgi.framework.BundleContext; + /**Simple link collection to enable access to Cytoscape instances * */ @@ -21,6 +28,12 @@ public class CyCore { public static CyNetworkViewFactory networkViewFactory; public static CyNetworkFactory networkFactory; public static CySwingApplication swing; + public static CyNetworkViewManager networkViewManager; + public static CyNetworkManager networkManager; + public static CyLayoutAlgorithmManager layoutAlgorithmManager; + public static VisualMappingManager visualMappingManager; + public static VisualStyleFactory visualStyleFactory; + public static VisualMappingFunctionFactory continuousMappingFactory; // } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoSolution.java b/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoSolution.java index 2ff9493f3d4fcce254ab77d955aebe93a4075335..083b120040ff093a9f9504a691498932d03e7c07 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoSolution.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/graphModel/YoshikoSolution.java @@ -1,14 +1,70 @@ package de.hhu.ba.yoshikoWrapper.graphModel; import java.util.ArrayList; +import java.util.HashMap; + +import org.cytoscape.model.CyEdge; +import org.cytoscape.model.CyNetwork; +import org.cytoscape.model.CyNode; + +import de.hhu.ba.yoshikoWrapper.core.CyCore; +import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; public class YoshikoSolution { + private CyNetwork originalGraph; public ArrayList<YoshikoCluster> cluster; public int id; - public YoshikoSolution() { + public YoshikoSolution(CyNetwork originalGraph) { cluster = new ArrayList<YoshikoCluster>(); + this.originalGraph = originalGraph; + } + + /** + * Transforms this solution in a meta-graph where each cluster is represented by one node + * @return The meta-graph as CyNetwork + */ + public CyNetwork toMetaGraph() { + + CyNetwork metaGraph = CyCore.networkFactory.createNetwork(); + + metaGraph.getRow(metaGraph).set(CyNetwork.NAME, LocalizationManager.get("metaGraph")); + + metaGraph.getDefaultNodeTable().createColumn("clusterSize", Integer.class, false); + + //Map Cluster to Nodes for further reference + HashMap<YoshikoCluster,CyNode> map = new HashMap<YoshikoCluster,CyNode>(); + + //Add nodes + for (YoshikoCluster c: cluster) { + CyNode clusterNode = metaGraph.addNode(); + metaGraph.getRow(clusterNode).set("name", LocalizationManager.get("cluster")+" "+c.id); + metaGraph.getRow(clusterNode).set("clusterSize",c.nodes.size()); + map.put(c, clusterNode); + } + + //Add edges (O(|C|^2*|V|^2) can maybe be improved? //TODO + for (YoshikoCluster c1:cluster) { + for (YoshikoCluster c2:cluster) { + if ( + metaGraph.containsEdge(map.get(c1),map.get(c2)) + || c1 == c2 + ) { + continue; + } + clusterloop: + for (CyNode c1n : c1.nodes) { + for (CyNode c2n : c2.nodes) { + if (originalGraph.containsEdge(c1n, c2n) || originalGraph.containsEdge(c2n, c1n)) { + metaGraph.addEdge(map.get(c1), map.get(c2), false); + break clusterloop; + } + } + } + } + } + return metaGraph; } } diff --git a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionTab.java b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionTab.java index 3bad6d69479b188085505bfcb74e40d53620e52b..3ed940f4a0edeb6e2dbe023940d2b2c114139a4c 100644 --- a/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionTab.java +++ b/src/main/java/de/hhu/ba/yoshikoWrapper/gui/SolutionTab.java @@ -1,6 +1,8 @@ package de.hhu.ba.yoshikoWrapper.gui; import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import javax.swing.Box; import javax.swing.BoxLayout; @@ -8,6 +10,14 @@ import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JScrollPane; +import org.cytoscape.model.CyNetwork; +import org.cytoscape.view.layout.CyLayoutAlgorithm; +import org.cytoscape.view.model.CyNetworkView; +import org.cytoscape.view.presentation.property.BasicVisualLexicon; +import org.cytoscape.view.vizmap.VisualStyle; +import org.cytoscape.view.vizmap.mappings.ContinuousMapping; + +import de.hhu.ba.yoshikoWrapper.core.CyCore; import de.hhu.ba.yoshikoWrapper.core.LocalizationManager; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoCluster; import de.hhu.ba.yoshikoWrapper.graphModel.YoshikoSolution; @@ -42,7 +52,45 @@ public class SolutionTab extends ComfortPanel { clusterCount = new JLabel(LocalizationManager.get("clusterFound")+" "+s.cluster.size()); createMetaGraph = new JButton(LocalizationManager.get("createMetaGraph")); - this.addAll(clusterCount,scrollPane); + createMetaGraph.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + CyNetwork metaGraph = solution.toMetaGraph(); + CyNetworkView view = CyCore.networkViewFactory.createNetworkView(metaGraph); + //layout solution + CyLayoutAlgorithm layout = CyCore.layoutAlgorithmManager.getDefaultLayout(); + CyCore.dialogTaskManager.execute( + layout.createTaskIterator( + view, + layout.getDefaultLayoutContext(), + CyLayoutAlgorithm.ALL_NODE_VIEWS, + null + ) + ); + //define style for solution + ContinuousMapping<Integer, Double> contMap = (ContinuousMapping<Integer, Double>)CyCore.continuousMappingFactory.createVisualMappingFunction( + "clusterSize", + Integer.class, + BasicVisualLexicon.NODE_SIZE + ); + VisualStyle vs= CyCore.visualStyleFactory.createVisualStyle("Meta-Graph Style"); + vs.addVisualMappingFunction(contMap); + CyCore.visualMappingManager.addVisualStyle(vs); + + + CyCore.networkManager.addNetwork(metaGraph); + CyCore.networkViewManager.addNetworkView( + view + ); + + CyCore.cy.setCurrentNetworkView(view); + vs.apply(CyCore.cy.getCurrentNetworkView()); + CyCore.cy.getCurrentNetworkView().updateView(); + } + + }); + this.addAll(clusterCount,scrollPane,createMetaGraph); } } diff --git a/src/main/resources/YoshikoStrings.properties b/src/main/resources/YoshikoStrings.properties index 0386be728defd72faa97b31dc5f02dc9fbef5d14..d443a6a175fad86114ee844cd199eeaca012a008 100644 --- a/src/main/resources/YoshikoStrings.properties +++ b/src/main/resources/YoshikoStrings.properties @@ -20,4 +20,5 @@ cost = Cost: nrSolutions = Number of Solutions: redRuleChooserTitle = Reduction Rules discardSolution = Discard -createMetaGraph = Create Meta-Graph \ No newline at end of file +createMetaGraph = Create Meta-Graph +metaGraph = Meta Graph \ No newline at end of file