DiagramControl provides two methods that make it easier to use external graph layout algorithms to arrange diagram shapes. The GraphOperations.GetDiagramGraph method reads the diagram currently loaded into DiagramControl and returns the Graph object that contains collections of edges and nodes represented by diagram items. You can use this information to calculate positions for diagram shapes. Then, for every shape, create the PositionInfo object containing the shape reference and its position. To apply the layout to the loaded diagram, call the DiagramControl.RelayoutDiagramItems extension method that accepts the collection of PositionInfo objects.
This example demonstrates how the GetDiagramGraph and RelayoutDiagramItems methods can be used to connect the Microsoft Automatic Graph Layout library to DiagramControl.
View Example
using DevExpress.Diagram.Core;
using DevExpress.Diagram.Core.Layout;
using DevExpress.Diagram.Core.Routing;
using Microsoft.Msagl.Core.Layout;
using Microsoft.Msagl.Core.Routing;
using System.Collections.Generic;
namespace MsaglHelpers {
public class GraphLayout {
GeometryGraph GeometryGraph { get; set; }
EdgeRoutingMode RoutingMode { get { return LayoutCalculator.LayoutAlgorithmSettings.EdgeRoutingSettings.EdgeRoutingMode; } }
protected ILayoutCalculator LayoutCalculator { get; set; }
public GraphLayout(ILayoutCalculator layoutCalculator) {
this.LayoutCalculator = layoutCalculator;
}
public virtual IEnumerable<PositionInfo<IDiagramItem>> RelayoutGraphNodesPosition(Graph<IDiagramItem> graph) {
GeometryGraph = MsaglGeometryGraphHelpers.CreateGeometryGraph(graph);
LayoutCalculator.CalculateLayout(GeometryGraph);
return MsaglGeometryGraphHelpers.GetGetNodesPositionInfo(GeometryGraph);
}
public ConnectorType GetDiagramConnectorType() {
return RoutingHelper.GetDiagramConnectorType(RoutingMode);
}
}
}
using Microsoft.Msagl;
using Microsoft.Msagl.Core.Geometry.Curves;
using Microsoft.Msagl.Layout.Layered;
using Microsoft.Msagl.Miscellaneous;
using System;
using Microsoft.Msagl.Core.Layout;
using Microsoft.Msagl.Core.Routing;
namespace MsaglHelpers {
public class SugiyamaLayoutCalculator : ILayoutCalculator {
public LayoutAlgorithmSettings LayoutAlgorithmSettings {
get {
return new SugiyamaLayoutSettings() {
NodeSeparation = 30,
Transformation = PlaneTransformation.Rotation(Math.PI / 2),
EdgeRoutingSettings = { EdgeRoutingMode = EdgeRoutingMode.SugiyamaSplines }
};
}
}
public void CalculateLayout(GeometryGraph geometryGraph) {
LayoutHelpers.CalculateLayout( geometryGraph, LayoutAlgorithmSettings, null);
}
}
}
using DevExpress.Diagram.Core;
using DevExpress.Diagram.Core.Layout;
using DevExpress.Diagram.Core.Routing;
using Microsoft.Msagl.Core.Layout;
using Microsoft.Msagl.Core.Routing;
using Microsoft.Msagl.Prototype.Phylo;
using System.Collections.Generic;
namespace MsaglHelpers {
public class PhyloTreeLayout : GraphLayout {
PhyloTree Tree { get; set; }
public PhyloTreeLayout(ILayoutCalculator layoutCalculator) : base(layoutCalculator) { }
public override IEnumerable<PositionInfo<IDiagramItem>> RelayoutGraphNodesPosition(Graph<IDiagramItem> graph) {
Tree = MsaglGeometryGraphHelpers.CreatePhyloTrees(graph);
LayoutCalculator.CalculateLayout(Tree);
return MsaglGeometryGraphHelpers.GetGetNodesPositionInfo(Tree);
}
}
}
Imports DevExpress.Diagram.Core
Imports DevExpress.Diagram.Core.Layout
Imports DevExpress.Diagram.Core.Routing
Imports Microsoft.Msagl.Core.Layout
Imports Microsoft.Msagl.Core.Routing
Imports System.Collections.Generic
Namespace MsaglHelpers
Public Class GraphLayout
Private Property GeometryGraph() As GeometryGraph
Private ReadOnly Property RoutingMode() As EdgeRoutingMode
Get
Return LayoutCalculator.LayoutAlgorithmSettings.EdgeRoutingSettings.EdgeRoutingMode
End Get
End Property
Protected Property LayoutCalculator() As ILayoutCalculator
Public Sub New(ByVal layoutCalculator As ILayoutCalculator)
Me.LayoutCalculator = layoutCalculator
End Sub
Public Overridable Function RelayoutGraphNodesPosition(ByVal graph As Graph(Of IDiagramItem)) As IEnumerable(Of PositionInfo(Of IDiagramItem))
GeometryGraph = MsaglGeometryGraphHelpers.CreateGeometryGraph(graph)
LayoutCalculator.CalculateLayout(GeometryGraph)
Return MsaglGeometryGraphHelpers.GetGetNodesPositionInfo(GeometryGraph)
End Function
Public Function GetDiagramConnectorType() As ConnectorType
Return RoutingHelper.GetDiagramConnectorType(RoutingMode)
End Function
End Class
End Namespace
Imports DevExpress.Diagram.Core
Imports DevExpress.Diagram.Core.Layout
Imports DevExpress.Diagram.Core.Routing
Imports Microsoft.Msagl.Core.Layout
Imports Microsoft.Msagl.Core.Routing
Imports Microsoft.Msagl.Prototype.Phylo
Imports System.Collections.Generic
Namespace MsaglHelpers
Public Class PhyloTreeLayout
Inherits GraphLayout
Private Property Tree() As PhyloTree
Public Sub New(ByVal layoutCalculator As ILayoutCalculator)
MyBase.New(layoutCalculator)
End Sub
Public Overrides Function RelayoutGraphNodesPosition(ByVal graph As Graph(Of IDiagramItem)) As IEnumerable(Of PositionInfo(Of IDiagramItem))
Tree = MsaglGeometryGraphHelpers.CreatePhyloTrees(graph)
LayoutCalculator.CalculateLayout(Tree)
Return MsaglGeometryGraphHelpers.GetGetNodesPositionInfo(Tree)
End Function
End Class
End Namespace
Imports Microsoft.Msagl
Imports Microsoft.Msagl.Core.Geometry.Curves
Imports Microsoft.Msagl.Layout.Layered
Imports Microsoft.Msagl.Miscellaneous
Imports System
Imports Microsoft.Msagl.Core.Layout
Imports Microsoft.Msagl.Core.Routing
Namespace MsaglHelpers
Public Class SugiyamaLayoutCalculator
Implements ILayoutCalculator
Public ReadOnly Property LayoutAlgorithmSettings() As LayoutAlgorithmSettings Implements ILayoutCalculator.LayoutAlgorithmSettings
Get
Return New SugiyamaLayoutSettings() With {
.NodeSeparation = 30, .Transformation = PlaneTransformation.Rotation(Math.PI / 2), .EdgeRoutingSettings = New EdgeRoutingSettings() With {.EdgeRoutingMode = EdgeRoutingMode.SugiyamaSplines}
}
End Get
End Property
Public Sub CalculateLayout(ByVal geometryGraph As GeometryGraph) Implements ILayoutCalculator.CalculateLayout
LayoutHelpers.CalculateLayout(geometryGraph, LayoutAlgorithmSettings, Nothing)
End Sub
End Class
End Namespace