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

net.sf.gluebooster.java.booster.basic.math.graph.JungGraphBoostUtils Maven / Gradle / Ivy

Go to download

Basic classes to support the development of applications. There should be as few dependencies on other frameworks as possible.

The newest version!
package net.sf.gluebooster.java.booster.basic.math.graph;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Paint;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.rmi.server.UID;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

import javax.swing.JFrame;

import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.lang3.tuple.Pair;

import edu.uci.ics.jung.algorithms.layout.FRLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.UndirectedGraph;
import edu.uci.ics.jung.graph.UndirectedSparseGraph;
import edu.uci.ics.jung.visualization.BasicVisualizationServer;
import net.sf.gluebooster.java.booster.basic.container.BoostedNode;
import net.sf.gluebooster.java.booster.basic.container.BoostedNodeUtils;
import net.sf.gluebooster.java.booster.basic.container.Tuple;
import net.sf.gluebooster.java.booster.basic.gui.swing.SwingBoostUtils;
import net.sf.gluebooster.java.booster.basic.math.GeometryBoostUtils;
import net.sf.gluebooster.java.booster.basic.transformation.CallableDelegate;
import net.sf.gluebooster.java.booster.essentials.eventsCommands.Callable;
import net.sf.gluebooster.java.booster.essentials.eventsCommands.CallableAbstraction;
import net.sf.gluebooster.java.booster.essentials.meta.objects.DisplayConfiguration;
import net.sf.gluebooster.java.booster.essentials.utils.ThreadBoostUtils;

/**
 * Utilities for graph creation and display using the Jung framework.
 * 
 * @defaultParamText transformationGraph the inspected graph
 * 
 */
public class JungGraphBoostUtils {

	/**
	 * Create the default graph representation of a transformation graph. The
	 * default graph is a detailed graph including the IN- and OUT-nodes.
	 * 
	 * @param graph
	 *            the graph to represent
	 * @return the representation
	 */
	public static Graph createDefaultDirectedGraph(
			TransformationGraph graph) {
		DirectedSparseMultigraph result = new DirectedSparseMultigraph<>();

		Set nodes = BoostedNodeUtils.getAllNodesOfGraph(graph
				.getRootNode());

		int counter = 0;
		for (BoostedNode node : nodes) {
			result.addVertex(node);

			for (BoostedNode inPoint : node.getInPoints()) {
				result.addVertex(inPoint);
				result.addEdge("in-" + counter++, inPoint, node);
			}
			for (BoostedNode outPoint : node.getOutPoints()) {
				result.addVertex(outPoint);
				result.addEdge("out-" + counter++, node, outPoint);
			}
		}

		// add edges between nodes
		for (BoostedNode node : nodes) {
			for (BoostedNode outPoint : node.getOutPoints()) {
				for (BoostedNode inPoint : node.getSuccessorInPoints(outPoint))
					result.addEdge(new UID().toString(), outPoint, inPoint);
			}
			// out points are sufficient, otherwise all edges would be
			// duplicated
			// for (BoostedNode inPoint : node.getInPoints()) {
			// for (BoostedNode outPoint : node
			// .getPredecessorOutPoints(inPoint))
			// result.addEdge(new UID().toString(), outPoint, inPoint);
			// }
		}

		return result;
	}

	/**
	 * Create the default graph representation of a transformation graph. The
	 * default graph is an overview without the IN- and OUT-nodes.
	 * 
	 * @param graph
	 *            the graph to represent
	 * @return the representation
	 */
	public static Graph createOverviewDirectedGraph(
			TransformationGraph graph) {
		DirectedSparseMultigraph result = new DirectedSparseMultigraph<>();

		Set nodes = BoostedNodeUtils.getAllNodesOfGraph(graph
				.getRootNode());

		// add the nodes
		for (BoostedNode node : nodes) {
			result.addVertex(node);
		}

		// add edges between nodes
		for (BoostedNode node : nodes) {
			for (BoostedNode outPoint : node.getOutPoints()) {
				for (BoostedNode inPoint : node.getSuccessorInPoints(outPoint))
					result.addEdge(new UID().toString(), node, inPoint
							.getZoomOut(null).getKey());
			}
			// out points are sufficient, otherwise all edges would be
			// duplicated
		}

		return result;
	}
	
