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 }