migrate sketch
This commit is contained in:
parent
e723881dfe
commit
9c19637fff
6 changed files with 107 additions and 74 deletions
|
|
@ -24,7 +24,16 @@
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
.layout-toggle {
|
.options-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.layout-toggle,
|
||||||
|
.sketch-toggle {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
@ -33,7 +42,8 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
.radio-label {
|
.radio-label,
|
||||||
|
.checkbox-label {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
@ -66,16 +76,24 @@
|
||||||
<body>
|
<body>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<textarea id="input">x -> y</textarea>
|
<textarea id="input">x -> y</textarea>
|
||||||
<div class="layout-toggle">
|
<div class="options-group">
|
||||||
<span>Layout:</span>
|
<div class="layout-toggle">
|
||||||
<div class="radio-group">
|
<span>Layout:</span>
|
||||||
<label class="radio-label">
|
<div class="radio-group">
|
||||||
<input type="radio" name="layout" value="dagre" checked />
|
<label class="radio-label">
|
||||||
Dagre
|
<input type="radio" name="layout" value="dagre" checked />
|
||||||
</label>
|
Dagre
|
||||||
<label class="radio-label">
|
</label>
|
||||||
<input type="radio" name="layout" value="elk" />
|
<label class="radio-label">
|
||||||
ELK
|
<input type="radio" name="layout" value="elk" />
|
||||||
|
ELK
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sketch-toggle">
|
||||||
|
<label class="checkbox-label">
|
||||||
|
<input type="checkbox" id="sketch" />
|
||||||
|
Sketch mode
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -88,9 +106,10 @@
|
||||||
window.compile = async () => {
|
window.compile = async () => {
|
||||||
const input = document.getElementById("input").value;
|
const input = document.getElementById("input").value;
|
||||||
const layout = document.querySelector('input[name="layout"]:checked').value;
|
const layout = document.querySelector('input[name="layout"]:checked').value;
|
||||||
|
const sketch = document.getElementById("sketch").checked;
|
||||||
try {
|
try {
|
||||||
const result = await d2.compile(input, { layout });
|
const result = await d2.compile(input, { layout, sketch });
|
||||||
const svg = await d2.render(result.diagram);
|
const svg = await d2.render(result.diagram, { sketch });
|
||||||
document.getElementById("output").innerHTML = svg;
|
document.getElementById("output").innerHTML = svg;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { parentPort } from "node:worker_threads";
|
||||||
|
|
||||||
let currentPort;
|
let currentPort;
|
||||||
let d2;
|
let d2;
|
||||||
|
let elk;
|
||||||
|
|
||||||
export function setupMessageHandler(isNode, port, initWasm) {
|
export function setupMessageHandler(isNode, port, initWasm) {
|
||||||
currentPort = port;
|
currentPort = port;
|
||||||
|
|
@ -14,8 +15,10 @@ export function setupMessageHandler(isNode, port, initWasm) {
|
||||||
try {
|
try {
|
||||||
if (isNode) {
|
if (isNode) {
|
||||||
eval(data.wasmExecContent);
|
eval(data.wasmExecContent);
|
||||||
|
eval(data.elkContent);
|
||||||
}
|
}
|
||||||
d2 = await initWasm(data.wasm);
|
d2 = await initWasm(data.wasm);
|
||||||
|
elk = new ELK();
|
||||||
currentPort.postMessage({ type: "ready" });
|
currentPort.postMessage({ type: "ready" });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
currentPort.postMessage({ type: "error", error: err.message });
|
currentPort.postMessage({ type: "error", error: err.message });
|
||||||
|
|
@ -24,6 +27,12 @@ export function setupMessageHandler(isNode, port, initWasm) {
|
||||||
|
|
||||||
case "compile":
|
case "compile":
|
||||||
try {
|
try {
|
||||||
|
if (data.options.layout === "elk") {
|
||||||
|
const elkGraph = await d2.getELKGraph(JSON.stringify(data));
|
||||||
|
const elkGraph2 = JSON.parse(elkGraph).data;
|
||||||
|
const layout = await elk.layout(elkGraph2);
|
||||||
|
globalThis.elkResult = layout;
|
||||||
|
}
|
||||||
const result = await d2.compile(JSON.stringify(data));
|
const result = await d2.compile(JSON.stringify(data));
|
||||||
const response = JSON.parse(result);
|
const response = JSON.parse(result);
|
||||||
if (response.error) throw new Error(response.error.message);
|
if (response.error) throw new Error(response.error.message);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,16 @@ describe("D2 Unit Tests", () => {
|
||||||
await d2.worker.terminate();
|
await d2.worker.terminate();
|
||||||
}, 20000);
|
}, 20000);
|
||||||
|
|
||||||
|
test("sketch render works", async () => {
|
||||||
|
const d2 = new D2();
|
||||||
|
const result = await d2.compile("x -> y", { sketch: true });
|
||||||
|
const svg = await d2.render(result.diagram, { sketch: true });
|
||||||
|
expect(svg).toContain("<svg");
|
||||||
|
expect(svg).toContain("</svg>");
|
||||||
|
expect(svg).toContain("sketch-overlay");
|
||||||
|
await d2.worker.terminate();
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
test("handles syntax errors correctly", async () => {
|
test("handles syntax errors correctly", async () => {
|
||||||
const d2 = new D2();
|
const d2 = new D2();
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -17,3 +17,7 @@ const root = {
|
||||||
};
|
};
|
||||||
const rc = rough.svg(root, { seed: 1 });
|
const rc = rough.svg(root, { seed: 1 });
|
||||||
let node;
|
let node;
|
||||||
|
|
||||||
|
if (typeof globalThis !== 'undefined') {
|
||||||
|
globalThis.rc = rc;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,11 @@ import (
|
||||||
|
|
||||||
_ "embed"
|
_ "embed"
|
||||||
|
|
||||||
"github.com/dop251/goja"
|
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/d2target"
|
"oss.terrastruct.com/d2/d2target"
|
||||||
"oss.terrastruct.com/d2/d2themes"
|
"oss.terrastruct.com/d2/d2themes"
|
||||||
"oss.terrastruct.com/d2/lib/color"
|
"oss.terrastruct.com/d2/lib/color"
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
|
"oss.terrastruct.com/d2/lib/jsrunner"
|
||||||
"oss.terrastruct.com/d2/lib/label"
|
"oss.terrastruct.com/d2/lib/label"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
"oss.terrastruct.com/util-go/go2"
|
"oss.terrastruct.com/util-go/go2"
|
||||||
|
|
@ -29,8 +28,6 @@ var setupJS string
|
||||||
//go:embed streaks.txt
|
//go:embed streaks.txt
|
||||||
var streaks string
|
var streaks string
|
||||||
|
|
||||||
type Runner goja.Runtime
|
|
||||||
|
|
||||||
var baseRoughProps = `fillWeight: 2.0,
|
var baseRoughProps = `fillWeight: 2.0,
|
||||||
hachureGap: 16,
|
hachureGap: 16,
|
||||||
fillStyle: "solid",
|
fillStyle: "solid",
|
||||||
|
|
@ -44,21 +41,14 @@ const (
|
||||||
FG_COLOR = color.N1
|
FG_COLOR = color.N1
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *Runner) run(js string) (goja.Value, error) {
|
func LoadJS(runner jsrunner.JSRunner) error {
|
||||||
vm := (*goja.Runtime)(r)
|
if _, err := runner.RunString(roughJS); err != nil {
|
||||||
return vm.RunString(js)
|
return err
|
||||||
}
|
|
||||||
|
|
||||||
func InitSketchVM() (*Runner, error) {
|
|
||||||
vm := goja.New()
|
|
||||||
if _, err := vm.RunString(roughJS); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
if _, err := vm.RunString(setupJS); err != nil {
|
if _, err := runner.RunString(setupJS); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
r := Runner(*vm)
|
return nil
|
||||||
return &r, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefineFillPatterns adds reusable patterns that are overlayed on shapes with
|
// DefineFillPatterns adds reusable patterns that are overlayed on shapes with
|
||||||
|
|
@ -83,7 +73,7 @@ func defineFillPattern(buf *bytes.Buffer, source string, luminanceCategory, fill
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Rect(r *Runner, shape d2target.Shape) (string, error) {
|
func Rect(r jsrunner.JSRunner, shape d2target.Shape) (string, error) {
|
||||||
js := fmt.Sprintf(`node = rc.rectangle(0, 0, %d, %d, {
|
js := fmt.Sprintf(`node = rc.rectangle(0, 0, %d, %d, {
|
||||||
fill: "#000",
|
fill: "#000",
|
||||||
stroke: "#000",
|
stroke: "#000",
|
||||||
|
|
@ -119,7 +109,7 @@ func Rect(r *Runner, shape d2target.Shape) (string, error) {
|
||||||
return output, nil
|
return output, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DoubleRect(r *Runner, shape d2target.Shape) (string, error) {
|
func DoubleRect(r jsrunner.JSRunner, shape d2target.Shape) (string, error) {
|
||||||
jsBigRect := fmt.Sprintf(`node = rc.rectangle(0, 0, %d, %d, {
|
jsBigRect := fmt.Sprintf(`node = rc.rectangle(0, 0, %d, %d, {
|
||||||
fill: "#000",
|
fill: "#000",
|
||||||
stroke: "#000",
|
stroke: "#000",
|
||||||
|
|
@ -179,7 +169,7 @@ func DoubleRect(r *Runner, shape d2target.Shape) (string, error) {
|
||||||
return output, nil
|
return output, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Oval(r *Runner, shape d2target.Shape) (string, error) {
|
func Oval(r jsrunner.JSRunner, shape d2target.Shape) (string, error) {
|
||||||
js := fmt.Sprintf(`node = rc.ellipse(%d, %d, %d, %d, {
|
js := fmt.Sprintf(`node = rc.ellipse(%d, %d, %d, %d, {
|
||||||
fill: "#000",
|
fill: "#000",
|
||||||
stroke: "#000",
|
stroke: "#000",
|
||||||
|
|
@ -218,7 +208,7 @@ func Oval(r *Runner, shape d2target.Shape) (string, error) {
|
||||||
return output, nil
|
return output, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DoubleOval(r *Runner, shape d2target.Shape) (string, error) {
|
func DoubleOval(r jsrunner.JSRunner, shape d2target.Shape) (string, error) {
|
||||||
jsBigCircle := fmt.Sprintf(`node = rc.ellipse(%d, %d, %d, %d, {
|
jsBigCircle := fmt.Sprintf(`node = rc.ellipse(%d, %d, %d, %d, {
|
||||||
fill: "#000",
|
fill: "#000",
|
||||||
stroke: "#000",
|
stroke: "#000",
|
||||||
|
|
@ -281,7 +271,7 @@ func DoubleOval(r *Runner, shape d2target.Shape) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO need to personalize this per shape like we do in Terrastruct app
|
// TODO need to personalize this per shape like we do in Terrastruct app
|
||||||
func Paths(r *Runner, shape d2target.Shape, paths []string) (string, error) {
|
func Paths(r jsrunner.JSRunner, shape d2target.Shape, paths []string) (string, error) {
|
||||||
output := ""
|
output := ""
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
js := fmt.Sprintf(`node = rc.path("%s", {
|
js := fmt.Sprintf(`node = rc.path("%s", {
|
||||||
|
|
@ -320,7 +310,7 @@ func Paths(r *Runner, shape d2target.Shape, paths []string) (string, error) {
|
||||||
return output, nil
|
return output, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Connection(r *Runner, connection d2target.Connection, path, attrs string) (string, error) {
|
func Connection(r jsrunner.JSRunner, connection d2target.Connection, path, attrs string) (string, error) {
|
||||||
animatedClass := ""
|
animatedClass := ""
|
||||||
if connection.Animated {
|
if connection.Animated {
|
||||||
animatedClass = " animated-connection"
|
animatedClass = " animated-connection"
|
||||||
|
|
@ -388,7 +378,7 @@ func Connection(r *Runner, connection d2target.Connection, path, attrs string) (
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO cleanup
|
// TODO cleanup
|
||||||
func Table(r *Runner, shape d2target.Shape) (string, error) {
|
func Table(r jsrunner.JSRunner, shape d2target.Shape) (string, error) {
|
||||||
output := ""
|
output := ""
|
||||||
js := fmt.Sprintf(`node = rc.rectangle(0, 0, %d, %d, {
|
js := fmt.Sprintf(`node = rc.rectangle(0, 0, %d, %d, {
|
||||||
fill: "#000",
|
fill: "#000",
|
||||||
|
|
@ -530,7 +520,7 @@ func Table(r *Runner, shape d2target.Shape) (string, error) {
|
||||||
return output, nil
|
return output, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Class(r *Runner, shape d2target.Shape) (string, error) {
|
func Class(r jsrunner.JSRunner, shape d2target.Shape) (string, error) {
|
||||||
output := ""
|
output := ""
|
||||||
js := fmt.Sprintf(`node = rc.rectangle(0, 0, %d, %d, {
|
js := fmt.Sprintf(`node = rc.rectangle(0, 0, %d, %d, {
|
||||||
fill: "#000",
|
fill: "#000",
|
||||||
|
|
@ -681,8 +671,8 @@ func classRow(shape d2target.Shape, box *geo.Box, prefix, nameText, typeText str
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
func computeRoughPathData(r *Runner, js string) ([]string, error) {
|
func computeRoughPathData(r jsrunner.JSRunner, js string) ([]string, error) {
|
||||||
if _, err := r.run(js); err != nil {
|
if _, err := r.RunString(js); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
roughPaths, err := extractRoughPaths(r)
|
roughPaths, err := extractRoughPaths(r)
|
||||||
|
|
@ -692,8 +682,8 @@ func computeRoughPathData(r *Runner, js string) ([]string, error) {
|
||||||
return extractPathData(roughPaths)
|
return extractPathData(roughPaths)
|
||||||
}
|
}
|
||||||
|
|
||||||
func computeRoughPaths(r *Runner, js string) ([]roughPath, error) {
|
func computeRoughPaths(r jsrunner.JSRunner, js string) ([]roughPath, error) {
|
||||||
if _, err := r.run(js); err != nil {
|
if _, err := r.RunString(js); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return extractRoughPaths(r)
|
return extractRoughPaths(r)
|
||||||
|
|
@ -722,8 +712,8 @@ func (rp roughPath) StyleCSS() string {
|
||||||
return style
|
return style
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractRoughPaths(r *Runner) ([]roughPath, error) {
|
func extractRoughPaths(r jsrunner.JSRunner) ([]roughPath, error) {
|
||||||
val, err := r.run("JSON.stringify(node.children, null, ' ')")
|
val, err := r.RunString("JSON.stringify(node.children, null, ' ')")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -756,7 +746,7 @@ func extractPathData(roughPaths []roughPath) ([]string, error) {
|
||||||
return paths, nil
|
return paths, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ArrowheadJS(r *Runner, arrowhead d2target.Arrowhead, stroke string, strokeWidth int) (arrowJS, extraJS string) {
|
func ArrowheadJS(r jsrunner.JSRunner, arrowhead d2target.Arrowhead, stroke string, strokeWidth int) (arrowJS, extraJS string) {
|
||||||
// Note: selected each seed that looks the good for consistent renders
|
// Note: selected each seed that looks the good for consistent renders
|
||||||
switch arrowhead {
|
switch arrowhead {
|
||||||
case d2target.ArrowArrowhead:
|
case d2target.ArrowArrowhead:
|
||||||
|
|
@ -854,7 +844,7 @@ func ArrowheadJS(r *Runner, arrowhead d2target.Arrowhead, stroke string, strokeW
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func Arrowheads(r *Runner, connection d2target.Connection, srcAdj, dstAdj *geo.Point) (string, error) {
|
func Arrowheads(r jsrunner.JSRunner, connection d2target.Connection, srcAdj, dstAdj *geo.Point) (string, error) {
|
||||||
arrowPaths := []string{}
|
arrowPaths := []string{}
|
||||||
|
|
||||||
if connection.SrcArrow != d2target.NoArrowhead {
|
if connection.SrcArrow != d2target.NoArrowhead {
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import (
|
||||||
"oss.terrastruct.com/d2/d2themes/d2themescatalog"
|
"oss.terrastruct.com/d2/d2themes/d2themescatalog"
|
||||||
"oss.terrastruct.com/d2/lib/color"
|
"oss.terrastruct.com/d2/lib/color"
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
|
"oss.terrastruct.com/d2/lib/jsrunner"
|
||||||
"oss.terrastruct.com/d2/lib/label"
|
"oss.terrastruct.com/d2/lib/label"
|
||||||
"oss.terrastruct.com/d2/lib/shape"
|
"oss.terrastruct.com/d2/lib/shape"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
|
@ -496,7 +497,7 @@ func makeLabelMask(labelTL *geo.Point, width, height int, opacity float64) strin
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawConnection(writer io.Writer, labelMaskID string, connection d2target.Connection, markers map[string]struct{}, idToShape map[string]d2target.Shape, sketchRunner *d2sketch.Runner, inlineTheme *d2themes.Theme) (labelMask string, _ error) {
|
func drawConnection(writer io.Writer, labelMaskID string, connection d2target.Connection, markers map[string]struct{}, idToShape map[string]d2target.Shape, jsRunner jsrunner.JSRunner, inlineTheme *d2themes.Theme) (labelMask string, _ error) {
|
||||||
opacityStyle := ""
|
opacityStyle := ""
|
||||||
if connection.Opacity != 1.0 {
|
if connection.Opacity != 1.0 {
|
||||||
opacityStyle = fmt.Sprintf(" style='opacity:%f'", connection.Opacity)
|
opacityStyle = fmt.Sprintf(" style='opacity:%f'", connection.Opacity)
|
||||||
|
|
@ -552,15 +553,15 @@ func drawConnection(writer io.Writer, labelMaskID string, connection d2target.Co
|
||||||
path := pathData(connection, srcAdj, dstAdj)
|
path := pathData(connection, srcAdj, dstAdj)
|
||||||
mask := fmt.Sprintf(`mask="url(#%s)"`, labelMaskID)
|
mask := fmt.Sprintf(`mask="url(#%s)"`, labelMaskID)
|
||||||
|
|
||||||
if sketchRunner != nil {
|
if jsRunner != nil {
|
||||||
out, err := d2sketch.Connection(sketchRunner, connection, path, mask)
|
out, err := d2sketch.Connection(jsRunner, connection, path, mask)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
fmt.Fprint(writer, out)
|
fmt.Fprint(writer, out)
|
||||||
|
|
||||||
// render sketch arrowheads separately
|
// render sketch arrowheads separately
|
||||||
arrowPaths, err := d2sketch.Arrowheads(sketchRunner, connection, srcAdj, dstAdj)
|
arrowPaths, err := d2sketch.Arrowheads(jsRunner, connection, srcAdj, dstAdj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
@ -957,7 +958,7 @@ func render3DHexagon(targetShape d2target.Shape, inlineTheme *d2themes.Theme) st
|
||||||
return borderMask + mainShapeRendered + renderedSides + renderedBorder
|
return borderMask + mainShapeRendered + renderedSides + renderedBorder
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape d2target.Shape, sketchRunner *d2sketch.Runner, inlineTheme *d2themes.Theme) (labelMask string, err error) {
|
func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape d2target.Shape, jsRunner jsrunner.JSRunner, inlineTheme *d2themes.Theme) (labelMask string, err error) {
|
||||||
closingTag := "</g>"
|
closingTag := "</g>"
|
||||||
if targetShape.Link != "" {
|
if targetShape.Link != "" {
|
||||||
|
|
||||||
|
|
@ -1021,8 +1022,8 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape
|
||||||
|
|
||||||
switch targetShape.Type {
|
switch targetShape.Type {
|
||||||
case d2target.ShapeClass:
|
case d2target.ShapeClass:
|
||||||
if sketchRunner != nil {
|
if jsRunner != nil {
|
||||||
out, err := d2sketch.Class(sketchRunner, targetShape)
|
out, err := d2sketch.Class(jsRunner, targetShape)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
@ -1035,8 +1036,8 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape
|
||||||
fmt.Fprint(writer, closingTag)
|
fmt.Fprint(writer, closingTag)
|
||||||
return labelMask, nil
|
return labelMask, nil
|
||||||
case d2target.ShapeSQLTable:
|
case d2target.ShapeSQLTable:
|
||||||
if sketchRunner != nil {
|
if jsRunner != nil {
|
||||||
out, err := d2sketch.Table(sketchRunner, targetShape)
|
out, err := d2sketch.Table(jsRunner, targetShape)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
@ -1053,8 +1054,8 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape
|
||||||
if targetShape.Multiple {
|
if targetShape.Multiple {
|
||||||
fmt.Fprint(writer, renderDoubleOval(multipleTL, width, height, fill, "", stroke, style, inlineTheme))
|
fmt.Fprint(writer, renderDoubleOval(multipleTL, width, height, fill, "", stroke, style, inlineTheme))
|
||||||
}
|
}
|
||||||
if sketchRunner != nil {
|
if jsRunner != nil {
|
||||||
out, err := d2sketch.DoubleOval(sketchRunner, targetShape)
|
out, err := d2sketch.DoubleOval(jsRunner, targetShape)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
@ -1066,8 +1067,8 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape
|
||||||
if targetShape.Multiple {
|
if targetShape.Multiple {
|
||||||
fmt.Fprint(writer, renderOval(multipleTL, width, height, fill, "", stroke, style, inlineTheme))
|
fmt.Fprint(writer, renderOval(multipleTL, width, height, fill, "", stroke, style, inlineTheme))
|
||||||
}
|
}
|
||||||
if sketchRunner != nil {
|
if jsRunner != nil {
|
||||||
out, err := d2sketch.Oval(sketchRunner, targetShape)
|
out, err := d2sketch.Oval(jsRunner, targetShape)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
@ -1111,8 +1112,8 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape
|
||||||
el.Rx = borderRadius
|
el.Rx = borderRadius
|
||||||
fmt.Fprint(writer, el.Render())
|
fmt.Fprint(writer, el.Render())
|
||||||
}
|
}
|
||||||
if sketchRunner != nil {
|
if jsRunner != nil {
|
||||||
out, err := d2sketch.Rect(sketchRunner, targetShape)
|
out, err := d2sketch.Rect(jsRunner, targetShape)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
@ -1155,8 +1156,8 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape
|
||||||
el.Rx = borderRadius
|
el.Rx = borderRadius
|
||||||
fmt.Fprint(writer, el.Render())
|
fmt.Fprint(writer, el.Render())
|
||||||
}
|
}
|
||||||
if sketchRunner != nil {
|
if jsRunner != nil {
|
||||||
out, err := d2sketch.DoubleRect(sketchRunner, targetShape)
|
out, err := d2sketch.DoubleRect(jsRunner, targetShape)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
@ -1203,8 +1204,8 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sketchRunner != nil {
|
if jsRunner != nil {
|
||||||
out, err := d2sketch.Paths(sketchRunner, targetShape, s.GetSVGPathData())
|
out, err := d2sketch.Paths(jsRunner, targetShape, s.GetSVGPathData())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
@ -1235,8 +1236,8 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sketchRunner != nil {
|
if jsRunner != nil {
|
||||||
out, err := d2sketch.Paths(sketchRunner, targetShape, s.GetSVGPathData())
|
out, err := d2sketch.Paths(jsRunner, targetShape, s.GetSVGPathData())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
@ -1846,7 +1847,7 @@ func appendOnTrigger(buf *bytes.Buffer, source string, triggers []string, newCon
|
||||||
var DEFAULT_DARK_THEME *int64 = nil // no theme selected
|
var DEFAULT_DARK_THEME *int64 = nil // no theme selected
|
||||||
|
|
||||||
func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
|
func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
|
||||||
var sketchRunner *d2sketch.Runner
|
var jsRunner jsrunner.JSRunner
|
||||||
pad := DEFAULT_PADDING
|
pad := DEFAULT_PADDING
|
||||||
themeID := d2themescatalog.NeutralDefault.ID
|
themeID := d2themescatalog.NeutralDefault.ID
|
||||||
darkThemeID := DEFAULT_DARK_THEME
|
darkThemeID := DEFAULT_DARK_THEME
|
||||||
|
|
@ -1856,8 +1857,8 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
|
||||||
pad = int(*opts.Pad)
|
pad = int(*opts.Pad)
|
||||||
}
|
}
|
||||||
if opts.Sketch != nil && *opts.Sketch {
|
if opts.Sketch != nil && *opts.Sketch {
|
||||||
var err error
|
jsRunner = jsrunner.NewJSRunner()
|
||||||
sketchRunner, err = d2sketch.InitSketchVM()
|
err := d2sketch.LoadJS(jsRunner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -1941,7 +1942,7 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
|
||||||
}
|
}
|
||||||
for _, obj := range allObjects {
|
for _, obj := range allObjects {
|
||||||
if c, is := obj.(d2target.Connection); is {
|
if c, is := obj.(d2target.Connection); is {
|
||||||
labelMask, err := drawConnection(buf, isolatedDiagramHash, c, markers, idToShape, sketchRunner, inlineTheme)
|
labelMask, err := drawConnection(buf, isolatedDiagramHash, c, markers, idToShape, jsRunner, inlineTheme)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -1949,7 +1950,7 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
|
||||||
labelMasks = append(labelMasks, labelMask)
|
labelMasks = append(labelMasks, labelMask)
|
||||||
}
|
}
|
||||||
} else if s, is := obj.(d2target.Shape); is {
|
} else if s, is := obj.(d2target.Shape); is {
|
||||||
labelMask, err := drawShape(buf, appendixItemBuf, diagramHash, s, sketchRunner, inlineTheme)
|
labelMask, err := drawShape(buf, appendixItemBuf, diagramHash, s, jsRunner, inlineTheme)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if labelMask != "" {
|
} else if labelMask != "" {
|
||||||
|
|
@ -2003,7 +2004,7 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
|
||||||
fmt.Fprintf(upperBuf, `<style type="text/css">%s</style>`, css)
|
fmt.Fprintf(upperBuf, `<style type="text/css">%s</style>`, css)
|
||||||
}
|
}
|
||||||
|
|
||||||
if sketchRunner != nil {
|
if jsRunner != nil {
|
||||||
d2sketch.DefineFillPatterns(upperBuf)
|
d2sketch.DefineFillPatterns(upperBuf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue