From 995110bc91abbf5c1b8382ecaf95aabdb1067b2d Mon Sep 17 00:00:00 2001 From: delfino Date: Tue, 11 Feb 2025 04:10:27 +0000 Subject: [PATCH 01/18] adding additional options for d2js --- ci/release/changelogs/next.md | 2 + d2js/d2wasm/functions.go | 24 ++++++ d2js/d2wasm/types.go | 10 ++- d2js/js/README.md | 5 ++ d2js/js/examples/customizable.html | 115 ++++++++++++++++++++++++++++- d2js/js/test/unit/basic.test.js | 10 +++ 6 files changed, 160 insertions(+), 6 deletions(-) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index f3c0d2a77..8cefc73b2 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -2,4 +2,6 @@ #### Improvements 🧹 +d2js: Support additional render options [#2343](https://github.com/terrastruct/d2/pull/2343) + #### Bugfixes ⛑️ diff --git a/d2js/d2wasm/functions.go b/d2js/d2wasm/functions.go index 9cb8e5b26..1a9e55727 100644 --- a/d2js/d2wasm/functions.go +++ b/d2js/d2wasm/functions.go @@ -201,9 +201,21 @@ func Compile(args []js.Value) (interface{}, error) { fontFamily = go2.Pointer(d2fonts.HandDrawn) renderOpts.Sketch = input.Opts.Sketch } + if input.Opts != nil && input.Opts.Pad != nil { + renderOpts.Pad = input.Opts.Pad + } + if input.Opts != nil && input.Opts.Center != nil { + renderOpts.Center = input.Opts.Center + } if input.Opts != nil && input.Opts.ThemeID != nil { renderOpts.ThemeID = input.Opts.ThemeID } + if input.Opts != nil && input.Opts.DarkThemeID != nil { + renderOpts.DarkThemeID = input.Opts.DarkThemeID + } + if input.Opts != nil && input.Opts.Scale != nil { + renderOpts.Scale = input.Opts.Scale + } diagram, g, err := d2lib.Compile(ctx, input.FS["index"], &d2lib.CompileOptions{ UTF16Pos: true, FS: fs, @@ -245,9 +257,21 @@ func Render(args []js.Value) (interface{}, error) { if input.Opts != nil && input.Opts.Sketch != nil { renderOpts.Sketch = input.Opts.Sketch } + if input.Opts != nil && input.Opts.Pad != nil { + renderOpts.Pad = input.Opts.Pad + } + if input.Opts != nil && input.Opts.Center != nil { + renderOpts.Center = input.Opts.Center + } if input.Opts != nil && input.Opts.ThemeID != nil { renderOpts.ThemeID = input.Opts.ThemeID } + if input.Opts != nil && input.Opts.DarkThemeID != nil { + renderOpts.DarkThemeID = input.Opts.DarkThemeID + } + if input.Opts != nil && input.Opts.Scale != nil { + renderOpts.Scale = input.Opts.Scale + } out, err := d2svg.Render(input.Diagram, renderOpts) if err != nil { return nil, &WASMError{Message: fmt.Sprintf("render failed: %s", err.Error()), Code: 500} diff --git a/d2js/d2wasm/types.go b/d2js/d2wasm/types.go index a13b82bae..34098c60b 100644 --- a/d2js/d2wasm/types.go +++ b/d2js/d2wasm/types.go @@ -37,9 +37,13 @@ type CompileRequest struct { } type RenderOptions struct { - Layout *string `json:"layout"` - Sketch *bool `json:"sketch"` - ThemeID *int64 `json:"themeID"` + Layout *string `json:"layout"` + Pad *int64 `json:"pad"` + Sketch *bool `json:"sketch"` + Center *bool `json:"center"` + ThemeID *int64 `json:"themeID"` + DarkThemeID *int64 `json:"darkThemeID"` + Scale *float64 `json:"scale"` } type CompileResponse struct { diff --git a/d2js/js/README.md b/d2js/js/README.md index 5918a8f0a..b355c6fb7 100644 --- a/d2js/js/README.md +++ b/d2js/js/README.md @@ -56,6 +56,11 @@ Compiles D2 markup into an intermediate representation. Options: - `layout`: Layout engine to use ('dagre' | 'elk') [default: 'dagre'] - `sketch`: Enable sketch mode [default: false] +- `themeId`: Theme ID to use [default: 0] +- `darkThemeId`: Theme ID to use when client is in dark mode +- `center`: Center the SVG in the containing viewbox [default: false] +- `pad`: Pixels padded around the rendered diagram [default: 100] +- `scale`: Scale the output. E.g., 0.5 to halve the default size. The default will render SVG's that will fit to screen. Setting to 1 turns off SVG fitting to screen. ### `render(diagram: Diagram, options?: RenderOptions): Promise` Renders a compiled diagram to SVG. diff --git a/d2js/js/examples/customizable.html b/d2js/js/examples/customizable.html index 13b7a2138..8da30c086 100644 --- a/d2js/js/examples/customizable.html +++ b/d2js/js/examples/customizable.html @@ -33,7 +33,12 @@ border-radius: 4px; } .layout-toggle, - .sketch-toggle { + .sketch-toggle, + .center-toggle, + .theme-select, + .dark-theme-select, + .padding-input, + .scale-input { display: flex; gap: 16px; align-items: center; @@ -42,6 +47,8 @@ display: flex; gap: 12px; } + .input-label, + .select-label, .radio-label, .checkbox-label { display: flex; @@ -49,6 +56,9 @@ align-items: center; cursor: pointer; } + .number-input { + width: 3rem; + } button { padding: 8px 16px; background: #0066cc; @@ -96,6 +106,74 @@ Sketch mode +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
@@ -104,12 +182,43 @@ import { D2 } from "../dist/browser/index.js"; const d2 = new D2(); window.compile = async () => { + const notNegative = (value) => { + if (value < 0) { + return null; + } else return value; + }; const input = document.getElementById("input").value; const layout = document.querySelector('input[name="layout"]:checked').value; const sketch = document.getElementById("sketch").checked; + const center = document.getElementById("center").checked; + const themeSelector = document.getElementById("theme"); + const themeId = notNegative( + Number(themeSelector.options[themeSelector.selectedIndex].value) + ); + const darkThemeSelector = document.getElementById("dark-theme"); + const darkThemeId = notNegative( + Number(darkThemeSelector.options[darkThemeSelector.selectedIndex].value) + ); + const scale = notNegative(Number(document.getElementById("scale").value)); + const pad = Number(document.getElementById("padding").value); try { - const result = await d2.compile(input, { layout, sketch }); - const svg = await d2.render(result.diagram, { sketch }); + const result = await d2.compile(input, { + layout, + sketch, + themeId, + darkThemeId, + scale, + pad, + center, + }); + const svg = await d2.render(result.diagram, { + sketch, + themeId, + darkThemeId, + scale, + pad, + center, + }); document.getElementById("output").innerHTML = svg; } catch (err) { console.error(err); diff --git a/d2js/js/test/unit/basic.test.js b/d2js/js/test/unit/basic.test.js index 063c02b7e..7f4b5a936 100644 --- a/d2js/js/test/unit/basic.test.js +++ b/d2js/js/test/unit/basic.test.js @@ -35,6 +35,16 @@ describe("D2 Unit Tests", () => { await d2.worker.terminate(); }, 20000); + test("center render works", async () => { + const d2 = new D2(); + const result = await d2.compile("x -> y", { center: true }); + const svg = await d2.render(result.diagram, { center: true }); + expect(svg).toContain(""); + expect(svg).toContain("xMidYMid meet"); + await d2.worker.terminate(); + }, 20000); + test("latex works", async () => { const d2 = new D2(); const result = await d2.compile("x: |latex \\frac{f(x+h)-f(x)}{h} |"); From 4ce43c324831ff11411362382a41c74694ca18f4 Mon Sep 17 00:00:00 2001 From: delfino Date: Thu, 13 Feb 2025 12:20:38 +0000 Subject: [PATCH 02/18] updating changelog and readme --- ci/release/changelogs/next.md | 2 +- d2js/js/README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 8cefc73b2..4a1a65c84 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -2,6 +2,6 @@ #### Improvements 🧹 -d2js: Support additional render options [#2343](https://github.com/terrastruct/d2/pull/2343) +d2js: Support additional render options (`themeID`, `darkThemeID`, `center`, `pad` and `scale`) [#2343](https://github.com/terrastruct/d2/pull/2343) #### Bugfixes ⛑️ diff --git a/d2js/js/README.md b/d2js/js/README.md index b355c6fb7..cdd77133f 100644 --- a/d2js/js/README.md +++ b/d2js/js/README.md @@ -56,8 +56,8 @@ Compiles D2 markup into an intermediate representation. Options: - `layout`: Layout engine to use ('dagre' | 'elk') [default: 'dagre'] - `sketch`: Enable sketch mode [default: false] -- `themeId`: Theme ID to use [default: 0] -- `darkThemeId`: Theme ID to use when client is in dark mode +- `themeID`: Theme ID to use [default: 0] +- `darkThemeID`: Theme ID to use when client is in dark mode - `center`: Center the SVG in the containing viewbox [default: false] - `pad`: Pixels padded around the rendered diagram [default: 100] - `scale`: Scale the output. E.g., 0.5 to halve the default size. The default will render SVG's that will fit to screen. Setting to 1 turns off SVG fitting to screen. From 9fcb7f86abf72c7ab9a256d2ea3f16f9198d92e5 Mon Sep 17 00:00:00 2001 From: delfino Date: Thu, 13 Feb 2025 19:06:37 +0000 Subject: [PATCH 03/18] d2js: updating customizable example --- d2js/js/examples/customizable.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/d2js/js/examples/customizable.html b/d2js/js/examples/customizable.html index 8da30c086..561ea59e2 100644 --- a/d2js/js/examples/customizable.html +++ b/d2js/js/examples/customizable.html @@ -109,14 +109,14 @@
+