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:
tom 2020-05-15 07:57:25 -04:00
parent 1afb87f6e3
commit 5575cce937
7 changed files with 43 additions and 25 deletions

View file

@ -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

View file

@ -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')

View file

@ -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();

View file

@ -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);

View file

@ -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();
}
}
}

View file

@ -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

View file

@ -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