private static GleeGraph CreateAndLayoutGraph(XmlModel xmlParser) { startNode = xmlParser.StartState; var graph = new GleeGraph { Margins = margin }; foreach (var state in xmlParser.States) { graph.AddNode(new Node(state, new Ellipse(nodeWidth, nodeHeight, new P()))); } foreach (var transition in xmlParser.Transitions) { var e = new Edge(graph.NodeMap[transition.From], graph.NodeMap[transition.To]) { UserData = transition.Trigger }; graph.AddEdge(e); } graph.CalculateLayout(); return(graph); }
private static GleeGraph CreateAndLayoutGraph(string fileName) { // Read the file as one string var fileString = string.Empty; using (var myFile = new StreamReader(fileName)) { fileString = myFile.ReadToEnd(); } var xmlParser = new XmlParser(fileString); startNode = xmlParser.StartState; var graph = new GleeGraph { Margins = margin }; foreach (var state in xmlParser.States) { graph.AddNode(new Node(state, new Ellipse(nodeWidth, nodeHeight, new P()))); } foreach (var transition in xmlParser.Transitions) { var e = new Edge(graph.NodeMap[transition.From], graph.NodeMap[transition.To]) { UserData = transition.Trigger }; graph.AddEdge(e); } graph.CalculateLayout(); return(graph); }
private static void ApplyShapesLayout(GleeGraph g, Dictionary <string, NodeShape> shapesMap, double graphLeft, double graphTop) { // apply layout information to child shapes foreach (string key in shapesMap.Keys) { NodeShape nodeShape = shapesMap[key]; Node node = g.NodeMap[key]; // appy layout information for shape double shapeTop = (graphTop - node.BBox.Top) + HostMargin; double shapeLeft; if (graphLeft <= 0) { shapeLeft = Math.Abs(graphLeft) + node.BBox.Left + HostMargin; } else { shapeLeft = node.BBox.Left - graphLeft + HostMargin; } if (nodeShape.MovementBehaviour == ShapeMovementBehaviour.PositionOnEdgeOfParent) { if (nodeShape.Parent != null) { nodeShape.SetLocation(NodeShape.CorrectPortLocation(nodeShape.Parent, nodeShape, new PointD(shapeLeft, shapeTop))); } } else { nodeShape.SetLocation(new PointD(shapeLeft, shapeTop)); } } }
private static void AddNode(GleeGraph g, NodeShape n, Dictionary <string, NodeShape> shapesMap) { shapesMap.Add(n.Id.ToString(), n); Node node = new Node(n.Id.ToString(), CurveFactory.CreateBox(n.Bounds.Width, n.Bounds.Height, new Point(0.0, 0.0))); node.Padding = NodePadding; if (n.IsRelativeChildShape) { if (n.MovementBehaviour == ShapeMovementBehaviour.PositionOnEdgeOfParent) { if (n.Parent != null) { if (g.NodeMap.ContainsKey(n.Parent.Id.ToString())) { //node.Padding = NodePaddingRelativeOnEdge; // add edge so that this shape is kept close to its parent shape //g.AddEdge(new Edge(g.NodeMap[n.Parent.Id.ToString()], node)); } } } } g.AddNode(node); }
protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); if (gleeGraph == null) { gleeGraph = CreateAndLayoutGraph(); } DrawFromGraph(e.Graphics); }
private GleeGraph CreateAndLayoutGraph() { double w = 30; double h = 20; GleeGraph graph = new GleeGraph(); Node a = new Node("a", new Ellipse(w, h, new P())); Node b = new Node("b", CurveFactory.CreateBox(w, h, new P())); graph.AddNode(a); graph.AddNode(b); Edge e = new Edge(a, b); e.ArrowHeadAtSource = true; graph.AddEdge(e); graph.AddEdge(new Edge(a, b)); graph.CalculateLayout(); return(graph); }
/// <summary> /// Layouts the diagram by using the GLEE library. /// </summary> /// <param name="diagram">Diagram.</param> public static void Layout(Diagram diagram) { Dictionary<string, NodeShape> shapesMap = new Dictionary<string, NodeShape>(); List<LinkShape> dEdges = new List<LinkShape>(); List<LinkShape> edges = new List<LinkShape>(); List<LinkShape> edgesLocal = new List<LinkShape>(); // create glee graph GleeGraph g = new GleeGraph(); g.Margins = GraphMargins; g.MinNodeHeight = MinNodeHeight; g.MinNodeWidth = GraphMargins; foreach (NodeShape shape in diagram.Children) { // layout shape if it has children if (shape.Children.Count > 0) LayoutShape(shape, edges, dEdges); // collect edges on the same level foreach (LinkShape linkShape in shape.OutgoingLinkShapes) { if (linkShape.ToShape.Parent == null) edgesLocal.Add(linkShape); else dEdges.Add(linkShape); } AddNode(g, shape, shapesMap); } // 2. add edges foreach (LinkShape linkShape in edgesLocal) { g.AddEdge(new Edge( g.NodeMap[linkShape.FromShape.Id.ToString()], g.NodeMap[linkShape.ToShape.Id.ToString()])); } edges.AddRange(edgesLocal); // layout graph g.CalculateLayout(); // apply layout information to diagram double left = g.Left; double top = g.Top; ApplyShapesLayout(g, shapesMap, left, top); // update absolute location of shapes UpdateAbsoluteLocation(diagram); // update layout of link shapes foreach (LinkShape linkShape in edges) { linkShape.Layout(FixedGeometryPoints.None); linkShape.SourceAnchor.DiscardLocationChange = false; linkShape.TargetAnchor.DiscardLocationChange = false; } // update layout of discarded link shapes foreach (LinkShape linkShape in dEdges) { linkShape.Layout(FixedGeometryPoints.None); linkShape.SourceAnchor.DiscardLocationChange = false; linkShape.TargetAnchor.DiscardLocationChange = false; } // layout included diagrams foreach (Diagram incD in diagram.IncludedDiagrams) Layout(incD); }
private static void ApplyShapesLayout(GleeGraph g, Dictionary<string, NodeShape> shapesMap, double graphLeft, double graphTop) { // apply layout information to child shapes foreach (string key in shapesMap.Keys) { NodeShape nodeShape = shapesMap[key]; Node node = g.NodeMap[key]; // appy layout information for shape double shapeTop = (graphTop - node.BBox.Top) + HostMargin; double shapeLeft; if (graphLeft <= 0) shapeLeft = Math.Abs(graphLeft) + node.BBox.Left + HostMargin; else shapeLeft = node.BBox.Left - graphLeft + HostMargin; if (nodeShape.MovementBehaviour == ShapeMovementBehaviour.PositionOnEdgeOfParent) { if (nodeShape.Parent != null) nodeShape.SetLocation(NodeShape.CorrectPortLocation(nodeShape.Parent, nodeShape, new PointD(shapeLeft, shapeTop))); } else nodeShape.SetLocation(new PointD(shapeLeft, shapeTop)); } }
private static void AddNode(GleeGraph g, NodeShape n, Dictionary<string, NodeShape> shapesMap) { shapesMap.Add(n.Id.ToString(), n); Node node = new Node(n.Id.ToString(), CurveFactory.CreateBox(n.Bounds.Width, n.Bounds.Height, new Point(0.0, 0.0))); node.Padding = NodePadding; if (n.IsRelativeChildShape) if (n.MovementBehaviour == ShapeMovementBehaviour.PositionOnEdgeOfParent) { if (n.Parent != null) if (g.NodeMap.ContainsKey(n.Parent.Id.ToString())) { //node.Padding = NodePaddingRelativeOnEdge; // add edge so that this shape is kept close to its parent shape //g.AddEdge(new Edge(g.NodeMap[n.Parent.Id.ToString()], node)); } } g.AddNode(node); }
/// <summary> /// Layout a subgraph defined by a given shape by using the GLEE layout library. /// </summary> /// <param name="shape">Main shape.</param> /// <remarks> /// This method needs to be called within a modeling transaction. /// </remarks> private static void LayoutShape(NodeShape shape, List<LinkShape> edges, List<LinkShape> dEdges) { Dictionary<string, NodeShape> shapesMap = new Dictionary<string, NodeShape>(); // create glee graph GleeGraph g = new GleeGraph(); g.Margins = GraphMargins; g.MinNodeHeight = MinNodeHeight; g.MinNodeWidth = GraphMargins; // transform the information in the diagram into the glee graph List<LinkShape> edgesLocal = new List<LinkShape>(); foreach (NodeShape childShape in shape.Children) { // layout shape if it has children if (childShape.Children.Count > 0) LayoutShape(childShape, edges, dEdges); // collect edges on the same level foreach (LinkShape linkShape in childShape.OutgoingLinkShapes) { if (linkShape.ToShape.Parent == shape) edgesLocal.Add(linkShape); else dEdges.Add(linkShape); } AddNode(g, childShape, shapesMap); } // 2. add edges foreach (LinkShape linkShape in edgesLocal) { g.AddEdge(new Edge( g.NodeMap[linkShape.FromShape.Id.ToString()], g.NodeMap[linkShape.ToShape.Id.ToString()])); } edges.AddRange(edgesLocal); // layout graph g.CalculateLayout(); // apply layout information to diagram if (shape.Children.Count > 0) // we have no way of knowning what min size a shape has for now.. { if (shape.ResizingBehaviour == ShapeResizingBehaviour.Normal) shape.SetSize(new SizeD(g.Width + HostMargin, g.Height + HostMargin)); else if (shape.ResizingBehaviour == ShapeResizingBehaviour.FixedWidth) shape.SetSize(new SizeD(shape.Size.Width, g.Height + HostMargin)); else if (shape.ResizingBehaviour == ShapeResizingBehaviour.FixedHeight) shape.SetSize(new SizeD(g.Width + HostMargin, shape.Size.Height)); } ApplyShapesLayout(g, shapesMap, g.Left, g.Top); // update absolute location of shapes UpdateAbsoluteLocation(shape); }
private static void DrawGraph(Bitmap bitmap, GleeGraph graph) { var graphics = Graphics.FromImage(bitmap); graphics.Clear(Color.White); var matrix = new System.Drawing.Drawing2D.Matrix(); matrix.Translate(-(float)graph.BoundingBox.Left, -(float)graph.BoundingBox.Bottom); graphics.Transform = matrix; // Nodes foreach (var node in graph.NodeMap.Values) { ICurve curve = node.MovedBoundaryCurve; Ellipse el = curve as Ellipse; if (el != null) { graphics.DrawEllipse(nodePen, new RectangleF((float)el.BBox.Left, (float)el.BBox.Bottom, (float)el.BBox.Width, (float)el.BBox.Height)); var font = (node.Id == startNode) ? startNodeFont : nodeFont; var textBrush = (node.Id == startNode) ? startNodeTextBrush : nodeTextBrush; graphics.DrawString( node.Id, font, textBrush, new RectangleF((float)el.BBox.Left, (float)el.BBox.Bottom, (float)el.BBox.Width, (float)el.BBox.Height), stringFormat); } } // Edges foreach (var edge in graph.Edges) { ICurve curve = edge.Curve; var c = curve as Curve; if (c != null) { foreach (ICurve s in c.Segs) { var l = s as LineSeg; if (l != null) { graphics.DrawLine(edgePen, GleePointToDrawingPoint(l.Start), GleePointToDrawingPoint(l.End)); } var cs = s as CubicBezierSeg; if (cs != null) { graphics.DrawBezier(edgePen, GleePointToDrawingPoint(cs.B(0)), GleePointToDrawingPoint(cs.B(1)), GleePointToDrawingPoint(cs.B(2)), GleePointToDrawingPoint(cs.B(3))); } } if (edge.ArrowHeadAtSource) { DrawArrow(edge, edgePen, graphics, edge.Curve.Start, edge.ArrowHeadAtSourcePosition); } if (edge.ArrowHeadAtTarget) { DrawArrow(edge, edgePen, graphics, edge.Curve.End, edge.ArrowHeadAtTargetPosition); } if (c.Segs.Count % 2 == 0) { // Even segs var index = c.Segs.Count / 2; var l = c.Segs[index] as LineSeg; if (l != null) { var p = GleePointToDrawingPoint(l.End); DrawEdgeLabel(graphics, edge, p.X, p.Y); } var cs = c.Segs[index] as CubicBezierSeg; if (cs != null) { var p = GleePointToDrawingPoint(cs.B(2)); DrawEdgeLabel(graphics, edge, p.X, p.Y); } } else { // Uneven segs var index = c.Segs.Count / 2; var l = c.Segs[index] as LineSeg; if (l != null) { var p1 = GleePointToDrawingPoint(l.Start); var p2 = GleePointToDrawingPoint(l.End); DrawEdgeLabel(graphics, edge, (p2.X - p1.X) / 2, (p2.Y - p1.Y) / 2); } var cs = c.Segs[index] as CubicBezierSeg; if (cs != null) { var p = GleePointToDrawingPoint(cs.B(1)); DrawEdgeLabel(graphics, edge, p.X, p.Y); } } } } graphics.Flush(); }
/// <summary> /// Layouts the diagram by using the GLEE library. /// </summary> /// <param name="diagram">Diagram.</param> public static void Layout(Diagram diagram) { Dictionary <string, NodeShape> shapesMap = new Dictionary <string, NodeShape>(); List <LinkShape> dEdges = new List <LinkShape>(); List <LinkShape> edges = new List <LinkShape>(); List <LinkShape> edgesLocal = new List <LinkShape>(); // create glee graph GleeGraph g = new GleeGraph(); g.Margins = GraphMargins; g.MinNodeHeight = MinNodeHeight; g.MinNodeWidth = GraphMargins; foreach (NodeShape shape in diagram.Children) { // layout shape if it has children if (shape.Children.Count > 0) { LayoutShape(shape, edges, dEdges); } // collect edges on the same level foreach (LinkShape linkShape in shape.OutgoingLinkShapes) { if (linkShape.ToShape.Parent == null) { edgesLocal.Add(linkShape); } else { dEdges.Add(linkShape); } } AddNode(g, shape, shapesMap); } // 2. add edges foreach (LinkShape linkShape in edgesLocal) { g.AddEdge(new Edge( g.NodeMap[linkShape.FromShape.Id.ToString()], g.NodeMap[linkShape.ToShape.Id.ToString()])); } edges.AddRange(edgesLocal); // layout graph g.CalculateLayout(); // apply layout information to diagram double left = g.Left; double top = g.Top; ApplyShapesLayout(g, shapesMap, left, top); // update absolute location of shapes UpdateAbsoluteLocation(diagram); // update layout of link shapes foreach (LinkShape linkShape in edges) { linkShape.Layout(FixedGeometryPoints.None); linkShape.SourceAnchor.DiscardLocationChange = false; linkShape.TargetAnchor.DiscardLocationChange = false; } // update layout of discarded link shapes foreach (LinkShape linkShape in dEdges) { linkShape.Layout(FixedGeometryPoints.None); linkShape.SourceAnchor.DiscardLocationChange = false; linkShape.TargetAnchor.DiscardLocationChange = false; } // layout included diagrams foreach (Diagram incD in diagram.IncludedDiagrams) { Layout(incD); } }
/// <summary> /// Layout a subgraph defined by a given shape by using the GLEE layout library. /// </summary> /// <param name="shape">Main shape.</param> /// <remarks> /// This method needs to be called within a modeling transaction. /// </remarks> private static void LayoutShape(NodeShape shape, List <LinkShape> edges, List <LinkShape> dEdges) { Dictionary <string, NodeShape> shapesMap = new Dictionary <string, NodeShape>(); // create glee graph GleeGraph g = new GleeGraph(); g.Margins = GraphMargins; g.MinNodeHeight = MinNodeHeight; g.MinNodeWidth = GraphMargins; // transform the information in the diagram into the glee graph List <LinkShape> edgesLocal = new List <LinkShape>(); foreach (NodeShape childShape in shape.Children) { // layout shape if it has children if (childShape.Children.Count > 0) { LayoutShape(childShape, edges, dEdges); } // collect edges on the same level foreach (LinkShape linkShape in childShape.OutgoingLinkShapes) { if (linkShape.ToShape.Parent == shape) { edgesLocal.Add(linkShape); } else { dEdges.Add(linkShape); } } AddNode(g, childShape, shapesMap); } // 2. add edges foreach (LinkShape linkShape in edgesLocal) { g.AddEdge(new Edge( g.NodeMap[linkShape.FromShape.Id.ToString()], g.NodeMap[linkShape.ToShape.Id.ToString()])); } edges.AddRange(edgesLocal); // layout graph g.CalculateLayout(); // apply layout information to diagram if (shape.Children.Count > 0) // we have no way of knowning what min size a shape has for now.. { if (shape.ResizingBehaviour == ShapeResizingBehaviour.Normal) { shape.SetSize(new SizeD(g.Width + HostMargin, g.Height + HostMargin)); } else if (shape.ResizingBehaviour == ShapeResizingBehaviour.FixedWidth) { shape.SetSize(new SizeD(shape.Size.Width, g.Height + HostMargin)); } else if (shape.ResizingBehaviour == ShapeResizingBehaviour.FixedHeight) { shape.SetSize(new SizeD(g.Width + HostMargin, shape.Size.Height)); } } ApplyShapesLayout(g, shapesMap, g.Left, g.Top); // update absolute location of shapes UpdateAbsoluteLocation(shape); }