-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.graphviz.drawable;\r
-\r
-import java.awt.Graphics2D;\r
-import java.awt.Shape;\r
-import java.awt.geom.Point2D;\r
-import java.awt.geom.Rectangle2D;\r
-import java.io.IOException;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-import java.util.concurrent.ExecutionException;\r
-\r
-import org.simantics.graphviz.Edge;\r
-import org.simantics.graphviz.Graph;\r
-import org.simantics.graphviz.Graphs;\r
-import org.simantics.graphviz.IGraphPart;\r
-import org.simantics.graphviz.Identifiable;\r
-import org.simantics.graphviz.continuation.Computation;\r
-import org.simantics.graphviz.continuation.Continuation;\r
-import org.simantics.graphviz.internal.parser.ParseException;\r
-import org.simantics.graphviz.internal.xdot.DrawCommand;\r
-import org.simantics.graphviz.internal.xdot.DrawCommandParser;\r
-import org.simantics.graphviz.internal.xdot.ShapeCommand;\r
-\r
-/**\r
- * A drawable that draws a given graph.\r
- * Supports picking elements.\r
- * \r
- * TODO: optimize, uses hashmaps in places where those are not useful. \r
- * \r
- * \r
- * @author Hannu Niemist�\r
- * @author Marko Luukkainen\r
- */\r
-public class GraphDrawable2 implements Drawable {\r
-\r
- private static String DEFAULT_ALGORITHM = "dot";\r
- \r
- Collection<DrawCommand> commands;\r
- Map<IGraphPart,Collection<DrawCommand>> partCommands;\r
- Map<IGraphPart,Rectangle2D> partBounds;\r
- \r
- Rectangle2D bounds;\r
- \r
- public GraphDrawable2(Graph graph, String algorithm) {\r
- try {\r
- setGraph(graph, algorithm).get();\r
- } catch (Exception e) {\r
- e.printStackTrace();\r
- }\r
- }\r
- \r
- public GraphDrawable2(Graph graph) {\r
- setGraph(graph);\r
- }\r
- \r
- public GraphDrawable2() {\r
- commands = new ArrayList<DrawCommand>();\r
- partCommands = new HashMap<IGraphPart, Collection<DrawCommand>>();\r
- partBounds = new HashMap<IGraphPart, Rectangle2D>();\r
- bounds = new Rectangle2D.Double(0, 0, 100, 100);\r
- }\r
- \r
- /**\r
- * Sets a new graph to be drawn. This operation may take a while. It can\r
- * be called from any thread.\r
- * @param graph\r
- */\r
- public void setGraph(Graph graph) {\r
- try {\r
- setGraph(graph, DEFAULT_ALGORITHM).get();\r
- } catch(Exception e) {\r
- e.printStackTrace();\r
- }\r
- }\r
- \r
- \r
- \r
- /**\r
- * Sets a new graph to be drawn. This operation may take a while. It can\r
- * be called from any thread.\r
- * @param graph\r
- */\r
- public synchronized Computation<Graph> setGraph(final Graph graph, String algorithm) {\r
- Computation<Graph> computation = Graphs.createXDot(graph, algorithm);\r
- computation.addContinuation(new Continuation<Graph>() {\r
- @Override\r
- public void succeeded(Graph xgraph) {\r
- commands = new ArrayList<DrawCommand>();\r
- partCommands = new HashMap<IGraphPart, Collection<DrawCommand>>();\r
- partBounds = new HashMap<IGraphPart, Rectangle2D>();\r
- DrawCommandParser.parse(xgraph,commands,partCommands);\r
- readBoundingBox(xgraph);\r
- updatePartBoundingBoxes(graph, xgraph);\r
- }\r
-\r
- @Override\r
- public void failed(Exception exception) {\r
- }\r
- });\r
- return computation;\r
- }\r
- \r
- private void readBoundingBox(Graph graph) {\r
- String[] parts = graph.get("bb").split(",");\r
- double minX = Double.parseDouble(parts[0]);\r
- double maxY = -Double.parseDouble(parts[1]);\r
- double maxX = Double.parseDouble(parts[2]);\r
- double minY = -Double.parseDouble(parts[3]);\r
- bounds = new Rectangle2D.Double(minX, minY, maxX-minX, maxY-minY);\r
- }\r
- \r
- private void updatePartBoundingBoxes(Graph graph, Graph xgraph) {\r
- // we have to map input Nodes to XGraph nodes\r
- \r
- Map<IGraphPart,IGraphPart> partMap = new HashMap<IGraphPart, IGraphPart>();\r
- \r
- for (IGraphPart xPart : xgraph.getParts()) {\r
- if (xPart instanceof Identifiable) {\r
- String xID = ((Identifiable)xPart).getId();\r
- for (IGraphPart gPart : graph.getParts()) {\r
- if (gPart instanceof Identifiable) {\r
- String gID = ((Identifiable)gPart).getId();\r
- if (xID.equals(gID)) {\r
- partMap.put(xPart, gPart);\r
- }\r
- }\r
- }\r
- } else if (xPart instanceof Edge) {\r
- String xHeadId = ((Edge)xPart).getHead().getId();\r
- String xTailId = ((Edge)xPart).getTail().getId();\r
- for (IGraphPart gPart : graph.getParts()) {\r
- if (gPart instanceof Edge) {\r
- String gHeadId = ((Edge)gPart).getHead().getId();\r
- String gTailId = ((Edge)gPart).getTail().getId();\r
- \r
- if (xHeadId.equals(gHeadId) && xTailId.equals(gTailId)) {\r
- partMap.put(xPart, gPart);\r
- }\r
- }\r
- }\r
- }\r
- }\r
- \r
- \r
- \r
- for (IGraphPart part : partCommands.keySet()) {\r
- Collection<DrawCommand> pCommands = partCommands.get(part);\r
- Rectangle2D r = null;\r
- for (DrawCommand c : pCommands) {\r
- if (c instanceof ShapeCommand) {\r
- Shape s = ((ShapeCommand)c).getShape();\r
- if (r == null)\r
- r = s.getBounds2D();\r
- else\r
- r.add(s.getBounds2D());\r
- }\r
- }\r
- if (r != null) {\r
- partBounds.put(partMap.get(part), r);\r
- }\r
- }\r
- }\r
- \r
- @Override\r
- public synchronized Rectangle2D getBounds() {\r
- return bounds;\r
- }\r
- \r
- \r
- public synchronized Rectangle2D getBounds(IGraphPart part) {\r
- return partBounds.get(part);\r
- }\r
- \r
- public synchronized Collection<IGraphPart> pick(Point2D point) {\r
- Collection<IGraphPart> picked = new ArrayList<IGraphPart>();\r
- for (IGraphPart part : partBounds.keySet()) {\r
- Rectangle2D r = partBounds.get(part);\r
- if (r.contains(point))\r
- picked.add(part);\r
- }\r
- return picked;\r
- }\r
- \r
- @Override\r
- public synchronized void draw(Graphics2D g, Rectangle2D area) {\r
- for(DrawCommand command : commands)\r
- command.draw(g);\r
- \r
-// for (Rectangle2D r : partBounds.values()) {\r
-// g.drawRect((int)r.getMinX(), (int)r.getMinY(), (int)r.getWidth(), (int)r.getHeight());\r
-// }\r
- }\r
- \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.graphviz.drawable;
+
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+import org.simantics.graphviz.Edge;
+import org.simantics.graphviz.Graph;
+import org.simantics.graphviz.Graphs;
+import org.simantics.graphviz.IGraphPart;
+import org.simantics.graphviz.Identifiable;
+import org.simantics.graphviz.continuation.Computation;
+import org.simantics.graphviz.continuation.Continuation;
+import org.simantics.graphviz.internal.parser.ParseException;
+import org.simantics.graphviz.internal.xdot.DrawCommand;
+import org.simantics.graphviz.internal.xdot.DrawCommandParser;
+import org.simantics.graphviz.internal.xdot.ShapeCommand;
+
+/**
+ * A drawable that draws a given graph.
+ * Supports picking elements.
+ *
+ * TODO: optimize, uses hashmaps in places where those are not useful.
+ *
+ *
+ * @author Hannu Niemist�
+ * @author Marko Luukkainen
+ */
+public class GraphDrawable2 implements Drawable {
+
+ private static String DEFAULT_ALGORITHM = "dot";
+
+ Collection<DrawCommand> commands;
+ Map<IGraphPart,Collection<DrawCommand>> partCommands;
+ Map<IGraphPart,Rectangle2D> partBounds;
+
+ Rectangle2D bounds;
+
+ public GraphDrawable2(Graph graph, String algorithm) {
+ try {
+ setGraph(graph, algorithm).get();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public GraphDrawable2(Graph graph) {
+ setGraph(graph);
+ }
+
+ public GraphDrawable2() {
+ commands = new ArrayList<DrawCommand>();
+ partCommands = new HashMap<IGraphPart, Collection<DrawCommand>>();
+ partBounds = new HashMap<IGraphPart, Rectangle2D>();
+ bounds = new Rectangle2D.Double(0, 0, 100, 100);
+ }
+
+ /**
+ * Sets a new graph to be drawn. This operation may take a while. It can
+ * be called from any thread.
+ * @param graph
+ */
+ public void setGraph(Graph graph) {
+ try {
+ setGraph(graph, DEFAULT_ALGORITHM).get();
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+
+
+ /**
+ * Sets a new graph to be drawn. This operation may take a while. It can
+ * be called from any thread.
+ * @param graph
+ */
+ public synchronized Computation<Graph> setGraph(final Graph graph, String algorithm) {
+ Computation<Graph> computation = Graphs.createXDot(graph, algorithm);
+ computation.addContinuation(new Continuation<Graph>() {
+ @Override
+ public void succeeded(Graph xgraph) {
+ commands = new ArrayList<DrawCommand>();
+ partCommands = new HashMap<IGraphPart, Collection<DrawCommand>>();
+ partBounds = new HashMap<IGraphPart, Rectangle2D>();
+ DrawCommandParser.parse(xgraph,commands,partCommands);
+ readBoundingBox(xgraph);
+ updatePartBoundingBoxes(graph, xgraph);
+ }
+
+ @Override
+ public void failed(Exception exception) {
+ }
+ });
+ return computation;
+ }
+
+ private void readBoundingBox(Graph graph) {
+ String[] parts = graph.get("bb").split(",");
+ double minX = Double.parseDouble(parts[0]);
+ double maxY = -Double.parseDouble(parts[1]);
+ double maxX = Double.parseDouble(parts[2]);
+ double minY = -Double.parseDouble(parts[3]);
+ bounds = new Rectangle2D.Double(minX, minY, maxX-minX, maxY-minY);
+ }
+
+ private void updatePartBoundingBoxes(Graph graph, Graph xgraph) {
+ // we have to map input Nodes to XGraph nodes
+
+ Map<IGraphPart,IGraphPart> partMap = new HashMap<IGraphPart, IGraphPart>();
+
+ for (IGraphPart xPart : xgraph.getParts()) {
+ if (xPart instanceof Identifiable) {
+ String xID = ((Identifiable)xPart).getId();
+ for (IGraphPart gPart : graph.getParts()) {
+ if (gPart instanceof Identifiable) {
+ String gID = ((Identifiable)gPart).getId();
+ if (xID.equals(gID)) {
+ partMap.put(xPart, gPart);
+ }
+ }
+ }
+ } else if (xPart instanceof Edge) {
+ String xHeadId = ((Edge)xPart).getHead().getId();
+ String xTailId = ((Edge)xPart).getTail().getId();
+ for (IGraphPart gPart : graph.getParts()) {
+ if (gPart instanceof Edge) {
+ String gHeadId = ((Edge)gPart).getHead().getId();
+ String gTailId = ((Edge)gPart).getTail().getId();
+
+ if (xHeadId.equals(gHeadId) && xTailId.equals(gTailId)) {
+ partMap.put(xPart, gPart);
+ }
+ }
+ }
+ }
+ }
+
+
+
+ for (IGraphPart part : partCommands.keySet()) {
+ Collection<DrawCommand> pCommands = partCommands.get(part);
+ Rectangle2D r = null;
+ for (DrawCommand c : pCommands) {
+ if (c instanceof ShapeCommand) {
+ Shape s = ((ShapeCommand)c).getShape();
+ if (r == null)
+ r = s.getBounds2D();
+ else
+ r.add(s.getBounds2D());
+ }
+ }
+ if (r != null) {
+ partBounds.put(partMap.get(part), r);
+ }
+ }
+ }
+
+ @Override
+ public synchronized Rectangle2D getBounds() {
+ return bounds;
+ }
+
+
+ public synchronized Rectangle2D getBounds(IGraphPart part) {
+ return partBounds.get(part);
+ }
+
+ public synchronized Collection<IGraphPart> pick(Point2D point) {
+ Collection<IGraphPart> picked = new ArrayList<IGraphPart>();
+ for (IGraphPart part : partBounds.keySet()) {
+ Rectangle2D r = partBounds.get(part);
+ if (r.contains(point))
+ picked.add(part);
+ }
+ return picked;
+ }
+
+ @Override
+ public synchronized void draw(Graphics2D g, Rectangle2D area) {
+ for(DrawCommand command : commands)
+ command.draw(g);
+
+// for (Rectangle2D r : partBounds.values()) {
+// g.drawRect((int)r.getMinX(), (int)r.getMinY(), (int)r.getWidth(), (int)r.getHeight());
+// }
+ }
+
+}