public Geometry DefiningGeometry(Edge drawingEdge, Microsoft.Msagl.Core.Layout.Edge geometryEdge) { if (geometryEdge.Curve == null) { Path.Visibility = Visibility.Hidden; } else { Path.Visibility = Visibility.Visible; if (Path.Triggers.Count == 0) { AddPathAnimation(); } } var streamGeometry = new StreamGeometry(); using (StreamGeometryContext context = streamGeometry.Open()) { FillStreamGeometryContext(context, drawingEdge, geometryEdge); return(streamGeometry); } }
public static void DrawCrossEdges(DGraph graph, IEnumerable <DEdge> edges) { GeometryGraph ggAux = new GeometryGraph(); Dictionary <DNode, GeometryNode> nodeMap = new Dictionary <DNode, GeometryNode>(); foreach (DEdge edge in edges) { if (edge.Label != null) { edge.Label.MeasureLabel(); } nodeMap[edge.Source] = null; nodeMap[edge.Target] = null; } FillAuxGraph(ggAux, graph, new GeometryPoint(0.0, 0.0), nodeMap); Dictionary <DEdge, GeometryEdge> edgeMap = new Dictionary <DEdge, GeometryEdge>(); foreach (DEdge edge in edges) { GeometryEdge gEdge = new GeometryEdge(nodeMap[edge.Source], nodeMap[edge.Target]) { GeometryParent = ggAux }; gEdge.EdgeGeometry.SourceArrowhead = edge.GeometryEdge.EdgeGeometry.SourceArrowhead; gEdge.EdgeGeometry.TargetArrowhead = edge.GeometryEdge.EdgeGeometry.TargetArrowhead; gEdge.Label = edge.GeometryEdge.Label; edgeMap[edge] = gEdge; ggAux.Edges.Add(gEdge); } var router = new SplineRouter(ggAux, 3.0, 2.0, Math.PI / 6.0) { ContinueOnOverlaps = true }; router.Run(); foreach (DEdge edge in edges) { edge.GeometryEdge = edgeMap[edge]; if (edge.DrawingEdge.Label != null) { if (edge.GeometryEdge.Label.Center == new GeometryPoint()) { edge.GeometryEdge.Label.Center = edge.GeometryEdge.BoundingBox.Center; } edge.DrawingEdge.Label.GeometryLabel = edge.GeometryEdge.Label; } } foreach (DEdge edge in edges) { edge.MakeVisual(); Canvas.SetZIndex(edge, 20000); graph.MainCanvas.Children.Add(edge); if (edge.Label != null) { edge.Label.MakeVisual(); Canvas.SetZIndex(edge.Label, 20000); graph.MainCanvas.Children.Add(edge.Label); } } }
private Dom.BezierCurve draw_edge_bezier(MSAGL.Core.Layout.Edge edge) { var final_bez_points = MsaglUtil.ToVAPoints(edge).Select(p => this.ToDocumentCoordinates(p)).ToList(); var bez_shape = new Dom.BezierCurve(final_bez_points); return(bez_shape); }
public static IList <Point> ToVAPoints(MG.Core.Layout.Edge edge) { if (edge.Curve is MG.Core.Geometry.Curves.Curve) { var curve = (MG.Core.Geometry.Curves.Curve)edge.Curve; var final_bez_points = new List <Point> { MsaglUtil.ToVAPoint(edge.Curve.Start) }; foreach (var cur_seg in curve.Segments) { if (cur_seg is MG.Core.Geometry.Curves.CubicBezierSegment) { var bezier_seg = (MG.Core.Geometry.Curves.CubicBezierSegment)cur_seg; var bez_points = new[] { 0, 1, 2, 3 } .Select(bezier_seg.B) .Select(MsaglUtil.ToVAPoint) .ToArray(); final_bez_points.AddRange(bez_points.Skip(1)); } else if (cur_seg is MG.Core.Geometry.Curves.LineSegment) { var line_seg = (MG.Core.Geometry.Curves.LineSegment)cur_seg; final_bez_points.Add(MsaglUtil.ToVAPoint(line_seg.Start)); final_bez_points.Add(MsaglUtil.ToVAPoint(line_seg.End)); final_bez_points.Add(MsaglUtil.ToVAPoint(line_seg.End)); } else { throw new InvalidOperationException("Unsupported Curve Segment type"); } } return(final_bez_points); } else if (edge.Curve is MG.Core.Geometry.Curves.LineSegment) { var final_bez_points = new List <Point> { MsaglUtil.ToVAPoint(edge.Curve.Start) }; var line_seg = (MG.Core.Geometry.Curves.LineSegment)edge.Curve; final_bez_points.Add(MsaglUtil.ToVAPoint(line_seg.Start)); final_bez_points.Add(MsaglUtil.ToVAPoint(line_seg.End)); final_bez_points.Add(MsaglUtil.ToVAPoint(line_seg.End)); return(final_bez_points); } throw new Exception(); }
public static IList <VisioAutomation.Geometry.Point> ToVAPoints(MG.Core.Layout.Edge edge) { if (edge.Curve is MG.Core.Geometry.Curves.Curve) { var curve = (MG.Core.Geometry.Curves.Curve)edge.Curve; var final_bez_points = new List <VisioAutomation.Geometry.Point> { MsaglUtil.ToVAPoint(edge.Curve.Start) }; foreach (var cur_seg in curve.Segments) { if (cur_seg is MG.Core.Geometry.Curves.CubicBezierSegment) { var bezier_seg = (MG.Core.Geometry.Curves.CubicBezierSegment)cur_seg; // The first point at index 0 is deliberately not added final_bez_points.Add(MsaglUtil.ToVAPoint(bezier_seg.B(1))); final_bez_points.Add(MsaglUtil.ToVAPoint(bezier_seg.B(2))); final_bez_points.Add(MsaglUtil.ToVAPoint(bezier_seg.B(3))); } else if (cur_seg is MG.Core.Geometry.Curves.LineSegment) { var line_seg = (MG.Core.Geometry.Curves.LineSegment)cur_seg; final_bez_points.Add(MsaglUtil.ToVAPoint(line_seg.Start)); final_bez_points.Add(MsaglUtil.ToVAPoint(line_seg.End)); final_bez_points.Add(MsaglUtil.ToVAPoint(line_seg.End)); } else { throw new InvalidOperationException("Unsupported Curve Segment type"); } } return(final_bez_points); } else if (edge.Curve is MG.Core.Geometry.Curves.LineSegment) { var final_bez_points = new List <VisioAutomation.Geometry.Point> { MsaglUtil.ToVAPoint(edge.Curve.Start) }; var line_seg = (MG.Core.Geometry.Curves.LineSegment)edge.Curve; final_bez_points.Add(MsaglUtil.ToVAPoint(line_seg.Start)); final_bez_points.Add(MsaglUtil.ToVAPoint(line_seg.End)); final_bez_points.Add(MsaglUtil.ToVAPoint(line_seg.End)); return(final_bez_points); } throw new System.ArgumentException("Unhandled Curve Type"); }
private void LayoutLinkedShapes(Graph graph, out Microsoft.Msagl.Core.Layout.GeometryGraph geometry) { var geomGraph = new Microsoft.Msagl.Core.Layout.GeometryGraph(); var layoutSettings = new Microsoft.Msagl.Layout.Layered.SugiyamaLayoutSettings(); Microsoft.Msagl.Core.Layout.Node EnsureNode(Node node) { var res = geomGraph.Nodes.FirstOrDefault(n => n.UserData == node); if (res == null) { var geomNode = new Microsoft.Msagl.Core.Layout.Node( Microsoft.Msagl.Core.Geometry.Curves.CurveFactory.CreateRectangle( ShapeSize, ShapeSize, new Microsoft.Msagl.Core.Geometry.Point() ), node ); geomGraph.Nodes.Add(geomNode); return(geomNode); } return(res); } foreach (var l in graph.Links) { var n1 = EnsureNode(l.Node1); var n2 = EnsureNode(l.Node2); var e = new Microsoft.Msagl.Core.Layout.Edge(n1, n2); geomGraph.Edges.Add(e); } LayoutHelpers.CalculateLayout(geomGraph, layoutSettings, null); foreach (var kv in nodesAndShapes) { var pos = geomGraph.Nodes.FirstOrDefault(n => n.UserData == kv.Key)?.Center; if (pos.HasValue) { kv.Value.X = (int)pos.Value.X + ShapeSize; kv.Value.Y = Diagram.Height - (int)pos.Value.Y + ShapeSize / 2; } } geometry = geomGraph; }
void FillStreamGeometryContext(StreamGeometryContext context, Edge drawingEdge, Microsoft.Msagl.Core.Layout.Edge geometryEdge) { if (geometryEdge.Curve == null) { return; } FillContextForICurve(context, geometryEdge.Curve); if (geometryEdge.EdgeGeometry != null && geometryEdge.EdgeGeometry.SourceArrowhead != null) { AddArrow(drawingEdge, context, geometryEdge.Curve.Start, geometryEdge.EdgeGeometry.SourceArrowhead.TipPosition, drawingEdge.SourceNode.Attr.LineWidth); } if (geometryEdge.EdgeGeometry != null && geometryEdge.EdgeGeometry.TargetArrowhead != null) { AddArrow(drawingEdge, context, geometryEdge.Curve.End, geometryEdge.EdgeGeometry.TargetArrowhead.TipPosition, drawingEdge.TargetNode.Attr.LineWidth); } }
IEnumerable <RectangleNode <object> > EdgeRectNodes(GeomEdge edge) { const int parts = 64; //divide each edge into 64 segments var curve = edge.Curve; double delta = (curve.ParEnd - curve.ParStart) / parts; Point p0 = curve.Start; for (int i = 1; i <= parts; i++) { yield return(new RectangleNode <object>(edge, new Rectangle(p0, p0 = curve[curve.ParStart + i * delta]))); } if (edge.ArrowheadAtSource) { yield return(new RectangleNode <object>(edge, new Rectangle(edge.EdgeGeometry.SourceArrowhead.TipPosition, curve.Start))); } if (edge.ArrowheadAtTarget) { yield return(new RectangleNode <object>(edge, new Rectangle(edge.EdgeGeometry.TargetArrowhead.TipPosition, curve.End))); } }
private MSAGL.Core.Layout.GeometryGraph CreateMsaglGraph(DirectedGraphLayout layout_diagram) { var mg_graph = new MSAGL.Core.Layout.GeometryGraph(); // Create the nodes in MSAGL foreach (var layout_shape in layout_diagram.Shapes) { var nodesize = this.ToMGCoordinates(layout_shape.Size ?? this.LayoutOptions.DefaultShapeSize); var node_user_data = new NodeUserData(layout_shape.ID, layout_shape); var center = new MSAGL.Core.Geometry.Point(); var rectangle = MSAGL.Core.Geometry.Curves.CurveFactory.CreateRectangle(nodesize.Width, nodesize.Height, center); var mg_node = new MSAGL.Core.Layout.Node(rectangle, node_user_data); mg_graph.Nodes.Add(mg_node); } this.validate_connectors(layout_diagram); var mg_coordinates = this.ToMGCoordinates(this.DefaultBezierConnectorLabelBoxSize); var map_id_to_ud = new Dictionary <string, MSAGL.Core.Layout.Node>(); foreach (var n in mg_graph.Nodes) { var ud = (NodeUserData)n.UserData; if (ud != null) { map_id_to_ud[ud.ID] = n; } } // Create the MG Connectors foreach (var layout_connector in layout_diagram.Connectors) { if (layout_connector.From == null) { throw new ArgumentException("Connector's From node is null"); } if (layout_connector.To == null) { throw new ArgumentException("Connector's To node is null"); } var from_node = map_id_to_ud[layout_connector.From.ID]; var to_node = map_id_to_ud[layout_connector.To.ID]; var new_edge = new MSAGL.Core.Layout.Edge(from_node, to_node); // TODO: MSAGL //new_edge.ArrowheadAtTarget = false; new_edge.UserData = new NodeUserData(layout_connector.ID, layout_connector); mg_graph.Edges.Add(new_edge); new_edge.Label = new MSAGL.Core.Layout.Label(mg_coordinates.Width, mg_coordinates.Height, new_edge); } var geom_graph_components = MSAGL.Core.Layout.GraphConnectedComponents.CreateComponents(mg_graph.Nodes, mg_graph.Edges); var settings = new MSAGL.Layout.Layered.SugiyamaLayoutSettings(); foreach (var subgraph in geom_graph_components) { var layout = new Microsoft.Msagl.Layout.Layered.LayeredLayout(subgraph, settings); subgraph.Margins = settings.NodeSeparation / 2; layout.Run(); } // Pack the graphs using Golden Aspect Ratio MSAGL.Layout.MDS.MdsGraphLayout.PackGraphs(geom_graph_components, settings); //Update the graphs bounding box mg_graph.UpdateBoundingBox(); this._mg_bb = new VA.Drawing.Rectangle( mg_graph.BoundingBox.Left, mg_graph.BoundingBox.Bottom, mg_graph.BoundingBox.Right, mg_graph.BoundingBox.Top); this._layout_bb = new VA.Drawing.Rectangle(0, 0, this._mg_bb.Width, this._mg_bb.Height) .Multiply(this.ScaleToDocument, this.ScaleToDocument); return(mg_graph); }
IEnumerable<RectangleNode<object >> EdgeRectNodes(GeomEdge edge) { const int parts = 64; //divide each edge into 64 segments var curve=edge.Curve; double delta=(curve.ParEnd-curve.ParStart)/parts; Point p0=curve.Start; for (int i = 1; i <= parts; i++) yield return new RectangleNode<object>(edge, new Rectangle(p0, p0=curve[curve.ParStart+i*delta])); if (edge.ArrowheadAtSource) yield return new RectangleNode<object>(edge, new Rectangle(edge.EdgeGeometry.SourceArrowhead.TipPosition, curve.Start)); if (edge.ArrowheadAtTarget) yield return new RectangleNode<object>(edge, new Rectangle(edge.EdgeGeometry.TargetArrowhead.TipPosition, curve.End)); }
private MSAGL.Core.Layout.GeometryGraph _create_msagl_graph(DirectedGraphLayout dglayout) { var msagl_graph = new MSAGL.Core.Layout.GeometryGraph(); // Create the nodes in MSAGL foreach (var layout_shape in dglayout.Nodes) { var nodesize = this._to_mg_coordinates(layout_shape.Size ?? this.LayoutOptions.DefaultShapeSize); var node_user_data = new ElementUserData(layout_shape.ID, layout_shape); var center = new MSAGL.Core.Geometry.Point(); var rectangle = MSAGL.Core.Geometry.Curves.CurveFactory.CreateRectangle(nodesize.Width, nodesize.Height, center); var mg_node = new MSAGL.Core.Layout.Node(rectangle, node_user_data); msagl_graph.Nodes.Add(mg_node); } this.validate_connectors(dglayout); var mg_coordinates = this._to_mg_coordinates(this.DefaultBezierConnectorLabelBoxSize); var map_id_to_ud = new Dictionary <string, MSAGL.Core.Layout.Node>(); foreach (var n in msagl_graph.Nodes) { var ud = (ElementUserData)n.UserData; if (ud != null) { map_id_to_ud[ud.ID] = n; } } // Create the MG Connectors foreach (var layout_connector in dglayout.Edges) { if (layout_connector.From == null) { throw new ArgumentException("Connector's From node is null"); } if (layout_connector.To == null) { throw new ArgumentException("Connector's To node is null"); } var from_node = map_id_to_ud[layout_connector.From.ID]; var to_node = map_id_to_ud[layout_connector.To.ID]; var new_edge = new MSAGL.Core.Layout.Edge(from_node, to_node); // TODO: MSAGL //new_edge.ArrowheadAtTarget = false; new_edge.UserData = new ElementUserData(layout_connector.ID, layout_connector); msagl_graph.Edges.Add(new_edge); new_edge.Label = new MSAGL.Core.Layout.Label(mg_coordinates.Width, mg_coordinates.Height, new_edge); } var msagl_graphs = MSAGL.Core.Layout.GraphConnectedComponents.CreateComponents(msagl_graph.Nodes, msagl_graph.Edges); var msagl_sugiyamasettings = new MSAGL.Layout.Layered.SugiyamaLayoutSettings(); if (this.LayoutOptions.Direction == MsaglDirection.TopToBottom) { // do nothing } else if (this.LayoutOptions.Direction == MsaglDirection.BottomToTop) { msagl_sugiyamasettings.Transformation = MSAGL.Core.Geometry.Curves.PlaneTransformation.Rotation(Math.PI); } else if (this.LayoutOptions.Direction == MsaglDirection.LeftToRight) { msagl_sugiyamasettings.Transformation = MSAGL.Core.Geometry.Curves.PlaneTransformation.Rotation(Math.PI / 2); } else if (this.LayoutOptions.Direction == MsaglDirection.RightToLeft) { msagl_sugiyamasettings.Transformation = MSAGL.Core.Geometry.Curves.PlaneTransformation.Rotation(-Math.PI / 2); } else { throw new System.ArgumentOutOfRangeException(); } foreach (var subgraph in msagl_graphs) { var layout = new Microsoft.Msagl.Layout.Layered.LayeredLayout(subgraph, msagl_sugiyamasettings); subgraph.Margins = msagl_sugiyamasettings.NodeSeparation / 2; layout.Run(); } // Pack the graphs using Golden Aspect Ratio MSAGL.Layout.MDS.MdsGraphLayout.PackGraphs(msagl_graphs, msagl_sugiyamasettings); //Update the graphs bounding box msagl_graph.UpdateBoundingBox(); this._msagl_bb = new VA.Geometry.Rectangle( msagl_graph.BoundingBox.Left, msagl_graph.BoundingBox.Bottom, msagl_graph.BoundingBox.Right, msagl_graph.BoundingBox.Top); this._visio_bb = new VA.Geometry.Rectangle(0, 0, this._msagl_bb.Width, this._msagl_bb.Height) .Multiply(this._scale_to_document, this._scale_to_document); return(msagl_graph); }