mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 12:00:04 +02:00
updated jungrapht-visualization to 1.0-RC8. Includes fixes noted in functional review. Adds additional layering algorithms to mincross layout algorithm. Fix Module.manifest versions
This commit is contained in:
parent
1afb87f6e3
commit
5575cce937
7 changed files with 43 additions and 25 deletions
|
@ -1,7 +1,7 @@
|
|||
EXCLUDE FROM GHIDRA JAR: true
|
||||
|
||||
MODULE FILE LICENSE: lib/jungrapht-visualization-2.11.20 BSD
|
||||
MODULE FILE LICENSE: lib/jgrapht-core-1.3.1.jar LGPL 2.1
|
||||
MODULE FILE LICENSE: lib/jgrapht-io-1.3.1.jar LGPL 2.1
|
||||
MODULE FILE LICENSE: lib/jungrapht-visualization-1.0-RC8 BSD
|
||||
MODULE FILE LICENSE: lib/jgrapht-core-1.4.0.jar LGPL 2.1
|
||||
MODULE FILE LICENSE: lib/jgrapht-io-1.4.0.jar LGPL 2.1
|
||||
MODULE FILE LICENSE: lib/jheaps-0.10.jar Apache License 2.0
|
||||
MODULE FILE LICENSE: lib/slf4j-api-1.7.25.jar MIT
|
||||
|
|
|
@ -11,12 +11,13 @@ eclipse.project.name = 'Features Graph Services'
|
|||
dependencies {
|
||||
compile project(":Base")
|
||||
|
||||
compile "com.github.tomnelson:jungrapht-visualization:1.0-RC7"
|
||||
compile "com.github.tomnelson:jungrapht-visualization:1.0-RC8"
|
||||
compile "org.jgrapht:jgrapht-core:1.4.0"
|
||||
|
||||
// not using jgrapht-io code that depends on antlr, so exclude antlr
|
||||
compile ("org.jgrapht:jgrapht-io:1.4.0") { exclude group: "org.antlr", module: "antlr4-runtime" }
|
||||
runtime "org.slf4j:slf4j-api:1.7.25"
|
||||
runtime "org.slf4j:slf4j-nop:1.7.25"
|
||||
runtime "org.jheaps:jheaps:0.11"
|
||||
|
||||
helpPath project(path: ":Base", configuration: 'helpPath')
|
||||
|
|
|
@ -229,7 +229,7 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
|||
.toolBarIcon(Icons.REFRESH_ICON)
|
||||
.onAction(context -> {
|
||||
viewer.reset();
|
||||
viewer.scaleToLayout();
|
||||
viewer.scaleToLayout(true);
|
||||
})
|
||||
.buildAndInstallLocal(componentProvider);
|
||||
|
||||
|
@ -345,17 +345,13 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
|||
Collection<AttributedVertex> selectedVertices = getVertices(e.getItem());
|
||||
List<String> selectedVertexIds = toVertexIds(selectedVertices);
|
||||
notifySelectionChanged(selectedVertexIds);
|
||||
multiSelectedVertexPaintable.setSelectedVertices(selectedVertices);
|
||||
|
||||
AttributedVertex vertex = CollectionUtils.any(selectedVertices);
|
||||
if (vertex != null) {
|
||||
singleSelectedVertexPaintable.setSelectedVertex(vertex);
|
||||
notifyLocationChanged(vertex.getId());
|
||||
}
|
||||
}
|
||||
else if (e.getStateChange() == ItemEvent.DESELECTED) {
|
||||
singleSelectedVertexPaintable.setSelectedVertex(null);
|
||||
multiSelectedVertexPaintable.setSelectedVertices(Collections.emptySet());
|
||||
notifySelectionChanged(Collections.emptyList());
|
||||
}
|
||||
viewer.repaint();
|
||||
|
@ -399,7 +395,6 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
|||
else if (!Arrays.asList(nodeSelectedState.getSelectedObjects()).containsAll(selected)) {
|
||||
nodeSelectedState.clear();
|
||||
nodeSelectedState.select(selected, false);
|
||||
multiSelectedVertexPaintable.setSelectedVertices(selected);
|
||||
scrollToSelected(selected);
|
||||
}
|
||||
viewer.repaint();
|
||||
|
@ -418,7 +413,6 @@ public class DefaultGraphDisplay implements GraphDisplay {
|
|||
Optional<AttributedVertex> selected =
|
||||
graph.vertexSet().stream().filter(v -> vertexID.equals(v.getId())).findFirst();
|
||||
log.fine("picking address:" + vertexID + " returned " + selected);
|
||||
singleSelectedVertexPaintable.setSelectedVertex(selected.orElse(null));
|
||||
viewer.repaint();
|
||||
selected.ifPresent(this::scrollToSelected);
|
||||
viewer.repaint();
|
||||
|
|
|
@ -31,7 +31,8 @@ import ghidra.service.graph.AttributedVertex;
|
|||
public class GhidraIconCache {
|
||||
|
||||
private static final int DEFAULT_STROKE_THICKNESS = 8;
|
||||
private static final int DEFAULT_FONT_SIZE = 20;
|
||||
private static final int DEFAULT_FONT_SIZE = 12;
|
||||
private static final String DEFAULT_FONT_NAME = "Dialog";
|
||||
private static final int DEFAULT_MARGIN_BORDER_SIZE = 4;
|
||||
private static final float LABEL_TO_ICON_PROPORTION_WAG = 1.4f;
|
||||
private static final double SQRT_2 = Math.sqrt(2.0);
|
||||
|
@ -64,7 +65,7 @@ public class GhidraIconCache {
|
|||
private Icon createIcon(AttributedVertex vertex) {
|
||||
rendererLabel.setText(ProgramGraphFunctions.getLabel(vertex));
|
||||
|
||||
rendererLabel.setFont(new Font("Serif", Font.BOLD, DEFAULT_FONT_SIZE));
|
||||
rendererLabel.setFont(new Font(DEFAULT_FONT_NAME, Font.BOLD, DEFAULT_FONT_SIZE));
|
||||
rendererLabel.setForeground(Color.black);
|
||||
rendererLabel.setBackground(Color.white);
|
||||
rendererLabel.setOpaque(true);
|
||||
|
|
|
@ -15,7 +15,11 @@
|
|||
*/
|
||||
package ghidra.graph.visualization;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.jungrapht.visualization.layout.algorithms.*;
|
||||
import org.jungrapht.visualization.layout.algorithms.sugiyama.Layering;
|
||||
|
||||
import org.jungrapht.visualization.layout.algorithms.repulsion.BarnesHutFRRepulsion;
|
||||
|
||||
import ghidra.service.graph.AttributedEdge;
|
||||
|
@ -28,24 +32,30 @@ import ghidra.service.graph.AttributedVertex;
|
|||
* This class provides LayoutAlgorithm builders instead of LayoutAlgorithms because some LayoutAlgorithms
|
||||
* accumulate state information (so are used only one time).
|
||||
*/
|
||||
class LayoutFunction {
|
||||
class LayoutFunction
|
||||
implements Function<String, LayoutAlgorithm.Builder<AttributedVertex, ?, ?>> {
|
||||
|
||||
static final String KAMADA_KAWAI = "Force Balanced";
|
||||
static final String FRUCTERMAN_REINGOLD = "Force Directed";
|
||||
static final String CIRCLE_MINCROSS = "Circle";
|
||||
static final String TIDIER_TREE = "Compact Hierarchical";
|
||||
static final String MIN_CROSS = "Hierarchical Min Cross";
|
||||
static final String MIN_CROSS_TOP_DOWN = "Hierarchical MinCross Top Down";
|
||||
static final String MIN_CROSS_LONGEST_PATH = "Hierarchical MinCross Longest Path";
|
||||
static final String MIN_CROSS_NETWORK_SIMPLEX = "Hierarchical MinCross Network Simplex";
|
||||
static final String MIN_CROSS_COFFMAN_GRAHAM = "Hierarchical MinCross Coffman Graham";
|
||||
static final String MULTI_ROW_EDGE_AWARE_TREE = "Hierarchical MultiRow";
|
||||
static final String EDGE_AWARE_TREE = "Hierarchical";
|
||||
static final String EDGE_AWARE_RADIAL = "Radial";
|
||||
|
||||
public String[] getNames() {
|
||||
return new String[] { KAMADA_KAWAI, FRUCTERMAN_REINGOLD, CIRCLE_MINCROSS, TIDIER_TREE, MIN_CROSS,
|
||||
MULTI_ROW_EDGE_AWARE_TREE, EDGE_AWARE_TREE, EDGE_AWARE_RADIAL};
|
||||
return new String[] { EDGE_AWARE_TREE, MULTI_ROW_EDGE_AWARE_TREE, TIDIER_TREE,
|
||||
MIN_CROSS_TOP_DOWN, MIN_CROSS_LONGEST_PATH, MIN_CROSS_NETWORK_SIMPLEX,
|
||||
MIN_CROSS_COFFMAN_GRAHAM, CIRCLE_MINCROSS, KAMADA_KAWAI, FRUCTERMAN_REINGOLD,
|
||||
EDGE_AWARE_RADIAL };
|
||||
}
|
||||
|
||||
public LayoutAlgorithm.Builder<AttributedVertex, ?, ?> apply(
|
||||
String name) {
|
||||
@Override
|
||||
public LayoutAlgorithm.Builder<AttributedVertex, ?, ?> apply(String name) {
|
||||
switch(name) {
|
||||
case KAMADA_KAWAI:
|
||||
return KKLayoutAlgorithm.<AttributedVertex> builder().preRelaxDuration(1000);
|
||||
|
@ -54,14 +64,25 @@ class LayoutFunction {
|
|||
.repulsionContractBuilder(BarnesHutFRRepulsion.barnesHutBuilder());
|
||||
case CIRCLE_MINCROSS:
|
||||
return CircleLayoutAlgorithm.<AttributedVertex> builder()
|
||||
.threaded(true)
|
||||
.reduceEdgeCrossing(true);
|
||||
case TIDIER_TREE:
|
||||
return TidierTreeLayoutAlgorithm.<AttributedVertex, AttributedEdge> edgeAwareBuilder();
|
||||
case MIN_CROSS:
|
||||
case MIN_CROSS_TOP_DOWN:
|
||||
return HierarchicalMinCrossLayoutAlgorithm
|
||||
.<AttributedVertex, AttributedEdge> edgeAwareBuilder()
|
||||
.threaded(true);
|
||||
.layering(Layering.TOP_DOWN);
|
||||
case MIN_CROSS_LONGEST_PATH:
|
||||
return EiglspergerLayoutAlgorithm
|
||||
.<AttributedVertex, AttributedEdge> edgeAwareBuilder()
|
||||
.layering(Layering.LONGEST_PATH);
|
||||
case MIN_CROSS_NETWORK_SIMPLEX:
|
||||
return EiglspergerLayoutAlgorithm
|
||||
.<AttributedVertex, AttributedEdge> edgeAwareBuilder()
|
||||
.layering(Layering.NETWORK_SIMPLEX);
|
||||
case MIN_CROSS_COFFMAN_GRAHAM:
|
||||
return EiglspergerLayoutAlgorithm
|
||||
.<AttributedVertex, AttributedEdge> edgeAwareBuilder()
|
||||
.layering(Layering.COFFMAN_GRAHAM);
|
||||
case MULTI_ROW_EDGE_AWARE_TREE:
|
||||
return MultiRowEdgeAwareTreeLayoutAlgorithm
|
||||
.<AttributedVertex, AttributedEdge> edgeAwareBuilder();
|
||||
|
@ -71,7 +92,8 @@ class LayoutFunction {
|
|||
.verticalVertexSpacing(300);
|
||||
case EDGE_AWARE_TREE:
|
||||
default:
|
||||
return EdgeAwareTreeLayoutAlgorithm.<AttributedVertex, AttributedEdge> edgeAwareBuilder();
|
||||
return EdgeAwareTreeLayoutAlgorithm
|
||||
.<AttributedVertex, AttributedEdge> edgeAwareBuilder();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class LayoutTransitionManager {
|
|||
/**
|
||||
* a {@link Comparator} to sort edges during layout graph traversal
|
||||
*/
|
||||
Comparator<AttributedEdge> edgeComparator;
|
||||
Comparator<AttributedEdge> edgeComparator = (e1, e2) -> 0;
|
||||
|
||||
/**
|
||||
* a {@link MultiActionDockingAction} to allow the user to select a layout algorithm
|
||||
|
|
|
@ -27,7 +27,7 @@ jungrapht.edgeWidth=4.0f
|
|||
# stroke size for the magnifier lens
|
||||
jungrapht.lensStrokeWidth=10.0
|
||||
# when scale is < .3, switch to lightweight rendering
|
||||
jungrapht.lightweightScaleThreshold=.3
|
||||
jungrapht.lightweightScaleThreshold=.8
|
||||
# under 50 vertices will use heavyweight rendering all the time
|
||||
jungrapht.lightweightCountThreshold=50
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue