]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graphviz/src/org/simantics/graphviz/Edge.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.graphviz / src / org / simantics / graphviz / Edge.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.graphviz;\r
13 \r
14 import java.io.PrintStream;\r
15 import java.util.HashSet;\r
16 import java.util.Set;\r
17 \r
18 /**\r
19  * An edge of a graph.\r
20  * \r
21  * @author Hannu Niemistö\r
22  */\r
23 public class Edge extends AbstractGraphPart {\r
24 \r
25         Identifiable tail;\r
26         Identifiable head;\r
27         \r
28         public Edge(IGraph graph, Identifiable tail, Identifiable head) {\r
29         super(graph);\r
30         this.tail = tail;\r
31         this.head = head;\r
32     }\r
33         \r
34         private static IGraph chooseParentGraph(IGraph a, IGraph b) {\r
35             if(a == b)\r
36                 return a;\r
37             Set<IGraph> graphs = new HashSet<IGraph>();\r
38             while(true) {\r
39                 graphs.add(a);\r
40                 if(a instanceof Identifiable)\r
41                     a = ((Identifiable)a).getParent();\r
42                 else\r
43                     break;\r
44             }\r
45             while(true) {\r
46                 if(graphs.contains(b))\r
47                     return b;\r
48                 if(b instanceof Identifiable)\r
49                 b = ((Identifiable)b).getParent();\r
50             else\r
51                 break;\r
52             }\r
53             throw new IllegalArgumentException("Tried to connect nodes that do not belong to the same graph.");\r
54         }\r
55         \r
56         public Edge(Identifiable tail, Identifiable head) {\r
57         this(chooseParentGraph(tail.getParent(), head.getParent()), tail, head);\r
58     }\r
59         \r
60     /**\r
61      * Text label attached to objects. \r
62      */\r
63         public void setLabel(String label) {\r
64                 set("label", label);\r
65         }\r
66         \r
67         /**\r
68          * Text label to be placed near head of edge.\r
69          */\r
70         public void setHeadLabel(String label) {\r
71             set("headlabel", label);\r
72         }\r
73         \r
74         \r
75         /**\r
76          * Text label to be placed near tail of edge.\r
77          */\r
78         public void setTailLabel(String label) {\r
79             set("taillabel", label);\r
80     }\r
81         \r
82         /**\r
83          * <p>Set edge type for drawing arrowheads. This indicates which ends of the edge should be decorated with an arrowhead. The actual style of the arrowhead can be specified using the arrowhead and arrowtail attributes.</p>\r
84          * <p>Alternatives: <tt>forward back both none</tt></p> \r
85          */\r
86     public void setDir(String label) {\r
87         set("dir", label);\r
88     }\r
89     \r
90     /**\r
91      * Set style for node or edge. For cluster subgraph, if "filled", the cluster box's background is filled.\r
92      */\r
93     public void setStyle(String style) {\r
94         set("style", style);\r
95     }\r
96     \r
97     /**\r
98      * If false, the edge is not used in ranking the nodes.\r
99      */\r
100     public void setConstraint(boolean constraint) {\r
101         set("constraint", Boolean.toString(constraint));\r
102     }\r
103     \r
104     /**\r
105      * <p>\r
106      * Basic drawing color for graphics, not text. For the latter, use the\r
107      * fontcolor attribute. For edges, the value can either be a single color or\r
108      * a colorList. In the latter case, the edge is drawn using parallel splines\r
109      * or lines, one for each color in the list, in the order given. The head\r
110      * arrow, if any, is drawn using the first color in the list, and the tail\r
111      * arrow, if any, the second color. This supports the common case of drawing\r
112      * opposing edges, but using parallel splines instead of separately routed\r
113      * multiedges.\r
114      * </p>\r
115      * <p>Supports arbitrary RGB(A) colors in format #xxxxxx, where\r
116      * each x is a hex digit. Supports also color names in x11 color chart.</p>\r
117      */\r
118     public void setColor(String color) {\r
119         set("color", color);\r
120     }\r
121     \r
122     /**\r
123      * Color used for text.\r
124      */\r
125     public void setFontColor(String color) {\r
126         set("fontcolor", color);\r
127     }\r
128         \r
129         /**\r
130          * <p>Sets the shape of the arrow head</p>\r
131          * \r
132          * <p>Arrow shapes can be specified and named using the following simple grammar. Literal characters are given in single quotes. Square brackets [ and ] enclose optional items. Vertical bars | separate alternatives.\r
133          * </p>\r
134          * <pre>\r
135          * arrowname   :   aname [ aname [ aname [ aname ] ] ]\r
136          * aname   :   [ modifiers ] shape\r
137          * modifiers   :   [ 'o' ] [ side ]\r
138          * side    :   'l'\r
139          *         |   'r'\r
140          * shape   :   box\r
141          *         |   crow\r
142          *         |   diamond\r
143          *         |   dot\r
144          *         |   inv\r
145          *         |   none\r
146          *         |   normal\r
147          *         |   tee\r
148          *         |   vee\r
149          * </pre>\r
150          * As for the modifiers:\r
151          * <ul>\r
152          * <li> 'l' Clip the shape, leaving only the part to the left of the edge.</li>\r
153          * <li> 'r' Clip the shape, leaving only the part to the right of the edge.</li>\r
154          * <li> 'o' Use an open (non-filled) version of the shape.</li>\r
155          * </ul>\r
156          * <p>Left and right are defined as those directions determined by looking from the edge towards the point where the arrow "touches" the node.\r
157          * </p>\r
158          * <p>Note that the first arrow shape specified occurs closest to the node. Subsequent arrow shapes, if specified, occur further from the node.\r
159          * </p>\r
160          */\r
161         public void setArrowhead(String arrowName) {\r
162             set("arrowhead", arrowName);\r
163         }\r
164         \r
165         /**\r
166          * <p>Sets the shape of the arrow tail</p>\r
167          * \r
168          * @see Edge#setArrowhead\r
169          */\r
170         public void setArrowtail(String arrowName) {\r
171         set("arrowtail", arrowName);\r
172     }\r
173         \r
174         public void setArrowsize(double arrowSize) {\r
175         set("arrowsize", Double.toString(arrowSize));\r
176     }\r
177         \r
178         public Identifiable getTail() {\r
179                 return tail;\r
180         }\r
181 \r
182         public Identifiable getHead() {\r
183                 return head;\r
184         }\r
185 \r
186         @Override\r
187         public void write(PrintStream s) {\r
188                 s.print(tail.getId());\r
189                 s.print(" -> ");\r
190                 s.print(head.getId());\r
191                 writeAttributes(s);\r
192         }\r
193 \r
194 }\r