	/**
	 * Create a detailed graph representation including the IN- and OUT-nodes.
	 * 
	 * @return the created graph component
	 */
	public static Component createDefaultGraphComponent(
			final TransformationGraph transformationGraph) {
		Graph graph = JungGraphBoostUtils.createDefaultDirectedGraph(transformationGraph);
		Callable vertexFillPaintTransformer = new CallableAbstraction() {

			@Override
			protected Paint callImpl(BoostedNode... parameters) throws Exception {
				BoostedNode node = parameters[0];
				Pair objectFocus = node
						.getZoomOut(null);
				if (objectFocus == null || objectFocus.getLeft() == null)
					return Color.BLUE;// main node
				else {
					if (objectFocus.getLeft().getInPoints().contains(node))
						return Color.ORANGE;// In-Point
					else
						return Color.MAGENTA;// Out-Point
				}
			}
		};
		Callable vertexStringer = new CallableAbstraction() {
			@Override
			protected String callImpl(BoostedNode... parameters) {
				return transformationGraph.getShortState(parameters[0]);
			}
		};

		Layout layout = new FRLayout(
				graph);
		// Layout layout = new CircleLayout(
		// graph);
		layout.setSize(new Dimension(300, 300)); // sets the initial size of the
													// space
		// The BasicVisualizationServer is parameterized by the edge types
		BasicVisualizationServer vv = new BasicVisualizationServer(
				layout);
		vv.setPreferredSize(new Dimension(700, 700));
		vv.getRenderContext().setVertexFillPaintTransformer(new CallableDelegate(vertexFillPaintTransformer));
		vv.getRenderContext().setVertexLabelTransformer(new CallableDelegate(vertexStringer));
		
		return vv;
	}

	/**
	 * Create a graph representation without the IN- and OUT-nodes.
	 * 
	 * @return the created graph component
	 * 
	 */
	public static Component createOverviewGraphComponent(
			final TransformationGraph transformationGraph) {
		Graph graph = JungGraphBoostUtils
				.createOverviewDirectedGraph(transformationGraph);
		CallableAbstraction vertexFillPaintTransformer = new CallableAbstraction() {

			@Override
			protected Paint callImpl(BoostedNode... parameters) throws Exception {
				return Color.BLUE;
			}
		};
		CallableAbstraction vertexStringer = new CallableAbstraction() {

			@Override
			protected String callImpl(BoostedNode... parameters) throws Exception {
				return transformationGraph.getShortState(parameters[0]);
			}
		};

		Layout layout = new FRLayout(
				graph);
		// Layout layout = new CircleLayout(
		// graph);
		layout.setSize(new Dimension(300, 300)); // sets the initial size of the
													// space
		// The BasicVisualizationServer is parameterized by the edge types
		BasicVisualizationServer vv = new BasicVisualizationServer(
				layout);
		vv.setPreferredSize(new Dimension(700, 700));
		vv.getRenderContext().setVertexFillPaintTransformer(new CallableDelegate(vertexFillPaintTransformer));
		vv.getRenderContext().setVertexLabelTransformer(new CallableDelegate(vertexStringer));

		return vv;
	}

	/**
	 * Copies a graph.
	 * 
	 * @param graph
	 *            the original graph
	 * @return the graph with the Object-class as edges.
	 */
	public static  UndirectedGraph createGraphWithObjectEdges(
			UndirectedGraph graph) {
		UndirectedSparseGraph result = new UndirectedSparseGraph();
		for (Vertex vertex : graph.getVertices()) {
			result.addVertex(vertex);
		}
	
		for (Edge edge : graph.getEdges()) {
			result.addEdge(edge, graph.getEndpoints(edge));
		}
	
		return result;
	}

