diff --git a/Sources/DotNetGraph.Tests/DefaultStylesGraphTests.cs b/Sources/DotNetGraph.Tests/DefaultStylesGraphTests.cs new file mode 100644 index 0000000..8b823ab --- /dev/null +++ b/Sources/DotNetGraph.Tests/DefaultStylesGraphTests.cs @@ -0,0 +1,58 @@ +using System.Drawing; +using DotNetGraph.Extensions; +using DotNetGraph.Node; +using NFluent; +using Xunit; + +namespace DotNetGraph.Tests +{ + public class DefaultStylesGraphTests + { + [Fact] + public void NullNodeDefaultStyle() + { + var graph = new DotGraph("TestGraph") + .WithDefaultNodeStyleLayout(null) + .AddNode("TestNode"); + + var compiled = graph.Compile(); + + Check.That(compiled).HasSameValueAs("graph TestGraph { TestNode ; }"); + } + + [Fact] + public void DefaultColorNodeDefaultStyle() + { + var graph = new DotGraph("TestGraph") + .WithDefaultNodeStyleLayout(new DotNodeStyleLayout + { + Color = Color.Red + }) + .AddNode("TestNode"); + + var compiled = graph.Compile(); + + Check.That(compiled).HasSameValueAs("graph TestGraph { TestNode [color=\"#FF0000\"]; }"); + } + + [Fact] + public void CompleteNodeDefaultStyle() + { + var graph = new DotGraph("TestGraph") + .WithDefaultNodeStyleLayout(new DotNodeStyleLayout + { + Color = Color.Red, + Height = 0.64f, + Shape = DotNodeShape.Box, + Style = DotNodeStyle.Dashed, + FillColor = Color.Blue, + FontColor = Color.Yellow + }) + .AddNode("TestNode"); + + var compiled = graph.Compile(); + + Check.That(compiled).HasSameValueAs("graph TestGraph { TestNode [color=\"#FF0000\",height=0.64,shape=box,style=dashed,fillcolor=\"#0000FF\",fontcolor=\"#FFFF00\"]; }"); + } + } +} \ No newline at end of file diff --git a/Sources/DotNetGraph.Tests/Node/BasicNodeTests.cs b/Sources/DotNetGraph.Tests/Node/BasicNodeTests.cs index 9210dd9..74052b2 100644 --- a/Sources/DotNetGraph.Tests/Node/BasicNodeTests.cs +++ b/Sources/DotNetGraph.Tests/Node/BasicNodeTests.cs @@ -52,7 +52,10 @@ public void NodeWithColor() { Elements = { - new DotNode("TestNode", Color.Red) + new DotNode("TestNode") + { + Color = Color.Red + } } }; diff --git a/Sources/DotNetGraph/Compiler/DotCompiler.cs b/Sources/DotNetGraph/Compiler/DotCompiler.cs index be0a2d6..cf49bbe 100644 --- a/Sources/DotNetGraph/Compiler/DotCompiler.cs +++ b/Sources/DotNetGraph/Compiler/DotCompiler.cs @@ -19,8 +19,14 @@ public DotCompiler(DotGraph graph) _graph = graph; } - public string Compile() + public string Compile(bool applyDefaultStyles = true) { + if (applyDefaultStyles) + { + var styleProcessor = new DotStyleProcessor(_graph); + styleProcessor.ApplyDefaultLayoutStyles(_graph); + } + var builder = new StringBuilder(); CompileGraph(builder); diff --git a/Sources/DotNetGraph/Compiler/DotStyleProcessor.cs b/Sources/DotNetGraph/Compiler/DotStyleProcessor.cs new file mode 100644 index 0000000..d8efe07 --- /dev/null +++ b/Sources/DotNetGraph/Compiler/DotStyleProcessor.cs @@ -0,0 +1,27 @@ +using DotNetGraph.Core; +using DotNetGraph.Node; + +namespace DotNetGraph.Compiler +{ + public class DotStyleProcessor + { + private readonly DotGraph _graph; + + public DotStyleProcessor(DotGraph graph) + { + _graph = graph; + } + + public void ApplyDefaultLayoutStyles(IElementWithChildren element) + { + foreach (var child in element.Elements) + { + if (child is DotNode dotNodeChild) + dotNodeChild.ApplyStyleLayout(_graph.DefaultNodeStyleLayout); + + if (child is IElementWithChildren childWithChildren) + ApplyDefaultLayoutStyles(childWithChildren); + } + } + } +} \ No newline at end of file diff --git a/Sources/DotNetGraph/Core/IElementWithChildren.cs b/Sources/DotNetGraph/Core/IElementWithChildren.cs new file mode 100644 index 0000000..c6a1cf0 --- /dev/null +++ b/Sources/DotNetGraph/Core/IElementWithChildren.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace DotNetGraph.Core +{ + public interface IElementWithChildren + { + List Elements { get; } + } +} \ No newline at end of file diff --git a/Sources/DotNetGraph/DotGraph.cs b/Sources/DotNetGraph/DotGraph.cs index 35c0315..8c448e8 100644 --- a/Sources/DotNetGraph/DotGraph.cs +++ b/Sources/DotNetGraph/DotGraph.cs @@ -1,9 +1,10 @@ using System.Collections.Generic; using DotNetGraph.Core; +using DotNetGraph.Node; namespace DotNetGraph { - public class DotGraph : IDotElement + public class DotGraph : IDotElement, IElementWithChildren { public bool Directed { get; set; } @@ -12,16 +13,26 @@ public class DotGraph : IDotElement public bool Strict { get; set; } public List Elements { get; } + + public DotNodeStyleLayout DefaultNodeStyleLayout { get; set; } - public DotGraph() + public DotGraph(string identifier, bool directed = false) { Elements = new List(); + Identifier = identifier; + Directed = directed; } - public DotGraph(string identifier, bool directed = false) : this() + public DotGraph AddElement(IDotElement element) { - Identifier = identifier; - Directed = directed; + Elements.Add(element); + return this; + } + + public DotGraph WithDefaultNodeStyleLayout(DotNodeStyleLayout nodeStyleLayout) + { + DefaultNodeStyleLayout = nodeStyleLayout; + return this; } } } \ No newline at end of file diff --git a/Sources/DotNetGraph/Extensions/DotGraphExtensions.cs b/Sources/DotNetGraph/Extensions/DotGraphExtensions.cs index ef05d63..861820a 100644 --- a/Sources/DotNetGraph/Extensions/DotGraphExtensions.cs +++ b/Sources/DotNetGraph/Extensions/DotGraphExtensions.cs @@ -1,12 +1,19 @@ using DotNetGraph.Compiler; +using DotNetGraph.Node; namespace DotNetGraph.Extensions { public static class DotGraphExtensions { - public static string Compile(this DotGraph graph) + public static string Compile(this DotGraph graph, bool applyDefaultStyles = true) { - return new DotCompiler(graph).Compile(); + return new DotCompiler(graph).Compile(applyDefaultStyles); + } + + public static DotGraph AddNode(this DotGraph graph, string identifier, DotNodeStyleLayout styleLayout = null) + { + var node = new DotNode(identifier, styleLayout); + return graph.AddElement(node); } } } \ No newline at end of file diff --git a/Sources/DotNetGraph/Node/DotNode.cs b/Sources/DotNetGraph/Node/DotNode.cs index cc8ebd8..5851ea2 100644 --- a/Sources/DotNetGraph/Node/DotNode.cs +++ b/Sources/DotNetGraph/Node/DotNode.cs @@ -49,10 +49,39 @@ public DotNodeHeightAttribute Height set => SetAttribute(value); } - public DotNode(string identifier = null, DotColorAttribute color = null) + public DotNode(string identifier) { Identifier = identifier; - Color = color; + } + + public DotNode(string identifier, DotNodeStyleLayout styleLayout) + { + Identifier = identifier; + ApplyStyleLayout(styleLayout); + } + + public void ApplyStyleLayout(DotNodeStyleLayout styleLayout) + { + if (styleLayout is null) + return; + + if (styleLayout.Color != null) + Color = styleLayout.Color; + + if (styleLayout.Height != null) + Height = styleLayout.Height; + + if (styleLayout.Shape != null) + Shape = styleLayout.Shape; + + if (styleLayout.Style != null) + Style = styleLayout.Style; + + if (styleLayout.FillColor != null) + FillColor = styleLayout.FillColor; + + if (styleLayout.FontColor != null) + FontColor = styleLayout.FontColor; } } } \ No newline at end of file diff --git a/Sources/DotNetGraph/Node/DotNodeStyleLayout.cs b/Sources/DotNetGraph/Node/DotNodeStyleLayout.cs new file mode 100644 index 0000000..5b9a569 --- /dev/null +++ b/Sources/DotNetGraph/Node/DotNodeStyleLayout.cs @@ -0,0 +1,19 @@ +using DotNetGraph.Attributes; + +namespace DotNetGraph.Node +{ + public class DotNodeStyleLayout + { + public DotColorAttribute Color { get; set; } + + public DotFontColorAttribute FontColor { get; set; } + + public DotFillColorAttribute FillColor { get; set; } + + public DotNodeShapeAttribute Shape { get; set; } + + public DotNodeStyleAttribute Style { get; set; } + + public DotNodeHeightAttribute Height { get; set; } + } +} \ No newline at end of file diff --git a/Sources/DotNetGraph/SubGraph/DotSubGraph.cs b/Sources/DotNetGraph/SubGraph/DotSubGraph.cs index 3526cfd..7f3a1c1 100644 --- a/Sources/DotNetGraph/SubGraph/DotSubGraph.cs +++ b/Sources/DotNetGraph/SubGraph/DotSubGraph.cs @@ -4,10 +4,12 @@ namespace DotNetGraph.SubGraph { - public class DotSubGraph : DotElementWithAttributes + public class DotSubGraph : DotElementWithAttributes, IElementWithChildren { public string Identifier { get; set; } + public List Elements { get; } + public DotColorAttribute Color { get => GetAttribute(); @@ -26,8 +28,6 @@ public DotLabelAttribute Label set => SetAttribute(value); } - public List Elements { get; } - public DotSubGraph(string identifier = null) { Elements = new List();