001 package nl.cwi.sen1.gui.plugin;
002
003 import java.awt.FontMetrics;
004 import java.awt.geom.Point2D;
005 import java.util.HashMap;
006 import java.util.Iterator;
007 import java.util.LinkedList;
008 import java.util.List;
009 import java.util.Map;
010
011 import nl.cwi.sen1.graph.Factory;
012 import nl.cwi.sen1.graph.types.Attribute;
013 import nl.cwi.sen1.graph.types.AttributeList;
014 import nl.cwi.sen1.graph.types.Color;
015 import nl.cwi.sen1.graph.types.Edge;
016 import nl.cwi.sen1.graph.types.EdgeList;
017 import nl.cwi.sen1.graph.types.Graph;
018 import nl.cwi.sen1.graph.types.Node;
019 import nl.cwi.sen1.graph.types.NodeId;
020 import nl.cwi.sen1.graph.types.NodeList;
021 import nl.cwi.sen1.graph.types.Point;
022 import nl.cwi.sen1.graph.types.Polygon;
023 import nl.cwi.sen1.graph.types.Shape;
024 import nl.cwi.sen1.graph.types.attribute.Location;
025 import nl.cwi.sen1.graph.types.attribute.Size;
026 import nl.cwi.sen1.util.Preferences;
027 import prefuse.util.ColorLib;
028 import prefuse.visual.VisualItem;
029
030 public class GraphAdapter extends prefuse.data.Graph {
031 public GraphAdapter(nl.cwi.sen1.graph.types.Graph graph) {
032 super(true);
033
034 Map<NodeId, prefuse.data.Node> nodeMap = new HashMap<NodeId, prefuse.data.Node>();
035
036 addColumn(GraphConstants.ID, String.class);
037 addColumn(GraphConstants.LABEL, String.class);
038 addColumn(GraphDotLayout.DOT_X, int.class);
039 addColumn(GraphDotLayout.DOT_Y, int.class);
040 addColumn(GraphDotLayout.DOT_WIDTH, int.class);
041 addColumn(GraphDotLayout.DOT_HEIGHT, int.class);
042 addColumn(GraphConstants.SHAPE, Shape.class);
043 addColumn(GraphDotLayout.CURVE_POINTS, Point2D[].class);
044 addColumn(GraphConstants.COLOR, int.class);
045 addColumn(GraphConstants.FILLCOLOR, int.class);
046 addColumn(GraphConstants.TOOLTIP, String.class);
047
048 for (NodeList nodes = graph.getNodes(); !nodes.isEmpty(); nodes = nodes
049 .getTail()) {
050 Node node = nodes.getHead();
051
052 prefuse.data.Node pNode = addNode();
053 pNode.setString(GraphConstants.ID, node.getId().getId().toString());
054 pNode.setString(GraphConstants.LABEL, getLabel(node));
055 pNode.setInt(GraphDotLayout.DOT_X, getX(node));
056 pNode.setInt(GraphDotLayout.DOT_Y, getY(node));
057 pNode.setInt(GraphDotLayout.DOT_WIDTH, getWidth(node));
058 pNode.setInt(GraphDotLayout.DOT_HEIGHT, getHeight(node));
059 pNode.set(GraphConstants.SHAPE, getShape(node));
060 pNode.set(GraphConstants.TOOLTIP, getTooltip(node));
061
062 Color fillColor = getFillColorAttribute(node);
063 if (fillColor != null) {
064 pNode.setInt(GraphConstants.FILLCOLOR, ColorLib.rgb(fillColor
065 .getRed(), fillColor.getGreen(), fillColor.getBlue()));
066 }
067
068 Color color = getColorAttribute(node);
069 if (color != null) {
070 pNode.setInt(GraphConstants.COLOR, ColorLib.rgb(color.getRed(),
071 color.getGreen(), color.getBlue()));
072 }
073
074 nodeMap.put(node.getId(), pNode);
075 }
076
077 for (EdgeList edges = graph.getEdges(); !edges.isEmpty(); edges = edges
078 .getTail()) {
079 Edge edge = edges.getHead();
080 prefuse.data.Node fromNode = nodeMap.get(edge.getFrom());
081 prefuse.data.Node toNode = nodeMap.get(edge.getTo());
082 prefuse.data.Edge pEdge = addEdge(fromNode, toNode);
083
084 pEdge.set(GraphDotLayout.CURVE_POINTS, getControlPoints(edge));
085 }
086 }
087
088 private Point2D[] getControlPoints(Edge edge) {
089 Polygon poly = getPolygon(edge);
090
091 if (poly != null) {
092 List<Point2D> points = new LinkedList<Point2D>();
093
094 for (; !poly.isEmpty(); poly = poly.getTail()) {
095 Point cp1 = poly.getHead();
096 points.add(new Point2D.Float(cp1.getX(), cp1.getY()));
097 }
098
099 Point2D[] result = new Point2D[points.size()];
100 Iterator<Point2D> iter = points.iterator();
101
102 for (int i = 0; iter.hasNext(); i++) {
103 result[i] = iter.next();
104 }
105 return result;
106 }
107
108 return new Point2D[0];
109 }
110
111 private Polygon getPolygon(Edge edge) {
112 AttributeList attrs = edge.getAttributes();
113 while (!attrs.isEmpty()) {
114 Attribute attr = attrs.getHead();
115 if (attr.isCurvePoints()) {
116 return attr.getPoints();
117 }
118 attrs = attrs.getTail();
119 }
120
121 return null;
122 }
123
124 private Shape getShape(Node node) {
125 AttributeList attrs = node.getAttributes();
126 while (!attrs.isEmpty()) {
127 Attribute attr = attrs.getHead();
128 if (attr.isShape()) {
129 return attr.getShape();
130 }
131 attrs = attrs.getTail();
132 }
133
134 return null;
135 }
136
137 static private Location getLocationAttribute(Node node) {
138 AttributeList attrs = node.getAttributes();
139 while (!attrs.isEmpty()) {
140 Attribute attr = attrs.getHead();
141 if (attr.isLocation()) {
142 return (Location) attr;
143 }
144 attrs = attrs.getTail();
145 }
146
147 return null;
148 }
149
150 static private Color getFillColorAttribute(Node node) {
151 AttributeList attrs = node.getAttributes();
152 while (!attrs.isEmpty()) {
153 Attribute attr = attrs.getHead();
154 if (attr.isFillColor()) {
155 return attr.getColor();
156 }
157 attrs = attrs.getTail();
158 }
159
160 return null;
161 }
162
163 static private Color getColorAttribute(Node node) {
164 AttributeList attrs = node.getAttributes();
165 while (!attrs.isEmpty()) {
166 Attribute attr = attrs.getHead();
167 if (attr.isColor()) {
168 return attr.getColor();
169 }
170 attrs = attrs.getTail();
171 }
172
173 return null;
174 }
175
176 static public int getX(Node node) {
177 Location location = getLocationAttribute(node);
178 if (location != null) {
179 return location.getX();
180 }
181 return 0;
182 }
183
184 static public int getY(Node node) {
185 Location location = getLocationAttribute(node);
186 if (location != null) {
187 return location.getY();
188 }
189 return 0;
190 }
191
192 static public int getWidth(Node node) {
193 Size size = getSizeAttribute(node);
194 if (size != null) {
195 return size.getWidth();
196 }
197 return 0;
198 }
199
200 static public int getHeight(Node node) {
201 Size size = getSizeAttribute(node);
202 if (size != null) {
203 return size.getHeight();
204 }
205 return 0;
206 }
207
208 static private String getLabel(Node node) {
209 AttributeList attrs = node.getAttributes();
210
211 for (; !attrs.isEmpty(); attrs = attrs.getTail()) {
212 Attribute attr = attrs.getHead();
213 if (attr.isLabel()) {
214 return attr.getLabel();
215 }
216 }
217 return node.getId().getId().toString();
218 }
219
220 static private String getTooltip(Node node) {
221 AttributeList attrs = node.getAttributes();
222
223 for (; !attrs.isEmpty(); attrs = attrs.getTail()) {
224 Attribute attr = attrs.getHead();
225 if (attr.isTooltip()) {
226 return attr.getTooltip();
227 }
228 }
229 return null;
230 }
231
232 static private Size getSizeAttribute(Node node) {
233 AttributeList attrs = node.getAttributes();
234 while (!attrs.isEmpty()) {
235 Attribute attr = attrs.getHead();
236 if (attr.isSize()) {
237 return (Size) attr;
238 }
239 attrs = attrs.getTail();
240 }
241
242 return null;
243 }
244
245 static private Node setSizeAttribute(Node node, Size sizeAttr) {
246 Factory factory = node.getGraphFactory();
247 AttributeList result = factory.makeAttributeList();
248 AttributeList attrs = node.getAttributes();
249 while (!attrs.isEmpty()) {
250 Attribute attr = attrs.getHead();
251 if (!attr.isSize()) {
252 result = factory.makeAttributeList(attr, result);
253 }
254 attrs = attrs.getTail();
255 }
256
257 result = factory.makeAttributeList(sizeAttr, result);
258 return node.setAttributes(result);
259 }
260
261 static private Node setNodeSize(FontMetrics metrics, Preferences prefs,
262 Node node) {
263 Factory factory = node.getGraphFactory();
264 int borderWidth = prefs.getInt(GraphConstants.NODE_BORDER_WIDTH);
265 int borderHeight = prefs.getInt(GraphConstants.NODE_BORDER_HEIGHT);
266 String label = getLabel(node);
267 int width = metrics.stringWidth(label) + borderWidth * 2;
268 int height = metrics.getHeight() + borderHeight * 2;
269
270 return setSizeAttribute(node, factory.makeAttribute_Size(width, height));
271 }
272
273 static public Graph sizeGraph(FontMetrics metrics, Preferences prefs,
274 Graph graph) {
275 Factory factory = graph.getGraphFactory();
276 NodeList nodes = graph.getNodes();
277 NodeList result = factory.makeNodeList();
278
279 for (; !nodes.isEmpty(); nodes = nodes.getTail()) {
280 Node node = nodes.getHead();
281 node = setNodeSize(metrics, prefs, node);
282 result = factory.makeNodeList(node, result);
283 }
284 return graph.setNodes(result.reverseNodeList());
285 }
286
287 static public void updateNode(VisualItem node, Attribute attr) {
288 if (attr.isLabel()) {
289 node.setString(GraphConstants.LABEL, attr.getLabel());
290 } else if (attr.isShape()) {
291 node.set(GraphConstants.SHAPE, attr.getShape());
292 } else if (attr.isColor()) {
293 Color color = attr.getColor();
294 node.setInt(GraphConstants.COLOR, ColorLib.rgb(color.getRed(),
295 color.getGreen(), color.getBlue()));
296 } else if (attr.isFillColor()) {
297 Color color = attr.getColor();
298 node.setInt(GraphConstants.FILLCOLOR, ColorLib.rgb(color.getRed(),
299 color.getGreen(), color.getBlue()));
300 }
301 }
302 }