	/**
	 * Creates an undirected graph with given vertices and edges
	 * 
	 * @param vertices
	 *            the vertices of the graph
	 * @param edges
	 *            the edges of the graph
	 * @return the created graph
	 */
	public static  UndirectedSparseGraph createUndirectedGraph(
			Collection vertices, MultiValuedMap edges) {
		UndirectedSparseGraph result = new UndirectedSparseGraph<>();
		for (Vertex vertex : vertices) {
			result.addVertex(vertex);
		}
	
		int counter = 0;
		for (Entry> edge : edges.asMap().entrySet()) {
			Vertex start = edge.getKey();
			for (Vertex end : edge.getValue()) {
				result.addEdge("edge" + counter++, start, end);
			}
		}
	
		return result;
	}

	/**
	 * Changes a (directed) graph into an undirected graph.
	 * 
	 * @param graph
	 *            the template
	 * @return the created graph
	 */
	public static  UndirectedSparseGraph createUndirectedGraph(
			Graph graph) {
		UndirectedSparseGraph undirectedGraph = new UndirectedSparseGraph();
		for (Vertex vertex : graph.getVertices()) {
			undirectedGraph.addVertex(vertex);
		}
	
		for (Edge edge : graph.getEdges()) {
			undirectedGraph.addEdge(edge, graph.getEndpoints(edge));
		}
	
		return undirectedGraph;
	}

	/*
	 * public static void removeDuplicateEdges(BoostedNode node){
	 * HashSet successors = new HashSet(); for
	 * (BoostedNode out : node.getOutPoints()) { for (BoostedNode in :
	 * node.getSuccessorInPoints(out)) { BoostedNode succ =
	 * in.getZoomOut(null).getLeft(); if(successors.contains(succ)){
	 * Refactor.removeEdge(node, out, in, succ); } else { successors.add(succ);
	 * } } }
	 * 
	 * HashSet predecessors = new HashSet(); for
	 * (BoostedNode in : node.getInPoints()) { for (BoostedNode out :
	 * node.getPredecessorOutPoints(in)) { BoostedNode pre =
	 * out.getZoomOut(null).getLeft(); if (predecessors.contains(pre)){
	 * Refactor.removeEdge(pre, out, in, node); } else { predecessors.add(pre);
	 * } } }
	 * 
	 * }
	 */
	
	
	
	// TODO add the feature into the transformation graph,
	// that the values are not computed beginning at the source nodes, but are
	// computed on request of the sinks
	
