d2js: updating target default + errors, readme

This commit is contained in:
delfino 2025-02-24 23:22:18 +00:00
parent 1417ded66a
commit 28e498aeaa
No known key found for this signature in database
GPG key ID: CFE0DD6A770BF48C
4 changed files with 53 additions and 9 deletions

View file

@ -4,7 +4,7 @@
#### Improvements 🧹
- d2js: Support `d2-config`. Support additional render options: [#2343](https://github.com/terrastruct/d2/pull/2343)
- d2js: Support `d2-config`. Support additional options: [#2343](https://github.com/terrastruct/d2/pull/2343)
- `themeID`
- `darkThemeID`
- `center`

View file

@ -271,20 +271,24 @@ func Render(args []js.Value) (interface{}, error) {
return nil, &WASMError{Message: "missing 'diagram' field in input JSON", Code: 400}
}
animateInterval := 0
if input.Opts != nil && input.Opts.AnimateInterval != nil && *input.Opts.AnimateInterval > 0 {
animateInterval = int(*input.Opts.AnimateInterval)
}
var boardPath []string
var noChildren bool
noChildren := true
if input.Opts.Target != nil {
switch *input.Opts.Target {
case "*":
noChildren = false
case "":
noChildren = true
default:
target := *input.Opts.Target
if strings.HasSuffix(target, ".*") {
target = target[:len(target)-2]
} else {
noChildren = true
noChildren = false
}
key, err := d2parser.ParseKey(target)
if err != nil {
@ -292,6 +296,9 @@ func Render(args []js.Value) (interface{}, error) {
}
boardPath = key.StringIDA()
}
if !noChildren && animateInterval <= 0 {
return nil, &WASMError{Message: fmt.Sprintf("target '%s' only supported for animated SVGs", *input.Opts.Target), Code: 500}
}
}
diagram := input.Diagram.GetBoard(boardPath)
@ -310,9 +317,7 @@ func Render(args []js.Value) (interface{}, error) {
renderOpts.Salt = input.Opts.Salt
}
var animateInterval = 0
if input.Opts != nil && input.Opts.AnimateInterval != nil && *input.Opts.AnimateInterval > 0 {
animateInterval = int(*input.Opts.AnimateInterval)
if animateInterval > 0 {
masterID, err := diagram.HashID(renderOpts.Salt)
if err != nil {
return nil, &WASMError{Message: fmt.Sprintf("cannot process animate interval: %s", err.Error()), Code: 500}

View file

@ -87,7 +87,7 @@ All [RenderOptions](#renderoptions) properties in addition to:
- `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.
- `forceAppendix`: Adds an appendix for tooltips and links [default: false]
- `target`: Target board to render. Pass an empty string to target root board. If target ends with '*', it will be rendered with all of its scenarios, steps, and layers. Otherwise, only the target board will be rendered. E.g. --target='' to render root board only or --target='layers.x.*' to render layer 'x' with all of its children.
- `target`: Target board/s to render. If target ends with '*', it will be rendered with all of its scenarios, steps, and layers. Otherwise, only the target board will be rendered. Pass '*' to render all scenarios, steps, and layers. E.g. `target: 'layers.x.*'` to render layer 'x' with all of its children. Multi-board outputs are currently only supported for animated SVGs and so `animateInterval` must be set to a value greater than 0.
- `animateInterval`: If given, multiple boards are packaged as 1 SVG which transitions through each board at the interval (in milliseconds).
- `salt`: Add a salt value to ensure the output uses unique IDs. This is useful when generating multiple identical diagrams to be included in the same HTML doc, so that duplicate IDs do not cause invalid HTML. The salt value is a string that will be appended to IDs in the output.
- `noXMLTag`: Omit XML tag `(<?xml ...?>)` from output SVG files. Useful when generating SVGs for direct HTML embedding.

View file

@ -121,6 +121,24 @@ x -> y
await d2.worker.terminate();
}, 20000);
test("animated multi-board works", async () => {
const d2 = new D2();
const source = `
x -> y
layers: {
numbers: {
1 -> 2
}
}
`;
const options = { target: "*", animateInterval: 1000 };
const result = await d2.compile(source, options);
const svg = await d2.render(result.diagram, result.renderOptions);
expect(svg).toContain("<svg");
expect(svg).toContain("</svg>");
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} |");
@ -141,4 +159,25 @@ x -> y
}
await d2.worker.terminate();
}, 20000);
test("handles unanimated multi-board error correctly", async () => {
const d2 = new D2();
const source = `
x -> y
layers: {
numbers: {
1 -> 2
}
}
`;
const result = await d2.compile(source);
try {
await d2.render(result.diagram, { target: "*" });
throw new Error("Should have thrown compile error");
} catch (err) {
expect(err).toBeDefined();
expect(err.message).not.toContain("Should have thrown compile error");
}
await d2.worker.terminate();
}, 20000);
});