Summary
When rendering SQL tables with the ELK layout engine, the D2 CLI correctly routes relationships from column to column (e.g. primary key to foreign key). However, the JavaScript package @terrastruct/d2 produces table-to-table connections for the same input and layout.
This appears to be a discrepancy between the CLI and D2.js rather than an ELK configuration issue.
Environment
- D2.js package:
@terrastruct/d2 0.1.33
- Embedded D2 engine:
v0.7.0-HEAD (reported by await d2.version())
- JS version:
0.1.33 (reported by await d2.jsVersion())
- Layout engine: ELK
Minimal example
users: {
shape: sql_table
id: int {constraint: primary_key}
name: string
email: string
}
orders: {
shape: sql_table
id: int {constraint: primary_key}
user_id: int {constraint: foreign_key}
}
users.id -> orders.user_id
D2.js code
import { D2 } from "@terrastruct/d2";
const d2 = new D2();
const { diagram, renderOptions } = await d2.compile(source, {
options: { layout: "elk" },
});
const svg = await d2.render(diagram, renderOptions);
Expected behavior
The relationship should connect from the users.id row to the orders.user_id row, matching the behavior of the D2 CLI.
Actual behavior
The relationship connects from table to table rather than row to row.
Comparison with the CLI
Running the exact same D2 source via the CLI:
d2 --layout elk schema.d2 schema.svg
produces the expected row-to-row connections.
Additional investigation
- Both use the ELK layout engine.
- Calling
await d2.version() returns v0.7.0-HEAD.
- Calling
await d2.jsVersion() returns 0.1.33.
- Inspecting the object returned by
d2.compile() shows no explicit port definitions for SQL table rows, although it is unclear whether these are expected to be generated during compilation or later in the rendering pipeline.
Conclusion
There appears to be a behavioral difference between the D2 CLI and the @terrastruct/d2 JavaScript package when rendering SQL tables with ELK. The CLI correctly performs row-to-row routing, while D2.js renders the same diagram as table-to-table.
If this behavior is intentional, it would be helpful to document any additional API calls or options required to enable SQL table port routing in D2.js. Otherwise, this appears to be a bug or feature parity issue between the CLI and the JavaScript renderer.
Summary
When rendering SQL tables with the ELK layout engine, the D2 CLI correctly routes relationships from column to column (e.g. primary key to foreign key). However, the JavaScript package
@terrastruct/d2produces table-to-table connections for the same input and layout.This appears to be a discrepancy between the CLI and D2.js rather than an ELK configuration issue.
Environment
@terrastruct/d20.1.33v0.7.0-HEAD(reported byawait d2.version())0.1.33(reported byawait d2.jsVersion())Minimal example
D2.js code
Expected behavior
The relationship should connect from the
users.idrow to theorders.user_idrow, matching the behavior of the D2 CLI.Actual behavior
The relationship connects from table to table rather than row to row.
Comparison with the CLI
Running the exact same D2 source via the CLI:
produces the expected row-to-row connections.
Additional investigation
await d2.version()returnsv0.7.0-HEAD.await d2.jsVersion()returns0.1.33.d2.compile()shows no explicit port definitions for SQL table rows, although it is unclear whether these are expected to be generated during compilation or later in the rendering pipeline.Conclusion
There appears to be a behavioral difference between the D2 CLI and the
@terrastruct/d2JavaScript package when rendering SQL tables with ELK. The CLI correctly performs row-to-row routing, while D2.js renders the same diagram as table-to-table.If this behavior is intentional, it would be helpful to document any additional API calls or options required to enable SQL table port routing in D2.js. Otherwise, this appears to be a bug or feature parity issue between the CLI and the JavaScript renderer.