net.automatalib.visualization.jung.JungGraphVisualizationProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of automata-jung-visualizer Show documentation
Show all versions of automata-jung-visualizer Show documentation
Visualizer using the Java Utility for Networks and Graphs
/* Copyright (C) 2015 TU Dortmund
* This file is part of AutomataLib, http://www.automatalib.net/.
*
* AutomataLib is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 3.0 as published by the Free Software Foundation.
*
* AutomataLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with AutomataLib; if not, see
* http://www.gnu.de/documents/lgpl.en.html.
*/
package net.automatalib.visualization.jung;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JDialog;
import javax.swing.JFrame;
import net.automatalib.commons.util.mappings.MutableMapping;
import net.automatalib.graphs.Graph;
import net.automatalib.graphs.concepts.NodeIDs;
import net.automatalib.graphs.dot.GraphDOTHelper;
import net.automatalib.graphs.dot.GraphDOTHelper.EdgeAttrs;
import net.automatalib.graphs.dot.GraphDOTHelper.NodeAttrs;
import net.automatalib.visualization.VisualizationProvider;
import org.apache.commons.collections15.Transformer;
import com.github.misberner.graphvizawtshapes.ShapeLibrary;
import edu.uci.ics.jung.algorithms.layout.KKLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.DirectedGraph;
import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
import edu.uci.ics.jung.visualization.RenderContext;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;
import edu.uci.ics.jung.visualization.control.PickingGraphMousePlugin;
import edu.uci.ics.jung.visualization.control.PluggableGraphMouse;
import edu.uci.ics.jung.visualization.control.ScalingGraphMousePlugin;
import edu.uci.ics.jung.visualization.control.TranslatingGraphMousePlugin;
public class JungGraphVisualizationProvider implements VisualizationProvider {
public static final class NodeVisualization {
public static final Transformer LABEL
= new Transformer() {
@Override
public String transform(NodeVisualization input) {
return input.label;
}
};
public static final Transformer DRAW_COLOR
= new Transformer() {
@Override
public Paint transform(NodeVisualization input) {
return input.color;
}
};
public static final Transformer FILL_COLOR
= new Transformer() {
@Override
public Paint transform(NodeVisualization input) {
return input.fillColor;
}
};
public static final Transformer SHAPE
= new Transformer() {
@Override
public Shape transform(NodeVisualization input) {
return input.shape;
}
};
public static final Transformer STROKE
= new Transformer() {
@Override
public Stroke transform(NodeVisualization input) {
return input.stroke;
}
};
public final String label;
public final Color color;
public final Color fillColor;
public final Shape shape;
public final Stroke stroke;
public NodeVisualization(String label, Color drawColor, Color fillColor, Shape shape, Stroke stroke) {
this.label = label;
this.color = drawColor;
this.fillColor = fillColor;
this.shape = shape;
this.stroke = stroke;
}
}
public static final class EdgeVisualization {
public static final Transformer LABEL
= new Transformer() {
@Override
public String transform(EdgeVisualization input) {
return input.label;
}
};
public static final Transformer DRAW_COLOR
= new Transformer() {
@Override
public Paint transform(EdgeVisualization input) {
return input.drawColor;
}
};
public final String label;
public final Color drawColor;
public EdgeVisualization(String label, Color drawColor) {
this.label = label;
this.drawColor = drawColor;
}
}
protected static NodeVisualization createNodeVisualization(Map props, int id) {
String label = props.get(NodeAttrs.LABEL);
if(label == null) {
label = "v" + id;
}
Color drawColor = getColor(props, "color", Color.BLACK);
Color fillColor = getColor(props, "fillcolor", Color.WHITE);
String shapeName = props.get(NodeAttrs.SHAPE);
if(shapeName == null) {
shapeName = "circle";
}
ShapeLibrary shapeLib = ShapeLibrary.getInstance();
Shape shape = shapeLib.createShape(shapeName);
if(shape == null) {
System.err.println("Could not create shape " + shapeName);
shape = shapeLib.createShape("circle");
}
String[] styles = {};
String styleAttr = props.get("style");
if(styleAttr != null) {
styles = styleAttr.toLowerCase().split(",");
}
List styleList = Arrays.asList(styles);
float penWidth = 1.0f;
Stroke stroke;
if(styleList.contains("bold")) {
penWidth = 3.0f;
}
if(styleList.contains("dashed")) {
float[] dash = {10.0f};
stroke = new BasicStroke(penWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f);
}
else if(styleList.contains("dotted")) {
float[] dash = {penWidth, penWidth + 7.0f};
stroke = new BasicStroke(penWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f);
}
else {
stroke = new BasicStroke(penWidth);
}
return new NodeVisualization(label, drawColor, fillColor, shape, stroke);
}
protected static EdgeVisualization createEdgeVisualization(Map props) {
String label = props.get(EdgeAttrs.LABEL);
if(label == null) {
label = "";
}
Color drawColor = getColor(props, "color", Color.BLACK);
return new EdgeVisualization(label, drawColor);
}
protected static Color getColor(Map props, String propName, Color defColor) {
String colName = props.get(propName);
if(colName == null) {
return defColor;
}
Color col = Color.getColor(colName);
if(col == null) {
return defColor;
}
return col;
}
public static DirectedGraph createVisualizationGraph(
Graph graph, GraphDOTHelper helper) {
Map defaultProps = new HashMap<>();
helper.getGlobalNodeProperties(defaultProps);
DirectedGraph jungGraph
= new DirectedSparseMultigraph<>();
MutableMapping mapping = graph.createStaticNodeMapping();
NodeIDs nodeIds = graph.nodeIDs();
for(N node : graph) {
int id = nodeIds.getNodeId(node);
Map props = new HashMap<>(defaultProps);
helper.getNodeProperties(node, props);
NodeVisualization vis = createNodeVisualization(props, id);
mapping.put(node, vis);
}
defaultProps = new HashMap<>();
helper.getGlobalEdgeProperties(defaultProps);
for(N node : graph) {
NodeVisualization srcVis = mapping.get(node);
for(E edge : graph.getOutgoingEdges(node)) {
N target = graph.getTarget(edge);
NodeVisualization tgtVis = mapping.get(target);
Map props = new HashMap<>(defaultProps);
helper.getEdgeProperties(node, edge, target, props);
EdgeVisualization edgeVis = createEdgeVisualization(props);
jungGraph.addEdge(edgeVis, srcVis, tgtVis);
}
}
return jungGraph;
}
private final PluggableGraphMouse mouse;
public JungGraphVisualizationProvider() {
mouse = new PluggableGraphMouse();
mouse.add(new PickingGraphMousePlugin<>());
mouse.add(new TranslatingGraphMousePlugin(MouseEvent.BUTTON3_MASK));
mouse.add(new ScalingGraphMousePlugin(new CrossoverScalingControl(), 0,
1 / 1.1f, 1.1f));
}
public static void setupRenderContext(RenderContext ctx) {
ctx.setVertexLabelTransformer(NodeVisualization.LABEL);
ctx.setVertexDrawPaintTransformer(NodeVisualization.DRAW_COLOR);
ctx.setVertexFillPaintTransformer(NodeVisualization.FILL_COLOR);
ctx.setVertexShapeTransformer(NodeVisualization.SHAPE);
ctx.setVertexStrokeTransformer(NodeVisualization.STROKE);
ctx.setEdgeLabelTransformer(EdgeVisualization.LABEL);
ctx.setEdgeDrawPaintTransformer(EdgeVisualization.DRAW_COLOR);
}
@Override
public void visualize(Graph graph, GraphDOTHelper helper,
boolean modal, Map options) {
DirectedGraph visGraph
= createVisualizationGraph(graph, helper);
Layout layout
= new KKLayout<>(visGraph);
VisualizationViewer vv = new VisualizationViewer<>(layout);
setupRenderContext(vv.getRenderContext());
vv.setGraphMouse(mouse);
final JDialog frame = new JDialog((Dialog)null, "Visualization", modal);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(vv);
frame.pack();
frame.setVisible(true);
}
@Override
public int getPriority() {
return 0;
}
@Override
public String getId() {
return "jung";
}
@Override
public boolean checkUsable() {
return true;
}
}