MSAGL:您能否强制从节点上的固定位置绘制边缘线,例如节点的四个基本边界中点?
MSAGL: Can you force edge lines to be drawn from a fixed location on a node like the node's four cardinal border midpoints?
是否可以强制从节点的四个基本边界中点绘制边线?即节点边界上的十二点钟、三点钟、六点钟和九点钟位置,类似于 Visio 或 PowerPoint 中的连接器。
我给 MSAGL 的主要作者 Lev Nachmanson 发了邮件,他很友好地回复了。他确认,截至 2022 年 1 月,MSAGL 目前没有此类功能。
编辑 1: MSAGL 有 FloatingPort
个对象 看起来 就像它们可以用来手动定位边的端点行:Edge
对象具有 SourcePort
和 TargetPort
属性。我还没有找到任何关于如何实际使用这些的文档或教程。任何指点表示赞赏。
编辑 2: 可以通过计算一次布局,然后 post-layout,强制 EdgeRouter
重新路由 foreach 中的所有边来完成循环。
我从 and https://github.com/microsoft/automatic-graph-layout/issues/250 和大量的试验和错误中汲取了大量灵感。
private void Button1_Click(object sender, EventArgs e)
{
//gViewer1.Invalidate();
gViewer1.CalculateLayout(_visgraph);
Microsoft.Msagl.Routing.InteractiveEdgeRouter edgeRouter = new Microsoft.Msagl.Routing.InteractiveEdgeRouter(_visgraph.GeometryGraph.Nodes.Select(n => n.BoundaryCurve), 3, 0.65 * 3, 0);
edgeRouter.Run();
Microsoft.Msagl.Core.Geometry.SmoothedPolyline ignore;
foreach (var edge in _visgraph.GeometryGraph.Edges)
{
Microsoft.Msagl.Core.Layout.FloatingPort p1 =
new Microsoft.Msagl.Core.Layout.FloatingPort(edge.Source.BoundaryCurve
, new Microsoft.Msagl.Core.Geometry.Point(edge.Source.BoundingBox.Right
,edge.Source.BoundingBox.Center.Y));
Microsoft.Msagl.Core.Layout.FloatingPort p2 =
new Microsoft.Msagl.Core.Layout.FloatingPort(edge.Target.BoundaryCurve
, new Microsoft.Msagl.Core.Geometry.Point(edge.Target.BoundingBox.Left
,edge.Target.BoundingBox.Center.Y));
edge.SourcePort = p1;
edge.TargetPort = p2;
edge.Curve = edgeRouter.RouteSplineFromPortToPortWhenTheWholeGraphIsReady(edge.SourcePort, edge.TargetPort, true, out ignore);
Microsoft.Msagl.Core.Layout.Arrowheads.TrimSplineAndCalculateArrowheads(edge
,edge.Curve
,true
,true);
}
}
是否可以强制从节点的四个基本边界中点绘制边线?即节点边界上的十二点钟、三点钟、六点钟和九点钟位置,类似于 Visio 或 PowerPoint 中的连接器。
我给 MSAGL 的主要作者 Lev Nachmanson 发了邮件,他很友好地回复了。他确认,截至 2022 年 1 月,MSAGL 目前没有此类功能。
编辑 1: MSAGL 有 FloatingPort
个对象 看起来 就像它们可以用来手动定位边的端点行:Edge
对象具有 SourcePort
和 TargetPort
属性。我还没有找到任何关于如何实际使用这些的文档或教程。任何指点表示赞赏。
编辑 2: 可以通过计算一次布局,然后 post-layout,强制 EdgeRouter
重新路由 foreach 中的所有边来完成循环。
我从
private void Button1_Click(object sender, EventArgs e)
{
//gViewer1.Invalidate();
gViewer1.CalculateLayout(_visgraph);
Microsoft.Msagl.Routing.InteractiveEdgeRouter edgeRouter = new Microsoft.Msagl.Routing.InteractiveEdgeRouter(_visgraph.GeometryGraph.Nodes.Select(n => n.BoundaryCurve), 3, 0.65 * 3, 0);
edgeRouter.Run();
Microsoft.Msagl.Core.Geometry.SmoothedPolyline ignore;
foreach (var edge in _visgraph.GeometryGraph.Edges)
{
Microsoft.Msagl.Core.Layout.FloatingPort p1 =
new Microsoft.Msagl.Core.Layout.FloatingPort(edge.Source.BoundaryCurve
, new Microsoft.Msagl.Core.Geometry.Point(edge.Source.BoundingBox.Right
,edge.Source.BoundingBox.Center.Y));
Microsoft.Msagl.Core.Layout.FloatingPort p2 =
new Microsoft.Msagl.Core.Layout.FloatingPort(edge.Target.BoundaryCurve
, new Microsoft.Msagl.Core.Geometry.Point(edge.Target.BoundingBox.Left
,edge.Target.BoundingBox.Center.Y));
edge.SourcePort = p1;
edge.TargetPort = p2;
edge.Curve = edgeRouter.RouteSplineFromPortToPortWhenTheWholeGraphIsReady(edge.SourcePort, edge.TargetPort, true, out ignore);
Microsoft.Msagl.Core.Layout.Arrowheads.TrimSplineAndCalculateArrowheads(edge
,edge.Curve
,true
,true);
}
}