Add ElkSharp rendering architecture docs, ADRs, tutorial, AGENTS rules

Five documentation deliverables for the ElkSharp rendering improvements:

1. docs/workflow/engine/16-elksharp-rendering-architecture.md (453 lines)
   Full pipeline: Sugiyama stages, edge routing strategies, hybrid
   deterministic mode, gateway geometry, 18-category scoring system,
   corridor routing, Y-gutter expansion, diagnostics.

2. docs/workflow/engine/17-elksharp-architectural-decisions.md (259 lines)
   Six ADRs: short-stub normalization, gateway vertex entries, Y-gutter
   expansion, corridor rerouting, FinalScore adjustment, alongside
   detection.

3. docs/workflow/tutorials/10-rendering/README.md (234 lines)
   Practical tutorial: setup, layout options, SVG/PNG rendering,
   diagnostics capture, violation reports, full end-to-end example.

4. src/__Libraries/StellaOps.ElkSharp/AGENTS.md — 7 new local rules
   for Y-gutter, corridor reroute, gateway vertices, FinalScore
   adjustments, short-stub normalization, alongside detection,
   target-join spread.

5. docs/workflow/ENGINE.md — replaced monolithic ElkSharp paragraph
   with structured pipeline overview, effort-level table, and links
   to the new architecture docs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-03-30 11:37:32 +03:00
parent b0d348c921
commit e91cf98f8f
5 changed files with 997 additions and 16 deletions

View File

