diff --git a/Sources/DotNetGraph.Tests/BasicGraphTests.cs b/Sources/DotNetGraph.Tests/BasicGraphTests.cs index 7c98c7b..4a407ab 100644 --- a/Sources/DotNetGraph.Tests/BasicGraphTests.cs +++ b/Sources/DotNetGraph.Tests/BasicGraphTests.cs @@ -1,3 +1,4 @@ +using DotNetGraph.Core; using DotNetGraph.Extensions; using DotNetGraph.Node; using NFluent; @@ -64,5 +65,18 @@ public void GraphWithoutStringsFormat() Check.That(compiled).HasSameValueAs("digraph \"TestGraph\" { \"TestNode\"[label=\"\\lTesting\"]; }"); } + + [Fact] + public void GraphWithLayout() + { + var graph = new DotGraph("TestGraph", true) + { + Layout = DotGraphLayout.Neato + }; + + var compiled = graph.Compile(false, false); + + Check.That(compiled).HasSameValueAs("digraph \"TestGraph\" { layout=neato; }"); + } } } \ No newline at end of file diff --git a/Sources/DotNetGraph/Attributes/DotGraphLayoutAttribute.cs b/Sources/DotNetGraph/Attributes/DotGraphLayoutAttribute.cs new file mode 100644 index 0000000..cee71f5 --- /dev/null +++ b/Sources/DotNetGraph/Attributes/DotGraphLayoutAttribute.cs @@ -0,0 +1,19 @@ +using DotNetGraph.Core; + +namespace DotNetGraph.Attributes +{ + public class DotGraphLayoutAttribute : IDotAttribute + { + public DotGraphLayout Layout { get; set; } + + public DotGraphLayoutAttribute(DotGraphLayout layout = DotGraphLayout.Dot) + { + Layout = layout; + } + + public static implicit operator DotGraphLayoutAttribute(DotGraphLayout? layout) + { + return layout.HasValue ? new DotGraphLayoutAttribute(layout.Value) : null; + } + } +} \ No newline at end of file diff --git a/Sources/DotNetGraph/Compiler/DotCompiler.cs b/Sources/DotNetGraph/Compiler/DotCompiler.cs index e0d8220..55cb125 100644 --- a/Sources/DotNetGraph/Compiler/DotCompiler.cs +++ b/Sources/DotNetGraph/Compiler/DotCompiler.cs @@ -44,6 +44,8 @@ private void CompileGraph(StringBuilder builder, bool indented, bool formatStrin indentationLevel++; + CompileGraphAttributes(builder, _graph.Attributes, formatStrings); + foreach (var element in _graph.Elements) { if (element is DotEdge edge) @@ -256,6 +258,24 @@ private void CompileAttributes(StringBuilder builder, ReadOnlyCollection attributes, bool formatStrings) + { + if (attributes.Count == 0) + return; + + foreach (var attribute in attributes) + { + if (attribute is DotGraphLayoutAttribute graphLayoutAttribute) + { + builder.Append($"layout={graphLayoutAttribute.Layout.ToString().ToLowerInvariant()}; "); + } + else + { + throw new DotException($"Attribute type not supported: {attribute.GetType()}"); + } + } + } + internal static string FormatString(string value, bool format) { if (!format) diff --git a/Sources/DotNetGraph/Core/DotGraphLayout.cs b/Sources/DotNetGraph/Core/DotGraphLayout.cs new file mode 100644 index 0000000..080cf2a --- /dev/null +++ b/Sources/DotNetGraph/Core/DotGraphLayout.cs @@ -0,0 +1,12 @@ +namespace DotNetGraph.Core +{ + public enum DotGraphLayout + { + Dot = 0, + Neato = 1, + Fdp = 2, + Sfdp = 3, + Twopi = 4, + Circo= 5 + } +} \ No newline at end of file diff --git a/Sources/DotNetGraph/DotGraph.cs b/Sources/DotNetGraph/DotGraph.cs index 35c0315..4899f79 100644 --- a/Sources/DotNetGraph/DotGraph.cs +++ b/Sources/DotNetGraph/DotGraph.cs @@ -1,9 +1,10 @@ using System.Collections.Generic; +using DotNetGraph.Attributes; using DotNetGraph.Core; namespace DotNetGraph { - public class DotGraph : IDotElement + public class DotGraph : DotElementWithAttributes { public bool Directed { get; set; } @@ -11,6 +12,12 @@ public class DotGraph : IDotElement public bool Strict { get; set; } + public DotGraphLayoutAttribute Layout + { + get => GetAttribute(); + set => SetAttribute(value); + } + public List Elements { get; } public DotGraph()