diff --git a/src/SparseTransform.CLI/Program.cs b/src/SparseTransform.CLI/Program.cs index 416dbe67d3497099f22c4335b7f428115c196728..bf0f2358031e3a382644cb579ae97c7146576d40 100644 --- a/src/SparseTransform.CLI/Program.cs +++ b/src/SparseTransform.CLI/Program.cs @@ -71,7 +71,7 @@ public class Program /// <returns>Dot String with coloring information</returns> private static String Partition2ColoredDot(String MMMatrix, bool textColor = false) { - return ConversionManager.Partition2ColoredDot(MMMatrix); + return ConversionManager.Partition2ColoredDot(MMMatrix, textColor); } /// <summary> diff --git a/src/SparseTransform/ConversionManager.cs b/src/SparseTransform/ConversionManager.cs index 4084f6e5b5b8e082a723b3e59a4a484820d161c9..5fc419b16404a3adb1dcec006784105a3b144377 100644 --- a/src/SparseTransform/ConversionManager.cs +++ b/src/SparseTransform/ConversionManager.cs @@ -26,7 +26,7 @@ namespace SparseTransform /// <param name="MMMatrix">raw MatrixMarket input String</param> /// <param name="textColor">true if color should additionally be represented as text</param> /// <returns>Dot String with coloring information</returns> - public static String Partition2ColoredDot(String MMMatrix, bool textColor= false) + public static String Partition2ColoredDot(String MMMatrix, bool textColor = false) { MatrixMarketReader reader = new MatrixMarketReader(); IGraph graph = reader.ReadGraph(MMMatrix); @@ -40,7 +40,7 @@ namespace SparseTransform } else color.PartialD2Color((BipartiteGraph)graph); - ColoredDotWriter writer = new ColoredDotWriter(textColor); + ColoredDotWriter writer = new ColoredDotWriter(graph, textColor); return writer.Write(graph); } diff --git a/src/SparseTransform/Convert/ColoredDotWriter.cs b/src/SparseTransform/Convert/ColoredDotWriter.cs index be629b633f826c7a77c58274e874dfce654175ad..f2e99e2ab6a376370089b37ec49ffe15d027b83b 100644 --- a/src/SparseTransform/Convert/ColoredDotWriter.cs +++ b/src/SparseTransform/Convert/ColoredDotWriter.cs @@ -1,4 +1,5 @@ using SparseTransform.DataStructures; +using System.Text; namespace SparseTransform.Convert { @@ -7,27 +8,17 @@ namespace SparseTransform.Convert /// </summary> public class ColoredDotWriter : DotWriter { - private bool textcolor; - private string[] dictColor = new string[65]; + private IGraph _coloredGraph; + private bool _textcolor; /// <summary> /// Constructor constructing a color-dictionary for coloring purpose. /// </summary> /// <param name="textColor">decision whether the labels should be colored or labelled.</param> - public ColoredDotWriter(bool textColor) + public ColoredDotWriter(IGraph graph, bool textColor) { - this.textcolor = textColor; - - for (int i = 0; i <= 3; i++) - { - for (int j = 0; j <= 3; j++) - { - for (int k = 0; k <= 4; k++) - { - dictColor[i * 16 + j * 4 + k] = ("#" + (255 - i * 60).ToString("X2") + (255 - j * 60).ToString("X2") + (255 - k * 60).ToString("X2")); - } - } - } + this._coloredGraph = graph; + this._textcolor = textColor; } /// <summary> @@ -38,14 +29,32 @@ namespace SparseTransform.Convert /// <returns></returns> public override String NodeLabel(GraphNode node, String prefix) { - if (textcolor || node.Color > 64) - { - return "\t" + prefix + node.Index + " [shape=circle, style=filled, label=\"" + prefix + node.Index + "\\n Farbe " + node.Color + "\"]"; - } - else + // This is the offset. Less colors = more distance between + int hueFactor = 255 / _coloredGraph.ColorsUsed; + // Calculate the hue. We modulo with 255 to not exceed spectrum. Then convert to float for DOT + double hue = Math.Round((double)((node.Color * hueFactor) % 255) / 255, 3); + + StringBuilder label = new StringBuilder(); + // Append label name and general layout info + label.Append($"\t{prefix}{node.Index} [shape=circle, style=filled"); + + // If current node is colored, apply either text label with color or set fill color + if (node.Colored) { - return "\t" + prefix + node.Index + " [shape=circle, style=filled, fillcolor=\"" + dictColor[node.Color] + "\"]"; + if (_textcolor || _coloredGraph.ColorsUsed > 255) + { + label.Append($", label=\"{prefix}{node.Index}\\n color:{node.Color}\""); + } + else + { + // Set saturation + value (brightness) to max for vibrant colors + label.Append($", fillcolor=\"{hue} {1} {1}\""); + } } + + // Close attribute line + label.Append("]"); + return label.ToString(); } } } diff --git a/src/SparseTransform/DataStructures/AdjacencyGraph.cs b/src/SparseTransform/DataStructures/AdjacencyGraph.cs index 75e31d00a441e1ac5981e119b2d0f01b651e747a..bbf98db747c0effd7cde2d863dc00e6762f8b3ca 100644 --- a/src/SparseTransform/DataStructures/AdjacencyGraph.cs +++ b/src/SparseTransform/DataStructures/AdjacencyGraph.cs @@ -37,7 +37,7 @@ namespace SparseTransform.DataStructures /// <summary> /// Number of colors used for coloring. /// </summary> - private int ColorsUsed + public int ColorsUsed { get { diff --git a/src/SparseTransform/DataStructures/BipartiteGraph.cs b/src/SparseTransform/DataStructures/BipartiteGraph.cs index 214907dfde4da15dc5ad59c8c7683ccfe734e8c1..a61f95189f03e482c32a88aff2980b791bc6a80d 100644 --- a/src/SparseTransform/DataStructures/BipartiteGraph.cs +++ b/src/SparseTransform/DataStructures/BipartiteGraph.cs @@ -69,7 +69,7 @@ namespace SparseTransform.DataStructures /// <summary> /// Number of colors used for coloring. Works if either or both sides are colored /// </summary> - private int ColorsUsed + public int ColorsUsed { get { diff --git a/src/SparseTransform/DataStructures/IGraph.cs b/src/SparseTransform/DataStructures/IGraph.cs index e821e1b50101099a2cbd946810ea92ea00744bdf..a4471936832a2e8aa9c263c8bb1b655c3bf3823f 100644 --- a/src/SparseTransform/DataStructures/IGraph.cs +++ b/src/SparseTransform/DataStructures/IGraph.cs @@ -6,6 +6,8 @@ namespace SparseTransform.DataStructures /// </summary> public interface IGraph { + public int ColorsUsed { get; } + /// <summary> /// Adds an edge between nodes i and j. If either of the nodes is missing it is created. /// </summary>