#c# #winforms #msagl
Вопрос:
Я пытаюсь установить минимальное расстояние между несвязанными узлами в MSAGL (WinForms), версия 1.1.3. Пользователь создает график с нуля. Это включает в себя создание узлов и перетаскивание между узлами для создания ребер. Но все узлы, у которых нет краев, прилипают к другим, как полистирольные шарики к шерстяному джемперу.
Я хочу, чтобы все узлы, с ребрами или без них, имели минимальное расстояние. Вероятно, на этот вопрос есть простой ответ, который до сих пор от меня ускользает. После поиска соответствующих материалов на GitHub, здесь и в Google я безуспешно пытался:
LayoutAlgorithmSettings.NodeSeparation = 200; //works well between nodes that have edges between
LayoutAlgorithmSettings.ClusterMargin = 200;
LayoutAlgorithmSettings.PackingMethod = Microsoft.Msagl.Core.Layout.PackingMethod.Columns;
LayoutAlgorithmSettings.PackingAspectRatio = 2;
LayoutAlgorithmSettings.EdgeRoutingSettings.Padding = 100;
Вот код, генерирующий график (некоторые объявления и другие детали опущены). Я использую макет MDS:
Graph graph = new Microsoft.Msagl.Drawing.Graph("graph");
graph.LayoutAlgorithmSettings = new Microsoft.Msagl.Layout.MDS.MdsLayoutSettings();
//add steps
foreach (Step step in config.Steps)
{
Node node = new Node(step.Name);
node.UserData = step;
UpdateNodeColour(node);
graph.AddNode(node);
}
//add transitions (edges)
foreach(Transition t in config.Transitions)
graph.AddEdge(t.FromStep.Name, t.Name, t.ToStep.Name);
gViewer.Graph = graph;
Кстати, MSAGL — это фантастика! Такой отличный инструмент для визуализации и редактирования государственных машин.
Ответ №1:
У меня была та же проблема с перекрытием. Я решил проблему, используя приведенное ниже.
Как только вы заполнили свой график, добавьте разделение узлов GeometryGraph
с помощью Microsoft.Msagl.Core.Layout.GraphConnectedComponents.CreateComponents()
:
if (graph.NodeCount > 1)
{
GeometryGraph geomGraph = graph.GeometryGraph;
IEnumerable< GeometryGraph> geomGraphComponents =
GraphConnectedComponents.CreateComponents(geomGraph.Nodes, geomGraph.Edges);
SugiyamaLayoutSettings settings = new SugiyamaLayoutSettings();
foreach (GeometryGraph subgraph in geomGraphComponents)
{
LayeredLayout layout = new LayeredLayout(subgraph, settings);
subgraph.Margins = settings.NodeSeparation / 2;
layout.Run();
}
MdsGraphLayout.PackGraphs(geomGraphComponents, settings);
geomGraph.UpdateBoundingBox();
}
См. Пример № 1 в LayeredLayout.Запустите Примеры:
Примечание: Из исходного примера не устанавливайте «gViewer1.NeedToCalculateLayout = false;», если вы собираетесь обновить свой график.