Доработан билдер BPMN
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using System.Text;
|
||||
using System.Text;
|
||||
|
||||
namespace SQLLinter.Infrastructure.Diagram;
|
||||
|
||||
@@ -9,114 +9,72 @@ public static class MermaidRenderer
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("flowchart TB");
|
||||
|
||||
// main: print Start, then tasks/gateways, then End
|
||||
var mainStart = diagram.Main.Nodes.Where(n => n.Type == BpmnNodeType.Start).ToList();
|
||||
var mainTasks = diagram.Main.Nodes.Where(n => n.Type == BpmnNodeType.Task || n.Type == BpmnNodeType.Gateway).ToList();
|
||||
var mainEnd = diagram.Main.Nodes.Where(n => n.Type == BpmnNodeType.End).ToList();
|
||||
|
||||
foreach (var node in mainStart)
|
||||
{
|
||||
var nid = SanitizeId(node.Id);
|
||||
var label = Escape(node.Label);
|
||||
sb.AppendLine($" {nid}((\"{label}\"))");
|
||||
}
|
||||
foreach (var node in mainTasks)
|
||||
{
|
||||
var nid = SanitizeId(node.Id);
|
||||
var label = Escape(node.Label);
|
||||
if (node.Type == BpmnNodeType.Gateway)
|
||||
sb.AppendLine($" {nid}{{\"{label}\"}}");
|
||||
else
|
||||
sb.AppendLine($" {nid}[\"{label}\"]");
|
||||
}
|
||||
foreach (var node in mainEnd)
|
||||
{
|
||||
var nid = SanitizeId(node.Id);
|
||||
var label = Escape(node.Label);
|
||||
sb.AppendLine($" {nid}((\"{label}\"))");
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
|
||||
// subprocesses as subgraphs: pool label, start, tasks/gateways, end
|
||||
foreach (var proc in diagram.Subprocesses)
|
||||
// -----------------------------------------
|
||||
// Рендер каждого процесса как subgraph
|
||||
// -----------------------------------------
|
||||
foreach (var proc in diagram.Processes)
|
||||
{
|
||||
var procId = SanitizeId(proc.Id);
|
||||
sb.AppendLine($" subgraph {procId} [\"{Escape(proc.Name)}\"]");
|
||||
sb.AppendLine($" direction TB");
|
||||
sb.AppendLine(" direction TB");
|
||||
|
||||
var startNodes = proc.Nodes.Where(n => n.Type == BpmnNodeType.Start).ToList();
|
||||
var taskNodes = proc.Nodes.Where(n => n.Type == BpmnNodeType.Task || n.Type == BpmnNodeType.Gateway).ToList();
|
||||
var endNodes = proc.Nodes.Where(n => n.Type == BpmnNodeType.End).ToList();
|
||||
var poolNodes = proc.Nodes.Where(n => n.Type == BpmnNodeType.Subprocess).ToList();
|
||||
|
||||
// pool label nodes (usually first)
|
||||
foreach (var node in poolNodes)
|
||||
foreach (var node in proc.Nodes)
|
||||
{
|
||||
var nid = SanitizeId(node.Id);
|
||||
var label = Escape(node.Label);
|
||||
sb.AppendLine($" {nid}[\"{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}");
|
||||
}
|
||||
|
||||
foreach (var node in startNodes)
|
||||
{
|
||||
var nid = SanitizeId(node.Id);
|
||||
var label = Escape(node.Label);
|
||||
sb.AppendLine($" {nid}((\"{label}\"))");
|
||||
}
|
||||
foreach (var node in taskNodes)
|
||||
{
|
||||
var nid = SanitizeId(node.Id);
|
||||
var label = Escape(node.Label);
|
||||
if (node.Type == BpmnNodeType.Gateway)
|
||||
sb.AppendLine($" {nid}{{\"{label}\"}}");
|
||||
else
|
||||
sb.AppendLine($" {nid}[\"{label}\"]");
|
||||
}
|
||||
foreach (var node in endNodes)
|
||||
{
|
||||
var nid = SanitizeId(node.Id);
|
||||
var label = Escape(node.Label);
|
||||
sb.AppendLine($" {nid}((\"{label}\"))");
|
||||
}
|
||||
|
||||
// edges inside subprocess
|
||||
// Edges внутри процесса
|
||||
foreach (var e in proc.Edges)
|
||||
{
|
||||
var from = SanitizeId(e.From);
|
||||
var to = SanitizeId(e.To);
|
||||
var arrow = e.Dashed ? "-.->" : "-->";
|
||||
var arrow = e.ArrowType switch
|
||||
{
|
||||
BpmnArrowType.Dashed => "-.->",
|
||||
_ => "-->",
|
||||
};
|
||||
var lbl = string.IsNullOrWhiteSpace(e.Label) ? string.Empty : $" |{Escape(e.Label)}|";
|
||||
sb.AppendLine($" {from} {arrow} {to}{lbl}");
|
||||
|
||||
sb.AppendLine($" {from} {arrow}{lbl} {to}");
|
||||
}
|
||||
|
||||
sb.AppendLine(" end");
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
// main edges
|
||||
foreach (var e in diagram.Main.Edges)
|
||||
// -----------------------------------------
|
||||
// Рендер глобальных связей между процессами
|
||||
// -----------------------------------------
|
||||
foreach (var e in diagram.GlobalEdges)
|
||||
{
|
||||
var from = SanitizeId(e.From);
|
||||
var to = SanitizeId(e.To);
|
||||
var arrow = e.Dashed ? "-.->" : "-->";
|
||||
var arrow = e.ArrowType switch
|
||||
{
|
||||
BpmnArrowType.Dashed => "-.->",
|
||||
_ => "-->",
|
||||
};
|
||||
var lbl = string.IsNullOrWhiteSpace(e.Label) ? string.Empty : $" |{Escape(e.Label)}|";
|
||||
sb.AppendLine($" {from} {arrow} {to}{lbl}");
|
||||
sb.AppendLine($" {from} {arrow}{lbl} {to}");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string RenderMarkdown(BpmnDiagram diagram)
|
||||
{
|
||||
var content = ToMermaidContent(diagram);
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("```mermaid");
|
||||
sb.Append(content);
|
||||
sb.AppendLine("```");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string Escape(string s)
|
||||
{
|
||||
if (s == null) return string.Empty;
|
||||
@@ -134,4 +92,4 @@ public static class MermaidRenderer
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user