~ubuntu-branches/ubuntu/jaunty/libjgraph-java/jaunty

« back to all changes in this revision

Viewing changes to examples/org/jgraph/example/JGraphParallelRouter.java

  • Committer: Bazaar Package Importer
  • Author(s): gregor herrmann
  • Date: 2007-02-26 17:25:47 UTC
  • Revision ID: james.westby@ubuntu.com-20070226172547-k03sz4dbg197zr0p
Tags: upstream-5.10.0.1.dfsg
ImportĀ upstreamĀ versionĀ 5.10.0.1.dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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
 
6
 * All rights reserved.
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without
 
9
 * modification, are permitted provided that the following conditions are met:
 
10
 *
 
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.
 
30
 */
 
31
package org.jgraph.example;
 
32
 
 
33
import java.awt.geom.Point2D;
 
34
import java.util.ArrayList;
 
35
import java.util.List;
 
36
 
 
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;
 
43
 
 
44
/**
 
45
 * Algorithm which create intermediates points for parallel edges
 
46
 */
 
47
public class JGraphParallelRouter extends DefaultEdge.LoopRouting {
 
48
 
 
49
        /**
 
50
         * Singleton to reach parallel edge router
 
51
         */
 
52
        private static final JGraphParallelRouter sharedInstance = new JGraphParallelRouter();
 
53
 
 
54
        /**
 
55
         * Default model
 
56
         */
 
57
        private static final GraphModel emptyModel = new DefaultGraphModel();
 
58
 
 
59
        /**
 
60
         * Distance between each parallel edge
 
61
         */
 
62
        private static double edgeSeparation = 10.;
 
63
 
 
64
        /**
 
65
         * Distance between intermediate and source/target points
 
66
         */
 
67
        private static double edgeDeparture = 10.;
 
68
 
 
69
        /**
 
70
         * Getter for singleton managing parallel edges
 
71
         * 
 
72
         * @return JGraphParallelRouter for parallel edges
 
73
         */
 
74
        public static JGraphParallelRouter getSharedInstance() {
 
75
                return JGraphParallelRouter.sharedInstance;
 
76
        }
 
77
 
 
78
        /**
 
79
         * Calc of intermediates points
 
80
         * 
 
81
         * @param edge
 
82
         *            Edge for which routing is demanding
 
83
         */
 
84
        public List routeEdge(EdgeView edge) {
 
85
                List newPoints = new ArrayList();
 
86
 
 
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())) {
 
91
                        return null;
 
92
                }
 
93
                newPoints.add(edge.getSource());
 
94
 
 
95
                // Check presence of parallel edges
 
96
                Object[] edges = getParallelEdges(edge);
 
97
                if (edges == null) {
 
98
                        return null;
 
99
                }
 
100
 
 
101
                // For one edge, no intermediate point
 
102
                if (edges.length >= 2) {
 
103
 
 
104
                        // Looking for position of edge
 
105
                        int position = 0;
 
106
                        for (int i = 0; i < edges.length; i++) {
 
107
                                Object e = edges[i];
 
108
                                if (e == edge.getCell()) {
 
109
                                        position = i + 1;
 
110
                                }
 
111
                        }
 
112
 
 
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);
 
118
 
 
119
                        if (from != null && to != null) {
 
120
                                double dy = from.getY() - to.getY();
 
121
                                double dx = from.getX() - to.getX();
 
122
 
 
123
                                // Calc of radius
 
124
                                double m = dy / dx;
 
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);
 
128
 
 
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.;
 
134
 
 
135
                                // Calc position of central point
 
136
                                double edgeMiddleDeparture = (Math.sqrt(dx * dx + dy * dy)
 
137
                                                - sizeFrom - sizeTo)
 
138
                                                / 2 + sizeFrom;
 
139
 
 
140
                                // Calc position of intermediates points
 
141
                                double edgeFromDeparture = edgeDeparture + sizeFrom;
 
142
                                double edgeToDeparture = edgeDeparture + sizeTo;
 
143
 
 
144
                                // Calc distance between edge and mediane source/target
 
145
                                double r = edgeSeparation * Math.floor(position / 2);
 
146
                                if (0 == (position % 2)) {
 
147
                                        r = -r;
 
148
                                }
 
149
 
 
150
                                // Convert coordinate
 
151
                                double ex = r * Math.cos(theta);
 
152
                                double ey = r * Math.sin(theta);
 
153
 
 
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;
 
158
 
 
159
                                        Point2D controlPoint = new Point2D.Double(ex + midX, ey
 
160
                                                        + midY);
 
161
 
 
162
                                        // Add intermediate point
 
163
                                        newPoints.add(controlPoint);
 
164
                                } else {
 
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;
 
169
 
 
170
                                        Point2D controlPointFrom = new Point2D.Double(
 
171
                                                        ex + midXFrom, ey + midYFrom);
 
172
                                        Point2D controlPointTo = new Point2D.Double(ex + midXTo, ey
 
173
                                                        + midYTo);
 
174
 
 
175
                                        // Add intermediates points
 
176
                                        newPoints.add(controlPointFrom);
 
177
                                        newPoints.add(controlPointTo);
 
178
                                }
 
179
                        }
 
180
                }
 
181
                newPoints.add(edge.getTarget());
 
182
                return newPoints;
 
183
        }
 
184
 
 
185
        /**
 
186
         * Getter to obtain the distance between each parallel edge
 
187
         * 
 
188
         * @return Distance
 
189
         */
 
190
        public static double getEdgeSeparation() {
 
191
                return JGraphParallelRouter.edgeSeparation;
 
192
        }
 
193
 
 
194
        /**
 
195
         * Setter to define distance between each parallel edge
 
196
         * 
 
197
         * @param edgeSeparation
 
198
         *            New distance
 
199
         */
 
200
        public static void setEdgeSeparation(double edgeSeparation) {
 
201
                JGraphParallelRouter.edgeSeparation = edgeSeparation;
 
202
        }
 
203
 
 
204
        /**
 
205
         * Getter to obtain the distance between intermediate and source/target
 
206
         * points
 
207
         * 
 
208
         * @return Distance
 
209
         */
 
210
        public static double getEdgeDeparture() {
 
211
                return JGraphParallelRouter.edgeDeparture;
 
212
        }
 
213
 
 
214
        /**
 
215
         * Setter to define distance between intermediate and source/target points
 
216
         * 
 
217
         * @param edgeDeparture
 
218
         *            New distance
 
219
         */
 
220
        public static void setEdgeDeparture(double edgeDeparture) {
 
221
                JGraphParallelRouter.edgeDeparture = edgeDeparture;
 
222
        }
 
223
 
 
224
        /**
 
225
         * Getter to obtain the list of parallel edges
 
226
         * 
 
227
         * @param edge
 
228
         *            Edge on which one wants to know parallel edges
 
229
         * @return Object[] Array of parallel edges (include edge passed on
 
230
         *         argument)
 
231
         */
 
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()
 
237
                                .getCell(), false);
 
238
        }
 
239
 
 
240
}