mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-10-01 17:11:44 -09:00
added post process function for vertex overlap in tree layouts that are used with graphs that are not trees.
This commit is contained in:
@@ -106,6 +106,8 @@ class LayoutTransitionManager {
|
||||
}
|
||||
if (layoutAlgorithm instanceof TreeLayout) {
|
||||
((TreeLayout<AttributedVertex>) layoutAlgorithm).setRootPredicate(rootPredicate);
|
||||
layoutAlgorithm.setAfter(new PostProcessRunnable<>(
|
||||
visualizationServer.getVisualizationModel().getLayoutModel()));
|
||||
}
|
||||
// remove any previously added layout paintables
|
||||
removePaintable(radialLayoutRings);
|
||||
@@ -127,7 +129,9 @@ class LayoutTransitionManager {
|
||||
if (layoutAlgorithm instanceof EdgeSorting) {
|
||||
((EdgeSorting<AttributedEdge>) layoutAlgorithm).setEdgeComparator(edgeComparator);
|
||||
}
|
||||
LayoutAlgorithmTransition.apply(visualizationServer, layoutAlgorithm);
|
||||
LayoutAlgorithmTransition.apply(visualizationServer,
|
||||
layoutAlgorithm,
|
||||
new PostProcessRunnable<>(visualizationServer.getVisualizationModel().getLayoutModel()));
|
||||
}
|
||||
|
||||
private void removePaintable(VisualizationServer.Paintable paintable) {
|
||||
@@ -146,6 +150,9 @@ class LayoutTransitionManager {
|
||||
.setRootPredicate(rootPredicate);
|
||||
((TreeLayout<AttributedVertex>) initialLayoutAlgorithm)
|
||||
.setVertexBoundsFunction(vertexBoundsFunction);
|
||||
initialLayoutAlgorithm.setAfter(new PostProcessRunnable<>(
|
||||
visualizationServer.getVisualizationModel().getLayoutModel()));
|
||||
|
||||
}
|
||||
if (initialLayoutAlgorithm instanceof EdgeSorting) {
|
||||
((EdgeSorting<AttributedEdge>) initialLayoutAlgorithm)
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.graph.visualization;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.jgrapht.Graph;
|
||||
import org.jungrapht.visualization.layout.model.LayoutModel;
|
||||
|
||||
/**
|
||||
* to post-process tree layouts to move vertices that overlap a vertical edge that
|
||||
* is not incident on the vertex.
|
||||
* This can be removed after jungrapht-layout-1.1
|
||||
* @param <V> vertex type
|
||||
* @param <E> edge type
|
||||
*/
|
||||
public class PostProcessRunnable<V, E> implements Runnable {
|
||||
|
||||
LayoutModel<V> layoutModel;
|
||||
|
||||
public PostProcessRunnable(LayoutModel<V> layoutModel) {
|
||||
this.layoutModel = layoutModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
moveVerticesThatOverlapVerticalEdges(layoutModel);
|
||||
}
|
||||
|
||||
protected int moveVerticesThatOverlapVerticalEdges(LayoutModel<V> layoutModel) {
|
||||
int offset = 100;
|
||||
int moved = 0;
|
||||
Graph<V, E> graph = layoutModel.getGraph();
|
||||
Map<Double, Set<E>> verticalEdgeMap = new LinkedHashMap<>();
|
||||
graph.edgeSet()
|
||||
.stream()
|
||||
.filter(e -> layoutModel.apply(graph.getEdgeSource(e)).x == layoutModel
|
||||
.apply(graph.getEdgeTarget(e)).x)
|
||||
.forEach(e -> verticalEdgeMap
|
||||
.computeIfAbsent(layoutModel.apply(graph.getEdgeSource(e)).x,
|
||||
k -> new HashSet<>())
|
||||
.add(e));
|
||||
|
||||
for (V v : graph.vertexSet()) {
|
||||
double x = layoutModel.apply(v).x;
|
||||
for (E edge : verticalEdgeMap.getOrDefault(x, Collections.emptySet())) {
|
||||
V source = graph.getEdgeSource(edge);
|
||||
V target = graph.getEdgeTarget(edge);
|
||||
if (!v.equals(source) && !v.equals(target)) {
|
||||
double lowy = layoutModel.apply(source).y;
|
||||
double hiy = layoutModel.apply(target).y;
|
||||
if (lowy > hiy) {
|
||||
double temp = lowy;
|
||||
lowy = hiy;
|
||||
hiy = temp;
|
||||
}
|
||||
double vy = layoutModel.apply(v).y;
|
||||
if (lowy <= vy && vy <= hiy) {
|
||||
layoutModel.set(v, layoutModel.apply(v).add(offset, 0));
|
||||
moved++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return moved;
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ jungrapht.circle.reduceEdgeCrossingMaxEdges=200
|
||||
jungrapht.initialDimensionVertexDensity=0.3f
|
||||
|
||||
jungrapht.minScale=0.001
|
||||
jungrapht.maxScale=1.0
|
||||
jungrapht.maxScale=4.0
|
||||
|
||||
# not using spatial data structures for vertices at this time. May remove after jungrapht 1.1
|
||||
jungrapht.vertexSpatialSupport=NONE
|
||||
|
||||
Reference in New Issue
Block a user