@@ -0,0 +1,234 @@
# Tutorial 10: Rendering Workflow Diagrams
This tutorial shows how to use the Stella Ops workflow rendering system to produce
visual diagrams from workflow definitions.
---
## Prerequisites
- A workflow canonical definition (from the compiler or imported JSON).
- Reference to `StellaOps.Workflow.Renderer` and `StellaOps.ElkSharp` assemblies.
---
## Basic Usage
### 1. Create the Layout Engine
```csharp
var engine = new ElkSharpWorkflowRenderLayoutEngine();
```
### 2. Configure Layout Options
```csharp
var request = new WorkflowRenderLayoutRequest
{
Direction = WorkflowRenderLayoutDirection.LeftToRight,
Effort = WorkflowRenderLayoutEffort.Best,
NodeSpacing = 40,
LayerSpacing = 60,
};
```
### 3. Compute the Layout
```csharp
var layout = await engine.LayoutAsync(graph, request);
```
The `graph` parameter is a `WorkflowRenderGraph` produced by the
`WorkflowRenderGraphCompiler` from a canonical workflow definition.
### 4. Render to SVG
```csharp
var svgRenderer = new WorkflowRenderSvgRenderer();
var svgDoc = svgRenderer.Render(layout, "My Workflow");
await File.WriteAllTextAsync("workflow.svg", svgDoc.Svg);
```
### 5. Export to PNG
```csharp
var pngExporter = new WorkflowRenderPngExporter();
await pngExporter.ExportAsync(svgDoc, "workflow.png", scale: 2f);
```
The `scale` parameter controls the pixel density (2f = 2x resolution for HiDPI).
---
## Layout Options Reference
### Direction
| Value | Description |
|-------|-------------|
| `LeftToRight` | Nodes flow left to right (default for workflows). |
| `TopToBottom` | Nodes flow top to bottom. Uses the legacy iterative path. |
### Effort Levels
| Level | Speed | Quality | Use Case |
|-------|-------|---------|----------|
| `Draft` | Fast (~1s) | Basic | Interactive editing, previews |
| `Balanced` | Medium (~3-5s) | Good | Medium graphs, dev-time rendering |
| `Best` | Slow (~12-15s) | Production | Final artifacts, export, CI rendering |
**Draft** uses 8 ordering iterations, 3 placement iterations, and baseline routing
only. No iterative optimization is performed.
**Balanced** uses 14 ordering iterations, 6 placement iterations, and light repair
that fixes the worst violations without full A* search.
**Best** uses 24 ordering iterations, 10 placement iterations, and the hybrid
deterministic optimization pipeline with full-core parallel repair candidates.
### Spacing
- **NodeSpacing** (default 40): Vertical gap between nodes in pixels. The engine
may scale this up to 1.8x when edge density is high.
- **LayerSpacing** (default 60): Horizontal gap between layers in pixels.
---
## Reading the Layout Result
The `LayoutAsync` result contains positioned nodes and routed edges.
### Nodes
```csharp
foreach (var node in layout.Nodes)
{
Console.WriteLine($"Node {node.Id}: ({node.X}, {node.Y}) " +
$"size {node.Width}x{node.Height} " +
$"shape={node.Shape}");
}
```
Node shapes include `Rectangle` (service tasks), `Diamond` (decision gateways),
`Hexagon` (fork/join gateways), `Circle` (start/end events), and others.
### Edges
```csharp
foreach (var edge in layout.Edges)
{
Console.WriteLine($"Edge {edge.SourceId} -> {edge.TargetId}");
foreach (var point in edge.BendPoints)
{
Console.WriteLine($" bend: ({point.X}, {point.Y})");
}
}
```
Bend points define the orthogonal path from source to target. Two consecutive
bend points with the same Y form a horizontal segment; two with the same X
form a vertical segment.
---
## Diagnostics
When using `Best` effort, the engine captures detailed diagnostics about the
optimization process.
### Enabling Diagnostics
Diagnostics are captured automatically in `Best` mode. Access them through
the layout result.
### Violation Report
The violation report lists each edge's violations with category, severity,
and geometric details.
```csharp
if (layout.Diagnostics?.ViolationReport != null)
{
foreach (var entry in layout.Diagnostics.ViolationReport)
{
Console.WriteLine($"Edge {entry.EdgeId}: " +
$"{entry.Category} (penalty {entry.Penalty})");
}
}
```
### Violation Categories
The scoring system uses 18 categories. Hard violations (100K penalty) include
node crossings, under-node routing, shared lanes, and boundary slot conflicts.
Medium violations (50K) include backtracking and detours. Soft violations
(200-650) include edge crossings, proximity, and excessive bends.
A FinalScore of 0 for hard violations indicates a clean layout with no visual
defects. See the [Rendering Architecture](../../engine/16-elksharp-rendering-architecture.md)
for the full violation taxonomy.
### Phase Timings
```csharp
if (layout.Diagnostics?.PhaseTimings != null)
{
foreach (var phase in layout.Diagnostics.PhaseTimings)
{
Console.WriteLine($"{phase.Name}: {phase.Duration.TotalMilliseconds}ms");
}
}
```
Phase timings cover ordering, placement, gutter expansion, base routing,
iterative optimization, and post-processing.
---
## End-to-End Example
```csharp
// Compile a workflow definition to a render graph
var compiler = new WorkflowRenderGraphCompiler();
var graph = compiler.Compile(workflowDefinition);
// Configure and run layout
var engine = new ElkSharpWorkflowRenderLayoutEngine();
var request = new WorkflowRenderLayoutRequest
{
Direction = WorkflowRenderLayoutDirection.LeftToRight,
Effort = WorkflowRenderLayoutEffort.Best,
NodeSpacing = 40,
LayerSpacing = 60,
};
var layout = await engine.LayoutAsync(graph, request);
// Render to SVG
var svgRenderer = new WorkflowRenderSvgRenderer();
var svgDoc = svgRenderer.Render(layout, workflowDefinition.Name);
await File.WriteAllTextAsync($"{workflowDefinition.Name}.svg", svgDoc.Svg);
// Export to PNG at 2x resolution
var pngExporter = new WorkflowRenderPngExporter();
await pngExporter.ExportAsync(svgDoc, $"{workflowDefinition.Name}.png", scale: 2f);
// Check for violations
var hardViolations = layout.Diagnostics?.ViolationReport?
.Where(v => v.Penalty >= 100_000)
.ToList();
if (hardViolations?.Any() == true)
{
Console.WriteLine($"WARNING: {hardViolations.Count} hard violations detected");
}
```
---
## Further Reading
- [ElkSharp Rendering Architecture](../../engine/16-elksharp-rendering-architecture.md) --
Full technical details of the Sugiyama pipeline, edge routing, and iterative optimization.
- [Architectural Decisions](../../engine/17-elksharp-architectural-decisions.md) --
ADR records for key design choices.
- [ENGINE.md](../../ENGINE.md) -- Workflow engine overview including layout engine
configuration and render pipeline.