	/**
	 * Displays a graph of shapes.
	 * 
	 * @param configuration
	 *            the configuration of the graph and display
	 */
	public static  void displayShapes(
			DisplayConfiguration> configuration
	) {
		String title = configuration.getTitle();
		Point framePosition = configuration.getFramePosition();
		Rectangle preferredSize = configuration.getPreferredSize();
		// some data manipulation, because the content may be an Object[]
		ArrayList> list = new ArrayList>();
		for (Object content : configuration.getContent()) {
			list.add((Graph) content);
		}
	
		Rectangle dim = GeometryBoostUtils.getGraphDimension((Collection) list);
		if (preferredSize == null) {
			preferredSize = dim;
		}
		if (framePosition == null) {
			framePosition = new Point(0, 0);
		}
	
		double xResizeFactor = 1;
		if (dim.width > preferredSize.width) {
			xResizeFactor = ((double) preferredSize.width) / dim.width;
		}
	
		double yResizeFactor = 1;
		if (dim.height > preferredSize.height) {
			yResizeFactor = ((double) preferredSize.height) / dim.height;
		}
	
		double xTranslate = 0;
		double minX = dim.x * xResizeFactor;
		if (minX != preferredSize.x) {
			xTranslate = preferredSize.x - minX;
		}
	
		double yTranslate = 0;
		double minY = dim.y * yResizeFactor;
		if (minY != preferredSize.y) {
			yTranslate = preferredSize.y - minY;
		}
	
		SwingBoostUtils guiFactory = new SwingBoostUtils();
		// add a margin to the dimension
		JFrame frame = guiFactory.createFrame(title, preferredSize.x
				+ preferredSize.width + 30, preferredSize.y
				+ preferredSize.height + 100,
				true, new BorderLayout());
		frame.setLocation(framePosition);
		Panel panel = new Panel();
		frame.getContentPane().add(panel, BorderLayout.CENTER);
		// frame.pack();
		// frame.setSize(400, 600);
		frame.setVisible(true);
		ThreadBoostUtils.sleep(3000);
	
		Color[] colors = { Color.BLACK, Color.RED, Color.BLUE, Color.CYAN,
				Color.GREEN, Color.MAGENTA, Color.ORANGE, Color.YELLOW };
		int index = 0;
	
		Graphics graphics = panel.getGraphics();
	
		for (Graph graph : list) {
			Color newColor = colors[index++ % colors.length];
			graphics.setColor(newColor);
			// panel.getGraphics().setPaintMode();
	
			for (Shape shape : graph.getVertices()) {
				Rectangle bounds = shape.getBounds();
				graphics.drawRect(
						scale(bounds.x, xResizeFactor, xTranslate),
						scale(bounds.y, yResizeFactor, yTranslate),
						scale(bounds.width, xResizeFactor, 0),
						scale(bounds.height, yResizeFactor, 0));
			}
	
			for (Edge edge : graph.getEdges()) {
				edu.uci.ics.jung.graph.util.Pair endpoints = graph
						.getEndpoints(edge);
				Rectangle point1 = endpoints.getFirst().getBounds();
				Rectangle point2 = endpoints.getSecond().getBounds();
				graphics.drawLine(
						scale(point1.x, xResizeFactor, xTranslate),
						scale(point1.y, yResizeFactor, yTranslate),
						scale(point2.x, xResizeFactor, xTranslate),
						scale(point2.y, yResizeFactor, yTranslate));
	
			}
		}
		ThreadBoostUtils.sleep(2000);
	}

	/**
	 * Copies a graph.
	 * 
	 * @param graph
	 *            the graph to copy
	 * @return the copy
	 */
	public static  Graph copy(Graph graph) {
		Graph result = new UndirectedSparseGraph();
		for (V vertex : graph.getVertices()) {
			result.addVertex(vertex);
		}
		for (E edge : graph.getEdges()) {
			edu.uci.ics.jung.graph.util.Pair endpoints = graph.getEndpoints(edge);
			result.addEdge(edge, endpoints.getFirst(), endpoints.getSecond());
		}
	
		return result;
	}

	/*
	 * public static void removeDuplicateEdges(BoostedNode node){
	 * HashSet successors = new HashSet(); for
	 * (BoostedNode out : node.getOutPoints()) { for (BoostedNode in :
	 * node.getSuccessorInPoints(out)) { BoostedNode succ =
	 * in.getZoomOut(null).getLeft(); if(successors.contains(succ)){
	 * Refactor.removeEdge(node, out, in, succ); } else { successors.add(succ);
	 * } } }
	 * 
	 * HashSet predecessors = new HashSet(); for
	 * (BoostedNode in : node.getInPoints()) { for (BoostedNode out :
	 * node.getPredecessorOutPoints(in)) { BoostedNode pre =
	 * out.getZoomOut(null).getLeft(); if (predecessors.contains(pre)){
	 * Refactor.removeEdge(pre, out, in, node); } else { predecessors.add(pre);
	 * } } }
	 * 
	 * }
	 */
	
	
	
	// TODO add the feature into the transformation graph,
	// that the values are not computed beginning at the source nodes, but are
	// computed on request of the sinks
	
	/**
	 * Scaling of a number with a given factor and translation
	 * 
	 * @param number
	 *            the number to change
	 * @param factor
	 *            the factor to scale
	 * @param translation
	 *            the translation
	 * @return number * factor + translation
	 */
	private static int scale(int number, double factor, double translation) {
		return (int) (number * factor + translation);
	}

	/*
		 * public static void removeDuplicateEdges(BoostedNode node){
		 * HashSet successors = new HashSet(); for
		 * (BoostedNode out : node.getOutPoints()) { for (BoostedNode in :
		 * node.getSuccessorInPoints(out)) { BoostedNode succ =
		 * in.getZoomOut(null).getLeft(); if(successors.contains(succ)){
		 * Refactor.removeEdge(node, out, in, succ); } else { successors.add(succ);
		 * } } }
		 * 
		 * HashSet predecessors = new HashSet(); for
		 * (BoostedNode in : node.getInPoints()) { for (BoostedNode out :
		 * node.getPredecessorOutPoints(in)) { BoostedNode pre =
		 * out.getZoomOut(null).getLeft(); if (predecessors.contains(pre)){
		 * Refactor.removeEdge(pre, out, in, node); } else { predecessors.add(pre);
		 * } } }
		 * 
		 * }
		 */
	
		
	
		// TODO add the feature into the transformation graph,
		// that the values are not computed beginning at the source nodes, but are
		// computed on request of the sinks
	
		/**
		 * Splits a graph into 2 subgraphs
		 * 
		 * @param graph
		 *            the inspected graph
		 * @param nodesOfFirstSubgraph
		 *            all these nodes and their connected components are put into
		 *            the first graph
		 * @return [graph with nodesOfFirstSubgraph, graph with other nodes, the
		 *         edges between graph1 and graph2 ]
		 */
	public static  Tuple, UndirectedGraph, List>, Void> split(
				Graph graph, Collection nodesOfFirstSubgraph) {
	
			UndirectedSparseGraph graph1 = new UndirectedSparseGraph();
			UndirectedSparseGraph graph2 = new UndirectedSparseGraph();
		ArrayList> edgesBetween = new ArrayList>();
	
			for (Vertex vertex : graph.getVertices()) {
				if (nodesOfFirstSubgraph.contains(vertex)) {
					graph1.addVertex(vertex);
				} else {
					graph2.addVertex(vertex);
				}
			}
	
			for (Edge edge : graph.getEdges()) {
				edu.uci.ics.jung.graph.util.Pair endpoints = graph
						.getEndpoints(edge);
				Vertex point1 = endpoints.getFirst();
				Vertex point2 = endpoints.getSecond();
	
				boolean point1Graph1 = nodesOfFirstSubgraph.contains(point1);
				boolean point2Graph1 = nodesOfFirstSubgraph.contains(point2);
	
				if (point1Graph1 && point2Graph1) {
					graph1.addEdge(edge, endpoints);
				} else if ((!point1Graph1) && (!point2Graph1)) {
					graph2.addEdge(edge, endpoints);
				} else if (point1Graph1) {
					edgesBetween
						.add(Tuple.triple(edge, point1, point2));
				} else { //
					edgesBetween
						.add(Tuple.triple(edge, point2, point1));
				}
	
			}
	
		return new Tuple, UndirectedGraph, List>, Void>(
					graph1, graph2, edgesBetween);
		}

	/**
	 * Create a component from the graph
	 * 
	 * @param graph
	 *            will be layouted
	 * @param displayConfiguration
	 *            configuration of the display
	 * @return the created component
	 */
	public static  Component layoutGraph(Graph graph, GraphDisplayConfiguration displayConfiguration) throws Exception {

		JungGraphLayouter layouter = new JungGraphLayouter();
		layouter.setConfiguration(displayConfiguration);
		layouter.setGraph(graph);
		return layouter.createLayoutComponent();

	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy