All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.automatalib.visualization.jung.JungGraphVisualizationProvider Maven / Gradle / Ivy

There is a newer version: 0.11.0
Show newest version
/* 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;
	}

	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy