General-purpose diagram layout and rendering for .NET. Describe a diagram as a graph, lay it out with a pluggable algorithm, and render it to SVG, PNG, JPEG, or WEBP. The design is inspired by the Eclipse Layout Kernel (ELK): layout and rendering are configured through an open, extensible property system, and new algorithms, renderers, and options are added additively.
- Pluggable layout algorithms — layered (Sugiyama-style), containment packing, a recursive hierarchical engine for compound (nested-container) graphs, and an auto-routing meta-algorithm that picks the best fit per connected component, each selected through the open property system.
- Orthogonal edge routing — axis-aligned connectors in all four flow directions, with obstacle avoidance around intervening containers.
- Named ports — first-class, labelled attachment points on a node's boundary, including parallel edges and per-side port labels.
- Boundary (delegation) ports — a container port that carries both an outward external label and an inward internal label at one shared anchor, relaying an external connection into the container's nested children, with external and internal fan-out consolidated onto that single anchor.
- Multiple output formats — SVG (zero external dependencies) plus PNG, JPEG, and WEBP via SkiaSharp, with light, dark, and print themes.
The four bundled layout algorithms cover different concerns; pick auto when a diagram's shape is
not known in advance, or select a leaf algorithm directly when it is. auto delegates every concern
to whichever leaf algorithm it routes a component to, so its result is only as good as that leaf's own
support for the row.
| Concern | layered |
containment |
hierarchical |
auto |
|---|---|---|---|---|
| Horizontal gap widening by edge count | Yes | Yes | Yes | Delegates |
| Vertical gap widening by edge count | Partial | No | No | Delegates |
| Container auto-expansion | N/A | N/A | Yes | Delegates |
| Port/label space reservation | Yes | No | Yes | Delegates |
| Direction/orientation support | Yes | No | Yes | Delegates |
| Connectivity/component awareness | Yes | No | Yes | Delegates |
| Aspect-ratio/canvas-shape targeting | Partial | Yes | Partial | Delegates |
| Nested/recursive containment handling | No | No | Yes | Delegates |
See the user guide for the full capability matrix with one-line reasons per cell,
the auto delegation caveats, and guidance on when to call a specific algorithm directly instead of
auto.
The library is split into focused packages so consumers take only what they need:
| Package | Purpose |
|---|---|
DemaConsulting.Rendering |
Layout model: the LayoutTree IR, the property system, and the input LayoutGraph |
DemaConsulting.Rendering.Abstractions |
SPI: ILayoutAlgorithm/IRenderer, registries, Theme, notation metrics |
DemaConsulting.Rendering.Layout |
Layout algorithms: the layered pipeline and LayeredLayoutAlgorithm |
DemaConsulting.Rendering.Svg |
SVG renderer with zero external dependencies |
DemaConsulting.Rendering.Skia |
SkiaSharp raster renderers (PNG, JPEG, WEBP) with an embedded Noto Sans font |
Package dependencies form an acyclic graph: Abstractions and Layout depend on the model;
Svg and Skia depend on the model and Abstractions; the model depends on nothing.
dotnet add package DemaConsulting.Rendering.Layout
dotnet add package DemaConsulting.Rendering.Svgusing System.IO;
using DemaConsulting.Rendering;
using DemaConsulting.Rendering.Abstractions;
using DemaConsulting.Rendering.Layout;
using DemaConsulting.Rendering.Svg;
// Describe the diagram as a graph of sized boxes and directed edges.
var graph = new LayoutGraph();
var a = graph.AddNode("a", width: 80, height: 40);
var b = graph.AddNode("b", width: 80, height: 40);
graph.AddEdge("a-b", a, b);
// Lay it out, then render the placed tree to SVG.
var tree = new LayeredLayoutAlgorithm().Apply(graph, new LayoutOptions());
using var output = File.Create("diagram.svg");
new SvgRenderer().Render(tree, new RenderOptions(Themes.Light), output);See the user guide for configuration options and extension points.
Every package ships its full API reference as compact, AI-friendly Markdown in an api/ folder
inside the NuGet package, generated from the XML documentation comments by ApiMark. Start at
api/api.md (the index) and drill into the per-namespace and per-type pages for signatures,
remarks, and usage examples.
A rendering gallery showcases what the library can produce — every bundled layout
algorithm, orthogonal edge routing, all three themes, and both the SVG and PNG output paths. Each
image is generated by the gallery test project directly from the public API, so the gallery doubles
as an end-to-end rendering smoke test. Regenerate it with ./gallery.ps1.
- New layout algorithms implement
ILayoutAlgorithmand register under a new id. - New output formats implement
IRendererwith a distinct media type. - New configuration options are declared as typed
LayoutProperty<T>keys carried in an open property bag, so adding an option never changes an existing method signature.
Generated documentation includes build notes, a user guide, a code quality report, requirements, requirement justifications, and a requirements-to-test trace matrix.
Contributions are welcome. See CONTRIBUTING.md for development setup, coding standards, and the pull request process.
Copyright (c) DEMA Consulting. Licensed under the MIT License. See LICENSE for details.
By contributing to this project, you agree that your contributions will be licensed under the MIT License.