org.jgraph.util.ParallelEdgeRouter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ingeniasjgraphmod Show documentation
Show all versions of ingeniasjgraphmod Show documentation
A modified version of some JGraph files
The newest version!
/*
* $Id: ParallelEdgeRouter.java,v 1.4 2008/11/13 00:12:39 david Exp $
*
* Copyright (c) 2001-2007 Gaudenz Alder
* Copyright (c) 2004-2007 David Benson
*
*/
package org.jgraph.util;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jgraph.JGraph;
import org.jgraph.graph.AbstractCellView;
import org.jgraph.graph.CellView;
import org.jgraph.graph.DefaultGraphModel;
import org.jgraph.graph.Edge;
import org.jgraph.graph.EdgeView;
import org.jgraph.graph.GraphConstants;
import org.jgraph.graph.GraphLayoutCache;
import org.jgraph.graph.GraphModel;
import org.jgraph.graph.DefaultEdge.LoopRouting;
/**
* A routing algorithm that
*/
public class ParallelEdgeRouter extends LoopRouting {
/**
* Singleton to reach parallel edge router
*/
protected static final ParallelEdgeRouter sharedInstance = new ParallelEdgeRouter();
/**
* Distance between each parallel edge
*/
private static double edgeSeparation = 10.;
/**
* Distance between intermediate and source/target points
*/
private static double edgeDeparture = 10.;
/**
* Getter for singleton managing parallel edges
*
* @return ParallelEdgeRouter for parallel edges
*/
public static ParallelEdgeRouter getSharedInstance() {
return ParallelEdgeRouter.sharedInstance;
}
/**
* Calc of intermediates points
*
* @param edge
* Edge for which routing is demanding
*/
public List routeEdge(GraphLayoutCache cache, EdgeView edge) {
List newPoints = new ArrayList();
CellView nodeFrom = edge.getSource();
CellView nodeTo = edge.getTarget();
// Check presence of source/target nodes
if (null == nodeFrom) {
nodeFrom = edge.getSourceParentView();
}
if (null == nodeTo) {
nodeTo = edge.getTargetParentView();
}
if ((null == nodeFrom) || (null == nodeTo)) {
// System.out.println("EdgeView has no source or target view : "
// + edge.toString());
return null;
}
if (nodeFrom == nodeTo) {
// System.out.println("nodeFrom and NodeTo are the same cell view");
return null;
}
List points = edge.getPoints();
Object startPort = points.get(0);
Object endPort = points.get(points.size() - 1);
newPoints.add(startPort);
// Promote edges up to first visible connected parents
// if (graph == null) {
// System.out
// .println("graph variable not correctly set, must be set to obtain parallel routing");
// }
// Check presence of parallel edges
Object[] edges = getParallelEdges(cache, edge, nodeFrom, nodeTo);
if (edges == null) {
return null;
}
// For one edge, no intermediate point
if (edges.length >= 2) {
// System.out.println("EdgeView indicates " + edges.length
// + " parallel edges");
// Looking for position of edge
int position = 0;
// System.out.println();
// System.out.println("edges.length = " + edges.length);
for (int i = 0; i < edges.length; i++) {
// System.out
// .println("edge value = "
// + String.valueOf(((DefaultGraphCell) edges[i])
// .getUserObject()));
// System.out
// .println("compared edge value = "
// + String.valueOf(((DefaultGraphCell) edge.getCell())
// .getUserObject()));
Object e = edges[i];
if (e == edge.getCell()) {
position = i + 1;
}
}
// System.out.println("position = " + position);
// Looking for position of source/target nodes (edge=>port=>vertex)
Point2D from;
Point2D perimeterPoint = edge.getTarget() != null ? edge
.getPoint(edge.getPointCount() - 1) : AbstractCellView
.getCenterPoint(nodeTo);
if (perimeterPoint == null) {
perimeterPoint = AbstractCellView.getCenterPoint(nodeTo);
}
if (edge.getSource() == null || edge.getSource().getParentView() == null) {
// System.out.println(edge+"-source promoted");
from = nodeFrom.getPerimeterPoint(edge,
AbstractCellView.getCenterPoint(nodeFrom),
perimeterPoint);
} else {
from = edge.getSource().getParentView().getPerimeterPoint(edge,
AbstractCellView.getCenterPoint(edge.getSource().getParentView()),
(edge.getTarget() != null && edge.getTarget().getParentView() != null) ?
AbstractCellView.getCenterPoint(edge.getTarget().getParentView()) :
AbstractCellView.getCenterPoint(nodeTo));
}
Point2D to;
if (edge.getTarget() == null || edge.getTarget().getParentView() == null) { // INV: nodeTo != null
// System.out.println(edge+"-target promoted");
to = nodeTo.getPerimeterPoint(edge, AbstractCellView.getCenterPoint(nodeTo), from);
} else {
to = edge.getTarget().getParentView().getPerimeterPoint
(edge, AbstractCellView.getCenterPoint(edge.getTarget().getParentView()), from);
}
// System.out.println("from Point = " + String.valueOf(from));
// System.out.println("to Point = " + String.valueOf(to));
if (from != null && to != null) {
double dy = from.getY() - to.getY();
double dx = from.getX() - to.getX();
if (dy == 0 && dx == 0) {
return null;
}
double theta = 0;
if (dy == 0) {
theta = Math.PI / 2.0;
} else if (dx == 0) {
theta = 0;
} else {
double m = dy / dx;
theta = Math.atan(-1 / m);
}
// Calc of radius
double length = Math.sqrt(dx * dx + dy * dy);
// System.out.println("length = " + length);
double rx = dx / length;
double ry = dy / length;
// Memorize size of source/target nodes
double sizeFrom = Math.max(nodeFrom.getBounds().getWidth(),
nodeFrom.getBounds().getHeight()) / 2.;
double sizeTo = Math.max(nodeTo.getBounds().getWidth(), nodeTo
.getBounds().getHeight()) / 2.;
// Calc position of central point
double edgeMiddleDeparture = (Math.sqrt(dx * dx + dy * dy)
- sizeFrom - sizeTo)
/ 2 + sizeFrom;
// Calc position of intermediates points
double edgeFromDeparture = edgeDeparture + sizeFrom;
double edgeToDeparture = edgeDeparture + sizeTo;
// Calc distance between edge and mediane source/target
double r = edgeSeparation * Math.floor(position / 2);
if (0 == (position % 2)) {
r = -r;
}
// Convert coordinate
double ex = r * Math.cos(theta);
double ey = r * Math.sin(theta);
// Check if is not better to have only one intermediate point
if (edgeMiddleDeparture <= edgeFromDeparture) {
double midX = from.getX() - rx * edgeMiddleDeparture;
double midY = from.getY() - ry * edgeMiddleDeparture;
Point2D controlPoint = new Point2D.Double(ex + midX, ey
+ midY);
// Add intermediate point
newPoints.add(controlPoint);
} else {
double midXFrom = from.getX() - rx * edgeFromDeparture;
double midYFrom = from.getY() - ry * edgeFromDeparture;
double midXTo = to.getX() + rx * edgeToDeparture;
double midYTo = to.getY() + ry * edgeToDeparture;
Point2D controlPointFrom = new Point2D.Double(
ex + midXFrom, ey + midYFrom);
Point2D controlPointTo = new Point2D.Double(ex + midXTo, ey
+ midYTo);
// Add intermediates points
newPoints.add(controlPointFrom);
newPoints.add(controlPointTo);
}
// Reposition the label, only if it's not been moved from its
// default location
Point2D labelPos = edge.getLabelPosition();
if (labelPos != null) {
double x = labelPos.getX();
if (x == GraphConstants.PERMILLE / 2) {
Map allAttributes = edge.getAllAttributes();
if (allAttributes != null) {
// Reverse the direction of r for up to down
// connections
if (dy < 0) {
r = -r;
}
int lineStyle = getPreferredLineStyle(edge);
if (lineStyle == Edge.Routing.NO_PREFERENCE) {
lineStyle = GraphConstants
.getLineStyle(allAttributes);
}
// The middle of the edge (where the label is) can
// vary in height
if (lineStyle == GraphConstants.STYLE_BEZIER
|| lineStyle == GraphConstants.STYLE_SPLINE) {
// TODO, sort this magic number out
GraphConstants.setLabelPosition(allAttributes,
new Point2D.Double(x, r
* edgeMiddleDeparture / 79));
} else {
GraphConstants.setExactSegmentLabel(allAttributes,true);
}
}
}
}
}
}
newPoints.add(endPort);
return newPoints;
}
/**
* Getter to obtain the distance between each parallel edge
*
* @return Distance
*/
public static double getEdgeSeparation() {
return ParallelEdgeRouter.edgeSeparation;
}
/**
* Setter to define distance between each parallel edge
*
* @param edgeSeparation
* New distance
*/
public static void setEdgeSeparation(double edgeSeparation) {
ParallelEdgeRouter.edgeSeparation = edgeSeparation;
}
/**
* Getter to obtain the distance between intermediate and source/target
* points
*
* @return Distance
*/
public static double getEdgeDeparture() {
return ParallelEdgeRouter.edgeDeparture;
}
/**
* Setter to define distance between intermediate and source/target points
*
* @param edgeDeparture
* New distance
*/
public static void setEdgeDeparture(double edgeDeparture) {
ParallelEdgeRouter.edgeDeparture = edgeDeparture;
}
/**
* Getter to obtain the list of parallel edges
*
* @param edge
* Edge on which one wants to know parallel edges
* @return Object[] Array of parallel edges (include edge passed on
* argument)
*/
protected Object[] getParallelEdges(GraphLayoutCache cache, EdgeView edge,
CellView cellView1, CellView cellView2) {
GraphModel model = cache.getModel();
Object cell1 = cellView1.getCell();
Object cell2 = cellView2.getCell();
// Need to exit if a load has just been performed and the model
// isn't in place properly yet
Object[] roots = DefaultGraphModel.getRoots(model);
if (roots.length == 0) {
return null;
}
// Need to order cells so direction of the edges doesn't
// affect the ordering of the output edges
Object[] cells = new Object[] { cell1, cell2 };
cells = DefaultGraphModel.order(model, cells);
if (cells == null || cells.length < 2) {
return null;
}
cell1 = cells[0];
cell2 = cells[1];
// System.out
// .println("cell1 of parallel edges = "
// + String.valueOf(((DefaultGraphCell) cell1)
// .getUserObject()));
while (model.getParent(cell1) != null && !cache.isVisible(cell1)) {
cell1 = model.getParent(cell1);
// if (cache.isVisible(cell1)) {
// System.out
// .println("cell1 promoted to = "
// + String.valueOf(((DefaultGraphCell) cell1)
// .getUserObject()));
// }
}
// System.out
// .println("cell2 of parallel edges = "
// + String.valueOf(((DefaultGraphCell) cell2)
// .getUserObject()));
while (model.getParent(cell2) != null && !cache.isVisible(cell2)) {
cell2 = model.getParent(cell2);
// if (cache.isVisible(cell2)) {
// System.out
// .println("cell2 promoted to = "
// + String.valueOf(((DefaultGraphCell) cell2)
// .getUserObject()));
// }
}
List cell1Children = DefaultGraphModel.getDescendants(model,
new Object[] { cell1 });
List cells1 = new ArrayList();
cells1.add(cell1);
Iterator iter = cell1Children.iterator();
while (iter.hasNext()) {
Object childCell = iter.next();
if (DefaultGraphModel.isVertex(model, childCell)
&& (!cache.isVisible(childCell))) {
cells1.add(childCell);
// System.out
// .println("cell1 has child "
// + String.valueOf(((DefaultGraphCell) childCell)
// .getUserObject()));
}
}
List cell2Children = DefaultGraphModel.getDescendants(model,
new Object[] { cell2 });
List cells2 = new ArrayList();
cells2.add(cell2);
iter = cell2Children.iterator();
while (iter.hasNext()) {
Object childCell = iter.next();
if (DefaultGraphModel.isVertex(model, childCell)
&& (!cache.isVisible(childCell))) {
cells2.add(childCell);
// System.out
// .println("cell2 has child "
// + String.valueOf(((DefaultGraphCell) childCell)
// .getUserObject()));
}
}
// Optimise for the standard case of no child cells
if (cells1.size() == 1 && cells2.size() == 1) {
// System.out.println("cells have no valid children");
return DefaultGraphModel
.getEdgesBetween(model, cell1, cell2, false);
}
// The object array to be returned
Object[] edgesBetween = null;
Iterator iter1 = cells1.iterator();
while (iter1.hasNext()) {
Object tempCell1 = iter1.next();
Iterator iter2 = cells2.iterator();
while (iter2.hasNext()) {
Object tempCell2 = iter2.next();
Object[] edges = DefaultGraphModel.getEdgesBetween(model,
tempCell1, tempCell2, false);
if (edges.length > 0) {
// for (int i = 0; i < edges.length; i++) {
// System.out
// .println("edge between "
// + i
// + " = "
// + String
// .valueOf(((DefaultGraphCell) edges[i])
// .getUserObject()));
// System.out
// .println("between cell "
// + String.valueOf(((DefaultGraphCell) tempCell1)
// .getUserObject()));
// System.out
// .println("and cell "
// + String.valueOf(((DefaultGraphCell) tempCell2)
// .getUserObject()));
// }
if (edgesBetween == null) {
edgesBetween = edges;
} else {
// need to copy everything into a new array
Object[] newArray = new Object[edges.length
+ edgesBetween.length];
System.arraycopy(edgesBetween, 0, newArray, 0,
edgesBetween.length);
System.arraycopy(edges, 0, newArray,
edgesBetween.length, edges.length);
edgesBetween = newArray;
}
}
}
}
return edgesBetween;
}
/**
* @deprecated graph instance retained internally
* @param graph
* The graph to set.
*/
public static void setGraph(JGraph graph) {
// No longer used from 5.10 API
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy