Commit 8345651f authored by Philipp Spohr's avatar Philipp Spohr
Browse files

Improved style handling

parent c81d667f
/*******************************************************************************
* Copyright (C) 2017 Philipp Spohr
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
......@@ -38,7 +38,6 @@ import org.cytoscape.service.util.AbstractCyActivator;
import org.cytoscape.service.util.CyServiceRegistrar;
import org.cytoscape.session.events.SessionLoadedListener;
import org.cytoscape.task.create.CloneNetworkTaskFactory;
import org.cytoscape.task.visualize.ApplyVisualStyleTaskFactory;
import org.cytoscape.view.model.CyNetworkViewFactory;
import org.cytoscape.view.layout.CyLayoutAlgorithmManager;
import org.cytoscape.view.model.CyNetworkViewManager;
......@@ -68,7 +67,7 @@ public class CyActivator extends AbstractCyActivator {
public CyActivator() {
super();
}
@Override
public void start(BundleContext context) throws Exception {
//Initialize cytoscape configuration system
......@@ -77,9 +76,9 @@ public class CyActivator extends AbstractCyActivator {
Properties propsReaderServiceProps = new Properties();
propsReaderServiceProps.setProperty("cyPropertyName", "yoshiko.props");
registerAllServices(context,cm,propsReaderServiceProps);
//Create symbolic links to give other classes access to Cytoscape Services
CyCore.cy = getService(context, CyApplicationManager.class);
CyCore.cy = getService(context, CyApplicationManager.class);
CyCore.dialogTaskManager = getService(context, DialogTaskManager.class);
CyCore.registrar = getService(context, CyServiceRegistrar.class);
CyCore.cm = cm;
......@@ -93,14 +92,13 @@ public class CyActivator extends AbstractCyActivator {
CyCore.visualStyleFactory = getService(context,VisualStyleFactory.class);
CyCore.continuousMappingFactory = getService(context,VisualMappingFunctionFactory.class, "(mapping.type=continuous)");
CyCore.rootNetworkManager = getService(context,CyRootNetworkManager.class);
CyCore.applyVisualStyleTaskFactory = getService(context,ApplyVisualStyleTaskFactory.class);
//Not sure how to correctly infer arguments here
CyCore.renderingEngineFactory = getService(context,RenderingEngineFactory.class);
CyCore.cloneNetworkTaskFactory = getService(context,CloneNetworkTaskFactory.class);
//Store a reference to the Version
YoshUtil.version = context.getBundle().getVersion();
//Set language according to settings -> Default to enUS
LocalizationManager.switchLanguage(cm.getProperties().getProperty("locale", "enUS"));
......@@ -111,12 +109,12 @@ public class CyActivator extends AbstractCyActivator {
YoshikoLoader.loadLibrary(pathToYosh);
}
}
//Initialize and register main panel
MainPanel mainPanel = new MainPanel();
registerService(context,mainPanel,CytoPanelComponent.class, new Properties());
//Listener for Network-Changes -> Updating possible columns for mapping
NetChangeListener netChangeListener = new NetChangeListener(mainPanel.getColumnMapper());
registerService(context,netChangeListener, AddedEdgesListener.class, new Properties());
......@@ -125,7 +123,7 @@ public class CyActivator extends AbstractCyActivator {
registerService(context,netChangeListener, ColumnDeletedListener.class, new Properties());
registerService(context,netChangeListener, SessionLoadedListener.class, new Properties());
registerService(context,netChangeListener, SetCurrentNetworkListener.class, new Properties());
//Show Startup-Hint
HintManager.showMappingHint(Hint.FIRST_START);
......
/*******************************************************************************
* Copyright (C) 2017 Philipp Spohr
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
......@@ -29,7 +29,6 @@ import org.cytoscape.model.CyNetworkManager;
import org.cytoscape.model.subnetwork.CyRootNetworkManager;
import org.cytoscape.service.util.CyServiceRegistrar;
import org.cytoscape.task.create.CloneNetworkTaskFactory;
import org.cytoscape.task.visualize.ApplyVisualStyleTaskFactory;
import org.cytoscape.view.layout.CyLayoutAlgorithmManager;
import org.cytoscape.view.model.CyNetworkViewFactory;
import org.cytoscape.view.model.CyNetworkViewManager;
......@@ -61,11 +60,10 @@ public class CyCore {
public static VisualStyleFactory visualStyleFactory;
public static VisualMappingFunctionFactory continuousMappingFactory;
public static CyRootNetworkManager rootNetworkManager;
public static ApplyVisualStyleTaskFactory applyVisualStyleTaskFactory;
public static RenderingEngineFactory<CyNetwork> renderingEngineFactory;
public static CloneNetworkTaskFactory cloneNetworkTaskFactory;
//
//Convenience
public static String getConfig(String key) {
return cm.getProperties().getProperty(key);
......
package de.hhu.ba.yoshikoWrapper.cytoUtil;
import java.util.List;
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.BoundaryRangeValues;
import org.cytoscape.view.vizmap.mappings.ContinuousMapping;
import de.hhu.ba.yoshikoWrapper.core.CyCore;
public class StyleManager {
public static final String CLUSTERSIZE_COLUMN_NAME = "clusterSize";
public static final String EDGESTRENGTH_COLUMN_NAME = "edgeStrength";
public static final double MIN_EDGE_SIZE = 1.0;
public static final double MAX_EDGE_SIZE = 10.0;
public static final double MIN_NODE_SIZE = 5.0;
public static final double MAX_NODE_SIZE = 30.0;
private static void apply (CyNetworkView view, VisualStyle style) {
CyCore.visualMappingManager.setVisualStyle(style,view);
style.apply(view);
view.updateView();
}
public static void style(CyNetworkView view, VisualStyle style) {
apply(view,style);
}
public static void styleWithMapping(CyNetworkView view, VisualStyle style) {
style = CyCore.visualStyleFactory.createVisualStyle(style);
//Define style for solution
ContinuousMapping<Integer, Double> contMapNodes = (ContinuousMapping<Integer, Double>)CyCore.continuousMappingFactory.createVisualMappingFunction(
CLUSTERSIZE_COLUMN_NAME,
Integer.class,
BasicVisualLexicon.NODE_SIZE
);
ContinuousMapping<Integer, Double> contMapEdges = (ContinuousMapping<Integer, Double>)CyCore.continuousMappingFactory.createVisualMappingFunction(
EDGESTRENGTH_COLUMN_NAME,
Integer.class,
BasicVisualLexicon.EDGE_WIDTH
);
//Calculate size range and scale accordingly
List<Integer> sizes = view.getModel().getDefaultNodeTable().getColumn(CLUSTERSIZE_COLUMN_NAME).getValues(Integer.class);
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (Integer i : sizes) {
if (i < min) {
min = i;
}
if (i > max) {
max = i;
}
}
contMapNodes.addPoint(min, new BoundaryRangeValues<Double>(MIN_NODE_SIZE,MIN_NODE_SIZE,MIN_NODE_SIZE));
contMapNodes.addPoint(max, new BoundaryRangeValues<Double>(MAX_NODE_SIZE,MAX_NODE_SIZE,MAX_NODE_SIZE));
sizes = view.getModel().getDefaultEdgeTable().getColumn(EDGESTRENGTH_COLUMN_NAME).getValues(Integer.class);
min = Integer.MAX_VALUE;
max = Integer.MIN_VALUE;
for (Integer i : sizes) {
if (i < min) {
min = i;
}
if (i > max) {
max = i;
}
}
contMapEdges.addPoint(min, new BoundaryRangeValues<Double>(MIN_EDGE_SIZE,MIN_EDGE_SIZE,MIN_EDGE_SIZE));
contMapEdges.addPoint(max, new BoundaryRangeValues<Double>(MAX_EDGE_SIZE,MAX_EDGE_SIZE,MAX_EDGE_SIZE));
style.addVisualMappingFunction(contMapNodes);
style.addVisualMappingFunction(contMapEdges);
apply(view,style);
}
}
/*******************************************************************************
* Copyright (C) 2017 Philipp Spohr
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
......@@ -38,7 +38,6 @@ import org.cytoscape.model.subnetwork.CySubNetwork;
import org.cytoscape.view.layout.CyLayoutAlgorithm;
import org.cytoscape.view.model.CyNetworkView;
import org.cytoscape.view.presentation.RenderingEngine;
import org.cytoscape.view.vizmap.VisualStyle;
import org.cytoscape.work.Task;
import org.cytoscape.work.TaskIterator;
import org.cytoscape.work.TaskMonitor;
......@@ -46,32 +45,33 @@ import org.slf4j.Logger;
import de.hhu.ba.yoshikoWrapper.core.CyCore;
import de.hhu.ba.yoshikoWrapper.core.LocalizationManager;
import de.hhu.ba.yoshikoWrapper.cytoUtil.StyleManager;
import de.hhu.ba.yoshikoWrapper.logging.YoshikoLogger;
import static org.cytoscape.view.presentation.property.BasicVisualLexicon.NETWORK_HEIGHT;
import static org.cytoscape.view.presentation.property.BasicVisualLexicon.NETWORK_WIDTH;
public class YoshikoCluster {
private final long id;
private ArrayList<CyNode> nodes;
private CySubNetwork net;
//SYMBOLIC LINKS
private final CyNetwork originalGraph;
private Logger logger = YoshikoLogger.getInstance().getLogger();
public YoshikoCluster(long id, CyNetwork originalGraph) {
this.id = id;
this.originalGraph = originalGraph;
this.nodes = new ArrayList<CyNode>();
this.nodes = new ArrayList<CyNode>();
}
private void createSubNetwork() {
if (net == null) {
CyRootNetwork originalGraphAsRoot = CyCore.rootNetworkManager.getRootNetwork(originalGraph);
......@@ -89,11 +89,11 @@ public class YoshikoCluster {
CySubNetwork subnet = originalGraphAsRoot.addSubNetwork(nodes ,inducedEdges);
subnet.getRow(subnet).set(CyNetwork.NAME, LocalizationManager.get("cluster")+" "+(id+1));
net = subnet; //Save for further reference
net = subnet; //Save for further reference
}
}
/**
* Attempt to select the nodes belonging to this cluster in the original Graph given that they still exist
*/
......@@ -112,41 +112,39 @@ public class YoshikoCluster {
logger.warn("The graph doesn't exist anymore, can't highlight nodes!");
}
}
public void generateImage(JLabel label, int width, int height) {
if (net == null) {
createSubNetwork();
}
final CyNetworkView view = CyCore.networkViewFactory.createNetworkView(net);
//layout cluster
final CyLayoutAlgorithm layout = CyCore.layoutAlgorithmManager.getDefaultLayout();
final TaskIterator createLayout = layout.createTaskIterator(
view,
layout.getDefaultLayoutContext(),
view,
layout.getDefaultLayoutContext(),
CyLayoutAlgorithm.ALL_NODE_VIEWS,
null
);
createLayout.append(
new Task() {
@Override
public void run(TaskMonitor taskMonitor) throws Exception {
taskMonitor.setStatusMessage("Generating cluster view for C:"+id);
VisualStyle vs= CyCore.visualStyleFactory.createVisualStyle(CyCore.visualMappingManager.getCurrentVisualStyle());
CyCore.visualMappingManager.setVisualStyle(vs, view);
vs.apply(view);
StyleManager.style(view, CyCore.visualMappingManager.getCurrentVisualStyle());
view.setVisualProperty(NETWORK_WIDTH, new Double(width));
view.setVisualProperty(NETWORK_HEIGHT, new Double(height));
view.fitContent();
view.updateView();
RenderingEngine<CyNetwork> renderingEngine = CyCore.renderingEngineFactory.createRenderingEngine(label, view);
SwingUtilities.invokeLater(new Runnable() {
......@@ -154,28 +152,28 @@ public class YoshikoCluster {
public void run() {
Image img = renderingEngine.createImage(width,height);
label.setIcon(new ImageIcon(img));
renderingEngine.dispose();
view.dispose();
}
});
}
@Override
public void cancel() {
//Nothing to do as GC is handled by JAVA
}
}
);
CyCore.dialogTaskManager.execute(
createLayout
);
}
......
/*******************************************************************************
* Copyright (C) 2017 Philipp Spohr
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
......@@ -32,24 +32,22 @@ import org.cytoscape.model.CyEdge.Type;
import org.cytoscape.model.subnetwork.CySubNetwork;
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.cytoUtil.StyleManager;
public class YoshikoSolution {
/**
* The original Graph from which the solution was generated.
* NOTE: This can be destroyed or modified during runtime while the solution still exists and may become invalid
*/
private CyNetwork originalGraph;
public ArrayList<YoshikoCluster> cluster;
public int id;
public YoshikoSolution(CyNetwork originalGraph) {
cluster = new ArrayList<YoshikoCluster>();
this.originalGraph = originalGraph;
......@@ -60,27 +58,26 @@ public class YoshikoSolution {
* The nodes are linked to subgraphs representing the cluster and also their size is scaled relative to cluster size
*/
public void exportMetaGraph() {
CyNetwork metaGraph = CyCore.networkFactory.createNetwork();
metaGraph.getRow(metaGraph).set(CyNetwork.NAME, LocalizationManager.get("metaGraph"));
metaGraph.getDefaultNodeTable().createColumn("clusterSize", Integer.class, false);
metaGraph.getDefaultEdgeTable().createColumn("edgeStrength", Integer.class, false);
CyLayoutAlgorithm layout = CyCore.layoutAlgorithmManager.getDefaultLayout();
//Map Cluster to Nodes for further reference
HashMap<YoshikoCluster,CyNode> map = new HashMap<YoshikoCluster,CyNode>();
//Add nodes
for (YoshikoCluster c: cluster) {
VisualStyle vs= CyCore.visualStyleFactory.createVisualStyle(CyCore.visualMappingManager.getCurrentVisualStyle());
CyNode clusterNode = metaGraph.addNode();
CySubNetwork subnet = c.getSubNetwork();
CyCore.networkManager.addNetwork(subnet);
......@@ -90,22 +87,22 @@ public class YoshikoSolution {
//layout cluster
CyCore.dialogTaskManager.execute(
layout.createTaskIterator(
subnetView,
layout.getDefaultLayoutContext(),
subnetView,
layout.getDefaultLayoutContext(),
CyLayoutAlgorithm.ALL_NODE_VIEWS,
null
)
);
CyCore.visualMappingManager.setVisualStyle(vs, subnetView);
vs.apply(subnetView);
subnetView.updateView();
StyleManager.style(subnetView,CyCore.visualMappingManager.getCurrentVisualStyle());
clusterNode.setNetworkPointer(subnet);
//Set node attributes
metaGraph.getRow(clusterNode).set("name", LocalizationManager.get("cluster")+" "+c.getID());
metaGraph.getRow(clusterNode).set("clusterSize",c.getSize());
metaGraph.getRow(clusterNode).set(StyleManager.CLUSTERSIZE_COLUMN_NAME,c.getSize());
map.put(c, clusterNode);
}
//Add edges (O(|C|^2*|V|^2) can maybe be improved? //TODO
for (YoshikoCluster c1:cluster) {
for (YoshikoCluster c2:cluster) {
......@@ -120,12 +117,12 @@ public class YoshikoSolution {
if (originalGraph.containsEdge(c1n, c2n) || originalGraph.containsEdge(c2n, c1n)) {
if (!metaGraph.containsEdge(map.get(c1), map.get(c2))){
CyEdge edge = metaGraph.addEdge(map.get(c1), map.get(c2), false);
metaGraph.getRow(edge).set("edgeStrength",1);
metaGraph.getRow(edge).set(StyleManager.EDGESTRENGTH_COLUMN_NAME,1);
}
else {
CyEdge edge = metaGraph.getConnectingEdgeList(map.get(c1), map.get(c2), Type.ANY).get(0);
metaGraph.getRow(edge).set("edgeStrength",
metaGraph.getRow(edge).get("edgeStrength", Integer.class)+1
metaGraph.getRow(edge).set(StyleManager.EDGESTRENGTH_COLUMN_NAME,
metaGraph.getRow(edge).get(StyleManager.EDGESTRENGTH_COLUMN_NAME, Integer.class)+1
);
}
}
......@@ -133,47 +130,28 @@ public class YoshikoSolution {
}
}
}
CyNetworkView view = CyCore.networkViewFactory.createNetworkView(metaGraph);
//layout solution
CyCore.dialogTaskManager.execute(
layout.createTaskIterator(
view,
layout.getDefaultLayoutContext(),
view,
layout.getDefaultLayoutContext(),
CyLayoutAlgorithm.ALL_NODE_VIEWS,
null
)
);
VisualStyle vs= CyCore.visualStyleFactory.createVisualStyle(CyCore.visualMappingManager.getCurrentVisualStyle());
CyCore.networkManager.addNetwork(metaGraph);
CyCore.networkViewManager.addNetworkView(
view
);
//define style for solution
ContinuousMapping<Integer, Double> contMap = (ContinuousMapping<Integer, Double>)CyCore.continuousMappingFactory.createVisualMappingFunction(
"clusterSize",
Integer.class,
BasicVisualLexicon.NODE_SIZE
);
ContinuousMapping<Integer, Double> contMapEdges = (ContinuousMapping<Integer, Double>)CyCore.continuousMappingFactory.createVisualMappingFunction(
"edgeStrength",
Integer.class,
BasicVisualLexicon.EDGE_WIDTH
);
//Apply visual style
CyCore.visualMappingManager.setVisualStyle(vs, view);
vs.addVisualMappingFunction(contMap);
vs.addVisualMappingFunction(contMapEdges);
vs.apply(view);
view.updateView();
StyleManager.styleWithMapping(view, CyCore.visualMappingManager.getCurrentVisualStyle());
CyCore.cy.setCurrentNetworkView(view);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment