2
* $Id: JGraphParallelRouter.java,v 1.1 2005/10/21 18:23:45 david Exp $
3
* Copyright (c) 2004-2005 France Telecom
4
* Copyright (c) 2004 Gaudenz Alder
5
* Copyright (c) 2005 David Benson
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions are met:
11
* - Redistributions of source code must retain the above copyright notice,
12
* this list of conditions and the following disclaimer.
13
* - Redistributions in binary form must reproduce the above copyright notice,
14
* this list of conditions and the following disclaimer in the documentation
15
* and/or other materials provided with the distribution.
16
* - Neither the name of JGraph nor the names of its contributors may be used
17
* to endorse or promote products derived from this software without specific
18
* prior written permission.
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
* POSSIBILITY OF SUCH DAMAGE.
31
package org.jgraph.example;
33
import java.awt.geom.Point2D;
34
import java.util.ArrayList;
35
import java.util.List;
37
import org.jgraph.graph.AbstractCellView;
38
import org.jgraph.graph.DefaultEdge;
39
import org.jgraph.graph.DefaultGraphModel;
40
import org.jgraph.graph.EdgeView;
41
import org.jgraph.graph.GraphModel;
42
import org.jgraph.graph.VertexView;
45
* Algorithm which create intermediates points for parallel edges
47
public class JGraphParallelRouter extends DefaultEdge.LoopRouting {
50
* Singleton to reach parallel edge router
52
private static final JGraphParallelRouter sharedInstance = new JGraphParallelRouter();
57
private static final GraphModel emptyModel = new DefaultGraphModel();
60
* Distance between each parallel edge
62
private static double edgeSeparation = 10.;
65
* Distance between intermediate and source/target points
67
private static double edgeDeparture = 10.;
70
* Getter for singleton managing parallel edges
72
* @return JGraphParallelRouter for parallel edges
74
public static JGraphParallelRouter getSharedInstance() {
75
return JGraphParallelRouter.sharedInstance;
79
* Calc of intermediates points
82
* Edge for which routing is demanding
84
public List routeEdge(EdgeView edge) {
85
List newPoints = new ArrayList();
87
// Check presence of source/target nodes
88
if ((null == edge.getSource()) || (null == edge.getTarget())
89
|| (null == edge.getSource().getParentView())
90
|| (null == edge.getTarget().getParentView())) {
93
newPoints.add(edge.getSource());
95
// Check presence of parallel edges
96
Object[] edges = getParallelEdges(edge);
101
// For one edge, no intermediate point
102
if (edges.length >= 2) {
104
// Looking for position of edge
106
for (int i = 0; i < edges.length; i++) {
108
if (e == edge.getCell()) {
113
// Looking for position of source/target nodes (edge=>port=>vertex)
114
VertexView nodeFrom = (VertexView) edge.getSource().getParentView();
115
VertexView nodeTo = (VertexView) edge.getTarget().getParentView();
116
Point2D from = AbstractCellView.getCenterPoint(nodeFrom);
117
Point2D to = AbstractCellView.getCenterPoint(nodeTo);
119
if (from != null && to != null) {
120
double dy = from.getY() - to.getY();
121
double dx = from.getX() - to.getX();
125
double theta = Math.atan(-1 / m);
126
double rx = dx / Math.sqrt(dx * dx + dy * dy);
127
double ry = dy / Math.sqrt(dx * dx + dy * dy);
129
// Memorize size of source/target nodes
130
double sizeFrom = Math.max(nodeFrom.getBounds().getWidth(),
131
nodeFrom.getBounds().getHeight()) / 2.;
132
double sizeTo = Math.max(nodeTo.getBounds().getWidth(), nodeTo
133
.getBounds().getHeight()) / 2.;
135
// Calc position of central point
136
double edgeMiddleDeparture = (Math.sqrt(dx * dx + dy * dy)
140
// Calc position of intermediates points
141
double edgeFromDeparture = edgeDeparture + sizeFrom;
142
double edgeToDeparture = edgeDeparture + sizeTo;
144
// Calc distance between edge and mediane source/target
145
double r = edgeSeparation * Math.floor(position / 2);
146
if (0 == (position % 2)) {
150
// Convert coordinate
151
double ex = r * Math.cos(theta);
152
double ey = r * Math.sin(theta);
154
// Check if is not better to have only one intermediate point
155
if (edgeMiddleDeparture <= edgeFromDeparture) {
156
double midX = from.getX() - rx * edgeMiddleDeparture;
157
double midY = from.getY() - ry * edgeMiddleDeparture;
159
Point2D controlPoint = new Point2D.Double(ex + midX, ey
162
// Add intermediate point
163
newPoints.add(controlPoint);
165
double midXFrom = from.getX() - rx * edgeFromDeparture;
166
double midYFrom = from.getY() - ry * edgeFromDeparture;
167
double midXTo = to.getX() + rx * edgeToDeparture;
168
double midYTo = to.getY() + ry * edgeToDeparture;
170
Point2D controlPointFrom = new Point2D.Double(
171
ex + midXFrom, ey + midYFrom);
172
Point2D controlPointTo = new Point2D.Double(ex + midXTo, ey
175
// Add intermediates points
176
newPoints.add(controlPointFrom);
177
newPoints.add(controlPointTo);
181
newPoints.add(edge.getTarget());
186
* Getter to obtain the distance between each parallel edge
190
public static double getEdgeSeparation() {
191
return JGraphParallelRouter.edgeSeparation;
195
* Setter to define distance between each parallel edge
197
* @param edgeSeparation
200
public static void setEdgeSeparation(double edgeSeparation) {
201
JGraphParallelRouter.edgeSeparation = edgeSeparation;
205
* Getter to obtain the distance between intermediate and source/target
210
public static double getEdgeDeparture() {
211
return JGraphParallelRouter.edgeDeparture;
215
* Setter to define distance between intermediate and source/target points
217
* @param edgeDeparture
220
public static void setEdgeDeparture(double edgeDeparture) {
221
JGraphParallelRouter.edgeDeparture = edgeDeparture;
225
* Getter to obtain the list of parallel edges
228
* Edge on which one wants to know parallel edges
229
* @return Object[] Array of parallel edges (include edge passed on
232
private Object[] getParallelEdges(EdgeView edge) {
233
// FIXME: The model is stored in the cells only in the default
234
// implementations. Otherwise we must use the real model here.
235
return DefaultGraphModel.getEdgesBetween(emptyModel, edge.getSource()
236
.getParentView().getCell(), edge.getTarget().getParentView()