![JAR search and dependency download from the Maven repository](/logo.png)
net.sf.gluebooster.java.booster.basic.math.graph.JungGraphBoostUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gb-basic Show documentation
Show all versions of gb-basic Show documentation
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 extends Shape, Edge> 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 extends Shape> 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