Skip to content

Commit 76c3de0

Browse files
committed
adding additional options for d2js
1 parent 73f2588 commit 76c3de0

File tree

5 files changed

+158
-6
lines changed

5 files changed

+158
-6
lines changed

d2js/d2wasm/functions.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,21 @@ func Compile(args []js.Value) (interface{}, error) {
201201
fontFamily = go2.Pointer(d2fonts.HandDrawn)
202202
renderOpts.Sketch = input.Opts.Sketch
203203
}
204+
if input.Opts != nil && input.Opts.Pad != nil {
205+
renderOpts.Pad = input.Opts.Pad
206+
}
207+
if input.Opts != nil && input.Opts.Center != nil {
208+
renderOpts.Center = input.Opts.Center
209+
}
204210
if input.Opts != nil && input.Opts.ThemeID != nil {
205211
renderOpts.ThemeID = input.Opts.ThemeID
206212
}
213+
if input.Opts != nil && input.Opts.DarkThemeID != nil {
214+
renderOpts.DarkThemeID = input.Opts.DarkThemeID
215+
}
216+
if input.Opts != nil && input.Opts.Scale != nil {
217+
renderOpts.Scale = input.Opts.Scale
218+
}
207219
diagram, g, err := d2lib.Compile(ctx, input.FS["index"], &d2lib.CompileOptions{
208220
UTF16Pos: true,
209221
FS: fs,
@@ -245,9 +257,21 @@ func Render(args []js.Value) (interface{}, error) {
245257
if input.Opts != nil && input.Opts.Sketch != nil {
246258
renderOpts.Sketch = input.Opts.Sketch
247259
}
260+
if input.Opts != nil && input.Opts.Pad != nil {
261+
renderOpts.Pad = input.Opts.Pad
262+
}
263+
if input.Opts != nil && input.Opts.Center != nil {
264+
renderOpts.Center = input.Opts.Center
265+
}
248266
if input.Opts != nil && input.Opts.ThemeID != nil {
249267
renderOpts.ThemeID = input.Opts.ThemeID
250268
}
269+
if input.Opts != nil && input.Opts.DarkThemeID != nil {
270+
renderOpts.DarkThemeID = input.Opts.DarkThemeID
271+
}
272+
if input.Opts != nil && input.Opts.Scale != nil {
273+
renderOpts.Scale = input.Opts.Scale
274+
}
251275
out, err := d2svg.Render(input.Diagram, renderOpts)
252276
if err != nil {
253277
return nil, &WASMError{Message: fmt.Sprintf("render failed: %s", err.Error()), Code: 500}

d2js/d2wasm/types.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,13 @@ type CompileRequest struct {
3737
}
3838

3939
type RenderOptions struct {
40-
Layout *string `json:"layout"`
41-
Sketch *bool `json:"sketch"`
42-
ThemeID *int64 `json:"themeID"`
40+
Layout *string `json:"layout"`
41+
Pad *int64 `json:"pad"`
42+
Sketch *bool `json:"sketch"`
43+
Center *bool `json:"center"`
44+
ThemeID *int64 `json:"themeID"`
45+
DarkThemeID *int64 `json:"darkThemeID"`
46+
Scale *float64 `json:"scale"`
4347
}
4448

4549
type CompileResponse struct {

d2js/js/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ Compiles D2 markup into an intermediate representation.
5656
Options:
5757
- `layout`: Layout engine to use ('dagre' | 'elk') [default: 'dagre']
5858
- `sketch`: Enable sketch mode [default: false]
59+
- `themeId`: Theme ID to use [default: 0]
60+
- `darkThemeId`: Theme ID to use when client is in dark mode
61+
- `center`: Center the SVG in the containing viewbox [default: false]
62+
- `pad`: Pixels padded around the rendered diagram [default: 100]
63+
- `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.
5964

6065
### `render(diagram: Diagram, options?: RenderOptions): Promise<string>`
6166
Renders a compiled diagram to SVG.

d2js/js/examples/customizable.html

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@
3333
border-radius: 4px;
3434
}
3535
.layout-toggle,
36-
.sketch-toggle {
36+
.sketch-toggle,
37+
.center-toggle,
38+
.theme-select,
39+
.dark-theme-select,
40+
.padding-input,
41+
.scale-input {
3742
display: flex;
3843
gap: 16px;
3944
align-items: center;
@@ -42,13 +47,18 @@
4247
display: flex;
4348
gap: 12px;
4449
}
50+
.input-label,
51+
.select-label,
4552
.radio-label,
4653
.checkbox-label {
4754
display: flex;
4855
gap: 4px;
4956
align-items: center;
5057
cursor: pointer;
5158
}
59+
.number-input {
60+
width: 3rem;
61+
}
5262
button {
5363
padding: 8px 16px;
5464
background: #0066cc;
@@ -96,6 +106,74 @@
96106
Sketch mode
97107
</label>
98108
</div>
109+
<div class="center-toggle">
110+
<label class="checkbox-label">
111+
<input type="checkbox" id="center" />
112+
Center mode
113+
</label>
114+
</div>
115+
<div class="theme-select">
116+
<label class="select-label">
117+
<select id="theme" name="theme">
118+
<option value="-1"></option>
119+
<option value="0">Default</option>
120+
<option value="1">Neutral grey</option>
121+
<option value="3">Flagship Terrastruct</option>
122+
<option value="4">Cool classics</option>
123+
<option value="5">Mixed berry blue</option>
124+
<option value="6">Grape soda</option>
125+
<option value="7">Aubergine</option>
126+
<option value="8">Colorblind clear</option>
127+
<option value="100">Vanilla nitro cola</option>
128+
<option value="101">Orange creamsicle</option>
129+
<option value="102">Shirley temple</option>
130+
<option value="103">Earth tones</option>
131+
<option value="104">Everglade green</option>
132+
<option value="105">Buttered toast</option>
133+
<option value="200">Dark mauve</option>
134+
<option value="300">Terminal</option>
135+
<option value="301">Terminal grayscale</option>
136+
</select>
137+
Theme ID
138+
</label>
139+
</div>
140+
<div class="dark-theme-select">
141+
<label class="select-label">
142+
<select id="dark-theme" name="dark-theme">
143+
<option value="-1"></option>
144+
<option value="0">Default</option>
145+
<option value="1">Neutral grey</option>
146+
<option value="3">Flagship Terrastruct</option>
147+
<option value="4">Cool classics</option>
148+
<option value="5">Mixed berry blue</option>
149+
<option value="6">Grape soda</option>
150+
<option value="7">Aubergine</option>
151+
<option value="8">Colorblind clear</option>
152+
<option value="100">Vanilla nitro cola</option>
153+
<option value="101">Orange creamsicle</option>
154+
<option value="102">Shirley temple</option>
155+
<option value="103">Earth tones</option>
156+
<option value="104">Everglade green</option>
157+
<option value="105">Buttered toast</option>
158+
<option value="200">Dark mauve</option>
159+
<option value="300">Terminal</option>
160+
<option value="301">Terminal grayscale</option>
161+
</select>
162+
Dark Theme ID
163+
</label>
164+
</div>
165+
<div class="padding-input">
166+
<label class="input-label">
167+
<input type="number" id="padding" value="20" step="10" class="number-input" />
168+
Padding
169+
</label>
170+
</div>
171+
<div class="scale-input">
172+
<label class="input-label">
173+
<input type="number" id="scale" value="-1" step="1" class="number-input" />
174+
Scale
175+
</label>
176+
</div>
99177
</div>
100178
<button onclick="compile()">Compile</button>
101179
</div>
@@ -104,12 +182,43 @@
104182
import { D2 } from "../dist/browser/index.js";
105183
const d2 = new D2();
106184
window.compile = async () => {
185+
const notNegative = (value) => {
186+
if (value < 0) {
187+
return null;
188+
} else return value;
189+
};
107190
const input = document.getElementById("input").value;
108191
const layout = document.querySelector('input[name="layout"]:checked').value;
109192
const sketch = document.getElementById("sketch").checked;
193+
const center = document.getElementById("center").checked;
194+
const themeSelector = document.getElementById("theme");
195+
const themeId = notNegative(
196+
Number(themeSelector.options[themeSelector.selectedIndex].value)
197+
);
198+
const darkThemeSelector = document.getElementById("dark-theme");
199+
const darkThemeId = notNegative(
200+
Number(darkThemeSelector.options[darkThemeSelector.selectedIndex].value)
201+
);
202+
const scale = notNegative(Number(document.getElementById("scale").value));
203+
const pad = Number(document.getElementById("padding").value);
110204
try {
111-
const result = await d2.compile(input, { layout, sketch });
112-
const svg = await d2.render(result.diagram, { sketch });
205+
const result = await d2.compile(input, {
206+
layout,
207+
sketch,
208+
themeId,
209+
darkThemeId,
210+
scale,
211+
pad,
212+
center,
213+
});
214+
const svg = await d2.render(result.diagram, {
215+
sketch,
216+
themeId,
217+
darkThemeId,
218+
scale,
219+
pad,
220+
center,
221+
});
113222
document.getElementById("output").innerHTML = svg;
114223
} catch (err) {
115224
console.error(err);

d2js/js/test/unit/basic.test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ describe("D2 Unit Tests", () => {
3535
await d2.worker.terminate();
3636
}, 20000);
3737

38+
test("center render works", async () => {
39+
const d2 = new D2();
40+
const result = await d2.compile("x -> y", { center: true });
41+
const svg = await d2.render(result.diagram, { center: true });
42+
expect(svg).toContain("<svg");
43+
expect(svg).toContain("</svg>");
44+
expect(svg).toContain("xMidYMid meet");
45+
await d2.worker.terminate();
46+
}, 20000);
47+
3848
test("latex works", async () => {
3949
const d2 = new D2();
4050
const result = await d2.compile("x: |latex \\frac{f(x+h)-f(x)}{h} |");

0 commit comments

Comments
 (0)