internal EdgeLayout CreateEdge(NodeLayout source, NodeLayout target, object edgeObject) { _dirty = true; var e = new EdgeLayout(this, source, target, edgeObject); CGraphLib.agxset(e.GraphVizEdge, _edgeDirAttribute, "none"); _objectToEdgeMap.Add(edgeObject, e); return(e); }
public void ComputeLayout() { if (!_dirty) { return; } foreach (var node in _objectToNodeMap.Values) { if (!node.IsSubGraph) { if (node.PreferredPosition != null) { CGraphLib.agxset(node.GraphVizNode, _nodePosAttribute, node.PreferredPosition.ToString()); } else { CGraphLib.agxset(node.GraphVizNode, _nodePosAttribute, ""); } if (node.PreferredSize != null) { CGraphLib.agxset(node.GraphVizNode, _nodeWidthAttribute, node.PreferredSize?.X.ToString()); CGraphLib.agxset(node.GraphVizNode, _nodeHeightAttribute, node.PreferredSize?.Y.ToString()); } else { CGraphLib.agxset(node.GraphVizNode, _nodeWidthAttribute, ""); CGraphLib.agxset(node.GraphVizNode, _nodeHeightAttribute, ""); } } else { //CGraphLib.agxset(node.GraphVizSubGraph, _nodePosAttribute, ""); //CGraphLib.agxset(node.GraphVizSubGraph, _nodeWidthAttribute, ""); //CGraphLib.agxset(node.GraphVizSubGraph, _nodeHeightAttribute, ""); CGraphLib.agxset(node.GraphVizSubGraph, _graphMarginAttribute, (this.NodeMargin * DefaultDpi).ToString()); } } CGraphLib.agxset(_graph, _graphNodeSepAttribute, this.NodeSeparation.ToString()); CGraphLib.agxset(_graph, _graphRankSepAttribute, this.RankSeparation.ToString()); CGraphLib.agxset(_graph, _graphLenAttribute, this.EdgeLength.ToString()); //CGraphLib.agxset(_graph, _graphMarginAttribute, this.NodeMargin.ToString()); _dot = GraphVizLib.Instance.Layout(_graph, _engine); var graphBb = Marshal.PtrToStringAnsi(CGraphLib.agxget(_graph, _graphBbAttribute)); if (!string.IsNullOrEmpty(graphBb)) { var parts = graphBb.Trim().Split(','); if (parts.Length == 4) { double x1, y1, x2, y2; for (int i = 0; i < parts.Length; i++) { var charSubParts = parts[i].Split('.'); if (charSubParts.Length > 1) { var subPart = charSubParts[0] + ',' + charSubParts[1]; parts[i] = subPart; } } if (Double.TryParse(parts[0], out x1) && Double.TryParse(parts[1], out y1) && Double.TryParse(parts[2], out x2) && Double.TryParse(parts[3], out y2)) { x1 /= DefaultDpi; y1 /= DefaultDpi; x2 /= DefaultDpi; y2 /= DefaultDpi; this.Position = new Point2D((x1 + x2) / 2, (y1 + y2) / 2); this.Size = new Point2D(x2 - x1, y2 - y1); } CGraphLib.agxset(_graph, _graphBbAttribute, ""); } } foreach (var node in _objectToNodeMap.Values) { if (node.IsSubGraph) { var gvBb = Marshal.PtrToStringAnsi(CGraphLib.agxget(node.GraphVizSubGraph, _graphBbAttribute)); if (!string.IsNullOrEmpty(gvBb)) { var parts = gvBb.Trim().Split(','); if (parts.Length == 4) { double x1, y1, x2, y2; for (int i = 0; i < parts.Length; i++) { var charSubParts = parts[i].Split('.'); if (charSubParts.Length > 1) { var subPart = charSubParts[0] + ',' + charSubParts[1]; parts[i] = subPart; } } if (double.TryParse(parts[0], out x1) && double.TryParse(parts[1], out y1) && double.TryParse(parts[2], out x2) && double.TryParse(parts[3], out y2)) { x1 /= DefaultDpi; y1 /= DefaultDpi; x2 /= DefaultDpi; y2 /= DefaultDpi; node.Position = new Point2D((x1 + x2) / 2, (y1 + y2) / 2); node.Size = new Point2D(x2 - x1, y2 - y1); } } CGraphLib.agxset(node.GraphVizSubGraph, _graphBbAttribute, ""); } else { if (node.PreferredSize != null) { node.Size = node.PreferredSize.Value; } } } else { var gvPos = Marshal.PtrToStringAnsi(CGraphLib.agxget(node.GraphVizNode, _nodePosAttribute)); if (!string.IsNullOrEmpty(gvPos)) { node.Position = new Point2D(gvPos, GraphLayout.DefaultDpi); CGraphLib.agxset(node.GraphVizNode, _nodePosAttribute, ""); } var gvWidth = Marshal.PtrToStringAnsi(CGraphLib.agxget(node.GraphVizNode, _nodeWidthAttribute)); var gvHeight = Marshal.PtrToStringAnsi(CGraphLib.agxget(node.GraphVizNode, _nodeHeightAttribute)); if (!string.IsNullOrEmpty(gvWidth) && !string.IsNullOrEmpty(gvHeight)) { if (double.TryParse(gvWidth, out var width) && double.TryParse(gvHeight, out var height)) { node.Size = new Point2D(width, height); } } else { if (node.PreferredSize != null) { node.Size = node.PreferredSize.Value; } } } } foreach (var edge in _objectToEdgeMap.Values) { var gvPos = Marshal.PtrToStringAnsi(CGraphLib.agxget(edge.GraphVizEdge, _edgePosAttribute)); if (!string.IsNullOrEmpty(gvPos)) { edge.SetControlPoints(gvPos); CGraphLib.agxset(edge.GraphVizEdge, _edgePosAttribute, ""); } } _dirty = false; }