Context
I use dlin to generate dbt lineage diagrams for design docs and pull request descriptions. The DOT output piped through Graphviz gets very close to being directly embeddable, and three small changes would get it the rest of the way. Let me know what you think and I can open PRs for these!
1. Optional suppression of redundant edge labels
DOT and Mermaid output label every edge with its dependency type (label="ref"). When every edge in a graph is the same type, the labels are pure noise and they measurably inflate the rendered image.
On a 31-node graph, dropping them took the PNG from 3576x1450 to 3439x966 — a 33% height reduction, purely from removing repeated text.
Today I do this post-process:
dlin graph <model> --no-transitive -o dot | sed -E 's/ *\[label="ref"\]//'
Proposal: a --no-edge-labels flag, or omit the label automatically when all edges in the output share one type.
2. Wrap long node labels
Some teams' dbt naming conventions produce long model names, often with a __ separator between domain and entity. Rendered as single-line labels these create very wide nodes, and the resulting image is far wider than it is tall — awkward to embed in a document or a PR, where it renders as a thin unreadable strip.
Wrapping labels at the __ boundary on the same 31-node graph:
|
Dimensions |
Aspect ratio |
| Single-line labels |
3439x966 |
3.56:1 |
Wrapped at __ |
2300x1028 |
2.24:1 |
A 33% width reduction, and the result is comfortably embeddable.
Proposal: a --wrap-labels[=<SEPARATOR>] flag, defaulting to __, or a generic max-width character wrap. Applies to DOT and Mermaid (both support multi-line labels — \n and <br/> respectively).
3. Draggable nodes in -o html
The HTML output is genuinely useful — self-contained, no external requests, with pan, zoom, search and a detail panel. The one thing people reach for and don't find is dragging a node to untangle a dense area.
The emitted markup already has everything needed:
- edges carry
data-source / data-target
- nodes are
<g data-id="..." class="node">
- the canvas pan handler already has
if (e.target.closest('.node')) return;, so mousedown on a node currently falls through unused
- the full adjacency map is already serialized client-side as
const data
So this looks like it could be JS-only inside the existing IIFE — recompute the incident edge paths on drag — with no changes to the layout engine, no new dependencies, and no change to -o svg.
Three things worth flagging for whoever implements it:
- pan/zoom is a CSS transform with a
scale variable; mouse deltas need dividing by scale or drags desync when zoomed
- a source/target pair isn't unique (multi-edges), so edge lookup needs
querySelectorAll
- the self-loop bezier formula degenerates and needs a NaN guard
Context
I use
dlinto generate dbt lineage diagrams for design docs and pull request descriptions. The DOT output piped through Graphviz gets very close to being directly embeddable, and three small changes would get it the rest of the way. Let me know what you think and I can open PRs for these!1. Optional suppression of redundant edge labels
DOT and Mermaid output label every edge with its dependency type (
label="ref"). When every edge in a graph is the same type, the labels are pure noise and they measurably inflate the rendered image.On a 31-node graph, dropping them took the PNG from 3576x1450 to 3439x966 — a 33% height reduction, purely from removing repeated text.
Today I do this post-process:
Proposal: a
--no-edge-labelsflag, or omit the label automatically when all edges in the output share one type.2. Wrap long node labels
Some teams' dbt naming conventions produce long model names, often with a
__separator between domain and entity. Rendered as single-line labels these create very wide nodes, and the resulting image is far wider than it is tall — awkward to embed in a document or a PR, where it renders as a thin unreadable strip.Wrapping labels at the
__boundary on the same 31-node graph:__A 33% width reduction, and the result is comfortably embeddable.
Proposal: a
--wrap-labels[=<SEPARATOR>]flag, defaulting to__, or a generic max-width character wrap. Applies to DOT and Mermaid (both support multi-line labels —\nand<br/>respectively).3. Draggable nodes in
-o htmlThe HTML output is genuinely useful — self-contained, no external requests, with pan, zoom, search and a detail panel. The one thing people reach for and don't find is dragging a node to untangle a dense area.
The emitted markup already has everything needed:
data-source/data-target<g data-id="..." class="node">if (e.target.closest('.node')) return;, so mousedown on a node currently falls through unusedconst dataSo this looks like it could be JS-only inside the existing IIFE — recompute the incident edge paths on drag — with no changes to the layout engine, no new dependencies, and no change to
-o svg.Three things worth flagging for whoever implements it:
scalevariable; mouse deltas need dividing byscaleor drags desync when zoomedquerySelectorAll