Skip to content

Commit d0f3dad

Browse files
committed
Using a Task to filter nodes/edges in order to prevent the UI from being frozen.
1 parent ca62908 commit d0f3dad

File tree

3 files changed

+243
-124
lines changed

3 files changed

+243
-124
lines changed

EnrichmentMapPlugin/src/main/java/org/baderlab/csplugins/enrichmentmap/ApplicationModule.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.baderlab.csplugins.enrichmentmap.task.CreateEMNetworkTask;
1313
import org.baderlab.csplugins.enrichmentmap.task.CreateEMViewTask;
1414
import org.baderlab.csplugins.enrichmentmap.task.CreateEnrichmentMapTaskFactory;
15+
import org.baderlab.csplugins.enrichmentmap.task.FilterNodesEdgesTask;
1516
import org.baderlab.csplugins.enrichmentmap.task.RemoveSignatureDataSetsTask;
1617
import org.baderlab.csplugins.enrichmentmap.view.creation.EditDataSetPanel;
1718
import org.baderlab.csplugins.enrichmentmap.view.creation.ErrorMessageDialog;
@@ -79,6 +80,7 @@ protected void configure() {
7980
installFactory(CreateEMNetworkTask.Factory.class);
8081
installFactory(CreateEMViewTask.Factory.class);
8182
installFactory(ApplyEMStyleTask.Factory.class);
83+
installFactory(FilterNodesEdgesTask.Factory.class);
8284
installFactory(ClusterRankingOption.Factory.class);
8385
installFactory(HeatMapParentPanel.Factory.class);
8486
installFactory(HeatMapMainPanel.Factory.class);
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
package org.baderlab.csplugins.enrichmentmap.task;
2+
3+
import static org.baderlab.csplugins.enrichmentmap.style.EMStyleBuilder.FILTERED_OUT_EDGE_TRANSPARENCY;
4+
import static org.baderlab.csplugins.enrichmentmap.style.EMStyleBuilder.FILTERED_OUT_NODE_TRANSPARENCY;
5+
import static org.cytoscape.view.presentation.property.BasicVisualLexicon.EDGE_LABEL_TRANSPARENCY;
6+
import static org.cytoscape.view.presentation.property.BasicVisualLexicon.EDGE_TRANSPARENCY;
7+
import static org.cytoscape.view.presentation.property.BasicVisualLexicon.EDGE_VISIBLE;
8+
import static org.cytoscape.view.presentation.property.BasicVisualLexicon.NODE_BORDER_TRANSPARENCY;
9+
import static org.cytoscape.view.presentation.property.BasicVisualLexicon.NODE_LABEL_TRANSPARENCY;
10+
import static org.cytoscape.view.presentation.property.BasicVisualLexicon.NODE_TRANSPARENCY;
11+
import static org.cytoscape.view.presentation.property.BasicVisualLexicon.NODE_VISIBLE;
12+
13+
import java.util.List;
14+
import java.util.Set;
15+
16+
import org.baderlab.csplugins.enrichmentmap.style.NullCustomGraphics;
17+
import org.cytoscape.model.CyEdge;
18+
import org.cytoscape.model.CyNetwork;
19+
import org.cytoscape.model.CyNode;
20+
import org.cytoscape.view.model.CyNetworkView;
21+
import org.cytoscape.view.model.View;
22+
import org.cytoscape.view.model.VisualLexicon;
23+
import org.cytoscape.view.model.VisualProperty;
24+
import org.cytoscape.view.presentation.RenderingEngineManager;
25+
import org.cytoscape.work.AbstractTask;
26+
import org.cytoscape.work.TaskMonitor;
27+
28+
import com.google.inject.Inject;
29+
import com.google.inject.assistedinject.Assisted;
30+
31+
public class FilterNodesEdgesTask extends AbstractTask {
32+
33+
public enum FilterMode {
34+
HIDE("Hide filtered out nodes and edges"),
35+
HIGHLIGHT("Highlight filtered nodes and edges"),
36+
SELECT("Select filtered nodes and edges");
37+
38+
private final String label;
39+
40+
private FilterMode(String label) {
41+
this.label = label;
42+
}
43+
44+
@Override
45+
public String toString() {
46+
return label;
47+
}
48+
}
49+
50+
@Inject private RenderingEngineManager renderingEngineManager;
51+
52+
private final CyNetworkView networkView;
53+
private final Set<CyNode> nodes;
54+
private final Set<CyEdge> edges;
55+
private final FilterMode filterMode;
56+
57+
public interface Factory {
58+
FilterNodesEdgesTask create(CyNetworkView networkView, Set<CyNode> nodes, Set<CyEdge> filteredEdges,
59+
FilterMode filterMode);
60+
}
61+
62+
@Inject
63+
public FilterNodesEdgesTask(@Assisted CyNetworkView networkView, @Assisted Set<CyNode> nodes,
64+
@Assisted Set<CyEdge> edges, @Assisted FilterMode filterMode) {
65+
this.networkView = networkView;
66+
this.nodes = nodes;
67+
this.edges = edges;
68+
this.filterMode = filterMode;
69+
}
70+
71+
@Override
72+
public void run(TaskMonitor taskMonitor) {
73+
taskMonitor.setTitle("Filtering Nodes and Edges");
74+
75+
taskMonitor.setStatusMessage("Filtering nodes...");
76+
taskMonitor.setProgress(0.0);
77+
78+
filterNodes(nodes, taskMonitor);
79+
80+
if (cancelled)
81+
return;
82+
83+
taskMonitor.setStatusMessage("Filtering edges...");
84+
taskMonitor.setProgress(0.2);
85+
86+
filterEdges(nodes, edges, taskMonitor, 0.2);
87+
taskMonitor.setProgress(1.0);
88+
}
89+
90+
private void filterNodes(Set<CyNode> nodes, TaskMonitor taskMonitor) {
91+
CyNetwork net = networkView.getModel();
92+
93+
for (CyNode n : net.getNodeList()) {
94+
if (cancelled)
95+
return;
96+
97+
final View<CyNode> nv = networkView.getNodeView(n);
98+
99+
if (nv == null)
100+
continue; // Should never happen!
101+
102+
boolean filteredIn = nodes.contains(n);
103+
104+
VisualLexicon lexicon = renderingEngineManager.getDefaultVisualLexicon();
105+
VisualProperty<?> customGraphics1 = lexicon.lookup(CyNode.class, "NODE_CUSTOMGRAPHICS_1");
106+
107+
// Don't forget to remove all previous locked values first!
108+
nv.clearValueLock(NODE_VISIBLE);
109+
nv.clearValueLock(NODE_TRANSPARENCY);
110+
nv.clearValueLock(NODE_BORDER_TRANSPARENCY);
111+
nv.clearValueLock(NODE_LABEL_TRANSPARENCY);
112+
113+
if (customGraphics1 != null)
114+
nv.clearValueLock(customGraphics1);
115+
116+
if (filteredIn) {
117+
if (filterMode == FilterMode.SELECT)
118+
net.getRow(n).set(CyNetwork.SELECTED, true);
119+
} else {
120+
switch (filterMode) {
121+
case HIDE:
122+
net.getRow(n).set(CyNetwork.SELECTED, false);
123+
nv.setLockedValue(NODE_VISIBLE, false);
124+
break;
125+
case HIGHLIGHT:
126+
nv.setLockedValue(NODE_TRANSPARENCY, FILTERED_OUT_NODE_TRANSPARENCY);
127+
nv.setLockedValue(NODE_BORDER_TRANSPARENCY, FILTERED_OUT_NODE_TRANSPARENCY);
128+
nv.setLockedValue(NODE_LABEL_TRANSPARENCY, 0);
129+
if (customGraphics1 != null)
130+
nv.setLockedValue(customGraphics1, NullCustomGraphics.getNullObject());
131+
break;
132+
case SELECT:
133+
net.getRow(n).set(CyNetwork.SELECTED, false);
134+
break;
135+
}
136+
}
137+
}
138+
}
139+
140+
private void filterEdges(Set<CyNode> nodes, Set<CyEdge> edges, TaskMonitor taskMonitor, double initialProgress) {
141+
CyNetwork net = networkView.getModel();
142+
List<CyEdge> edgeList = net.getEdgeList();
143+
int total = edgeList.size();
144+
int count = 0;
145+
float progress = (float) initialProgress;
146+
147+
for (CyEdge e : edgeList) {
148+
if (cancelled)
149+
return;
150+
151+
final View<CyEdge> ev = networkView.getEdgeView(e);
152+
153+
if (ev == null)
154+
continue; // Should never happen!
155+
156+
boolean filteredIn = edges.contains(e) && nodes.contains(e.getSource()) && nodes.contains(e.getTarget());
157+
158+
// Don't forget to remove all locked values first!
159+
ev.clearValueLock(EDGE_VISIBLE);
160+
ev.clearValueLock(EDGE_TRANSPARENCY);
161+
ev.clearValueLock(EDGE_LABEL_TRANSPARENCY);
162+
163+
if (filteredIn) {
164+
if (filterMode == FilterMode.SELECT)
165+
net.getRow(e).set(CyNetwork.SELECTED, true);
166+
} else {
167+
switch (filterMode) {
168+
case HIDE:
169+
net.getRow(e).set(CyNetwork.SELECTED, false);
170+
ev.setLockedValue(EDGE_VISIBLE, false);
171+
break;
172+
case HIGHLIGHT:
173+
ev.setLockedValue(EDGE_TRANSPARENCY, FILTERED_OUT_EDGE_TRANSPARENCY);
174+
ev.setLockedValue(EDGE_LABEL_TRANSPARENCY, FILTERED_OUT_EDGE_TRANSPARENCY);
175+
break;
176+
case SELECT:
177+
net.getRow(e).set(CyNetwork.SELECTED, false);
178+
break;
179+
}
180+
}
181+
182+
// Use only 2 decimals to avoid too many UI updates when setting very small numbers
183+
float newProgress = Math.round((initialProgress + count * (1 - initialProgress) / total) * 100) / 100.0f;
184+
185+
if (newProgress != progress) {
186+
taskMonitor.setProgress(newProgress);
187+
progress = newProgress;
188+
}
189+
190+
count++;
191+
}
192+
}
193+
}

0 commit comments

Comments
 (0)