95 lines
3.1 KiB
C#
95 lines
3.1 KiB
C#
using System.Text;
|
|
|
|
namespace SQLLinter.Infrastructure.Diagram;
|
|
|
|
public static class MermaidRenderer
|
|
{
|
|
public static string ToMermaidContent(BpmnDiagram diagram)
|
|
{
|
|
var sb = new StringBuilder();
|
|
sb.AppendLine("flowchart TB");
|
|
|
|
// -----------------------------------------
|
|
// Рендер каждого процесса как subgraph
|
|
// -----------------------------------------
|
|
foreach (var proc in diagram.Processes)
|
|
{
|
|
var procId = SanitizeId(proc.Id);
|
|
sb.AppendLine($" subgraph {procId} [\"{Escape(proc.Name)}\"]");
|
|
sb.AppendLine(" direction TB");
|
|
|
|
foreach (var node in proc.Nodes)
|
|
{
|
|
var nid = SanitizeId(node.Id);
|
|
var label = Escape(node.Label);
|
|
|
|
label = node.Type switch
|
|
{
|
|
BpmnNodeType.Start => $@"((""{label}""))",
|
|
BpmnNodeType.Task => $@"[""{label}""]",
|
|
BpmnNodeType.Subprocess => $@"[[""{label}""]]",
|
|
BpmnNodeType.Gateway => $@"{{""{label}""}}",
|
|
BpmnNodeType.Hexagon => $@"{{{{""{label}""}}}}",
|
|
BpmnNodeType.End => $@"((""{label}""))",
|
|
_ => $@">""{label}""]"
|
|
};
|
|
|
|
sb.AppendLine($" {nid}{label}");
|
|
}
|
|
|
|
// Edges внутри процесса
|
|
foreach (var e in proc.Edges)
|
|
{
|
|
var from = SanitizeId(e.From);
|
|
var to = SanitizeId(e.To);
|
|
var arrow = e.ArrowType switch
|
|
{
|
|
BpmnArrowType.Dashed => "-.->",
|
|
_ => "-->",
|
|
};
|
|
var lbl = string.IsNullOrWhiteSpace(e.Label) ? string.Empty : $" |{Escape(e.Label)}|";
|
|
|
|
sb.AppendLine($" {from} {arrow}{lbl} {to}");
|
|
}
|
|
|
|
sb.AppendLine(" end");
|
|
sb.AppendLine();
|
|
}
|
|
|
|
// -----------------------------------------
|
|
// Рендер глобальных связей между процессами
|
|
// -----------------------------------------
|
|
foreach (var e in diagram.GlobalEdges)
|
|
{
|
|
var from = SanitizeId(e.From);
|
|
var to = SanitizeId(e.To);
|
|
var arrow = e.ArrowType switch
|
|
{
|
|
BpmnArrowType.Dashed => "-.->",
|
|
_ => "-->",
|
|
};
|
|
var lbl = string.IsNullOrWhiteSpace(e.Label) ? string.Empty : $" |{Escape(e.Label)}|";
|
|
sb.AppendLine($" {from} {arrow}{lbl} {to}");
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
private static string Escape(string s)
|
|
{
|
|
if (s == null) return string.Empty;
|
|
return s.Replace("\"", "\\\"").Replace("\n", " ").Replace("\r", " ");
|
|
}
|
|
|
|
private static string SanitizeId(string s)
|
|
{
|
|
if (string.IsNullOrEmpty(s)) return "id";
|
|
var sb = new StringBuilder();
|
|
foreach (var ch in s)
|
|
{
|
|
if (char.IsLetterOrDigit(ch)) sb.Append(ch);
|
|
else sb.Append('_');
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
} |