From 0955ef608de3b0b15ca7690e3ab1e4b0913f4ad1 Mon Sep 17 00:00:00 2001 From: melsonic Date: Sun, 9 Mar 2025 22:05:16 +0530 Subject: [PATCH 01/54] ci: add validate command --- d2cli/help.go | 2 ++ d2cli/main.go | 2 ++ d2cli/validate.go | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 d2cli/validate.go diff --git a/d2cli/help.go b/d2cli/help.go index eb80c85bf..6b95a2c33 100644 --- a/d2cli/help.go +++ b/d2cli/help.go @@ -23,6 +23,7 @@ Usage: %[1]s layout [name] %[1]s fmt file.d2 ... %[1]s play [--theme=0] [--sketch] file.d2 + %[1]s validate file.d2 ... %[1]s compiles and renders file.d2 to file.svg | file.png It defaults to file.svg if an output path is not provided. @@ -40,6 +41,7 @@ Subcommands: %[1]s themes - Lists available themes %[1]s fmt file.d2 ... - Format passed files %[1]s play file.d2 - Opens the file in playground, an online web viewer (https://play.d2lang.com) + %[1]s validate file.d2 ... - Validate input files See more docs and the source code at https://oss.terrastruct.com/d2. Hosted icons at https://icons.terrastruct.com. diff --git a/d2cli/main.go b/d2cli/main.go index dbf1ae2c4..3eb486d70 100644 --- a/d2cli/main.go +++ b/d2cli/main.go @@ -173,6 +173,8 @@ func Run(ctx context.Context, ms *xmain.State) (err error) { return fmtCmd(ctx, ms, *checkFlag) case "play": return playCmd(ctx, ms) + case "validate": + return validateCmd(ctx, ms) case "version": if len(ms.Opts.Flags.Args()) > 1 { return xmain.UsageErrorf("version subcommand accepts no arguments") diff --git a/d2cli/validate.go b/d2cli/validate.go new file mode 100644 index 000000000..29840ef5b --- /dev/null +++ b/d2cli/validate.go @@ -0,0 +1,35 @@ +package d2cli + +import ( + "context" + + "oss.terrastruct.com/d2/d2lib" + "oss.terrastruct.com/util-go/xdefer" + "oss.terrastruct.com/util-go/xmain" +) + +func validateCmd(ctx context.Context, ms *xmain.State) (err error) { + defer xdefer.Errorf(&err, "failed to validate") + + ms.Opts = xmain.NewOpts(ms.Env, ms.Opts.Flags.Args()[1:]) + if len(ms.Opts.Args) == 0 { + return xmain.UsageErrorf("validate must be passed at least one file to be validated") + } + + for _, inputPath := range ms.Opts.Args { + if inputPath != "-" { + inputPath = ms.AbsPath(inputPath) + } + + input, err := ms.ReadPath(inputPath) + if err != nil { + return err + } + + _, err = d2lib.Parse(ctx, string(input), nil) + if err != nil { + return err + } + } + return nil +} From 3727173f312e0642f6fcebb27121633afd414d13 Mon Sep 17 00:00:00 2001 From: melsonic Date: Sun, 9 Mar 2025 22:38:10 +0530 Subject: [PATCH 02/54] add changelog & man page changes --- ci/release/changelogs/next.md | 3 +++ ci/release/template/man/d2.1 | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index a29f10f45..48661ab23 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -24,6 +24,9 @@ - Support relative imports. Improve elk error handling: [#2382](https://github.com/terrastruct/d2/pull/2382) - Support fonts (`fontRegular`, `fontItalic`, `fontBold`, `fontSemiBold`): [#2384](https://github.com/terrastruct/d2/pull/2384) +- d2cli: + - Support `validate` command. [#2415](https://github.com/terrastruct/d2/pull/2415) + #### Bugfixes ⛑️ - Compiler: diff --git a/ci/release/template/man/d2.1 b/ci/release/template/man/d2.1 index 24ebdd7e1..eb888c57c 100644 --- a/ci/release/template/man/d2.1 +++ b/ci/release/template/man/d2.1 @@ -17,6 +17,8 @@ .Ar fmt Ar file.d2 ... .Nm d2 .Ar play Ar file.d2 +.Nm d2 +.Ar validate Ar file.d2 ... .Sh DESCRIPTION .Nm compiles and renders @@ -162,6 +164,8 @@ Lists available themes Format all passed files .It Ar play Ar file.d2 Opens the file in playground, an online web viewer (https://play.d2lang.com) +.It Ar validate Ar file.d2 ... +Validate all input files .El .Sh ENVIRONMENT VARIABLES Many flags can also be set with environment variables. From 20ecd634cc9aff57cd91b0b1ad6356692d8c4795 Mon Sep 17 00:00:00 2001 From: melsonic Date: Mon, 10 Mar 2025 22:52:51 +0530 Subject: [PATCH 03/54] support single input file --- ci/release/template/man/d2.1 | 6 +++--- d2cli/help.go | 4 ++-- d2cli/validate.go | 25 ++++++++++++------------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/ci/release/template/man/d2.1 b/ci/release/template/man/d2.1 index eb888c57c..08eb02c0e 100644 --- a/ci/release/template/man/d2.1 +++ b/ci/release/template/man/d2.1 @@ -18,7 +18,7 @@ .Nm d2 .Ar play Ar file.d2 .Nm d2 -.Ar validate Ar file.d2 ... +.Ar validate Ar file.d2 .Sh DESCRIPTION .Nm compiles and renders @@ -164,8 +164,8 @@ Lists available themes Format all passed files .It Ar play Ar file.d2 Opens the file in playground, an online web viewer (https://play.d2lang.com) -.It Ar validate Ar file.d2 ... -Validate all input files +.It Ar validate Ar file.d2 +Validate all input file .El .Sh ENVIRONMENT VARIABLES Many flags can also be set with environment variables. diff --git a/d2cli/help.go b/d2cli/help.go index 6b95a2c33..faa5ba6f8 100644 --- a/d2cli/help.go +++ b/d2cli/help.go @@ -23,7 +23,7 @@ Usage: %[1]s layout [name] %[1]s fmt file.d2 ... %[1]s play [--theme=0] [--sketch] file.d2 - %[1]s validate file.d2 ... + %[1]s validate file.d2 %[1]s compiles and renders file.d2 to file.svg | file.png It defaults to file.svg if an output path is not provided. @@ -41,7 +41,7 @@ Subcommands: %[1]s themes - Lists available themes %[1]s fmt file.d2 ... - Format passed files %[1]s play file.d2 - Opens the file in playground, an online web viewer (https://play.d2lang.com) - %[1]s validate file.d2 ... - Validate input files + %[1]s validate file.d2 - Validate input file See more docs and the source code at https://oss.terrastruct.com/d2. Hosted icons at https://icons.terrastruct.com. diff --git a/d2cli/validate.go b/d2cli/validate.go index 29840ef5b..b62aec2ed 100644 --- a/d2cli/validate.go +++ b/d2cli/validate.go @@ -13,23 +13,22 @@ func validateCmd(ctx context.Context, ms *xmain.State) (err error) { ms.Opts = xmain.NewOpts(ms.Env, ms.Opts.Flags.Args()[1:]) if len(ms.Opts.Args) == 0 { - return xmain.UsageErrorf("validate must be passed at least one file to be validated") + return xmain.UsageErrorf("validate must be passed an input file to be validated") } - for _, inputPath := range ms.Opts.Args { - if inputPath != "-" { - inputPath = ms.AbsPath(inputPath) - } + inputPath := ms.Opts.Args[0] + if inputPath != "-" { + inputPath = ms.AbsPath(inputPath) + } - input, err := ms.ReadPath(inputPath) - if err != nil { - return err - } + input, err := ms.ReadPath(inputPath) + if err != nil { + return err + } - _, err = d2lib.Parse(ctx, string(input), nil) - if err != nil { - return err - } + _, err = d2lib.Parse(ctx, string(input), nil) + if err != nil { + return err } return nil } From 61ba9132dd6c6aa0474d736c8c41039fd1a72c5e Mon Sep 17 00:00:00 2001 From: melsonic Date: Tue, 11 Mar 2025 00:48:43 +0530 Subject: [PATCH 04/54] updated text changes --- ci/release/template/man/d2.1 | 2 +- d2cli/help.go | 2 +- d2cli/validate.go | 11 +++++++++-- d2cli/watch.go | 1 + 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ci/release/template/man/d2.1 b/ci/release/template/man/d2.1 index 08eb02c0e..70269172b 100644 --- a/ci/release/template/man/d2.1 +++ b/ci/release/template/man/d2.1 @@ -165,7 +165,7 @@ Format all passed files .It Ar play Ar file.d2 Opens the file in playground, an online web viewer (https://play.d2lang.com) .It Ar validate Ar file.d2 -Validate all input file +Validates file.d2 .El .Sh ENVIRONMENT VARIABLES Many flags can also be set with environment variables. diff --git a/d2cli/help.go b/d2cli/help.go index faa5ba6f8..5b025b6bb 100644 --- a/d2cli/help.go +++ b/d2cli/help.go @@ -41,7 +41,7 @@ Subcommands: %[1]s themes - Lists available themes %[1]s fmt file.d2 ... - Format passed files %[1]s play file.d2 - Opens the file in playground, an online web viewer (https://play.d2lang.com) - %[1]s validate file.d2 - Validate input file + %[1]s validate file.d2 - Validates file.d2 See more docs and the source code at https://oss.terrastruct.com/d2. Hosted icons at https://icons.terrastruct.com. diff --git a/d2cli/validate.go b/d2cli/validate.go index b62aec2ed..ba118e0f9 100644 --- a/d2cli/validate.go +++ b/d2cli/validate.go @@ -2,6 +2,7 @@ package d2cli import ( "context" + "fmt" "oss.terrastruct.com/d2/d2lib" "oss.terrastruct.com/util-go/xdefer" @@ -9,11 +10,11 @@ import ( ) func validateCmd(ctx context.Context, ms *xmain.State) (err error) { - defer xdefer.Errorf(&err, "failed to validate") + defer xdefer.Errorf(&err, "") ms.Opts = xmain.NewOpts(ms.Env, ms.Opts.Flags.Args()[1:]) if len(ms.Opts.Args) == 0 { - return xmain.UsageErrorf("validate must be passed an input file to be validated") + return xmain.UsageErrorf("validate must be passed an input file") } inputPath := ms.Opts.Args[0] @@ -30,5 +31,11 @@ func validateCmd(ctx context.Context, ms *xmain.State) (err error) { if err != nil { return err } + + if inputPath == "-" { + inputPath = "Input" + } + + fmt.Printf("Success! [%s] is valid D2.\n", inputPath) return nil } diff --git a/d2cli/watch.go b/d2cli/watch.go index 6c240a711..458c7cd28 100644 --- a/d2cli/watch.go +++ b/d2cli/watch.go @@ -438,6 +438,7 @@ func (w *watcher) compileLoop(ctx context.Context) error { if len(svg) > 0 { err = fmt.Errorf("failed to fully %scompile (rendering partial svg): %w", recompiledPrefix, err) } else { + fmt.Println(recompiledPrefix) err = fmt.Errorf("failed to %scompile: %w", recompiledPrefix, err) } errs = err.Error() From 544bf5726595e387fcd5649452d6d3f601d47154 Mon Sep 17 00:00:00 2001 From: melsonic Date: Tue, 11 Mar 2025 00:49:16 +0530 Subject: [PATCH 05/54] added e2etests-cli tests --- e2etests-cli/main_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/e2etests-cli/main_test.go b/e2etests-cli/main_test.go index dbdcd2833..441fbd986 100644 --- a/e2etests-cli/main_test.go +++ b/e2etests-cli/main_test.go @@ -1346,6 +1346,22 @@ c assert.Success(t, err) }, }, + { + name: "validate-against-correct-d2", + run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) { + writeFile(t, dir, "correct.d2", `x -> y`) + err := runTestMainPersist(t, ctx, dir, env, "validate", "correct.d2") + assert.Success(t, err) + }, + }, + { + name: "validate-against-incorrect-d2", + run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) { + writeFile(t, dir, "incorrect.d2", `x > y`) + err := runTestMainPersist(t, ctx, dir, env, "validate", "incorrect.d2") + assert.Error(t, err) + }, + }, } ctx := context.Background() From 6253d5994e6e9a337f515892709ba3c5fb2b02c7 Mon Sep 17 00:00:00 2001 From: melsonic Date: Tue, 11 Mar 2025 23:56:27 +0530 Subject: [PATCH 06/54] a bit refactoring --- d2cli/validate.go | 2 +- d2cli/watch.go | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/d2cli/validate.go b/d2cli/validate.go index ba118e0f9..69bd6028e 100644 --- a/d2cli/validate.go +++ b/d2cli/validate.go @@ -14,7 +14,7 @@ func validateCmd(ctx context.Context, ms *xmain.State) (err error) { ms.Opts = xmain.NewOpts(ms.Env, ms.Opts.Flags.Args()[1:]) if len(ms.Opts.Args) == 0 { - return xmain.UsageErrorf("validate must be passed an input file") + return xmain.UsageErrorf("input argument required") } inputPath := ms.Opts.Args[0] diff --git a/d2cli/watch.go b/d2cli/watch.go index 458c7cd28..6c240a711 100644 --- a/d2cli/watch.go +++ b/d2cli/watch.go @@ -438,7 +438,6 @@ func (w *watcher) compileLoop(ctx context.Context) error { if len(svg) > 0 { err = fmt.Errorf("failed to fully %scompile (rendering partial svg): %w", recompiledPrefix, err) } else { - fmt.Println(recompiledPrefix) err = fmt.Errorf("failed to %scompile: %w", recompiledPrefix, err) } errs = err.Error() From 3e4397f6b685c6deffff31118660ee733c99b807 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Tue, 11 Mar 2025 15:30:05 -0600 Subject: [PATCH 07/54] d2svg: implement legend --- d2renderers/d2svg/d2svg.go | 340 ++ d2renderers/d2svg/d2svg.go-e | 2992 +++++++++++++++++ d2target/d2target.go | 10 + .../txtar/legend/dagre/board.exp.json | 725 ++++ .../txtar/legend/dagre/sketch.exp.svg | 106 + .../testdata/txtar/legend/elk/board.exp.json | 684 ++++ .../testdata/txtar/legend/elk/sketch.exp.svg | 106 + e2etests/txtar.txt | 42 + 8 files changed, 5005 insertions(+) create mode 100644 d2renderers/d2svg/d2svg.go-e create mode 100644 e2etests/testdata/txtar/legend/dagre/board.exp.json create mode 100644 e2etests/testdata/txtar/legend/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/txtar/legend/elk/board.exp.json create mode 100644 e2etests/testdata/txtar/legend/elk/sketch.exp.svg diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index 8c28b9e5e..1c16261c3 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -44,6 +44,13 @@ const ( DEFAULT_PADDING = 100 appendixIconRadius = 16 + + // Legend constants + LEGEND_PADDING = 20 + LEGEND_ITEM_SPACING = 15 + LEGEND_ICON_SIZE = 24 + LEGEND_FONT_SIZE = 14 + LEGEND_CORNER_PADDING = 10 ) var multipleOffset = geo.NewVector(d2target.MULTIPLE_OFFSET, -d2target.MULTIPLE_OFFSET) @@ -101,6 +108,262 @@ func dimensions(diagram *d2target.Diagram, pad int) (left, top, width, height in return left, top, width, height } +func renderLegend(buf *bytes.Buffer, diagram *d2target.Diagram, diagramHash string, theme *d2themes.Theme) error { + if diagram.Legend == nil || (len(diagram.Legend.Shapes) == 0 && len(diagram.Legend.Connections) == 0) { + return nil + } + + _, br := diagram.BoundingBox() + + ruler, err := textmeasure.NewRuler() + if err != nil { + return err + } + + totalHeight := LEGEND_PADDING + LEGEND_FONT_SIZE + LEGEND_ITEM_SPACING + maxLabelWidth := 0 + + itemCount := 0 + + for _, s := range diagram.Legend.Shapes { + if s.Label == "" { + continue + } + + mtext := &d2target.MText{ + Text: s.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + for _, c := range diagram.Legend.Connections { + if c.Label == "" { + continue + } + + mtext := &d2target.MText{ + Text: c.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + if itemCount > 0 { + totalHeight -= LEGEND_ITEM_SPACING / 2 + } + + if itemCount > 0 && len(diagram.Legend.Connections) > 0 { + totalHeight += LEGEND_PADDING * 1.5 + } else { + totalHeight += LEGEND_PADDING * 1.2 + } + + legendWidth := LEGEND_PADDING*2 + LEGEND_ICON_SIZE + LEGEND_PADDING + maxLabelWidth + legendX := br.X + LEGEND_CORNER_PADDING + tl, _ := diagram.BoundingBox() + legendY := br.Y - totalHeight + if legendY < tl.Y { + legendY = tl.Y + } + + shadowEl := d2themes.NewThemableElement("rect", theme) + shadowEl.Fill = "#F7F7FA" + shadowEl.Stroke = "#DEE1EB" + shadowEl.Style = "stroke-width: 1px; filter: drop-shadow(0px 2px 3px rgba(0, 0, 0, 0.1))" + shadowEl.X = float64(legendX) + shadowEl.Y = float64(legendY) + shadowEl.Width = float64(legendWidth) + shadowEl.Height = float64(totalHeight) + shadowEl.Rx = 4 + fmt.Fprint(buf, shadowEl.Render()) + + legendEl := d2themes.NewThemableElement("rect", theme) + legendEl.Fill = "#ffffff" + legendEl.Stroke = "#DEE1EB" + legendEl.Style = "stroke-width: 1px" + legendEl.X = float64(legendX) + legendEl.Y = float64(legendY) + legendEl.Width = float64(legendWidth) + legendEl.Height = float64(totalHeight) + legendEl.Rx = 4 + fmt.Fprint(buf, legendEl.Render()) + + fmt.Fprintf(buf, `Legend`, + legendX+LEGEND_PADDING, legendY+LEGEND_PADDING+LEGEND_FONT_SIZE, LEGEND_FONT_SIZE+2) + + currentY := legendY + LEGEND_PADDING*2 + LEGEND_FONT_SIZE + + shapeCount := 0 + for _, s := range diagram.Legend.Shapes { + if s.Label == "" { + continue + } + + iconX := legendX + LEGEND_PADDING + iconY := currentY + + shapeIcon, err := renderLegendShapeIcon(s, iconX, iconY, diagramHash, theme) + if err != nil { + return err + } + fmt.Fprint(buf, shapeIcon) + + mtext := &d2target.MText{ + Text: s.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + + rowHeight := go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + textY := currentY + rowHeight/2 + int(float64(dims.Height)*0.3) + + fmt.Fprintf(buf, `%s`, + iconX+LEGEND_ICON_SIZE+LEGEND_PADDING, textY, LEGEND_FONT_SIZE, + html.EscapeString(s.Label)) + + currentY += rowHeight + LEGEND_ITEM_SPACING + shapeCount++ + } + + if shapeCount > 0 && len(diagram.Legend.Connections) > 0 { + currentY += LEGEND_ITEM_SPACING / 2 + + separatorEl := d2themes.NewThemableElement("line", theme) + separatorEl.X1 = float64(legendX + LEGEND_PADDING) + separatorEl.Y1 = float64(currentY) + separatorEl.X2 = float64(legendX + legendWidth - LEGEND_PADDING) + separatorEl.Y2 = float64(currentY) + separatorEl.Stroke = "#DEE1EB" + separatorEl.StrokeDashArray = "2,2" + fmt.Fprint(buf, separatorEl.Render()) + + currentY += LEGEND_ITEM_SPACING + } + + for _, c := range diagram.Legend.Connections { + if c.Label == "" { + continue + } + + iconX := legendX + LEGEND_PADDING + iconY := currentY + LEGEND_ICON_SIZE/2 + + connIcon, err := renderLegendConnectionIcon(c, iconX, iconY, theme) + if err != nil { + return err + } + fmt.Fprint(buf, connIcon) + + mtext := &d2target.MText{ + Text: c.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + + rowHeight := go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + textY := currentY + rowHeight/2 + int(float64(dims.Height)*0.2) + + fmt.Fprintf(buf, `%s`, + iconX+LEGEND_ICON_SIZE+LEGEND_PADDING, textY, LEGEND_FONT_SIZE, + html.EscapeString(c.Label)) + + currentY += rowHeight + LEGEND_ITEM_SPACING + } + + if shapeCount > 0 && len(diagram.Legend.Connections) > 0 { + currentY += LEGEND_PADDING / 2 + } else { + currentY += LEGEND_PADDING / 4 + } + + return nil +} + +func renderLegendShapeIcon(s d2target.Shape, x, y int, diagramHash string, theme *d2themes.Theme) (string, error) { + iconShape := s + const sizeFactor = 5 + iconShape.Pos.X = 0 + iconShape.Pos.Y = 0 + iconShape.Width = LEGEND_ICON_SIZE * sizeFactor + iconShape.Height = LEGEND_ICON_SIZE * sizeFactor + iconShape.Label = "" + buf := &bytes.Buffer{} + appendixBuf := &bytes.Buffer{} + finalBuf := &bytes.Buffer{} + fmt.Fprintf(finalBuf, ``, + x, y, 1.0/sizeFactor) + _, err := drawShape(buf, appendixBuf, diagramHash, iconShape, nil, theme) + if err != nil { + return "", err + } + + fmt.Fprint(finalBuf, buf.String()) + + fmt.Fprint(finalBuf, ``) + + return finalBuf.String(), nil +} + +func renderLegendConnectionIcon(c d2target.Connection, x, y int, theme *d2themes.Theme) (string, error) { + finalBuf := &bytes.Buffer{} + + buf := &bytes.Buffer{} + + const sizeFactor = 2 + + legendConn := *d2target.BaseConnection() + + legendConn.ID = c.ID + legendConn.SrcArrow = c.SrcArrow + legendConn.DstArrow = c.DstArrow + legendConn.StrokeDash = c.StrokeDash + legendConn.StrokeWidth = c.StrokeWidth + legendConn.Stroke = c.Stroke + legendConn.Fill = c.Fill + legendConn.BorderRadius = c.BorderRadius + legendConn.Opacity = c.Opacity + legendConn.Animated = c.Animated + + startX := 0.0 + midY := 0.0 + width := float64(LEGEND_ICON_SIZE * sizeFactor) + + legendConn.Route = []*geo.Point{ + {X: startX, Y: midY}, + {X: startX + width, Y: midY}, + } + + legendHash := fmt.Sprintf("legend-%s", hash(fmt.Sprintf("%s-%d-%d", c.ID, x, y))) + + markers := make(map[string]struct{}) + idToShape := make(map[string]d2target.Shape) + + fmt.Fprintf(finalBuf, ``, + x, y, 1.0/sizeFactor) + + _, err := drawConnection(buf, legendHash, legendConn, markers, idToShape, nil, theme) + if err != nil { + return "", err + } + + fmt.Fprint(finalBuf, buf.String()) + + fmt.Fprint(finalBuf, ``) + + return finalBuf.String(), nil +} + func arrowheadMarkerID(diagramHash string, isTarget bool, connection d2target.Connection) string { var arrowhead d2target.Arrowhead if isTarget { @@ -2085,8 +2348,85 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) { // add all appendix items afterwards so they are always on top fmt.Fprint(buf, appendixItemBuf) + if diagram.Legend != nil && (len(diagram.Legend.Shapes) > 0 || len(diagram.Legend.Connections) > 0) { + legendBuf := &bytes.Buffer{} + err := renderLegend(legendBuf, diagram, diagramHash, inlineTheme) + if err != nil { + return nil, err + } + fmt.Fprint(buf, legendBuf) + } + // Note: we always want this since we reference it on connections even if there end up being no masked labels left, top, w, h := dimensions(diagram, pad) + + if diagram.Legend != nil && (len(diagram.Legend.Shapes) > 0 || len(diagram.Legend.Connections) > 0) { + tl, br := diagram.BoundingBox() + totalHeight := LEGEND_PADDING + LEGEND_FONT_SIZE + LEGEND_ITEM_SPACING + maxLabelWidth := 0 + itemCount := 0 + ruler, _ := textmeasure.NewRuler() + if ruler != nil { + for _, s := range diagram.Legend.Shapes { + if s.Label == "" { + continue + } + mtext := &d2target.MText{ + Text: s.Label, + FontSize: LEGEND_FONT_SIZE, + } + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + for _, c := range diagram.Legend.Connections { + if c.Label == "" { + continue + } + mtext := &d2target.MText{ + Text: c.Label, + FontSize: LEGEND_FONT_SIZE, + } + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + if itemCount > 0 { + totalHeight -= LEGEND_ITEM_SPACING / 2 + } + + totalHeight += LEGEND_PADDING + + if totalHeight > 0 && maxLabelWidth > 0 { + legendWidth := LEGEND_PADDING*2 + LEGEND_ICON_SIZE + LEGEND_PADDING + maxLabelWidth + + legendY := br.Y - totalHeight + if legendY < tl.Y { + legendY = tl.Y + } + + legendRight := br.X + LEGEND_CORNER_PADDING + legendWidth + if left+w < legendRight { + w = legendRight - left + pad/2 + } + + if legendY < top { + diffY := top - legendY + top -= diffY + h += diffY + } + + legendBottom := legendY + totalHeight + if top+h < legendBottom { + h = legendBottom - top + pad/2 + } + } + } + } fmt.Fprint(buf, strings.Join([]string{ fmt.Sprintf(``, isolatedDiagramHash, left, top, w, h, diff --git a/d2renderers/d2svg/d2svg.go-e b/d2renderers/d2svg/d2svg.go-e new file mode 100644 index 000000000..e71eb3f92 --- /dev/null +++ b/d2renderers/d2svg/d2svg.go-e @@ -0,0 +1,2992 @@ +// d2svg implements an SVG renderer for d2 diagrams. +// The input is d2exporter's output +package d2svg + +import ( + "bytes" + _ "embed" + "encoding/base64" + "errors" + "fmt" + "hash/fnv" + "html" + "io" + "sort" + "strings" + + "math" + + "github.com/alecthomas/chroma/v2" + "github.com/alecthomas/chroma/v2/formatters" + "github.com/alecthomas/chroma/v2/lexers" + "github.com/alecthomas/chroma/v2/styles" + + "oss.terrastruct.com/d2/d2ast" + "oss.terrastruct.com/d2/d2graph" + "oss.terrastruct.com/d2/d2renderers/d2fonts" + "oss.terrastruct.com/d2/d2renderers/d2latex" + "oss.terrastruct.com/d2/d2renderers/d2sketch" + "oss.terrastruct.com/d2/d2target" + "oss.terrastruct.com/d2/d2themes" + "oss.terrastruct.com/d2/d2themes/d2themescatalog" + "oss.terrastruct.com/d2/lib/color" + "oss.terrastruct.com/d2/lib/geo" + "oss.terrastruct.com/d2/lib/jsrunner" + "oss.terrastruct.com/d2/lib/label" + "oss.terrastruct.com/d2/lib/shape" + "oss.terrastruct.com/d2/lib/svg" + "oss.terrastruct.com/d2/lib/textmeasure" + "oss.terrastruct.com/d2/lib/version" + "oss.terrastruct.com/util-go/go2" +) + +const ( + DEFAULT_PADDING = 100 + + appendixIconRadius = 16 + + // Legend constants + LEGEND_PADDING = 20 + LEGEND_ITEM_SPACING = 15 + LEGEND_ICON_SIZE = 24 + LEGEND_FONT_SIZE = 14 + LEGEND_CORNER_PADDING = 10 +) + +var multipleOffset = geo.NewVector(d2target.MULTIPLE_OFFSET, -d2target.MULTIPLE_OFFSET) + +//go:embed tooltip.svg +var TooltipIcon string + +//go:embed link.svg +var LinkIcon string + +//go:embed style.css +var BaseStylesheet string + +//go:embed github-markdown.css +var MarkdownCSS string + +//go:embed dots.txt +var dots string + +//go:embed lines.txt +var lines string + +//go:embed grain.txt +var grain string + +//go:embed paper.txt +var paper string + +type RenderOpts struct { + Pad *int64 + Sketch *bool + Center *bool + ThemeID *int64 + DarkThemeID *int64 + ThemeOverrides *d2target.ThemeOverrides + DarkThemeOverrides *d2target.ThemeOverrides + Font string + // the svg will be scaled by this factor, if unset the svg will fit to screen + Scale *float64 + + // MasterID is passed when the diagram should use something other than its own hash for unique targeting + // Currently, that's when multi-boards are collapsed + MasterID string + NoXMLTag *bool + Salt *string +} + +func dimensions(diagram *d2target.Diagram, pad int) (left, top, width, height int) { + tl, br := diagram.BoundingBox() + left = tl.X - pad + top = tl.Y - pad + width = br.X - tl.X + pad*2 + height = br.Y - tl.Y + pad*2 + + return left, top, width, height +} + +// renderLegend renders the legend box in the bottom right of the diagram +func renderLegend(buf *bytes.Buffer, diagram *d2target.Diagram, diagramHash string, theme *d2themes.Theme) error { + if diagram.Legend == nil || (len(diagram.Legend.Shapes) == 0 && len(diagram.Legend.Connections) == 0) { + return nil + } + + _, br := diagram.BoundingBox() + + // Create a ruler to measure text + ruler, err := textmeasure.NewRuler() + if err != nil { + return err + } + + // Calculate total height of legend items + // Start with top padding and title height + totalHeight := LEGEND_PADDING + LEGEND_FONT_SIZE + LEGEND_ITEM_SPACING + maxLabelWidth := 0 + + // Track number of items for precise height calculation + itemCount := 0 + + // Measure text for each legend item to determine dimensions + for _, s := range diagram.Legend.Shapes { + if s.Label == "" { + continue + } + + mtext := &d2target.MText{ + Text: s.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + for _, c := range diagram.Legend.Connections { + if c.Label == "" { + continue + } + + mtext := &d2target.MText{ + Text: c.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + // If we have items, remove the extra spacing from the last item and add bottom padding + if itemCount > 0 { + totalHeight -= LEGEND_ITEM_SPACING / 2 // Remove some of the last spacing + } + + // Add bottom padding + totalHeight += LEGEND_PADDING + + // Calculate legend dimensions + legendWidth := LEGEND_PADDING*2 + LEGEND_ICON_SIZE + LEGEND_PADDING + maxLabelWidth + + // Position legend to the right of the diagram with padding + // Add extra padding to ensure it doesn't overlap with diagram elements + legendX := br.X + LEGEND_CORNER_PADDING + // Center vertically using the bounding box, but ensure it's not too close to the top + tl, _ := diagram.BoundingBox() + legendY := tl.Y + (br.Y-tl.Y-totalHeight)/2 + if legendY < tl.Y { + legendY = tl.Y + } + + // Draw legend background with subtle shadow for better visual separation + // Add shadow/outline effect first + shadowEl := d2themes.NewThemableElement("rect", theme) + shadowEl.Fill = "#F7F7FA" + shadowEl.Stroke = "#DEE1EB" + shadowEl.Style = "stroke-width: 1px; filter: drop-shadow(0px 2px 3px rgba(0, 0, 0, 0.1))" + shadowEl.X = float64(legendX) + shadowEl.Y = float64(legendY) + shadowEl.Width = float64(legendWidth) + shadowEl.Height = float64(totalHeight) + shadowEl.Rx = 4 + fmt.Fprint(buf, shadowEl.Render()) + + // Draw legend background + legendEl := d2themes.NewThemableElement("rect", theme) + legendEl.Fill = "#ffffff" + legendEl.Stroke = "#DEE1EB" + legendEl.Style = "stroke-width: 1px" + legendEl.X = float64(legendX) + legendEl.Y = float64(legendY) + legendEl.Width = float64(legendWidth) + legendEl.Height = float64(totalHeight) + legendEl.Rx = 4 + fmt.Fprint(buf, legendEl.Render()) + + // Draw legend title + fmt.Fprintf(buf, `Legend`, + legendX+LEGEND_PADDING, legendY+LEGEND_PADDING+LEGEND_FONT_SIZE, LEGEND_FONT_SIZE+2) + + // Current Y position for drawing items + currentY := legendY + LEGEND_PADDING*2 + LEGEND_FONT_SIZE + + // Draw legend shapes + for _, s := range diagram.Legend.Shapes { + if s.Label == "" { + continue + } + + iconX := legendX + LEGEND_PADDING + iconY := currentY + + // Draw shape as icon + shapeIcon, err := renderLegendShapeIcon(s, iconX, iconY, diagramHash, theme) + if err != nil { + return err + } + fmt.Fprint(buf, shapeIcon) + + // Draw label + mtext := &d2target.MText{ + Text: s.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + textY := currentY + dims.Height/2 + + fmt.Fprintf(buf, `%s`, + iconX+LEGEND_ICON_SIZE+LEGEND_PADDING, textY, LEGEND_FONT_SIZE, + html.EscapeString(s.Label)) + + currentY += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + } + + // Draw legend connections + for _, c := range diagram.Legend.Connections { + if c.Label == "" { + continue + } + + iconX := legendX + LEGEND_PADDING + iconY := currentY + LEGEND_ICON_SIZE/2 + + // Draw connection as line + connIcon, err := renderLegendConnectionIcon(c, iconX, iconY, theme) + if err != nil { + return err + } + fmt.Fprint(buf, connIcon) + + // Draw label + mtext := &d2target.MText{ + Text: c.Label, + FontSize: LEGEND_FONT_SIZE, + } + + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + textY := currentY + dims.Height/2 + + fmt.Fprintf(buf, `%s`, + iconX+LEGEND_ICON_SIZE+LEGEND_PADDING, textY, LEGEND_FONT_SIZE, + html.EscapeString(c.Label)) + + currentY += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + } + + return nil +} + +// renderLegendShapeIcon creates a small representation of a shape for the legend +// This reuses the existing shape drawing code +func renderLegendShapeIcon(s d2target.Shape, x, y int, diagramHash string, theme *d2themes.Theme) (string, error) { + // Create a miniature version of the shape + iconShape := s + + // Set the position and size for the legend icon + iconShape.X = x + iconShape.Y = y + iconShape.Width = LEGEND_ICON_SIZE + iconShape.Height = LEGEND_ICON_SIZE + + // Remove the label since we don't want it in the icon + iconShape.Label = "" + + // Create wrappers to capture the rendered SVG + buf := &bytes.Buffer{} + appendixBuf := &bytes.Buffer{} + + // Use the existing drawShape function to render the shape with its proper appearance + _, err := drawShape(buf, appendixBuf, diagramHash, iconShape, nil, theme) + if err != nil { + return "", err + } + + return buf.String(), nil +} + +// renderLegendConnectionIcon creates a small representation of a connection for the legend +func renderLegendConnectionIcon(c d2target.Connection, x, y int, theme *d2themes.Theme) (string, error) { + buf := &bytes.Buffer{} + + // Default stroke width and color + strokeWidth := 2.0 + + // Default color + strokeColor := "#000000" + if c.Stroke != "" { + strokeColor = c.Stroke + } else if theme != nil { + strokeColor = theme.Colors.B4 // Use a theme color for connections + } + + // Draw simple line to represent connection + startX := float64(x) + endX := float64(x + LEGEND_ICON_SIZE) + midY := float64(y) + + fmt.Fprintf(buf, ``, + startX, midY, endX, midY, strokeColor, strokeWidth) + + // Add arrowhead if needed - check if either has an arrowhead that's not "none" + if c.SrcArrow != "none" || c.DstArrow != "none" { + // Draw destination arrowhead (right side) + fmt.Fprintf(buf, ``, + endX-6, midY-3, endX, midY, endX-6, midY+3, strokeColor) + } + + return buf.String(), nil +} + +// renderSimplifiedShape creates a simplified version of a shape for the legend +func renderSimplifiedShape(buf *bytes.Buffer, s d2target.Shape, theme *d2themes.Theme) error { + // Get fill and stroke colors + fillColor := "#E8EAF1" // Default fill color + strokeColor := "#CED3E5" // Default stroke color + + if s.Fill != "" { + fillColor = s.Fill + } else if theme != nil { + fillColor = theme.Colors.B5 // Use a theme color for fills + } + + if s.Stroke != "" { + strokeColor = s.Stroke + } else if theme != nil { + strokeColor = theme.Colors.B4 // Use a theme color for strokes + } + + // Create a simplified shape representation based on shape type + switch s.Type { + case d2target.ShapeCircle: + // Circle + circleEl := d2themes.NewThemableElement("circle", theme) + circleEl.Fill = fillColor + circleEl.Stroke = strokeColor + circleEl.Style = "stroke-width: 1px" + circleEl.Cx = float64(LEGEND_ICON_SIZE) / 2 + circleEl.Cy = float64(LEGEND_ICON_SIZE) / 2 + circleEl.R = float64(LEGEND_ICON_SIZE)/2 - 2 + fmt.Fprint(buf, circleEl.Render()) + + case d2target.ShapeDiamond: + // Diamond shape using a simple polygon + size := float64(LEGEND_ICON_SIZE) + halfSize := size / 2 + + diamondEl := d2themes.NewThemableElement("polygon", theme) + diamondEl.Fill = fillColor + diamondEl.Stroke = strokeColor + diamondEl.Style = "stroke-width: 1px" + diamondEl.Points = fmt.Sprintf("%.1f,%.1f %.1f,%.1f %.1f,%.1f %.1f,%.1f", + halfSize, 2.0, // top + size-2.0, halfSize, // right + halfSize, size-2.0, // bottom + 2.0, halfSize) // left + fmt.Fprint(buf, diamondEl.Render()) + + case d2target.ShapeCylinder: + // Simplified cylinder + fmt.Fprintf(buf, ``) + + // Main rectangle part (body of cylinder) + rectEl := d2themes.NewThemableElement("rect", theme) + rectEl.Fill = fillColor + rectEl.Stroke = strokeColor + rectEl.Style = "stroke-width: 1px" + rectEl.X = 2 + rectEl.Y = 6 + rectEl.Width = float64(LEGEND_ICON_SIZE - 4) + rectEl.Height = float64(LEGEND_ICON_SIZE - 10) + fmt.Fprint(buf, rectEl.Render()) + + // Top ellipse + ellipseEl := d2themes.NewThemableElement("ellipse", theme) + ellipseEl.Fill = fillColor + ellipseEl.Stroke = strokeColor + ellipseEl.Style = "stroke-width: 1px" + ellipseEl.Cx = float64(LEGEND_ICON_SIZE) / 2 + ellipseEl.Cy = 6 + ellipseEl.Rx = float64(LEGEND_ICON_SIZE-4) / 2 + ellipseEl.Ry = 3 + fmt.Fprint(buf, ellipseEl.Render()) + + fmt.Fprintf(buf, ``) + + default: + // Default rectangle for all other shapes + rectEl := d2themes.NewThemableElement("rect", theme) + rectEl.Fill = fillColor + rectEl.Stroke = strokeColor + rectEl.Style = "stroke-width: 1px" + rectEl.X = 2 + rectEl.Y = 2 + rectEl.Width = float64(LEGEND_ICON_SIZE - 4) + rectEl.Height = float64(LEGEND_ICON_SIZE - 4) + + // Apply borderRadius appropriately + if s.Type != d2target.ShapeSquare && s.Type != d2target.ShapeRectangle { + rectEl.Rx = 4 + } + + fmt.Fprint(buf, rectEl.Render()) + } + + return nil +} + +func arrowheadMarkerID(diagramHash string, isTarget bool, connection d2target.Connection) string { + var arrowhead d2target.Arrowhead + if isTarget { + arrowhead = connection.DstArrow + } else { + arrowhead = connection.SrcArrow + } + + return fmt.Sprintf("mk-%s-%s", diagramHash, hash(fmt.Sprintf("%s,%t,%d,%s", + arrowhead, isTarget, connection.StrokeWidth, connection.Stroke, + ))) +} + +func arrowheadMarker(isTarget bool, id string, connection d2target.Connection, inlineTheme *d2themes.Theme) string { + arrowhead := connection.DstArrow + if !isTarget { + arrowhead = connection.SrcArrow + } + strokeWidth := float64(connection.StrokeWidth) + width, height := arrowhead.Dimensions(strokeWidth) + + var path string + switch arrowhead { + case d2target.ArrowArrowhead: + polygonEl := d2themes.NewThemableElement("polygon", inlineTheme) + polygonEl.Fill = connection.Stroke + polygonEl.ClassName = "connection" + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + 0., 0., + width, height/2, + 0., height, + width/4, height/2, + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + 0., height/2, + width, 0., + width*3/4, height/2, + width, height, + ) + } + path = polygonEl.Render() + case d2target.UnfilledTriangleArrowhead: + polygonEl := d2themes.NewThemableElement("polygon", inlineTheme) + polygonEl.Fill = d2target.BG_COLOR + polygonEl.Stroke = connection.Stroke + polygonEl.ClassName = "connection" + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + inset := strokeWidth / 2 + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f", + inset, inset, + width-inset, height/2.0, + inset, height-inset, + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f", + width-inset, inset, + inset, height/2.0, + width-inset, height-inset, + ) + } + path = polygonEl.Render() + + case d2target.TriangleArrowhead: + polygonEl := d2themes.NewThemableElement("polygon", inlineTheme) + polygonEl.Fill = connection.Stroke + polygonEl.ClassName = "connection" + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f", + 0., 0., + width, height/2.0, + 0., height, + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f", + width, 0., + 0., height/2.0, + width, height, + ) + } + path = polygonEl.Render() + case d2target.LineArrowhead: + polylineEl := d2themes.NewThemableElement("polyline", inlineTheme) + polylineEl.Fill = color.None + polylineEl.ClassName = "connection" + polylineEl.Stroke = connection.Stroke + polylineEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + polylineEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f", + strokeWidth/2, strokeWidth/2, + width-strokeWidth/2, height/2, + strokeWidth/2, height-strokeWidth/2, + ) + } else { + polylineEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f", + width-strokeWidth/2, strokeWidth/2, + strokeWidth/2, height/2, + width-strokeWidth/2, height-strokeWidth/2, + ) + } + path = polylineEl.Render() + case d2target.FilledDiamondArrowhead: + polygonEl := d2themes.NewThemableElement("polygon", inlineTheme) + polygonEl.ClassName = "connection" + polygonEl.Fill = connection.Stroke + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + 0., height/2.0, + width/2.0, 0., + width, height/2.0, + width/2.0, height, + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + 0., height/2.0, + width/2.0, 0., + width, height/2.0, + width/2.0, height, + ) + } + path = polygonEl.Render() + case d2target.DiamondArrowhead: + polygonEl := d2themes.NewThemableElement("polygon", inlineTheme) + polygonEl.ClassName = "connection" + polygonEl.Fill = d2target.BG_COLOR + polygonEl.Stroke = connection.Stroke + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + 0., height/2.0, + width/2, height/8, + width, height/2.0, + width/2.0, height*0.9, + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + width/8, height/2.0, + width*0.6, height/8, + width*1.1, height/2.0, + width*0.6, height*7/8, + ) + } + path = polygonEl.Render() + case d2target.FilledCircleArrowhead: + radius := width / 2 + + circleEl := d2themes.NewThemableElement("circle", inlineTheme) + circleEl.Cy = radius + circleEl.R = radius - strokeWidth/2 + circleEl.Fill = connection.Stroke + circleEl.ClassName = "connection" + circleEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + circleEl.Cx = radius + strokeWidth/2 + } else { + circleEl.Cx = radius - strokeWidth/2 + } + + path = circleEl.Render() + case d2target.CircleArrowhead: + radius := width / 2 + + circleEl := d2themes.NewThemableElement("circle", inlineTheme) + circleEl.Cy = radius + circleEl.R = radius - strokeWidth + circleEl.Fill = d2target.BG_COLOR + circleEl.Stroke = connection.Stroke + circleEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + circleEl.Cx = radius + strokeWidth/2 + } else { + circleEl.Cx = radius - strokeWidth/2 + } + + path = circleEl.Render() + case d2target.FilledBoxArrowhead: + polygonEl := d2themes.NewThemableElement("polygon", inlineTheme) + polygonEl.ClassName = "connection" + polygonEl.Fill = connection.Stroke + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + 0., 0., + 0., height, + width, height, + width, 0., + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + 0., 0., + 0., height, + width, height, + width, 0., + ) + } + + path = polygonEl.Render() + case d2target.BoxArrowhead: + polygonEl := d2themes.NewThemableElement("polygon", inlineTheme) + polygonEl.ClassName = "connection" + polygonEl.Fill = d2target.BG_COLOR + polygonEl.Stroke = connection.Stroke + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + polygonEl.Style = fmt.Sprintf("%sstroke-linejoin:miter;", polygonEl.Style) + + inset := strokeWidth / 2 + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + inset, inset, + inset, height-inset, + width-inset, height-inset, + width-inset, inset, + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f %f,%f", + inset, inset, + inset, height-inset, + width-inset, height-inset, + width-inset, inset, + ) + } + path = polygonEl.Render() + case d2target.CfOne, d2target.CfMany, d2target.CfOneRequired, d2target.CfManyRequired: + offset := 3.0 + float64(connection.StrokeWidth)*1.8 + + var modifierEl *d2themes.ThemableElement + if arrowhead == d2target.CfOneRequired || arrowhead == d2target.CfManyRequired { + modifierEl = d2themes.NewThemableElement("path", inlineTheme) + modifierEl.D = fmt.Sprintf("M%f,%f %f,%f", + offset, 0., + offset, height, + ) + modifierEl.Fill = d2target.BG_COLOR + modifierEl.Stroke = connection.Stroke + modifierEl.ClassName = "connection" + modifierEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + } else { + modifierEl = d2themes.NewThemableElement("circle", inlineTheme) + modifierEl.Cx = offset/2.0 + 2.0 + modifierEl.Cy = height / 2.0 + modifierEl.R = offset / 2.0 + modifierEl.Fill = d2target.BG_COLOR + modifierEl.Stroke = connection.Stroke + modifierEl.ClassName = "connection" + modifierEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + } + + childPathEl := d2themes.NewThemableElement("path", inlineTheme) + if arrowhead == d2target.CfMany || arrowhead == d2target.CfManyRequired { + childPathEl.D = fmt.Sprintf("M%f,%f %f,%f M%f,%f %f,%f M%f,%f %f,%f", + width-3.0, height/2.0, + width+offset, height/2.0, + offset+3.0, height/2.0, + width+offset, 0., + offset+3.0, height/2.0, + width+offset, height, + ) + } else { + childPathEl.D = fmt.Sprintf("M%f,%f %f,%f M%f,%f %f,%f", + width-3.0, height/2.0, + width+offset, height/2.0, + offset*2.0, 0., + offset*2.0, height, + ) + } + + gEl := d2themes.NewThemableElement("g", inlineTheme) + if !isTarget { + gEl.Transform = fmt.Sprintf("scale(-1) translate(-%f, -%f)", width, height) + } + gEl.Fill = d2target.BG_COLOR + gEl.Stroke = connection.Stroke + gEl.ClassName = "connection" + gEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + gEl.Content = fmt.Sprintf("%s%s", + modifierEl.Render(), childPathEl.Render(), + ) + path = gEl.Render() + default: + return "" + } + + var refX float64 + refY := height / 2 + switch arrowhead { + case d2target.DiamondArrowhead: + if isTarget { + refX = width - 0.6*strokeWidth + } else { + refX = width/8 + 0.6*strokeWidth + } + width *= 1.1 + default: + if isTarget { + refX = width - 1.5*strokeWidth + } else { + refX = 1.5 * strokeWidth + } + } + + return strings.Join([]string{ + fmt.Sprintf(``, + path, + "", + }, " ") +} + +// compute the (dx, dy) adjustment to apply to get the arrowhead-adjusted end point +func arrowheadAdjustment(start, end *geo.Point, arrowhead d2target.Arrowhead, edgeStrokeWidth, shapeStrokeWidth int) *geo.Point { + distance := (float64(edgeStrokeWidth) + float64(shapeStrokeWidth)) / 2.0 + if arrowhead != d2target.NoArrowhead { + distance += float64(edgeStrokeWidth) + } + + v := geo.NewVector(end.X-start.X, end.Y-start.Y) + return v.Unit().Multiply(-distance).ToPoint() +} + +func getArrowheadAdjustments(connection d2target.Connection, idToShape map[string]d2target.Shape) (srcAdj, dstAdj *geo.Point) { + route := connection.Route + srcShape := idToShape[connection.Src] + dstShape := idToShape[connection.Dst] + + sourceAdjustment := arrowheadAdjustment(route[1], route[0], connection.SrcArrow, connection.StrokeWidth, srcShape.StrokeWidth) + + targetAdjustment := arrowheadAdjustment(route[len(route)-2], route[len(route)-1], connection.DstArrow, connection.StrokeWidth, dstShape.StrokeWidth) + return sourceAdjustment, targetAdjustment +} + +// returns the path's d attribute for the given connection +func pathData(connection d2target.Connection, srcAdj, dstAdj *geo.Point) string { + var path []string + route := connection.Route + + path = append(path, fmt.Sprintf("M %f %f", + route[0].X+srcAdj.X, + route[0].Y+srcAdj.Y, + )) + + if connection.IsCurve { + i := 1 + for ; i < len(route)-3; i += 3 { + path = append(path, fmt.Sprintf("C %f %f %f %f %f %f", + route[i].X, route[i].Y, + route[i+1].X, route[i+1].Y, + route[i+2].X, route[i+2].Y, + )) + } + // final curve target adjustment + path = append(path, fmt.Sprintf("C %f %f %f %f %f %f", + route[i].X, route[i].Y, + route[i+1].X, route[i+1].Y, + route[i+2].X+dstAdj.X, + route[i+2].Y+dstAdj.Y, + )) + } else { + for i := 1; i < len(route)-1; i++ { + prevSource := route[i-1] + prevTarget := route[i] + currTarget := route[i+1] + prevVector := prevSource.VectorTo(prevTarget) + currVector := prevTarget.VectorTo(currTarget) + + dist := geo.EuclideanDistance(prevTarget.X, prevTarget.Y, currTarget.X, currTarget.Y) + + connectionBorderRadius := connection.BorderRadius + units := math.Min(connectionBorderRadius, dist/2) + + prevTranslations := prevVector.Unit().Multiply(units).ToPoint() + currTranslations := currVector.Unit().Multiply(units).ToPoint() + + path = append(path, fmt.Sprintf("L %f %f", + prevTarget.X-prevTranslations.X, + prevTarget.Y-prevTranslations.Y, + )) + + // If the segment length is too small, instead of drawing 2 arcs, just skip this segment and bezier curve to the next one + if units < connectionBorderRadius && i < len(route)-2 { + nextTarget := route[i+2] + nextVector := geo.NewVector(nextTarget.X-currTarget.X, nextTarget.Y-currTarget.Y) + i++ + nextTranslations := nextVector.Unit().Multiply(units).ToPoint() + + // These 2 bezier control points aren't just at the corner -- they are reflected at the corner, which causes the curve to be ~tangent to the corner, + // which matches how the two arcs look + path = append(path, fmt.Sprintf("C %f %f %f %f %f %f", + // Control point + prevTarget.X+prevTranslations.X, + prevTarget.Y+prevTranslations.Y, + // Control point + currTarget.X-nextTranslations.X, + currTarget.Y-nextTranslations.Y, + // Where curve ends + currTarget.X+nextTranslations.X, + currTarget.Y+nextTranslations.Y, + )) + } else { + path = append(path, fmt.Sprintf("S %f %f %f %f", + prevTarget.X, + prevTarget.Y, + prevTarget.X+currTranslations.X, + prevTarget.Y+currTranslations.Y, + )) + } + } + + lastPoint := route[len(route)-1] + path = append(path, fmt.Sprintf("L %f %f", + lastPoint.X+dstAdj.X, + lastPoint.Y+dstAdj.Y, + )) + } + + return strings.Join(path, " ") +} + +func makeLabelMask(labelTL *geo.Point, width, height int, opacity float64) string { + fill := "black" + if opacity != 1 { + fill = fmt.Sprintf("rgba(0,0,0,%.2f)", opacity) + } + return fmt.Sprintf(``, + labelTL.X, labelTL.Y, + width, + height, + fill, + ) +} + +func drawConnection(writer io.Writer, diagramHash string, connection d2target.Connection, markers map[string]struct{}, idToShape map[string]d2target.Shape, jsRunner jsrunner.JSRunner, inlineTheme *d2themes.Theme) (labelMask string, _ error) { + opacityStyle := "" + if connection.Opacity != 1.0 { + opacityStyle = fmt.Sprintf(" style='opacity:%f'", connection.Opacity) + } + + classes := []string{base64.URLEncoding.EncodeToString([]byte(svg.EscapeText(connection.ID)))} + classes = append(classes, connection.Classes...) + classStr := fmt.Sprintf(` class="%s"`, strings.Join(classes, " ")) + + fmt.Fprintf(writer, ``, classStr, opacityStyle) + var markerStart string + if connection.SrcArrow != d2target.NoArrowhead { + id := arrowheadMarkerID(diagramHash, false, connection) + if _, in := markers[id]; !in { + marker := arrowheadMarker(false, id, connection, inlineTheme) + if marker == "" { + panic(fmt.Sprintf("received empty arrow head marker for: %#v", connection)) + } + fmt.Fprint(writer, marker) + markers[id] = struct{}{} + } + markerStart = fmt.Sprintf(`marker-start="url(#%s)" `, id) + } + + var markerEnd string + if connection.DstArrow != d2target.NoArrowhead { + id := arrowheadMarkerID(diagramHash, true, connection) + if _, in := markers[id]; !in { + marker := arrowheadMarker(true, id, connection, inlineTheme) + if marker == "" { + panic(fmt.Sprintf("received empty arrow head marker for: %#v", connection)) + } + fmt.Fprint(writer, marker) + markers[id] = struct{}{} + } + markerEnd = fmt.Sprintf(`marker-end="url(#%s)" `, id) + } + + if connection.Icon != nil { + iconPos := connection.GetIconPosition() + if iconPos != nil { + fmt.Fprintf(writer, ``, + html.EscapeString(connection.Icon.String()), + iconPos.X, + iconPos.Y, + d2target.DEFAULT_ICON_SIZE, + d2target.DEFAULT_ICON_SIZE, + ) + } + } + + var labelTL *geo.Point + if connection.Label != "" { + labelTL = connection.GetLabelTopLeft() + labelTL.X = math.Round(labelTL.X) + labelTL.Y = math.Round(labelTL.Y) + + maskTL := labelTL.Copy() + width := connection.LabelWidth + height := connection.LabelHeight + + if connection.Icon != nil { + width += d2target.CONNECTION_ICON_LABEL_GAP + d2target.DEFAULT_ICON_SIZE + maskTL.X -= float64(d2target.CONNECTION_ICON_LABEL_GAP + d2target.DEFAULT_ICON_SIZE) + } + + if label.FromString(connection.LabelPosition).IsOnEdge() { + labelMask = makeLabelMask(maskTL, width, height, 1) + } else { + labelMask = makeLabelMask(maskTL, width, height, 0.75) + } + } else if connection.Icon != nil { + iconPos := connection.GetIconPosition() + if iconPos != nil { + maskTL := &geo.Point{ + X: iconPos.X, + Y: iconPos.Y, + } + if label.FromString(connection.IconPosition).IsOnEdge() { + labelMask = makeLabelMask(maskTL, d2target.DEFAULT_ICON_SIZE, d2target.DEFAULT_ICON_SIZE, 1) + } else { + labelMask = makeLabelMask(maskTL, d2target.DEFAULT_ICON_SIZE, d2target.DEFAULT_ICON_SIZE, 0.75) + } + } + } + + srcAdj, dstAdj := getArrowheadAdjustments(connection, idToShape) + path := pathData(connection, srcAdj, dstAdj) + mask := fmt.Sprintf(`mask="url(#%s)"`, diagramHash) + + if jsRunner != nil { + out, err := d2sketch.Connection(jsRunner, connection, path, mask) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + + // render sketch arrowheads separately + arrowPaths, err := d2sketch.Arrowheads(jsRunner, connection, srcAdj, dstAdj) + if err != nil { + return "", err + } + fmt.Fprint(writer, arrowPaths) + } else { + animatedClass := "" + if connection.Animated { + animatedClass = " animated-connection" + } + + // If connection is animated and bidirectional + if connection.Animated && ((connection.DstArrow == d2target.NoArrowhead && connection.SrcArrow == d2target.NoArrowhead) || (connection.DstArrow != d2target.NoArrowhead && connection.SrcArrow != d2target.NoArrowhead)) { + // There is no pure CSS way to animate bidirectional connections in two directions, so we split it up + path1, path2, err := svg.SplitPath(path, 0.5) + + if err != nil { + return "", err + } + + pathEl1 := d2themes.NewThemableElement("path", inlineTheme) + pathEl1.D = path1 + pathEl1.Fill = color.None + pathEl1.Stroke = connection.Stroke + pathEl1.ClassName = fmt.Sprintf("connection%s", animatedClass) + pathEl1.Style = connection.CSSStyle() + pathEl1.Style += "animation-direction: reverse;" + pathEl1.Attributes = fmt.Sprintf("%s%s", markerStart, mask) + fmt.Fprint(writer, pathEl1.Render()) + + pathEl2 := d2themes.NewThemableElement("path", inlineTheme) + pathEl2.D = path2 + pathEl2.Fill = color.None + pathEl2.Stroke = connection.Stroke + pathEl2.ClassName = fmt.Sprintf("connection%s", animatedClass) + pathEl2.Style = connection.CSSStyle() + pathEl2.Attributes = fmt.Sprintf("%s%s", markerEnd, mask) + fmt.Fprint(writer, pathEl2.Render()) + } else { + pathEl := d2themes.NewThemableElement("path", inlineTheme) + pathEl.D = path + pathEl.Fill = color.None + pathEl.Stroke = connection.Stroke + pathEl.ClassName = fmt.Sprintf("connection%s", animatedClass) + pathEl.Style = connection.CSSStyle() + pathEl.Attributes = fmt.Sprintf("%s%s%s", markerStart, markerEnd, mask) + fmt.Fprint(writer, pathEl.Render()) + } + } + + if connection.Label != "" { + fontClass := "text" + if connection.FontFamily == "mono" { + fontClass = "text-mono" + } + if connection.Bold { + fontClass += "-bold" + } else if connection.Italic { + fontClass += "-italic" + } + if connection.Underline { + fontClass += " text-underline" + } + if connection.Fill != color.Empty { + rectEl := d2themes.NewThemableElement("rect", inlineTheme) + rectEl.Rx = 10 + rectEl.X, rectEl.Y = labelTL.X-4, labelTL.Y-3 + rectEl.Width, rectEl.Height = float64(connection.LabelWidth)+8, float64(connection.LabelHeight)+6 + rectEl.Fill = connection.Fill + fmt.Fprint(writer, rectEl.Render()) + } + + textEl := d2themes.NewThemableElement("text", inlineTheme) + textEl.X = labelTL.X + float64(connection.LabelWidth)/2 + textEl.Y = labelTL.Y + float64(connection.FontSize) + textEl.ClassName = fontClass + textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "middle", connection.FontSize) + textEl.Content = RenderText(connection.Label, textEl.X, float64(connection.LabelHeight)) + + if connection.Link != "" { + textEl.ClassName += " text-underline text-link" + + fmt.Fprintf(writer, ``, svg.EscapeText(connection.Link)) + } else { + textEl.Fill = connection.GetFontColor() + } + + fmt.Fprint(writer, textEl.Render()) + + if connection.Link != "" { + fmt.Fprintf(writer, "") + } + } + + if connection.SrcLabel != nil && connection.SrcLabel.Label != "" { + fmt.Fprint(writer, renderArrowheadLabel(connection, connection.SrcLabel.Label, false, inlineTheme)) + } + if connection.DstLabel != nil && connection.DstLabel.Label != "" { + fmt.Fprint(writer, renderArrowheadLabel(connection, connection.DstLabel.Label, true, inlineTheme)) + } + fmt.Fprintf(writer, ``) + return +} + +func renderArrowheadLabel(connection d2target.Connection, text string, isDst bool, inlineTheme *d2themes.Theme) string { + var width, height float64 + if isDst { + width = float64(connection.DstLabel.LabelWidth) + height = float64(connection.DstLabel.LabelHeight) + } else { + width = float64(connection.SrcLabel.LabelWidth) + height = float64(connection.SrcLabel.LabelHeight) + } + + labelTL := connection.GetArrowheadLabelPosition(isDst) + + // svg text is positioned with the center of its baseline + baselineCenter := geo.Point{ + X: labelTL.X + width/2., + Y: labelTL.Y + float64(connection.FontSize), + } + + textEl := d2themes.NewThemableElement("text", inlineTheme) + textEl.X = baselineCenter.X + textEl.Y = baselineCenter.Y + textEl.Fill = d2target.FG_COLOR + if isDst { + if connection.DstLabel.Color != "" { + textEl.Fill = connection.DstLabel.Color + } + } else { + if connection.SrcLabel.Color != "" { + textEl.Fill = connection.SrcLabel.Color + } + } + textEl.ClassName = "text-italic" + textEl.Style = fmt.Sprintf("text-anchor:middle;font-size:%vpx", connection.FontSize) + textEl.Content = RenderText(text, textEl.X, height) + return textEl.Render() +} + +func renderOval(tl *geo.Point, width, height float64, fill, fillPattern, stroke, style string, inlineTheme *d2themes.Theme) string { + el := d2themes.NewThemableElement("ellipse", inlineTheme) + el.Rx = width / 2 + el.Ry = height / 2 + el.Cx = tl.X + el.Rx + el.Cy = tl.Y + el.Ry + el.Fill, el.Stroke = fill, stroke + el.FillPattern = fillPattern + el.ClassName = "shape" + el.Style = style + return el.Render() +} + +func renderDoubleOval(tl *geo.Point, width, height float64, fill, fillStroke, stroke, style string, inlineTheme *d2themes.Theme) string { + var innerTL *geo.Point = tl.AddVector(geo.NewVector(d2target.INNER_BORDER_OFFSET, d2target.INNER_BORDER_OFFSET)) + return renderOval(tl, width, height, fill, fillStroke, stroke, style, inlineTheme) + renderOval(innerTL, width-10, height-10, fill, "", stroke, style, inlineTheme) +} + +func defineGradients(writer io.Writer, cssGradient string) { + gradient, _ := color.ParseGradient(cssGradient) + fmt.Fprint(writer, fmt.Sprintf(`%s`, color.GradientToSVG(gradient))) +} + +func defineShadowFilter(writer io.Writer) { + fmt.Fprint(writer, ` + + + + + + + +`) +} + +func render3DRect(diagramHash string, targetShape d2target.Shape, inlineTheme *d2themes.Theme) string { + moveTo := func(p d2target.Point) string { + return fmt.Sprintf("M%d,%d", p.X+targetShape.Pos.X, p.Y+targetShape.Pos.Y) + } + lineTo := func(p d2target.Point) string { + return fmt.Sprintf("L%d,%d", p.X+targetShape.Pos.X, p.Y+targetShape.Pos.Y) + } + + // draw border all in one path to prevent overlapping sections + var borderSegments []string + borderSegments = append(borderSegments, + moveTo(d2target.Point{X: 0, Y: 0}), + ) + for _, v := range []d2target.Point{ + {X: d2target.THREE_DEE_OFFSET, Y: -d2target.THREE_DEE_OFFSET}, + {X: targetShape.Width + d2target.THREE_DEE_OFFSET, Y: -d2target.THREE_DEE_OFFSET}, + {X: targetShape.Width + d2target.THREE_DEE_OFFSET, Y: targetShape.Height - d2target.THREE_DEE_OFFSET}, + {X: targetShape.Width, Y: targetShape.Height}, + {X: 0, Y: targetShape.Height}, + {X: 0, Y: 0}, + {X: targetShape.Width, Y: 0}, + {X: targetShape.Width, Y: targetShape.Height}, + } { + borderSegments = append(borderSegments, lineTo(v)) + } + // move to top right to draw last segment without overlapping + borderSegments = append(borderSegments, + moveTo(d2target.Point{X: targetShape.Width, Y: 0}), + ) + borderSegments = append(borderSegments, + lineTo(d2target.Point{X: targetShape.Width + d2target.THREE_DEE_OFFSET, Y: -d2target.THREE_DEE_OFFSET}), + ) + border := d2themes.NewThemableElement("path", inlineTheme) + border.D = strings.Join(borderSegments, " ") + border.Fill = color.None + _, borderStroke := d2themes.ShapeTheme(targetShape) + border.Stroke = borderStroke + borderStyle := targetShape.CSSStyle() + border.Style = borderStyle + renderedBorder := border.Render() + + // create mask from border stroke, to cut away from the shape fills + maskID := fmt.Sprintf("border-mask-%v-%v", diagramHash, svg.EscapeText(targetShape.ID)) + borderMask := strings.Join([]string{ + fmt.Sprintf(``, + maskID, targetShape.Pos.X, targetShape.Pos.Y-d2target.THREE_DEE_OFFSET, targetShape.Width+d2target.THREE_DEE_OFFSET, targetShape.Height+d2target.THREE_DEE_OFFSET, + ), + fmt.Sprintf(``, + targetShape.Pos.X, targetShape.Pos.Y-d2target.THREE_DEE_OFFSET, targetShape.Width+d2target.THREE_DEE_OFFSET, targetShape.Height+d2target.THREE_DEE_OFFSET, + ), + fmt.Sprintf(``, + strings.Join(borderSegments, ""), borderStyle), + }, "\n") + + // render the main rectangle without stroke and the border mask + mainShape := d2themes.NewThemableElement("rect", inlineTheme) + mainShape.X = float64(targetShape.Pos.X) + mainShape.Y = float64(targetShape.Pos.Y) + mainShape.Width = float64(targetShape.Width) + mainShape.Height = float64(targetShape.Height) + mainShape.SetMaskUrl(maskID) + mainShapeFill, _ := d2themes.ShapeTheme(targetShape) + mainShape.Fill = mainShapeFill + mainShape.FillPattern = targetShape.FillPattern + mainShape.Stroke = color.None + mainShape.Style = targetShape.CSSStyle() + mainShapeRendered := mainShape.Render() + + // render the side shapes in the darkened color without stroke and the border mask + var sidePoints []string + for _, v := range []d2target.Point{ + {X: 0, Y: 0}, + {X: d2target.THREE_DEE_OFFSET, Y: -d2target.THREE_DEE_OFFSET}, + {X: targetShape.Width + d2target.THREE_DEE_OFFSET, Y: -d2target.THREE_DEE_OFFSET}, + {X: targetShape.Width + d2target.THREE_DEE_OFFSET, Y: targetShape.Height - d2target.THREE_DEE_OFFSET}, + {X: targetShape.Width, Y: targetShape.Height}, + {X: targetShape.Width, Y: 0}, + } { + sidePoints = append(sidePoints, + fmt.Sprintf("%d,%d", v.X+targetShape.Pos.X, v.Y+targetShape.Pos.Y), + ) + } + darkerColor, err := color.Darken(targetShape.Fill) + if err != nil { + darkerColor = targetShape.Fill + } + sideShape := d2themes.NewThemableElement("polygon", inlineTheme) + sideShape.Fill = darkerColor + sideShape.Points = strings.Join(sidePoints, " ") + sideShape.SetMaskUrl(maskID) + sideShape.Style = targetShape.CSSStyle() + renderedSides := sideShape.Render() + + return borderMask + mainShapeRendered + renderedSides + renderedBorder +} + +func render3DHexagon(diagramHash string, targetShape d2target.Shape, inlineTheme *d2themes.Theme) string { + moveTo := func(p d2target.Point) string { + return fmt.Sprintf("M%d,%d", p.X+targetShape.Pos.X, p.Y+targetShape.Pos.Y) + } + lineTo := func(p d2target.Point) string { + return fmt.Sprintf("L%d,%d", p.X+targetShape.Pos.X, p.Y+targetShape.Pos.Y) + } + scale := func(n int, f float64) int { + return int(float64(n) * f) + } + halfYFactor := 43.6 / 87.3 + + // draw border all in one path to prevent overlapping sections + var borderSegments []string + // start from the top-left + borderSegments = append(borderSegments, + moveTo(d2target.Point{X: scale(targetShape.Width, 0.25), Y: 0}), + ) + Y_OFFSET := d2target.THREE_DEE_OFFSET / 2 + // The following iterates through the sidepoints in clockwise order from top-left, then the main points in clockwise order from bottom-right + for _, v := range []d2target.Point{ + {X: scale(targetShape.Width, 0.25) + d2target.THREE_DEE_OFFSET, Y: -Y_OFFSET}, + {X: scale(targetShape.Width, 0.75) + d2target.THREE_DEE_OFFSET, Y: -Y_OFFSET}, + {X: targetShape.Width + d2target.THREE_DEE_OFFSET, Y: scale(targetShape.Height, halfYFactor) - Y_OFFSET}, + {X: scale(targetShape.Width, 0.75) + d2target.THREE_DEE_OFFSET, Y: targetShape.Height - Y_OFFSET}, + {X: scale(targetShape.Width, 0.75), Y: targetShape.Height}, + {X: scale(targetShape.Width, 0.25), Y: targetShape.Height}, + {X: 0, Y: scale(targetShape.Height, halfYFactor)}, + {X: scale(targetShape.Width, 0.25), Y: 0}, + {X: scale(targetShape.Width, 0.75), Y: 0}, + {X: targetShape.Width, Y: scale(targetShape.Height, halfYFactor)}, + {X: scale(targetShape.Width, 0.75), Y: targetShape.Height}, + } { + borderSegments = append(borderSegments, lineTo(v)) + } + for _, v := range []d2target.Point{ + {X: scale(targetShape.Width, 0.75), Y: 0}, + {X: targetShape.Width, Y: scale(targetShape.Height, halfYFactor)}, + {X: scale(targetShape.Width, 0.75), Y: targetShape.Height}, + } { + borderSegments = append(borderSegments, moveTo(v)) + borderSegments = append(borderSegments, lineTo( + d2target.Point{X: v.X + d2target.THREE_DEE_OFFSET, Y: v.Y - Y_OFFSET}, + )) + } + border := d2themes.NewThemableElement("path", inlineTheme) + border.D = strings.Join(borderSegments, " ") + border.Fill = color.None + _, borderStroke := d2themes.ShapeTheme(targetShape) + border.Stroke = borderStroke + borderStyle := targetShape.CSSStyle() + border.Style = borderStyle + renderedBorder := border.Render() + + var mainPoints []string + for _, v := range []d2target.Point{ + {X: scale(targetShape.Width, 0.25), Y: 0}, + {X: scale(targetShape.Width, 0.75), Y: 0}, + {X: targetShape.Width, Y: scale(targetShape.Height, halfYFactor)}, + {X: scale(targetShape.Width, 0.75), Y: targetShape.Height}, + {X: scale(targetShape.Width, 0.25), Y: targetShape.Height}, + {X: 0, Y: scale(targetShape.Height, halfYFactor)}, + } { + mainPoints = append(mainPoints, + fmt.Sprintf("%d,%d", v.X+targetShape.Pos.X, v.Y+targetShape.Pos.Y), + ) + } + + mainPointsPoly := strings.Join(mainPoints, " ") + // create mask from border stroke, to cut away from the shape fills + maskID := fmt.Sprintf("border-mask-%v-%v", diagramHash, svg.EscapeText(targetShape.ID)) + borderMask := strings.Join([]string{ + fmt.Sprintf(``, + maskID, targetShape.Pos.X, targetShape.Pos.Y-d2target.THREE_DEE_OFFSET, targetShape.Width+d2target.THREE_DEE_OFFSET, targetShape.Height+d2target.THREE_DEE_OFFSET, + ), + fmt.Sprintf(``, + targetShape.Pos.X, targetShape.Pos.Y-d2target.THREE_DEE_OFFSET, targetShape.Width+d2target.THREE_DEE_OFFSET, targetShape.Height+d2target.THREE_DEE_OFFSET, + ), + fmt.Sprintf(``, + strings.Join(borderSegments, ""), borderStyle), + }, "\n") + // render the main hexagon without stroke and the border mask + mainShape := d2themes.NewThemableElement("polygon", inlineTheme) + mainShape.X = float64(targetShape.Pos.X) + mainShape.Y = float64(targetShape.Pos.Y) + mainShape.Points = mainPointsPoly + mainShape.SetMaskUrl(maskID) + mainShapeFill, _ := d2themes.ShapeTheme(targetShape) + mainShape.FillPattern = targetShape.FillPattern + mainShape.Fill = mainShapeFill + mainShape.Stroke = color.None + mainShape.Style = targetShape.CSSStyle() + mainShapeRendered := mainShape.Render() + + // render the side shapes in the darkened color without stroke and the border mask + var sidePoints []string + for _, v := range []d2target.Point{ + {X: scale(targetShape.Width, 0.25) + d2target.THREE_DEE_OFFSET, Y: -Y_OFFSET}, + {X: scale(targetShape.Width, 0.75) + d2target.THREE_DEE_OFFSET, Y: -Y_OFFSET}, + {X: targetShape.Width + d2target.THREE_DEE_OFFSET, Y: scale(targetShape.Height, halfYFactor) - Y_OFFSET}, + {X: scale(targetShape.Width, 0.75) + d2target.THREE_DEE_OFFSET, Y: targetShape.Height - Y_OFFSET}, + {X: scale(targetShape.Width, 0.75), Y: targetShape.Height}, + {X: targetShape.Width, Y: scale(targetShape.Height, halfYFactor)}, + {X: scale(targetShape.Width, 0.75), Y: 0}, + {X: scale(targetShape.Width, 0.25), Y: 0}, + } { + sidePoints = append(sidePoints, + fmt.Sprintf("%d,%d", v.X+targetShape.Pos.X, v.Y+targetShape.Pos.Y), + ) + } + // TODO make darker color part of the theme? or just keep this bypass + darkerColor, err := color.Darken(targetShape.Fill) + if err != nil { + darkerColor = targetShape.Fill + } + sideShape := d2themes.NewThemableElement("polygon", inlineTheme) + sideShape.Fill = darkerColor + sideShape.Points = strings.Join(sidePoints, " ") + sideShape.SetMaskUrl(maskID) + sideShape.Style = targetShape.CSSStyle() + renderedSides := sideShape.Render() + + return borderMask + mainShapeRendered + renderedSides + renderedBorder +} + +func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape d2target.Shape, jsRunner jsrunner.JSRunner, inlineTheme *d2themes.Theme) (labelMask string, err error) { + closingTag := "" + if targetShape.Link != "" { + + fmt.Fprintf(writer, ``, svg.EscapeText(targetShape.Link)) + closingTag += "" + } + // Opacity is a unique style, it applies to everything for a shape + opacityStyle := "" + if targetShape.Opacity != 1.0 { + opacityStyle = fmt.Sprintf(" style='opacity:%f'", targetShape.Opacity) + } + + // this clipPath must be defined outside `g` element + if targetShape.BorderRadius != 0 && (targetShape.Type == d2target.ShapeClass || targetShape.Type == d2target.ShapeSQLTable) { + fmt.Fprint(writer, clipPathForBorderRadius(diagramHash, targetShape)) + } + classes := []string{base64.URLEncoding.EncodeToString([]byte(svg.EscapeText(targetShape.ID)))} + if targetShape.Animated { + classes = append(classes, "animated-shape") + } + classes = append(classes, targetShape.Classes...) + classStr := fmt.Sprintf(` class="%s"`, strings.Join(classes, " ")) + fmt.Fprintf(writer, ``, classStr, opacityStyle) + tl := geo.NewPoint(float64(targetShape.Pos.X), float64(targetShape.Pos.Y)) + width := float64(targetShape.Width) + height := float64(targetShape.Height) + fill, stroke := d2themes.ShapeTheme(targetShape) + style := targetShape.CSSStyle() + shapeType := d2target.DSL_SHAPE_TO_SHAPE_TYPE[targetShape.Type] + + s := shape.NewShape(shapeType, geo.NewBox(tl, width, height)) + if shapeType == shape.CLOUD_TYPE && targetShape.ContentAspectRatio != nil { + s.SetInnerBoxAspectRatio(*targetShape.ContentAspectRatio) + } + + var shadowAttr string + if targetShape.Shadow { + switch targetShape.Type { + case d2target.ShapeText, + d2target.ShapeCode, + d2target.ShapeClass, + d2target.ShapeSQLTable: + default: + shadowAttr = `filter="url(#shadow-filter)" ` + } + } + + var blendModeClass string + if targetShape.Blend { + blendModeClass = " blend" + } + + fmt.Fprintf(writer, ``, blendModeClass, shadowAttr) + + var multipleTL *geo.Point + if targetShape.Multiple { + multipleTL = tl.AddVector(multipleOffset) + } + + switch targetShape.Type { + case d2target.ShapeClass: + if jsRunner != nil { + out, err := d2sketch.Class(jsRunner, targetShape) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + drawClass(writer, diagramHash, targetShape, inlineTheme) + } + addAppendixItems(appendixWriter, diagramHash, targetShape, s) + fmt.Fprint(writer, ``) + fmt.Fprint(writer, closingTag) + return labelMask, nil + case d2target.ShapeSQLTable: + if jsRunner != nil { + out, err := d2sketch.Table(jsRunner, targetShape) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + drawTable(writer, diagramHash, targetShape, inlineTheme) + } + addAppendixItems(appendixWriter, diagramHash, targetShape, s) + fmt.Fprint(writer, ``) + fmt.Fprint(writer, closingTag) + return labelMask, nil + case d2target.ShapeOval: + if targetShape.DoubleBorder { + if targetShape.Multiple { + fmt.Fprint(writer, renderDoubleOval(multipleTL, width, height, fill, "", stroke, style, inlineTheme)) + } + if jsRunner != nil { + out, err := d2sketch.DoubleOval(jsRunner, targetShape) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + fmt.Fprint(writer, renderDoubleOval(tl, width, height, fill, targetShape.FillPattern, stroke, style, inlineTheme)) + } + } else { + if targetShape.Multiple { + fmt.Fprint(writer, renderOval(multipleTL, width, height, fill, "", stroke, style, inlineTheme)) + } + if jsRunner != nil { + out, err := d2sketch.Oval(jsRunner, targetShape) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + fmt.Fprint(writer, renderOval(tl, width, height, fill, targetShape.FillPattern, stroke, style, inlineTheme)) + } + } + + case d2target.ShapeImage: + el := d2themes.NewThemableElement("image", inlineTheme) + el.X = float64(targetShape.Pos.X) + el.Y = float64(targetShape.Pos.Y) + el.Width = float64(targetShape.Width) + el.Height = float64(targetShape.Height) + el.Href = html.EscapeString(targetShape.Icon.String()) + el.Fill = fill + el.Stroke = stroke + el.Style = style + fmt.Fprint(writer, el.Render()) + + // TODO should standardize "" to rectangle + case d2target.ShapeRectangle, d2target.ShapeSequenceDiagram, d2target.ShapeHierarchy, "": + borderRadius := math.MaxFloat64 + if targetShape.BorderRadius != 0 { + borderRadius = float64(targetShape.BorderRadius) + } + if targetShape.ThreeDee { + fmt.Fprint(writer, render3DRect(diagramHash, targetShape, inlineTheme)) + } else { + if !targetShape.DoubleBorder { + if targetShape.Multiple { + el := d2themes.NewThemableElement("rect", inlineTheme) + el.X = float64(targetShape.Pos.X + 10) + el.Y = float64(targetShape.Pos.Y - 10) + el.Width = float64(targetShape.Width) + el.Height = float64(targetShape.Height) + el.Fill = fill + el.Stroke = stroke + el.Style = style + el.Rx = borderRadius + fmt.Fprint(writer, el.Render()) + } + if jsRunner != nil { + out, err := d2sketch.Rect(jsRunner, targetShape) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + el := d2themes.NewThemableElement("rect", inlineTheme) + el.X = float64(targetShape.Pos.X) + el.Y = float64(targetShape.Pos.Y) + el.Width = float64(targetShape.Width) + el.Height = float64(targetShape.Height) + el.Fill = fill + el.FillPattern = targetShape.FillPattern + el.Stroke = stroke + el.Style = style + el.Rx = borderRadius + fmt.Fprint(writer, el.Render()) + } + } else { + if targetShape.Multiple { + el := d2themes.NewThemableElement("rect", inlineTheme) + el.X = float64(targetShape.Pos.X + 10) + el.Y = float64(targetShape.Pos.Y - 10) + el.Width = float64(targetShape.Width) + el.Height = float64(targetShape.Height) + el.Fill = fill + el.FillPattern = targetShape.FillPattern + el.Stroke = stroke + el.Style = style + el.Rx = borderRadius + fmt.Fprint(writer, el.Render()) + + el = d2themes.NewThemableElement("rect", inlineTheme) + el.X = float64(targetShape.Pos.X + 10 + d2target.INNER_BORDER_OFFSET) + el.Y = float64(targetShape.Pos.Y - 10 + d2target.INNER_BORDER_OFFSET) + el.Width = float64(targetShape.Width - 2*d2target.INNER_BORDER_OFFSET) + el.Height = float64(targetShape.Height - 2*d2target.INNER_BORDER_OFFSET) + el.Fill = fill + el.Stroke = stroke + el.Style = style + el.Rx = borderRadius + fmt.Fprint(writer, el.Render()) + } + if jsRunner != nil { + out, err := d2sketch.DoubleRect(jsRunner, targetShape) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + el := d2themes.NewThemableElement("rect", inlineTheme) + el.X = float64(targetShape.Pos.X) + el.Y = float64(targetShape.Pos.Y) + el.Width = float64(targetShape.Width) + el.Height = float64(targetShape.Height) + el.Fill = fill + el.FillPattern = targetShape.FillPattern + el.Stroke = stroke + el.Style = style + el.Rx = borderRadius + fmt.Fprint(writer, el.Render()) + + el = d2themes.NewThemableElement("rect", inlineTheme) + el.X = float64(targetShape.Pos.X + d2target.INNER_BORDER_OFFSET) + el.Y = float64(targetShape.Pos.Y + d2target.INNER_BORDER_OFFSET) + el.Width = float64(targetShape.Width - 2*d2target.INNER_BORDER_OFFSET) + el.Height = float64(targetShape.Height - 2*d2target.INNER_BORDER_OFFSET) + el.Fill = "transparent" + el.Stroke = stroke + el.Style = style + el.Rx = borderRadius + fmt.Fprint(writer, el.Render()) + } + } + } + case d2target.ShapeHexagon: + if targetShape.ThreeDee { + fmt.Fprint(writer, render3DHexagon(diagramHash, targetShape, inlineTheme)) + } else { + if targetShape.Multiple { + multiplePathData := shape.NewShape(shapeType, geo.NewBox(multipleTL, width, height)).GetSVGPathData() + el := d2themes.NewThemableElement("path", inlineTheme) + el.Fill = fill + el.Stroke = stroke + el.Style = style + for _, pathData := range multiplePathData { + el.D = pathData + fmt.Fprint(writer, el.Render()) + } + } + + if jsRunner != nil { + out, err := d2sketch.Paths(jsRunner, targetShape, s.GetSVGPathData()) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + el := d2themes.NewThemableElement("path", inlineTheme) + el.Fill = fill + el.FillPattern = targetShape.FillPattern + el.Stroke = stroke + el.Style = style + for _, pathData := range s.GetSVGPathData() { + el.D = pathData + fmt.Fprint(writer, el.Render()) + } + } + } + case d2target.ShapeText, d2target.ShapeCode: + default: + if targetShape.Multiple { + multiplePathData := shape.NewShape(shapeType, geo.NewBox(multipleTL, width, height)).GetSVGPathData() + el := d2themes.NewThemableElement("path", inlineTheme) + el.Fill = fill + el.Stroke = stroke + el.Style = style + for _, pathData := range multiplePathData { + el.D = pathData + fmt.Fprint(writer, el.Render()) + } + } + + if jsRunner != nil { + out, err := d2sketch.Paths(jsRunner, targetShape, s.GetSVGPathData()) + if err != nil { + return "", err + } + fmt.Fprint(writer, out) + } else { + el := d2themes.NewThemableElement("path", inlineTheme) + el.Fill = fill + el.FillPattern = targetShape.FillPattern + el.Stroke = stroke + el.Style = style + for _, pathData := range s.GetSVGPathData() { + el.D = pathData + fmt.Fprint(writer, el.Render()) + } + } + } + + // // to examine shape's innerBox + // innerBox := s.GetInnerBox() + // el := d2themes.NewThemableElement("rect", inlineTheme) + // el.X = float64(innerBox.TopLeft.X) + // el.Y = float64(innerBox.TopLeft.Y) + // el.Width = float64(innerBox.Width) + // el.Height = float64(innerBox.Height) + // el.Style = "fill:rgba(255,0,0,0.5);" + // fmt.Fprint(writer, el.Render()) + + // Closes the class=shape + fmt.Fprint(writer, ``) + + if targetShape.Icon != nil && targetShape.Type != d2target.ShapeImage && targetShape.Opacity != 0 { + iconPosition := label.FromString(targetShape.IconPosition) + var box *geo.Box + if iconPosition.IsOutside() { + box = s.GetBox() + } else { + box = s.GetInnerBox() + } + iconSize := d2target.GetIconSize(box, targetShape.IconPosition) + + tl := iconPosition.GetPointOnBox(box, label.PADDING, float64(iconSize), float64(iconSize)) + + fmt.Fprintf(writer, ``, + html.EscapeString(targetShape.Icon.String()), + tl.X, + tl.Y, + iconSize, + iconSize, + ) + } + + if targetShape.Label != "" && targetShape.Opacity != 0 { + labelPosition := label.FromString(targetShape.LabelPosition) + var box *geo.Box + if labelPosition.IsOutside() { + box = s.GetBox().Copy() + // if it is 3d/multiple, place label using box around those + if targetShape.ThreeDee { + offsetY := d2target.THREE_DEE_OFFSET + if targetShape.Type == d2target.ShapeHexagon { + offsetY /= 2 + } + box.TopLeft.Y -= float64(offsetY) + box.Height += float64(offsetY) + box.Width += d2target.THREE_DEE_OFFSET + } else if targetShape.Multiple { + box.TopLeft.Y -= d2target.MULTIPLE_OFFSET + box.Height += d2target.MULTIPLE_OFFSET + box.Width += d2target.MULTIPLE_OFFSET + } + } else { + box = s.GetInnerBox() + } + labelTL := labelPosition.GetPointOnBox(box, label.PADDING, + float64(targetShape.LabelWidth), + float64(targetShape.LabelHeight), + ) + labelMask = makeLabelMask(labelTL, targetShape.LabelWidth, targetShape.LabelHeight, 0.75) + + fontClass := "text" + if targetShape.FontFamily == "mono" { + fontClass = "text-mono" + } + if targetShape.Bold { + fontClass += "-bold" + } else if targetShape.Italic { + fontClass += "-italic" + } + if targetShape.Underline { + fontClass += " text-underline" + } + + if targetShape.Language == "latex" { + render, err := d2latex.Render(targetShape.Label) + if err != nil { + return labelMask, err + } + gEl := d2themes.NewThemableElement("g", inlineTheme) + + labelPosition := label.FromString(targetShape.LabelPosition) + if labelPosition == label.Unset { + labelPosition = label.InsideMiddleCenter + } + var box *geo.Box + if labelPosition.IsOutside() { + box = s.GetBox() + } else { + box = s.GetInnerBox() + } + labelTL := labelPosition.GetPointOnBox(box, label.PADDING, + float64(targetShape.LabelWidth), + float64(targetShape.LabelHeight), + ) + gEl.SetTranslate(labelTL.X, labelTL.Y) + + gEl.Color = targetShape.Stroke + gEl.Content = render + fmt.Fprint(writer, gEl.Render()) + } else if targetShape.Language == "markdown" { + render, err := textmeasure.RenderMarkdown(targetShape.Label) + if err != nil { + return labelMask, err + } + + labelPosition := label.FromString(targetShape.LabelPosition) + if labelPosition == label.Unset { + labelPosition = label.InsideMiddleCenter + } + var box *geo.Box + if labelPosition.IsOutside() { + box = s.GetBox() + } else { + box = s.GetInnerBox() + } + labelTL := labelPosition.GetPointOnBox(box, label.PADDING, + float64(targetShape.LabelWidth), + float64(targetShape.LabelHeight), + ) + + fmt.Fprintf(writer, ``, + labelTL.X, labelTL.Y, targetShape.LabelWidth, targetShape.LabelHeight, + ) + + // we need the self closing form in this svg/xhtml context + render = strings.ReplaceAll(render, "
", "
") + + mdEl := d2themes.NewThemableElement("div", inlineTheme) + mdEl.ClassName = "md" + mdEl.Content = render + + // We have to set with styles since within foreignObject, we're in html + // land and not SVG attributes + var styles []string + if targetShape.FontSize != textmeasure.MarkdownFontSize { + styles = append(styles, fmt.Sprintf("font-size:%vpx", targetShape.FontSize)) + } + if targetShape.Fill != "" && targetShape.Fill != "transparent" { + styles = append(styles, fmt.Sprintf(`background-color:%s`, targetShape.Fill)) + } + if !color.IsThemeColor(targetShape.Color) { + styles = append(styles, fmt.Sprintf(`color:%s`, targetShape.Color)) + } else { + styles = append(styles, fmt.Sprintf(`color:%s`, d2themes.ResolveThemeColor(*inlineTheme, targetShape.Color))) + } + + mdEl.Style = strings.Join(styles, ";") + + fmt.Fprint(writer, mdEl.Render()) + fmt.Fprint(writer, `
`) + } else if targetShape.Language != "" { + lexer := lexers.Get(targetShape.Language) + if lexer == nil { + lexer = lexers.Fallback + } + for _, isLight := range []bool{true, false} { + theme := "github" + if !isLight { + theme = "catppuccin-mocha" + } + style := styles.Get(theme) + if style == nil { + return labelMask, errors.New(`code snippet style "github" not found`) + } + formatter := formatters.Get("svg") + if formatter == nil { + return labelMask, errors.New(`code snippet formatter "svg" not found`) + } + iterator, err := lexer.Tokenise(nil, targetShape.Label) + if err != nil { + return labelMask, err + } + + svgStyles := styleToSVG(style) + class := "light-code" + if !isLight { + class = "dark-code" + } + var fontSize string + if targetShape.FontSize != d2fonts.FONT_SIZE_M { + fontSize = fmt.Sprintf(` style="font-size:%v"`, targetShape.FontSize) + } + fmt.Fprintf(writer, ``, + box.TopLeft.X, box.TopLeft.Y, class, fontSize, + ) + rectEl := d2themes.NewThemableElement("rect", inlineTheme) + rectEl.Width = float64(targetShape.Width) + rectEl.Height = float64(targetShape.Height) + rectEl.Stroke = targetShape.Stroke + rectEl.ClassName = "shape" + rectEl.Style = fmt.Sprintf(`fill:%s;stroke-width:%d;`, + style.Get(chroma.Background).Background.String(), + targetShape.StrokeWidth, + ) + fmt.Fprint(writer, rectEl.Render()) + // Padding = 0.5em + padding := float64(targetShape.FontSize) / 2. + fmt.Fprintf(writer, ``, padding, padding) + + lineHeight := textmeasure.CODE_LINE_HEIGHT + for index, tokens := range chroma.SplitTokensIntoLines(iterator.Tokens()) { + fmt.Fprintf(writer, "", 1+float64(index)*lineHeight) + for _, token := range tokens { + text := svgEscaper.Replace(token.String()) + attr := styleAttr(svgStyles, token.Type) + if attr != "" { + text = fmt.Sprintf("%s", attr, text) + } + fmt.Fprint(writer, text) + } + fmt.Fprint(writer, "") + } + fmt.Fprint(writer, "") + } + } else { + if targetShape.LabelFill != "" { + rectEl := d2themes.NewThemableElement("rect", inlineTheme) + rectEl.X = labelTL.X + rectEl.Y = labelTL.Y + rectEl.Width = float64(targetShape.LabelWidth) + rectEl.Height = float64(targetShape.LabelHeight) + rectEl.Fill = targetShape.LabelFill + fmt.Fprint(writer, rectEl.Render()) + } + textEl := d2themes.NewThemableElement("text", inlineTheme) + textEl.X = labelTL.X + float64(targetShape.LabelWidth)/2 + // text is vertically positioned at its baseline which is at labelTL+FontSize + textEl.Y = labelTL.Y + float64(targetShape.FontSize) + textEl.Fill = targetShape.GetFontColor() + textEl.ClassName = fontClass + textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "middle", targetShape.FontSize) + textEl.Content = RenderText(targetShape.Label, textEl.X, float64(targetShape.LabelHeight)) + fmt.Fprint(writer, textEl.Render()) + if targetShape.Blend { + labelMask = makeLabelMask(labelTL, targetShape.LabelWidth, targetShape.LabelHeight-d2graph.INNER_LABEL_PADDING, 1) + } + } + } + if targetShape.Tooltip != "" { + fmt.Fprintf(writer, `%s`, + svg.EscapeText(targetShape.Tooltip), + ) + } + addAppendixItems(appendixWriter, diagramHash, targetShape, s) + + fmt.Fprint(writer, closingTag) + return labelMask, nil +} + +func addAppendixItems(writer io.Writer, diagramHash string, targetShape d2target.Shape, s shape.Shape) { + var p1, p2 *geo.Point + if targetShape.Tooltip != "" || targetShape.Link != "" { + bothIcons := targetShape.Tooltip != "" && targetShape.Link != "" + corner := geo.NewPoint(float64(targetShape.Pos.X+targetShape.Width), float64(targetShape.Pos.Y)) + center := geo.NewPoint( + float64(targetShape.Pos.X)+float64(targetShape.Width)/2., + float64(targetShape.Pos.Y)+float64(targetShape.Height)/2., + ) + offset := geo.Vector{-2 * appendixIconRadius, 0} + var leftOnShape bool + switch s.GetType() { + case shape.STEP_TYPE, shape.HEXAGON_TYPE, shape.QUEUE_TYPE, shape.PAGE_TYPE: + // trace straight left for these + center.Y = float64(targetShape.Pos.Y) + case shape.PACKAGE_TYPE: + // trace straight down + center.X = float64(targetShape.Pos.X + targetShape.Width) + case shape.CIRCLE_TYPE, shape.OVAL_TYPE, shape.DIAMOND_TYPE, + shape.PERSON_TYPE, shape.CLOUD_TYPE, shape.CYLINDER_TYPE: + if bothIcons { + leftOnShape = true + corner = corner.AddVector(offset) + } + } + v1 := center.VectorTo(corner) + p1 = shape.TraceToShapeBorder(s, corner, corner.AddVector(v1)) + if bothIcons { + if leftOnShape { + // these shapes should have p1 on shape border + p2 = p1.AddVector(offset.Reverse()) + p1, p2 = p2, p1 + } else { + p2 = p1.AddVector(offset) + } + } + } + + if targetShape.Tooltip != "" { + x := int(math.Ceil(p1.X)) + y := int(math.Ceil(p1.Y)) + + fmt.Fprintf(writer, `%s%s`, + x-appendixIconRadius, + y-appendixIconRadius, + svg.EscapeText(targetShape.Tooltip), + fmt.Sprintf(TooltipIcon, diagramHash, svg.SVGID(targetShape.ID)), + ) + } + if targetShape.Link != "" { + if p2 == nil { + p2 = p1 + } + x := int(math.Ceil(p2.X)) + y := int(math.Ceil(p2.Y)) + fmt.Fprintf(writer, `%s`, + x-appendixIconRadius, + y-appendixIconRadius, + fmt.Sprintf(LinkIcon, diagramHash, svg.SVGID(targetShape.ID)), + ) + } +} + +func RenderText(text string, x, height float64) string { + if !strings.Contains(text, "\n") { + return svg.EscapeText(text) + } + rendered := []string{} + lines := strings.Split(text, "\n") + for i, line := range lines { + dy := height / float64(len(lines)) + if i == 0 { + dy = 0 + } + escaped := svg.EscapeText(line) + if escaped == "" { + // if there are multiple newlines in a row we still need text for the tspan to render + escaped = " " + } + rendered = append(rendered, fmt.Sprintf(`%s`, x, dy, escaped)) + } + return strings.Join(rendered, "") +} + +func EmbedFonts(buf *bytes.Buffer, diagramHash, source string, fontFamily *d2fonts.FontFamily, corpus string) { + fmt.Fprint(buf, ``) +} + +func appendOnTrigger(buf *bytes.Buffer, source string, triggers []string, newContent string) { + for _, trigger := range triggers { + if strings.Contains(source, trigger) { + fmt.Fprint(buf, newContent) + break + } + } +} + +var DEFAULT_DARK_THEME *int64 = nil // no theme selected + +func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) { + var jsRunner jsrunner.JSRunner + pad := DEFAULT_PADDING + themeID := d2themescatalog.NeutralDefault.ID + darkThemeID := DEFAULT_DARK_THEME + var scale *float64 + if opts != nil { + if opts.Pad != nil { + pad = int(*opts.Pad) + } + if opts.Sketch != nil && *opts.Sketch { + jsRunner = jsrunner.NewJSRunner() + err := d2sketch.LoadJS(jsRunner) + if err != nil { + return nil, err + } + } + if opts.ThemeID != nil { + themeID = *opts.ThemeID + } + darkThemeID = opts.DarkThemeID + scale = opts.Scale + } else { + opts = &RenderOpts{} + } + + buf := &bytes.Buffer{} + + // only define shadow filter if a shape uses it + for _, s := range diagram.Shapes { + if s.Shadow { + defineShadowFilter(buf) + break + } + } + + if color.IsGradient(diagram.Root.Fill) { + defineGradients(buf, diagram.Root.Fill) + } + if color.IsGradient(diagram.Root.Stroke) { + defineGradients(buf, diagram.Root.Stroke) + } + for _, s := range diagram.Shapes { + if color.IsGradient(s.Fill) { + defineGradients(buf, s.Fill) + } + if color.IsGradient(s.Stroke) { + defineGradients(buf, s.Stroke) + } + if color.IsGradient(s.Color) { + defineGradients(buf, s.Color) + } + } + for _, c := range diagram.Connections { + if color.IsGradient(c.Stroke) { + defineGradients(buf, c.Stroke) + } + if color.IsGradient(c.Fill) { + defineGradients(buf, c.Fill) + } + } + + // Apply hash on IDs for targeting, to be specific for this diagram + diagramHash, err := diagram.HashID(opts.Salt) + if err != nil { + return nil, err + } + // Some targeting is still per-board, like masks for connections + isolatedDiagramHash := diagramHash + if opts != nil && opts.MasterID != "" { + diagramHash = opts.MasterID + } + + // SVG has no notion of z-index. The z-index is effectively the order it's drawn. + // So draw from the least nested to most nested + idToShape := make(map[string]d2target.Shape) + allObjects := make([]DiagramObject, 0, len(diagram.Shapes)+len(diagram.Connections)) + for _, s := range diagram.Shapes { + idToShape[s.ID] = s + allObjects = append(allObjects, s) + } + for _, c := range diagram.Connections { + allObjects = append(allObjects, c) + } + + sortObjects(allObjects) + + appendixItemBuf := &bytes.Buffer{} + + var labelMasks []string + markers := map[string]struct{}{} + var inlineTheme *d2themes.Theme + // We only want to inline when no dark theme is specified, otherwise the inline style will override the CSS + if darkThemeID == nil { + inlineTheme = go2.Pointer(d2themescatalog.Find(themeID)) + inlineTheme.ApplyOverrides(opts.ThemeOverrides) + } + for _, obj := range allObjects { + if c, is := obj.(d2target.Connection); is { + labelMask, err := drawConnection(buf, isolatedDiagramHash, c, markers, idToShape, jsRunner, inlineTheme) + if err != nil { + return nil, err + } + if labelMask != "" { + labelMasks = append(labelMasks, labelMask) + } + } else if s, is := obj.(d2target.Shape); is { + labelMask, err := drawShape(buf, appendixItemBuf, diagramHash, s, jsRunner, inlineTheme) + if err != nil { + return nil, err + } else if labelMask != "" { + labelMasks = append(labelMasks, labelMask) + } + } else { + return nil, fmt.Errorf("unknown object of type %T", obj) + } + } + // add all appendix items afterwards so they are always on top + fmt.Fprint(buf, appendixItemBuf) + + // Render legend if present + if diagram.Legend != nil && (len(diagram.Legend.Shapes) > 0 || len(diagram.Legend.Connections) > 0) { + legendBuf := &bytes.Buffer{} + err := renderLegend(legendBuf, diagram, diagramHash, inlineTheme) + if err != nil { + return nil, err + } + fmt.Fprint(buf, legendBuf) + } + + // Note: we always want this since we reference it on connections even if there end up being no masked labels + left, top, w, h := dimensions(diagram, pad) + + // Adjust the width and height if the legend is present to ensure it's fully visible + if diagram.Legend != nil && (len(diagram.Legend.Shapes) > 0 || len(diagram.Legend.Connections) > 0) { + // Calculate dimensions needed for legend + tl, br := diagram.BoundingBox() + // Start with top padding and title height + totalHeight := LEGEND_PADDING + LEGEND_FONT_SIZE + LEGEND_ITEM_SPACING + maxLabelWidth := 0 + itemCount := 0 + ruler, _ := textmeasure.NewRuler() + if ruler != nil { + // Calculate height and width of legend + for _, s := range diagram.Legend.Shapes { + if s.Label == "" { + continue + } + mtext := &d2target.MText{ + Text: s.Label, + FontSize: LEGEND_FONT_SIZE, + } + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + for _, c := range diagram.Legend.Connections { + if c.Label == "" { + continue + } + mtext := &d2target.MText{ + Text: c.Label, + FontSize: LEGEND_FONT_SIZE, + } + dims := d2graph.GetTextDimensions(nil, ruler, mtext, nil) + maxLabelWidth = go2.IntMax(maxLabelWidth, dims.Width) + totalHeight += go2.IntMax(dims.Height, LEGEND_ICON_SIZE) + LEGEND_ITEM_SPACING + itemCount++ + } + + // If we have items, remove the extra spacing from the last item and add bottom padding + if itemCount > 0 { + totalHeight -= LEGEND_ITEM_SPACING / 2 // Remove some of the last spacing + } + + // Add bottom padding + totalHeight += LEGEND_PADDING + + if totalHeight > 0 && maxLabelWidth > 0 { + legendWidth := LEGEND_PADDING*2 + LEGEND_ICON_SIZE + LEGEND_PADDING + maxLabelWidth + + // Calculate legend vertical position (centered) + legendY := tl.Y + (br.Y-tl.Y-totalHeight)/2 + if legendY < tl.Y { + legendY = tl.Y + } + + // Expand width to include legend to the right + legendRight := br.X + LEGEND_CORNER_PADDING + legendWidth + if left+w < legendRight { + w = legendRight - left + pad/2 + } + + // Make sure the top of the legend is visible + if legendY < top { + diffY := top - legendY + top -= diffY + h += diffY + } + + // Make sure the bottom of the legend is visible + legendBottom := legendY + totalHeight + if top+h < legendBottom { + h = legendBottom - top + pad/2 + } + } + } + } + fmt.Fprint(buf, strings.Join([]string{ + fmt.Sprintf(``, + isolatedDiagramHash, left, top, w, h, + ), + fmt.Sprintf(``, + left, top, w, h, + ), + strings.Join(labelMasks, "\n"), + ``, + }, "\n")) + + // generate style elements that will be appended to the SVG tag + upperBuf := &bytes.Buffer{} + if opts.MasterID == "" { + EmbedFonts(upperBuf, diagramHash, buf.String(), diagram.FontFamily, diagram.GetCorpus()) // EmbedFonts *must* run before `d2sketch.DefineFillPatterns`, but after all elements are appended to `buf` + themeStylesheet, err := ThemeCSS(diagramHash, &themeID, darkThemeID, opts.ThemeOverrides, opts.DarkThemeOverrides) + if err != nil { + return nil, err + } + fmt.Fprintf(upperBuf, ``, BaseStylesheet, themeStylesheet) + + hasMarkdown := false + for _, s := range diagram.Shapes { + if s.Language == "markdown" { + hasMarkdown = true + break + } + } + if hasMarkdown { + css := MarkdownCSS + css = strings.ReplaceAll(css, ".md", fmt.Sprintf(".%s .md", diagramHash)) + css = strings.ReplaceAll(css, "font-italic", fmt.Sprintf("%s-font-italic", diagramHash)) + css = strings.ReplaceAll(css, "font-bold", fmt.Sprintf("%s-font-bold", diagramHash)) + css = strings.ReplaceAll(css, "font-mono", fmt.Sprintf("%s-font-mono", diagramHash)) + css = strings.ReplaceAll(css, "font-regular", fmt.Sprintf("%s-font-regular", diagramHash)) + css = strings.ReplaceAll(css, "font-semibold", fmt.Sprintf("%s-font-semibold", diagramHash)) + fmt.Fprintf(upperBuf, ``, css) + } + + if jsRunner != nil { + d2sketch.DefineFillPatterns(upperBuf, diagramHash) + } + } + + // This shift is for background el to envelop the diagram + left -= int(math.Ceil(float64(diagram.Root.StrokeWidth) / 2.)) + top -= int(math.Ceil(float64(diagram.Root.StrokeWidth) / 2.)) + w += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.) * 2.) + h += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.) * 2.) + backgroundEl := d2themes.NewThemableElement("rect", inlineTheme) + // We don't want to change the document viewbox, only the background el + backgroundEl.X = float64(left) + backgroundEl.Y = float64(top) + backgroundEl.Width = float64(w) + backgroundEl.Height = float64(h) + backgroundEl.Fill = diagram.Root.Fill + backgroundEl.Stroke = diagram.Root.Stroke + backgroundEl.FillPattern = diagram.Root.FillPattern + backgroundEl.Rx = float64(diagram.Root.BorderRadius) + if diagram.Root.StrokeDash != 0 { + dashSize, gapSize := svg.GetStrokeDashAttributes(float64(diagram.Root.StrokeWidth), diagram.Root.StrokeDash) + backgroundEl.StrokeDashArray = fmt.Sprintf("%f, %f", dashSize, gapSize) + } + backgroundEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, diagram.Root.StrokeWidth) + + // This shift is for viewbox to envelop the background el + left -= int(math.Ceil(float64(diagram.Root.StrokeWidth) / 2.)) + top -= int(math.Ceil(float64(diagram.Root.StrokeWidth) / 2.)) + w += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.) * 2.) + h += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.) * 2.) + + doubleBorderElStr := "" + if diagram.Root.DoubleBorder { + offset := d2target.INNER_BORDER_OFFSET + + left -= int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.)) + offset + top -= int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.)) + offset + w += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.)*2.) + 2*offset + h += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.)*2.) + 2*offset + + backgroundEl2 := backgroundEl.Copy() + // No need to double-paint + backgroundEl.Fill = "transparent" + + backgroundEl2.X = float64(left) + backgroundEl2.Y = float64(top) + backgroundEl2.Width = float64(w) + backgroundEl2.Height = float64(h) + doubleBorderElStr = backgroundEl2.Render() + + left -= int(math.Ceil(float64(diagram.Root.StrokeWidth) / 2.)) + top -= int(math.Ceil(float64(diagram.Root.StrokeWidth) / 2.)) + w += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.) * 2.) + h += int(math.Ceil(float64(diagram.Root.StrokeWidth)/2.) * 2.) + } + + bufStr := buf.String() + patternDefs := "" + for _, pattern := range d2ast.FillPatterns { + if strings.Contains(bufStr, fmt.Sprintf("%s-overlay", pattern)) || diagram.Root.FillPattern == pattern { + if patternDefs == "" { + fmt.Fprint(upperBuf, ``) + fmt.Fprint(upperBuf, "") + fmt.Fprint(upperBuf, patternDefs) + fmt.Fprint(upperBuf, "") + } + + var dimensions string + if scale != nil { + dimensions = fmt.Sprintf(` width="%d" height="%d"`, + int(math.Ceil((*scale)*float64(w))), + int(math.Ceil((*scale)*float64(h))), + ) + } + + alignment := "xMinYMin" + if opts.Center != nil && *opts.Center { + alignment = "xMidYMid" + } + fitToScreenWrapperOpening := "" + xmlTag := "" + fitToScreenWrapperClosing := "" + idAttr := "" + tag := "g" + // Many things change when this is rendering for animation + if opts.MasterID == "" { + fitToScreenWrapperOpening = fmt.Sprintf(``, + version.Version, + alignment, + w, h, + dimensions, + ) + if opts.NoXMLTag == nil || !*opts.NoXMLTag { + xmlTag = `` + } + fitToScreenWrapperClosing = "" + idAttr = `d2-svg` + tag = "svg" + } + + // TODO minify + docRendered := fmt.Sprintf(`%s%s<%s class="%s" width="%d" height="%d" viewBox="%d %d %d %d">%s%s%s%s%s`, + xmlTag, + fitToScreenWrapperOpening, + tag, + strings.Join([]string{diagramHash, idAttr}, " "), + w, h, left, top, w, h, + doubleBorderElStr, + backgroundEl.Render(), + upperBuf.String(), + buf.String(), + tag, + fitToScreenWrapperClosing, + ) + return []byte(docRendered), nil +} + +// TODO include only colors that are being used to reduce size +func ThemeCSS(diagramHash string, themeID *int64, darkThemeID *int64, overrides, darkOverrides *d2target.ThemeOverrides) (stylesheet string, err error) { + if themeID == nil { + themeID = &d2themescatalog.NeutralDefault.ID + } + out, err := singleThemeRulesets(diagramHash, *themeID, overrides) + if err != nil { + return "", err + } + + if darkThemeID != nil { + darkOut, err := singleThemeRulesets(diagramHash, *darkThemeID, darkOverrides) + if err != nil { + return "", err + } + out += fmt.Sprintf("@media screen and (prefers-color-scheme:dark){%s}", darkOut) + } + + return out, nil +} + +func singleThemeRulesets(diagramHash string, themeID int64, overrides *d2target.ThemeOverrides) (rulesets string, err error) { + out := "" + theme := d2themescatalog.Find(themeID) + theme.ApplyOverrides(overrides) + + // Global theme colors + for _, property := range []string{"fill", "stroke", "background-color", "color"} { + out += fmt.Sprintf(` + .%s .%s-N1{%s:%s;} + .%s .%s-N2{%s:%s;} + .%s .%s-N3{%s:%s;} + .%s .%s-N4{%s:%s;} + .%s .%s-N5{%s:%s;} + .%s .%s-N6{%s:%s;} + .%s .%s-N7{%s:%s;} + .%s .%s-B1{%s:%s;} + .%s .%s-B2{%s:%s;} + .%s .%s-B3{%s:%s;} + .%s .%s-B4{%s:%s;} + .%s .%s-B5{%s:%s;} + .%s .%s-B6{%s:%s;} + .%s .%s-AA2{%s:%s;} + .%s .%s-AA4{%s:%s;} + .%s .%s-AA5{%s:%s;} + .%s .%s-AB4{%s:%s;} + .%s .%s-AB5{%s:%s;}`, + diagramHash, + property, property, theme.Colors.Neutrals.N1, + diagramHash, + property, property, theme.Colors.Neutrals.N2, + diagramHash, + property, property, theme.Colors.Neutrals.N3, + diagramHash, + property, property, theme.Colors.Neutrals.N4, + diagramHash, + property, property, theme.Colors.Neutrals.N5, + diagramHash, + property, property, theme.Colors.Neutrals.N6, + diagramHash, + property, property, theme.Colors.Neutrals.N7, + diagramHash, + property, property, theme.Colors.B1, + diagramHash, + property, property, theme.Colors.B2, + diagramHash, + property, property, theme.Colors.B3, + diagramHash, + property, property, theme.Colors.B4, + diagramHash, + property, property, theme.Colors.B5, + diagramHash, + property, property, theme.Colors.B6, + diagramHash, + property, property, theme.Colors.AA2, + diagramHash, + property, property, theme.Colors.AA4, + diagramHash, + property, property, theme.Colors.AA5, + diagramHash, + property, property, theme.Colors.AB4, + diagramHash, + property, property, theme.Colors.AB5, + ) + } + + // Appendix + out += fmt.Sprintf(".appendix text.text{fill:%s}", theme.Colors.Neutrals.N1) + + // Markdown specific rulesets + out += fmt.Sprintf(".md{--color-fg-default:%s;--color-fg-muted:%s;--color-fg-subtle:%s;--color-canvas-default:%s;--color-canvas-subtle:%s;--color-border-default:%s;--color-border-muted:%s;--color-neutral-muted:%s;--color-accent-fg:%s;--color-accent-emphasis:%s;--color-attention-subtle:%s;--color-danger-fg:%s;}", + theme.Colors.Neutrals.N1, theme.Colors.Neutrals.N2, theme.Colors.Neutrals.N3, + theme.Colors.Neutrals.N7, theme.Colors.Neutrals.N6, + theme.Colors.B1, theme.Colors.B2, + theme.Colors.Neutrals.N6, + theme.Colors.B2, theme.Colors.B2, + theme.Colors.Neutrals.N2, // TODO or N3 --color-attention-subtle + "red", + ) + + // Sketch style specific rulesets + // B + lc, err := color.LuminanceCategory(theme.Colors.B1) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.B1, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.B2) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.B2, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.B3) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.B3, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.B4) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.B4, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.B5) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.B5, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.B6) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.B6, lc, diagramHash, blendMode(lc)) + + // AA + lc, err = color.LuminanceCategory(theme.Colors.AA2) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.AA2, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.AA4) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.AA4, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.AA5) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.AA5, lc, diagramHash, blendMode(lc)) + + // AB + lc, err = color.LuminanceCategory(theme.Colors.AB4) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.AB4, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.AB5) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.AB5, lc, diagramHash, blendMode(lc)) + + // Neutrals + lc, err = color.LuminanceCategory(theme.Colors.Neutrals.N1) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.N1, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.Neutrals.N2) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.N2, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.Neutrals.N3) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.N3, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.Neutrals.N4) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.N4, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.Neutrals.N5) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.N5, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.Neutrals.N6) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.N6, lc, diagramHash, blendMode(lc)) + lc, err = color.LuminanceCategory(theme.Colors.Neutrals.N7) + if err != nil { + return "", err + } + out += fmt.Sprintf(".sketch-overlay-%s{fill:url(#streaks-%s-%s);mix-blend-mode:%s}", color.N7, lc, diagramHash, blendMode(lc)) + + if theme.IsDark() { + out += ".light-code{display: none}" + out += ".dark-code{display: block}" + } else { + out += ".light-code{display: block}" + out += ".dark-code{display: none}" + } + + return out, nil +} + +func blendMode(lc string) string { + switch lc { + case "bright": + return "darken" + case "normal": + return "color-burn" + case "dark": + return "overlay" + case "darker": + return "lighten" + } + panic("invalid luminance category") +} + +type DiagramObject interface { + GetID() string + GetZIndex() int +} + +// sortObjects sorts all diagrams objects (shapes and connections) in the desired drawing order +// the sorting criteria is: +// 1. zIndex, lower comes first +// 2. two shapes with the same zIndex are sorted by their level (container nesting), containers come first +// 3. two shapes with the same zIndex and same level, are sorted in the order they were exported +// 4. shape and edge, shapes come first +func sortObjects(allObjects []DiagramObject) { + sort.SliceStable(allObjects, func(i, j int) bool { + // first sort by zIndex + iZIndex := allObjects[i].GetZIndex() + jZIndex := allObjects[j].GetZIndex() + if iZIndex != jZIndex { + return iZIndex < jZIndex + } + + // then, if both are shapes, parents come before their children + iShape, iIsShape := allObjects[i].(d2target.Shape) + jShape, jIsShape := allObjects[j].(d2target.Shape) + if iIsShape && jIsShape { + return iShape.Level < jShape.Level + } + + // then, shapes come before connections + _, jIsConnection := allObjects[j].(d2target.Connection) + return iIsShape && jIsConnection + }) +} + +func hash(s string) string { + const secret = "lalalas" + h := fnv.New32a() + h.Write([]byte(fmt.Sprintf("%s%s", s, secret))) + return fmt.Sprint(h.Sum32()) +} + +func RenderMultiboard(diagram *d2target.Diagram, opts *RenderOpts) ([][]byte, error) { + var boards [][]byte + for _, dl := range diagram.Layers { + childrenBoards, err := RenderMultiboard(dl, opts) + if err != nil { + return nil, err + } + boards = append(boards, childrenBoards...) + } + for _, dl := range diagram.Scenarios { + childrenBoards, err := RenderMultiboard(dl, opts) + if err != nil { + return nil, err + } + boards = append(boards, childrenBoards...) + } + for _, dl := range diagram.Steps { + childrenBoards, err := RenderMultiboard(dl, opts) + if err != nil { + return nil, err + } + boards = append(boards, childrenBoards...) + } + + if !diagram.IsFolderOnly { + out, err := Render(diagram, opts) + if err != nil { + return boards, err + } + boards = append([][]byte{out}, boards...) + return boards, nil + } + return boards, nil +} diff --git a/d2target/d2target.go b/d2target/d2target.go index 3da7cec08..1965b4b51 100644 --- a/d2target/d2target.go +++ b/d2target/d2target.go @@ -456,6 +456,16 @@ func (diagram Diagram) GetCorpus() string { } } + if diagram.Legend != nil { + corpus += "Legend" + for _, s := range diagram.Legend.Shapes { + corpus += s.Label + } + for _, c := range diagram.Legend.Connections { + corpus += c.Label + } + } + return corpus } diff --git a/e2etests/testdata/txtar/legend/dagre/board.exp.json b/e2etests/testdata/txtar/legend/dagre/board.exp.json new file mode 100644 index 000000000..838cefcc8 --- /dev/null +++ b/e2etests/testdata/txtar/legend/dagre/board.exp.json @@ -0,0 +1,725 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "api-1", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 81, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "api-1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "api-2", + "type": "rectangle", + "pos": { + "x": 141, + "y": 166 + }, + "width": 81, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "api-2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "postgres", + "type": "cylinder", + "pos": { + "x": 18, + "y": 332 + }, + "width": 106, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AA4", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "postgres", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 61, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "external", + "type": "rectangle", + "pos": { + "x": 18, + "y": 550 + }, + "width": 105, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "external", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 60, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "api-3", + "type": "rectangle", + "pos": { + "x": 0, + "y": 166 + }, + "width": 81, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "api-3", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(api-1 -> postgres)[0]", + "src": "api-1", + "srcArrow": "none", + "dst": "postgres", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 8, + "y": 66 + }, + { + "x": -30.399999618530273, + "y": 106 + }, + { + "x": -40, + "y": 132.60000610351562 + }, + { + "x": -40, + "y": 157.5 + }, + { + "x": -40, + "y": 182.39999389648438 + }, + { + "x": -27.399999618530273, + "y": 294.3999938964844 + }, + { + "x": 23, + "y": 344 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(api-2 -> postgres)[0]", + "src": "api-2", + "srcArrow": "none", + "dst": "postgres", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 181.5, + "y": 232 + }, + { + "x": 181.5, + "y": 272 + }, + { + "x": 169, + "y": 294.3999938964844 + }, + { + "x": 119, + "y": 344 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(postgres -> external)[0]", + "src": "postgres", + "srcArrow": "none", + "dst": "external", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "black", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 71, + "y": 450 + }, + { + "x": 70.80000305175781, + "y": 490 + }, + { + "x": 70.75, + "y": 510 + }, + { + "x": 70.75, + "y": 550 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(api-1 <-> api-2)[0]", + "src": "api-1", + "srcArrow": "triangle", + "dst": "api-2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 2, + "strokeWidth": 2, + "stroke": "red", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 80.5, + "y": 57 + }, + { + "x": 161.3000030517578, + "y": 104.19999694824219 + }, + { + "x": 181.5, + "y": 126 + }, + { + "x": 181.5, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(api-1 -> api-3)[0]", + "src": "api-1", + "srcArrow": "none", + "dst": "api-3", + "dstArrow": "circle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 40.5, + "y": 66 + }, + { + "x": 40.5, + "y": 106 + }, + { + "x": 40.5, + "y": 126 + }, + { + "x": 40.5, + "y": 166 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + }, + "legend": { + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 10, + "y": 10 + }, + "width": 100, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Microservice", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "cylinder", + "pos": { + "x": 10, + "y": 10 + }, + "width": 100, + "height": 100, + "opacity": 1, + "strokeDash": 2, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AA4", + "stroke": "B2", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Database", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a <-> b)[0]", + "src": "a", + "srcArrow": "triangle", + "dst": "b", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 2, + "strokeWidth": 1, + "stroke": "red", + "borderRadius": 10, + "label": "Good relationship", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 10, + "y": 10 + }, + { + "x": 110, + "y": 10 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "dst": "b", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Bad relationship", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 10, + "y": 10 + }, + { + "x": 110, + "y": 10 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a -> b)[1]", + "src": "a", + "srcArrow": "none", + "dst": "b", + "dstArrow": "circle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Tenuous", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 10, + "y": 10 + }, + { + "x": 110, + "y": 10 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] + } +} diff --git a/e2etests/testdata/txtar/legend/dagre/sketch.exp.svg b/e2etests/testdata/txtar/legend/dagre/sketch.exp.svg new file mode 100644 index 000000000..47b7b2a65 --- /dev/null +++ b/e2etests/testdata/txtar/legend/dagre/sketch.exp.svg @@ -0,0 +1,106 @@ +api-1api-2postgresexternalapi-3 LegendMicroserviceDatabase Good relationship Bad relationship Tenuous + + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/txtar/legend/elk/board.exp.json b/e2etests/testdata/txtar/legend/elk/board.exp.json new file mode 100644 index 000000000..5376eae0a --- /dev/null +++ b/e2etests/testdata/txtar/legend/elk/board.exp.json @@ -0,0 +1,684 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "api-1", + "type": "rectangle", + "pos": { + "x": 45, + "y": 12 + }, + "width": 120, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "api-1", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "api-2", + "type": "rectangle", + "pos": { + "x": 65, + "y": 158 + }, + "width": 81, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "api-2", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "postgres", + "type": "cylinder", + "pos": { + "x": 12, + "y": 304 + }, + "width": 106, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AA4", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "postgres", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 61, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "external", + "type": "rectangle", + "pos": { + "x": 12, + "y": 492 + }, + "width": 105, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "external", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 60, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "api-3", + "type": "rectangle", + "pos": { + "x": 166, + "y": 158 + }, + "width": 81, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "api-3", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 36, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(api-1 -> postgres)[0]", + "src": "api-1", + "srcArrow": "none", + "dst": "postgres", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 75.75, + "y": 78 + }, + { + "x": 75.75, + "y": 118 + }, + { + "x": 24.249000549316406, + "y": 118 + }, + { + "x": 24, + "y": 311 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(api-2 -> postgres)[0]", + "src": "api-2", + "srcArrow": "none", + "dst": "postgres", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 82.66600036621094, + "y": 224 + }, + { + "x": 83, + "y": 305 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(postgres -> external)[0]", + "src": "postgres", + "srcArrow": "none", + "dst": "external", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "black", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 65, + "y": 422 + }, + { + "x": 65, + "y": 492 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(api-1 <-> api-2)[0]", + "src": "api-1", + "srcArrow": "triangle", + "dst": "api-2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 2, + "strokeWidth": 2, + "stroke": "red", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 105.75, + "y": 78 + }, + { + "x": 105.75, + "y": 158 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(api-1 -> api-3)[0]", + "src": "api-1", + "srcArrow": "none", + "dst": "api-3", + "dstArrow": "circle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 135.75, + "y": 78 + }, + { + "x": 135.75, + "y": 118 + }, + { + "x": 206.75, + "y": 118 + }, + { + "x": 206.75, + "y": 158 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + }, + "legend": { + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 10, + "y": 10 + }, + "width": 100, + "height": 100, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Microservice", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 1 + }, + { + "id": "b", + "type": "cylinder", + "pos": { + "x": 10, + "y": 10 + }, + "width": 100, + "height": 100, + "opacity": 1, + "strokeDash": 2, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AA4", + "stroke": "B2", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Database", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(a <-> b)[0]", + "src": "a", + "srcArrow": "triangle", + "dst": "b", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 2, + "strokeWidth": 1, + "stroke": "red", + "borderRadius": 10, + "label": "Good relationship", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 10, + "y": 10 + }, + { + "x": 110, + "y": 10 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a -> b)[0]", + "src": "a", + "srcArrow": "none", + "dst": "b", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Bad relationship", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 10, + "y": 10 + }, + { + "x": 110, + "y": 10 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(a -> b)[1]", + "src": "a", + "srcArrow": "none", + "dst": "b", + "dstArrow": "circle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Tenuous", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 10, + "y": 10 + }, + { + "x": 110, + "y": 10 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + } + ] + } +} diff --git a/e2etests/testdata/txtar/legend/elk/sketch.exp.svg b/e2etests/testdata/txtar/legend/elk/sketch.exp.svg new file mode 100644 index 000000000..1cf312712 --- /dev/null +++ b/e2etests/testdata/txtar/legend/elk/sketch.exp.svg @@ -0,0 +1,106 @@ +api-1api-2postgresexternalapi-3 LegendMicroserviceDatabase Good relationship Bad relationship Tenuous + + + + + + + \ No newline at end of file diff --git a/e2etests/txtar.txt b/e2etests/txtar.txt index ec6be2ce9..591372192 100644 --- a/e2etests/txtar.txt +++ b/e2etests/txtar.txt @@ -1127,3 +1127,45 @@ customer -> email_system: "Sends e-mails to" internet_banking_system.api_app -> email_system: "Sends e-mail using" internet_banking_system.database <-> internet_banking_system.api_app: "Reads from and writes to\n[SQL/TCP]" +-- legend -- +vars: { + d2-legend: { + a: { + label: Microservice + } + b: Database { + shape: cylinder + style.stroke-dash: 2 + } + a <-> b: Good relationship { + style.stroke: red + style.stroke-dash: 2 + style.stroke-width: 1 + } + a -> b: Bad relationship + a -> b: Tenuous { + target-arrowhead.shape: circle + } + } +} + +api-1 +api-2 + +api-1 -> postgres +api-2 -> postgres + +postgres: { + shape: cylinder +} +postgres -> external: { + style.stroke: black +} + +api-1 <-> api-2: { + style.stroke: red + style.stroke-dash: 2 +} +api-1 -> api-3: { + target-arrowhead.shape: circle +} From 3c3069305260b4864b1101d063af4292f6294d0c Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Tue, 11 Mar 2025 16:03:57 -0600 Subject: [PATCH 08/54] next --- ci/release/changelogs/next.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 48661ab23..ab55c0441 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -6,6 +6,7 @@ - Render: - markdown, latex, and code can be used as object labels [#2204](https://github.com/terrastruct/d2/pull/2204) - `shape: c4-person` to render a person shape like what the C4 model prescribes [#2397](https://github.com/terrastruct/d2/pull/2397) +- Diagram legends are implemented [#2416](https://github.com/terrastruct/d2/pull/2416) #### Improvements 🧹 From 8b324c496381e712ca52f65e709b42a0141440c2 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Tue, 11 Mar 2025 19:53:45 -0600 Subject: [PATCH 09/54] fix md label with dark theme and c4 person shape when small --- d2renderers/d2svg/d2svg.go | 3 +- .../dark-theme-shape/dagre/board.exp.json | 99 ++ .../dark-theme-shape/dagre/sketch.exp.svg | 908 ++++++++++++++++++ .../txtar/dark-theme-shape/elk/board.exp.json | 99 ++ .../txtar/dark-theme-shape/elk/sketch.exp.svg | 908 ++++++++++++++++++ .../small-c4-person/dagre/board.exp.json | 99 ++ .../small-c4-person/dagre/sketch.exp.svg | 95 ++ .../txtar/small-c4-person/elk/board.exp.json | 99 ++ .../txtar/small-c4-person/elk/sketch.exp.svg | 95 ++ e2etests/txtar.txt | 18 + lib/shape/shape_c4_person.go | 4 +- 11 files changed, 2425 insertions(+), 2 deletions(-) create mode 100644 e2etests/testdata/txtar/dark-theme-shape/dagre/board.exp.json create mode 100644 e2etests/testdata/txtar/dark-theme-shape/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/txtar/dark-theme-shape/elk/board.exp.json create mode 100644 e2etests/testdata/txtar/dark-theme-shape/elk/sketch.exp.svg create mode 100644 e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json create mode 100644 e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/txtar/small-c4-person/elk/board.exp.json create mode 100644 e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index 1c16261c3..434b97bc2 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -1746,9 +1746,10 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape } if !color.IsThemeColor(targetShape.Color) { styles = append(styles, fmt.Sprintf(`color:%s`, targetShape.Color)) - } else { + } else if inlineTheme != nil { styles = append(styles, fmt.Sprintf(`color:%s`, d2themes.ResolveThemeColor(*inlineTheme, targetShape.Color))) } + // When using dark theme, inlineTheme is nil and we rely on CSS variables mdEl.Style = strings.Join(styles, ";") diff --git a/e2etests/testdata/txtar/dark-theme-shape/dagre/board.exp.json b/e2etests/testdata/txtar/dark-theme-shape/dagre/board.exp.json new file mode 100644 index 000000000..f3333ec26 --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-shape/dagre/board.exp.json @@ -0,0 +1,99 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": 200, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 96, + "height": 96, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# hey", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 51, + "labelHeight": 51, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/dark-theme-shape/dagre/sketch.exp.svg b/e2etests/testdata/txtar/dark-theme-shape/dagre/sketch.exp.svg new file mode 100644 index 000000000..a297d152f --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-shape/dagre/sketch.exp.svg @@ -0,0 +1,908 @@ +

hey

+
+ + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/dark-theme-shape/elk/board.exp.json b/e2etests/testdata/txtar/dark-theme-shape/elk/board.exp.json new file mode 100644 index 000000000..c467d88ac --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-shape/elk/board.exp.json @@ -0,0 +1,99 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": 200, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 96, + "height": 96, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# hey", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 51, + "labelHeight": 51, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/dark-theme-shape/elk/sketch.exp.svg b/e2etests/testdata/txtar/dark-theme-shape/elk/sketch.exp.svg new file mode 100644 index 000000000..6409b8037 --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-shape/elk/sketch.exp.svg @@ -0,0 +1,908 @@ +

hey

+
+ + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json new file mode 100644 index 000000000..be4ffa74e --- /dev/null +++ b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json @@ -0,0 +1,99 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "c4-person", + "pos": { + "x": 0, + "y": 0 + }, + "width": 180, + "height": 114, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c4-person", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 71, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg new file mode 100644 index 000000000..afeff911b --- /dev/null +++ b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg @@ -0,0 +1,95 @@ +c4-person + + + \ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json new file mode 100644 index 000000000..899afe63f --- /dev/null +++ b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json @@ -0,0 +1,99 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "c4-person", + "pos": { + "x": 12, + "y": 12 + }, + "width": 180, + "height": 114, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c4-person", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 71, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg new file mode 100644 index 000000000..68477ef9d --- /dev/null +++ b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg @@ -0,0 +1,95 @@ +c4-person + + + \ No newline at end of file diff --git a/e2etests/txtar.txt b/e2etests/txtar.txt index 591372192..d20dbb221 100644 --- a/e2etests/txtar.txt +++ b/e2etests/txtar.txt @@ -1169,3 +1169,21 @@ api-1 <-> api-2: { api-1 -> api-3: { target-arrowhead.shape: circle } + +-- dark-theme-md -- + +vars: { + d2-config: { + dark-theme-id: 200 + } +} +a.shape: rectangle +a: |md + # hey +| + +-- small-c4-person -- + +a.shape: c4-person +a: c4-person +a.width: 180 diff --git a/lib/shape/shape_c4_person.go b/lib/shape/shape_c4_person.go index eb70c2a62..8535c5b79 100644 --- a/lib/shape/shape_c4_person.go +++ b/lib/shape/shape_c4_person.go @@ -61,7 +61,9 @@ func bodyPath(box *geo.Box) *svg.SvgPathContext { bodyWidth := width bodyHeight := height - bodyTop bodyLeft := 0 - cornerRadius := width * 0.175 + // Ensure cornerRadius is constrained to a portion of the shortest dimension + // This prevents distorted corners when width is large compared to height + cornerRadius := math.Min(width*0.175, bodyHeight*0.25) pc.StartAt(pc.Absolute(float64(bodyLeft), bodyTop+cornerRadius)) From 4a2b7a2bbe21c3f48defac581d0eab0ab36cd155 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Tue, 11 Mar 2025 22:06:59 -0600 Subject: [PATCH 10/54] Ta --- .../txtar/dark-theme-md/dagre/board.exp.json | 99 ++ .../txtar/dark-theme-md/dagre/sketch.exp.svg | 908 ++++++++++++++++++ .../txtar/dark-theme-md/elk/board.exp.json | 99 ++ .../txtar/dark-theme-md/elk/sketch.exp.svg | 908 ++++++++++++++++++ 4 files changed, 2014 insertions(+) create mode 100644 e2etests/testdata/txtar/dark-theme-md/dagre/board.exp.json create mode 100644 e2etests/testdata/txtar/dark-theme-md/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/txtar/dark-theme-md/elk/board.exp.json create mode 100644 e2etests/testdata/txtar/dark-theme-md/elk/sketch.exp.svg diff --git a/e2etests/testdata/txtar/dark-theme-md/dagre/board.exp.json b/e2etests/testdata/txtar/dark-theme-md/dagre/board.exp.json new file mode 100644 index 000000000..f3333ec26 --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-md/dagre/board.exp.json @@ -0,0 +1,99 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": 200, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 0, + "y": 0 + }, + "width": 96, + "height": 96, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# hey", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 51, + "labelHeight": 51, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/dark-theme-md/dagre/sketch.exp.svg b/e2etests/testdata/txtar/dark-theme-md/dagre/sketch.exp.svg new file mode 100644 index 000000000..a297d152f --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-md/dagre/sketch.exp.svg @@ -0,0 +1,908 @@ +

hey

+
+ + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/dark-theme-md/elk/board.exp.json b/e2etests/testdata/txtar/dark-theme-md/elk/board.exp.json new file mode 100644 index 000000000..c467d88ac --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-md/elk/board.exp.json @@ -0,0 +1,99 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": 200, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "rectangle", + "pos": { + "x": 12, + "y": 12 + }, + "width": 96, + "height": 96, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "# hey", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 51, + "labelHeight": 51, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/dark-theme-md/elk/sketch.exp.svg b/e2etests/testdata/txtar/dark-theme-md/elk/sketch.exp.svg new file mode 100644 index 000000000..6409b8037 --- /dev/null +++ b/e2etests/testdata/txtar/dark-theme-md/elk/sketch.exp.svg @@ -0,0 +1,908 @@ +

hey

+
+ + +
\ No newline at end of file From 3bbb33866ef539b9bd1a817af59a2d64c93cc4f1 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Wed, 12 Mar 2025 13:59:15 -0600 Subject: [PATCH 11/54] fix edge suspension --- d2ir/compile.go | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/d2ir/compile.go b/d2ir/compile.go index 63588d8c8..49e0cd740 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -1275,10 +1275,28 @@ func (c *compiler) _compileEdges(refctx *RefContext) { if refctx.Key.Primary.Suspension != nil || refctx.Key.Value.Suspension != nil { if !c.lazyGlobBeingApplied { + var suspensionValue bool if refctx.Key.Primary.Suspension != nil { - e.suspended = refctx.Key.Primary.Suspension.Value + suspensionValue = refctx.Key.Primary.Suspension.Value } else { - e.suspended = refctx.Key.Value.Suspension.Value + suspensionValue = refctx.Key.Value.Suspension.Value + } + e.suspended = suspensionValue + + // If we're unsuspending an edge, we should also unsuspend its src and dst objects + if !suspensionValue { + // Find the source and destination objects + srcPath, dstPath := e.ID.SrcPath, e.ID.DstPath + srcObj := refctx.ScopeMap.GetField(srcPath...) + dstObj := refctx.ScopeMap.GetField(dstPath...) + + // Unsuspend the objects + if srcObj != nil { + srcObj.suspended = false + } + if dstObj != nil { + dstObj.suspended = false + } } } } @@ -1309,7 +1327,7 @@ func (c *compiler) _compileEdges(refctx *RefContext) { } c.compileField(e.Map_, refctx.Key.EdgeKey, refctx) } else { - if refctx.Key.Primary.Unbox() != nil { + if refctx.Key.Primary.Unbox() != nil && refctx.Key.Primary.Suspension == nil { if c.ignoreLazyGlob(e) { return } @@ -1330,7 +1348,7 @@ func (c *compiler) _compileEdges(refctx *RefContext) { c.mapRefContextStack = append(c.mapRefContextStack, refctx) c.compileMap(e.Map_, refctx.Key.Value.Map, refctx.ScopeAST) c.mapRefContextStack = c.mapRefContextStack[:len(c.mapRefContextStack)-1] - } else if refctx.Key.Value.ScalarBox().Unbox() != nil { + } else if refctx.Key.Value.ScalarBox().Unbox() != nil && refctx.Key.Value.Suspension == nil { if c.ignoreLazyGlob(e) { return } From cbb54f06c0e34db23391b56d12e6b4335856e71c Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Wed, 12 Mar 2025 14:56:09 -0600 Subject: [PATCH 12/54] fix suspend --- d2compiler/compile_test.go | 38 ++ d2ir/compile.go | 2 - d2ir/d2ir.go | 36 +- .../TestCompile2/globs/suspend-shape.exp.json | 101 +++++ .../globs/unsuspend-edge-label.exp.json | 405 ++++++++++++++++++ .../globs/unsuspend-label.exp.json | 405 ++++++++++++++++++ .../globs/unsuspend-shape-label.exp.json | 178 ++++++++ 7 files changed, 1162 insertions(+), 3 deletions(-) create mode 100644 testdata/d2compiler/TestCompile2/globs/suspend-shape.exp.json create mode 100644 testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.exp.json create mode 100644 testdata/d2compiler/TestCompile2/globs/unsuspend-label.exp.json create mode 100644 testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.exp.json diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 00f3a24e4..39c0bb454 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -5617,6 +5617,44 @@ d -> d: "suspend" assert.Equal(t, 1, len(g.Edges)) }, }, + { + name: "unsuspend-edge-label", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +a -> b: hello +c +**: suspend +(** -> **)[*]: suspend + +(* -> *)[*]: unsuspend +`, ``) + assert.Equal(t, 2, len(g.Objects)) + assert.Equal(t, 1, len(g.Edges)) + assert.Equal(t, "hello", g.Edges[0].Label.Value) + }, + }, + { + name: "unsuspend-shape-label", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +a: hello +*: suspend +*: unsuspend +`, ``) + assert.Equal(t, 1, len(g.Objects)) + assert.Equal(t, "hello", g.Objects[0].Label.Value) + }, + }, + { + name: "suspend-shape", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +a: hello +*: suspend +`, ``) + assert.Equal(t, 0, len(g.Objects)) + }, + }, { name: "edge-glob-ampersand-filter/1", run: func(t *testing.T) { diff --git a/d2ir/compile.go b/d2ir/compile.go index 49e0cd740..db4984cd5 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -1285,12 +1285,10 @@ func (c *compiler) _compileEdges(refctx *RefContext) { // If we're unsuspending an edge, we should also unsuspend its src and dst objects if !suspensionValue { - // Find the source and destination objects srcPath, dstPath := e.ID.SrcPath, e.ID.DstPath srcObj := refctx.ScopeMap.GetField(srcPath...) dstObj := refctx.ScopeMap.GetField(dstPath...) - // Unsuspend the objects if srcObj != nil { srcObj.suspended = false } diff --git a/d2ir/d2ir.go b/d2ir/d2ir.go index 4ea360b92..e41edbb83 100644 --- a/d2ir/d2ir.go +++ b/d2ir/d2ir.go @@ -650,7 +650,41 @@ func (rc *RefContext) EdgeIndex() int { func (rc *RefContext) Equal(rc2 *RefContext) bool { // We intentionally ignore edges here because the same glob can produce multiple RefContexts that should be treated the same with only the edge as the difference. // Same with ScopeMap. - return rc.Key.Equals(rc2.Key) && rc.Scope == rc2.Scope && rc.ScopeAST == rc2.ScopeAST + if !(rc.Key.Equals(rc2.Key) && rc.Scope == rc2.Scope && rc.ScopeAST == rc2.ScopeAST) { + return false + } + + // Check if suspension values match for suspension operations + // We don't want these two to equal + // 1. *: suspend + // 2. *: unsuspend + hasSuspension1 := (rc.Key.Primary.Suspension != nil || rc.Key.Value.Suspension != nil) + hasSuspension2 := (rc2.Key.Primary.Suspension != nil || rc2.Key.Value.Suspension != nil) + + if hasSuspension1 || hasSuspension2 { + var val1, val2 bool + if rc.Key.Primary.Suspension != nil { + val1 = rc.Key.Primary.Suspension.Value + } else if rc.Key.Value.Suspension != nil { + val1 = rc.Key.Value.Suspension.Value + } + + if rc2.Key.Primary.Suspension != nil { + val2 = rc2.Key.Primary.Suspension.Value + } else if rc2.Key.Value.Suspension != nil { + val2 = rc2.Key.Value.Suspension.Value + } + + if hasSuspension1 && hasSuspension2 && val1 != val2 { + return false + } + + if hasSuspension1 != hasSuspension2 { + return false + } + } + + return true } func (m *Map) FieldCountRecursive() int { diff --git a/testdata/d2compiler/TestCompile2/globs/suspend-shape.exp.json b/testdata/d2compiler/TestCompile2/globs/suspend-shape.exp.json new file mode 100644 index 000000000..baf429ece --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/suspend-shape.exp.json @@ -0,0 +1,101 @@ +{ + "graph": { + "name": "", + "isFolderOnly": true, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,0:0:0-3:0:21", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,1:0:1-1:8:9", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,1:3:4-1:8:9", + "value": [ + { + "string": "hello", + "raw_string": "hello" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,2:0:10-2:10:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,2:0:10-2:1:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,2:0:10-2:1:11", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/suspend-shape.d2,2:3:13-2:10:20", + "value": true + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": null + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.exp.json b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.exp.json new file mode 100644 index 000000000..d33cb9b7c --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.exp.json @@ -0,0 +1,405 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,0:0:0-7:0:76", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:0:1-1:13:14", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:0:1-1:6:7", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:5:6-1:6:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:5:6-1:6:7", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:8:9-1:13:14", + "value": [ + { + "string": "hello", + "raw_string": "hello" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,2:0:15-2:1:16", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,2:0:15-2:1:16", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,2:0:15-2:1:16", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,3:0:17-3:11:28", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,3:0:17-3:2:19", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,3:0:17-3:2:19", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,3:4:21-3:11:28", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:0:29-4:22:51", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:1:30-4:9:38", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:1:30-4:3:32", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:1:30-4:3:32", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:7:36-4:9:38", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:7:36-4:9:38", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:10:39-4:13:42", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,4:15:44-4:22:51", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:0:53-6:22:75", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:1:54-6:7:60", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:1:54-6:2:55", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:1:54-6:2:55", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:6:59-6:7:60", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:6:59-6:7:60", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:8:61-6:11:64", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,6:13:66-6:22:75", + "value": false + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "hello" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:5:6-1:6:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label.d2,1:5:6-1:6:7", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/globs/unsuspend-label.exp.json b/testdata/d2compiler/TestCompile2/globs/unsuspend-label.exp.json new file mode 100644 index 000000000..3a0edc892 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/unsuspend-label.exp.json @@ -0,0 +1,405 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,0:0:0-7:0:76", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:0:1-1:13:14", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:0:1-1:6:7", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:5:6-1:6:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:5:6-1:6:7", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:8:9-1:13:14", + "value": [ + { + "string": "hello", + "raw_string": "hello" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,2:0:15-2:1:16", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,2:0:15-2:1:16", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,2:0:15-2:1:16", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,3:0:17-3:11:28", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,3:0:17-3:2:19", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,3:0:17-3:2:19", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,3:4:21-3:11:28", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:0:29-4:22:51", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:1:30-4:9:38", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:1:30-4:3:32", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:1:30-4:3:32", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:7:36-4:9:38", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:7:36-4:9:38", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:10:39-4:13:42", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,4:15:44-4:22:51", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:0:53-6:22:75", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:1:54-6:7:60", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:1:54-6:2:55", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:1:54-6:2:55", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:6:59-6:7:60", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:6:59-6:7:60", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:8:61-6:11:64", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,6:13:66-6:22:75", + "value": false + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "hello" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:5:6-1:6:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-label.d2,1:5:6-1:6:7", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.exp.json b/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.exp.json new file mode 100644 index 000000000..2ab9e4cfb --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.exp.json @@ -0,0 +1,178 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,0:0:0-4:0:34", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,1:0:1-1:8:9", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,1:3:4-1:8:9", + "value": [ + { + "string": "hello", + "raw_string": "hello" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,2:0:10-2:10:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,2:0:10-2:1:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,2:0:10-2:1:11", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,2:3:13-2:10:20", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,3:0:21-3:12:33", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,3:0:21-3:1:22", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,3:0:21-3:1:22", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,3:3:24-3:12:33", + "value": false + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-shape-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "hello" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} From b175c0370c2e2b8b62fc4dc1ee664edb79f6ce14 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Wed, 12 Mar 2025 15:29:48 -0600 Subject: [PATCH 13/54] fix edge glob ampersand filters --- d2compiler/compile_test.go | 15 + d2ir/compile.go | 14 + .../edge-glob-ampersand-filter/1.exp.json | 144 --- .../edge-glob-ampersand-filter/2.exp.json | 144 --- .../globs/unsuspend-edge-filter.exp.json | 284 ++++++ .../d2ir/TestCompile/filters/edge.exp.json | 823 +++++++--------- .../filters/label-filter/2.exp.json | 920 ------------------ .../filters/label-filter/3.exp.json | 184 ---- 8 files changed, 657 insertions(+), 1871 deletions(-) create mode 100644 testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.exp.json diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 39c0bb454..009e7885e 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -5633,6 +5633,21 @@ c assert.Equal(t, "hello", g.Edges[0].Label.Value) }, }, + { + name: "unsuspend-edge-filter", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +a -> b +**: suspend +(** -> **)[*]: suspend +(* -> *)[*]: unsuspend { + &dst: a +} +`, ``) + assert.Equal(t, 0, len(g.Objects)) + assert.Equal(t, 0, len(g.Edges)) + }, + }, { name: "unsuspend-shape-label", run: func(t *testing.T) { diff --git a/d2ir/compile.go b/d2ir/compile.go index db4984cd5..5799b2ae5 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -1273,6 +1273,20 @@ func (c *compiler) _compileEdges(refctx *RefContext) { continue } + if refctx.Key.Value.Map != nil && refctx.Key.Value.Map.HasFilter() { + if e.Map_ == nil { + e.Map_ = &Map{ + parent: e, + } + } + c.mapRefContextStack = append(c.mapRefContextStack, refctx) + ok := c.ampersandFilterMap(e.Map_, refctx.Key.Value.Map, refctx.ScopeAST) + c.mapRefContextStack = c.mapRefContextStack[:len(c.mapRefContextStack)-1] + if !ok { + continue + } + } + if refctx.Key.Primary.Suspension != nil || refctx.Key.Value.Suspension != nil { if !c.lazyGlobBeingApplied { var suspensionValue bool diff --git a/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/1.exp.json b/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/1.exp.json index b6304d711..6c2ac09a5 100644 --- a/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/1.exp.json +++ b/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/1.exp.json @@ -628,102 +628,6 @@ "src_arrow": false, "dst_arrow": true, "references": [ - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, { "map_key_edge_index": 0 }, @@ -761,36 +665,6 @@ "src_arrow": false, "dst_arrow": true, "references": [ - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, { "map_key_edge_index": 0 }, @@ -834,24 +708,6 @@ "src_arrow": false, "dst_arrow": true, "references": [ - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, { "map_key_edge_index": 0 }, diff --git a/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/2.exp.json b/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/2.exp.json index 19f5ece5a..26a0db37c 100644 --- a/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/2.exp.json +++ b/testdata/d2compiler/TestCompile2/globs/edge-glob-ampersand-filter/2.exp.json @@ -1149,102 +1149,6 @@ "src_arrow": false, "dst_arrow": true, "references": [ - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, { "map_key_edge_index": 0 }, @@ -1282,36 +1186,6 @@ "src_arrow": false, "dst_arrow": true, "references": [ - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, { "map_key_edge_index": 0 }, @@ -1355,24 +1229,6 @@ "src_arrow": false, "dst_arrow": true, "references": [ - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, - { - "map_key_edge_index": 0 - }, { "map_key_edge_index": 0 }, diff --git a/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.exp.json b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.exp.json new file mode 100644 index 000000000..aaf8ce50e --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.exp.json @@ -0,0 +1,284 @@ +{ + "graph": { + "name": "", + "isFolderOnly": true, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,0:0:0-7:0:80", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,1:0:1-1:6:7", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,1:0:1-1:6:7", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,1:5:6-1:6:7", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,1:5:6-1:6:7", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,2:0:8-2:11:19", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,2:0:8-2:2:10", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,2:0:8-2:2:10", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,2:4:12-2:11:19", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:0:20-3:22:42", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:1:21-3:9:29", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:1:21-3:3:23", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:1:21-3:3:23", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:7:27-3:9:29", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:7:27-3:9:29", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:10:30-3:13:33", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,3:15:35-3:22:42", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:0:43-6:1:79", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:1:44-4:7:50", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:1:44-4:2:45", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:1:44-4:2:45", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:6:49-4:7:50", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:6:49-4:7:50", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:8:51-4:11:54", + "int": null, + "glob": true + }, + "primary": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:13:56-4:22:65", + "value": false + } + }, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,4:23:66-6:1:79", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,5:2:70-5:9:77", + "ampersand": true, + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,5:3:71-5:6:74", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,5:3:71-5:6:74", + "value": [ + { + "string": "dst", + "raw_string": "dst" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-filter.d2,5:8:76-5:9:77", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": null + }, + "err": null +} diff --git a/testdata/d2ir/TestCompile/filters/edge.exp.json b/testdata/d2ir/TestCompile/filters/edge.exp.json index 5622ca570..89c6f9104 100644 --- a/testdata/d2ir/TestCompile/filters/edge.exp.json +++ b/testdata/d2ir/TestCompile/filters/edge.exp.json @@ -580,258 +580,6 @@ }, "due_to_glob": true, "due_to_lazy_glob": false - }, - { - "string": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "value": [ - { - "string": "x", - "raw_string": "x" - } - ] - }, - "key_path": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "value": [ - { - "string": "x", - "raw_string": "x" - } - ] - } - } - ] - }, - "context": { - "edge": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:7:93", - "src": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "value": [ - { - "string": "x", - "raw_string": "x" - } - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/edge.d2,6:0:86-10:1:203", - "edges": [ - { - "range": "TestCompile/filters/edge.d2,6:1:87-6:7:93", - "src": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "value": [ - { - "string": "x", - "raw_string": "x" - } - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/edge.d2,6:8:94-6:11:97", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/edge.d2,6:13:99-10:1:203", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/edge.d2,7:1:102-7:33:134", - "ampersand": true, - "key": { - "range": "TestCompile/filters/edge.d2,7:2:103-7:24:125", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", - "value": [ - { - "string": "source-arrowhead", - "raw_string": "source-arrowhead" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", - "value": [ - { - "string": "shape", - "raw_string": "shape" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,7:26:127-7:33:134", - "value": [ - { - "string": "diamond", - "raw_string": "diamond" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/edge.d2,8:1:136-8:33:168", - "ampersand": true, - "key": { - "range": "TestCompile/filters/edge.d2,8:2:137-8:24:159", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", - "value": [ - { - "string": "target-arrowhead", - "raw_string": "target-arrowhead" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", - "value": [ - { - "string": "shape", - "raw_string": "shape" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,8:26:161-8:33:168", - "value": [ - { - "string": "diamond", - "raw_string": "diamond" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/edge.d2,9:1:170-9:32:201", - "key": { - "range": "TestCompile/filters/edge.d2,9:1:170-9:6:175", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,9:1:170-9:6:175", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,9:8:177-9:32:201", - "value": [ - { - "string": "diamond shape arrowheads", - "raw_string": "diamond shape arrowheads" - } - ] - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": false } ] }, @@ -1318,6 +1066,92 @@ "due_to_glob": false, "due_to_lazy_glob": false }, + { + "string": { + "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + }, + "key_path": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:24:125", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", + "value": [ + { + "string": "source-arrowhead", + "raw_string": "source-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/filters/edge.d2,7:1:102-7:33:134", + "ampersand": true, + "key": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:24:125", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", + "value": [ + { + "string": "source-arrowhead", + "raw_string": "source-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:26:127-7:33:134", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + }, + "due_to_glob": true, + "due_to_lazy_glob": false + }, { "string": { "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", @@ -1495,6 +1329,92 @@ "due_to_glob": false, "due_to_lazy_glob": false }, + { + "string": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", + "value": [ + { + "string": "source-arrowhead", + "raw_string": "source-arrowhead" + } + ] + }, + "key_path": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:24:125", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", + "value": [ + { + "string": "source-arrowhead", + "raw_string": "source-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/filters/edge.d2,7:1:102-7:33:134", + "ampersand": true, + "key": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:24:125", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", + "value": [ + { + "string": "source-arrowhead", + "raw_string": "source-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,7:26:127-7:33:134", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + }, + "due_to_glob": true, + "due_to_lazy_glob": false + }, { "string": { "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", @@ -1702,6 +1622,92 @@ "due_to_glob": false, "due_to_lazy_glob": false }, + { + "string": { + "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + }, + "key_path": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:24:159", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/filters/edge.d2,8:1:136-8:33:168", + "ampersand": true, + "key": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:24:159", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:26:161-8:33:168", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + }, + "due_to_glob": true, + "due_to_lazy_glob": false + }, { "string": { "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", @@ -1879,6 +1885,92 @@ "due_to_glob": false, "due_to_lazy_glob": false }, + { + "string": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + }, + "key_path": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:24:159", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "context": { + "edge": null, + "key": { + "range": "TestCompile/filters/edge.d2,8:1:136-8:33:168", + "ampersand": true, + "key": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:24:159", + "path": [ + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", + "value": [ + { + "string": "target-arrowhead", + "raw_string": "target-arrowhead" + } + ] + } + }, + { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", + "value": [ + { + "string": "shape", + "raw_string": "shape" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "TestCompile/filters/edge.d2,8:26:161-8:33:168", + "value": [ + { + "string": "diamond", + "raw_string": "diamond" + } + ] + } + } + } + }, + "due_to_glob": true, + "due_to_lazy_glob": false + }, { "string": { "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", @@ -2588,233 +2680,6 @@ }, "due_to_glob": false, "due_to_lazy_glob": false - }, - { - "context": { - "edge": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:7:93", - "src": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "value": [ - { - "string": "x", - "raw_string": "x" - } - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/edge.d2,6:0:86-10:1:203", - "edges": [ - { - "range": "TestCompile/filters/edge.d2,6:1:87-6:7:93", - "src": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:1:87-6:2:88", - "value": [ - { - "string": "x", - "raw_string": "x" - } - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,6:6:92-6:7:93", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/edge.d2,6:8:94-6:11:97", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/edge.d2,6:13:99-10:1:203", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/edge.d2,7:1:102-7:33:134", - "ampersand": true, - "key": { - "range": "TestCompile/filters/edge.d2,7:2:103-7:24:125", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,7:2:103-7:18:119", - "value": [ - { - "string": "source-arrowhead", - "raw_string": "source-arrowhead" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,7:19:120-7:24:125", - "value": [ - { - "string": "shape", - "raw_string": "shape" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,7:26:127-7:33:134", - "value": [ - { - "string": "diamond", - "raw_string": "diamond" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/edge.d2,8:1:136-8:33:168", - "ampersand": true, - "key": { - "range": "TestCompile/filters/edge.d2,8:2:137-8:24:159", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,8:2:137-8:18:153", - "value": [ - { - "string": "target-arrowhead", - "raw_string": "target-arrowhead" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,8:19:154-8:24:159", - "value": [ - { - "string": "shape", - "raw_string": "shape" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,8:26:161-8:33:168", - "value": [ - { - "string": "diamond", - "raw_string": "diamond" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/edge.d2,9:1:170-9:32:201", - "key": { - "range": "TestCompile/filters/edge.d2,9:1:170-9:6:175", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,9:1:170-9:6:175", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/edge.d2,9:8:177-9:32:201", - "value": [ - { - "string": "diamond shape arrowheads", - "raw_string": "diamond shape arrowheads" - } - ] - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": false } ] } diff --git a/testdata/d2ir/TestCompile/filters/label-filter/2.exp.json b/testdata/d2ir/TestCompile/filters/label-filter/2.exp.json index c8901f508..a6814b031 100644 --- a/testdata/d2ir/TestCompile/filters/label-filter/2.exp.json +++ b/testdata/d2ir/TestCompile/filters/label-filter/2.exp.json @@ -1505,374 +1505,6 @@ }, "due_to_glob": true, "due_to_lazy_glob": true - }, - { - "context": { - "edge": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,3:0:33-6:1:81", - "edges": [ - { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/label-filter/2.d2,3:8:41-3:11:44", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/label-filter/2.d2,3:13:46-6:1:81", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,4:2:50-4:12:60", - "ampersand": true, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:10:58-4:12:60", - "value": [ - { - "string": "hi", - "raw_string": "hi" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:18:79", - "key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:15:76", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:7:68", - "value": [ - { - "string": "style", - "raw_string": "style" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:8:69-5:15:76", - "value": [ - { - "string": "opacity", - "raw_string": "opacity" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "number": { - "range": "TestCompile/filters/label-filter/2.d2,5:17:78-5:18:79", - "raw": "1", - "value": "1" - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": true - }, - { - "context": { - "edge": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,3:0:33-6:1:81", - "edges": [ - { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/label-filter/2.d2,3:8:41-3:11:44", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/label-filter/2.d2,3:13:46-6:1:81", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,4:2:50-4:12:60", - "ampersand": true, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:10:58-4:12:60", - "value": [ - { - "string": "hi", - "raw_string": "hi" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:18:79", - "key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:15:76", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:7:68", - "value": [ - { - "string": "style", - "raw_string": "style" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:8:69-5:15:76", - "value": [ - { - "string": "opacity", - "raw_string": "opacity" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "number": { - "range": "TestCompile/filters/label-filter/2.d2,5:17:78-5:18:79", - "raw": "1", - "value": "1" - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": true } ] }, @@ -2518,558 +2150,6 @@ }, "due_to_glob": true, "due_to_lazy_glob": true - }, - { - "context": { - "edge": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,3:0:33-6:1:81", - "edges": [ - { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/label-filter/2.d2,3:8:41-3:11:44", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/label-filter/2.d2,3:13:46-6:1:81", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,4:2:50-4:12:60", - "ampersand": true, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:10:58-4:12:60", - "value": [ - { - "string": "hi", - "raw_string": "hi" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:18:79", - "key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:15:76", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:7:68", - "value": [ - { - "string": "style", - "raw_string": "style" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:8:69-5:15:76", - "value": [ - { - "string": "opacity", - "raw_string": "opacity" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "number": { - "range": "TestCompile/filters/label-filter/2.d2,5:17:78-5:18:79", - "raw": "1", - "value": "1" - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": true - }, - { - "context": { - "edge": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,3:0:33-6:1:81", - "edges": [ - { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/label-filter/2.d2,3:8:41-3:11:44", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/label-filter/2.d2,3:13:46-6:1:81", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,4:2:50-4:12:60", - "ampersand": true, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:10:58-4:12:60", - "value": [ - { - "string": "hi", - "raw_string": "hi" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:18:79", - "key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:15:76", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:7:68", - "value": [ - { - "string": "style", - "raw_string": "style" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:8:69-5:15:76", - "value": [ - { - "string": "opacity", - "raw_string": "opacity" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "number": { - "range": "TestCompile/filters/label-filter/2.d2,5:17:78-5:18:79", - "raw": "1", - "value": "1" - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": true - }, - { - "context": { - "edge": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,3:0:33-6:1:81", - "edges": [ - { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:7:40", - "src": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:1:34-3:2:35", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,3:6:39-3:7:40", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/label-filter/2.d2,3:8:41-3:11:44", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/label-filter/2.d2,3:13:46-6:1:81", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,4:2:50-4:12:60", - "ampersand": true, - "key": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:3:51-4:8:56", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,4:10:58-4:12:60", - "value": [ - { - "string": "hi", - "raw_string": "hi" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:18:79", - "key": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:15:76", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:2:63-5:7:68", - "value": [ - { - "string": "style", - "raw_string": "style" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/2.d2,5:8:69-5:15:76", - "value": [ - { - "string": "opacity", - "raw_string": "opacity" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "number": { - "range": "TestCompile/filters/label-filter/2.d2,5:17:78-5:18:79", - "raw": "1", - "value": "1" - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": true } ] } diff --git a/testdata/d2ir/TestCompile/filters/label-filter/3.exp.json b/testdata/d2ir/TestCompile/filters/label-filter/3.exp.json index 987ebd9e8..65f2526bd 100644 --- a/testdata/d2ir/TestCompile/filters/label-filter/3.exp.json +++ b/testdata/d2ir/TestCompile/filters/label-filter/3.exp.json @@ -798,190 +798,6 @@ }, "due_to_glob": true, "due_to_lazy_glob": true - }, - { - "context": { - "edge": { - "range": "TestCompile/filters/label-filter/3.d2,1:1:2-1:7:8", - "src": { - "range": "TestCompile/filters/label-filter/3.d2,1:1:2-1:2:3", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,1:1:2-1:2:3", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/3.d2,1:6:7-1:7:8", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,1:6:7-1:7:8", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - }, - "key": { - "range": "TestCompile/filters/label-filter/3.d2,1:0:1-4:1:51", - "edges": [ - { - "range": "TestCompile/filters/label-filter/3.d2,1:1:2-1:7:8", - "src": { - "range": "TestCompile/filters/label-filter/3.d2,1:1:2-1:2:3", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,1:1:2-1:2:3", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "src_arrow": "", - "dst": { - "range": "TestCompile/filters/label-filter/3.d2,1:6:7-1:7:8", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,1:6:7-1:7:8", - "value": [ - { - "string": "*", - "raw_string": "*" - } - ], - "pattern": [ - "*" - ] - } - } - ] - }, - "dst_arrow": ">" - } - ], - "edge_index": { - "range": "TestCompile/filters/label-filter/3.d2,1:8:9-1:11:12", - "int": null, - "glob": true - }, - "primary": {}, - "value": { - "map": { - "range": "TestCompile/filters/label-filter/3.d2,1:13:14-4:1:51", - "nodes": [ - { - "map_key": { - "range": "TestCompile/filters/label-filter/3.d2,2:2:18-2:12:28", - "ampersand": true, - "key": { - "range": "TestCompile/filters/label-filter/3.d2,2:3:19-2:8:24", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,2:3:19-2:8:24", - "value": [ - { - "string": "label", - "raw_string": "label" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,2:10:26-2:12:28", - "value": [ - { - "string": "hi", - "raw_string": "hi" - } - ] - } - } - } - }, - { - "map_key": { - "range": "TestCompile/filters/label-filter/3.d2,3:2:31-3:20:49", - "key": { - "range": "TestCompile/filters/label-filter/3.d2,3:2:31-3:15:44", - "path": [ - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,3:2:31-3:7:36", - "value": [ - { - "string": "style", - "raw_string": "style" - } - ] - } - }, - { - "unquoted_string": { - "range": "TestCompile/filters/label-filter/3.d2,3:8:37-3:15:44", - "value": [ - { - "string": "opacity", - "raw_string": "opacity" - } - ] - } - } - ] - }, - "primary": {}, - "value": { - "number": { - "range": "TestCompile/filters/label-filter/3.d2,3:17:46-3:20:49", - "raw": "0.1", - "value": "1/10" - } - } - } - } - ] - } - } - } - }, - "due_to_glob": true, - "due_to_lazy_glob": true } ] } From c25d31351124c90afe9f001ce509262a6bf7de71 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Wed, 12 Mar 2025 16:05:08 -0600 Subject: [PATCH 14/54] unsuspend ancestors --- d2compiler/compile_test.go | 18 + d2ir/compile.go | 69 ++- .../globs/unsuspend-edge-child.exp.json | 490 ++++++++++++++++++ 3 files changed, 575 insertions(+), 2 deletions(-) create mode 100644 testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.exp.json diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 009e7885e..b9df3323a 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -5648,6 +5648,24 @@ a -> b assert.Equal(t, 0, len(g.Edges)) }, }, + { + name: "unsuspend-edge-child", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +a: { + b -> c +} + +**: suspend +(** -> **)[*]: suspend +(** -> **)[*]: unsuspend { + &dst: a.c +} +`, ``) + assert.Equal(t, 3, len(g.Objects)) + assert.Equal(t, 1, len(g.Edges)) + }, + }, { name: "unsuspend-shape-label", run: func(t *testing.T) { diff --git a/d2ir/compile.go b/d2ir/compile.go index 5799b2ae5..71e8d7c7e 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -869,6 +869,22 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool { for _, part := range edge.ID.SrcPath { srcParts = append(srcParts, part.ScalarString()) } + + container := ParentField(edge) + if container != nil && container.Name.ScalarString() != "root" { + containerPath := []string{} + curr := container + for curr != nil && curr.Name.ScalarString() != "root" { + containerPath = append([]string{curr.Name.ScalarString()}, containerPath...) + curr = ParentField(curr) + } + + srcStart := srcParts[0] + if !strings.EqualFold(srcStart, containerPath[0]) { + srcParts = append(containerPath, srcParts...) + } + } + srcPath := strings.Join(srcParts, ".") return srcPath == filterValue @@ -889,6 +905,23 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool { for _, part := range edge.ID.DstPath { dstParts = append(dstParts, part.ScalarString()) } + + // Find the container that holds this edge + // Build the absolute path by prepending the container's path + container := ParentField(edge) + if container != nil && container.Name.ScalarString() != "root" { + containerPath := []string{} + curr := container + for curr != nil && curr.Name.ScalarString() != "root" { + containerPath = append([]string{curr.Name.ScalarString()}, containerPath...) + curr = ParentField(curr) + } + + dstStart := dstParts[0] + if !strings.EqualFold(dstStart, containerPath[0]) { + dstParts = append(containerPath, dstParts...) + } + } dstPath := strings.Join(dstParts, ".") return dstPath == filterValue @@ -1298,16 +1331,48 @@ func (c *compiler) _compileEdges(refctx *RefContext) { e.suspended = suspensionValue // If we're unsuspending an edge, we should also unsuspend its src and dst objects + // And their ancestors if !suspensionValue { srcPath, dstPath := e.ID.SrcPath, e.ID.DstPath - srcObj := refctx.ScopeMap.GetField(srcPath...) - dstObj := refctx.ScopeMap.GetField(dstPath...) + container := ParentField(e) + if container != nil && container.Name.ScalarString() != "root" { + containerPath := []d2ast.String{} + curr := container + for curr != nil && curr.Name.ScalarString() != "root" { + containerPath = append([]d2ast.String{curr.Name}, containerPath...) + curr = ParentField(curr) + } + + if len(srcPath) > 0 && !strings.EqualFold(srcPath[0].ScalarString(), containerPath[0].ScalarString()) { + absSrcPath := append([]d2ast.String{}, containerPath...) + srcPath = append(absSrcPath, srcPath...) + } + + if len(dstPath) > 0 && !strings.EqualFold(dstPath[0].ScalarString(), containerPath[0].ScalarString()) { + absDstPath := append([]d2ast.String{}, containerPath...) + dstPath = append(absDstPath, dstPath...) + } + } + + rootMap := RootMap(refctx.ScopeMap) + srcObj := rootMap.GetField(srcPath...) + dstObj := rootMap.GetField(dstPath...) if srcObj != nil { srcObj.suspended = false + parent := ParentField(srcObj) + for parent != nil && parent.Name.ScalarString() != "root" { + parent.suspended = false + parent = ParentField(parent) + } } if dstObj != nil { dstObj.suspended = false + parent := ParentField(srcObj) + for parent != nil && parent.Name.ScalarString() != "root" { + parent.suspended = false + parent = ParentField(parent) + } } } } diff --git a/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.exp.json b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.exp.json new file mode 100644 index 000000000..0cc431588 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.exp.json @@ -0,0 +1,490 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,0:0:0-10:0:94", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-3:1:16", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:3:4-3:1:16", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:8:14", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:8:14", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:3:9", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:3:9", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:7:13-2:8:14", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:7:13-2:8:14", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,5:0:18-5:11:29", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,5:0:18-5:2:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,5:0:18-5:2:20", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,5:4:22-5:11:29", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:0:30-6:22:52", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:1:31-6:9:39", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:1:31-6:3:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:1:31-6:3:33", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:7:37-6:9:39", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:7:37-6:9:39", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:10:40-6:13:43", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:15:45-6:22:52", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:0:53-9:1:93", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:1:54-7:9:62", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:1:54-7:3:56", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:1:54-7:3:56", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:7:60-7:9:62", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:7:60-7:9:62", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:10:63-7:13:66", + "int": null, + "glob": true + }, + "primary": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:15:68-7:24:77", + "value": false + } + }, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:25:78-9:1:93", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,8:2:82-8:11:91", + "ampersand": true, + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,8:3:83-8:6:86", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,8:3:83-8:6:86", + "value": [ + { + "string": "dst", + "raw_string": "dst" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,8:8:88-8:11:91", + "value": [ + { + "string": "a.c", + "raw_string": "a.c" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:3:9", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:3:9", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "c", + "id_val": "c", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:7:13-2:8:14", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:7:13-2:8:14", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "c" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} From d01a0ea5f83374d61657d94feccaded8f81ac10b Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Wed, 12 Mar 2025 16:22:20 -0600 Subject: [PATCH 15/54] fix nested child --- d2compiler/compile_test.go | 21 + d2ir/compile.go | 22 +- ...uspend-cross-container-edge-label.exp.json | 766 ++++++++++++++++++ .../globs/unsuspend-edge-label#01.exp.json | 577 +++++++++++++ 4 files changed, 1385 insertions(+), 1 deletion(-) create mode 100644 testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.exp.json create mode 100644 testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.exp.json diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index b9df3323a..c3ce5c5e7 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -5666,6 +5666,27 @@ a: { assert.Equal(t, 1, len(g.Edges)) }, }, + { + name: "unsuspend-cross-container-edge-label", + run: func(t *testing.T) { + g, _ := assertCompile(t, ` +a: { + b +} +c: { + d +} +a.b -> c.d: likes +**: suspend +(** -> **)[*]: suspend +(** -> **)[*]: unsuspend { + &label: likes +} +`, ``) + assert.Equal(t, 4, len(g.Objects)) + assert.Equal(t, 1, len(g.Edges)) + }, + }, { name: "unsuspend-shape-label", run: func(t *testing.T) { diff --git a/d2ir/compile.go b/d2ir/compile.go index 71e8d7c7e..9473b7e37 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -1322,6 +1322,21 @@ func (c *compiler) _compileEdges(refctx *RefContext) { if refctx.Key.Primary.Suspension != nil || refctx.Key.Value.Suspension != nil { if !c.lazyGlobBeingApplied { + // Check if edge passes filter before applying suspension + if refctx.Key.Value.Map != nil && refctx.Key.Value.Map.HasFilter() { + if e.Map_ == nil { + e.Map_ = &Map{ + parent: e, + } + } + c.mapRefContextStack = append(c.mapRefContextStack, refctx) + ok := c.ampersandFilterMap(e.Map_, refctx.Key.Value.Map, refctx.ScopeAST) + c.mapRefContextStack = c.mapRefContextStack[:len(c.mapRefContextStack)-1] + if !ok { + continue + } + } + var suspensionValue bool if refctx.Key.Primary.Suspension != nil { suspensionValue = refctx.Key.Primary.Suspension.Value @@ -1334,6 +1349,8 @@ func (c *compiler) _compileEdges(refctx *RefContext) { // And their ancestors if !suspensionValue { srcPath, dstPath := e.ID.SrcPath, e.ID.DstPath + + // Make paths absolute if they're relative container := ParentField(e) if container != nil && container.Name.ScalarString() != "root" { containerPath := []d2ast.String{} @@ -1358,6 +1375,7 @@ func (c *compiler) _compileEdges(refctx *RefContext) { srcObj := rootMap.GetField(srcPath...) dstObj := rootMap.GetField(dstPath...) + // Unsuspend source node and all its ancestors if srcObj != nil { srcObj.suspended = false parent := ParentField(srcObj) @@ -1366,9 +1384,11 @@ func (c *compiler) _compileEdges(refctx *RefContext) { parent = ParentField(parent) } } + + // Unsuspend destination node and all its ancestors if dstObj != nil { dstObj.suspended = false - parent := ParentField(srcObj) + parent := ParentField(dstObj) for parent != nil && parent.Name.ScalarString() != "root" { parent.suspended = false parent = ParentField(parent) diff --git a/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.exp.json b/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.exp.json new file mode 100644 index 000000000..70fca048f --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.exp.json @@ -0,0 +1,766 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,0:0:0-13:0:121", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,1:0:1-3:1:11", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,1:3:4-3:1:11", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,2:2:8-2:3:9", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,2:2:8-2:3:9", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,2:2:8-2:3:9", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,4:0:12-6:1:22", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,4:0:12-4:1:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,4:0:12-4:1:13", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,4:3:15-6:1:22", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,5:2:19-5:3:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,5:2:19-5:3:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,5:2:19-5:3:20", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:17:40", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:10:33", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:3:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:1:24", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:2:25-7:3:26", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:7:30-7:10:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:7:30-7:8:31", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:9:32-7:10:33", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:12:35-7:17:40", + "value": [ + { + "string": "likes", + "raw_string": "likes" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,8:0:41-8:11:52", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,8:0:41-8:2:43", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,8:0:41-8:2:43", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,8:4:45-8:11:52", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:0:53-9:22:75", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:1:54-9:9:62", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:1:54-9:3:56", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:1:54-9:3:56", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:7:60-9:9:62", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:7:60-9:9:62", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:10:63-9:13:66", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,9:15:68-9:22:75", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:0:76-12:1:120", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:1:77-10:9:85", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:1:77-10:3:79", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:1:77-10:3:79", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:7:83-10:9:85", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:7:83-10:9:85", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:10:86-10:13:89", + "int": null, + "glob": true + }, + "primary": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:15:91-10:24:100", + "value": false + } + }, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,10:25:101-12:1:120", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,11:2:105-11:15:118", + "ampersand": true, + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,11:3:106-11:8:111", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,11:3:106-11:8:111", + "value": [ + { + "string": "label", + "raw_string": "label" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,11:10:113-11:15:118", + "value": [ + { + "string": "likes", + "raw_string": "likes" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + }, + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "likes" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:3:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:1:24", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:2:25-7:3:26", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,2:2:8-2:3:9", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,2:2:8-2:3:9", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:3:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:0:23-7:1:24", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:2:25-7:3:26", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 1, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "c", + "id_val": "c", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,4:0:12-4:1:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,4:0:12-4:1:13", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:7:30-7:10:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:7:30-7:8:31", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:9:32-7:10:33", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "c" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "d", + "id_val": "d", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,5:2:19-5:3:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,5:2:19-5:3:20", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:7:30-7:10:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:7:30-7:8:31", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-cross-container-edge-label.d2,7:9:32-7:10:33", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "key_path_index": 1, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "d" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.exp.json b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.exp.json new file mode 100644 index 000000000..c3508fbc6 --- /dev/null +++ b/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.exp.json @@ -0,0 +1,577 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,0:0:0-13:0:121", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,1:0:1-3:1:11", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,1:3:4-3:1:11", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,2:2:8-2:3:9", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,2:2:8-2:3:9", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,2:2:8-2:3:9", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,4:0:12-6:1:22", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,4:0:12-4:1:13", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,4:0:12-4:1:13", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,4:3:15-6:1:22", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,5:2:19-5:3:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,5:2:19-5:3:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,5:2:19-5:3:20", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:17:40", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:10:33", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:3:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:1:24", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:2:25-7:3:26", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:7:30-7:10:33", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:7:30-7:8:31", + "value": [ + { + "string": "c", + "raw_string": "c" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:9:32-7:10:33", + "value": [ + { + "string": "d", + "raw_string": "d" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:12:35-7:17:40", + "value": [ + { + "string": "likes", + "raw_string": "likes" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,8:0:41-8:11:52", + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,8:0:41-8:2:43", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,8:0:41-8:2:43", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,8:4:45-8:11:52", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:0:53-9:22:75", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:1:54-9:9:62", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:1:54-9:3:56", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:1:54-9:3:56", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:7:60-9:9:62", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:7:60-9:9:62", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:10:63-9:13:66", + "int": null, + "glob": true + }, + "primary": {}, + "value": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,9:15:68-9:22:75", + "value": true + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:0:76-12:1:120", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:1:77-10:9:85", + "src": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:1:77-10:3:79", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:1:77-10:3:79", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:7:83-10:9:85", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:7:83-10:9:85", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "edge_index": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:10:86-10:13:89", + "int": null, + "glob": true + }, + "primary": { + "suspension": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:15:91-10:24:100", + "value": false + } + }, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,10:25:101-12:1:120", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,11:2:105-11:15:118", + "ampersand": true, + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,11:3:106-11:8:111", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,11:3:106-11:8:111", + "value": [ + { + "string": "label", + "raw_string": "label" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,11:10:113-11:15:118", + "value": [ + { + "string": "likes", + "raw_string": "likes" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,1:0:1-1:1:2", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,1:0:1-1:1:2", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:3:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:1:24", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:2:25-7:3:26", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,2:2:8-2:3:9", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,2:2:8-2:3:9", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:3:26", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:0:23-7:1:24", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-label#01.d2,7:2:25-7:3:26", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 1, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} From 9eba6219d6e729a149a2bd9d417c95445d6570a5 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 13 Mar 2025 11:55:30 -0600 Subject: [PATCH 16/54] fix c4 person dimensions --- .../c4-person-shape/dagre/board.exp.json | 100 +-- .../c4-person-shape/dagre/sketch.exp.svg | 578 ++++++++--------- .../txtar/c4-person-shape/elk/board.exp.json | 82 +-- .../txtar/c4-person-shape/elk/sketch.exp.svg | 578 ++++++++--------- .../txtar/c4-theme/dagre/board.exp.json | 184 +++--- .../txtar/c4-theme/dagre/sketch.exp.svg | 612 +++++++++--------- .../txtar/c4-theme/elk/board.exp.json | 106 +-- .../txtar/c4-theme/elk/sketch.exp.svg | 612 +++++++++--------- .../small-c4-person/dagre/board.exp.json | 2 +- .../small-c4-person/dagre/sketch.exp.svg | 156 ++--- .../txtar/small-c4-person/elk/board.exp.json | 2 +- .../txtar/small-c4-person/elk/sketch.exp.svg | 156 ++--- lib/shape/shape.go | 2 +- lib/shape/shape_c4_person.go | 19 +- 14 files changed, 1596 insertions(+), 1593 deletions(-) diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json index f14fb0556..eb7cde4fb 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 0, - "y": 544 + "y": 612 }, - "width": 312, - "height": 350, + "width": 390, + "height": 468, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -57,11 +57,11 @@ "id": "c4person", "type": "c4-person", "pos": { - "x": 244, + "x": 286, "y": 0 }, - "width": 135, - "height": 152, + "width": 169, + "height": 203, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -99,8 +99,8 @@ "id": "regular_person", "type": "person", "pos": { - "x": 89, - "y": 339 + "x": 128, + "y": 399 }, "width": 134, "height": 89, @@ -141,11 +141,11 @@ "id": "styling", "type": "rectangle", "pos": { - "x": 362, - "y": 293 + "x": 440, + "y": 344 }, "width": 210, - "height": 546, + "height": 622, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -183,11 +183,11 @@ "id": "styling.c4styled", "type": "c4-person", "pos": { - "x": 425, - "y": 323 + "x": 492, + "y": 374 }, - "width": 85, - "height": 121, + "width": 107, + "height": 138, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -225,8 +225,8 @@ "id": "styling.c4sized", "type": "c4-person", "pos": { - "x": 392, - "y": 629 + "x": 470, + "y": 756 }, "width": 150, "height": 180, @@ -291,20 +291,20 @@ "link": "", "route": [ { - "x": 156, - "y": 454 + "x": 195, + "y": 514 }, { - "x": 156, - "y": 486 + "x": 195, + "y": 552.4000244140625 }, { - "x": 156, - "y": 502.79998779296875 + "x": 195, + "y": 571.5999755859375 }, { - "x": 156, - "y": 538 + "x": 195, + "y": 610 } ], "isCurve": true, @@ -339,20 +339,20 @@ "link": "", "route": [ { - "x": 245, - "y": 135 + "x": 287, + "y": 179 }, { - "x": 173.8000030517578, - "y": 197 + "x": 213.3990020751953, + "y": 246.60000610351562 }, { - "x": 156, - "y": 286.20001220703125 - }, - { - "x": 156, + "x": 195, "y": 339 + }, + { + "x": 195, + "y": 399 } ], "isCurve": true, @@ -387,20 +387,20 @@ "link": "", "route": [ { - "x": 379, - "y": 135 + "x": 455, + "y": 180 }, { - "x": 449.3999938964844, - "y": 197 + "x": 527, + "y": 246.8000030517578 }, { - "x": 467, - "y": 283.6000061035156 + "x": 545, + "y": 334.20001220703125 }, { - "x": 467, - "y": 326 + "x": 545, + "y": 375 } ], "isCurve": true, @@ -435,20 +435,20 @@ "link": "", "route": [ { - "x": 467, - "y": 445 + "x": 545, + "y": 512 }, { - "x": 467, - "y": 484.20001220703125 + "x": 545, + "y": 552 }, { - "x": 467, - "y": 520.7990112304688 + "x": 545, + "y": 600.5999755859375 }, { - "x": 467, - "y": 628 + "x": 545, + "y": 755 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg index 395dc0e3d..4965fde2b 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json index c9290285f..7c12572db 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 12, - "y": 975 + "y": 1043 }, - "width": 312, - "height": 350, + "width": 390, + "height": 468, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -57,11 +57,11 @@ "id": "c4person", "type": "c4-person", "pos": { - "x": 201, + "x": 223, "y": 12 }, - "width": 135, - "height": 152, + "width": 169, + "height": 203, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -99,8 +99,8 @@ "id": "regular_person", "type": "person", "pos": { - "x": 101, - "y": 790 + "x": 140, + "y": 858 }, "width": 134, "height": 89, @@ -141,11 +141,11 @@ "id": "styling", "type": "rectangle", "pos": { - "x": 244, - "y": 249 + "x": 283, + "y": 300 }, "width": 250, - "height": 471, + "height": 488, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -183,11 +183,11 @@ "id": "styling.c4styled", "type": "c4-person", "pos": { - "x": 327, - "y": 299 + "x": 355, + "y": 350 }, - "width": 85, - "height": 121, + "width": 107, + "height": 138, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -225,8 +225,8 @@ "id": "styling.c4sized", "type": "c4-person", "pos": { - "x": 294, - "y": 490 + "x": 333, + "y": 558 }, "width": 150, "height": 180, @@ -291,12 +291,12 @@ "link": "", "route": [ { - "x": 168, - "y": 905 + "x": 207, + "y": 973 }, { - "x": 168, - "y": 969 + "x": 207, + "y": 1041 } ], "animated": false, @@ -330,20 +330,20 @@ "link": "", "route": [ { - "x": 246, - "y": 165 + "x": 280, + "y": 216 }, { - "x": 246.25, - "y": 204 + "x": 279.5830078125, + "y": 255 }, { - "x": 168, - "y": 204 + "x": 207, + "y": 255 }, { - "x": 168, - "y": 790 + "x": 207, + "y": 858 } ], "animated": false, @@ -377,20 +377,20 @@ "link": "", "route": [ { - "x": 291, - "y": 165 + "x": 336, + "y": 216 }, { - "x": 291.25, - "y": 204 + "x": 335.9159851074219, + "y": 255 }, { - "x": 369.5, - "y": 204 + "x": 408.5, + "y": 255 }, { - "x": 370, - "y": 302 + "x": 409, + "y": 351 } ], "animated": false, @@ -424,12 +424,12 @@ "link": "", "route": [ { - "x": 369, - "y": 421 + "x": 408, + "y": 488 }, { - "x": 370, - "y": 489 + "x": 409, + "y": 557 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg index d04252bfb..08e6f0148 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json index bdb6871ab..372879a1c 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json @@ -15,11 +15,11 @@ "id": "customer", "type": "c4-person", "pos": { - "x": 1105, + "x": 1057, "y": 0 }, - "width": 383, - "height": 429, + "width": 479, + "height": 575, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 147, - "y": 586 + "y": 732 }, "width": 2407, "height": 915, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 177, - "y": 616 + "y": 762 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 390, - "y": 901 + "y": 1047 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 1123, - "y": 901 + "y": 1047 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 1246, - "y": 1202 + "y": 1348 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1890, - "y": 901 + "y": 1047 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 2410, - "y": 1638 + "y": 1784 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 0, - "y": 1638 + "y": 1784 }, "width": 629, "height": 164, @@ -417,20 +417,20 @@ "link": "", "route": [ { - "x": 1105, - "y": 279 + "x": 1057, + "y": 388 }, { - "x": 582.5999755859375, - "y": 453.79998779296875 + "x": 573, + "y": 592.4000244140625 }, { "x": 452, - "y": 576 + "y": 722 }, { "x": 452, - "y": 616 + "y": 762 } ], "isCurve": true, @@ -466,19 +466,19 @@ "route": [ { "x": 452, - "y": 779.5 + "y": 925.5 }, { "x": 452, - "y": 828.2999877929688 + "y": 974.2999877929688 }, { "x": 472.3999938964844, - "y": 852.7000122070312 + "y": 998.7000122070312 }, { "x": 554, - "y": 901.5 + "y": 1047.5 } ], "isCurve": true, @@ -513,44 +513,44 @@ "link": "", "route": [ { - "x": 1105, - "y": 365 + "x": 1063, + "y": 519 }, { - "x": 970.5999755859375, - "y": 471 + "x": 962.2000122070312, + "y": 618.5999755859375 }, { "x": 937, - "y": 511.20001220703125 + "y": 657.2000122070312 }, { "x": 937, - "y": 531.75 + "y": 677.75 }, { "x": 937, - "y": 552.2999877929688 + "y": 698.2999877929688 }, { "x": 937, - "y": 592.4000244140625 + "y": 738.4000244140625 }, { "x": 937, - "y": 632 + "y": 778 }, { "x": 937, - "y": 671.5999755859375 + "y": 817.5999755859375 }, { "x": 916.5999755859375, - "y": 852.7000122070312 + "y": 998.7000122070312 }, { "x": 835, - "y": 901.5 + "y": 1047.5 } ], "isCurve": true, @@ -585,44 +585,44 @@ "link": "", "route": [ { - "x": 1432, - "y": 428 + "x": 1442, + "y": 576 }, { - "x": 1467.199951171875, - "y": 483.6000061035156 + "x": 1469.199951171875, + "y": 630 }, { "x": 1476, - "y": 511.20001220703125 + "y": 657.2000122070312 }, { "x": 1476, - "y": 531.75 + "y": 677.75 }, { "x": 1476, - "y": 552.2999877929688 + "y": 698.2999877929688 }, { "x": 1476, - "y": 592.4000244140625 + "y": 738.4000244140625 }, { "x": 1476, - "y": 632 + "y": 778 }, { "x": 1476, - "y": 671.5999755859375 + "y": 817.5999755859375 }, { "x": 1476, - "y": 852.7000122070312 + "y": 998.7000122070312 }, { "x": 1476, - "y": 901.5 + "y": 1047.5 } ], "isCurve": true, @@ -658,19 +658,19 @@ "route": [ { "x": 694.5, - "y": 1064.5 + "y": 1210.5 }, { "x": 694.5, - "y": 1119.699951171875 + "y": 1265.699951171875 }, { "x": 804.7000122070312, - "y": 1154.7220458984375 + "y": 1300.7220458984375 }, { "x": 1245.5, - "y": 1239.6099853515625 + "y": 1385.6099853515625 } ], "isCurve": true, @@ -706,19 +706,19 @@ "route": [ { "x": 1476, - "y": 1064.5 + "y": 1210.5 }, { "x": 1476, - "y": 1119.699951171875 + "y": 1265.699951171875 }, { "x": 1476, - "y": 1147.300048828125 + "y": 1293.300048828125 }, { "x": 1476, - "y": 1202.5 + "y": 1348.5 } ], "isCurve": true, @@ -754,19 +754,19 @@ "route": [ { "x": 1245.5, - "y": 1310.1949462890625 + "y": 1456.1949462890625 }, { "x": 500.6990051269531, - "y": 1462.8389892578125 + "y": 1608.8389892578125 }, { "x": 314.5, - "y": 1583.300048828125 + "y": 1729.300048828125 }, { "x": 314.5, - "y": 1638.5 + "y": 1784.5 } ], "isCurve": true, @@ -801,104 +801,104 @@ "link": "", "route": [ { - "x": 1488, - "y": 255 + "x": 1536, + "y": 351 }, { - "x": 2407.199951171875, - "y": 449 + "x": 2416.800048828125, + "y": 585 }, { "x": 2637, - "y": 511.20001220703125 + "y": 657.2000122070312 }, { "x": 2637, - "y": 531.75 + "y": 677.75 }, { "x": 2637, - "y": 552.2999877929688 + "y": 698.2999877929688 }, { "x": 2637, - "y": 592.4000244140625 + "y": 738.4000244140625 }, { "x": 2637, - "y": 632 + "y": 778 }, { "x": 2637, - "y": 671.5999755859375 + "y": 817.5999755859375 }, { "x": 2637, - "y": 726.5 + "y": 872.5 }, { "x": 2637, - "y": 769.25 + "y": 915.25 }, { "x": 2637, - "y": 812 + "y": 958 }, { "x": 2637, - "y": 869 + "y": 1015 }, { "x": 2637, - "y": 911.75 + "y": 1057.75 }, { "x": 2637, - "y": 954.5 + "y": 1100.5 }, { "x": 2637, - "y": 1013.0999755859375 + "y": 1159.0999755859375 }, { "x": 2637, - "y": 1058.25 + "y": 1204.25 }, { "x": 2637, - "y": 1103.4000244140625 + "y": 1249.4000244140625 }, { "x": 2637, - "y": 1163.5999755859375 + "y": 1309.5999755859375 }, { "x": 2637, - "y": 1208.75 + "y": 1354.75 }, { "x": 2637, - "y": 1253.9000244140625 + "y": 1399.9000244140625 }, { "x": 2637, - "y": 1327.4000244140625 + "y": 1473.4000244140625 }, { "x": 2637, - "y": 1392.5 + "y": 1538.5 }, { "x": 2637, - "y": 1457.5999755859375 + "y": 1603.5999755859375 }, { "x": 2632.800048828125, - "y": 1583.300048828125 + "y": 1729.300048828125 }, { "x": 2616, - "y": 1638.5 + "y": 1784.5 } ], "isCurve": true, @@ -934,19 +934,19 @@ "route": [ { "x": 1707.5, - "y": 1317.843994140625 + "y": 1463.843994140625 }, { "x": 2241.5, - "y": 1464.3680419921875 + "y": 1610.3680419921875 }, { "x": 2394.39990234375, - "y": 1583.300048828125 + "y": 1729.300048828125 }, { "x": 2472, - "y": 1638.5 + "y": 1784.5 } ], "isCurve": true, @@ -982,19 +982,19 @@ "route": [ { "x": 2206.5, - "y": 1064.5 + "y": 1210.5 }, { "x": 2206.5, - "y": 1119.699951171875 + "y": 1265.699951171875 }, { "x": 2106.5, - "y": 1154.0999755859375 + "y": 1300.0999755859375 }, { "x": 1706.5, - "y": 1236.5 + "y": 1382.5 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg index 1982bf242..48ce9e34b 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json index d2a3bd3f0..1753ba0a8 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json @@ -15,11 +15,11 @@ "id": "customer", "type": "c4-person", "pos": { - "x": 720, + "x": 672, "y": 12 }, - "width": 383, - "height": 429, + "width": 479, + "height": 575, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 12, - "y": 693 + "y": 839 }, "width": 2218, "height": 1035, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 62, - "y": 743 + "y": 889 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 190, - "y": 1078 + "y": 1224 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 819, - "y": 1078 + "y": 1224 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 942, - "y": 1429 + "y": 1575 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1546, - "y": 1078 + "y": 1224 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 1746, - "y": 1930 + "y": 2076 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 781, - "y": 1930 + "y": 2076 }, "width": 629, "height": 164, @@ -417,20 +417,20 @@ "link": "", "route": [ { - "x": 797, - "y": 441 + "x": 769, + "y": 588 }, { - "x": 797.3499755859375, - "y": 481 + "x": 768.5499877929688, + "y": 627 }, { "x": 359.25, - "y": 481 + "y": 627 }, { "x": 359.25, - "y": 743 + "y": 889 } ], "animated": false, @@ -465,11 +465,11 @@ "route": [ { "x": 393, - "y": 907 + "y": 1053 }, { "x": 393, - "y": 1078 + "y": 1224 } ], "animated": false, @@ -503,20 +503,20 @@ "link": "", "route": [ { - "x": 874, - "y": 441 + "x": 864, + "y": 588 }, { - "x": 873.9500122070312, - "y": 531 + "x": 864.3499755859375, + "y": 677 }, { "x": 652, - "y": 531 + "y": 677 }, { "x": 652, - "y": 1078 + "y": 1224 } ], "animated": false, @@ -550,12 +550,12 @@ "link": "", "route": [ { - "x": 951, - "y": 441 + "x": 960, + "y": 588 }, { - "x": 950.5499877929688, - "y": 1078 + "x": 960.1500244140625, + "y": 1224 } ], "animated": false, @@ -590,19 +590,19 @@ "route": [ { "x": 494.5, - "y": 1242 + "y": 1388 }, { "x": 494.5, - "y": 1389 + "y": 1535 }, { "x": 1057.25, - "y": 1389 + "y": 1535 }, { "x": 1057.25, - "y": 1429 + "y": 1575 } ], "animated": false, @@ -637,11 +637,11 @@ "route": [ { "x": 1172.5, - "y": 1242 + "y": 1388 }, { "x": 1172.5, - "y": 1429 + "y": 1575 } ], "animated": false, @@ -676,11 +676,11 @@ "route": [ { "x": 1095.666015625, - "y": 1593 + "y": 1739 }, { "x": 1095.666015625, - "y": 1930 + "y": 2076 } ], "animated": false, @@ -714,28 +714,28 @@ "link": "", "route": [ { - "x": 1027, - "y": 441 + "x": 1056, + "y": 588 }, { - "x": 1027.1500244140625, - "y": 481 + "x": 1055.948974609375, + "y": 627 }, { "x": 2303.5, - "y": 481 + "y": 627 }, { "x": 2303.5, - "y": 1890 + "y": 2036 }, { "x": 1986.8330078125, - "y": 1890 + "y": 2036 }, { "x": 1986.8330078125, - "y": 1930 + "y": 2076 } ], "animated": false, @@ -770,19 +770,19 @@ "route": [ { "x": 1249.3330078125, - "y": 1593 + "y": 1739 }, { "x": 1249.3330078125, - "y": 1890 + "y": 2036 }, { "x": 1866.8330078125, - "y": 1890 + "y": 2036 }, { "x": 1866.8330078125, - "y": 1930 + "y": 2076 } ], "animated": false, @@ -817,19 +817,19 @@ "route": [ { "x": 1863, - "y": 1242 + "y": 1388 }, { "x": 1863, - "y": 1389 + "y": 1535 }, { "x": 1287.75, - "y": 1389 + "y": 1535 }, { "x": 1287.75, - "y": 1429 + "y": 1575 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg index 52d5d51f4..66502edd6 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json index be4ffa74e..678575f50 100644 --- a/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json +++ b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json @@ -19,7 +19,7 @@ "y": 0 }, "width": 180, - "height": 114, + "height": 126, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg index afeff911b..68df2d2e2 100644 --- a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg @@ -1,9 +1,9 @@ -c4-person - - + .d2-144415964 .fill-N1{fill:#0A0F25;} + .d2-144415964 .fill-N2{fill:#676C7E;} + .d2-144415964 .fill-N3{fill:#9499AB;} + .d2-144415964 .fill-N4{fill:#CFD2DD;} + .d2-144415964 .fill-N5{fill:#DEE1EB;} + .d2-144415964 .fill-N6{fill:#EEF1F8;} + .d2-144415964 .fill-N7{fill:#FFFFFF;} + .d2-144415964 .fill-B1{fill:#0D32B2;} + .d2-144415964 .fill-B2{fill:#0D32B2;} + .d2-144415964 .fill-B3{fill:#E3E9FD;} + .d2-144415964 .fill-B4{fill:#E3E9FD;} + .d2-144415964 .fill-B5{fill:#EDF0FD;} + .d2-144415964 .fill-B6{fill:#F7F8FE;} + .d2-144415964 .fill-AA2{fill:#4A6FF3;} + .d2-144415964 .fill-AA4{fill:#EDF0FD;} + .d2-144415964 .fill-AA5{fill:#F7F8FE;} + .d2-144415964 .fill-AB4{fill:#EDF0FD;} + .d2-144415964 .fill-AB5{fill:#F7F8FE;} + .d2-144415964 .stroke-N1{stroke:#0A0F25;} + .d2-144415964 .stroke-N2{stroke:#676C7E;} + .d2-144415964 .stroke-N3{stroke:#9499AB;} + .d2-144415964 .stroke-N4{stroke:#CFD2DD;} + .d2-144415964 .stroke-N5{stroke:#DEE1EB;} + .d2-144415964 .stroke-N6{stroke:#EEF1F8;} + .d2-144415964 .stroke-N7{stroke:#FFFFFF;} + .d2-144415964 .stroke-B1{stroke:#0D32B2;} + .d2-144415964 .stroke-B2{stroke:#0D32B2;} + .d2-144415964 .stroke-B3{stroke:#E3E9FD;} + .d2-144415964 .stroke-B4{stroke:#E3E9FD;} + .d2-144415964 .stroke-B5{stroke:#EDF0FD;} + .d2-144415964 .stroke-B6{stroke:#F7F8FE;} + .d2-144415964 .stroke-AA2{stroke:#4A6FF3;} + .d2-144415964 .stroke-AA4{stroke:#EDF0FD;} + .d2-144415964 .stroke-AA5{stroke:#F7F8FE;} + .d2-144415964 .stroke-AB4{stroke:#EDF0FD;} + .d2-144415964 .stroke-AB5{stroke:#F7F8FE;} + .d2-144415964 .background-color-N1{background-color:#0A0F25;} + .d2-144415964 .background-color-N2{background-color:#676C7E;} + .d2-144415964 .background-color-N3{background-color:#9499AB;} + .d2-144415964 .background-color-N4{background-color:#CFD2DD;} + .d2-144415964 .background-color-N5{background-color:#DEE1EB;} + .d2-144415964 .background-color-N6{background-color:#EEF1F8;} + .d2-144415964 .background-color-N7{background-color:#FFFFFF;} + .d2-144415964 .background-color-B1{background-color:#0D32B2;} + .d2-144415964 .background-color-B2{background-color:#0D32B2;} + .d2-144415964 .background-color-B3{background-color:#E3E9FD;} + .d2-144415964 .background-color-B4{background-color:#E3E9FD;} + .d2-144415964 .background-color-B5{background-color:#EDF0FD;} + .d2-144415964 .background-color-B6{background-color:#F7F8FE;} + .d2-144415964 .background-color-AA2{background-color:#4A6FF3;} + .d2-144415964 .background-color-AA4{background-color:#EDF0FD;} + .d2-144415964 .background-color-AA5{background-color:#F7F8FE;} + .d2-144415964 .background-color-AB4{background-color:#EDF0FD;} + .d2-144415964 .background-color-AB5{background-color:#F7F8FE;} + .d2-144415964 .color-N1{color:#0A0F25;} + .d2-144415964 .color-N2{color:#676C7E;} + .d2-144415964 .color-N3{color:#9499AB;} + .d2-144415964 .color-N4{color:#CFD2DD;} + .d2-144415964 .color-N5{color:#DEE1EB;} + .d2-144415964 .color-N6{color:#EEF1F8;} + .d2-144415964 .color-N7{color:#FFFFFF;} + .d2-144415964 .color-B1{color:#0D32B2;} + .d2-144415964 .color-B2{color:#0D32B2;} + .d2-144415964 .color-B3{color:#E3E9FD;} + .d2-144415964 .color-B4{color:#E3E9FD;} + .d2-144415964 .color-B5{color:#EDF0FD;} + .d2-144415964 .color-B6{color:#F7F8FE;} + .d2-144415964 .color-AA2{color:#4A6FF3;} + .d2-144415964 .color-AA4{color:#EDF0FD;} + .d2-144415964 .color-AA5{color:#F7F8FE;} + .d2-144415964 .color-AB4{color:#EDF0FD;} + .d2-144415964 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-144415964);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-144415964);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-144415964);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-144415964);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-144415964);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-144415964);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-144415964);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-144415964);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-144415964);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-144415964);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-144415964);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-144415964);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-144415964);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-144415964);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-144415964);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-144415964);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-144415964);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-144415964);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + + \ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json index 899afe63f..90602f386 100644 --- a/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json +++ b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json @@ -19,7 +19,7 @@ "y": 12 }, "width": 180, - "height": 114, + "height": 126, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg index 68477ef9d..3a19838ab 100644 --- a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg @@ -1,9 +1,9 @@ -c4-person - - + .d2-1179796372 .fill-N1{fill:#0A0F25;} + .d2-1179796372 .fill-N2{fill:#676C7E;} + .d2-1179796372 .fill-N3{fill:#9499AB;} + .d2-1179796372 .fill-N4{fill:#CFD2DD;} + .d2-1179796372 .fill-N5{fill:#DEE1EB;} + .d2-1179796372 .fill-N6{fill:#EEF1F8;} + .d2-1179796372 .fill-N7{fill:#FFFFFF;} + .d2-1179796372 .fill-B1{fill:#0D32B2;} + .d2-1179796372 .fill-B2{fill:#0D32B2;} + .d2-1179796372 .fill-B3{fill:#E3E9FD;} + .d2-1179796372 .fill-B4{fill:#E3E9FD;} + .d2-1179796372 .fill-B5{fill:#EDF0FD;} + .d2-1179796372 .fill-B6{fill:#F7F8FE;} + .d2-1179796372 .fill-AA2{fill:#4A6FF3;} + .d2-1179796372 .fill-AA4{fill:#EDF0FD;} + .d2-1179796372 .fill-AA5{fill:#F7F8FE;} + .d2-1179796372 .fill-AB4{fill:#EDF0FD;} + .d2-1179796372 .fill-AB5{fill:#F7F8FE;} + .d2-1179796372 .stroke-N1{stroke:#0A0F25;} + .d2-1179796372 .stroke-N2{stroke:#676C7E;} + .d2-1179796372 .stroke-N3{stroke:#9499AB;} + .d2-1179796372 .stroke-N4{stroke:#CFD2DD;} + .d2-1179796372 .stroke-N5{stroke:#DEE1EB;} + .d2-1179796372 .stroke-N6{stroke:#EEF1F8;} + .d2-1179796372 .stroke-N7{stroke:#FFFFFF;} + .d2-1179796372 .stroke-B1{stroke:#0D32B2;} + .d2-1179796372 .stroke-B2{stroke:#0D32B2;} + .d2-1179796372 .stroke-B3{stroke:#E3E9FD;} + .d2-1179796372 .stroke-B4{stroke:#E3E9FD;} + .d2-1179796372 .stroke-B5{stroke:#EDF0FD;} + .d2-1179796372 .stroke-B6{stroke:#F7F8FE;} + .d2-1179796372 .stroke-AA2{stroke:#4A6FF3;} + .d2-1179796372 .stroke-AA4{stroke:#EDF0FD;} + .d2-1179796372 .stroke-AA5{stroke:#F7F8FE;} + .d2-1179796372 .stroke-AB4{stroke:#EDF0FD;} + .d2-1179796372 .stroke-AB5{stroke:#F7F8FE;} + .d2-1179796372 .background-color-N1{background-color:#0A0F25;} + .d2-1179796372 .background-color-N2{background-color:#676C7E;} + .d2-1179796372 .background-color-N3{background-color:#9499AB;} + .d2-1179796372 .background-color-N4{background-color:#CFD2DD;} + .d2-1179796372 .background-color-N5{background-color:#DEE1EB;} + .d2-1179796372 .background-color-N6{background-color:#EEF1F8;} + .d2-1179796372 .background-color-N7{background-color:#FFFFFF;} + .d2-1179796372 .background-color-B1{background-color:#0D32B2;} + .d2-1179796372 .background-color-B2{background-color:#0D32B2;} + .d2-1179796372 .background-color-B3{background-color:#E3E9FD;} + .d2-1179796372 .background-color-B4{background-color:#E3E9FD;} + .d2-1179796372 .background-color-B5{background-color:#EDF0FD;} + .d2-1179796372 .background-color-B6{background-color:#F7F8FE;} + .d2-1179796372 .background-color-AA2{background-color:#4A6FF3;} + .d2-1179796372 .background-color-AA4{background-color:#EDF0FD;} + .d2-1179796372 .background-color-AA5{background-color:#F7F8FE;} + .d2-1179796372 .background-color-AB4{background-color:#EDF0FD;} + .d2-1179796372 .background-color-AB5{background-color:#F7F8FE;} + .d2-1179796372 .color-N1{color:#0A0F25;} + .d2-1179796372 .color-N2{color:#676C7E;} + .d2-1179796372 .color-N3{color:#9499AB;} + .d2-1179796372 .color-N4{color:#CFD2DD;} + .d2-1179796372 .color-N5{color:#DEE1EB;} + .d2-1179796372 .color-N6{color:#EEF1F8;} + .d2-1179796372 .color-N7{color:#FFFFFF;} + .d2-1179796372 .color-B1{color:#0D32B2;} + .d2-1179796372 .color-B2{color:#0D32B2;} + .d2-1179796372 .color-B3{color:#E3E9FD;} + .d2-1179796372 .color-B4{color:#E3E9FD;} + .d2-1179796372 .color-B5{color:#EDF0FD;} + .d2-1179796372 .color-B6{color:#F7F8FE;} + .d2-1179796372 .color-AA2{color:#4A6FF3;} + .d2-1179796372 .color-AA4{color:#EDF0FD;} + .d2-1179796372 .color-AA5{color:#F7F8FE;} + .d2-1179796372 .color-AB4{color:#EDF0FD;} + .d2-1179796372 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-1179796372);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-1179796372);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-1179796372);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-1179796372);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1179796372);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1179796372);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-1179796372);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-1179796372);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1179796372);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-1179796372);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1179796372);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1179796372);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1179796372);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1179796372);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1179796372);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-1179796372);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1179796372);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1179796372);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + + \ No newline at end of file diff --git a/lib/shape/shape.go b/lib/shape/shape.go index 6e3e0b81b..6dd6cec7a 100644 --- a/lib/shape/shape.go +++ b/lib/shape/shape.go @@ -21,7 +21,7 @@ const ( CALLOUT_TYPE = "Callout" STORED_DATA_TYPE = "StoredData" PERSON_TYPE = "Person" - C4_PERSON_TYPE = "c4-person" + C4_PERSON_TYPE = "C4Person" DIAMOND_TYPE = "Diamond" OVAL_TYPE = "Oval" CIRCLE_TYPE = "Circle" diff --git a/lib/shape/shape_c4_person.go b/lib/shape/shape_c4_person.go index 8535c5b79..673afbf8f 100644 --- a/lib/shape/shape_c4_person.go +++ b/lib/shape/shape_c4_person.go @@ -138,16 +138,19 @@ func (s shapeC4Person) GetSVGPathData() []string { } func (s shapeC4Person) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { - totalWidth := width + paddingX - totalHeight := height + paddingY - - if totalHeight < totalWidth*0.8 { - totalHeight = totalWidth * 0.8 + contentWidth := width + paddingX + contentHeight := height + paddingY + totalWidth := contentWidth / 0.8 + headRadius := totalWidth * 0.22 + bodyTop := totalWidth*0.18 + headRadius*0.8 + verticalPaddingRatio := 0.1 // 5% top + 5% bottom + totalHeight := (contentHeight + bodyTop) / (1 - verticalPaddingRatio) + minHeight := totalWidth * 1.2 + if totalHeight < minHeight { + totalHeight = minHeight } - - totalHeight *= 1.4 - totalWidth, totalHeight = LimitAR(totalWidth, totalHeight, C4_PERSON_AR_LIMIT) + return math.Ceil(totalWidth), math.Ceil(totalHeight) } From 1153b11e3579d9389f69bc9c1e740a2fc6f2b1c7 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 13 Mar 2025 12:20:34 -0600 Subject: [PATCH 17/54] fix c4 person --- .../c4-person-label/dagre/board.exp.json | 183 ++++ .../c4-person-label/dagre/sketch.exp.svg | 846 ++++++++++++++++++ .../txtar/c4-person-label/elk/board.exp.json | 183 ++++ .../txtar/c4-person-label/elk/sketch.exp.svg | 846 ++++++++++++++++++ .../c4-person-shape/dagre/board.exp.json | 98 +- .../c4-person-shape/dagre/sketch.exp.svg | 578 ++++++------ .../txtar/c4-person-shape/elk/board.exp.json | 82 +- .../txtar/c4-person-shape/elk/sketch.exp.svg | 578 ++++++------ .../txtar/c4-theme/dagre/board.exp.json | 184 ++-- .../txtar/c4-theme/dagre/sketch.exp.svg | 612 ++++++------- .../txtar/c4-theme/elk/board.exp.json | 106 +-- .../txtar/c4-theme/elk/sketch.exp.svg | 612 ++++++------- .../small-c4-person/dagre/board.exp.json | 2 +- .../small-c4-person/dagre/sketch.exp.svg | 156 ++-- .../txtar/small-c4-person/elk/board.exp.json | 2 +- .../txtar/small-c4-person/elk/sketch.exp.svg | 156 ++-- e2etests/txtar.txt | 34 + lib/shape/shape_c4_person.go | 33 +- 18 files changed, 3698 insertions(+), 1593 deletions(-) create mode 100644 e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json create mode 100644 e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg create mode 100644 e2etests/testdata/txtar/c4-person-label/elk/board.exp.json create mode 100644 e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json new file mode 100644 index 000000000..cfb656f9b --- /dev/null +++ b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json @@ -0,0 +1,183 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "c4mdperson", + "type": "c4-person", + "pos": { + "x": 0, + "y": 0 + }, + "width": 422, + "height": 506, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n\n[person]\n\nA customer of the bank, with personal bank accounts", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 354, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c4mdperson2", + "type": "c4-person", + "pos": { + "x": 482, + "y": 0 + }, + "width": 422, + "height": 506, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n\n[person]\n\nA customer of the bank, with personal bank accounts", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 354, + "labelHeight": 119, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c4mdperson3", + "type": "c4-person", + "pos": { + "x": 964, + "y": 0 + }, + "width": 422, + "height": 506, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n\n[person]\n\nA customer of the bank, with personal bank accounts", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 354, + "labelHeight": 119, + "labelPosition": "INSIDE_BOTTOM_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg new file mode 100644 index 000000000..0acadd4be --- /dev/null +++ b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg @@ -0,0 +1,846 @@ +

Personal Banking Customer

+

[person]

+

A customer of the bank, with personal bank accounts

+

Personal Banking Customer

+

[person]

+

A customer of the bank, with personal bank accounts

+

Personal Banking Customer

+

[person]

+

A customer of the bank, with personal bank accounts

+
+ + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json new file mode 100644 index 000000000..1767158d2 --- /dev/null +++ b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json @@ -0,0 +1,183 @@ +{ + "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "c4mdperson", + "type": "c4-person", + "pos": { + "x": 12, + "y": 12 + }, + "width": 422, + "height": 506, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n\n[person]\n\nA customer of the bank, with personal bank accounts", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 354, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c4mdperson2", + "type": "c4-person", + "pos": { + "x": 454, + "y": 12 + }, + "width": 422, + "height": 506, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n\n[person]\n\nA customer of the bank, with personal bank accounts", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 354, + "labelHeight": 119, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "c4mdperson3", + "type": "c4-person", + "pos": { + "x": 896, + "y": 12 + }, + "width": 422, + "height": 506, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n\n[person]\n\nA customer of the bank, with personal bank accounts", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 354, + "labelHeight": 119, + "labelPosition": "INSIDE_BOTTOM_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "zIndex": 0, + "level": 0 + } +} diff --git a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg new file mode 100644 index 000000000..cef62e084 --- /dev/null +++ b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg @@ -0,0 +1,846 @@ +

Personal Banking Customer

+

[person]

+

A customer of the bank, with personal bank accounts

+

Personal Banking Customer

+

[person]

+

A customer of the bank, with personal bank accounts

+

Personal Banking Customer

+

[person]

+

A customer of the bank, with personal bank accounts

+
+ + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json index eb7cde4fb..7fa64364e 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 0, - "y": 612 + "y": 577 }, - "width": 390, - "height": 468, + "width": 347, + "height": 416, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -57,11 +57,11 @@ "id": "c4person", "type": "c4-person", "pos": { - "x": 286, + "x": 263, "y": 0 }, - "width": 169, - "height": 203, + "width": 150, + "height": 180, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -99,8 +99,8 @@ "id": "regular_person", "type": "person", "pos": { - "x": 128, - "y": 399 + "x": 107, + "y": 370 }, "width": 134, "height": 89, @@ -141,11 +141,11 @@ "id": "styling", "type": "rectangle", "pos": { - "x": 440, - "y": 344 + "x": 397, + "y": 321 }, "width": 210, - "height": 622, + "height": 584, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -183,11 +183,11 @@ "id": "styling.c4styled", "type": "c4-person", "pos": { - "x": 492, - "y": 374 + "x": 455, + "y": 351 }, - "width": 107, - "height": 138, + "width": 95, + "height": 126, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -225,8 +225,8 @@ "id": "styling.c4sized", "type": "c4-person", "pos": { - "x": 470, - "y": 756 + "x": 427, + "y": 695 }, "width": 150, "height": 180, @@ -291,20 +291,20 @@ "link": "", "route": [ { - "x": 195, - "y": 514 + "x": 173.5, + "y": 485 }, { - "x": 195, - "y": 552.4000244140625 + "x": 173.5, + "y": 518.5999755859375 }, { - "x": 195, - "y": 571.5999755859375 + "x": 173.60000610351562, + "y": 536.7999877929688 }, { - "x": 195, - "y": 610 + "x": 174, + "y": 576 } ], "isCurve": true, @@ -339,20 +339,20 @@ "link": "", "route": [ { - "x": 287, - "y": 179 + "x": 264, + "y": 157 }, { - "x": 213.3990020751953, - "y": 246.60000610351562 + "x": 191.60000610351562, + "y": 223.8000030517578 }, { - "x": 195, - "y": 339 + "x": 173.60000610351562, + "y": 314.79998779296875 }, { - "x": 195, - "y": 399 + "x": 174, + "y": 370 } ], "isCurve": true, @@ -387,20 +387,20 @@ "link": "", "route": [ { - "x": 455, - "y": 180 + "x": 413, + "y": 158 }, { - "x": 527, - "y": 246.8000030517578 + "x": 484.20001220703125, + "y": 224 }, { - "x": 545, - "y": 334.20001220703125 + "x": 502, + "y": 311.3999938964844 }, { - "x": 545, - "y": 375 + "x": 502, + "y": 353 } ], "isCurve": true, @@ -435,20 +435,20 @@ "link": "", "route": [ { - "x": 545, - "y": 512 + "x": 502, + "y": 477 }, { - "x": 545, - "y": 552 + "x": 502, + "y": 517 }, { - "x": 545, - "y": 600.5999755859375 + "x": 502, + "y": 560.4000244140625 }, { - "x": 545, - "y": 755 + "x": 502, + "y": 694 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg index 4965fde2b..735587575 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json index 7c12572db..9fea05c01 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 12, - "y": 1043 + "y": 1008 }, - "width": 390, - "height": 468, + "width": 347, + "height": 416, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -57,11 +57,11 @@ "id": "c4person", "type": "c4-person", "pos": { - "x": 223, + "x": 211, "y": 12 }, - "width": 169, - "height": 203, + "width": 150, + "height": 180, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -99,8 +99,8 @@ "id": "regular_person", "type": "person", "pos": { - "x": 140, - "y": 858 + "x": 118, + "y": 823 }, "width": 134, "height": 89, @@ -141,11 +141,11 @@ "id": "styling", "type": "rectangle", "pos": { - "x": 283, - "y": 300 + "x": 262, + "y": 277 }, "width": 250, - "height": 488, + "height": 476, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -183,11 +183,11 @@ "id": "styling.c4styled", "type": "c4-person", "pos": { - "x": 355, - "y": 350 + "x": 339, + "y": 327 }, - "width": 107, - "height": 138, + "width": 95, + "height": 126, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -225,8 +225,8 @@ "id": "styling.c4sized", "type": "c4-person", "pos": { - "x": 333, - "y": 558 + "x": 312, + "y": 523 }, "width": 150, "height": 180, @@ -291,12 +291,12 @@ "link": "", "route": [ { - "x": 207, - "y": 973 + "x": 185.5, + "y": 938 }, { - "x": 207, - "y": 1041 + "x": 186, + "y": 1007 } ], "animated": false, @@ -330,20 +330,20 @@ "link": "", "route": [ { - "x": 280, - "y": 216 + "x": 261, + "y": 192 }, { - "x": 279.5830078125, - "y": 255 + "x": 261.25, + "y": 232 }, { - "x": 207, - "y": 255 + "x": 185.5, + "y": 232 }, { - "x": 207, - "y": 858 + "x": 186, + "y": 823 } ], "animated": false, @@ -377,20 +377,20 @@ "link": "", "route": [ { - "x": 336, - "y": 216 + "x": 311, + "y": 192 }, { - "x": 335.9159851074219, - "y": 255 + "x": 311.25, + "y": 232 }, { - "x": 408.5, - "y": 255 + "x": 387, + "y": 232 }, { - "x": 409, - "y": 351 + "x": 387, + "y": 329 } ], "animated": false, @@ -424,12 +424,12 @@ "link": "", "route": [ { - "x": 408, - "y": 488 + "x": 387, + "y": 453 }, { - "x": 409, - "y": 557 + "x": 387, + "y": 522 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg index 08e6f0148..7b2a78932 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json index 372879a1c..afe425343 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json @@ -15,11 +15,11 @@ "id": "customer", "type": "c4-person", "pos": { - "x": 1057, + "x": 1083, "y": 0 }, - "width": 479, - "height": 575, + "width": 426, + "height": 511, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 147, - "y": 732 + "y": 668 }, "width": 2407, "height": 915, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 177, - "y": 762 + "y": 698 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 390, - "y": 1047 + "y": 983 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 1123, - "y": 1047 + "y": 983 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 1246, - "y": 1348 + "y": 1284 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1890, - "y": 1047 + "y": 983 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 2410, - "y": 1784 + "y": 1720 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 0, - "y": 1784 + "y": 1720 }, "width": 629, "height": 164, @@ -417,20 +417,20 @@ "link": "", "route": [ { - "x": 1057, - "y": 388 + "x": 1083, + "y": 337 }, { - "x": 573, - "y": 592.4000244140625 + "x": 578.2000122070312, + "y": 531 }, { "x": 452, - "y": 722 + "y": 658 }, { "x": 452, - "y": 762 + "y": 698 } ], "isCurve": true, @@ -466,19 +466,19 @@ "route": [ { "x": 452, - "y": 925.5 + "y": 861.5 }, { "x": 452, - "y": 974.2999877929688 + "y": 910.2999877929688 }, { "x": 472.3999938964844, - "y": 998.7000122070312 + "y": 934.7000122070312 }, { "x": 554, - "y": 1047.5 + "y": 983.5 } ], "isCurve": true, @@ -513,44 +513,44 @@ "link": "", "route": [ { - "x": 1063, - "y": 519 + "x": 1084, + "y": 447 }, { - "x": 962.2000122070312, - "y": 618.5999755859375 + "x": 966.4000244140625, + "y": 553 }, { "x": 937, - "y": 657.2000122070312 + "y": 593.2000122070312 }, { "x": 937, - "y": 677.75 + "y": 613.75 }, { "x": 937, - "y": 698.2999877929688 + "y": 634.2999877929688 }, { "x": 937, - "y": 738.4000244140625 + "y": 674.4000244140625 }, { "x": 937, - "y": 778 + "y": 714 }, { "x": 937, - "y": 817.5999755859375 + "y": 753.5999755859375 }, { "x": 916.5999755859375, - "y": 998.7000122070312 + "y": 934.7000122070312 }, { "x": 835, - "y": 1047.5 + "y": 983.5 } ], "isCurve": true, @@ -585,44 +585,44 @@ "link": "", "route": [ { - "x": 1442, - "y": 576 + "x": 1439, + "y": 512 }, { - "x": 1469.199951171875, - "y": 630 + "x": 1468.5999755859375, + "y": 566 }, { "x": 1476, - "y": 657.2000122070312 + "y": 593.2000122070312 }, { "x": 1476, - "y": 677.75 + "y": 613.75 }, { "x": 1476, - "y": 698.2999877929688 + "y": 634.2999877929688 }, { "x": 1476, - "y": 738.4000244140625 + "y": 674.4000244140625 }, { "x": 1476, - "y": 778 + "y": 714 }, { "x": 1476, - "y": 817.5999755859375 + "y": 753.5999755859375 }, { "x": 1476, - "y": 998.7000122070312 + "y": 934.7000122070312 }, { "x": 1476, - "y": 1047.5 + "y": 983.5 } ], "isCurve": true, @@ -658,19 +658,19 @@ "route": [ { "x": 694.5, - "y": 1210.5 + "y": 1146.5 }, { "x": 694.5, - "y": 1265.699951171875 + "y": 1201.699951171875 }, { "x": 804.7000122070312, - "y": 1300.7220458984375 + "y": 1236.7220458984375 }, { "x": 1245.5, - "y": 1385.6099853515625 + "y": 1321.6099853515625 } ], "isCurve": true, @@ -706,19 +706,19 @@ "route": [ { "x": 1476, - "y": 1210.5 + "y": 1146.5 }, { "x": 1476, - "y": 1265.699951171875 + "y": 1201.699951171875 }, { "x": 1476, - "y": 1293.300048828125 + "y": 1229.300048828125 }, { "x": 1476, - "y": 1348.5 + "y": 1284.5 } ], "isCurve": true, @@ -754,19 +754,19 @@ "route": [ { "x": 1245.5, - "y": 1456.1949462890625 + "y": 1392.1949462890625 }, { "x": 500.6990051269531, - "y": 1608.8389892578125 + "y": 1544.8389892578125 }, { "x": 314.5, - "y": 1729.300048828125 + "y": 1665.300048828125 }, { "x": 314.5, - "y": 1784.5 + "y": 1720.5 } ], "isCurve": true, @@ -801,104 +801,104 @@ "link": "", "route": [ { - "x": 1536, - "y": 351 + "x": 1510, + "y": 307 }, { - "x": 2416.800048828125, - "y": 585 + "x": 2411.60009765625, + "y": 525 }, { "x": 2637, - "y": 657.2000122070312 + "y": 593.2000122070312 }, { "x": 2637, - "y": 677.75 + "y": 613.75 }, { "x": 2637, - "y": 698.2999877929688 + "y": 634.2999877929688 }, { "x": 2637, - "y": 738.4000244140625 + "y": 674.4000244140625 }, { "x": 2637, - "y": 778 + "y": 714 }, { "x": 2637, - "y": 817.5999755859375 + "y": 753.5999755859375 }, { "x": 2637, - "y": 872.5 + "y": 808.5 }, { "x": 2637, - "y": 915.25 + "y": 851.25 }, { "x": 2637, - "y": 958 + "y": 894 }, { "x": 2637, - "y": 1015 + "y": 951 }, { "x": 2637, - "y": 1057.75 + "y": 993.75 }, { "x": 2637, - "y": 1100.5 + "y": 1036.5 }, { "x": 2637, - "y": 1159.0999755859375 + "y": 1095.0999755859375 }, { "x": 2637, - "y": 1204.25 + "y": 1140.25 }, { "x": 2637, - "y": 1249.4000244140625 + "y": 1185.4000244140625 }, { "x": 2637, - "y": 1309.5999755859375 + "y": 1245.5999755859375 }, { "x": 2637, - "y": 1354.75 + "y": 1290.75 }, { "x": 2637, - "y": 1399.9000244140625 + "y": 1335.9000244140625 }, { "x": 2637, - "y": 1473.4000244140625 + "y": 1409.4000244140625 }, { "x": 2637, - "y": 1538.5 + "y": 1474.5 }, { "x": 2637, - "y": 1603.5999755859375 + "y": 1539.5999755859375 }, { "x": 2632.800048828125, - "y": 1729.300048828125 + "y": 1665.300048828125 }, { "x": 2616, - "y": 1784.5 + "y": 1720.5 } ], "isCurve": true, @@ -934,19 +934,19 @@ "route": [ { "x": 1707.5, - "y": 1463.843994140625 + "y": 1399.843994140625 }, { "x": 2241.5, - "y": 1610.3680419921875 + "y": 1546.3680419921875 }, { "x": 2394.39990234375, - "y": 1729.300048828125 + "y": 1665.300048828125 }, { "x": 2472, - "y": 1784.5 + "y": 1720.5 } ], "isCurve": true, @@ -982,19 +982,19 @@ "route": [ { "x": 2206.5, - "y": 1210.5 + "y": 1146.5 }, { "x": 2206.5, - "y": 1265.699951171875 + "y": 1201.699951171875 }, { "x": 2106.5, - "y": 1300.0999755859375 + "y": 1236.0999755859375 }, { "x": 1706.5, - "y": 1382.5 + "y": 1318.5 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg index 48ce9e34b..7edf6d842 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json index 1753ba0a8..1e4e527d0 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json @@ -15,11 +15,11 @@ "id": "customer", "type": "c4-person", "pos": { - "x": 672, + "x": 699, "y": 12 }, - "width": 479, - "height": 575, + "width": 426, + "height": 511, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 12, - "y": 839 + "y": 775 }, "width": 2218, "height": 1035, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 62, - "y": 889 + "y": 825 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 190, - "y": 1224 + "y": 1160 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 819, - "y": 1224 + "y": 1160 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 942, - "y": 1575 + "y": 1511 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1546, - "y": 1224 + "y": 1160 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 1746, - "y": 2076 + "y": 2012 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 781, - "y": 2076 + "y": 2012 }, "width": 629, "height": 164, @@ -417,20 +417,20 @@ "link": "", "route": [ { - "x": 769, - "y": 588 + "x": 784, + "y": 524 }, { - "x": 768.5499877929688, - "y": 627 + "x": 784.4500122070312, + "y": 563 }, { "x": 359.25, - "y": 627 + "y": 563 }, { "x": 359.25, - "y": 889 + "y": 825 } ], "animated": false, @@ -465,11 +465,11 @@ "route": [ { "x": 393, - "y": 1053 + "y": 989 }, { "x": 393, - "y": 1224 + "y": 1160 } ], "animated": false, @@ -503,20 +503,20 @@ "link": "", "route": [ { - "x": 864, - "y": 588 + "x": 870, + "y": 524 }, { - "x": 864.3499755859375, - "y": 677 + "x": 869.6500244140625, + "y": 613 }, { "x": 652, - "y": 677 + "y": 613 }, { "x": 652, - "y": 1224 + "y": 1160 } ], "animated": false, @@ -550,12 +550,12 @@ "link": "", "route": [ { - "x": 960, - "y": 588 + "x": 955, + "y": 524 }, { - "x": 960.1500244140625, - "y": 1224 + "x": 954.8499755859375, + "y": 1160 } ], "animated": false, @@ -590,19 +590,19 @@ "route": [ { "x": 494.5, - "y": 1388 + "y": 1324 }, { "x": 494.5, - "y": 1535 + "y": 1471 }, { "x": 1057.25, - "y": 1535 + "y": 1471 }, { "x": 1057.25, - "y": 1575 + "y": 1511 } ], "animated": false, @@ -637,11 +637,11 @@ "route": [ { "x": 1172.5, - "y": 1388 + "y": 1324 }, { "x": 1172.5, - "y": 1575 + "y": 1511 } ], "animated": false, @@ -676,11 +676,11 @@ "route": [ { "x": 1095.666015625, - "y": 1739 + "y": 1675 }, { "x": 1095.666015625, - "y": 2076 + "y": 2012 } ], "animated": false, @@ -714,28 +714,28 @@ "link": "", "route": [ { - "x": 1056, - "y": 588 + "x": 1040, + "y": 524 }, { - "x": 1055.948974609375, - "y": 627 + "x": 1040.050048828125, + "y": 563 }, { "x": 2303.5, - "y": 627 + "y": 563 }, { "x": 2303.5, - "y": 2036 + "y": 1972 }, { "x": 1986.8330078125, - "y": 2036 + "y": 1972 }, { "x": 1986.8330078125, - "y": 2076 + "y": 2012 } ], "animated": false, @@ -770,19 +770,19 @@ "route": [ { "x": 1249.3330078125, - "y": 1739 + "y": 1675 }, { "x": 1249.3330078125, - "y": 2036 + "y": 1972 }, { "x": 1866.8330078125, - "y": 2036 + "y": 1972 }, { "x": 1866.8330078125, - "y": 2076 + "y": 2012 } ], "animated": false, @@ -817,19 +817,19 @@ "route": [ { "x": 1863, - "y": 1388 + "y": 1324 }, { "x": 1863, - "y": 1535 + "y": 1471 }, { "x": 1287.75, - "y": 1535 + "y": 1471 }, { "x": 1287.75, - "y": 1575 + "y": 1511 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg index 66502edd6..03b3ce096 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json index 678575f50..be4ffa74e 100644 --- a/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json +++ b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json @@ -19,7 +19,7 @@ "y": 0 }, "width": 180, - "height": 126, + "height": 114, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg index 68df2d2e2..afeff911b 100644 --- a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg @@ -1,9 +1,9 @@ -c4-person - - + .d2-1872684779 .fill-N1{fill:#0A0F25;} + .d2-1872684779 .fill-N2{fill:#676C7E;} + .d2-1872684779 .fill-N3{fill:#9499AB;} + .d2-1872684779 .fill-N4{fill:#CFD2DD;} + .d2-1872684779 .fill-N5{fill:#DEE1EB;} + .d2-1872684779 .fill-N6{fill:#EEF1F8;} + .d2-1872684779 .fill-N7{fill:#FFFFFF;} + .d2-1872684779 .fill-B1{fill:#0D32B2;} + .d2-1872684779 .fill-B2{fill:#0D32B2;} + .d2-1872684779 .fill-B3{fill:#E3E9FD;} + .d2-1872684779 .fill-B4{fill:#E3E9FD;} + .d2-1872684779 .fill-B5{fill:#EDF0FD;} + .d2-1872684779 .fill-B6{fill:#F7F8FE;} + .d2-1872684779 .fill-AA2{fill:#4A6FF3;} + .d2-1872684779 .fill-AA4{fill:#EDF0FD;} + .d2-1872684779 .fill-AA5{fill:#F7F8FE;} + .d2-1872684779 .fill-AB4{fill:#EDF0FD;} + .d2-1872684779 .fill-AB5{fill:#F7F8FE;} + .d2-1872684779 .stroke-N1{stroke:#0A0F25;} + .d2-1872684779 .stroke-N2{stroke:#676C7E;} + .d2-1872684779 .stroke-N3{stroke:#9499AB;} + .d2-1872684779 .stroke-N4{stroke:#CFD2DD;} + .d2-1872684779 .stroke-N5{stroke:#DEE1EB;} + .d2-1872684779 .stroke-N6{stroke:#EEF1F8;} + .d2-1872684779 .stroke-N7{stroke:#FFFFFF;} + .d2-1872684779 .stroke-B1{stroke:#0D32B2;} + .d2-1872684779 .stroke-B2{stroke:#0D32B2;} + .d2-1872684779 .stroke-B3{stroke:#E3E9FD;} + .d2-1872684779 .stroke-B4{stroke:#E3E9FD;} + .d2-1872684779 .stroke-B5{stroke:#EDF0FD;} + .d2-1872684779 .stroke-B6{stroke:#F7F8FE;} + .d2-1872684779 .stroke-AA2{stroke:#4A6FF3;} + .d2-1872684779 .stroke-AA4{stroke:#EDF0FD;} + .d2-1872684779 .stroke-AA5{stroke:#F7F8FE;} + .d2-1872684779 .stroke-AB4{stroke:#EDF0FD;} + .d2-1872684779 .stroke-AB5{stroke:#F7F8FE;} + .d2-1872684779 .background-color-N1{background-color:#0A0F25;} + .d2-1872684779 .background-color-N2{background-color:#676C7E;} + .d2-1872684779 .background-color-N3{background-color:#9499AB;} + .d2-1872684779 .background-color-N4{background-color:#CFD2DD;} + .d2-1872684779 .background-color-N5{background-color:#DEE1EB;} + .d2-1872684779 .background-color-N6{background-color:#EEF1F8;} + .d2-1872684779 .background-color-N7{background-color:#FFFFFF;} + .d2-1872684779 .background-color-B1{background-color:#0D32B2;} + .d2-1872684779 .background-color-B2{background-color:#0D32B2;} + .d2-1872684779 .background-color-B3{background-color:#E3E9FD;} + .d2-1872684779 .background-color-B4{background-color:#E3E9FD;} + .d2-1872684779 .background-color-B5{background-color:#EDF0FD;} + .d2-1872684779 .background-color-B6{background-color:#F7F8FE;} + .d2-1872684779 .background-color-AA2{background-color:#4A6FF3;} + .d2-1872684779 .background-color-AA4{background-color:#EDF0FD;} + .d2-1872684779 .background-color-AA5{background-color:#F7F8FE;} + .d2-1872684779 .background-color-AB4{background-color:#EDF0FD;} + .d2-1872684779 .background-color-AB5{background-color:#F7F8FE;} + .d2-1872684779 .color-N1{color:#0A0F25;} + .d2-1872684779 .color-N2{color:#676C7E;} + .d2-1872684779 .color-N3{color:#9499AB;} + .d2-1872684779 .color-N4{color:#CFD2DD;} + .d2-1872684779 .color-N5{color:#DEE1EB;} + .d2-1872684779 .color-N6{color:#EEF1F8;} + .d2-1872684779 .color-N7{color:#FFFFFF;} + .d2-1872684779 .color-B1{color:#0D32B2;} + .d2-1872684779 .color-B2{color:#0D32B2;} + .d2-1872684779 .color-B3{color:#E3E9FD;} + .d2-1872684779 .color-B4{color:#E3E9FD;} + .d2-1872684779 .color-B5{color:#EDF0FD;} + .d2-1872684779 .color-B6{color:#F7F8FE;} + .d2-1872684779 .color-AA2{color:#4A6FF3;} + .d2-1872684779 .color-AA4{color:#EDF0FD;} + .d2-1872684779 .color-AA5{color:#F7F8FE;} + .d2-1872684779 .color-AB4{color:#EDF0FD;} + .d2-1872684779 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-1872684779);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-1872684779);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-1872684779);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-1872684779);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1872684779);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1872684779);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-1872684779);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-1872684779);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1872684779);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-1872684779);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1872684779);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1872684779);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1872684779);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1872684779);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1872684779);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-1872684779);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1872684779);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1872684779);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + + \ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json index 90602f386..899afe63f 100644 --- a/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json +++ b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json @@ -19,7 +19,7 @@ "y": 12 }, "width": 180, - "height": 126, + "height": 114, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg index 3a19838ab..68477ef9d 100644 --- a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg @@ -1,9 +1,9 @@ -c4-person - - + .d2-1815602595 .fill-N1{fill:#0A0F25;} + .d2-1815602595 .fill-N2{fill:#676C7E;} + .d2-1815602595 .fill-N3{fill:#9499AB;} + .d2-1815602595 .fill-N4{fill:#CFD2DD;} + .d2-1815602595 .fill-N5{fill:#DEE1EB;} + .d2-1815602595 .fill-N6{fill:#EEF1F8;} + .d2-1815602595 .fill-N7{fill:#FFFFFF;} + .d2-1815602595 .fill-B1{fill:#0D32B2;} + .d2-1815602595 .fill-B2{fill:#0D32B2;} + .d2-1815602595 .fill-B3{fill:#E3E9FD;} + .d2-1815602595 .fill-B4{fill:#E3E9FD;} + .d2-1815602595 .fill-B5{fill:#EDF0FD;} + .d2-1815602595 .fill-B6{fill:#F7F8FE;} + .d2-1815602595 .fill-AA2{fill:#4A6FF3;} + .d2-1815602595 .fill-AA4{fill:#EDF0FD;} + .d2-1815602595 .fill-AA5{fill:#F7F8FE;} + .d2-1815602595 .fill-AB4{fill:#EDF0FD;} + .d2-1815602595 .fill-AB5{fill:#F7F8FE;} + .d2-1815602595 .stroke-N1{stroke:#0A0F25;} + .d2-1815602595 .stroke-N2{stroke:#676C7E;} + .d2-1815602595 .stroke-N3{stroke:#9499AB;} + .d2-1815602595 .stroke-N4{stroke:#CFD2DD;} + .d2-1815602595 .stroke-N5{stroke:#DEE1EB;} + .d2-1815602595 .stroke-N6{stroke:#EEF1F8;} + .d2-1815602595 .stroke-N7{stroke:#FFFFFF;} + .d2-1815602595 .stroke-B1{stroke:#0D32B2;} + .d2-1815602595 .stroke-B2{stroke:#0D32B2;} + .d2-1815602595 .stroke-B3{stroke:#E3E9FD;} + .d2-1815602595 .stroke-B4{stroke:#E3E9FD;} + .d2-1815602595 .stroke-B5{stroke:#EDF0FD;} + .d2-1815602595 .stroke-B6{stroke:#F7F8FE;} + .d2-1815602595 .stroke-AA2{stroke:#4A6FF3;} + .d2-1815602595 .stroke-AA4{stroke:#EDF0FD;} + .d2-1815602595 .stroke-AA5{stroke:#F7F8FE;} + .d2-1815602595 .stroke-AB4{stroke:#EDF0FD;} + .d2-1815602595 .stroke-AB5{stroke:#F7F8FE;} + .d2-1815602595 .background-color-N1{background-color:#0A0F25;} + .d2-1815602595 .background-color-N2{background-color:#676C7E;} + .d2-1815602595 .background-color-N3{background-color:#9499AB;} + .d2-1815602595 .background-color-N4{background-color:#CFD2DD;} + .d2-1815602595 .background-color-N5{background-color:#DEE1EB;} + .d2-1815602595 .background-color-N6{background-color:#EEF1F8;} + .d2-1815602595 .background-color-N7{background-color:#FFFFFF;} + .d2-1815602595 .background-color-B1{background-color:#0D32B2;} + .d2-1815602595 .background-color-B2{background-color:#0D32B2;} + .d2-1815602595 .background-color-B3{background-color:#E3E9FD;} + .d2-1815602595 .background-color-B4{background-color:#E3E9FD;} + .d2-1815602595 .background-color-B5{background-color:#EDF0FD;} + .d2-1815602595 .background-color-B6{background-color:#F7F8FE;} + .d2-1815602595 .background-color-AA2{background-color:#4A6FF3;} + .d2-1815602595 .background-color-AA4{background-color:#EDF0FD;} + .d2-1815602595 .background-color-AA5{background-color:#F7F8FE;} + .d2-1815602595 .background-color-AB4{background-color:#EDF0FD;} + .d2-1815602595 .background-color-AB5{background-color:#F7F8FE;} + .d2-1815602595 .color-N1{color:#0A0F25;} + .d2-1815602595 .color-N2{color:#676C7E;} + .d2-1815602595 .color-N3{color:#9499AB;} + .d2-1815602595 .color-N4{color:#CFD2DD;} + .d2-1815602595 .color-N5{color:#DEE1EB;} + .d2-1815602595 .color-N6{color:#EEF1F8;} + .d2-1815602595 .color-N7{color:#FFFFFF;} + .d2-1815602595 .color-B1{color:#0D32B2;} + .d2-1815602595 .color-B2{color:#0D32B2;} + .d2-1815602595 .color-B3{color:#E3E9FD;} + .d2-1815602595 .color-B4{color:#E3E9FD;} + .d2-1815602595 .color-B5{color:#EDF0FD;} + .d2-1815602595 .color-B6{color:#F7F8FE;} + .d2-1815602595 .color-AA2{color:#4A6FF3;} + .d2-1815602595 .color-AA4{color:#EDF0FD;} + .d2-1815602595 .color-AA5{color:#F7F8FE;} + .d2-1815602595 .color-AB4{color:#EDF0FD;} + .d2-1815602595 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-1815602595);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-1815602595);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-1815602595);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-1815602595);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1815602595);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1815602595);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-1815602595);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-1815602595);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1815602595);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-1815602595);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1815602595);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1815602595);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1815602595);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1815602595);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1815602595);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-1815602595);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1815602595);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1815602595);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + + \ No newline at end of file diff --git a/e2etests/txtar.txt b/e2etests/txtar.txt index d20dbb221..89d18ce17 100644 --- a/e2etests/txtar.txt +++ b/e2etests/txtar.txt @@ -1187,3 +1187,37 @@ a: |md a.shape: c4-person a: c4-person a.width: 180 + +-- c4-person-label -- +c4mdperson: |md +## Personal Banking Customer + +[person] + +A customer of the bank, with personal bank accounts + | { + shape: c4-person + label.near: center-center + } + +c4mdperson2: |md +## Personal Banking Customer + +[person] + +A customer of the bank, with personal bank accounts + | { + shape: c4-person + label.near: top-center + } + +c4mdperson3: |md +## Personal Banking Customer + +[person] + +A customer of the bank, with personal bank accounts + | { + shape: c4-person + label.near: bottom-center + } diff --git a/lib/shape/shape_c4_person.go b/lib/shape/shape_c4_person.go index 673afbf8f..9cf8fbea3 100644 --- a/lib/shape/shape_c4_person.go +++ b/lib/shape/shape_c4_person.go @@ -38,13 +38,20 @@ func (s shapeC4Person) GetInnerBox() *geo.Box { headCenterY := height * 0.18 bodyTop := headCenterY + headRadius*0.8 - tl := s.Box.TopLeft.Copy() - horizontalPadding := width * 0.1 - tl.X += horizontalPadding - tl.Y += bodyTop + height*0.05 + // Use a small fixed percentage instead of the full corner radius + horizontalPadding := width * 0.05 // 5% padding + tl := s.Box.TopLeft.Copy() + tl.X += horizontalPadding + + // Add vertical padding + tl.Y += bodyTop + height*0.03 + + // Width minus padding on both sides innerWidth := width - (horizontalPadding * 2) - innerHeight := height - tl.Y + s.Box.TopLeft.Y - (height * 0.05) + + // Add bottom padding + innerHeight := height - (tl.Y - s.Box.TopLeft.Y) - (height * 0.03) return geo.NewBox(tl, innerWidth, innerHeight) } @@ -140,17 +147,23 @@ func (s shapeC4Person) GetSVGPathData() []string { func (s shapeC4Person) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { contentWidth := width + paddingX contentHeight := height + paddingY - totalWidth := contentWidth / 0.8 + + // Account for 10% total horizontal padding (5% on each side) + totalWidth := contentWidth / 0.9 headRadius := totalWidth * 0.22 - bodyTop := totalWidth*0.18 + headRadius*0.8 - verticalPaddingRatio := 0.1 // 5% top + 5% bottom - totalHeight := (contentHeight + bodyTop) / (1 - verticalPaddingRatio) + headCenterY := totalWidth * 0.18 + bodyTop := headCenterY + headRadius*0.8 + + // Include vertical padding from GetInnerBox + verticalPadding := totalWidth * 0.06 // 3% top + 3% bottom + totalHeight := contentHeight + bodyTop + verticalPadding + minHeight := totalWidth * 1.2 if totalHeight < minHeight { totalHeight = minHeight } - totalWidth, totalHeight = LimitAR(totalWidth, totalHeight, C4_PERSON_AR_LIMIT) + totalWidth, totalHeight = LimitAR(totalWidth, totalHeight, C4_PERSON_AR_LIMIT) return math.Ceil(totalWidth), math.Ceil(totalHeight) } From 33bb2b280f1319f62dc63832d37907d06e1fc40d Mon Sep 17 00:00:00 2001 From: stereobooster Date: Thu, 13 Mar 2025 20:31:46 +0100 Subject: [PATCH 18/54] TypeScript signatures --- ci/release/changelogs/next.md | 1 + d2js/js/index.d.ts | 66 +++++++++++++++++++++++++++++++++++ d2js/js/package.json | 4 ++- 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 d2js/js/index.d.ts diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index ab55c0441..4b28a34de 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -24,6 +24,7 @@ - `noXMLTag` - Support relative imports. Improve elk error handling: [#2382](https://github.com/terrastruct/d2/pull/2382) - Support fonts (`fontRegular`, `fontItalic`, `fontBold`, `fontSemiBold`): [#2384](https://github.com/terrastruct/d2/pull/2384) + - Add TypeScript signatures - d2cli: - Support `validate` command. [#2415](https://github.com/terrastruct/d2/pull/2415) diff --git a/d2js/js/index.d.ts b/d2js/js/index.d.ts new file mode 100644 index 000000000..42bbff56d --- /dev/null +++ b/d2js/js/index.d.ts @@ -0,0 +1,66 @@ +declare module "@terrastruct/d2" { + interface RenderOptions { + /** Enable sketch mode [default: false] */ + sketch?: boolean; + /** Theme ID to use [default: 0] */ + themeID?: number; + /** Theme ID to use when client is in dark mode */ + darkThemeID?: number; + /** Center the SVG in the containing viewbox [default: false] */ + center?: boolean; + /** Pixels padded around the rendered diagram [default: 100] */ + pad?: number; + /** 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. */ + scale?: number; + /** Adds an appendix for tooltips and links [default: false] */ + forceAppendix?: boolean; + /** 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. E.g. target: 'layers.x.*' to render layer 'x' with all of its children. Pass '' to render all scenarios, steps, and layers. By default, only the root board is rendered. Multi-board outputs are currently only supported for animated SVGs and so animateInterval must be set to a value greater than 0 when targeting multiple boards. */ + target?: string; + /** If given, multiple boards are packaged as 1 SVG which transitions through each board at the interval (in milliseconds). */ + animateInterval?: number; + /** 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. */ + salt?: string; + /** Omit XML tag () from output SVG files. Useful when generating SVGs for direct HTML embedding. */ + noXMLTag?: boolean; + } + + interface CompileOptions extends RenderOptions { + /** Layout engine to use [default: 'dagre'] */ + layout?: 'dagre' | 'elk'; + /** A byte array containing .ttf file to use for the regular font. If none provided, Source Sans Pro Regular is used. */ + fontRegular?: Uint8Array; + /** A byte array containing .ttf file to use for the italic font. If none provided, Source Sans Pro Italic is used. */ + fontItalic?: Uint8Array; + /** A byte array containing .ttf file to use for the bold font. If none provided, Source Sans Pro Bold is used. */ + fontBold?: Uint8Array; + /** A byte array containing .ttf file to use for the semibold font. If none provided, Source Sans Pro Semibold is used. */ + fontSemibold?: Uint8Array; + } + + interface CompileRequest { + /** A mapping of D2 file paths to their content*/ + fs: Record; + /** The path of the entry D2 file [default: index]*/ + inputPath: string; + /** The CompileOptions to pass to the compiler*/ + options: CompileOptions; + } + + interface Diagram { + config: RenderOptions; + } + + interface CompileResult { + /** Compiled D2 diagram*/ + diagram: Diagram; + /** RenderOptions: Render options merged with configuration set in diagram*/ + renderOptions: RenderOptions; + fs: Record; + graph: unknown; + } + + class D2 { + compile(input: string | CompileRequest, options?: CompileOptions): Promise; + render(diagram: Diagram, options?: RenderOptions): Promise; + } +} diff --git a/d2js/js/package.json b/d2js/js/package.json index 9a7834975..a876c24be 100644 --- a/d2js/js/package.json +++ b/d2js/js/package.json @@ -31,8 +31,10 @@ "./worker": "./dist/browser/worker.js" }, "files": [ - "dist" + "dist", + "index.d.ts" ], + "types": "./index.d.ts", "scripts": { "build": "./make.sh build", "test": "bun test test/unit", From 08d67f102c52920700a6c23eb65c1bb3f27349bd Mon Sep 17 00:00:00 2001 From: stereobooster Date: Thu, 13 Mar 2025 20:49:33 +0100 Subject: [PATCH 19/54] Rehype plugin --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 12133f941..390b1a48a 100644 --- a/README.md +++ b/README.md @@ -267,6 +267,7 @@ let us know and we'll be happy to include it here! - **VitePress Plugin**: [https://github.com/BadgerHobbs/vitepress-plugin-d2](https://github.com/BadgerHobbs/vitepress-plugin-d2) - **Zed extension**: [https://github.com/gabeidx/zed-d2](https://github.com/gabeidx/zed-d2) - **Hexo blog extension**: [https://github.com/leverimmy/hexo-d2](https://github.com/leverimmy/hexo-d2) +- **Rehype Plugin**: [https://github.com/stereobooster/beoe/tree/main/packages/rehype-d2](https://github.com/stereobooster/beoe/tree/main/packages/rehype-d2) ### Misc From 3fe5d1ff74e21ea1db1d76f07f9e678ed3ff3f47 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 13 Mar 2025 14:40:33 -0600 Subject: [PATCH 20/54] fix height --- .../c4-person-label/dagre/board.exp.json | 16 +- .../c4-person-label/dagre/sketch.exp.svg | 562 ++++++++-------- .../txtar/c4-person-label/elk/board.exp.json | 16 +- .../txtar/c4-person-label/elk/sketch.exp.svg | 562 ++++++++-------- .../c4-person-shape/dagre/board.exp.json | 98 +-- .../c4-person-shape/dagre/sketch.exp.svg | 578 ++++++++--------- .../txtar/c4-person-shape/elk/board.exp.json | 78 +-- .../txtar/c4-person-shape/elk/sketch.exp.svg | 578 ++++++++--------- .../txtar/c4-theme/dagre/board.exp.json | 184 +++--- .../txtar/c4-theme/dagre/sketch.exp.svg | 612 +++++++++--------- .../txtar/c4-theme/elk/board.exp.json | 106 +-- .../txtar/c4-theme/elk/sketch.exp.svg | 612 +++++++++--------- .../small-c4-person/dagre/board.exp.json | 2 +- .../small-c4-person/dagre/sketch.exp.svg | 156 ++--- .../txtar/small-c4-person/elk/board.exp.json | 2 +- .../txtar/small-c4-person/elk/sketch.exp.svg | 156 ++--- lib/shape/shape_c4_person.go | 7 +- 17 files changed, 2164 insertions(+), 2161 deletions(-) diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json index cfb656f9b..d164ab8a8 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json @@ -18,8 +18,8 @@ "x": 0, "y": 0 }, - "width": 422, - "height": 506, + "width": 410, + "height": 390, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -57,11 +57,11 @@ "id": "c4mdperson2", "type": "c4-person", "pos": { - "x": 482, + "x": 470, "y": 0 }, - "width": 422, - "height": 506, + "width": 410, + "height": 390, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -99,11 +99,11 @@ "id": "c4mdperson3", "type": "c4-person", "pos": { - "x": 964, + "x": 940, "y": 0 }, - "width": 422, - "height": 506, + "width": 410, + "height": 390, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg index 0acadd4be..bab515547 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg @@ -1,13 +1,13 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-
- - - - +
+ + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json index 1767158d2..636de29e5 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json @@ -18,8 +18,8 @@ "x": 12, "y": 12 }, - "width": 422, - "height": 506, + "width": 410, + "height": 390, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -57,11 +57,11 @@ "id": "c4mdperson2", "type": "c4-person", "pos": { - "x": 454, + "x": 442, "y": 12 }, - "width": 422, - "height": 506, + "width": 410, + "height": 390, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -99,11 +99,11 @@ "id": "c4mdperson3", "type": "c4-person", "pos": { - "x": 896, + "x": 872, "y": 12 }, - "width": 422, - "height": 506, + "width": 410, + "height": 390, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg index cef62e084..bfadee541 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg @@ -1,13 +1,13 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-
- - - - +
+ + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json index 7fa64364e..279169e81 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 0, - "y": 577 + "y": 504 }, - "width": 347, - "height": 416, + "width": 336, + "height": 328, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -57,11 +57,11 @@ "id": "c4person", "type": "c4-person", "pos": { - "x": 263, + "x": 260, "y": 0 }, - "width": 150, - "height": 180, + "width": 139, + "height": 132, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -99,8 +99,8 @@ "id": "regular_person", "type": "person", "pos": { - "x": 107, - "y": 370 + "x": 101, + "y": 309 }, "width": 134, "height": 89, @@ -141,11 +141,11 @@ "id": "styling", "type": "rectangle", "pos": { - "x": 397, - "y": 321 + "x": 386, + "y": 273 }, "width": 210, - "height": 584, + "height": 515, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -183,11 +183,11 @@ "id": "styling.c4styled", "type": "c4-person", "pos": { - "x": 455, - "y": 351 + "x": 449, + "y": 303 }, - "width": 95, - "height": 126, + "width": 84, + "height": 101, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -225,8 +225,8 @@ "id": "styling.c4sized", "type": "c4-person", "pos": { - "x": 427, - "y": 695 + "x": 416, + "y": 578 }, "width": 150, "height": 180, @@ -291,20 +291,20 @@ "link": "", "route": [ { - "x": 173.5, - "y": 485 + "x": 168, + "y": 424 }, { - "x": 173.5, - "y": 518.5999755859375 + "x": 168, + "y": 448 }, { - "x": 173.60000610351562, - "y": 536.7999877929688 + "x": 168, + "y": 461 }, { - "x": 174, - "y": 576 + "x": 168, + "y": 489 } ], "isCurve": true, @@ -339,20 +339,20 @@ "link": "", "route": [ { - "x": 264, - "y": 157 + "x": 262, + "y": 119 }, { - "x": 191.60000610351562, - "y": 223.8000030517578 + "x": 186.8000030517578, + "y": 177.8000030517578 }, { - "x": 173.60000610351562, - "y": 314.79998779296875 + "x": 168, + "y": 264.20001220703125 }, { - "x": 174, - "y": 370 + "x": 168, + "y": 309 } ], "isCurve": true, @@ -387,20 +387,20 @@ "link": "", "route": [ { - "x": 413, - "y": 158 + "x": 397, + "y": 119 }, { - "x": 484.20001220703125, - "y": 224 + "x": 472.20001220703125, + "y": 177.8000030517578 }, { - "x": 502, - "y": 311.3999938964844 + "x": 491, + "y": 263 }, { - "x": 502, - "y": 353 + "x": 491, + "y": 303 } ], "isCurve": true, @@ -435,20 +435,20 @@ "link": "", "route": [ { - "x": 502, - "y": 477 + "x": 491, + "y": 405 }, { - "x": 502, - "y": 517 + "x": 491, + "y": 444.20001220703125 }, { - "x": 502, - "y": 560.4000244140625 + "x": 491, + "y": 478.6000061035156 }, { - "x": 502, - "y": 694 + "x": 491, + "y": 577 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg index 735587575..65e12a1b3 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json index 9fea05c01..95cb99c31 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 12, - "y": 1008 + "y": 935 }, - "width": 347, - "height": 416, + "width": 336, + "height": 328, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -60,8 +60,8 @@ "x": 211, "y": 12 }, - "width": 150, - "height": 180, + "width": 139, + "height": 132, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -99,8 +99,8 @@ "id": "regular_person", "type": "person", "pos": { - "x": 118, - "y": 823 + "x": 113, + "y": 750 }, "width": 134, "height": 89, @@ -141,11 +141,11 @@ "id": "styling", "type": "rectangle", "pos": { - "x": 262, - "y": 277 + "x": 256, + "y": 229 }, "width": 250, - "height": 476, + "height": 451, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -184,10 +184,10 @@ "type": "c4-person", "pos": { "x": 339, - "y": 327 + "y": 279 }, - "width": 95, - "height": 126, + "width": 84, + "height": 101, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -225,8 +225,8 @@ "id": "styling.c4sized", "type": "c4-person", "pos": { - "x": 312, - "y": 523 + "x": 306, + "y": 450 }, "width": 150, "height": 180, @@ -291,12 +291,12 @@ "link": "", "route": [ { - "x": 185.5, - "y": 938 + "x": 180, + "y": 865 }, { - "x": 186, - "y": 1007 + "x": 180, + "y": 920 } ], "animated": false, @@ -330,20 +330,20 @@ "link": "", "route": [ { - "x": 261, - "y": 192 + "x": 258, + "y": 144 }, { - "x": 261.25, - "y": 232 + "x": 257.5830078125, + "y": 184 }, { - "x": 185.5, - "y": 232 + "x": 180, + "y": 184 }, { - "x": 186, - "y": 823 + "x": 180, + "y": 750 } ], "animated": false, @@ -377,20 +377,20 @@ "link": "", "route": [ { - "x": 311, - "y": 192 + "x": 304, + "y": 144 }, { - "x": 311.25, - "y": 232 + "x": 303.9159851074219, + "y": 184 }, { - "x": 387, - "y": 232 + "x": 381.5, + "y": 184 }, { - "x": 387, - "y": 329 + "x": 382, + "y": 279 } ], "animated": false, @@ -424,12 +424,12 @@ "link": "", "route": [ { - "x": 387, - "y": 453 + "x": 381, + "y": 381 }, { - "x": 387, - "y": 522 + "x": 382, + "y": 449 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg index 7b2a78932..d7fdb9e74 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json index afe425343..e462c9a73 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json @@ -15,11 +15,11 @@ "id": "customer", "type": "c4-person", "pos": { - "x": 1083, + "x": 1089, "y": 0 }, - "width": 426, - "height": 511, + "width": 415, + "height": 394, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 147, - "y": 668 + "y": 551 }, "width": 2407, "height": 915, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 177, - "y": 698 + "y": 581 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 390, - "y": 983 + "y": 866 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 1123, - "y": 983 + "y": 866 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 1246, - "y": 1284 + "y": 1167 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1890, - "y": 983 + "y": 866 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 2410, - "y": 1720 + "y": 1603 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 0, - "y": 1720 + "y": 1603 }, "width": 629, "height": 164, @@ -417,20 +417,20 @@ "link": "", "route": [ { - "x": 1083, - "y": 337 + "x": 1089, + "y": 262 }, { - "x": 578.2000122070312, - "y": 531 + "x": 579.4000244140625, + "y": 422.3999938964844 }, { "x": 452, - "y": 658 + "y": 541 }, { "x": 452, - "y": 698 + "y": 581 } ], "isCurve": true, @@ -466,19 +466,19 @@ "route": [ { "x": 452, - "y": 861.5 + "y": 744.5 }, { "x": 452, - "y": 910.2999877929688 + "y": 793.2999877929688 }, { "x": 472.3999938964844, - "y": 934.7000122070312 + "y": 817.7000122070312 }, { "x": 554, - "y": 983.5 + "y": 866.5 } ], "isCurve": true, @@ -513,44 +513,44 @@ "link": "", "route": [ { - "x": 1084, - "y": 447 + "x": 1092, + "y": 348 }, { - "x": 966.4000244140625, - "y": 553 + "x": 968, + "y": 439.6000061035156 }, { "x": 937, - "y": 593.2000122070312 + "y": 476.20001220703125 }, { "x": 937, - "y": 613.75 + "y": 496.75 }, { "x": 937, - "y": 634.2999877929688 + "y": 517.2990112304688 }, { "x": 937, - "y": 674.4000244140625 + "y": 557.4000244140625 }, { "x": 937, - "y": 714 + "y": 597 }, { "x": 937, - "y": 753.5999755859375 + "y": 636.5999755859375 }, { "x": 916.5999755859375, - "y": 934.7000122070312 + "y": 817.7000122070312 }, { "x": 835, - "y": 983.5 + "y": 866.5 } ], "isCurve": true, @@ -585,44 +585,44 @@ "link": "", "route": [ { - "x": 1439, - "y": 512 + "x": 1430, + "y": 394 }, { - "x": 1468.5999755859375, - "y": 566 + "x": 1466.800048828125, + "y": 448.79998779296875 }, { "x": 1476, - "y": 593.2000122070312 + "y": 476.20001220703125 }, { "x": 1476, - "y": 613.75 + "y": 496.75 }, { "x": 1476, - "y": 634.2999877929688 + "y": 517.2990112304688 }, { "x": 1476, - "y": 674.4000244140625 + "y": 557.4000244140625 }, { "x": 1476, - "y": 714 + "y": 597 }, { "x": 1476, - "y": 753.5999755859375 + "y": 636.5999755859375 }, { "x": 1476, - "y": 934.7000122070312 + "y": 817.7000122070312 }, { "x": 1476, - "y": 983.5 + "y": 866.5 } ], "isCurve": true, @@ -658,19 +658,19 @@ "route": [ { "x": 694.5, - "y": 1146.5 + "y": 1029.5 }, { "x": 694.5, - "y": 1201.699951171875 + "y": 1084.699951171875 }, { "x": 804.7000122070312, - "y": 1236.7220458984375 + "y": 1119.7220458984375 }, { "x": 1245.5, - "y": 1321.6099853515625 + "y": 1204.6099853515625 } ], "isCurve": true, @@ -706,19 +706,19 @@ "route": [ { "x": 1476, - "y": 1146.5 + "y": 1029.5 }, { "x": 1476, - "y": 1201.699951171875 + "y": 1084.699951171875 }, { "x": 1476, - "y": 1229.300048828125 + "y": 1112.300048828125 }, { "x": 1476, - "y": 1284.5 + "y": 1167.5 } ], "isCurve": true, @@ -754,19 +754,19 @@ "route": [ { "x": 1245.5, - "y": 1392.1949462890625 + "y": 1275.1949462890625 }, { "x": 500.6990051269531, - "y": 1544.8389892578125 + "y": 1427.8389892578125 }, { "x": 314.5, - "y": 1665.300048828125 + "y": 1548.300048828125 }, { "x": 314.5, - "y": 1720.5 + "y": 1603.5 } ], "isCurve": true, @@ -801,104 +801,104 @@ "link": "", "route": [ { - "x": 1510, - "y": 307 + "x": 1505, + "y": 238 }, { - "x": 2411.60009765625, - "y": 525 + "x": 2410.60009765625, + "y": 417.6000061035156 }, { "x": 2637, - "y": 593.2000122070312 + "y": 476.20001220703125 }, { "x": 2637, - "y": 613.75 + "y": 496.75 }, { "x": 2637, - "y": 634.2999877929688 + "y": 517.2990112304688 }, { "x": 2637, - "y": 674.4000244140625 + "y": 557.4000244140625 }, { "x": 2637, - "y": 714 + "y": 597 }, { "x": 2637, - "y": 753.5999755859375 + "y": 636.5999755859375 }, { "x": 2637, - "y": 808.5 + "y": 691.5 }, { "x": 2637, - "y": 851.25 + "y": 734.25 }, { "x": 2637, - "y": 894 + "y": 777 }, { "x": 2637, - "y": 951 + "y": 834 }, { "x": 2637, - "y": 993.75 + "y": 876.75 }, { "x": 2637, - "y": 1036.5 + "y": 919.5 }, { "x": 2637, - "y": 1095.0999755859375 + "y": 978.0999755859375 }, { "x": 2637, - "y": 1140.25 + "y": 1023.25 }, { "x": 2637, - "y": 1185.4000244140625 + "y": 1068.4000244140625 }, { "x": 2637, - "y": 1245.5999755859375 + "y": 1128.5999755859375 }, { "x": 2637, - "y": 1290.75 + "y": 1173.75 }, { "x": 2637, - "y": 1335.9000244140625 + "y": 1218.9000244140625 }, { "x": 2637, - "y": 1409.4000244140625 + "y": 1292.4000244140625 }, { "x": 2637, - "y": 1474.5 + "y": 1357.5 }, { "x": 2637, - "y": 1539.5999755859375 + "y": 1422.5999755859375 }, { "x": 2632.800048828125, - "y": 1665.300048828125 + "y": 1548.300048828125 }, { "x": 2616, - "y": 1720.5 + "y": 1603.5 } ], "isCurve": true, @@ -934,19 +934,19 @@ "route": [ { "x": 1707.5, - "y": 1399.843994140625 + "y": 1282.843994140625 }, { "x": 2241.5, - "y": 1546.3680419921875 + "y": 1429.3680419921875 }, { "x": 2394.39990234375, - "y": 1665.300048828125 + "y": 1548.300048828125 }, { "x": 2472, - "y": 1720.5 + "y": 1603.5 } ], "isCurve": true, @@ -982,19 +982,19 @@ "route": [ { "x": 2206.5, - "y": 1146.5 + "y": 1029.5 }, { "x": 2206.5, - "y": 1201.699951171875 + "y": 1084.699951171875 }, { "x": 2106.5, - "y": 1236.0999755859375 + "y": 1119.0999755859375 }, { "x": 1706.5, - "y": 1318.5 + "y": 1201.5 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg index 7edf6d842..2613fb8b3 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json index 1e4e527d0..4d6d3ccd8 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json @@ -15,11 +15,11 @@ "id": "customer", "type": "c4-person", "pos": { - "x": 699, + "x": 704, "y": 12 }, - "width": 426, - "height": 511, + "width": 415, + "height": 394, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 12, - "y": 775 + "y": 658 }, "width": 2218, "height": 1035, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 62, - "y": 825 + "y": 708 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 190, - "y": 1160 + "y": 1043 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 819, - "y": 1160 + "y": 1043 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 942, - "y": 1511 + "y": 1394 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1546, - "y": 1160 + "y": 1043 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 1746, - "y": 2012 + "y": 1895 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 781, - "y": 2012 + "y": 1895 }, "width": 629, "height": 164, @@ -417,20 +417,20 @@ "link": "", "route": [ { - "x": 784, - "y": 524 + "x": 788, + "y": 406 }, { - "x": 784.4500122070312, - "y": 563 + "x": 787.75, + "y": 446 }, { "x": 359.25, - "y": 563 + "y": 446 }, { "x": 359.25, - "y": 825 + "y": 708 } ], "animated": false, @@ -465,11 +465,11 @@ "route": [ { "x": 393, - "y": 989 + "y": 872 }, { "x": 393, - "y": 1160 + "y": 1043 } ], "animated": false, @@ -503,20 +503,20 @@ "link": "", "route": [ { - "x": 870, - "y": 524 + "x": 871, + "y": 406 }, { - "x": 869.6500244140625, - "y": 613 + "x": 870.75, + "y": 496 }, { "x": 652, - "y": 613 + "y": 496 }, { "x": 652, - "y": 1160 + "y": 1043 } ], "animated": false, @@ -550,12 +550,12 @@ "link": "", "route": [ { - "x": 955, - "y": 524 + "x": 954, + "y": 406 }, { - "x": 954.8499755859375, - "y": 1160 + "x": 953.75, + "y": 1043 } ], "animated": false, @@ -590,19 +590,19 @@ "route": [ { "x": 494.5, - "y": 1324 + "y": 1207 }, { "x": 494.5, - "y": 1471 + "y": 1354 }, { "x": 1057.25, - "y": 1471 + "y": 1354 }, { "x": 1057.25, - "y": 1511 + "y": 1394 } ], "animated": false, @@ -637,11 +637,11 @@ "route": [ { "x": 1172.5, - "y": 1324 + "y": 1207 }, { "x": 1172.5, - "y": 1511 + "y": 1394 } ], "animated": false, @@ -676,11 +676,11 @@ "route": [ { "x": 1095.666015625, - "y": 1675 + "y": 1558 }, { "x": 1095.666015625, - "y": 2012 + "y": 1895 } ], "animated": false, @@ -714,28 +714,28 @@ "link": "", "route": [ { - "x": 1040, - "y": 524 + "x": 1037, + "y": 406 }, { - "x": 1040.050048828125, - "y": 563 + "x": 1036.75, + "y": 446 }, { "x": 2303.5, - "y": 563 + "y": 446 }, { "x": 2303.5, - "y": 1972 + "y": 1855 }, { "x": 1986.8330078125, - "y": 1972 + "y": 1855 }, { "x": 1986.8330078125, - "y": 2012 + "y": 1895 } ], "animated": false, @@ -770,19 +770,19 @@ "route": [ { "x": 1249.3330078125, - "y": 1675 + "y": 1558 }, { "x": 1249.3330078125, - "y": 1972 + "y": 1855 }, { "x": 1866.8330078125, - "y": 1972 + "y": 1855 }, { "x": 1866.8330078125, - "y": 2012 + "y": 1895 } ], "animated": false, @@ -817,19 +817,19 @@ "route": [ { "x": 1863, - "y": 1324 + "y": 1207 }, { "x": 1863, - "y": 1471 + "y": 1354 }, { "x": 1287.75, - "y": 1471 + "y": 1354 }, { "x": 1287.75, - "y": 1511 + "y": 1394 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg index 03b3ce096..31b06adcb 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json index be4ffa74e..e0d8c0959 100644 --- a/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json +++ b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json @@ -19,7 +19,7 @@ "y": 0 }, "width": 180, - "height": 114, + "height": 94, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg index afeff911b..009c53f4e 100644 --- a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg @@ -1,9 +1,9 @@ -c4-person - - + .d2-4248901620 .fill-N1{fill:#0A0F25;} + .d2-4248901620 .fill-N2{fill:#676C7E;} + .d2-4248901620 .fill-N3{fill:#9499AB;} + .d2-4248901620 .fill-N4{fill:#CFD2DD;} + .d2-4248901620 .fill-N5{fill:#DEE1EB;} + .d2-4248901620 .fill-N6{fill:#EEF1F8;} + .d2-4248901620 .fill-N7{fill:#FFFFFF;} + .d2-4248901620 .fill-B1{fill:#0D32B2;} + .d2-4248901620 .fill-B2{fill:#0D32B2;} + .d2-4248901620 .fill-B3{fill:#E3E9FD;} + .d2-4248901620 .fill-B4{fill:#E3E9FD;} + .d2-4248901620 .fill-B5{fill:#EDF0FD;} + .d2-4248901620 .fill-B6{fill:#F7F8FE;} + .d2-4248901620 .fill-AA2{fill:#4A6FF3;} + .d2-4248901620 .fill-AA4{fill:#EDF0FD;} + .d2-4248901620 .fill-AA5{fill:#F7F8FE;} + .d2-4248901620 .fill-AB4{fill:#EDF0FD;} + .d2-4248901620 .fill-AB5{fill:#F7F8FE;} + .d2-4248901620 .stroke-N1{stroke:#0A0F25;} + .d2-4248901620 .stroke-N2{stroke:#676C7E;} + .d2-4248901620 .stroke-N3{stroke:#9499AB;} + .d2-4248901620 .stroke-N4{stroke:#CFD2DD;} + .d2-4248901620 .stroke-N5{stroke:#DEE1EB;} + .d2-4248901620 .stroke-N6{stroke:#EEF1F8;} + .d2-4248901620 .stroke-N7{stroke:#FFFFFF;} + .d2-4248901620 .stroke-B1{stroke:#0D32B2;} + .d2-4248901620 .stroke-B2{stroke:#0D32B2;} + .d2-4248901620 .stroke-B3{stroke:#E3E9FD;} + .d2-4248901620 .stroke-B4{stroke:#E3E9FD;} + .d2-4248901620 .stroke-B5{stroke:#EDF0FD;} + .d2-4248901620 .stroke-B6{stroke:#F7F8FE;} + .d2-4248901620 .stroke-AA2{stroke:#4A6FF3;} + .d2-4248901620 .stroke-AA4{stroke:#EDF0FD;} + .d2-4248901620 .stroke-AA5{stroke:#F7F8FE;} + .d2-4248901620 .stroke-AB4{stroke:#EDF0FD;} + .d2-4248901620 .stroke-AB5{stroke:#F7F8FE;} + .d2-4248901620 .background-color-N1{background-color:#0A0F25;} + .d2-4248901620 .background-color-N2{background-color:#676C7E;} + .d2-4248901620 .background-color-N3{background-color:#9499AB;} + .d2-4248901620 .background-color-N4{background-color:#CFD2DD;} + .d2-4248901620 .background-color-N5{background-color:#DEE1EB;} + .d2-4248901620 .background-color-N6{background-color:#EEF1F8;} + .d2-4248901620 .background-color-N7{background-color:#FFFFFF;} + .d2-4248901620 .background-color-B1{background-color:#0D32B2;} + .d2-4248901620 .background-color-B2{background-color:#0D32B2;} + .d2-4248901620 .background-color-B3{background-color:#E3E9FD;} + .d2-4248901620 .background-color-B4{background-color:#E3E9FD;} + .d2-4248901620 .background-color-B5{background-color:#EDF0FD;} + .d2-4248901620 .background-color-B6{background-color:#F7F8FE;} + .d2-4248901620 .background-color-AA2{background-color:#4A6FF3;} + .d2-4248901620 .background-color-AA4{background-color:#EDF0FD;} + .d2-4248901620 .background-color-AA5{background-color:#F7F8FE;} + .d2-4248901620 .background-color-AB4{background-color:#EDF0FD;} + .d2-4248901620 .background-color-AB5{background-color:#F7F8FE;} + .d2-4248901620 .color-N1{color:#0A0F25;} + .d2-4248901620 .color-N2{color:#676C7E;} + .d2-4248901620 .color-N3{color:#9499AB;} + .d2-4248901620 .color-N4{color:#CFD2DD;} + .d2-4248901620 .color-N5{color:#DEE1EB;} + .d2-4248901620 .color-N6{color:#EEF1F8;} + .d2-4248901620 .color-N7{color:#FFFFFF;} + .d2-4248901620 .color-B1{color:#0D32B2;} + .d2-4248901620 .color-B2{color:#0D32B2;} + .d2-4248901620 .color-B3{color:#E3E9FD;} + .d2-4248901620 .color-B4{color:#E3E9FD;} + .d2-4248901620 .color-B5{color:#EDF0FD;} + .d2-4248901620 .color-B6{color:#F7F8FE;} + .d2-4248901620 .color-AA2{color:#4A6FF3;} + .d2-4248901620 .color-AA4{color:#EDF0FD;} + .d2-4248901620 .color-AA5{color:#F7F8FE;} + .d2-4248901620 .color-AB4{color:#EDF0FD;} + .d2-4248901620 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-4248901620);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-4248901620);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-4248901620);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-4248901620);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-4248901620);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-4248901620);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-4248901620);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + + \ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json index 899afe63f..56a15e872 100644 --- a/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json +++ b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json @@ -19,7 +19,7 @@ "y": 12 }, "width": 180, - "height": 114, + "height": 94, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg index 68477ef9d..4de020608 100644 --- a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg @@ -1,9 +1,9 @@ -c4-person - - + .d2-108552620 .fill-N1{fill:#0A0F25;} + .d2-108552620 .fill-N2{fill:#676C7E;} + .d2-108552620 .fill-N3{fill:#9499AB;} + .d2-108552620 .fill-N4{fill:#CFD2DD;} + .d2-108552620 .fill-N5{fill:#DEE1EB;} + .d2-108552620 .fill-N6{fill:#EEF1F8;} + .d2-108552620 .fill-N7{fill:#FFFFFF;} + .d2-108552620 .fill-B1{fill:#0D32B2;} + .d2-108552620 .fill-B2{fill:#0D32B2;} + .d2-108552620 .fill-B3{fill:#E3E9FD;} + .d2-108552620 .fill-B4{fill:#E3E9FD;} + .d2-108552620 .fill-B5{fill:#EDF0FD;} + .d2-108552620 .fill-B6{fill:#F7F8FE;} + .d2-108552620 .fill-AA2{fill:#4A6FF3;} + .d2-108552620 .fill-AA4{fill:#EDF0FD;} + .d2-108552620 .fill-AA5{fill:#F7F8FE;} + .d2-108552620 .fill-AB4{fill:#EDF0FD;} + .d2-108552620 .fill-AB5{fill:#F7F8FE;} + .d2-108552620 .stroke-N1{stroke:#0A0F25;} + .d2-108552620 .stroke-N2{stroke:#676C7E;} + .d2-108552620 .stroke-N3{stroke:#9499AB;} + .d2-108552620 .stroke-N4{stroke:#CFD2DD;} + .d2-108552620 .stroke-N5{stroke:#DEE1EB;} + .d2-108552620 .stroke-N6{stroke:#EEF1F8;} + .d2-108552620 .stroke-N7{stroke:#FFFFFF;} + .d2-108552620 .stroke-B1{stroke:#0D32B2;} + .d2-108552620 .stroke-B2{stroke:#0D32B2;} + .d2-108552620 .stroke-B3{stroke:#E3E9FD;} + .d2-108552620 .stroke-B4{stroke:#E3E9FD;} + .d2-108552620 .stroke-B5{stroke:#EDF0FD;} + .d2-108552620 .stroke-B6{stroke:#F7F8FE;} + .d2-108552620 .stroke-AA2{stroke:#4A6FF3;} + .d2-108552620 .stroke-AA4{stroke:#EDF0FD;} + .d2-108552620 .stroke-AA5{stroke:#F7F8FE;} + .d2-108552620 .stroke-AB4{stroke:#EDF0FD;} + .d2-108552620 .stroke-AB5{stroke:#F7F8FE;} + .d2-108552620 .background-color-N1{background-color:#0A0F25;} + .d2-108552620 .background-color-N2{background-color:#676C7E;} + .d2-108552620 .background-color-N3{background-color:#9499AB;} + .d2-108552620 .background-color-N4{background-color:#CFD2DD;} + .d2-108552620 .background-color-N5{background-color:#DEE1EB;} + .d2-108552620 .background-color-N6{background-color:#EEF1F8;} + .d2-108552620 .background-color-N7{background-color:#FFFFFF;} + .d2-108552620 .background-color-B1{background-color:#0D32B2;} + .d2-108552620 .background-color-B2{background-color:#0D32B2;} + .d2-108552620 .background-color-B3{background-color:#E3E9FD;} + .d2-108552620 .background-color-B4{background-color:#E3E9FD;} + .d2-108552620 .background-color-B5{background-color:#EDF0FD;} + .d2-108552620 .background-color-B6{background-color:#F7F8FE;} + .d2-108552620 .background-color-AA2{background-color:#4A6FF3;} + .d2-108552620 .background-color-AA4{background-color:#EDF0FD;} + .d2-108552620 .background-color-AA5{background-color:#F7F8FE;} + .d2-108552620 .background-color-AB4{background-color:#EDF0FD;} + .d2-108552620 .background-color-AB5{background-color:#F7F8FE;} + .d2-108552620 .color-N1{color:#0A0F25;} + .d2-108552620 .color-N2{color:#676C7E;} + .d2-108552620 .color-N3{color:#9499AB;} + .d2-108552620 .color-N4{color:#CFD2DD;} + .d2-108552620 .color-N5{color:#DEE1EB;} + .d2-108552620 .color-N6{color:#EEF1F8;} + .d2-108552620 .color-N7{color:#FFFFFF;} + .d2-108552620 .color-B1{color:#0D32B2;} + .d2-108552620 .color-B2{color:#0D32B2;} + .d2-108552620 .color-B3{color:#E3E9FD;} + .d2-108552620 .color-B4{color:#E3E9FD;} + .d2-108552620 .color-B5{color:#EDF0FD;} + .d2-108552620 .color-B6{color:#F7F8FE;} + .d2-108552620 .color-AA2{color:#4A6FF3;} + .d2-108552620 .color-AA4{color:#EDF0FD;} + .d2-108552620 .color-AA5{color:#F7F8FE;} + .d2-108552620 .color-AB4{color:#EDF0FD;} + .d2-108552620 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-108552620);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-108552620);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-108552620);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-108552620);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-108552620);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-108552620);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-108552620);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + + \ No newline at end of file diff --git a/lib/shape/shape_c4_person.go b/lib/shape/shape_c4_person.go index 9cf8fbea3..99d47b07d 100644 --- a/lib/shape/shape_c4_person.go +++ b/lib/shape/shape_c4_person.go @@ -158,7 +158,10 @@ func (s shapeC4Person) GetDimensionsToFit(width, height, paddingX, paddingY floa verticalPadding := totalWidth * 0.06 // 3% top + 3% bottom totalHeight := contentHeight + bodyTop + verticalPadding - minHeight := totalWidth * 1.2 + // Calculate minimum height based on actual proportions + // Head height: 2 * headRadius = 0.44 * width + // Body should be at least half the width + minHeight := totalWidth * 0.95 // Reduced from 1.2 if totalHeight < minHeight { totalHeight = minHeight } @@ -168,5 +171,5 @@ func (s shapeC4Person) GetDimensionsToFit(width, height, paddingX, paddingY floa } func (s shapeC4Person) GetDefaultPadding() (paddingX, paddingY float64) { - return 20, defaultPadding * 1.5 + return 10, defaultPadding } From e9760389142ec2c5e2569596d2ff40bc0ecca435 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 13 Mar 2025 15:41:03 -0600 Subject: [PATCH 21/54] update --- .../c4-person-label/dagre/board.exp.json | 519 ++++++++++++++- .../c4-person-label/dagre/sketch.exp.svg | 584 +++++++++-------- .../txtar/c4-person-label/elk/board.exp.json | 421 +++++++++++- .../txtar/c4-person-label/elk/sketch.exp.svg | 584 +++++++++-------- .../c4-person-shape/dagre/board.exp.json | 58 +- .../c4-person-shape/dagre/sketch.exp.svg | 578 ++++++++--------- .../txtar/c4-person-shape/elk/board.exp.json | 42 +- .../txtar/c4-person-shape/elk/sketch.exp.svg | 578 ++++++++--------- .../txtar/c4-theme/dagre/board.exp.json | 172 ++--- .../txtar/c4-theme/dagre/sketch.exp.svg | 612 +++++++++--------- .../txtar/c4-theme/elk/board.exp.json | 86 +-- .../txtar/c4-theme/elk/sketch.exp.svg | 612 +++++++++--------- .../small-c4-person/dagre/board.exp.json | 2 +- .../small-c4-person/dagre/sketch.exp.svg | 156 ++--- .../txtar/small-c4-person/elk/board.exp.json | 2 +- .../txtar/small-c4-person/elk/sketch.exp.svg | 156 ++--- e2etests/txtar.txt | 44 ++ lib/shape/shape_c4_person.go | 76 +-- 18 files changed, 3135 insertions(+), 2147 deletions(-) diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json index d164ab8a8..f0edbecf7 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 0, - "y": 0 + "y": 8 }, "width": 410, - "height": 390, + "height": 284, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,10 +58,10 @@ "type": "c4-person", "pos": { "x": 470, - "y": 0 + "y": 8 }, "width": 410, - "height": 390, + "height": 284, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -100,10 +100,10 @@ "type": "c4-person", "pos": { "x": 940, - "y": 0 + "y": 8 }, "width": 410, - "height": 390, + "height": 284, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -136,9 +136,514 @@ "labelPosition": "INSIDE_BOTTOM_CENTER", "zIndex": 0, "level": 1 + }, + { + "id": "customer1", + "type": "c4-person", + "pos": { + "x": 1410, + "y": 0 + }, + "width": 448, + "height": 299, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank ccountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 388, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer2", + "type": "c4-person", + "pos": { + "x": 1137, + "y": 399 + }, + "width": 457, + "height": 378, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customerk\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 199, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer3", + "type": "c4-person", + "pos": { + "x": 1147, + "y": 877 + }, + "width": 457, + "height": 304, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer4", + "type": "c4-person", + "pos": { + "x": 1426, + "y": 1281 + }, + "width": 457, + "height": 304, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(customer1 -> customer2)[0]", + "src": "customer1", + "srcArrow": "none", + "dst": "customer2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1436, + "y": 297 + }, + { + "x": 1379.5999755859375, + "y": 338.6000061035156 + }, + { + "x": 1365.5999755859375, + "y": 359 + }, + { + "x": 1366, + "y": 399 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer2 -> customer3)[0]", + "src": "customer2", + "srcArrow": "none", + "dst": "customer3", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1358, + "y": 777 + }, + { + "x": 1356, + "y": 817 + }, + { + "x": 1356.5999755859375, + "y": 837.2000122070312 + }, + { + "x": 1361, + "y": 878 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer3 -> customer4)[0]", + "src": "customer3", + "srcArrow": "none", + "dst": "customer4", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1375, + "y": 1181 + }, + { + "x": 1375.4000244140625, + "y": 1221 + }, + { + "x": 1415, + "y": 1259.5999755859375 + }, + { + "x": 1573, + "y": 1374 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer4 -> customer1)[0]", + "src": "customer4", + "srcArrow": "none", + "dst": "customer1", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1654, + "y": 1281 + }, + { + "x": 1654, + "y": 1241 + }, + { + "x": 1654, + "y": 1190.5999755859375 + }, + { + "x": 1654, + "y": 1130 + }, + { + "x": 1654, + "y": 1069.4000244140625 + }, + { + "x": 1654, + "y": 988.5999755859375 + }, + { + "x": 1654, + "y": 928 + }, + { + "x": 1654, + "y": 867.4000244140625 + }, + { + "x": 1654, + "y": 779.2000122070312 + }, + { + "x": 1654, + "y": 707.5 + }, + { + "x": 1654, + "y": 635.7999877929688 + }, + { + "x": 1653, + "y": 339 + }, + { + "x": 1649, + "y": 299 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer1 -> customer3)[0]", + "src": "customer1", + "srcArrow": "none", + "dst": "customer3", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1634, + "y": 299 + }, + { + "x": 1634, + "y": 339 + }, + { + "x": 1634, + "y": 396.79998779296875 + }, + { + "x": 1634, + "y": 468.5 + }, + { + "x": 1634, + "y": 540.2000122070312 + }, + { + "x": 1598.800048828125, + "y": 854.5999755859375 + }, + { + "x": 1458, + "y": 965 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer3 -> customer2)[0]", + "src": "customer3", + "srcArrow": "none", + "dst": "customer2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1442, + "y": 911 + }, + { + "x": 1480.199951171875, + "y": 843.7999877929688 + }, + { + "x": 1484.5999755859375, + "y": 817 + }, + { + "x": 1464, + "y": 777 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 } ], - "connections": [], "root": { "id": "", "type": "", diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg index bab515547..7c7343d0c 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg @@ -1,14 +1,14 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-
- - - - +

Personal Banking Customer

+

[person]

+

A customer of the bank, with pekkrsonal bank ccountskks.

+

Personal Banking Customerk

+

[person]

+

A customer of the bank, with pekkrsonal bank accountskks.

+

A customer of the bank, with pekkrsonal bank accountskks.

+

A customer of the bank, with pekkrsonal bank accountskks.

+

Personal Banking Customer

+

[person]

+

A customer of the bank, with pekkrsonal bank accountskks.

+

Personal Banking Customer

+

[person]

+

A customer of the bank, with pekkrsonal bank accountskks.

+
+ + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json index 636de29e5..f55b84f10 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 12, - "y": 12 + "y": 19 }, "width": 410, - "height": 390, + "height": 284, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -57,11 +57,11 @@ "id": "c4mdperson2", "type": "c4-person", "pos": { - "x": 442, - "y": 12 + "x": 441, + "y": 19 }, "width": 410, - "height": 390, + "height": 284, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -99,11 +99,11 @@ "id": "c4mdperson3", "type": "c4-person", "pos": { - "x": 872, - "y": 12 + "x": 871, + "y": 19 }, "width": 410, - "height": 390, + "height": 284, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -136,9 +136,412 @@ "labelPosition": "INSIDE_BOTTOM_CENTER", "zIndex": 0, "level": 1 + }, + { + "id": "customer1", + "type": "c4-person", + "pos": { + "x": 1301, + "y": 12 + }, + "width": 448, + "height": 299, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank ccountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 388, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer2", + "type": "c4-person", + "pos": { + "x": 1028, + "y": 391 + }, + "width": 457, + "height": 378, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customerk\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 199, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer3", + "type": "c4-person", + "pos": { + "x": 1123, + "y": 849 + }, + "width": 457, + "height": 304, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer4", + "type": "c4-person", + "pos": { + "x": 1313, + "y": 1233 + }, + "width": 457, + "height": 304, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(customer1 -> customer2)[0]", + "src": "customer1", + "srcArrow": "none", + "dst": "customer2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1414, + "y": 311 + }, + { + "x": 1414, + "y": 540 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer2 -> customer3)[0]", + "src": "customer2", + "srcArrow": "none", + "dst": "customer3", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1237, + "y": 769 + }, + { + "x": 1237, + "y": 997 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer3 -> customer4)[0]", + "src": "customer3", + "srcArrow": "none", + "dst": "customer4", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1465, + "y": 1153 + }, + { + "x": 1466, + "y": 1284 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer4 -> customer1)[0]", + "src": "customer4", + "srcArrow": "none", + "dst": "customer1", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1620, + "y": 1290 + }, + { + "x": 1620, + "y": 311 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer1 -> customer3)[0]", + "src": "customer1", + "srcArrow": "none", + "dst": "customer3", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1526, + "y": 311 + }, + { + "x": 1526, + "y": 997 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer3 -> customer2)[0]", + "src": "customer3", + "srcArrow": "none", + "dst": "customer2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1334, + "y": 851 + }, + { + "x": 1334, + "y": 769 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 } ], - "connections": [], "root": { "id": "", "type": "", diff --git a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg index bfadee541..aafc758b9 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg @@ -1,14 +1,14 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-
- - - - +

Personal Banking Customer

+

[person]

+

A customer of the bank, with pekkrsonal bank ccountskks.

+

Personal Banking Customerk

+

[person]

+

A customer of the bank, with pekkrsonal bank accountskks.

+

A customer of the bank, with pekkrsonal bank accountskks.

+

A customer of the bank, with pekkrsonal bank accountskks.

+

Personal Banking Customer

+

[person]

+

A customer of the bank, with pekkrsonal bank accountskks.

+

Personal Banking Customer

+

[person]

+

A customer of the bank, with pekkrsonal bank accountskks.

+
+ + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json index 279169e81..196f6f710 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 0, - "y": 504 + "y": 469 }, "width": 336, - "height": 328, + "height": 286, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -61,7 +61,7 @@ "y": 0 }, "width": 139, - "height": 132, + "height": 107, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -100,7 +100,7 @@ "type": "person", "pos": { "x": 101, - "y": 309 + "y": 279 }, "width": 134, "height": 89, @@ -142,10 +142,10 @@ "type": "rectangle", "pos": { "x": 386, - "y": 273 + "y": 248 }, "width": 210, - "height": 515, + "height": 484, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -184,10 +184,10 @@ "type": "c4-person", "pos": { "x": 449, - "y": 303 + "y": 278 }, "width": 84, - "height": 101, + "height": 91, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -226,7 +226,7 @@ "type": "c4-person", "pos": { "x": 416, - "y": 578 + "y": 522 }, "width": 150, "height": 180, @@ -292,19 +292,19 @@ "route": [ { "x": 168, - "y": 424 + "y": 394 }, { "x": 168, - "y": 448 + "y": 414 }, { "x": 168, - "y": 461 + "y": 429 }, { "x": 168, - "y": 489 + "y": 469 } ], "isCurve": true, @@ -339,20 +339,20 @@ "link": "", "route": [ { - "x": 262, - "y": 119 + "x": 263, + "y": 100 }, { - "x": 186.8000030517578, - "y": 177.8000030517578 + "x": 187, + "y": 154 }, { "x": 168, - "y": 264.20001220703125 + "y": 238.1999969482422 }, { "x": 168, - "y": 309 + "y": 279 } ], "isCurve": true, @@ -387,20 +387,20 @@ "link": "", "route": [ { - "x": 397, - "y": 119 + "x": 395, + "y": 100 }, { - "x": 472.20001220703125, - "y": 177.8000030517578 + "x": 471.79998779296875, + "y": 154 }, { "x": 491, - "y": 263 + "y": 238 }, { "x": 491, - "y": 303 + "y": 278 } ], "isCurve": true, @@ -436,19 +436,19 @@ "route": [ { "x": 491, - "y": 405 + "y": 369 }, { "x": 491, - "y": 444.20001220703125 + "y": 409 }, { "x": 491, - "y": 478.6000061035156 + "y": 439.6000061035156 }, { "x": 491, - "y": 577 + "y": 522 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg index 65e12a1b3..e3498e842 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json index 95cb99c31..7c1686a85 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 12, - "y": 935 + "y": 900 }, "width": 336, - "height": 328, + "height": 286, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -61,7 +61,7 @@ "y": 12 }, "width": 139, - "height": 132, + "height": 107, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -100,7 +100,7 @@ "type": "person", "pos": { "x": 113, - "y": 750 + "y": 715 }, "width": 134, "height": 89, @@ -142,10 +142,10 @@ "type": "rectangle", "pos": { "x": 256, - "y": 229 + "y": 204 }, "width": 250, - "height": 451, + "height": 441, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -184,10 +184,10 @@ "type": "c4-person", "pos": { "x": 339, - "y": 279 + "y": 254 }, "width": 84, - "height": 101, + "height": 91, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -226,7 +226,7 @@ "type": "c4-person", "pos": { "x": 306, - "y": 450 + "y": 415 }, "width": 150, "height": 180, @@ -292,11 +292,11 @@ "route": [ { "x": 180, - "y": 865 + "y": 830 }, { "x": 180, - "y": 920 + "y": 900 } ], "animated": false, @@ -331,19 +331,19 @@ "route": [ { "x": 258, - "y": 144 + "y": 119 }, { "x": 257.5830078125, - "y": 184 + "y": 159 }, { "x": 180, - "y": 184 + "y": 159 }, { "x": 180, - "y": 750 + "y": 715 } ], "animated": false, @@ -378,19 +378,19 @@ "route": [ { "x": 304, - "y": 144 + "y": 119 }, { "x": 303.9159851074219, - "y": 184 + "y": 159 }, { "x": 381.5, - "y": 184 + "y": 159 }, { "x": 382, - "y": 279 + "y": 254 } ], "animated": false, @@ -425,11 +425,11 @@ "route": [ { "x": 381, - "y": 381 + "y": 345 }, { "x": 382, - "y": 449 + "y": 415 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg index d7fdb9e74..ec77604b2 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json index e462c9a73..9f035283b 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json @@ -19,7 +19,7 @@ "y": 0 }, "width": 415, - "height": 394, + "height": 285, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 147, - "y": 551 + "y": 442 }, "width": 2407, "height": 915, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 177, - "y": 581 + "y": 472 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 390, - "y": 866 + "y": 757 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 1123, - "y": 866 + "y": 757 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 1246, - "y": 1167 + "y": 1058 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1890, - "y": 866 + "y": 757 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 2410, - "y": 1603 + "y": 1494 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 0, - "y": 1603 + "y": 1494 }, "width": 629, "height": 164, @@ -418,19 +418,19 @@ "route": [ { "x": 1089, - "y": 262 + "y": 194 }, { "x": 579.4000244140625, - "y": 422.3999938964844 + "y": 321.6000061035156 }, { "x": 452, - "y": 541 + "y": 432 }, { "x": 452, - "y": 581 + "y": 472 } ], "isCurve": true, @@ -466,19 +466,19 @@ "route": [ { "x": 452, - "y": 744.5 + "y": 635.5 }, { "x": 452, - "y": 793.2999877929688 + "y": 684.2999877929688 }, { "x": 472.3999938964844, - "y": 817.7000122070312 + "y": 708.7000122070312 }, { "x": 554, - "y": 866.5 + "y": 757.5 } ], "isCurve": true, @@ -513,44 +513,44 @@ "link": "", "route": [ { - "x": 1092, - "y": 348 + "x": 1093, + "y": 262 }, { - "x": 968, - "y": 439.6000061035156 + "x": 968.2000122070312, + "y": 335.20001220703125 }, { "x": 937, - "y": 476.20001220703125 + "y": 367.20001220703125 }, { "x": 937, - "y": 496.75 + "y": 387.75 }, { "x": 937, - "y": 517.2990112304688 + "y": 408.29998779296875 }, { "x": 937, - "y": 557.4000244140625 + "y": 448.3999938964844 }, { "x": 937, - "y": 597 + "y": 488 }, { "x": 937, - "y": 636.5999755859375 + "y": 527.5999755859375 }, { "x": 916.5999755859375, - "y": 817.7000122070312 + "y": 708.7000122070312 }, { "x": 835, - "y": 866.5 + "y": 757.5 } ], "isCurve": true, @@ -585,44 +585,44 @@ "link": "", "route": [ { - "x": 1430, - "y": 394 + "x": 1418, + "y": 285 }, { - "x": 1466.800048828125, - "y": 448.79998779296875 + "x": 1464.4000244140625, + "y": 339.79998779296875 }, { "x": 1476, - "y": 476.20001220703125 + "y": 367.20001220703125 }, { "x": 1476, - "y": 496.75 + "y": 387.75 }, { "x": 1476, - "y": 517.2990112304688 + "y": 408.29998779296875 }, { "x": 1476, - "y": 557.4000244140625 + "y": 448.3999938964844 }, { "x": 1476, - "y": 597 + "y": 488 }, { "x": 1476, - "y": 636.5999755859375 + "y": 527.5999755859375 }, { "x": 1476, - "y": 817.7000122070312 + "y": 708.7000122070312 }, { "x": 1476, - "y": 866.5 + "y": 757.5 } ], "isCurve": true, @@ -658,19 +658,19 @@ "route": [ { "x": 694.5, - "y": 1029.5 + "y": 920.5 }, { "x": 694.5, - "y": 1084.699951171875 + "y": 975.7000122070312 }, { "x": 804.7000122070312, - "y": 1119.7220458984375 + "y": 1010.7219848632812 }, { "x": 1245.5, - "y": 1204.6099853515625 + "y": 1095.6099853515625 } ], "isCurve": true, @@ -706,19 +706,19 @@ "route": [ { "x": 1476, - "y": 1029.5 + "y": 920.5 }, { "x": 1476, - "y": 1084.699951171875 + "y": 975.7000122070312 }, { "x": 1476, - "y": 1112.300048828125 + "y": 1003.2999877929688 }, { "x": 1476, - "y": 1167.5 + "y": 1058.5 } ], "isCurve": true, @@ -754,19 +754,19 @@ "route": [ { "x": 1245.5, - "y": 1275.1949462890625 + "y": 1166.1949462890625 }, { "x": 500.6990051269531, - "y": 1427.8389892578125 + "y": 1318.8389892578125 }, { "x": 314.5, - "y": 1548.300048828125 + "y": 1439.300048828125 }, { "x": 314.5, - "y": 1603.5 + "y": 1494.5 } ], "isCurve": true, @@ -802,103 +802,103 @@ "route": [ { "x": 1505, - "y": 238 + "y": 175 }, { "x": 2410.60009765625, - "y": 417.6000061035156 + "y": 317.79998779296875 }, { "x": 2637, - "y": 476.20001220703125 + "y": 367.20001220703125 }, { "x": 2637, - "y": 496.75 + "y": 387.75 }, { "x": 2637, - "y": 517.2990112304688 + "y": 408.29998779296875 }, { "x": 2637, - "y": 557.4000244140625 + "y": 448.3999938964844 }, { "x": 2637, - "y": 597 + "y": 488 }, { "x": 2637, - "y": 636.5999755859375 + "y": 527.5999755859375 }, { "x": 2637, - "y": 691.5 + "y": 582.5 }, { "x": 2637, - "y": 734.25 + "y": 625.25 }, { "x": 2637, - "y": 777 + "y": 668 }, { "x": 2637, - "y": 834 + "y": 725 }, { "x": 2637, - "y": 876.75 + "y": 767.75 }, { "x": 2637, - "y": 919.5 + "y": 810.5 }, { "x": 2637, - "y": 978.0999755859375 + "y": 869.0999755859375 }, { "x": 2637, - "y": 1023.25 + "y": 914.25 }, { "x": 2637, - "y": 1068.4000244140625 + "y": 959.4000244140625 }, { "x": 2637, - "y": 1128.5999755859375 + "y": 1019.5999755859375 }, { "x": 2637, - "y": 1173.75 + "y": 1064.75 }, { "x": 2637, - "y": 1218.9000244140625 + "y": 1109.9000244140625 }, { "x": 2637, - "y": 1292.4000244140625 + "y": 1183.4000244140625 }, { "x": 2637, - "y": 1357.5 + "y": 1248.5 }, { "x": 2637, - "y": 1422.5999755859375 + "y": 1313.5999755859375 }, { "x": 2632.800048828125, - "y": 1548.300048828125 + "y": 1439.300048828125 }, { "x": 2616, - "y": 1603.5 + "y": 1494.5 } ], "isCurve": true, @@ -934,19 +934,19 @@ "route": [ { "x": 1707.5, - "y": 1282.843994140625 + "y": 1173.843994140625 }, { "x": 2241.5, - "y": 1429.3680419921875 + "y": 1320.3680419921875 }, { "x": 2394.39990234375, - "y": 1548.300048828125 + "y": 1439.300048828125 }, { "x": 2472, - "y": 1603.5 + "y": 1494.5 } ], "isCurve": true, @@ -982,19 +982,19 @@ "route": [ { "x": 2206.5, - "y": 1029.5 + "y": 920.5 }, { "x": 2206.5, - "y": 1084.699951171875 + "y": 975.7000122070312 }, { "x": 2106.5, - "y": 1119.0999755859375 + "y": 1010.0999755859375 }, { "x": 1706.5, - "y": 1201.5 + "y": 1092.5 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg index 2613fb8b3..4e4ff9f84 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json index 4d6d3ccd8..3d9b2d3b7 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json @@ -19,7 +19,7 @@ "y": 12 }, "width": 415, - "height": 394, + "height": 285, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 12, - "y": 658 + "y": 549 }, "width": 2218, "height": 1035, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 62, - "y": 708 + "y": 599 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 190, - "y": 1043 + "y": 934 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 819, - "y": 1043 + "y": 934 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 942, - "y": 1394 + "y": 1285 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1546, - "y": 1043 + "y": 934 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 1746, - "y": 1895 + "y": 1786 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 781, - "y": 1895 + "y": 1786 }, "width": 629, "height": 164, @@ -418,19 +418,19 @@ "route": [ { "x": 788, - "y": 406 + "y": 297 }, { "x": 787.75, - "y": 446 + "y": 337 }, { "x": 359.25, - "y": 446 + "y": 337 }, { "x": 359.25, - "y": 708 + "y": 599 } ], "animated": false, @@ -465,11 +465,11 @@ "route": [ { "x": 393, - "y": 872 + "y": 763 }, { "x": 393, - "y": 1043 + "y": 934 } ], "animated": false, @@ -504,19 +504,19 @@ "route": [ { "x": 871, - "y": 406 + "y": 297 }, { "x": 870.75, - "y": 496 + "y": 387 }, { "x": 652, - "y": 496 + "y": 387 }, { "x": 652, - "y": 1043 + "y": 934 } ], "animated": false, @@ -551,11 +551,11 @@ "route": [ { "x": 954, - "y": 406 + "y": 297 }, { "x": 953.75, - "y": 1043 + "y": 934 } ], "animated": false, @@ -590,19 +590,19 @@ "route": [ { "x": 494.5, - "y": 1207 + "y": 1098 }, { "x": 494.5, - "y": 1354 + "y": 1245 }, { "x": 1057.25, - "y": 1354 + "y": 1245 }, { "x": 1057.25, - "y": 1394 + "y": 1285 } ], "animated": false, @@ -637,11 +637,11 @@ "route": [ { "x": 1172.5, - "y": 1207 + "y": 1098 }, { "x": 1172.5, - "y": 1394 + "y": 1285 } ], "animated": false, @@ -676,11 +676,11 @@ "route": [ { "x": 1095.666015625, - "y": 1558 + "y": 1449 }, { "x": 1095.666015625, - "y": 1895 + "y": 1786 } ], "animated": false, @@ -715,27 +715,27 @@ "route": [ { "x": 1037, - "y": 406 + "y": 297 }, { "x": 1036.75, - "y": 446 + "y": 337 }, { "x": 2303.5, - "y": 446 + "y": 337 }, { "x": 2303.5, - "y": 1855 + "y": 1746 }, { "x": 1986.8330078125, - "y": 1855 + "y": 1746 }, { "x": 1986.8330078125, - "y": 1895 + "y": 1786 } ], "animated": false, @@ -770,19 +770,19 @@ "route": [ { "x": 1249.3330078125, - "y": 1558 + "y": 1449 }, { "x": 1249.3330078125, - "y": 1855 + "y": 1746 }, { "x": 1866.8330078125, - "y": 1855 + "y": 1746 }, { "x": 1866.8330078125, - "y": 1895 + "y": 1786 } ], "animated": false, @@ -817,19 +817,19 @@ "route": [ { "x": 1863, - "y": 1207 + "y": 1098 }, { "x": 1863, - "y": 1354 + "y": 1245 }, { "x": 1287.75, - "y": 1354 + "y": 1245 }, { "x": 1287.75, - "y": 1394 + "y": 1285 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg index 31b06adcb..dc7185d81 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json index e0d8c0959..3b7bdaf8e 100644 --- a/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json +++ b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json @@ -19,7 +19,7 @@ "y": 0 }, "width": 180, - "height": 94, + "height": 85, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg index 009c53f4e..6f92c0949 100644 --- a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg @@ -1,9 +1,9 @@ -c4-person - - + .d2-680955506 .fill-N1{fill:#0A0F25;} + .d2-680955506 .fill-N2{fill:#676C7E;} + .d2-680955506 .fill-N3{fill:#9499AB;} + .d2-680955506 .fill-N4{fill:#CFD2DD;} + .d2-680955506 .fill-N5{fill:#DEE1EB;} + .d2-680955506 .fill-N6{fill:#EEF1F8;} + .d2-680955506 .fill-N7{fill:#FFFFFF;} + .d2-680955506 .fill-B1{fill:#0D32B2;} + .d2-680955506 .fill-B2{fill:#0D32B2;} + .d2-680955506 .fill-B3{fill:#E3E9FD;} + .d2-680955506 .fill-B4{fill:#E3E9FD;} + .d2-680955506 .fill-B5{fill:#EDF0FD;} + .d2-680955506 .fill-B6{fill:#F7F8FE;} + .d2-680955506 .fill-AA2{fill:#4A6FF3;} + .d2-680955506 .fill-AA4{fill:#EDF0FD;} + .d2-680955506 .fill-AA5{fill:#F7F8FE;} + .d2-680955506 .fill-AB4{fill:#EDF0FD;} + .d2-680955506 .fill-AB5{fill:#F7F8FE;} + .d2-680955506 .stroke-N1{stroke:#0A0F25;} + .d2-680955506 .stroke-N2{stroke:#676C7E;} + .d2-680955506 .stroke-N3{stroke:#9499AB;} + .d2-680955506 .stroke-N4{stroke:#CFD2DD;} + .d2-680955506 .stroke-N5{stroke:#DEE1EB;} + .d2-680955506 .stroke-N6{stroke:#EEF1F8;} + .d2-680955506 .stroke-N7{stroke:#FFFFFF;} + .d2-680955506 .stroke-B1{stroke:#0D32B2;} + .d2-680955506 .stroke-B2{stroke:#0D32B2;} + .d2-680955506 .stroke-B3{stroke:#E3E9FD;} + .d2-680955506 .stroke-B4{stroke:#E3E9FD;} + .d2-680955506 .stroke-B5{stroke:#EDF0FD;} + .d2-680955506 .stroke-B6{stroke:#F7F8FE;} + .d2-680955506 .stroke-AA2{stroke:#4A6FF3;} + .d2-680955506 .stroke-AA4{stroke:#EDF0FD;} + .d2-680955506 .stroke-AA5{stroke:#F7F8FE;} + .d2-680955506 .stroke-AB4{stroke:#EDF0FD;} + .d2-680955506 .stroke-AB5{stroke:#F7F8FE;} + .d2-680955506 .background-color-N1{background-color:#0A0F25;} + .d2-680955506 .background-color-N2{background-color:#676C7E;} + .d2-680955506 .background-color-N3{background-color:#9499AB;} + .d2-680955506 .background-color-N4{background-color:#CFD2DD;} + .d2-680955506 .background-color-N5{background-color:#DEE1EB;} + .d2-680955506 .background-color-N6{background-color:#EEF1F8;} + .d2-680955506 .background-color-N7{background-color:#FFFFFF;} + .d2-680955506 .background-color-B1{background-color:#0D32B2;} + .d2-680955506 .background-color-B2{background-color:#0D32B2;} + .d2-680955506 .background-color-B3{background-color:#E3E9FD;} + .d2-680955506 .background-color-B4{background-color:#E3E9FD;} + .d2-680955506 .background-color-B5{background-color:#EDF0FD;} + .d2-680955506 .background-color-B6{background-color:#F7F8FE;} + .d2-680955506 .background-color-AA2{background-color:#4A6FF3;} + .d2-680955506 .background-color-AA4{background-color:#EDF0FD;} + .d2-680955506 .background-color-AA5{background-color:#F7F8FE;} + .d2-680955506 .background-color-AB4{background-color:#EDF0FD;} + .d2-680955506 .background-color-AB5{background-color:#F7F8FE;} + .d2-680955506 .color-N1{color:#0A0F25;} + .d2-680955506 .color-N2{color:#676C7E;} + .d2-680955506 .color-N3{color:#9499AB;} + .d2-680955506 .color-N4{color:#CFD2DD;} + .d2-680955506 .color-N5{color:#DEE1EB;} + .d2-680955506 .color-N6{color:#EEF1F8;} + .d2-680955506 .color-N7{color:#FFFFFF;} + .d2-680955506 .color-B1{color:#0D32B2;} + .d2-680955506 .color-B2{color:#0D32B2;} + .d2-680955506 .color-B3{color:#E3E9FD;} + .d2-680955506 .color-B4{color:#E3E9FD;} + .d2-680955506 .color-B5{color:#EDF0FD;} + .d2-680955506 .color-B6{color:#F7F8FE;} + .d2-680955506 .color-AA2{color:#4A6FF3;} + .d2-680955506 .color-AA4{color:#EDF0FD;} + .d2-680955506 .color-AA5{color:#F7F8FE;} + .d2-680955506 .color-AB4{color:#EDF0FD;} + .d2-680955506 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-680955506);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-680955506);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-680955506);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-680955506);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-680955506);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-680955506);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-680955506);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-680955506);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-680955506);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-680955506);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-680955506);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-680955506);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-680955506);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-680955506);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-680955506);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-680955506);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-680955506);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-680955506);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + + \ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json index 56a15e872..342178f5f 100644 --- a/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json +++ b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json @@ -19,7 +19,7 @@ "y": 12 }, "width": 180, - "height": 94, + "height": 85, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg index 4de020608..d41c6027d 100644 --- a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg @@ -1,9 +1,9 @@ -c4-person - - + .d2-2607365194 .fill-N1{fill:#0A0F25;} + .d2-2607365194 .fill-N2{fill:#676C7E;} + .d2-2607365194 .fill-N3{fill:#9499AB;} + .d2-2607365194 .fill-N4{fill:#CFD2DD;} + .d2-2607365194 .fill-N5{fill:#DEE1EB;} + .d2-2607365194 .fill-N6{fill:#EEF1F8;} + .d2-2607365194 .fill-N7{fill:#FFFFFF;} + .d2-2607365194 .fill-B1{fill:#0D32B2;} + .d2-2607365194 .fill-B2{fill:#0D32B2;} + .d2-2607365194 .fill-B3{fill:#E3E9FD;} + .d2-2607365194 .fill-B4{fill:#E3E9FD;} + .d2-2607365194 .fill-B5{fill:#EDF0FD;} + .d2-2607365194 .fill-B6{fill:#F7F8FE;} + .d2-2607365194 .fill-AA2{fill:#4A6FF3;} + .d2-2607365194 .fill-AA4{fill:#EDF0FD;} + .d2-2607365194 .fill-AA5{fill:#F7F8FE;} + .d2-2607365194 .fill-AB4{fill:#EDF0FD;} + .d2-2607365194 .fill-AB5{fill:#F7F8FE;} + .d2-2607365194 .stroke-N1{stroke:#0A0F25;} + .d2-2607365194 .stroke-N2{stroke:#676C7E;} + .d2-2607365194 .stroke-N3{stroke:#9499AB;} + .d2-2607365194 .stroke-N4{stroke:#CFD2DD;} + .d2-2607365194 .stroke-N5{stroke:#DEE1EB;} + .d2-2607365194 .stroke-N6{stroke:#EEF1F8;} + .d2-2607365194 .stroke-N7{stroke:#FFFFFF;} + .d2-2607365194 .stroke-B1{stroke:#0D32B2;} + .d2-2607365194 .stroke-B2{stroke:#0D32B2;} + .d2-2607365194 .stroke-B3{stroke:#E3E9FD;} + .d2-2607365194 .stroke-B4{stroke:#E3E9FD;} + .d2-2607365194 .stroke-B5{stroke:#EDF0FD;} + .d2-2607365194 .stroke-B6{stroke:#F7F8FE;} + .d2-2607365194 .stroke-AA2{stroke:#4A6FF3;} + .d2-2607365194 .stroke-AA4{stroke:#EDF0FD;} + .d2-2607365194 .stroke-AA5{stroke:#F7F8FE;} + .d2-2607365194 .stroke-AB4{stroke:#EDF0FD;} + .d2-2607365194 .stroke-AB5{stroke:#F7F8FE;} + .d2-2607365194 .background-color-N1{background-color:#0A0F25;} + .d2-2607365194 .background-color-N2{background-color:#676C7E;} + .d2-2607365194 .background-color-N3{background-color:#9499AB;} + .d2-2607365194 .background-color-N4{background-color:#CFD2DD;} + .d2-2607365194 .background-color-N5{background-color:#DEE1EB;} + .d2-2607365194 .background-color-N6{background-color:#EEF1F8;} + .d2-2607365194 .background-color-N7{background-color:#FFFFFF;} + .d2-2607365194 .background-color-B1{background-color:#0D32B2;} + .d2-2607365194 .background-color-B2{background-color:#0D32B2;} + .d2-2607365194 .background-color-B3{background-color:#E3E9FD;} + .d2-2607365194 .background-color-B4{background-color:#E3E9FD;} + .d2-2607365194 .background-color-B5{background-color:#EDF0FD;} + .d2-2607365194 .background-color-B6{background-color:#F7F8FE;} + .d2-2607365194 .background-color-AA2{background-color:#4A6FF3;} + .d2-2607365194 .background-color-AA4{background-color:#EDF0FD;} + .d2-2607365194 .background-color-AA5{background-color:#F7F8FE;} + .d2-2607365194 .background-color-AB4{background-color:#EDF0FD;} + .d2-2607365194 .background-color-AB5{background-color:#F7F8FE;} + .d2-2607365194 .color-N1{color:#0A0F25;} + .d2-2607365194 .color-N2{color:#676C7E;} + .d2-2607365194 .color-N3{color:#9499AB;} + .d2-2607365194 .color-N4{color:#CFD2DD;} + .d2-2607365194 .color-N5{color:#DEE1EB;} + .d2-2607365194 .color-N6{color:#EEF1F8;} + .d2-2607365194 .color-N7{color:#FFFFFF;} + .d2-2607365194 .color-B1{color:#0D32B2;} + .d2-2607365194 .color-B2{color:#0D32B2;} + .d2-2607365194 .color-B3{color:#E3E9FD;} + .d2-2607365194 .color-B4{color:#E3E9FD;} + .d2-2607365194 .color-B5{color:#EDF0FD;} + .d2-2607365194 .color-B6{color:#F7F8FE;} + .d2-2607365194 .color-AA2{color:#4A6FF3;} + .d2-2607365194 .color-AA4{color:#EDF0FD;} + .d2-2607365194 .color-AA5{color:#F7F8FE;} + .d2-2607365194 .color-AB4{color:#EDF0FD;} + .d2-2607365194 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-2607365194);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-2607365194);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-2607365194);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-2607365194);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-2607365194);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-2607365194);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-2607365194);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-2607365194);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-2607365194);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-2607365194);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-2607365194);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-2607365194);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-2607365194);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-2607365194);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-2607365194);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-2607365194);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-2607365194);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-2607365194);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + + \ No newline at end of file diff --git a/e2etests/txtar.txt b/e2etests/txtar.txt index 89d18ce17..1b7eaca96 100644 --- a/e2etests/txtar.txt +++ b/e2etests/txtar.txt @@ -1221,3 +1221,47 @@ A customer of the bank, with personal bank accounts shape: c4-person label.near: bottom-center } + + customer1: |md + ## Personal Banking Customer + [person] + + A customer of the bank, with pekkrsonal bank ccountskks. +| { + shape: c4-person +} + +customer2: |md + ## Personal Banking Customerk + [person] + + A customer of the bank, with pekkrsonal bank accountskks. + + A customer of the bank, with pekkrsonal bank accountskks. + + A customer of the bank, with pekkrsonal bank accountskks. +| { + shape: c4-person +} + +customer3: |md + ## Personal Banking Customer + [person] + + A customer of the bank, with pekkrsonal bank accountskks. +| { + shape: c4-person +} + +customer4: |md + ## Personal Banking Customer + [person] + + A customer of the bank, with pekkrsonal bank accountskks. +| { + shape: c4-person +} + +customer1 -> customer2 -> customer3 -> customer4 +customer4 -> customer1 -> customer3 -> customer2 + diff --git a/lib/shape/shape_c4_person.go b/lib/shape/shape_c4_person.go index 99d47b07d..a9b7b9560 100644 --- a/lib/shape/shape_c4_person.go +++ b/lib/shape/shape_c4_person.go @@ -32,26 +32,24 @@ const ( func (s shapeC4Person) GetInnerBox() *geo.Box { width := s.Box.Width - height := s.Box.Height - headRadius := width * 0.22 - headCenterY := height * 0.18 + // Reduce head radius from 22% to 18% of width + headRadius := width * 0.18 + headCenterY := headRadius bodyTop := headCenterY + headRadius*0.8 - // Use a small fixed percentage instead of the full corner radius - horizontalPadding := width * 0.05 // 5% padding + // Horizontal padding = 5% of width + horizontalPadding := width * 0.05 + + // Vertical padding = 3% of width (not height) + vertPadding := width * 0.03 tl := s.Box.TopLeft.Copy() tl.X += horizontalPadding + tl.Y += bodyTop + vertPadding - // Add vertical padding - tl.Y += bodyTop + height*0.03 - - // Width minus padding on both sides innerWidth := width - (horizontalPadding * 2) - - // Add bottom padding - innerHeight := height - (tl.Y - s.Box.TopLeft.Y) - (height * 0.03) + innerHeight := s.Box.Height - bodyTop - (vertPadding * 2) return geo.NewBox(tl, innerWidth, innerHeight) } @@ -62,8 +60,10 @@ func bodyPath(box *geo.Box) *svg.SvgPathContext { pc := svg.NewSVGPathContext(box.TopLeft, 1, 1) - headRadius := width * 0.22 - headCenterY := height * 0.18 + // Reduce head radius from 22% to 18% of width + headRadius := width * 0.18 + // Adjust headCenterY to ensure head fits within box + headCenterY := headRadius bodyTop := headCenterY + headRadius*0.8 bodyWidth := width bodyHeight := height - bodyTop @@ -88,13 +88,13 @@ func bodyPath(box *geo.Box) *svg.SvgPathContext { func headPath(box *geo.Box) *svg.SvgPathContext { width := box.Width - height := box.Height - pc := svg.NewSVGPathContext(box.TopLeft, 1, 1) - headRadius := width * 0.22 + // Reduce head radius from 22% to 18% of width + headRadius := width * 0.18 headCenterX := width / 2 - headCenterY := height * 0.18 + // Adjust headCenterY to ensure head fits within box + headCenterY := headRadius pc.StartAt(pc.Absolute(headCenterX, headCenterY-headRadius)) @@ -123,13 +123,13 @@ func headPath(box *geo.Box) *svg.SvgPathContext { func (s shapeC4Person) Perimeter() []geo.Intersectable { width := s.Box.Width - height := s.Box.Height bodyPerimeter := bodyPath(s.Box).Path - headRadius := width * 0.22 + // Reduce head radius from 22% to 18% of width + headRadius := width * 0.18 headCenterX := s.Box.TopLeft.X + width/2 - headCenterY := s.Box.TopLeft.Y + height*0.18 + headCenterY := s.Box.TopLeft.Y + headRadius headCenter := geo.NewPoint(headCenterX, headCenterY) headEllipse := geo.NewEllipse(headCenter, headRadius, headRadius) @@ -145,28 +145,28 @@ func (s shapeC4Person) GetSVGPathData() []string { } func (s shapeC4Person) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { - contentWidth := width + paddingX - contentHeight := height + paddingY + // Start with content dimensions + padding + totalWidth := width + paddingX + totalHeight := height + paddingY - // Account for 10% total horizontal padding (5% on each side) - totalWidth := contentWidth / 0.9 - headRadius := totalWidth * 0.22 - headCenterY := totalWidth * 0.18 - bodyTop := headCenterY + headRadius*0.8 + // Reduce head radius from 22% to 18% of width + headRadius := totalWidth * 0.18 - // Include vertical padding from GetInnerBox - verticalPadding := totalWidth * 0.06 // 3% top + 3% bottom - totalHeight := contentHeight + bodyTop + verticalPadding + // Head center is now at headRadius from the top + headCenterY := headRadius - // Calculate minimum height based on actual proportions - // Head height: 2 * headRadius = 0.44 * width - // Body should be at least half the width - minHeight := totalWidth * 0.95 // Reduced from 1.2 - if totalHeight < minHeight { - totalHeight = minHeight - } + // Body starts at headCenterY + headRadius*0.8 + bodyTopPosition := headCenterY + headRadius*0.8 + // Add space for body (head is now fully contained) + totalHeight += bodyTopPosition + + // Horizontal padding is handled in GetInnerBox (5% on each side) + totalWidth /= 0.9 + + // Prevent the shape's aspect ratio from becoming too extreme totalWidth, totalHeight = LimitAR(totalWidth, totalHeight, C4_PERSON_AR_LIMIT) + return math.Ceil(totalWidth), math.Ceil(totalHeight) } From 5b55e4d81826a7d830e7474d2aec1146ab6e8005 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 13 Mar 2025 19:24:54 -0600 Subject: [PATCH 22/54] Revert "update" This reverts commit e9760389142ec2c5e2569596d2ff40bc0ecca435. --- .../c4-person-label/dagre/board.exp.json | 519 +-------------- .../c4-person-label/dagre/sketch.exp.svg | 584 ++++++++--------- .../txtar/c4-person-label/elk/board.exp.json | 421 +----------- .../txtar/c4-person-label/elk/sketch.exp.svg | 584 ++++++++--------- .../c4-person-shape/dagre/board.exp.json | 58 +- .../c4-person-shape/dagre/sketch.exp.svg | 578 ++++++++--------- .../txtar/c4-person-shape/elk/board.exp.json | 42 +- .../txtar/c4-person-shape/elk/sketch.exp.svg | 578 ++++++++--------- .../txtar/c4-theme/dagre/board.exp.json | 172 ++--- .../txtar/c4-theme/dagre/sketch.exp.svg | 612 +++++++++--------- .../txtar/c4-theme/elk/board.exp.json | 86 +-- .../txtar/c4-theme/elk/sketch.exp.svg | 612 +++++++++--------- .../small-c4-person/dagre/board.exp.json | 2 +- .../small-c4-person/dagre/sketch.exp.svg | 156 ++--- .../txtar/small-c4-person/elk/board.exp.json | 2 +- .../txtar/small-c4-person/elk/sketch.exp.svg | 156 ++--- e2etests/txtar.txt | 44 -- lib/shape/shape_c4_person.go | 76 +-- 18 files changed, 2147 insertions(+), 3135 deletions(-) diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json index f0edbecf7..d164ab8a8 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 0, - "y": 8 + "y": 0 }, "width": 410, - "height": 284, + "height": 390, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,10 +58,10 @@ "type": "c4-person", "pos": { "x": 470, - "y": 8 + "y": 0 }, "width": 410, - "height": 284, + "height": 390, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -100,10 +100,10 @@ "type": "c4-person", "pos": { "x": 940, - "y": 8 + "y": 0 }, "width": 410, - "height": 284, + "height": 390, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -136,514 +136,9 @@ "labelPosition": "INSIDE_BOTTOM_CENTER", "zIndex": 0, "level": 1 - }, - { - "id": "customer1", - "type": "c4-person", - "pos": { - "x": 1410, - "y": 0 - }, - "width": 448, - "height": 299, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B3", - "stroke": "B1", - "animated": false, - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank ccountskks.", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 388, - "labelHeight": 119, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "customer2", - "type": "c4-person", - "pos": { - "x": 1137, - "y": 399 - }, - "width": 457, - "height": 378, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B3", - "stroke": "B1", - "animated": false, - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "## Personal Banking Customerk\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 396, - "labelHeight": 199, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "customer3", - "type": "c4-person", - "pos": { - "x": 1147, - "y": 877 - }, - "width": 457, - "height": 304, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B3", - "stroke": "B1", - "animated": false, - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 396, - "labelHeight": 119, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "customer4", - "type": "c4-person", - "pos": { - "x": 1426, - "y": 1281 - }, - "width": 457, - "height": 304, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B3", - "stroke": "B1", - "animated": false, - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 396, - "labelHeight": 119, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - } - ], - "connections": [ - { - "id": "(customer1 -> customer2)[0]", - "src": "customer1", - "srcArrow": "none", - "dst": "customer2", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1436, - "y": 297 - }, - { - "x": 1379.5999755859375, - "y": 338.6000061035156 - }, - { - "x": 1365.5999755859375, - "y": 359 - }, - { - "x": 1366, - "y": 399 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer2 -> customer3)[0]", - "src": "customer2", - "srcArrow": "none", - "dst": "customer3", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1358, - "y": 777 - }, - { - "x": 1356, - "y": 817 - }, - { - "x": 1356.5999755859375, - "y": 837.2000122070312 - }, - { - "x": 1361, - "y": 878 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer3 -> customer4)[0]", - "src": "customer3", - "srcArrow": "none", - "dst": "customer4", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1375, - "y": 1181 - }, - { - "x": 1375.4000244140625, - "y": 1221 - }, - { - "x": 1415, - "y": 1259.5999755859375 - }, - { - "x": 1573, - "y": 1374 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer4 -> customer1)[0]", - "src": "customer4", - "srcArrow": "none", - "dst": "customer1", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1654, - "y": 1281 - }, - { - "x": 1654, - "y": 1241 - }, - { - "x": 1654, - "y": 1190.5999755859375 - }, - { - "x": 1654, - "y": 1130 - }, - { - "x": 1654, - "y": 1069.4000244140625 - }, - { - "x": 1654, - "y": 988.5999755859375 - }, - { - "x": 1654, - "y": 928 - }, - { - "x": 1654, - "y": 867.4000244140625 - }, - { - "x": 1654, - "y": 779.2000122070312 - }, - { - "x": 1654, - "y": 707.5 - }, - { - "x": 1654, - "y": 635.7999877929688 - }, - { - "x": 1653, - "y": 339 - }, - { - "x": 1649, - "y": 299 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer1 -> customer3)[0]", - "src": "customer1", - "srcArrow": "none", - "dst": "customer3", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1634, - "y": 299 - }, - { - "x": 1634, - "y": 339 - }, - { - "x": 1634, - "y": 396.79998779296875 - }, - { - "x": 1634, - "y": 468.5 - }, - { - "x": 1634, - "y": 540.2000122070312 - }, - { - "x": 1598.800048828125, - "y": 854.5999755859375 - }, - { - "x": 1458, - "y": 965 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer3 -> customer2)[0]", - "src": "customer3", - "srcArrow": "none", - "dst": "customer2", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1442, - "y": 911 - }, - { - "x": 1480.199951171875, - "y": 843.7999877929688 - }, - { - "x": 1484.5999755859375, - "y": 817 - }, - { - "x": 1464, - "y": 777 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 } ], + "connections": [], "root": { "id": "", "type": "", diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg index 7c7343d0c..bab515547 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg @@ -1,14 +1,14 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

-

[person]

-

A customer of the bank, with pekkrsonal bank ccountskks.

-

Personal Banking Customerk

-

[person]

-

A customer of the bank, with pekkrsonal bank accountskks.

-

A customer of the bank, with pekkrsonal bank accountskks.

-

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

-

[person]

-

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

-

[person]

-

A customer of the bank, with pekkrsonal bank accountskks.

-
- - - - - - - - +
+ + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json index f55b84f10..636de29e5 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 12, - "y": 19 + "y": 12 }, "width": 410, - "height": 284, + "height": 390, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -57,11 +57,11 @@ "id": "c4mdperson2", "type": "c4-person", "pos": { - "x": 441, - "y": 19 + "x": 442, + "y": 12 }, "width": 410, - "height": 284, + "height": 390, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -99,11 +99,11 @@ "id": "c4mdperson3", "type": "c4-person", "pos": { - "x": 871, - "y": 19 + "x": 872, + "y": 12 }, "width": 410, - "height": 284, + "height": 390, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -136,412 +136,9 @@ "labelPosition": "INSIDE_BOTTOM_CENTER", "zIndex": 0, "level": 1 - }, - { - "id": "customer1", - "type": "c4-person", - "pos": { - "x": 1301, - "y": 12 - }, - "width": 448, - "height": 299, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B3", - "stroke": "B1", - "animated": false, - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank ccountskks.", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 388, - "labelHeight": 119, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "customer2", - "type": "c4-person", - "pos": { - "x": 1028, - "y": 391 - }, - "width": 457, - "height": 378, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B3", - "stroke": "B1", - "animated": false, - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "## Personal Banking Customerk\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 396, - "labelHeight": 199, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "customer3", - "type": "c4-person", - "pos": { - "x": 1123, - "y": 849 - }, - "width": 457, - "height": 304, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B3", - "stroke": "B1", - "animated": false, - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 396, - "labelHeight": 119, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - }, - { - "id": "customer4", - "type": "c4-person", - "pos": { - "x": 1313, - "y": 1233 - }, - "width": 457, - "height": 304, - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "borderRadius": 0, - "fill": "B3", - "stroke": "B1", - "animated": false, - "shadow": false, - "3d": false, - "multiple": false, - "double-border": false, - "tooltip": "", - "link": "", - "icon": null, - "iconPosition": "", - "blend": false, - "fields": null, - "methods": null, - "columns": null, - "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "markdown", - "color": "N1", - "italic": false, - "bold": true, - "underline": false, - "labelWidth": 396, - "labelHeight": 119, - "labelPosition": "INSIDE_MIDDLE_CENTER", - "zIndex": 0, - "level": 1 - } - ], - "connections": [ - { - "id": "(customer1 -> customer2)[0]", - "src": "customer1", - "srcArrow": "none", - "dst": "customer2", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1414, - "y": 311 - }, - { - "x": 1414, - "y": 540 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer2 -> customer3)[0]", - "src": "customer2", - "srcArrow": "none", - "dst": "customer3", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1237, - "y": 769 - }, - { - "x": 1237, - "y": 997 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer3 -> customer4)[0]", - "src": "customer3", - "srcArrow": "none", - "dst": "customer4", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1465, - "y": 1153 - }, - { - "x": 1466, - "y": 1284 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer4 -> customer1)[0]", - "src": "customer4", - "srcArrow": "none", - "dst": "customer1", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1620, - "y": 1290 - }, - { - "x": 1620, - "y": 311 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer1 -> customer3)[0]", - "src": "customer1", - "srcArrow": "none", - "dst": "customer3", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1526, - "y": 311 - }, - { - "x": 1526, - "y": 997 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer3 -> customer2)[0]", - "src": "customer3", - "srcArrow": "none", - "dst": "customer2", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1334, - "y": 851 - }, - { - "x": 1334, - "y": 769 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 } ], + "connections": [], "root": { "id": "", "type": "", diff --git a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg index aafc758b9..bfadee541 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg @@ -1,14 +1,14 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

-

[person]

-

A customer of the bank, with pekkrsonal bank ccountskks.

-

Personal Banking Customerk

-

[person]

-

A customer of the bank, with pekkrsonal bank accountskks.

-

A customer of the bank, with pekkrsonal bank accountskks.

-

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

-

[person]

-

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

-

[person]

-

A customer of the bank, with pekkrsonal bank accountskks.

-
- - - - - - - - +
+ + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json index 196f6f710..279169e81 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 0, - "y": 469 + "y": 504 }, "width": 336, - "height": 286, + "height": 328, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -61,7 +61,7 @@ "y": 0 }, "width": 139, - "height": 107, + "height": 132, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -100,7 +100,7 @@ "type": "person", "pos": { "x": 101, - "y": 279 + "y": 309 }, "width": 134, "height": 89, @@ -142,10 +142,10 @@ "type": "rectangle", "pos": { "x": 386, - "y": 248 + "y": 273 }, "width": 210, - "height": 484, + "height": 515, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -184,10 +184,10 @@ "type": "c4-person", "pos": { "x": 449, - "y": 278 + "y": 303 }, "width": 84, - "height": 91, + "height": 101, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -226,7 +226,7 @@ "type": "c4-person", "pos": { "x": 416, - "y": 522 + "y": 578 }, "width": 150, "height": 180, @@ -292,19 +292,19 @@ "route": [ { "x": 168, - "y": 394 + "y": 424 }, { "x": 168, - "y": 414 + "y": 448 }, { "x": 168, - "y": 429 + "y": 461 }, { "x": 168, - "y": 469 + "y": 489 } ], "isCurve": true, @@ -339,20 +339,20 @@ "link": "", "route": [ { - "x": 263, - "y": 100 + "x": 262, + "y": 119 }, { - "x": 187, - "y": 154 + "x": 186.8000030517578, + "y": 177.8000030517578 }, { "x": 168, - "y": 238.1999969482422 + "y": 264.20001220703125 }, { "x": 168, - "y": 279 + "y": 309 } ], "isCurve": true, @@ -387,20 +387,20 @@ "link": "", "route": [ { - "x": 395, - "y": 100 + "x": 397, + "y": 119 }, { - "x": 471.79998779296875, - "y": 154 + "x": 472.20001220703125, + "y": 177.8000030517578 }, { "x": 491, - "y": 238 + "y": 263 }, { "x": 491, - "y": 278 + "y": 303 } ], "isCurve": true, @@ -436,19 +436,19 @@ "route": [ { "x": 491, - "y": 369 + "y": 405 }, { "x": 491, - "y": 409 + "y": 444.20001220703125 }, { "x": 491, - "y": 439.6000061035156 + "y": 478.6000061035156 }, { "x": 491, - "y": 522 + "y": 577 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg index e3498e842..65e12a1b3 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json index 7c1686a85..95cb99c31 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 12, - "y": 900 + "y": 935 }, "width": 336, - "height": 286, + "height": 328, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -61,7 +61,7 @@ "y": 12 }, "width": 139, - "height": 107, + "height": 132, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -100,7 +100,7 @@ "type": "person", "pos": { "x": 113, - "y": 715 + "y": 750 }, "width": 134, "height": 89, @@ -142,10 +142,10 @@ "type": "rectangle", "pos": { "x": 256, - "y": 204 + "y": 229 }, "width": 250, - "height": 441, + "height": 451, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -184,10 +184,10 @@ "type": "c4-person", "pos": { "x": 339, - "y": 254 + "y": 279 }, "width": 84, - "height": 91, + "height": 101, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -226,7 +226,7 @@ "type": "c4-person", "pos": { "x": 306, - "y": 415 + "y": 450 }, "width": 150, "height": 180, @@ -292,11 +292,11 @@ "route": [ { "x": 180, - "y": 830 + "y": 865 }, { "x": 180, - "y": 900 + "y": 920 } ], "animated": false, @@ -331,19 +331,19 @@ "route": [ { "x": 258, - "y": 119 + "y": 144 }, { "x": 257.5830078125, - "y": 159 + "y": 184 }, { "x": 180, - "y": 159 + "y": 184 }, { "x": 180, - "y": 715 + "y": 750 } ], "animated": false, @@ -378,19 +378,19 @@ "route": [ { "x": 304, - "y": 119 + "y": 144 }, { "x": 303.9159851074219, - "y": 159 + "y": 184 }, { "x": 381.5, - "y": 159 + "y": 184 }, { "x": 382, - "y": 254 + "y": 279 } ], "animated": false, @@ -425,11 +425,11 @@ "route": [ { "x": 381, - "y": 345 + "y": 381 }, { "x": 382, - "y": 415 + "y": 449 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg index ec77604b2..d7fdb9e74 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json index 9f035283b..e462c9a73 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json @@ -19,7 +19,7 @@ "y": 0 }, "width": 415, - "height": 285, + "height": 394, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 147, - "y": 442 + "y": 551 }, "width": 2407, "height": 915, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 177, - "y": 472 + "y": 581 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 390, - "y": 757 + "y": 866 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 1123, - "y": 757 + "y": 866 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 1246, - "y": 1058 + "y": 1167 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1890, - "y": 757 + "y": 866 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 2410, - "y": 1494 + "y": 1603 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 0, - "y": 1494 + "y": 1603 }, "width": 629, "height": 164, @@ -418,19 +418,19 @@ "route": [ { "x": 1089, - "y": 194 + "y": 262 }, { "x": 579.4000244140625, - "y": 321.6000061035156 + "y": 422.3999938964844 }, { "x": 452, - "y": 432 + "y": 541 }, { "x": 452, - "y": 472 + "y": 581 } ], "isCurve": true, @@ -466,19 +466,19 @@ "route": [ { "x": 452, - "y": 635.5 + "y": 744.5 }, { "x": 452, - "y": 684.2999877929688 + "y": 793.2999877929688 }, { "x": 472.3999938964844, - "y": 708.7000122070312 + "y": 817.7000122070312 }, { "x": 554, - "y": 757.5 + "y": 866.5 } ], "isCurve": true, @@ -513,44 +513,44 @@ "link": "", "route": [ { - "x": 1093, - "y": 262 + "x": 1092, + "y": 348 }, { - "x": 968.2000122070312, - "y": 335.20001220703125 + "x": 968, + "y": 439.6000061035156 }, { "x": 937, - "y": 367.20001220703125 + "y": 476.20001220703125 }, { "x": 937, - "y": 387.75 + "y": 496.75 }, { "x": 937, - "y": 408.29998779296875 + "y": 517.2990112304688 }, { "x": 937, - "y": 448.3999938964844 + "y": 557.4000244140625 }, { "x": 937, - "y": 488 + "y": 597 }, { "x": 937, - "y": 527.5999755859375 + "y": 636.5999755859375 }, { "x": 916.5999755859375, - "y": 708.7000122070312 + "y": 817.7000122070312 }, { "x": 835, - "y": 757.5 + "y": 866.5 } ], "isCurve": true, @@ -585,44 +585,44 @@ "link": "", "route": [ { - "x": 1418, - "y": 285 + "x": 1430, + "y": 394 }, { - "x": 1464.4000244140625, - "y": 339.79998779296875 + "x": 1466.800048828125, + "y": 448.79998779296875 }, { "x": 1476, - "y": 367.20001220703125 + "y": 476.20001220703125 }, { "x": 1476, - "y": 387.75 + "y": 496.75 }, { "x": 1476, - "y": 408.29998779296875 + "y": 517.2990112304688 }, { "x": 1476, - "y": 448.3999938964844 + "y": 557.4000244140625 }, { "x": 1476, - "y": 488 + "y": 597 }, { "x": 1476, - "y": 527.5999755859375 + "y": 636.5999755859375 }, { "x": 1476, - "y": 708.7000122070312 + "y": 817.7000122070312 }, { "x": 1476, - "y": 757.5 + "y": 866.5 } ], "isCurve": true, @@ -658,19 +658,19 @@ "route": [ { "x": 694.5, - "y": 920.5 + "y": 1029.5 }, { "x": 694.5, - "y": 975.7000122070312 + "y": 1084.699951171875 }, { "x": 804.7000122070312, - "y": 1010.7219848632812 + "y": 1119.7220458984375 }, { "x": 1245.5, - "y": 1095.6099853515625 + "y": 1204.6099853515625 } ], "isCurve": true, @@ -706,19 +706,19 @@ "route": [ { "x": 1476, - "y": 920.5 + "y": 1029.5 }, { "x": 1476, - "y": 975.7000122070312 + "y": 1084.699951171875 }, { "x": 1476, - "y": 1003.2999877929688 + "y": 1112.300048828125 }, { "x": 1476, - "y": 1058.5 + "y": 1167.5 } ], "isCurve": true, @@ -754,19 +754,19 @@ "route": [ { "x": 1245.5, - "y": 1166.1949462890625 + "y": 1275.1949462890625 }, { "x": 500.6990051269531, - "y": 1318.8389892578125 + "y": 1427.8389892578125 }, { "x": 314.5, - "y": 1439.300048828125 + "y": 1548.300048828125 }, { "x": 314.5, - "y": 1494.5 + "y": 1603.5 } ], "isCurve": true, @@ -802,103 +802,103 @@ "route": [ { "x": 1505, - "y": 175 + "y": 238 }, { "x": 2410.60009765625, - "y": 317.79998779296875 + "y": 417.6000061035156 }, { "x": 2637, - "y": 367.20001220703125 + "y": 476.20001220703125 }, { "x": 2637, - "y": 387.75 + "y": 496.75 }, { "x": 2637, - "y": 408.29998779296875 + "y": 517.2990112304688 }, { "x": 2637, - "y": 448.3999938964844 + "y": 557.4000244140625 }, { "x": 2637, - "y": 488 + "y": 597 }, { "x": 2637, - "y": 527.5999755859375 + "y": 636.5999755859375 }, { "x": 2637, - "y": 582.5 + "y": 691.5 }, { "x": 2637, - "y": 625.25 + "y": 734.25 }, { "x": 2637, - "y": 668 + "y": 777 }, { "x": 2637, - "y": 725 + "y": 834 }, { "x": 2637, - "y": 767.75 + "y": 876.75 }, { "x": 2637, - "y": 810.5 + "y": 919.5 }, { "x": 2637, - "y": 869.0999755859375 + "y": 978.0999755859375 }, { "x": 2637, - "y": 914.25 + "y": 1023.25 }, { "x": 2637, - "y": 959.4000244140625 + "y": 1068.4000244140625 }, { "x": 2637, - "y": 1019.5999755859375 + "y": 1128.5999755859375 }, { "x": 2637, - "y": 1064.75 + "y": 1173.75 }, { "x": 2637, - "y": 1109.9000244140625 + "y": 1218.9000244140625 }, { "x": 2637, - "y": 1183.4000244140625 + "y": 1292.4000244140625 }, { "x": 2637, - "y": 1248.5 + "y": 1357.5 }, { "x": 2637, - "y": 1313.5999755859375 + "y": 1422.5999755859375 }, { "x": 2632.800048828125, - "y": 1439.300048828125 + "y": 1548.300048828125 }, { "x": 2616, - "y": 1494.5 + "y": 1603.5 } ], "isCurve": true, @@ -934,19 +934,19 @@ "route": [ { "x": 1707.5, - "y": 1173.843994140625 + "y": 1282.843994140625 }, { "x": 2241.5, - "y": 1320.3680419921875 + "y": 1429.3680419921875 }, { "x": 2394.39990234375, - "y": 1439.300048828125 + "y": 1548.300048828125 }, { "x": 2472, - "y": 1494.5 + "y": 1603.5 } ], "isCurve": true, @@ -982,19 +982,19 @@ "route": [ { "x": 2206.5, - "y": 920.5 + "y": 1029.5 }, { "x": 2206.5, - "y": 975.7000122070312 + "y": 1084.699951171875 }, { "x": 2106.5, - "y": 1010.0999755859375 + "y": 1119.0999755859375 }, { "x": 1706.5, - "y": 1092.5 + "y": 1201.5 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg index 4e4ff9f84..2613fb8b3 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json index 3d9b2d3b7..4d6d3ccd8 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json @@ -19,7 +19,7 @@ "y": 12 }, "width": 415, - "height": 285, + "height": 394, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 12, - "y": 549 + "y": 658 }, "width": 2218, "height": 1035, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 62, - "y": 599 + "y": 708 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 190, - "y": 934 + "y": 1043 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 819, - "y": 934 + "y": 1043 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 942, - "y": 1285 + "y": 1394 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1546, - "y": 934 + "y": 1043 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 1746, - "y": 1786 + "y": 1895 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 781, - "y": 1786 + "y": 1895 }, "width": 629, "height": 164, @@ -418,19 +418,19 @@ "route": [ { "x": 788, - "y": 297 + "y": 406 }, { "x": 787.75, - "y": 337 + "y": 446 }, { "x": 359.25, - "y": 337 + "y": 446 }, { "x": 359.25, - "y": 599 + "y": 708 } ], "animated": false, @@ -465,11 +465,11 @@ "route": [ { "x": 393, - "y": 763 + "y": 872 }, { "x": 393, - "y": 934 + "y": 1043 } ], "animated": false, @@ -504,19 +504,19 @@ "route": [ { "x": 871, - "y": 297 + "y": 406 }, { "x": 870.75, - "y": 387 + "y": 496 }, { "x": 652, - "y": 387 + "y": 496 }, { "x": 652, - "y": 934 + "y": 1043 } ], "animated": false, @@ -551,11 +551,11 @@ "route": [ { "x": 954, - "y": 297 + "y": 406 }, { "x": 953.75, - "y": 934 + "y": 1043 } ], "animated": false, @@ -590,19 +590,19 @@ "route": [ { "x": 494.5, - "y": 1098 + "y": 1207 }, { "x": 494.5, - "y": 1245 + "y": 1354 }, { "x": 1057.25, - "y": 1245 + "y": 1354 }, { "x": 1057.25, - "y": 1285 + "y": 1394 } ], "animated": false, @@ -637,11 +637,11 @@ "route": [ { "x": 1172.5, - "y": 1098 + "y": 1207 }, { "x": 1172.5, - "y": 1285 + "y": 1394 } ], "animated": false, @@ -676,11 +676,11 @@ "route": [ { "x": 1095.666015625, - "y": 1449 + "y": 1558 }, { "x": 1095.666015625, - "y": 1786 + "y": 1895 } ], "animated": false, @@ -715,27 +715,27 @@ "route": [ { "x": 1037, - "y": 297 + "y": 406 }, { "x": 1036.75, - "y": 337 + "y": 446 }, { "x": 2303.5, - "y": 337 + "y": 446 }, { "x": 2303.5, - "y": 1746 + "y": 1855 }, { "x": 1986.8330078125, - "y": 1746 + "y": 1855 }, { "x": 1986.8330078125, - "y": 1786 + "y": 1895 } ], "animated": false, @@ -770,19 +770,19 @@ "route": [ { "x": 1249.3330078125, - "y": 1449 + "y": 1558 }, { "x": 1249.3330078125, - "y": 1746 + "y": 1855 }, { "x": 1866.8330078125, - "y": 1746 + "y": 1855 }, { "x": 1866.8330078125, - "y": 1786 + "y": 1895 } ], "animated": false, @@ -817,19 +817,19 @@ "route": [ { "x": 1863, - "y": 1098 + "y": 1207 }, { "x": 1863, - "y": 1245 + "y": 1354 }, { "x": 1287.75, - "y": 1245 + "y": 1354 }, { "x": 1287.75, - "y": 1285 + "y": 1394 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg index dc7185d81..31b06adcb 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json index 3b7bdaf8e..e0d8c0959 100644 --- a/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json +++ b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json @@ -19,7 +19,7 @@ "y": 0 }, "width": 180, - "height": 85, + "height": 94, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg index 6f92c0949..009c53f4e 100644 --- a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg @@ -1,9 +1,9 @@ -c4-person - - + .d2-4248901620 .fill-N1{fill:#0A0F25;} + .d2-4248901620 .fill-N2{fill:#676C7E;} + .d2-4248901620 .fill-N3{fill:#9499AB;} + .d2-4248901620 .fill-N4{fill:#CFD2DD;} + .d2-4248901620 .fill-N5{fill:#DEE1EB;} + .d2-4248901620 .fill-N6{fill:#EEF1F8;} + .d2-4248901620 .fill-N7{fill:#FFFFFF;} + .d2-4248901620 .fill-B1{fill:#0D32B2;} + .d2-4248901620 .fill-B2{fill:#0D32B2;} + .d2-4248901620 .fill-B3{fill:#E3E9FD;} + .d2-4248901620 .fill-B4{fill:#E3E9FD;} + .d2-4248901620 .fill-B5{fill:#EDF0FD;} + .d2-4248901620 .fill-B6{fill:#F7F8FE;} + .d2-4248901620 .fill-AA2{fill:#4A6FF3;} + .d2-4248901620 .fill-AA4{fill:#EDF0FD;} + .d2-4248901620 .fill-AA5{fill:#F7F8FE;} + .d2-4248901620 .fill-AB4{fill:#EDF0FD;} + .d2-4248901620 .fill-AB5{fill:#F7F8FE;} + .d2-4248901620 .stroke-N1{stroke:#0A0F25;} + .d2-4248901620 .stroke-N2{stroke:#676C7E;} + .d2-4248901620 .stroke-N3{stroke:#9499AB;} + .d2-4248901620 .stroke-N4{stroke:#CFD2DD;} + .d2-4248901620 .stroke-N5{stroke:#DEE1EB;} + .d2-4248901620 .stroke-N6{stroke:#EEF1F8;} + .d2-4248901620 .stroke-N7{stroke:#FFFFFF;} + .d2-4248901620 .stroke-B1{stroke:#0D32B2;} + .d2-4248901620 .stroke-B2{stroke:#0D32B2;} + .d2-4248901620 .stroke-B3{stroke:#E3E9FD;} + .d2-4248901620 .stroke-B4{stroke:#E3E9FD;} + .d2-4248901620 .stroke-B5{stroke:#EDF0FD;} + .d2-4248901620 .stroke-B6{stroke:#F7F8FE;} + .d2-4248901620 .stroke-AA2{stroke:#4A6FF3;} + .d2-4248901620 .stroke-AA4{stroke:#EDF0FD;} + .d2-4248901620 .stroke-AA5{stroke:#F7F8FE;} + .d2-4248901620 .stroke-AB4{stroke:#EDF0FD;} + .d2-4248901620 .stroke-AB5{stroke:#F7F8FE;} + .d2-4248901620 .background-color-N1{background-color:#0A0F25;} + .d2-4248901620 .background-color-N2{background-color:#676C7E;} + .d2-4248901620 .background-color-N3{background-color:#9499AB;} + .d2-4248901620 .background-color-N4{background-color:#CFD2DD;} + .d2-4248901620 .background-color-N5{background-color:#DEE1EB;} + .d2-4248901620 .background-color-N6{background-color:#EEF1F8;} + .d2-4248901620 .background-color-N7{background-color:#FFFFFF;} + .d2-4248901620 .background-color-B1{background-color:#0D32B2;} + .d2-4248901620 .background-color-B2{background-color:#0D32B2;} + .d2-4248901620 .background-color-B3{background-color:#E3E9FD;} + .d2-4248901620 .background-color-B4{background-color:#E3E9FD;} + .d2-4248901620 .background-color-B5{background-color:#EDF0FD;} + .d2-4248901620 .background-color-B6{background-color:#F7F8FE;} + .d2-4248901620 .background-color-AA2{background-color:#4A6FF3;} + .d2-4248901620 .background-color-AA4{background-color:#EDF0FD;} + .d2-4248901620 .background-color-AA5{background-color:#F7F8FE;} + .d2-4248901620 .background-color-AB4{background-color:#EDF0FD;} + .d2-4248901620 .background-color-AB5{background-color:#F7F8FE;} + .d2-4248901620 .color-N1{color:#0A0F25;} + .d2-4248901620 .color-N2{color:#676C7E;} + .d2-4248901620 .color-N3{color:#9499AB;} + .d2-4248901620 .color-N4{color:#CFD2DD;} + .d2-4248901620 .color-N5{color:#DEE1EB;} + .d2-4248901620 .color-N6{color:#EEF1F8;} + .d2-4248901620 .color-N7{color:#FFFFFF;} + .d2-4248901620 .color-B1{color:#0D32B2;} + .d2-4248901620 .color-B2{color:#0D32B2;} + .d2-4248901620 .color-B3{color:#E3E9FD;} + .d2-4248901620 .color-B4{color:#E3E9FD;} + .d2-4248901620 .color-B5{color:#EDF0FD;} + .d2-4248901620 .color-B6{color:#F7F8FE;} + .d2-4248901620 .color-AA2{color:#4A6FF3;} + .d2-4248901620 .color-AA4{color:#EDF0FD;} + .d2-4248901620 .color-AA5{color:#F7F8FE;} + .d2-4248901620 .color-AB4{color:#EDF0FD;} + .d2-4248901620 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-4248901620);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-4248901620);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-4248901620);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-4248901620);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-4248901620);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-4248901620);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-4248901620);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-4248901620);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + + \ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json index 342178f5f..56a15e872 100644 --- a/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json +++ b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json @@ -19,7 +19,7 @@ "y": 12 }, "width": 180, - "height": 85, + "height": 94, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg index d41c6027d..4de020608 100644 --- a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg @@ -1,9 +1,9 @@ -c4-person - - + .d2-108552620 .fill-N1{fill:#0A0F25;} + .d2-108552620 .fill-N2{fill:#676C7E;} + .d2-108552620 .fill-N3{fill:#9499AB;} + .d2-108552620 .fill-N4{fill:#CFD2DD;} + .d2-108552620 .fill-N5{fill:#DEE1EB;} + .d2-108552620 .fill-N6{fill:#EEF1F8;} + .d2-108552620 .fill-N7{fill:#FFFFFF;} + .d2-108552620 .fill-B1{fill:#0D32B2;} + .d2-108552620 .fill-B2{fill:#0D32B2;} + .d2-108552620 .fill-B3{fill:#E3E9FD;} + .d2-108552620 .fill-B4{fill:#E3E9FD;} + .d2-108552620 .fill-B5{fill:#EDF0FD;} + .d2-108552620 .fill-B6{fill:#F7F8FE;} + .d2-108552620 .fill-AA2{fill:#4A6FF3;} + .d2-108552620 .fill-AA4{fill:#EDF0FD;} + .d2-108552620 .fill-AA5{fill:#F7F8FE;} + .d2-108552620 .fill-AB4{fill:#EDF0FD;} + .d2-108552620 .fill-AB5{fill:#F7F8FE;} + .d2-108552620 .stroke-N1{stroke:#0A0F25;} + .d2-108552620 .stroke-N2{stroke:#676C7E;} + .d2-108552620 .stroke-N3{stroke:#9499AB;} + .d2-108552620 .stroke-N4{stroke:#CFD2DD;} + .d2-108552620 .stroke-N5{stroke:#DEE1EB;} + .d2-108552620 .stroke-N6{stroke:#EEF1F8;} + .d2-108552620 .stroke-N7{stroke:#FFFFFF;} + .d2-108552620 .stroke-B1{stroke:#0D32B2;} + .d2-108552620 .stroke-B2{stroke:#0D32B2;} + .d2-108552620 .stroke-B3{stroke:#E3E9FD;} + .d2-108552620 .stroke-B4{stroke:#E3E9FD;} + .d2-108552620 .stroke-B5{stroke:#EDF0FD;} + .d2-108552620 .stroke-B6{stroke:#F7F8FE;} + .d2-108552620 .stroke-AA2{stroke:#4A6FF3;} + .d2-108552620 .stroke-AA4{stroke:#EDF0FD;} + .d2-108552620 .stroke-AA5{stroke:#F7F8FE;} + .d2-108552620 .stroke-AB4{stroke:#EDF0FD;} + .d2-108552620 .stroke-AB5{stroke:#F7F8FE;} + .d2-108552620 .background-color-N1{background-color:#0A0F25;} + .d2-108552620 .background-color-N2{background-color:#676C7E;} + .d2-108552620 .background-color-N3{background-color:#9499AB;} + .d2-108552620 .background-color-N4{background-color:#CFD2DD;} + .d2-108552620 .background-color-N5{background-color:#DEE1EB;} + .d2-108552620 .background-color-N6{background-color:#EEF1F8;} + .d2-108552620 .background-color-N7{background-color:#FFFFFF;} + .d2-108552620 .background-color-B1{background-color:#0D32B2;} + .d2-108552620 .background-color-B2{background-color:#0D32B2;} + .d2-108552620 .background-color-B3{background-color:#E3E9FD;} + .d2-108552620 .background-color-B4{background-color:#E3E9FD;} + .d2-108552620 .background-color-B5{background-color:#EDF0FD;} + .d2-108552620 .background-color-B6{background-color:#F7F8FE;} + .d2-108552620 .background-color-AA2{background-color:#4A6FF3;} + .d2-108552620 .background-color-AA4{background-color:#EDF0FD;} + .d2-108552620 .background-color-AA5{background-color:#F7F8FE;} + .d2-108552620 .background-color-AB4{background-color:#EDF0FD;} + .d2-108552620 .background-color-AB5{background-color:#F7F8FE;} + .d2-108552620 .color-N1{color:#0A0F25;} + .d2-108552620 .color-N2{color:#676C7E;} + .d2-108552620 .color-N3{color:#9499AB;} + .d2-108552620 .color-N4{color:#CFD2DD;} + .d2-108552620 .color-N5{color:#DEE1EB;} + .d2-108552620 .color-N6{color:#EEF1F8;} + .d2-108552620 .color-N7{color:#FFFFFF;} + .d2-108552620 .color-B1{color:#0D32B2;} + .d2-108552620 .color-B2{color:#0D32B2;} + .d2-108552620 .color-B3{color:#E3E9FD;} + .d2-108552620 .color-B4{color:#E3E9FD;} + .d2-108552620 .color-B5{color:#EDF0FD;} + .d2-108552620 .color-B6{color:#F7F8FE;} + .d2-108552620 .color-AA2{color:#4A6FF3;} + .d2-108552620 .color-AA4{color:#EDF0FD;} + .d2-108552620 .color-AA5{color:#F7F8FE;} + .d2-108552620 .color-AB4{color:#EDF0FD;} + .d2-108552620 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-108552620);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-108552620);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-108552620);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-108552620);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-108552620);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-108552620);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-108552620);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-108552620);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + + \ No newline at end of file diff --git a/e2etests/txtar.txt b/e2etests/txtar.txt index 1b7eaca96..89d18ce17 100644 --- a/e2etests/txtar.txt +++ b/e2etests/txtar.txt @@ -1221,47 +1221,3 @@ A customer of the bank, with personal bank accounts shape: c4-person label.near: bottom-center } - - customer1: |md - ## Personal Banking Customer - [person] - - A customer of the bank, with pekkrsonal bank ccountskks. -| { - shape: c4-person -} - -customer2: |md - ## Personal Banking Customerk - [person] - - A customer of the bank, with pekkrsonal bank accountskks. - - A customer of the bank, with pekkrsonal bank accountskks. - - A customer of the bank, with pekkrsonal bank accountskks. -| { - shape: c4-person -} - -customer3: |md - ## Personal Banking Customer - [person] - - A customer of the bank, with pekkrsonal bank accountskks. -| { - shape: c4-person -} - -customer4: |md - ## Personal Banking Customer - [person] - - A customer of the bank, with pekkrsonal bank accountskks. -| { - shape: c4-person -} - -customer1 -> customer2 -> customer3 -> customer4 -customer4 -> customer1 -> customer3 -> customer2 - diff --git a/lib/shape/shape_c4_person.go b/lib/shape/shape_c4_person.go index a9b7b9560..99d47b07d 100644 --- a/lib/shape/shape_c4_person.go +++ b/lib/shape/shape_c4_person.go @@ -32,24 +32,26 @@ const ( func (s shapeC4Person) GetInnerBox() *geo.Box { width := s.Box.Width + height := s.Box.Height - // Reduce head radius from 22% to 18% of width - headRadius := width * 0.18 - headCenterY := headRadius + headRadius := width * 0.22 + headCenterY := height * 0.18 bodyTop := headCenterY + headRadius*0.8 - // Horizontal padding = 5% of width - horizontalPadding := width * 0.05 - - // Vertical padding = 3% of width (not height) - vertPadding := width * 0.03 + // Use a small fixed percentage instead of the full corner radius + horizontalPadding := width * 0.05 // 5% padding tl := s.Box.TopLeft.Copy() tl.X += horizontalPadding - tl.Y += bodyTop + vertPadding + // Add vertical padding + tl.Y += bodyTop + height*0.03 + + // Width minus padding on both sides innerWidth := width - (horizontalPadding * 2) - innerHeight := s.Box.Height - bodyTop - (vertPadding * 2) + + // Add bottom padding + innerHeight := height - (tl.Y - s.Box.TopLeft.Y) - (height * 0.03) return geo.NewBox(tl, innerWidth, innerHeight) } @@ -60,10 +62,8 @@ func bodyPath(box *geo.Box) *svg.SvgPathContext { pc := svg.NewSVGPathContext(box.TopLeft, 1, 1) - // Reduce head radius from 22% to 18% of width - headRadius := width * 0.18 - // Adjust headCenterY to ensure head fits within box - headCenterY := headRadius + headRadius := width * 0.22 + headCenterY := height * 0.18 bodyTop := headCenterY + headRadius*0.8 bodyWidth := width bodyHeight := height - bodyTop @@ -88,13 +88,13 @@ func bodyPath(box *geo.Box) *svg.SvgPathContext { func headPath(box *geo.Box) *svg.SvgPathContext { width := box.Width + height := box.Height + pc := svg.NewSVGPathContext(box.TopLeft, 1, 1) - // Reduce head radius from 22% to 18% of width - headRadius := width * 0.18 + headRadius := width * 0.22 headCenterX := width / 2 - // Adjust headCenterY to ensure head fits within box - headCenterY := headRadius + headCenterY := height * 0.18 pc.StartAt(pc.Absolute(headCenterX, headCenterY-headRadius)) @@ -123,13 +123,13 @@ func headPath(box *geo.Box) *svg.SvgPathContext { func (s shapeC4Person) Perimeter() []geo.Intersectable { width := s.Box.Width + height := s.Box.Height bodyPerimeter := bodyPath(s.Box).Path - // Reduce head radius from 22% to 18% of width - headRadius := width * 0.18 + headRadius := width * 0.22 headCenterX := s.Box.TopLeft.X + width/2 - headCenterY := s.Box.TopLeft.Y + headRadius + headCenterY := s.Box.TopLeft.Y + height*0.18 headCenter := geo.NewPoint(headCenterX, headCenterY) headEllipse := geo.NewEllipse(headCenter, headRadius, headRadius) @@ -145,28 +145,28 @@ func (s shapeC4Person) GetSVGPathData() []string { } func (s shapeC4Person) GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64) { - // Start with content dimensions + padding - totalWidth := width + paddingX - totalHeight := height + paddingY + contentWidth := width + paddingX + contentHeight := height + paddingY - // Reduce head radius from 22% to 18% of width - headRadius := totalWidth * 0.18 + // Account for 10% total horizontal padding (5% on each side) + totalWidth := contentWidth / 0.9 + headRadius := totalWidth * 0.22 + headCenterY := totalWidth * 0.18 + bodyTop := headCenterY + headRadius*0.8 - // Head center is now at headRadius from the top - headCenterY := headRadius + // Include vertical padding from GetInnerBox + verticalPadding := totalWidth * 0.06 // 3% top + 3% bottom + totalHeight := contentHeight + bodyTop + verticalPadding - // Body starts at headCenterY + headRadius*0.8 - bodyTopPosition := headCenterY + headRadius*0.8 + // Calculate minimum height based on actual proportions + // Head height: 2 * headRadius = 0.44 * width + // Body should be at least half the width + minHeight := totalWidth * 0.95 // Reduced from 1.2 + if totalHeight < minHeight { + totalHeight = minHeight + } - // Add space for body (head is now fully contained) - totalHeight += bodyTopPosition - - // Horizontal padding is handled in GetInnerBox (5% on each side) - totalWidth /= 0.9 - - // Prevent the shape's aspect ratio from becoming too extreme totalWidth, totalHeight = LimitAR(totalWidth, totalHeight, C4_PERSON_AR_LIMIT) - return math.Ceil(totalWidth), math.Ceil(totalHeight) } From b26c036cc988db42f7b53da93b929740938de821 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 13 Mar 2025 19:41:31 -0600 Subject: [PATCH 23/54] fix --- .../testdata/TestCLI_E2E/empty-base.exp.svg | 168 ++--- .../c4-person-label/dagre/board.exp.json | 513 ++++++++++++++- .../c4-person-label/dagre/sketch.exp.svg | 584 +++++++++--------- .../txtar/c4-person-label/elk/board.exp.json | 415 ++++++++++++- .../txtar/c4-person-label/elk/sketch.exp.svg | 584 +++++++++--------- .../c4-person-shape/dagre/board.exp.json | 32 +- .../c4-person-shape/dagre/sketch.exp.svg | 576 ++++++++--------- .../txtar/c4-person-shape/elk/board.exp.json | 26 +- .../txtar/c4-person-shape/elk/sketch.exp.svg | 576 ++++++++--------- .../txtar/c4-theme/dagre/board.exp.json | 12 +- .../txtar/c4-theme/dagre/sketch.exp.svg | 562 ++++++++--------- .../txtar/c4-theme/elk/sketch.exp.svg | 4 +- .../small-c4-person/dagre/board.exp.json | 2 +- .../small-c4-person/dagre/sketch.exp.svg | 156 ++--- .../txtar/small-c4-person/elk/board.exp.json | 2 +- .../txtar/small-c4-person/elk/sketch.exp.svg | 156 ++--- e2etests/txtar.txt | 43 ++ lib/shape/shape_c4_person.go | 71 ++- 18 files changed, 2734 insertions(+), 1748 deletions(-) diff --git a/e2etests-cli/testdata/TestCLI_E2E/empty-base.exp.svg b/e2etests-cli/testdata/TestCLI_E2E/empty-base.exp.svg index 5efe15eb8..99003267f 100644 --- a/e2etests-cli/testdata/TestCLI_E2E/empty-base.exp.svg +++ b/e2etests-cli/testdata/TestCLI_E2E/empty-base.exp.svg @@ -1,9 +1,9 @@ ab +}]]>ab -abdc +abdc -abdce - +abdce + - - - + + + \ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json index d164ab8a8..def972f1f 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json @@ -16,7 +16,7 @@ "type": "c4-person", "pos": { "x": 0, - "y": 0 + "y": 18 }, "width": 410, "height": 390, @@ -58,7 +58,7 @@ "type": "c4-person", "pos": { "x": 470, - "y": 0 + "y": 18 }, "width": 410, "height": 390, @@ -100,7 +100,7 @@ "type": "c4-person", "pos": { "x": 940, - "y": 0 + "y": 18 }, "width": 410, "height": 390, @@ -136,9 +136,514 @@ "labelPosition": "INSIDE_BOTTOM_CENTER", "zIndex": 0, "level": 1 + }, + { + "id": "customer1", + "type": "c4-person", + "pos": { + "x": 1410, + "y": 0 + }, + "width": 448, + "height": 426, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank ccountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 388, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer2", + "type": "c4-person", + "pos": { + "x": 1137, + "y": 526 + }, + "width": 457, + "height": 453, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customerk\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 199, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer3", + "type": "c4-person", + "pos": { + "x": 1147, + "y": 1079 + }, + "width": 457, + "height": 434, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer4", + "type": "c4-person", + "pos": { + "x": 1426, + "y": 1613 + }, + "width": 457, + "height": 434, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(customer1 -> customer2)[0]", + "src": "customer1", + "srcArrow": "none", + "dst": "customer2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1433, + "y": 410 + }, + { + "x": 1379, + "y": 462.79998779296875 + }, + { + "x": 1365.5999755859375, + "y": 486 + }, + { + "x": 1366, + "y": 526 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer2 -> customer3)[0]", + "src": "customer2", + "srcArrow": "none", + "dst": "customer3", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1358, + "y": 979 + }, + { + "x": 1356, + "y": 1019 + }, + { + "x": 1356.4000244140625, + "y": 1039.199951171875 + }, + { + "x": 1360, + "y": 1080 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer3 -> customer4)[0]", + "src": "customer3", + "srcArrow": "none", + "dst": "customer4", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1375, + "y": 1513 + }, + { + "x": 1375.4000244140625, + "y": 1553 + }, + { + "x": 1411.800048828125, + "y": 1597.800048828125 + }, + { + "x": 1557, + "y": 1737 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer4 -> customer1)[0]", + "src": "customer4", + "srcArrow": "none", + "dst": "customer1", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1654, + "y": 1613 + }, + { + "x": 1654, + "y": 1573 + }, + { + "x": 1654, + "y": 1509.5999755859375 + }, + { + "x": 1654, + "y": 1429.5 + }, + { + "x": 1654, + "y": 1349.4000244140625 + }, + { + "x": 1654, + "y": 1242.5999755859375 + }, + { + "x": 1654, + "y": 1162.5 + }, + { + "x": 1654, + "y": 1082.4000244140625 + }, + { + "x": 1654, + "y": 973.7000122070312 + }, + { + "x": 1654, + "y": 890.75 + }, + { + "x": 1654, + "y": 807.7999877929688 + }, + { + "x": 1653.199951171875, + "y": 466 + }, + { + "x": 1650, + "y": 426 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer1 -> customer3)[0]", + "src": "customer1", + "srcArrow": "none", + "dst": "customer3", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1634, + "y": 426 + }, + { + "x": 1634, + "y": 466 + }, + { + "x": 1634, + "y": 531.2999877929688 + }, + { + "x": 1634, + "y": 614.25 + }, + { + "x": 1634, + "y": 697.2000122070312 + }, + { + "x": 1602.199951171875, + "y": 1062.199951171875 + }, + { + "x": 1475, + "y": 1195 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer3 -> customer2)[0]", + "src": "customer3", + "srcArrow": "none", + "dst": "customer2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1453, + "y": 1116 + }, + { + "x": 1482.4000244140625, + "y": 1046.4000244140625 + }, + { + "x": 1485.4000244140625, + "y": 1019 + }, + { + "x": 1468, + "y": 979 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 } ], - "connections": [], "root": { "id": "", "type": "", diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg index bab515547..25c78740e 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg @@ -1,14 +1,14 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-
- - - - +

Personal Banking Customer

+

[person]

+

A customer of the bank, with pekkrsonal bank ccountskks.

+

Personal Banking Customerk

+

[person]

+

A customer of the bank, with pekkrsonal bank accountskks.

+

A customer of the bank, with pekkrsonal bank accountskks.

+

A customer of the bank, with pekkrsonal bank accountskks.

+

Personal Banking Customer

+

[person]

+

A customer of the bank, with pekkrsonal bank accountskks.

+

Personal Banking Customer

+

[person]

+

A customer of the bank, with pekkrsonal bank accountskks.

+
+ + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json index 636de29e5..e46b21769 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json @@ -16,7 +16,7 @@ "type": "c4-person", "pos": { "x": 12, - "y": 12 + "y": 30 }, "width": 410, "height": 390, @@ -57,8 +57,8 @@ "id": "c4mdperson2", "type": "c4-person", "pos": { - "x": 442, - "y": 12 + "x": 441, + "y": 30 }, "width": 410, "height": 390, @@ -99,8 +99,8 @@ "id": "c4mdperson3", "type": "c4-person", "pos": { - "x": 872, - "y": 12 + "x": 871, + "y": 30 }, "width": 410, "height": 390, @@ -136,9 +136,412 @@ "labelPosition": "INSIDE_BOTTOM_CENTER", "zIndex": 0, "level": 1 + }, + { + "id": "customer1", + "type": "c4-person", + "pos": { + "x": 1301, + "y": 12 + }, + "width": 448, + "height": 426, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank ccountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 388, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer2", + "type": "c4-person", + "pos": { + "x": 1028, + "y": 518 + }, + "width": 457, + "height": 453, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customerk\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 199, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer3", + "type": "c4-person", + "pos": { + "x": 1123, + "y": 1051 + }, + "width": 457, + "height": 434, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "customer4", + "type": "c4-person", + "pos": { + "x": 1313, + "y": 1565 + }, + "width": 457, + "height": 434, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "stroke": "B1", + "animated": false, + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "## Personal Banking Customer\n[person]\n\nA customer of the bank, with pekkrsonal bank accountskks.", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 396, + "labelHeight": 119, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + } + ], + "connections": [ + { + "id": "(customer1 -> customer2)[0]", + "src": "customer1", + "srcArrow": "none", + "dst": "customer2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1414, + "y": 438 + }, + { + "x": 1414, + "y": 699 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer2 -> customer3)[0]", + "src": "customer2", + "srcArrow": "none", + "dst": "customer3", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1237, + "y": 971 + }, + { + "x": 1237, + "y": 1232 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer3 -> customer4)[0]", + "src": "customer3", + "srcArrow": "none", + "dst": "customer4", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1466, + "y": 1485 + }, + { + "x": 1466, + "y": 1600 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer4 -> customer1)[0]", + "src": "customer4", + "srcArrow": "none", + "dst": "customer1", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1620, + "y": 1603 + }, + { + "x": 1620, + "y": 438 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer1 -> customer3)[0]", + "src": "customer1", + "srcArrow": "none", + "dst": "customer3", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1526, + "y": 438 + }, + { + "x": 1526, + "y": 1233 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(customer3 -> customer2)[0]", + "src": "customer3", + "srcArrow": "none", + "dst": "customer2", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "link": "", + "route": [ + { + "x": 1334, + "y": 1053 + }, + { + "x": 1334, + "y": 971 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 } ], - "connections": [], "root": { "id": "", "type": "", diff --git a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg index bfadee541..5a6e872f4 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg @@ -1,14 +1,14 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-
- - - - +

Personal Banking Customer

+

[person]

+

A customer of the bank, with pekkrsonal bank ccountskks.

+

Personal Banking Customerk

+

[person]

+

A customer of the bank, with pekkrsonal bank accountskks.

+

A customer of the bank, with pekkrsonal bank accountskks.

+

A customer of the bank, with pekkrsonal bank accountskks.

+

Personal Banking Customer

+

[person]

+

A customer of the bank, with pekkrsonal bank accountskks.

+

Personal Banking Customer

+

[person]

+

A customer of the bank, with pekkrsonal bank accountskks.

+
+ + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json index 279169e81..bd1bb8ae3 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 0, - "y": 504 + "y": 507 }, "width": 336, - "height": 328, + "height": 342, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -100,7 +100,7 @@ "type": "person", "pos": { "x": 101, - "y": 309 + "y": 311 }, "width": 134, "height": 89, @@ -145,7 +145,7 @@ "y": 273 }, "width": 210, - "height": 515, + "height": 525, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -187,7 +187,7 @@ "y": 303 }, "width": 84, - "height": 101, + "height": 104, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -226,7 +226,7 @@ "type": "c4-person", "pos": { "x": 416, - "y": 578 + "y": 588 }, "width": 150, "height": 180, @@ -292,19 +292,19 @@ "route": [ { "x": 168, - "y": 424 + "y": 426 }, { "x": 168, - "y": 448 + "y": 450.79998779296875 }, { "x": 168, - "y": 461 + "y": 467 }, { "x": 168, - "y": 489 + "y": 507 } ], "isCurve": true, @@ -348,11 +348,11 @@ }, { "x": 168, - "y": 264.20001220703125 + "y": 264.6000061035156 }, { "x": 168, - "y": 309 + "y": 311 } ], "isCurve": true, @@ -436,19 +436,19 @@ "route": [ { "x": 491, - "y": 405 + "y": 407 }, { "x": 491, - "y": 444.20001220703125 + "y": 447 }, { "x": 491, - "y": 478.6000061035156 + "y": 483.20001220703125 }, { "x": 491, - "y": 577 + "y": 588 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg index 65e12a1b3..251910a6e 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + - - - + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json index 95cb99c31..52e292df6 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 12, - "y": 935 + "y": 938 }, "width": 336, - "height": 328, + "height": 342, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -100,7 +100,7 @@ "type": "person", "pos": { "x": 113, - "y": 750 + "y": 753 }, "width": 134, "height": 89, @@ -145,7 +145,7 @@ "y": 229 }, "width": 250, - "height": 451, + "height": 454, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -187,7 +187,7 @@ "y": 279 }, "width": 84, - "height": 101, + "height": 104, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -226,7 +226,7 @@ "type": "c4-person", "pos": { "x": 306, - "y": 450 + "y": 453 }, "width": 150, "height": 180, @@ -292,11 +292,11 @@ "route": [ { "x": 180, - "y": 865 + "y": 868 }, { "x": 180, - "y": 920 + "y": 938 } ], "animated": false, @@ -331,7 +331,7 @@ "route": [ { "x": 258, - "y": 144 + "y": 143 }, { "x": 257.5830078125, @@ -343,7 +343,7 @@ }, { "x": 180, - "y": 750 + "y": 753 } ], "animated": false, @@ -378,7 +378,7 @@ "route": [ { "x": 304, - "y": 144 + "y": 143 }, { "x": 303.9159851074219, @@ -425,11 +425,11 @@ "route": [ { "x": 381, - "y": 381 + "y": 383 }, { "x": 382, - "y": 449 + "y": 453 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg index d7fdb9e74..6305b8c57 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + - - - + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json index e462c9a73..4b80ded31 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json @@ -513,12 +513,12 @@ "link": "", "route": [ { - "x": 1092, - "y": 348 + "x": 1091, + "y": 349 }, { - "x": 968, - "y": 439.6000061035156 + "x": 967.7999877929688, + "y": 439.79998779296875 }, { "x": 937, @@ -801,11 +801,11 @@ "link": "", "route": [ { - "x": 1505, + "x": 1503, "y": 238 }, { - "x": 2410.60009765625, + "x": 2410.199951171875, "y": 417.6000061035156 }, { diff --git a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg index 2613fb8b3..fb2279b45 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

Internet Banking System

@@ -862,9 +862,9 @@

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - + @@ -875,12 +875,12 @@ - + - +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg index 31b06adcb..46f088711 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg @@ -836,7 +836,7 @@ .d2-1295531492 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

Internet Banking System

@@ -864,7 +864,7 @@

Stores user registration information, hashed authentication credentials, access logs, etc.

Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - + diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json index e0d8c0959..999037997 100644 --- a/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json +++ b/e2etests/testdata/txtar/small-c4-person/dagre/board.exp.json @@ -19,7 +19,7 @@ "y": 0 }, "width": 180, - "height": 94, + "height": 97, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg index 009c53f4e..a743498d0 100644 --- a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg @@ -1,9 +1,9 @@ -c4-person - - + .d2-1864249435 .fill-N1{fill:#0A0F25;} + .d2-1864249435 .fill-N2{fill:#676C7E;} + .d2-1864249435 .fill-N3{fill:#9499AB;} + .d2-1864249435 .fill-N4{fill:#CFD2DD;} + .d2-1864249435 .fill-N5{fill:#DEE1EB;} + .d2-1864249435 .fill-N6{fill:#EEF1F8;} + .d2-1864249435 .fill-N7{fill:#FFFFFF;} + .d2-1864249435 .fill-B1{fill:#0D32B2;} + .d2-1864249435 .fill-B2{fill:#0D32B2;} + .d2-1864249435 .fill-B3{fill:#E3E9FD;} + .d2-1864249435 .fill-B4{fill:#E3E9FD;} + .d2-1864249435 .fill-B5{fill:#EDF0FD;} + .d2-1864249435 .fill-B6{fill:#F7F8FE;} + .d2-1864249435 .fill-AA2{fill:#4A6FF3;} + .d2-1864249435 .fill-AA4{fill:#EDF0FD;} + .d2-1864249435 .fill-AA5{fill:#F7F8FE;} + .d2-1864249435 .fill-AB4{fill:#EDF0FD;} + .d2-1864249435 .fill-AB5{fill:#F7F8FE;} + .d2-1864249435 .stroke-N1{stroke:#0A0F25;} + .d2-1864249435 .stroke-N2{stroke:#676C7E;} + .d2-1864249435 .stroke-N3{stroke:#9499AB;} + .d2-1864249435 .stroke-N4{stroke:#CFD2DD;} + .d2-1864249435 .stroke-N5{stroke:#DEE1EB;} + .d2-1864249435 .stroke-N6{stroke:#EEF1F8;} + .d2-1864249435 .stroke-N7{stroke:#FFFFFF;} + .d2-1864249435 .stroke-B1{stroke:#0D32B2;} + .d2-1864249435 .stroke-B2{stroke:#0D32B2;} + .d2-1864249435 .stroke-B3{stroke:#E3E9FD;} + .d2-1864249435 .stroke-B4{stroke:#E3E9FD;} + .d2-1864249435 .stroke-B5{stroke:#EDF0FD;} + .d2-1864249435 .stroke-B6{stroke:#F7F8FE;} + .d2-1864249435 .stroke-AA2{stroke:#4A6FF3;} + .d2-1864249435 .stroke-AA4{stroke:#EDF0FD;} + .d2-1864249435 .stroke-AA5{stroke:#F7F8FE;} + .d2-1864249435 .stroke-AB4{stroke:#EDF0FD;} + .d2-1864249435 .stroke-AB5{stroke:#F7F8FE;} + .d2-1864249435 .background-color-N1{background-color:#0A0F25;} + .d2-1864249435 .background-color-N2{background-color:#676C7E;} + .d2-1864249435 .background-color-N3{background-color:#9499AB;} + .d2-1864249435 .background-color-N4{background-color:#CFD2DD;} + .d2-1864249435 .background-color-N5{background-color:#DEE1EB;} + .d2-1864249435 .background-color-N6{background-color:#EEF1F8;} + .d2-1864249435 .background-color-N7{background-color:#FFFFFF;} + .d2-1864249435 .background-color-B1{background-color:#0D32B2;} + .d2-1864249435 .background-color-B2{background-color:#0D32B2;} + .d2-1864249435 .background-color-B3{background-color:#E3E9FD;} + .d2-1864249435 .background-color-B4{background-color:#E3E9FD;} + .d2-1864249435 .background-color-B5{background-color:#EDF0FD;} + .d2-1864249435 .background-color-B6{background-color:#F7F8FE;} + .d2-1864249435 .background-color-AA2{background-color:#4A6FF3;} + .d2-1864249435 .background-color-AA4{background-color:#EDF0FD;} + .d2-1864249435 .background-color-AA5{background-color:#F7F8FE;} + .d2-1864249435 .background-color-AB4{background-color:#EDF0FD;} + .d2-1864249435 .background-color-AB5{background-color:#F7F8FE;} + .d2-1864249435 .color-N1{color:#0A0F25;} + .d2-1864249435 .color-N2{color:#676C7E;} + .d2-1864249435 .color-N3{color:#9499AB;} + .d2-1864249435 .color-N4{color:#CFD2DD;} + .d2-1864249435 .color-N5{color:#DEE1EB;} + .d2-1864249435 .color-N6{color:#EEF1F8;} + .d2-1864249435 .color-N7{color:#FFFFFF;} + .d2-1864249435 .color-B1{color:#0D32B2;} + .d2-1864249435 .color-B2{color:#0D32B2;} + .d2-1864249435 .color-B3{color:#E3E9FD;} + .d2-1864249435 .color-B4{color:#E3E9FD;} + .d2-1864249435 .color-B5{color:#EDF0FD;} + .d2-1864249435 .color-B6{color:#F7F8FE;} + .d2-1864249435 .color-AA2{color:#4A6FF3;} + .d2-1864249435 .color-AA4{color:#EDF0FD;} + .d2-1864249435 .color-AA5{color:#F7F8FE;} + .d2-1864249435 .color-AB4{color:#EDF0FD;} + .d2-1864249435 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-1864249435);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1864249435);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1864249435);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1864249435);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + + \ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json index 56a15e872..a6f4b3250 100644 --- a/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json +++ b/e2etests/testdata/txtar/small-c4-person/elk/board.exp.json @@ -19,7 +19,7 @@ "y": 12 }, "width": 180, - "height": 94, + "height": 97, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, diff --git a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg index 4de020608..fa51d71b6 100644 --- a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg @@ -1,9 +1,9 @@ -c4-person - - + .d2-1736778707 .fill-N1{fill:#0A0F25;} + .d2-1736778707 .fill-N2{fill:#676C7E;} + .d2-1736778707 .fill-N3{fill:#9499AB;} + .d2-1736778707 .fill-N4{fill:#CFD2DD;} + .d2-1736778707 .fill-N5{fill:#DEE1EB;} + .d2-1736778707 .fill-N6{fill:#EEF1F8;} + .d2-1736778707 .fill-N7{fill:#FFFFFF;} + .d2-1736778707 .fill-B1{fill:#0D32B2;} + .d2-1736778707 .fill-B2{fill:#0D32B2;} + .d2-1736778707 .fill-B3{fill:#E3E9FD;} + .d2-1736778707 .fill-B4{fill:#E3E9FD;} + .d2-1736778707 .fill-B5{fill:#EDF0FD;} + .d2-1736778707 .fill-B6{fill:#F7F8FE;} + .d2-1736778707 .fill-AA2{fill:#4A6FF3;} + .d2-1736778707 .fill-AA4{fill:#EDF0FD;} + .d2-1736778707 .fill-AA5{fill:#F7F8FE;} + .d2-1736778707 .fill-AB4{fill:#EDF0FD;} + .d2-1736778707 .fill-AB5{fill:#F7F8FE;} + .d2-1736778707 .stroke-N1{stroke:#0A0F25;} + .d2-1736778707 .stroke-N2{stroke:#676C7E;} + .d2-1736778707 .stroke-N3{stroke:#9499AB;} + .d2-1736778707 .stroke-N4{stroke:#CFD2DD;} + .d2-1736778707 .stroke-N5{stroke:#DEE1EB;} + .d2-1736778707 .stroke-N6{stroke:#EEF1F8;} + .d2-1736778707 .stroke-N7{stroke:#FFFFFF;} + .d2-1736778707 .stroke-B1{stroke:#0D32B2;} + .d2-1736778707 .stroke-B2{stroke:#0D32B2;} + .d2-1736778707 .stroke-B3{stroke:#E3E9FD;} + .d2-1736778707 .stroke-B4{stroke:#E3E9FD;} + .d2-1736778707 .stroke-B5{stroke:#EDF0FD;} + .d2-1736778707 .stroke-B6{stroke:#F7F8FE;} + .d2-1736778707 .stroke-AA2{stroke:#4A6FF3;} + .d2-1736778707 .stroke-AA4{stroke:#EDF0FD;} + .d2-1736778707 .stroke-AA5{stroke:#F7F8FE;} + .d2-1736778707 .stroke-AB4{stroke:#EDF0FD;} + .d2-1736778707 .stroke-AB5{stroke:#F7F8FE;} + .d2-1736778707 .background-color-N1{background-color:#0A0F25;} + .d2-1736778707 .background-color-N2{background-color:#676C7E;} + .d2-1736778707 .background-color-N3{background-color:#9499AB;} + .d2-1736778707 .background-color-N4{background-color:#CFD2DD;} + .d2-1736778707 .background-color-N5{background-color:#DEE1EB;} + .d2-1736778707 .background-color-N6{background-color:#EEF1F8;} + .d2-1736778707 .background-color-N7{background-color:#FFFFFF;} + .d2-1736778707 .background-color-B1{background-color:#0D32B2;} + .d2-1736778707 .background-color-B2{background-color:#0D32B2;} + .d2-1736778707 .background-color-B3{background-color:#E3E9FD;} + .d2-1736778707 .background-color-B4{background-color:#E3E9FD;} + .d2-1736778707 .background-color-B5{background-color:#EDF0FD;} + .d2-1736778707 .background-color-B6{background-color:#F7F8FE;} + .d2-1736778707 .background-color-AA2{background-color:#4A6FF3;} + .d2-1736778707 .background-color-AA4{background-color:#EDF0FD;} + .d2-1736778707 .background-color-AA5{background-color:#F7F8FE;} + .d2-1736778707 .background-color-AB4{background-color:#EDF0FD;} + .d2-1736778707 .background-color-AB5{background-color:#F7F8FE;} + .d2-1736778707 .color-N1{color:#0A0F25;} + .d2-1736778707 .color-N2{color:#676C7E;} + .d2-1736778707 .color-N3{color:#9499AB;} + .d2-1736778707 .color-N4{color:#CFD2DD;} + .d2-1736778707 .color-N5{color:#DEE1EB;} + .d2-1736778707 .color-N6{color:#EEF1F8;} + .d2-1736778707 .color-N7{color:#FFFFFF;} + .d2-1736778707 .color-B1{color:#0D32B2;} + .d2-1736778707 .color-B2{color:#0D32B2;} + .d2-1736778707 .color-B3{color:#E3E9FD;} + .d2-1736778707 .color-B4{color:#E3E9FD;} + .d2-1736778707 .color-B5{color:#EDF0FD;} + .d2-1736778707 .color-B6{color:#F7F8FE;} + .d2-1736778707 .color-AA2{color:#4A6FF3;} + .d2-1736778707 .color-AA4{color:#EDF0FD;} + .d2-1736778707 .color-AA5{color:#F7F8FE;} + .d2-1736778707 .color-AB4{color:#EDF0FD;} + .d2-1736778707 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-1736778707);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1736778707);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1736778707);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1736778707);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + + \ No newline at end of file diff --git a/e2etests/txtar.txt b/e2etests/txtar.txt index 89d18ce17..62d82d7ef 100644 --- a/e2etests/txtar.txt +++ b/e2etests/txtar.txt @@ -1221,3 +1221,46 @@ A customer of the bank, with personal bank accounts shape: c4-person label.near: bottom-center } + +customer1: |md + ## Personal Banking Customer + [person] + + A customer of the bank, with pekkrsonal bank ccountskks. +| { + shape: c4-person +} + +customer2: |md + ## Personal Banking Customerk + [person] + + A customer of the bank, with pekkrsonal bank accountskks. + + A customer of the bank, with pekkrsonal bank accountskks. + + A customer of the bank, with pekkrsonal bank accountskks. +| { + shape: c4-person +} + +customer3: |md + ## Personal Banking Customer + [person] + + A customer of the bank, with pekkrsonal bank accountskks. +| { + shape: c4-person +} + +customer4: |md + ## Personal Banking Customer + [person] + + A customer of the bank, with pekkrsonal bank accountskks. +| { + shape: c4-person +} + +customer1 -> customer2 -> customer3 -> customer4 +customer4 -> customer1 -> customer3 -> customer2 diff --git a/lib/shape/shape_c4_person.go b/lib/shape/shape_c4_person.go index 99d47b07d..e08dc2810 100644 --- a/lib/shape/shape_c4_person.go +++ b/lib/shape/shape_c4_person.go @@ -11,6 +11,14 @@ import ( // Optimal value for circular arc approximation with cubic bezier curves const kCircleApprox = 0.5522847498307936 // 4*(math.Sqrt(2)-1)/3 +// Constants to match frontend implementation +const ( + C4_PERSON_AR_LIMIT = 1.5 + HEAD_RADIUS_FACTOR = 0.22 + BODY_TOP_FACTOR = 0.8 + CORNER_RADIUS_FACTOR = 0.175 +) + type shapeC4Person struct { *baseShape } @@ -26,32 +34,25 @@ func NewC4Person(box *geo.Box) Shape { return shape } -const ( - C4_PERSON_AR_LIMIT = 1.5 -) - func (s shapeC4Person) GetInnerBox() *geo.Box { width := s.Box.Width height := s.Box.Height - headRadius := width * 0.22 - headCenterY := height * 0.18 - bodyTop := headCenterY + headRadius*0.8 + headRadius := width * HEAD_RADIUS_FACTOR + headCenterY := headRadius + bodyTop := headCenterY + headRadius*BODY_TOP_FACTOR - // Use a small fixed percentage instead of the full corner radius - horizontalPadding := width * 0.05 // 5% padding + // Horizontal padding = 5% of width + horizontalPadding := width * 0.05 + // Vertical padding = 3% of height + verticalPadding := height * 0.03 tl := s.Box.TopLeft.Copy() tl.X += horizontalPadding + tl.Y += bodyTop + verticalPadding - // Add vertical padding - tl.Y += bodyTop + height*0.03 - - // Width minus padding on both sides innerWidth := width - (horizontalPadding * 2) - - // Add bottom padding - innerHeight := height - (tl.Y - s.Box.TopLeft.Y) - (height * 0.03) + innerHeight := height - bodyTop - (verticalPadding * 2) return geo.NewBox(tl, innerWidth, innerHeight) } @@ -62,15 +63,15 @@ func bodyPath(box *geo.Box) *svg.SvgPathContext { pc := svg.NewSVGPathContext(box.TopLeft, 1, 1) - headRadius := width * 0.22 - headCenterY := height * 0.18 - bodyTop := headCenterY + headRadius*0.8 + headRadius := width * HEAD_RADIUS_FACTOR + headCenterY := headRadius + bodyTop := headCenterY + headRadius*BODY_TOP_FACTOR bodyWidth := width bodyHeight := height - bodyTop bodyLeft := 0 - // Ensure cornerRadius is constrained to a portion of the shortest dimension - // This prevents distorted corners when width is large compared to height - cornerRadius := math.Min(width*0.175, bodyHeight*0.25) + + // Use the same corner radius calculation as frontend + cornerRadius := math.Min(width*CORNER_RADIUS_FACTOR, bodyHeight*0.25) pc.StartAt(pc.Absolute(float64(bodyLeft), bodyTop+cornerRadius)) @@ -88,13 +89,12 @@ func bodyPath(box *geo.Box) *svg.SvgPathContext { func headPath(box *geo.Box) *svg.SvgPathContext { width := box.Width - height := box.Height pc := svg.NewSVGPathContext(box.TopLeft, 1, 1) - headRadius := width * 0.22 + headRadius := width * HEAD_RADIUS_FACTOR headCenterX := width / 2 - headCenterY := height * 0.18 + headCenterY := headRadius pc.StartAt(pc.Absolute(headCenterX, headCenterY-headRadius)) @@ -123,13 +123,12 @@ func headPath(box *geo.Box) *svg.SvgPathContext { func (s shapeC4Person) Perimeter() []geo.Intersectable { width := s.Box.Width - height := s.Box.Height bodyPerimeter := bodyPath(s.Box).Path - headRadius := width * 0.22 + headRadius := width * HEAD_RADIUS_FACTOR headCenterX := s.Box.TopLeft.X + width/2 - headCenterY := s.Box.TopLeft.Y + height*0.18 + headCenterY := s.Box.TopLeft.Y + headRadius headCenter := geo.NewPoint(headCenterX, headCenterY) headEllipse := geo.NewEllipse(headCenter, headRadius, headRadius) @@ -150,18 +149,18 @@ func (s shapeC4Person) GetDimensionsToFit(width, height, paddingX, paddingY floa // Account for 10% total horizontal padding (5% on each side) totalWidth := contentWidth / 0.9 - headRadius := totalWidth * 0.22 - headCenterY := totalWidth * 0.18 - bodyTop := headCenterY + headRadius*0.8 + headRadius := totalWidth * HEAD_RADIUS_FACTOR - // Include vertical padding from GetInnerBox + // Use positioning matching frontend + headCenterY := headRadius + bodyTop := headCenterY + headRadius*BODY_TOP_FACTOR + + // Include vertical padding verticalPadding := totalWidth * 0.06 // 3% top + 3% bottom totalHeight := contentHeight + bodyTop + verticalPadding - // Calculate minimum height based on actual proportions - // Head height: 2 * headRadius = 0.44 * width - // Body should be at least half the width - minHeight := totalWidth * 0.95 // Reduced from 1.2 + // Calculate minimum height + minHeight := totalWidth * 0.95 if totalHeight < minHeight { totalHeight = minHeight } From 434dca025015cf144efc2de993b4387efa401158 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 13 Mar 2025 19:54:31 -0600 Subject: [PATCH 24/54] revert test --- .../testdata/TestCLI_E2E/empty-base.exp.svg | 168 +++++++++--------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/e2etests-cli/testdata/TestCLI_E2E/empty-base.exp.svg b/e2etests-cli/testdata/TestCLI_E2E/empty-base.exp.svg index 99003267f..5efe15eb8 100644 --- a/e2etests-cli/testdata/TestCLI_E2E/empty-base.exp.svg +++ b/e2etests-cli/testdata/TestCLI_E2E/empty-base.exp.svg @@ -1,9 +1,9 @@ ab +}]]>ab -abdc +abdc -abdce - +abdce + - - - + + + \ No newline at end of file From c22a8e1ef2644cd45b92089501c9808bcc47a7ee Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 13 Mar 2025 20:04:14 -0600 Subject: [PATCH 25/54] round --- .../c4-person-label/dagre/board.exp.json | 16 +- .../c4-person-label/dagre/sketch.exp.svg | 576 ++++++++--------- .../txtar/c4-person-label/elk/board.exp.json | 10 +- .../txtar/c4-person-label/elk/sketch.exp.svg | 576 ++++++++--------- .../c4-person-shape/dagre/board.exp.json | 44 +- .../c4-person-shape/dagre/sketch.exp.svg | 574 ++++++++-------- .../txtar/c4-person-shape/elk/board.exp.json | 30 +- .../txtar/c4-person-shape/elk/sketch.exp.svg | 574 ++++++++-------- .../txtar/c4-theme/dagre/board.exp.json | 168 ++--- .../txtar/c4-theme/dagre/sketch.exp.svg | 612 +++++++++--------- .../txtar/c4-theme/elk/board.exp.json | 100 +-- .../txtar/c4-theme/elk/sketch.exp.svg | 612 +++++++++--------- .../small-c4-person/dagre/sketch.exp.svg | 4 +- .../txtar/small-c4-person/elk/sketch.exp.svg | 4 +- lib/shape/shape_c4_person.go | 41 +- 15 files changed, 1970 insertions(+), 1971 deletions(-) diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json index def972f1f..46d5d7efb 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json @@ -581,12 +581,12 @@ "y": 697.2000122070312 }, { - "x": 1602.199951171875, - "y": 1062.199951171875 + "x": 1602.4000244140625, + "y": 1061.800048828125 }, { - "x": 1475, - "y": 1195 + "x": 1476, + "y": 1193 } ], "isCurve": true, @@ -621,12 +621,12 @@ "link": "", "route": [ { - "x": 1453, - "y": 1116 + "x": 1454, + "y": 1115 }, { - "x": 1482.4000244140625, - "y": 1046.4000244140625 + "x": 1482.5999755859375, + "y": 1046.199951171875 }, { "x": 1485.4000244140625, diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg index 25c78740e..50b84155b 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg @@ -1,13 +1,13 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank ccountskks.

-

Personal Banking Customerk

+

Personal Banking Customerk

[person]

A customer of the bank, with pekkrsonal bank accountskks.

A customer of the bank, with pekkrsonal bank accountskks.

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank accountskks.

-
+
- - - - - - - + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json index e46b21769..475186c2e 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json @@ -338,7 +338,7 @@ }, { "x": 1414, - "y": 699 + "y": 700 } ], "animated": false, @@ -377,7 +377,7 @@ }, { "x": 1237, - "y": 1232 + "y": 1233 } ], "animated": false, @@ -411,7 +411,7 @@ "link": "", "route": [ { - "x": 1466, + "x": 1465, "y": 1485 }, { @@ -451,7 +451,7 @@ "route": [ { "x": 1620, - "y": 1603 + "y": 1602 }, { "x": 1620, @@ -494,7 +494,7 @@ }, { "x": 1526, - "y": 1233 + "y": 1234 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg index 5a6e872f4..c47068bb4 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg @@ -1,13 +1,13 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank ccountskks.

-

Personal Banking Customerk

+

Personal Banking Customerk

[person]

A customer of the bank, with pekkrsonal bank accountskks.

A customer of the bank, with pekkrsonal bank accountskks.

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank accountskks.

-
+
- - - - - - - + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json index bd1bb8ae3..6927d0036 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 0, - "y": 507 + "y": 506 }, "width": 336, - "height": 342, + "height": 341, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -100,7 +100,7 @@ "type": "person", "pos": { "x": 101, - "y": 311 + "y": 310 }, "width": 134, "height": 89, @@ -145,7 +145,7 @@ "y": 273 }, "width": 210, - "height": 525, + "height": 524, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -183,11 +183,11 @@ "id": "styling.c4styled", "type": "c4-person", "pos": { - "x": 449, + "x": 450, "y": 303 }, - "width": 84, - "height": 104, + "width": 83, + "height": 103, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -226,7 +226,7 @@ "type": "c4-person", "pos": { "x": 416, - "y": 588 + "y": 587 }, "width": 150, "height": 180, @@ -292,19 +292,19 @@ "route": [ { "x": 168, - "y": 426 + "y": 425 }, { "x": 168, - "y": 450.79998779296875 + "y": 449.79998779296875 }, { "x": 168, - "y": 467 + "y": 466 }, { "x": 168, - "y": 507 + "y": 506 } ], "isCurve": true, @@ -339,20 +339,20 @@ "link": "", "route": [ { - "x": 262, + "x": 261, "y": 119 }, { - "x": 186.8000030517578, + "x": 186.60000610351562, "y": 177.8000030517578 }, { "x": 168, - "y": 264.6000061035156 + "y": 264.3999938964844 }, { "x": 168, - "y": 311 + "y": 310 } ], "isCurve": true, @@ -387,11 +387,11 @@ "link": "", "route": [ { - "x": 397, + "x": 398, "y": 119 }, { - "x": 472.20001220703125, + "x": 472.3999938964844, "y": 177.8000030517578 }, { @@ -436,19 +436,19 @@ "route": [ { "x": 491, - "y": 407 + "y": 406 }, { "x": 491, - "y": 447 + "y": 446 }, { "x": 491, - "y": 483.20001220703125 + "y": 482.20001220703125 }, { "x": 491, - "y": 588 + "y": 587 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg index 251910a6e..09f65b478 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + - - + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json index 52e292df6..7e26d5c32 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 12, - "y": 938 + "y": 937 }, "width": 336, - "height": 342, + "height": 341, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -100,7 +100,7 @@ "type": "person", "pos": { "x": 113, - "y": 753 + "y": 752 }, "width": 134, "height": 89, @@ -145,7 +145,7 @@ "y": 229 }, "width": 250, - "height": 454, + "height": 453, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -183,11 +183,11 @@ "id": "styling.c4styled", "type": "c4-person", "pos": { - "x": 339, + "x": 340, "y": 279 }, - "width": 84, - "height": 104, + "width": 83, + "height": 103, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -226,7 +226,7 @@ "type": "c4-person", "pos": { "x": 306, - "y": 453 + "y": 452 }, "width": 150, "height": 180, @@ -292,11 +292,11 @@ "route": [ { "x": 180, - "y": 868 + "y": 867 }, { "x": 180, - "y": 938 + "y": 937 } ], "animated": false, @@ -331,7 +331,7 @@ "route": [ { "x": 258, - "y": 143 + "y": 144 }, { "x": 257.5830078125, @@ -343,7 +343,7 @@ }, { "x": 180, - "y": 753 + "y": 752 } ], "animated": false, @@ -378,7 +378,7 @@ "route": [ { "x": 304, - "y": 143 + "y": 144 }, { "x": 303.9159851074219, @@ -425,11 +425,11 @@ "route": [ { "x": 381, - "y": 383 + "y": 382 }, { "x": 382, - "y": 453 + "y": 452 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg index 6305b8c57..f1cdfda47 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + - - + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json index 4b80ded31..bfeabddd5 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json @@ -18,8 +18,8 @@ "x": 1089, "y": 0 }, - "width": 415, - "height": 394, + "width": 414, + "height": 393, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 147, - "y": 551 + "y": 550 }, "width": 2407, "height": 915, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 177, - "y": 581 + "y": 580 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 390, - "y": 866 + "y": 865 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 1123, - "y": 866 + "y": 865 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 1246, - "y": 1167 + "y": 1166 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1890, - "y": 866 + "y": 865 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 2410, - "y": 1603 + "y": 1602 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 0, - "y": 1603 + "y": 1602 }, "width": 629, "height": 164, @@ -418,19 +418,19 @@ "route": [ { "x": 1089, - "y": 262 + "y": 261 }, { "x": 579.4000244140625, - "y": 422.3999938964844 + "y": 421.3999938964844 }, { "x": 452, - "y": 541 + "y": 540 }, { "x": 452, - "y": 581 + "y": 580 } ], "isCurve": true, @@ -466,19 +466,19 @@ "route": [ { "x": 452, - "y": 744.5 + "y": 743.5 }, { "x": 452, - "y": 793.2999877929688 + "y": 792.2999877929688 }, { "x": 472.3999938964844, - "y": 817.7000122070312 + "y": 816.7000122070312 }, { "x": 554, - "y": 866.5 + "y": 865.5 } ], "isCurve": true, @@ -514,43 +514,43 @@ "route": [ { "x": 1091, - "y": 349 + "y": 348 }, { "x": 967.7999877929688, - "y": 439.79998779296875 + "y": 438.79998779296875 }, { "x": 937, - "y": 476.20001220703125 + "y": 475.20001220703125 }, { "x": 937, - "y": 496.75 + "y": 495.75 }, { "x": 937, - "y": 517.2990112304688 + "y": 516.2990112304688 }, { "x": 937, - "y": 557.4000244140625 + "y": 556.4000244140625 }, { "x": 937, - "y": 597 + "y": 596 }, { "x": 937, - "y": 636.5999755859375 + "y": 635.5999755859375 }, { "x": 916.5999755859375, - "y": 817.7000122070312 + "y": 816.7000122070312 }, { "x": 835, - "y": 866.5 + "y": 865.5 } ], "isCurve": true, @@ -585,44 +585,44 @@ "link": "", "route": [ { - "x": 1430, - "y": 394 + "x": 1429, + "y": 393 }, { - "x": 1466.800048828125, - "y": 448.79998779296875 + "x": 1466.5999755859375, + "y": 447.79998779296875 }, { "x": 1476, - "y": 476.20001220703125 + "y": 475.20001220703125 }, { "x": 1476, - "y": 496.75 + "y": 495.75 }, { "x": 1476, - "y": 517.2990112304688 + "y": 516.2990112304688 }, { "x": 1476, - "y": 557.4000244140625 + "y": 556.4000244140625 }, { "x": 1476, - "y": 597 + "y": 596 }, { "x": 1476, - "y": 636.5999755859375 + "y": 635.5999755859375 }, { "x": 1476, - "y": 817.7000122070312 + "y": 816.7000122070312 }, { "x": 1476, - "y": 866.5 + "y": 865.5 } ], "isCurve": true, @@ -658,19 +658,19 @@ "route": [ { "x": 694.5, - "y": 1029.5 + "y": 1028.5 }, { "x": 694.5, - "y": 1084.699951171875 + "y": 1083.699951171875 }, { "x": 804.7000122070312, - "y": 1119.7220458984375 + "y": 1118.7220458984375 }, { "x": 1245.5, - "y": 1204.6099853515625 + "y": 1203.6099853515625 } ], "isCurve": true, @@ -706,19 +706,19 @@ "route": [ { "x": 1476, - "y": 1029.5 + "y": 1028.5 }, { "x": 1476, - "y": 1084.699951171875 + "y": 1083.699951171875 }, { "x": 1476, - "y": 1112.300048828125 + "y": 1111.300048828125 }, { "x": 1476, - "y": 1167.5 + "y": 1166.5 } ], "isCurve": true, @@ -754,19 +754,19 @@ "route": [ { "x": 1245.5, - "y": 1275.1949462890625 + "y": 1274.1949462890625 }, { "x": 500.6990051269531, - "y": 1427.8389892578125 + "y": 1426.8389892578125 }, { "x": 314.5, - "y": 1548.300048828125 + "y": 1547.300048828125 }, { "x": 314.5, - "y": 1603.5 + "y": 1602.5 } ], "isCurve": true, @@ -806,99 +806,99 @@ }, { "x": 2410.199951171875, - "y": 417.6000061035156 + "y": 416.79998779296875 }, { "x": 2637, - "y": 476.20001220703125 + "y": 475.20001220703125 }, { "x": 2637, - "y": 496.75 + "y": 495.75 }, { "x": 2637, - "y": 517.2990112304688 + "y": 516.2990112304688 }, { "x": 2637, - "y": 557.4000244140625 + "y": 556.4000244140625 }, { "x": 2637, - "y": 597 + "y": 596 }, { "x": 2637, - "y": 636.5999755859375 + "y": 635.5999755859375 }, { "x": 2637, - "y": 691.5 + "y": 690.5 }, { "x": 2637, - "y": 734.25 + "y": 733.25 }, { "x": 2637, - "y": 777 + "y": 776 }, { "x": 2637, - "y": 834 + "y": 833 }, { "x": 2637, - "y": 876.75 + "y": 875.75 }, { "x": 2637, - "y": 919.5 + "y": 918.5 }, { "x": 2637, - "y": 978.0999755859375 + "y": 977.0999755859375 }, { "x": 2637, - "y": 1023.25 + "y": 1022.25 }, { "x": 2637, - "y": 1068.4000244140625 + "y": 1067.4000244140625 }, { "x": 2637, - "y": 1128.5999755859375 + "y": 1127.5999755859375 }, { "x": 2637, - "y": 1173.75 + "y": 1172.75 }, { "x": 2637, - "y": 1218.9000244140625 + "y": 1217.9000244140625 }, { "x": 2637, - "y": 1292.4000244140625 + "y": 1291.4000244140625 }, { "x": 2637, - "y": 1357.5 + "y": 1356.5 }, { "x": 2637, - "y": 1422.5999755859375 + "y": 1421.5999755859375 }, { "x": 2632.800048828125, - "y": 1548.300048828125 + "y": 1547.300048828125 }, { "x": 2616, - "y": 1603.5 + "y": 1602.5 } ], "isCurve": true, @@ -934,19 +934,19 @@ "route": [ { "x": 1707.5, - "y": 1282.843994140625 + "y": 1281.843994140625 }, { "x": 2241.5, - "y": 1429.3680419921875 + "y": 1428.3680419921875 }, { "x": 2394.39990234375, - "y": 1548.300048828125 + "y": 1547.300048828125 }, { "x": 2472, - "y": 1603.5 + "y": 1602.5 } ], "isCurve": true, @@ -982,19 +982,19 @@ "route": [ { "x": 2206.5, - "y": 1029.5 + "y": 1028.5 }, { "x": 2206.5, - "y": 1084.699951171875 + "y": 1083.699951171875 }, { "x": 2106.5, - "y": 1119.0999755859375 + "y": 1118.0999755859375 }, { "x": 1706.5, - "y": 1201.5 + "y": 1200.5 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg index fb2279b45..ba14d5df2 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json index 4d6d3ccd8..4f90b629b 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json @@ -15,11 +15,11 @@ "id": "customer", "type": "c4-person", "pos": { - "x": 704, + "x": 705, "y": 12 }, - "width": 415, - "height": 394, + "width": 414, + "height": 393, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 12, - "y": 658 + "y": 657 }, "width": 2218, "height": 1035, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 62, - "y": 708 + "y": 707 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 190, - "y": 1043 + "y": 1042 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 819, - "y": 1043 + "y": 1042 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 942, - "y": 1394 + "y": 1393 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1546, - "y": 1043 + "y": 1042 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 1746, - "y": 1895 + "y": 1894 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 781, - "y": 1895 + "y": 1894 }, "width": 629, "height": 164, @@ -418,19 +418,19 @@ "route": [ { "x": 788, - "y": 406 + "y": 405 }, { - "x": 787.75, - "y": 446 + "x": 788.0499877929688, + "y": 445 }, { "x": 359.25, - "y": 446 + "y": 445 }, { "x": 359.25, - "y": 708 + "y": 707 } ], "animated": false, @@ -465,11 +465,11 @@ "route": [ { "x": 393, - "y": 872 + "y": 871 }, { "x": 393, - "y": 1043 + "y": 1042 } ], "animated": false, @@ -504,19 +504,19 @@ "route": [ { "x": 871, - "y": 406 + "y": 405 }, { - "x": 870.75, - "y": 496 + "x": 870.8489990234375, + "y": 495 }, { "x": 652, - "y": 496 + "y": 495 }, { "x": 652, - "y": 1043 + "y": 1042 } ], "animated": false, @@ -551,11 +551,11 @@ "route": [ { "x": 954, - "y": 406 + "y": 405 }, { - "x": 953.75, - "y": 1043 + "x": 953.6489868164062, + "y": 1042 } ], "animated": false, @@ -590,19 +590,19 @@ "route": [ { "x": 494.5, - "y": 1207 + "y": 1206 }, { "x": 494.5, - "y": 1354 + "y": 1353 }, { "x": 1057.25, - "y": 1354 + "y": 1353 }, { "x": 1057.25, - "y": 1394 + "y": 1393 } ], "animated": false, @@ -637,11 +637,11 @@ "route": [ { "x": 1172.5, - "y": 1207 + "y": 1206 }, { "x": 1172.5, - "y": 1394 + "y": 1393 } ], "animated": false, @@ -676,11 +676,11 @@ "route": [ { "x": 1095.666015625, - "y": 1558 + "y": 1557 }, { "x": 1095.666015625, - "y": 1895 + "y": 1894 } ], "animated": false, @@ -714,28 +714,28 @@ "link": "", "route": [ { - "x": 1037, - "y": 406 + "x": 1036, + "y": 405 }, { - "x": 1036.75, - "y": 446 + "x": 1036.448974609375, + "y": 445 }, { "x": 2303.5, - "y": 446 + "y": 445 }, { "x": 2303.5, - "y": 1855 + "y": 1854 }, { "x": 1986.8330078125, - "y": 1855 + "y": 1854 }, { "x": 1986.8330078125, - "y": 1895 + "y": 1894 } ], "animated": false, @@ -770,19 +770,19 @@ "route": [ { "x": 1249.3330078125, - "y": 1558 + "y": 1557 }, { "x": 1249.3330078125, - "y": 1855 + "y": 1854 }, { "x": 1866.8330078125, - "y": 1855 + "y": 1854 }, { "x": 1866.8330078125, - "y": 1895 + "y": 1894 } ], "animated": false, @@ -817,19 +817,19 @@ "route": [ { "x": 1863, - "y": 1207 + "y": 1206 }, { "x": 1863, - "y": 1354 + "y": 1353 }, { "x": 1287.75, - "y": 1354 + "y": 1353 }, { "x": 1287.75, - "y": 1394 + "y": 1393 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg index 46f088711..19d96dd6b 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg index a743498d0..eab5e1bdf 100644 --- a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg @@ -89,7 +89,7 @@ .d2-1864249435 .color-AA4{color:#EDF0FD;} .d2-1864249435 .color-AA5{color:#F7F8FE;} .d2-1864249435 .color-AB4{color:#EDF0FD;} - .d2-1864249435 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-1864249435);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1864249435);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1864249435);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1864249435);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + .d2-1864249435 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-1864249435);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1864249435);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1864249435);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1864249435);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person - + \ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg index fa51d71b6..8d06fbfb8 100644 --- a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg @@ -89,7 +89,7 @@ .d2-1736778707 .color-AA4{color:#EDF0FD;} .d2-1736778707 .color-AA5{color:#F7F8FE;} .d2-1736778707 .color-AB4{color:#EDF0FD;} - .d2-1736778707 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-1736778707);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1736778707);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1736778707);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1736778707);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + .d2-1736778707 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-1736778707);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1736778707);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1736778707);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1736778707);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person - + \ No newline at end of file diff --git a/lib/shape/shape_c4_person.go b/lib/shape/shape_c4_person.go index e08dc2810..b2a571d2b 100644 --- a/lib/shape/shape_c4_person.go +++ b/lib/shape/shape_c4_person.go @@ -38,21 +38,21 @@ func (s shapeC4Person) GetInnerBox() *geo.Box { width := s.Box.Width height := s.Box.Height - headRadius := width * HEAD_RADIUS_FACTOR + headRadius := math.Round(width * HEAD_RADIUS_FACTOR) headCenterY := headRadius - bodyTop := headCenterY + headRadius*BODY_TOP_FACTOR + bodyTop := math.Round(headCenterY + headRadius*BODY_TOP_FACTOR) // Horizontal padding = 5% of width - horizontalPadding := width * 0.05 + horizontalPadding := math.Round(width * 0.05) // Vertical padding = 3% of height - verticalPadding := height * 0.03 + verticalPadding := math.Round(height * 0.03) tl := s.Box.TopLeft.Copy() tl.X += horizontalPadding tl.Y += bodyTop + verticalPadding - innerWidth := width - (horizontalPadding * 2) - innerHeight := height - bodyTop - (verticalPadding * 2) + innerWidth := math.Round(width - (horizontalPadding * 2)) + innerHeight := math.Round(height - bodyTop - (verticalPadding * 2)) return geo.NewBox(tl, innerWidth, innerHeight) } @@ -63,15 +63,14 @@ func bodyPath(box *geo.Box) *svg.SvgPathContext { pc := svg.NewSVGPathContext(box.TopLeft, 1, 1) - headRadius := width * HEAD_RADIUS_FACTOR + headRadius := math.Round(width * HEAD_RADIUS_FACTOR) headCenterY := headRadius - bodyTop := headCenterY + headRadius*BODY_TOP_FACTOR + bodyTop := math.Round(headCenterY + headRadius*BODY_TOP_FACTOR) bodyWidth := width - bodyHeight := height - bodyTop + bodyHeight := math.Round(height - bodyTop) bodyLeft := 0 - // Use the same corner radius calculation as frontend - cornerRadius := math.Min(width*CORNER_RADIUS_FACTOR, bodyHeight*0.25) + cornerRadius := math.Round(math.Min(width*CORNER_RADIUS_FACTOR, bodyHeight*0.25)) pc.StartAt(pc.Absolute(float64(bodyLeft), bodyTop+cornerRadius)) @@ -92,8 +91,8 @@ func headPath(box *geo.Box) *svg.SvgPathContext { pc := svg.NewSVGPathContext(box.TopLeft, 1, 1) - headRadius := width * HEAD_RADIUS_FACTOR - headCenterX := width / 2 + headRadius := math.Round(width * HEAD_RADIUS_FACTOR) + headCenterX := math.Round(width / 2) headCenterY := headRadius pc.StartAt(pc.Absolute(headCenterX, headCenterY-headRadius)) @@ -126,8 +125,8 @@ func (s shapeC4Person) Perimeter() []geo.Intersectable { bodyPerimeter := bodyPath(s.Box).Path - headRadius := width * HEAD_RADIUS_FACTOR - headCenterX := s.Box.TopLeft.X + width/2 + headRadius := math.Round(width * HEAD_RADIUS_FACTOR) + headCenterX := s.Box.TopLeft.X + math.Round(width/2) headCenterY := s.Box.TopLeft.Y + headRadius headCenter := geo.NewPoint(headCenterX, headCenterY) @@ -148,19 +147,19 @@ func (s shapeC4Person) GetDimensionsToFit(width, height, paddingX, paddingY floa contentHeight := height + paddingY // Account for 10% total horizontal padding (5% on each side) - totalWidth := contentWidth / 0.9 - headRadius := totalWidth * HEAD_RADIUS_FACTOR + totalWidth := math.Round(contentWidth / 0.9) + headRadius := math.Round(totalWidth * HEAD_RADIUS_FACTOR) // Use positioning matching frontend headCenterY := headRadius - bodyTop := headCenterY + headRadius*BODY_TOP_FACTOR + bodyTop := math.Round(headCenterY + headRadius*BODY_TOP_FACTOR) // Include vertical padding - verticalPadding := totalWidth * 0.06 // 3% top + 3% bottom - totalHeight := contentHeight + bodyTop + verticalPadding + verticalPadding := math.Round(totalWidth * 0.06) // 3% top + 3% bottom + totalHeight := math.Round(contentHeight + bodyTop + verticalPadding) // Calculate minimum height - minHeight := totalWidth * 0.95 + minHeight := math.Round(totalWidth * 0.95) if totalHeight < minHeight { totalHeight = minHeight } From e9aee89a1236550dd469e5f858ea7aab83e53684 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 13 Mar 2025 20:11:35 -0600 Subject: [PATCH 26/54] Revert "round" This reverts commit c22a8e1ef2644cd45b92089501c9808bcc47a7ee. --- .../c4-person-label/dagre/board.exp.json | 16 +- .../c4-person-label/dagre/sketch.exp.svg | 576 ++++++++--------- .../txtar/c4-person-label/elk/board.exp.json | 10 +- .../txtar/c4-person-label/elk/sketch.exp.svg | 576 ++++++++--------- .../c4-person-shape/dagre/board.exp.json | 44 +- .../c4-person-shape/dagre/sketch.exp.svg | 574 ++++++++-------- .../txtar/c4-person-shape/elk/board.exp.json | 30 +- .../txtar/c4-person-shape/elk/sketch.exp.svg | 574 ++++++++-------- .../txtar/c4-theme/dagre/board.exp.json | 168 ++--- .../txtar/c4-theme/dagre/sketch.exp.svg | 612 +++++++++--------- .../txtar/c4-theme/elk/board.exp.json | 100 +-- .../txtar/c4-theme/elk/sketch.exp.svg | 612 +++++++++--------- .../small-c4-person/dagre/sketch.exp.svg | 4 +- .../txtar/small-c4-person/elk/sketch.exp.svg | 4 +- lib/shape/shape_c4_person.go | 41 +- 15 files changed, 1971 insertions(+), 1970 deletions(-) diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json index 46d5d7efb..def972f1f 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json @@ -581,12 +581,12 @@ "y": 697.2000122070312 }, { - "x": 1602.4000244140625, - "y": 1061.800048828125 + "x": 1602.199951171875, + "y": 1062.199951171875 }, { - "x": 1476, - "y": 1193 + "x": 1475, + "y": 1195 } ], "isCurve": true, @@ -621,12 +621,12 @@ "link": "", "route": [ { - "x": 1454, - "y": 1115 + "x": 1453, + "y": 1116 }, { - "x": 1482.5999755859375, - "y": 1046.199951171875 + "x": 1482.4000244140625, + "y": 1046.4000244140625 }, { "x": 1485.4000244140625, diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg index 50b84155b..25c78740e 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg @@ -1,13 +1,13 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank ccountskks.

-

Personal Banking Customerk

+

Personal Banking Customerk

[person]

A customer of the bank, with pekkrsonal bank accountskks.

A customer of the bank, with pekkrsonal bank accountskks.

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank accountskks.

-
+
- - - - - - - + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json index 475186c2e..e46b21769 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json @@ -338,7 +338,7 @@ }, { "x": 1414, - "y": 700 + "y": 699 } ], "animated": false, @@ -377,7 +377,7 @@ }, { "x": 1237, - "y": 1233 + "y": 1232 } ], "animated": false, @@ -411,7 +411,7 @@ "link": "", "route": [ { - "x": 1465, + "x": 1466, "y": 1485 }, { @@ -451,7 +451,7 @@ "route": [ { "x": 1620, - "y": 1602 + "y": 1603 }, { "x": 1620, @@ -494,7 +494,7 @@ }, { "x": 1526, - "y": 1234 + "y": 1233 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg index c47068bb4..5a6e872f4 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg @@ -1,13 +1,13 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank ccountskks.

-

Personal Banking Customerk

+

Personal Banking Customerk

[person]

A customer of the bank, with pekkrsonal bank accountskks.

A customer of the bank, with pekkrsonal bank accountskks.

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank accountskks.

-
+
- - - - - - - + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json index 6927d0036..bd1bb8ae3 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 0, - "y": 506 + "y": 507 }, "width": 336, - "height": 341, + "height": 342, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -100,7 +100,7 @@ "type": "person", "pos": { "x": 101, - "y": 310 + "y": 311 }, "width": 134, "height": 89, @@ -145,7 +145,7 @@ "y": 273 }, "width": 210, - "height": 524, + "height": 525, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -183,11 +183,11 @@ "id": "styling.c4styled", "type": "c4-person", "pos": { - "x": 450, + "x": 449, "y": 303 }, - "width": 83, - "height": 103, + "width": 84, + "height": 104, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -226,7 +226,7 @@ "type": "c4-person", "pos": { "x": 416, - "y": 587 + "y": 588 }, "width": 150, "height": 180, @@ -292,19 +292,19 @@ "route": [ { "x": 168, - "y": 425 + "y": 426 }, { "x": 168, - "y": 449.79998779296875 + "y": 450.79998779296875 }, { "x": 168, - "y": 466 + "y": 467 }, { "x": 168, - "y": 506 + "y": 507 } ], "isCurve": true, @@ -339,20 +339,20 @@ "link": "", "route": [ { - "x": 261, + "x": 262, "y": 119 }, { - "x": 186.60000610351562, + "x": 186.8000030517578, "y": 177.8000030517578 }, { "x": 168, - "y": 264.3999938964844 + "y": 264.6000061035156 }, { "x": 168, - "y": 310 + "y": 311 } ], "isCurve": true, @@ -387,11 +387,11 @@ "link": "", "route": [ { - "x": 398, + "x": 397, "y": 119 }, { - "x": 472.3999938964844, + "x": 472.20001220703125, "y": 177.8000030517578 }, { @@ -436,19 +436,19 @@ "route": [ { "x": 491, - "y": 406 + "y": 407 }, { "x": 491, - "y": 446 + "y": 447 }, { "x": 491, - "y": 482.20001220703125 + "y": 483.20001220703125 }, { "x": 491, - "y": 587 + "y": 588 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg index 09f65b478..251910a6e 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + - - + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json index 7e26d5c32..52e292df6 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json @@ -16,10 +16,10 @@ "type": "c4-person", "pos": { "x": 12, - "y": 937 + "y": 938 }, "width": 336, - "height": 341, + "height": 342, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -100,7 +100,7 @@ "type": "person", "pos": { "x": 113, - "y": 752 + "y": 753 }, "width": 134, "height": 89, @@ -145,7 +145,7 @@ "y": 229 }, "width": 250, - "height": 453, + "height": 454, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -183,11 +183,11 @@ "id": "styling.c4styled", "type": "c4-person", "pos": { - "x": 340, + "x": 339, "y": 279 }, - "width": 83, - "height": 103, + "width": 84, + "height": 104, "opacity": 1, "strokeDash": 0, "strokeWidth": 1, @@ -226,7 +226,7 @@ "type": "c4-person", "pos": { "x": 306, - "y": 452 + "y": 453 }, "width": 150, "height": 180, @@ -292,11 +292,11 @@ "route": [ { "x": 180, - "y": 867 + "y": 868 }, { "x": 180, - "y": 937 + "y": 938 } ], "animated": false, @@ -331,7 +331,7 @@ "route": [ { "x": 258, - "y": 144 + "y": 143 }, { "x": 257.5830078125, @@ -343,7 +343,7 @@ }, { "x": 180, - "y": 752 + "y": 753 } ], "animated": false, @@ -378,7 +378,7 @@ "route": [ { "x": 304, - "y": 144 + "y": 143 }, { "x": 303.9159851074219, @@ -425,11 +425,11 @@ "route": [ { "x": 381, - "y": 382 + "y": 383 }, { "x": 382, - "y": 452 + "y": 453 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg index f1cdfda47..6305b8c57 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg @@ -1,27 +1,27 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with
personal bank accounts

-
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes - - - - +
C4 Style PersonStandard Personstylingc4styledCustom Size Compare shapes + + + + - - + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json index bfeabddd5..4b80ded31 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json @@ -18,8 +18,8 @@ "x": 1089, "y": 0 }, - "width": 414, - "height": 393, + "width": 415, + "height": 394, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 147, - "y": 550 + "y": 551 }, "width": 2407, "height": 915, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 177, - "y": 580 + "y": 581 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 390, - "y": 865 + "y": 866 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 1123, - "y": 865 + "y": 866 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 1246, - "y": 1166 + "y": 1167 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1890, - "y": 865 + "y": 866 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 2410, - "y": 1602 + "y": 1603 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 0, - "y": 1602 + "y": 1603 }, "width": 629, "height": 164, @@ -418,19 +418,19 @@ "route": [ { "x": 1089, - "y": 261 + "y": 262 }, { "x": 579.4000244140625, - "y": 421.3999938964844 + "y": 422.3999938964844 }, { "x": 452, - "y": 540 + "y": 541 }, { "x": 452, - "y": 580 + "y": 581 } ], "isCurve": true, @@ -466,19 +466,19 @@ "route": [ { "x": 452, - "y": 743.5 + "y": 744.5 }, { "x": 452, - "y": 792.2999877929688 + "y": 793.2999877929688 }, { "x": 472.3999938964844, - "y": 816.7000122070312 + "y": 817.7000122070312 }, { "x": 554, - "y": 865.5 + "y": 866.5 } ], "isCurve": true, @@ -514,43 +514,43 @@ "route": [ { "x": 1091, - "y": 348 + "y": 349 }, { "x": 967.7999877929688, - "y": 438.79998779296875 + "y": 439.79998779296875 }, { "x": 937, - "y": 475.20001220703125 + "y": 476.20001220703125 }, { "x": 937, - "y": 495.75 + "y": 496.75 }, { "x": 937, - "y": 516.2990112304688 + "y": 517.2990112304688 }, { "x": 937, - "y": 556.4000244140625 + "y": 557.4000244140625 }, { "x": 937, - "y": 596 + "y": 597 }, { "x": 937, - "y": 635.5999755859375 + "y": 636.5999755859375 }, { "x": 916.5999755859375, - "y": 816.7000122070312 + "y": 817.7000122070312 }, { "x": 835, - "y": 865.5 + "y": 866.5 } ], "isCurve": true, @@ -585,44 +585,44 @@ "link": "", "route": [ { - "x": 1429, - "y": 393 + "x": 1430, + "y": 394 }, { - "x": 1466.5999755859375, - "y": 447.79998779296875 + "x": 1466.800048828125, + "y": 448.79998779296875 }, { "x": 1476, - "y": 475.20001220703125 + "y": 476.20001220703125 }, { "x": 1476, - "y": 495.75 + "y": 496.75 }, { "x": 1476, - "y": 516.2990112304688 + "y": 517.2990112304688 }, { "x": 1476, - "y": 556.4000244140625 + "y": 557.4000244140625 }, { "x": 1476, - "y": 596 + "y": 597 }, { "x": 1476, - "y": 635.5999755859375 + "y": 636.5999755859375 }, { "x": 1476, - "y": 816.7000122070312 + "y": 817.7000122070312 }, { "x": 1476, - "y": 865.5 + "y": 866.5 } ], "isCurve": true, @@ -658,19 +658,19 @@ "route": [ { "x": 694.5, - "y": 1028.5 + "y": 1029.5 }, { "x": 694.5, - "y": 1083.699951171875 + "y": 1084.699951171875 }, { "x": 804.7000122070312, - "y": 1118.7220458984375 + "y": 1119.7220458984375 }, { "x": 1245.5, - "y": 1203.6099853515625 + "y": 1204.6099853515625 } ], "isCurve": true, @@ -706,19 +706,19 @@ "route": [ { "x": 1476, - "y": 1028.5 + "y": 1029.5 }, { "x": 1476, - "y": 1083.699951171875 + "y": 1084.699951171875 }, { "x": 1476, - "y": 1111.300048828125 + "y": 1112.300048828125 }, { "x": 1476, - "y": 1166.5 + "y": 1167.5 } ], "isCurve": true, @@ -754,19 +754,19 @@ "route": [ { "x": 1245.5, - "y": 1274.1949462890625 + "y": 1275.1949462890625 }, { "x": 500.6990051269531, - "y": 1426.8389892578125 + "y": 1427.8389892578125 }, { "x": 314.5, - "y": 1547.300048828125 + "y": 1548.300048828125 }, { "x": 314.5, - "y": 1602.5 + "y": 1603.5 } ], "isCurve": true, @@ -806,99 +806,99 @@ }, { "x": 2410.199951171875, - "y": 416.79998779296875 + "y": 417.6000061035156 }, { "x": 2637, - "y": 475.20001220703125 + "y": 476.20001220703125 }, { "x": 2637, - "y": 495.75 + "y": 496.75 }, { "x": 2637, - "y": 516.2990112304688 + "y": 517.2990112304688 }, { "x": 2637, - "y": 556.4000244140625 + "y": 557.4000244140625 }, { "x": 2637, - "y": 596 + "y": 597 }, { "x": 2637, - "y": 635.5999755859375 + "y": 636.5999755859375 }, { "x": 2637, - "y": 690.5 + "y": 691.5 }, { "x": 2637, - "y": 733.25 + "y": 734.25 }, { "x": 2637, - "y": 776 + "y": 777 }, { "x": 2637, - "y": 833 + "y": 834 }, { "x": 2637, - "y": 875.75 + "y": 876.75 }, { "x": 2637, - "y": 918.5 + "y": 919.5 }, { "x": 2637, - "y": 977.0999755859375 + "y": 978.0999755859375 }, { "x": 2637, - "y": 1022.25 + "y": 1023.25 }, { "x": 2637, - "y": 1067.4000244140625 + "y": 1068.4000244140625 }, { "x": 2637, - "y": 1127.5999755859375 + "y": 1128.5999755859375 }, { "x": 2637, - "y": 1172.75 + "y": 1173.75 }, { "x": 2637, - "y": 1217.9000244140625 + "y": 1218.9000244140625 }, { "x": 2637, - "y": 1291.4000244140625 + "y": 1292.4000244140625 }, { "x": 2637, - "y": 1356.5 + "y": 1357.5 }, { "x": 2637, - "y": 1421.5999755859375 + "y": 1422.5999755859375 }, { "x": 2632.800048828125, - "y": 1547.300048828125 + "y": 1548.300048828125 }, { "x": 2616, - "y": 1602.5 + "y": 1603.5 } ], "isCurve": true, @@ -934,19 +934,19 @@ "route": [ { "x": 1707.5, - "y": 1281.843994140625 + "y": 1282.843994140625 }, { "x": 2241.5, - "y": 1428.3680419921875 + "y": 1429.3680419921875 }, { "x": 2394.39990234375, - "y": 1547.300048828125 + "y": 1548.300048828125 }, { "x": 2472, - "y": 1602.5 + "y": 1603.5 } ], "isCurve": true, @@ -982,19 +982,19 @@ "route": [ { "x": 2206.5, - "y": 1028.5 + "y": 1029.5 }, { "x": 2206.5, - "y": 1083.699951171875 + "y": 1084.699951171875 }, { "x": 2106.5, - "y": 1118.0999755859375 + "y": 1119.0999755859375 }, { "x": 1706.5, - "y": 1200.5 + "y": 1201.5 } ], "isCurve": true, diff --git a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg index ba14d5df2..fb2279b45 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json index 4f90b629b..4d6d3ccd8 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json @@ -15,11 +15,11 @@ "id": "customer", "type": "c4-person", "pos": { - "x": 705, + "x": 704, "y": 12 }, - "width": 414, - "height": 393, + "width": 415, + "height": 394, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, @@ -58,7 +58,7 @@ "type": "rectangle", "pos": { "x": 12, - "y": 657 + "y": 658 }, "width": 2218, "height": 1035, @@ -100,7 +100,7 @@ "type": "rectangle", "pos": { "x": 62, - "y": 707 + "y": 708 }, "width": 550, "height": 164, @@ -142,7 +142,7 @@ "type": "rectangle", "pos": { "x": 190, - "y": 1042 + "y": 1043 }, "width": 609, "height": 164, @@ -184,7 +184,7 @@ "type": "rectangle", "pos": { "x": 819, - "y": 1042 + "y": 1043 }, "width": 707, "height": 164, @@ -226,7 +226,7 @@ "type": "rectangle", "pos": { "x": 942, - "y": 1393 + "y": 1394 }, "width": 461, "height": 164, @@ -268,7 +268,7 @@ "type": "rectangle", "pos": { "x": 1546, - "y": 1042 + "y": 1043 }, "width": 634, "height": 164, @@ -310,7 +310,7 @@ "type": "rectangle", "pos": { "x": 1746, - "y": 1894 + "y": 1895 }, "width": 360, "height": 164, @@ -352,7 +352,7 @@ "type": "rectangle", "pos": { "x": 781, - "y": 1894 + "y": 1895 }, "width": 629, "height": 164, @@ -418,19 +418,19 @@ "route": [ { "x": 788, - "y": 405 + "y": 406 }, { - "x": 788.0499877929688, - "y": 445 + "x": 787.75, + "y": 446 }, { "x": 359.25, - "y": 445 + "y": 446 }, { "x": 359.25, - "y": 707 + "y": 708 } ], "animated": false, @@ -465,11 +465,11 @@ "route": [ { "x": 393, - "y": 871 + "y": 872 }, { "x": 393, - "y": 1042 + "y": 1043 } ], "animated": false, @@ -504,19 +504,19 @@ "route": [ { "x": 871, - "y": 405 + "y": 406 }, { - "x": 870.8489990234375, - "y": 495 + "x": 870.75, + "y": 496 }, { "x": 652, - "y": 495 + "y": 496 }, { "x": 652, - "y": 1042 + "y": 1043 } ], "animated": false, @@ -551,11 +551,11 @@ "route": [ { "x": 954, - "y": 405 + "y": 406 }, { - "x": 953.6489868164062, - "y": 1042 + "x": 953.75, + "y": 1043 } ], "animated": false, @@ -590,19 +590,19 @@ "route": [ { "x": 494.5, - "y": 1206 + "y": 1207 }, { "x": 494.5, - "y": 1353 + "y": 1354 }, { "x": 1057.25, - "y": 1353 + "y": 1354 }, { "x": 1057.25, - "y": 1393 + "y": 1394 } ], "animated": false, @@ -637,11 +637,11 @@ "route": [ { "x": 1172.5, - "y": 1206 + "y": 1207 }, { "x": 1172.5, - "y": 1393 + "y": 1394 } ], "animated": false, @@ -676,11 +676,11 @@ "route": [ { "x": 1095.666015625, - "y": 1557 + "y": 1558 }, { "x": 1095.666015625, - "y": 1894 + "y": 1895 } ], "animated": false, @@ -714,28 +714,28 @@ "link": "", "route": [ { - "x": 1036, - "y": 405 + "x": 1037, + "y": 406 }, { - "x": 1036.448974609375, - "y": 445 + "x": 1036.75, + "y": 446 }, { "x": 2303.5, - "y": 445 + "y": 446 }, { "x": 2303.5, - "y": 1854 + "y": 1855 }, { "x": 1986.8330078125, - "y": 1854 + "y": 1855 }, { "x": 1986.8330078125, - "y": 1894 + "y": 1895 } ], "animated": false, @@ -770,19 +770,19 @@ "route": [ { "x": 1249.3330078125, - "y": 1557 + "y": 1558 }, { "x": 1249.3330078125, - "y": 1854 + "y": 1855 }, { "x": 1866.8330078125, - "y": 1854 + "y": 1855 }, { "x": 1866.8330078125, - "y": 1894 + "y": 1895 } ], "animated": false, @@ -817,19 +817,19 @@ "route": [ { "x": 1863, - "y": 1206 + "y": 1207 }, { "x": 1863, - "y": 1353 + "y": 1354 }, { "x": 1287.75, - "y": 1353 + "y": 1354 }, { "x": 1287.75, - "y": 1393 + "y": 1394 } ], "animated": false, diff --git a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg index 19d96dd6b..46f088711 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] - - - - - - - - - - - - - - - - - - - - +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg index eab5e1bdf..a743498d0 100644 --- a/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/dagre/sketch.exp.svg @@ -89,7 +89,7 @@ .d2-1864249435 .color-AA4{color:#EDF0FD;} .d2-1864249435 .color-AA5{color:#F7F8FE;} .d2-1864249435 .color-AB4{color:#EDF0FD;} - .d2-1864249435 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-1864249435);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1864249435);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1864249435);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1864249435);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + .d2-1864249435 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-1864249435);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1864249435);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1864249435);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1864249435);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1864249435);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1864249435);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person - + \ No newline at end of file diff --git a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg index 8d06fbfb8..fa51d71b6 100644 --- a/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/small-c4-person/elk/sketch.exp.svg @@ -89,7 +89,7 @@ .d2-1736778707 .color-AA4{color:#EDF0FD;} .d2-1736778707 .color-AA5{color:#F7F8FE;} .d2-1736778707 .color-AB4{color:#EDF0FD;} - .d2-1736778707 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-1736778707);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1736778707);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1736778707);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1736778707);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person + .d2-1736778707 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark-d2-1736778707);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker-d2-1736778707);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark-d2-1736778707);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal-d2-1736778707);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal-d2-1736778707);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright-d2-1736778707);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]>c4-person - + \ No newline at end of file diff --git a/lib/shape/shape_c4_person.go b/lib/shape/shape_c4_person.go index b2a571d2b..e08dc2810 100644 --- a/lib/shape/shape_c4_person.go +++ b/lib/shape/shape_c4_person.go @@ -38,21 +38,21 @@ func (s shapeC4Person) GetInnerBox() *geo.Box { width := s.Box.Width height := s.Box.Height - headRadius := math.Round(width * HEAD_RADIUS_FACTOR) + headRadius := width * HEAD_RADIUS_FACTOR headCenterY := headRadius - bodyTop := math.Round(headCenterY + headRadius*BODY_TOP_FACTOR) + bodyTop := headCenterY + headRadius*BODY_TOP_FACTOR // Horizontal padding = 5% of width - horizontalPadding := math.Round(width * 0.05) + horizontalPadding := width * 0.05 // Vertical padding = 3% of height - verticalPadding := math.Round(height * 0.03) + verticalPadding := height * 0.03 tl := s.Box.TopLeft.Copy() tl.X += horizontalPadding tl.Y += bodyTop + verticalPadding - innerWidth := math.Round(width - (horizontalPadding * 2)) - innerHeight := math.Round(height - bodyTop - (verticalPadding * 2)) + innerWidth := width - (horizontalPadding * 2) + innerHeight := height - bodyTop - (verticalPadding * 2) return geo.NewBox(tl, innerWidth, innerHeight) } @@ -63,14 +63,15 @@ func bodyPath(box *geo.Box) *svg.SvgPathContext { pc := svg.NewSVGPathContext(box.TopLeft, 1, 1) - headRadius := math.Round(width * HEAD_RADIUS_FACTOR) + headRadius := width * HEAD_RADIUS_FACTOR headCenterY := headRadius - bodyTop := math.Round(headCenterY + headRadius*BODY_TOP_FACTOR) + bodyTop := headCenterY + headRadius*BODY_TOP_FACTOR bodyWidth := width - bodyHeight := math.Round(height - bodyTop) + bodyHeight := height - bodyTop bodyLeft := 0 - cornerRadius := math.Round(math.Min(width*CORNER_RADIUS_FACTOR, bodyHeight*0.25)) + // Use the same corner radius calculation as frontend + cornerRadius := math.Min(width*CORNER_RADIUS_FACTOR, bodyHeight*0.25) pc.StartAt(pc.Absolute(float64(bodyLeft), bodyTop+cornerRadius)) @@ -91,8 +92,8 @@ func headPath(box *geo.Box) *svg.SvgPathContext { pc := svg.NewSVGPathContext(box.TopLeft, 1, 1) - headRadius := math.Round(width * HEAD_RADIUS_FACTOR) - headCenterX := math.Round(width / 2) + headRadius := width * HEAD_RADIUS_FACTOR + headCenterX := width / 2 headCenterY := headRadius pc.StartAt(pc.Absolute(headCenterX, headCenterY-headRadius)) @@ -125,8 +126,8 @@ func (s shapeC4Person) Perimeter() []geo.Intersectable { bodyPerimeter := bodyPath(s.Box).Path - headRadius := math.Round(width * HEAD_RADIUS_FACTOR) - headCenterX := s.Box.TopLeft.X + math.Round(width/2) + headRadius := width * HEAD_RADIUS_FACTOR + headCenterX := s.Box.TopLeft.X + width/2 headCenterY := s.Box.TopLeft.Y + headRadius headCenter := geo.NewPoint(headCenterX, headCenterY) @@ -147,19 +148,19 @@ func (s shapeC4Person) GetDimensionsToFit(width, height, paddingX, paddingY floa contentHeight := height + paddingY // Account for 10% total horizontal padding (5% on each side) - totalWidth := math.Round(contentWidth / 0.9) - headRadius := math.Round(totalWidth * HEAD_RADIUS_FACTOR) + totalWidth := contentWidth / 0.9 + headRadius := totalWidth * HEAD_RADIUS_FACTOR // Use positioning matching frontend headCenterY := headRadius - bodyTop := math.Round(headCenterY + headRadius*BODY_TOP_FACTOR) + bodyTop := headCenterY + headRadius*BODY_TOP_FACTOR // Include vertical padding - verticalPadding := math.Round(totalWidth * 0.06) // 3% top + 3% bottom - totalHeight := math.Round(contentHeight + bodyTop + verticalPadding) + verticalPadding := totalWidth * 0.06 // 3% top + 3% bottom + totalHeight := contentHeight + bodyTop + verticalPadding // Calculate minimum height - minHeight := math.Round(totalWidth * 0.95) + minHeight := totalWidth * 0.95 if totalHeight < minHeight { totalHeight = minHeight } From 048344218253a97afb5496c9ce16e1e4610be9c0 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 13 Mar 2025 20:14:40 -0600 Subject: [PATCH 27/54] calc --- lib/shape/shape_c4_person.go | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/lib/shape/shape_c4_person.go b/lib/shape/shape_c4_person.go index e08dc2810..9424347a1 100644 --- a/lib/shape/shape_c4_person.go +++ b/lib/shape/shape_c4_person.go @@ -8,9 +8,6 @@ import ( "oss.terrastruct.com/util-go/go2" ) -// Optimal value for circular arc approximation with cubic bezier curves -const kCircleApprox = 0.5522847498307936 // 4*(math.Sqrt(2)-1)/3 - // Constants to match frontend implementation const ( C4_PERSON_AR_LIMIT = 1.5 @@ -75,13 +72,13 @@ func bodyPath(box *geo.Box) *svg.SvgPathContext { pc.StartAt(pc.Absolute(float64(bodyLeft), bodyTop+cornerRadius)) - pc.C(true, 0, -kCircleApprox*cornerRadius, kCircleApprox*cornerRadius, -cornerRadius, cornerRadius, -cornerRadius) + pc.C(true, 0, -4*(math.Sqrt(2)-1)/3*cornerRadius, 4*(math.Sqrt(2)-1)/3*cornerRadius, -cornerRadius, cornerRadius, -cornerRadius) pc.H(true, bodyWidth-2*cornerRadius) - pc.C(true, kCircleApprox*cornerRadius, 0, cornerRadius, kCircleApprox*cornerRadius, cornerRadius, cornerRadius) + pc.C(true, 4*(math.Sqrt(2)-1)/3*cornerRadius, 0, cornerRadius, 4*(math.Sqrt(2)-1)/3*cornerRadius, cornerRadius, cornerRadius) pc.V(true, bodyHeight-2*cornerRadius) - pc.C(true, 0, kCircleApprox*cornerRadius, -kCircleApprox*cornerRadius, cornerRadius, -cornerRadius, cornerRadius) + pc.C(true, 0, 4*(math.Sqrt(2)-1)/3*cornerRadius, -4*(math.Sqrt(2)-1)/3*cornerRadius, cornerRadius, -cornerRadius, cornerRadius) pc.H(true, -(bodyWidth - 2*cornerRadius)) - pc.C(true, -kCircleApprox*cornerRadius, 0, -cornerRadius, -kCircleApprox*cornerRadius, -cornerRadius, -cornerRadius) + pc.C(true, -4*(math.Sqrt(2)-1)/3*cornerRadius, 0, -cornerRadius, -4*(math.Sqrt(2)-1)/3*cornerRadius, -cornerRadius, -cornerRadius) pc.Z() return pc @@ -99,23 +96,23 @@ func headPath(box *geo.Box) *svg.SvgPathContext { pc.StartAt(pc.Absolute(headCenterX, headCenterY-headRadius)) pc.C(false, - headCenterX+headRadius*kCircleApprox, headCenterY-headRadius, - headCenterX+headRadius, headCenterY-headRadius*kCircleApprox, + headCenterX+headRadius*4*(math.Sqrt(2)-1)/3, headCenterY-headRadius, + headCenterX+headRadius, headCenterY-headRadius*4*(math.Sqrt(2)-1)/3, headCenterX+headRadius, headCenterY) pc.C(false, - headCenterX+headRadius, headCenterY+headRadius*kCircleApprox, - headCenterX+headRadius*kCircleApprox, headCenterY+headRadius, + headCenterX+headRadius, headCenterY+headRadius*4*(math.Sqrt(2)-1)/3, + headCenterX+headRadius*4*(math.Sqrt(2)-1)/3, headCenterY+headRadius, headCenterX, headCenterY+headRadius) pc.C(false, - headCenterX-headRadius*kCircleApprox, headCenterY+headRadius, - headCenterX-headRadius, headCenterY+headRadius*kCircleApprox, + headCenterX-headRadius*4*(math.Sqrt(2)-1)/3, headCenterY+headRadius, + headCenterX-headRadius, headCenterY+headRadius*4*(math.Sqrt(2)-1)/3, headCenterX-headRadius, headCenterY) pc.C(false, - headCenterX-headRadius, headCenterY-headRadius*kCircleApprox, - headCenterX-headRadius*kCircleApprox, headCenterY-headRadius, + headCenterX-headRadius, headCenterY-headRadius*4*(math.Sqrt(2)-1)/3, + headCenterX-headRadius*4*(math.Sqrt(2)-1)/3, headCenterY-headRadius, headCenterX, headCenterY-headRadius) return pc From 7312799fb650f4dce785f76623e663db751649da Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 13 Mar 2025 20:20:16 -0600 Subject: [PATCH 28/54] remove tests --- e2etests/txtar.txt | 103 --------------------------------------------- 1 file changed, 103 deletions(-) diff --git a/e2etests/txtar.txt b/e2etests/txtar.txt index 62d82d7ef..ac940b683 100644 --- a/e2etests/txtar.txt +++ b/e2etests/txtar.txt @@ -1027,106 +1027,6 @@ c4person -> styling.c4styled -> styling.c4sized style.stroke-width: 1 } --- c4-theme -- - -vars: { - d2-config: { - theme-id: 303 - } -} - -customer: |md - ## Personal Banking Customer - [person] - - A customer of the bank, with personal bank accounts. -| { - shape: c4-person -} - -internet_banking_system: |md - ## Internet Banking System - [Software System] -| { - shape: rectangle - label.near: bottom-left -} - -internet_banking_system.web_app: |md - ## Web Application - [Container: Java and Spring MVC] - - Delivers the static content and the Internet banking single page application. -| { - shape: rectangle -} - -internet_banking_system.spa: |md - ## Single-Page Application - [Container: JavaScript and Angular] - - Provides all of the Internet banking functionality to customers via their web browser. -| { - shape: rectangle -} - -internet_banking_system.mobile_app: |md - ## Mobile App - [Container: Xamarin] - - Provides a limited subset of the Internet banking functionality to customers via their mobile device. -| { - shape: rectangle -} - -internet_banking_system.api_app: |md - ## API Application - [Container: Java and Spring MVC] - - Provides Internet banking functionality via a JSON/HTTPS API. -| { - shape: rectangle -} - -internet_banking_system.database: |md - ## Database - [Container: Oracle Database Schema] - - Stores user registration information, hashed authentication credentials, access logs, etc. -| { - shape: rectangle -} - -email_system: |md - ## E-mail System - [Software System] - - The internal Microsoft Exchange e-mail system. -| { - shape: rectangle -} - -mainframe: |md - ## Mainframe Banking System - [Software System] - - Stores all of the core banking information about customers, accounts, transactions, etc. -| { - shape: rectangle -} - -# Connections -customer -> internet_banking_system.web_app: "Visits bigbank.com/ib using\n[HTTPS]" -internet_banking_system.web_app -> internet_banking_system.spa: "Delivers to the customer's web browser" -customer -> internet_banking_system.spa: "Views account balances, and makes payments using" -customer -> internet_banking_system.mobile_app: "Views account balances, and makes payments using" -internet_banking_system.spa -> internet_banking_system.api_app: "Makes API calls to\n[JSON/HTTPS]" -internet_banking_system.mobile_app -> internet_banking_system.api_app: "Makes API calls to\n[JSON/HTTPS]" -internet_banking_system.api_app -> mainframe: "Makes API calls to\n[XML/HTTPS]" -customer -> email_system: "Sends e-mails to" -internet_banking_system.api_app -> email_system: "Sends e-mail using" -internet_banking_system.database <-> internet_banking_system.api_app: "Reads from and writes to\n[SQL/TCP]" - -- legend -- vars: { d2-legend: { @@ -1261,6 +1161,3 @@ customer4: |md | { shape: c4-person } - -customer1 -> customer2 -> customer3 -> customer4 -customer4 -> customer1 -> customer3 -> customer2 From dff430e006c409c8997241bdbde3fee742c1b580 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 13 Mar 2025 20:21:25 -0600 Subject: [PATCH 29/54] ta --- .../c4-person-label/dagre/board.exp.json | 359 +---------- .../c4-person-label/dagre/sketch.exp.svg | 578 +++++++++--------- .../txtar/c4-person-label/elk/board.exp.json | 263 +------- .../txtar/c4-person-label/elk/sketch.exp.svg | 578 +++++++++--------- 4 files changed, 603 insertions(+), 1175 deletions(-) diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json index def972f1f..2c7e30d13 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-label/dagre/board.exp.json @@ -16,7 +16,7 @@ "type": "c4-person", "pos": { "x": 0, - "y": 18 + "y": 32 }, "width": 410, "height": 390, @@ -58,7 +58,7 @@ "type": "c4-person", "pos": { "x": 470, - "y": 18 + "y": 32 }, "width": 410, "height": 390, @@ -100,7 +100,7 @@ "type": "c4-person", "pos": { "x": 940, - "y": 18 + "y": 32 }, "width": 410, "height": 390, @@ -142,7 +142,7 @@ "type": "c4-person", "pos": { "x": 1410, - "y": 0 + "y": 14 }, "width": 448, "height": 426, @@ -183,8 +183,8 @@ "id": "customer2", "type": "c4-person", "pos": { - "x": 1137, - "y": 526 + "x": 1918, + "y": 0 }, "width": 457, "height": 453, @@ -225,8 +225,8 @@ "id": "customer3", "type": "c4-person", "pos": { - "x": 1147, - "y": 1079 + "x": 2435, + "y": 10 }, "width": 457, "height": 434, @@ -267,8 +267,8 @@ "id": "customer4", "type": "c4-person", "pos": { - "x": 1426, - "y": 1613 + "x": 2952, + "y": 10 }, "width": 457, "height": 434, @@ -306,344 +306,7 @@ "level": 1 } ], - "connections": [ - { - "id": "(customer1 -> customer2)[0]", - "src": "customer1", - "srcArrow": "none", - "dst": "customer2", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1433, - "y": 410 - }, - { - "x": 1379, - "y": 462.79998779296875 - }, - { - "x": 1365.5999755859375, - "y": 486 - }, - { - "x": 1366, - "y": 526 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer2 -> customer3)[0]", - "src": "customer2", - "srcArrow": "none", - "dst": "customer3", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1358, - "y": 979 - }, - { - "x": 1356, - "y": 1019 - }, - { - "x": 1356.4000244140625, - "y": 1039.199951171875 - }, - { - "x": 1360, - "y": 1080 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer3 -> customer4)[0]", - "src": "customer3", - "srcArrow": "none", - "dst": "customer4", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1375, - "y": 1513 - }, - { - "x": 1375.4000244140625, - "y": 1553 - }, - { - "x": 1411.800048828125, - "y": 1597.800048828125 - }, - { - "x": 1557, - "y": 1737 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer4 -> customer1)[0]", - "src": "customer4", - "srcArrow": "none", - "dst": "customer1", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1654, - "y": 1613 - }, - { - "x": 1654, - "y": 1573 - }, - { - "x": 1654, - "y": 1509.5999755859375 - }, - { - "x": 1654, - "y": 1429.5 - }, - { - "x": 1654, - "y": 1349.4000244140625 - }, - { - "x": 1654, - "y": 1242.5999755859375 - }, - { - "x": 1654, - "y": 1162.5 - }, - { - "x": 1654, - "y": 1082.4000244140625 - }, - { - "x": 1654, - "y": 973.7000122070312 - }, - { - "x": 1654, - "y": 890.75 - }, - { - "x": 1654, - "y": 807.7999877929688 - }, - { - "x": 1653.199951171875, - "y": 466 - }, - { - "x": 1650, - "y": 426 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer1 -> customer3)[0]", - "src": "customer1", - "srcArrow": "none", - "dst": "customer3", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1634, - "y": 426 - }, - { - "x": 1634, - "y": 466 - }, - { - "x": 1634, - "y": 531.2999877929688 - }, - { - "x": 1634, - "y": 614.25 - }, - { - "x": 1634, - "y": 697.2000122070312 - }, - { - "x": 1602.199951171875, - "y": 1062.199951171875 - }, - { - "x": 1475, - "y": 1195 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer3 -> customer2)[0]", - "src": "customer3", - "srcArrow": "none", - "dst": "customer2", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1453, - "y": 1116 - }, - { - "x": 1482.4000244140625, - "y": 1046.4000244140625 - }, - { - "x": 1485.4000244140625, - "y": 1019 - }, - { - "x": 1468, - "y": 979 - } - ], - "isCurve": true, - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - } - ], + "connections": [], "root": { "id": "", "type": "", diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg index 25c78740e..24701726f 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg @@ -1,13 +1,13 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank ccountskks.

-

Personal Banking Customerk

+

Personal Banking Customerk

[person]

A customer of the bank, with pekkrsonal bank accountskks.

A customer of the bank, with pekkrsonal bank accountskks.

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank accountskks.

-
- - - - - - - - +
+ + + + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json index e46b21769..ecf5fb0fd 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-person-label/elk/board.exp.json @@ -16,7 +16,7 @@ "type": "c4-person", "pos": { "x": 12, - "y": 30 + "y": 43 }, "width": 410, "height": 390, @@ -57,8 +57,8 @@ "id": "c4mdperson2", "type": "c4-person", "pos": { - "x": 441, - "y": 30 + "x": 442, + "y": 43 }, "width": 410, "height": 390, @@ -99,8 +99,8 @@ "id": "c4mdperson3", "type": "c4-person", "pos": { - "x": 871, - "y": 30 + "x": 872, + "y": 43 }, "width": 410, "height": 390, @@ -141,8 +141,8 @@ "id": "customer1", "type": "c4-person", "pos": { - "x": 1301, - "y": 12 + "x": 1302, + "y": 25 }, "width": 448, "height": 426, @@ -183,8 +183,8 @@ "id": "customer2", "type": "c4-person", "pos": { - "x": 1028, - "y": 518 + "x": 1770, + "y": 12 }, "width": 457, "height": 453, @@ -225,8 +225,8 @@ "id": "customer3", "type": "c4-person", "pos": { - "x": 1123, - "y": 1051 + "x": 2247, + "y": 21 }, "width": 457, "height": 434, @@ -267,8 +267,8 @@ "id": "customer4", "type": "c4-person", "pos": { - "x": 1313, - "y": 1565 + "x": 2724, + "y": 21 }, "width": 457, "height": 434, @@ -306,242 +306,7 @@ "level": 1 } ], - "connections": [ - { - "id": "(customer1 -> customer2)[0]", - "src": "customer1", - "srcArrow": "none", - "dst": "customer2", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1414, - "y": 438 - }, - { - "x": 1414, - "y": 699 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer2 -> customer3)[0]", - "src": "customer2", - "srcArrow": "none", - "dst": "customer3", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1237, - "y": 971 - }, - { - "x": 1237, - "y": 1232 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer3 -> customer4)[0]", - "src": "customer3", - "srcArrow": "none", - "dst": "customer4", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1466, - "y": 1485 - }, - { - "x": 1466, - "y": 1600 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer4 -> customer1)[0]", - "src": "customer4", - "srcArrow": "none", - "dst": "customer1", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1620, - "y": 1603 - }, - { - "x": 1620, - "y": 438 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer1 -> customer3)[0]", - "src": "customer1", - "srcArrow": "none", - "dst": "customer3", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1526, - "y": 438 - }, - { - "x": 1526, - "y": 1233 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - }, - { - "id": "(customer3 -> customer2)[0]", - "src": "customer3", - "srcArrow": "none", - "dst": "customer2", - "dstArrow": "triangle", - "opacity": 1, - "strokeDash": 0, - "strokeWidth": 2, - "stroke": "B1", - "borderRadius": 10, - "label": "", - "fontSize": 16, - "fontFamily": "DEFAULT", - "language": "", - "color": "N2", - "italic": true, - "bold": false, - "underline": false, - "labelWidth": 0, - "labelHeight": 0, - "labelPosition": "", - "labelPercentage": 0, - "link": "", - "route": [ - { - "x": 1334, - "y": 1053 - }, - { - "x": 1334, - "y": 971 - } - ], - "animated": false, - "tooltip": "", - "icon": null, - "zIndex": 0 - } - ], + "connections": [], "root": { "id": "", "type": "", diff --git a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg index 5a6e872f4..01c202e6c 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg @@ -1,13 +1,13 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank ccountskks.

-

Personal Banking Customerk

+

Personal Banking Customerk

[person]

A customer of the bank, with pekkrsonal bank accountskks.

A customer of the bank, with pekkrsonal bank accountskks.

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank accountskks.

-

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with pekkrsonal bank accountskks.

-
- - - - - - - - +
+ + + + + + + +
\ No newline at end of file From f277522b2aade38fe65262cf3d5e05e62ccf0ba4 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 14 Mar 2025 19:58:37 -0600 Subject: [PATCH 30/54] add test --- d2compiler/compile_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index c3ce5c5e7..47183fe9c 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -3125,6 +3125,24 @@ x*: { tassert.Equal(t, "x2.ok", g.Objects[3].AbsID()) }, }, + { + name: "import-var-chain", + + text: `...@dev +`, + files: map[string]string{ + "dev.d2": ` +vars: { + a: { + b + } + c: { + ...${a} + } +} +`, + }, + }, { name: "var_in_markdown", text: `vars: { From cc1e647dfc8ddcf3ac2af251e283c4626d834845 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 14 Mar 2025 21:17:41 -0600 Subject: [PATCH 31/54] fix var panic --- d2ir/compile.go | 4 ++ .../TestCompile/import-var-chain.exp.json | 57 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 testdata/d2compiler/TestCompile/import-var-chain.exp.json diff --git a/d2ir/compile.go b/d2ir/compile.go index 9473b7e37..a239862a8 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -1134,6 +1134,10 @@ func (c *compiler) extendLinks(m *Map, importF *Field, importDir string) { nodeBoardKind := NodeBoardKind(m) importIDA := IDA(importF) for _, f := range m.Fields { + // A substitute or such + if f.Name == nil { + continue + } if f.Name.ScalarString() == "link" && f.Name.IsUnquoted() { if nodeBoardKind != "" { c.errorf(f.LastRef().AST(), "a board itself cannot be linked; only objects within a board can be linked") diff --git a/testdata/d2compiler/TestCompile/import-var-chain.exp.json b/testdata/d2compiler/TestCompile/import-var-chain.exp.json new file mode 100644 index 000000000..8868dcdb7 --- /dev/null +++ b/testdata/d2compiler/TestCompile/import-var-chain.exp.json @@ -0,0 +1,57 @@ +{ + "graph": { + "name": "", + "isFolderOnly": true, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/import-var-chain.d2,0:0:0-1:0:8", + "nodes": [ + { + "import": { + "range": "d2/testdata/d2compiler/TestCompile/import-var-chain.d2,0:0:0-0:7:7", + "spread": true, + "pre": "", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/import-var-chain.d2,0:4:4-0:7:7", + "value": [ + { + "string": "dev", + "raw_string": "dev" + } + ] + } + } + ] + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": null + }, + "err": null +} From 4bce55eb493f7dd4ae62329a8d030ab0852cd68d Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 14 Mar 2025 21:18:45 -0600 Subject: [PATCH 32/54] next --- ci/release/changelogs/next.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index ab55c0441..0aec8da04 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -32,6 +32,7 @@ - Compiler: - fixes panic when `sql_shape` shape value had mixed casing [#2349](https://github.com/terrastruct/d2/pull/2349) + - fixes panic when importing from a file with spread substitutions in `vars` [#2427](https://github.com/terrastruct/d2/pull/2427) - fixes support for `center` in `d2-config` [#2360](https://github.com/terrastruct/d2/pull/2360) - fixes panic when comment lines appear in arrays [#2378](https://github.com/terrastruct/d2/pull/2378) - fixes inconsistencies when objects were double quoted [#2390](https://github.com/terrastruct/d2/pull/2390) From 1e89c55232883c32e80deddc9a98650aadfa427a Mon Sep 17 00:00:00 2001 From: stereobooster Date: Sun, 16 Mar 2025 16:10:41 +0100 Subject: [PATCH 33/54] More types --- d2js/js/index.d.ts | 405 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 341 insertions(+), 64 deletions(-) diff --git a/d2js/js/index.d.ts b/d2js/js/index.d.ts index 42bbff56d..9b2977a44 100644 --- a/d2js/js/index.d.ts +++ b/d2js/js/index.d.ts @@ -1,66 +1,343 @@ -declare module "@terrastruct/d2" { - interface RenderOptions { - /** Enable sketch mode [default: false] */ - sketch?: boolean; - /** Theme ID to use [default: 0] */ - themeID?: number; - /** Theme ID to use when client is in dark mode */ - darkThemeID?: number; - /** Center the SVG in the containing viewbox [default: false] */ - center?: boolean; - /** Pixels padded around the rendered diagram [default: 100] */ - pad?: number; - /** 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. */ - scale?: number; - /** Adds an appendix for tooltips and links [default: false] */ - forceAppendix?: boolean; - /** 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. E.g. target: 'layers.x.*' to render layer 'x' with all of its children. Pass '' to render all scenarios, steps, and layers. By default, only the root board is rendered. Multi-board outputs are currently only supported for animated SVGs and so animateInterval must be set to a value greater than 0 when targeting multiple boards. */ - target?: string; - /** If given, multiple boards are packaged as 1 SVG which transitions through each board at the interval (in milliseconds). */ - animateInterval?: number; - /** 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. */ - salt?: string; - /** Omit XML tag () from output SVG files. Useful when generating SVGs for direct HTML embedding. */ - noXMLTag?: boolean; - } +export class D2 { + compile(input: string, options?: Omit): Promise; + compile(input: CompileRequest): Promise; - interface CompileOptions extends RenderOptions { - /** Layout engine to use [default: 'dagre'] */ - layout?: 'dagre' | 'elk'; - /** A byte array containing .ttf file to use for the regular font. If none provided, Source Sans Pro Regular is used. */ - fontRegular?: Uint8Array; - /** A byte array containing .ttf file to use for the italic font. If none provided, Source Sans Pro Italic is used. */ - fontItalic?: Uint8Array; - /** A byte array containing .ttf file to use for the bold font. If none provided, Source Sans Pro Bold is used. */ - fontBold?: Uint8Array; - /** A byte array containing .ttf file to use for the semibold font. If none provided, Source Sans Pro Semibold is used. */ - fontSemibold?: Uint8Array; - } - - interface CompileRequest { - /** A mapping of D2 file paths to their content*/ - fs: Record; - /** The path of the entry D2 file [default: index]*/ - inputPath: string; - /** The CompileOptions to pass to the compiler*/ - options: CompileOptions; - } - - interface Diagram { - config: RenderOptions; - } - - interface CompileResult { - /** Compiled D2 diagram*/ - diagram: Diagram; - /** RenderOptions: Render options merged with configuration set in diagram*/ - renderOptions: RenderOptions; - fs: Record; - graph: unknown; - } - - class D2 { - compile(input: string | CompileRequest, options?: CompileOptions): Promise; - render(diagram: Diagram, options?: RenderOptions): Promise; - } + render(diagram: Diagram, options?: RenderOptions): Promise; +} + +export interface RenderOptions { + /** Enable sketch mode [default: false] */ + sketch?: boolean; + /** Theme ID to use [default: 0] */ + themeID?: number; + /** Theme ID to use when client is in dark mode */ + darkThemeID?: number; + /** Center the SVG in the containing viewbox [default: false] */ + center?: boolean; + /** Pixels padded around the rendered diagram [default: 100] */ + pad?: number; + /** 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. */ + scale?: number; + /** Adds an appendix for tooltips and links [default: false] */ + forceAppendix?: boolean; + /** 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. E.g. target: 'layers.x.*' to render layer 'x' with all of its children. Pass '' to render all scenarios, steps, and layers. By default, only the root board is rendered. Multi-board outputs are currently only supported for animated SVGs and so animateInterval must be set to a value greater than 0 when targeting multiple boards. */ + target?: string; + /** If given, multiple boards are packaged as 1 SVG which transitions through each board at the interval (in milliseconds). */ + animateInterval?: number; + /** 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. */ + salt?: string; + /** Omit XML tag () from output SVG files. Useful when generating SVGs for direct HTML embedding. */ + noXMLTag?: boolean; +} + +export interface CompileOptions extends RenderOptions { + /** Layout engine to use [default: 'dagre'] */ + layout?: "dagre" | "elk"; + /** A byte array containing .ttf file to use for the regular font. If none provided, Source Sans Pro Regular is used. */ + fontRegular?: Uint8Array; + /** A byte array containing .ttf file to use for the italic font. If none provided, Source Sans Pro Italic is used. */ + fontItalic?: Uint8Array; + /** A byte array containing .ttf file to use for the bold font. If none provided, Source Sans Pro Bold is used. */ + fontBold?: Uint8Array; + /** A byte array containing .ttf file to use for the semibold font. If none provided, Source Sans Pro Semibold is used. */ + fontSemibold?: Uint8Array; +} + +export interface CompileRequest { + /** A mapping of D2 file paths to their content*/ + fs: Record; + /** The path of the entry D2 file [default: index]*/ + inputPath: string; + /** The CompileOptions to pass to the compiler*/ + options: CompileOptions; +} + +export interface CompileResponse { + /** Compiled D2 diagram*/ + diagram: Diagram /* d2target.Diagram */; + /** RenderOptions: Render options merged with configuration set in diagram*/ + renderOptions: RenderOptions; + fs: Record; + graph: Graph; + inputPath: string; +} + +export interface Diagram { + config?: RenderOptions; + name: string; + /** + * See docs on the same field in d2graph to understand what it means. + */ + isFolderOnly: boolean; + description?: string; + fontFamily?: any /* d2fonts.FontFamily */; + shapes: Shape[]; + connections: Connection[]; + root: Shape; + legend?: Legend; + layers?: (Diagram | undefined)[]; + scenarios?: (Diagram | undefined)[]; + steps?: (Diagram | undefined)[]; +} + +export interface Legend { + shapes?: Shape[]; + connections?: Connection[]; +} + +export type Shape = (Class | SQLTable | Text) & ShapeBase; + +export interface ShapeBase { + id: string; + type: string; + classes?: string[]; + pos: Point; + width: number /* int */; + height: number /* int */; + opacity: number /* float64 */; + strokeDash: number /* float64 */; + strokeWidth: number /* int */; + borderRadius: number /* int */; + fill: string; + fillPattern?: string; + stroke: string; + animated: boolean; + shadow: boolean; + "3d": boolean; + multiple: boolean; + "double-border": boolean; + tooltip: string; + link: string; + prettyLink?: string; + icon?: string /* url.URL */; + iconPosition: string; + /** + * Whether the shape should allow shapes behind it to bleed through + * Currently just used for sequence diagram groups + */ + blend: boolean; + contentAspectRatio?: number /* float64 */; + labelPosition?: string; + zIndex: number /* int */; + level: number /* int */; + /** + * These are used for special shapes, sql_table and class + */ + primaryAccentColor?: string; + secondaryAccentColor?: string; + neutralAccentColor?: string; +} + +export interface Point { + x: number /* int */; + y: number /* int */; +} + +export interface Class { + fields: ClassField[]; + methods: ClassMethod[]; +} + +export interface ClassField { + name: string; + type: string; + visibility: string; +} + +export interface ClassMethod { + name: string; + return: string; + visibility: string; +} + +export interface SQLTable { + columns: SQLColumn[]; +} + +export interface SQLColumn { + name: Text; + type: Text; + constraint: string[]; + reference: string; +} + +export interface Text { + label: string; + fontSize: number /* int */; + fontFamily: string; + language: string; + color: string; + italic: boolean; + bold: boolean; + underline: boolean; + labelWidth: number /* int */; + labelHeight: number /* int */; + labelFill?: string; +} + +export interface Connection extends Text { + id: string; + classes?: string[]; + src: string; + srcArrow: Arrowhead; + srcLabel?: Text; + dst: string; + dstArrow: Arrowhead; + dstLabel?: Text; + opacity: number /* float64 */; + strokeDash: number /* float64 */; + strokeWidth: number /* int */; + stroke: string; + fill?: string; + borderRadius?: number /* float64 */; + labelPosition: string; + labelPercentage: number /* float64 */; + link: string; + prettyLink?: string; + route: (any /* geo.Point */ | undefined)[]; + isCurve?: boolean; + animated: boolean; + tooltip: string; + icon?: string /* url.URL */; + iconPosition?: string; + zIndex: number /* int */; +} + +export type Arrowhead = + | "none" + | "arrow" + | "unfilled-triangle" + | "triangle" + | "diamond" + | "filled-diamond" + | "circle" + | "filled-circle" + | "box" + | "filled-box" + | "line" + | "cf-one" + | "cf-many" + | "cf-one-required" + | "cf-many-required"; + +export interface Graph { + name: string; + /** + * IsFolderOnly indicates a board or scenario itself makes no modifications from its + * base. Folder only boards do not have a render and are used purely for organizing + * the board tree. + */ + isFolderOnly: boolean; + ast?: any /* d2ast.Map */; + root?: Object; + legend?: Legend; + edges: (Edge | undefined)[]; + objects: (Object | undefined)[]; + layers?: (Graph | undefined)[]; + scenarios?: (Graph | undefined)[]; + steps?: (Graph | undefined)[]; + theme?: any /* d2themes.Theme */; + /** + * Object.Level uses the location of a nested graph + */ + rootLevel?: number /* int */; + /** + * Currently this holds data embedded from source code configuration variables + * Plugins only have access to exported graph, so this data structure allows + * carrying arbitrary metadata that any plugin might handle + */ + data?: { [key: string]: any }; +} + +export interface Edge { + index: number /* int */; + srcTableColumnIndex?: number /* int */; + dstTableColumnIndex?: number /* int */; + labelPosition?: string; + labelPercentage?: number /* float64 */; + isCurve: boolean; + route?: (any /* geo.Point */ | undefined)[]; + src_arrow: boolean; + srcArrowhead?: Attributes; + /** + * TODO alixander (Mon Sep 12 2022): deprecate SrcArrow and DstArrow and just use SrcArrowhead and DstArrowhead + */ + dst_arrow: boolean; + dstArrowhead?: Attributes; + references?: EdgeReference[]; + attributes?: Attributes; + zIndex: number /* int */; +} + +export interface Attributes { + label: Scalar; + labelDimensions: TextDimensions; + style: Style; + icon?: string /* url.URL */; + tooltip?: Scalar; + link?: Scalar; + width?: Scalar; + height?: Scalar; + top?: Scalar; + left?: Scalar; + /** + * TODO consider separate Attributes struct for shape-specific and edge-specific + * Shapes only + */ + near_key?: any /* d2ast.KeyPath */; + language?: string; + /** + * TODO: default to ShapeRectangle instead of empty string + */ + shape: Scalar; + direction: Scalar; + constraint: string[]; + gridRows?: Scalar; + gridColumns?: Scalar; + gridGap?: Scalar; + verticalGap?: Scalar; + horizontalGap?: Scalar; + labelPosition?: Scalar; + iconPosition?: Scalar; + /** + * These names are attached to the rendered elements in SVG + * so that users can target them however they like outside of D2 + */ + classes?: string[]; +} + +export interface EdgeReference { + map_key_edge_index: number /* int */; +} + +export interface Scalar { + value: string; +} + +export interface Style { + opacity?: Scalar; + stroke?: Scalar; + fill?: Scalar; + fillPattern?: Scalar; + strokeWidth?: Scalar; + strokeDash?: Scalar; + borderRadius?: Scalar; + shadow?: Scalar; + "3d"?: Scalar; + multiple?: Scalar; + font?: Scalar; + fontSize?: Scalar; + fontColor?: Scalar; + animated?: Scalar; + bold?: Scalar; + italic?: Scalar; + underline?: Scalar; + filled?: Scalar; + doubleBorder?: Scalar; + textTransform?: Scalar; +} + +export interface TextDimensions { + width: number /* int */; + height: number /* int */; } From 5c63672dbd36d68fbb2b265209e243b2d455bf02 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 16 Mar 2025 09:49:00 -0600 Subject: [PATCH 34/54] save --- d2renderers/d2svg/d2svg.go | 22 +- d2renderers/d2svg/github-markdown.css | 1 - .../txtar/c4-theme/dagre/board.exp.json | 2 +- .../txtar/c4-theme/dagre/sketch.exp.svg | 645 ++++++++++-------- .../txtar/c4-theme/elk/board.exp.json | 2 +- .../txtar/c4-theme/elk/sketch.exp.svg | 645 ++++++++++-------- e2etests/txtar.txt | 100 +++ 7 files changed, 835 insertions(+), 582 deletions(-) diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index 434b97bc2..3fb83496c 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -1732,23 +1732,31 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape render = strings.ReplaceAll(render, "
", "
") mdEl := d2themes.NewThemableElement("div", inlineTheme) - mdEl.ClassName = "md" mdEl.Content = render // We have to set with styles since within foreignObject, we're in html // land and not SVG attributes var styles []string + var classes []string = []string{"md"} if targetShape.FontSize != textmeasure.MarkdownFontSize { styles = append(styles, fmt.Sprintf("font-size:%vpx", targetShape.FontSize)) } + if targetShape.Fill != "" && targetShape.Fill != "transparent" { - styles = append(styles, fmt.Sprintf(`background-color:%s`, targetShape.Fill)) + if color.IsThemeColor(targetShape.Fill) { + classes = append(classes, fmt.Sprintf("fill-%s", targetShape.Fill)) + } else { + styles = append(styles, fmt.Sprintf(`background-color:%s`, targetShape.Fill)) + } } + if !color.IsThemeColor(targetShape.Color) { styles = append(styles, fmt.Sprintf(`color:%s`, targetShape.Color)) - } else if inlineTheme != nil { - styles = append(styles, fmt.Sprintf(`color:%s`, d2themes.ResolveThemeColor(*inlineTheme, targetShape.Color))) + } else { + classes = append(classes, fmt.Sprintf("color-%s", targetShape.Color)) } + + mdEl.ClassName = strings.Join(classes, " ") // When using dark theme, inlineTheme is nil and we rely on CSS variables mdEl.Style = strings.Join(styles, ";") @@ -1948,6 +1956,7 @@ func EmbedFonts(buf *bytes.Buffer, diagramHash, source string, fontFamily *d2fon `class="text"`, `class="text `, `class="md"`, + `class="md `, }, fmt.Sprintf(` .%s .text { @@ -1967,7 +1976,10 @@ func EmbedFonts(buf *bytes.Buffer, diagramHash, source string, fontFamily *d2fon appendOnTrigger( buf, source, - []string{`class="md"`}, + []string{ + `class="md"`, + `class="md `, + }, fmt.Sprintf(` @font-face { font-family: %s-font-semibold; diff --git a/d2renderers/d2svg/github-markdown.css b/d2renderers/d2svg/github-markdown.css index c271b67d7..53a7e2102 100644 --- a/d2renderers/d2svg/github-markdown.css +++ b/d2renderers/d2svg/github-markdown.css @@ -26,7 +26,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "font-regular"; font-size: 16px; diff --git a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json index 4b80ded31..b8a4d8dd5 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json @@ -3,7 +3,7 @@ "config": { "sketch": false, "themeID": 303, - "darkThemeID": null, + "darkThemeID": 200, "pad": null, "center": null, "layoutEngine": null diff --git a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg index fb2279b45..e3cab1bd5 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] diff --git a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json index 4d6d3ccd8..a7c6cbe2f 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json @@ -3,7 +3,7 @@ "config": { "sketch": false, "themeID": 303, - "darkThemeID": null, + "darkThemeID": 200, "pad": null, "center": null, "layoutEngine": null diff --git a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg index 46f088711..d6f366fc8 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -

Personal Banking Customer

+

Personal Banking Customer

[person]

A customer of the bank, with personal bank accounts.

-

Internet Banking System

+

Internet Banking System

[Software System]

-

E-mail System

+

E-mail System

[Software System]

The internal Microsoft Exchange e-mail system.

-

Mainframe Banking System

+

Mainframe Banking System

[Software System]

Stores all of the core banking information about customers, accounts, transactions, etc.

-

Web Application

+

Web Application

[Container: Java and Spring MVC]

Delivers the static content and the Internet banking single page application.

-

Single-Page Application

+

Single-Page Application

[Container: JavaScript and Angular]

Provides all of the Internet banking functionality to customers via their web browser.

-

Mobile App

+

Mobile App

[Container: Xamarin]

Provides a limited subset of the Internet banking functionality to customers via their mobile device.

-

API Application

+

API Application

[Container: Java and Spring MVC]

Provides Internet banking functionality via a JSON/HTTPS API.

-

Database

+

Database

[Container: Oracle Database Schema]

Stores user registration information, hashed authentication credentials, access logs, etc.

-
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] +
Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] diff --git a/e2etests/txtar.txt b/e2etests/txtar.txt index ac940b683..a9b843e26 100644 --- a/e2etests/txtar.txt +++ b/e2etests/txtar.txt @@ -1161,3 +1161,103 @@ customer4: |md | { shape: c4-person } + +-- c4-theme -- +vars: { + d2-config: { + theme-id: 303 + dark-theme-id: 200 + } +} + +customer: |md + ## Personal Banking Customer + [person] + + A customer of the bank, with personal bank accounts. +| { + shape: c4-person +} + +internet_banking_system: |md + ## Internet Banking System + [Software System] +| { + shape: rectangle + label.near: bottom-left +} + +internet_banking_system.web_app: |md + ## Web Application + [Container: Java and Spring MVC] + + Delivers the static content and the Internet banking single page application. +| { + shape: rectangle +} + +internet_banking_system.spa: |md + ## Single-Page Application + [Container: JavaScript and Angular] + + Provides all of the Internet banking functionality to customers via their web browser. +| { + shape: rectangle +} + +internet_banking_system.mobile_app: |md + ## Mobile App + [Container: Xamarin] + + Provides a limited subset of the Internet banking functionality to customers via their mobile device. +| { + shape: rectangle +} + +internet_banking_system.api_app: |md + ## API Application + [Container: Java and Spring MVC] + + Provides Internet banking functionality via a JSON/HTTPS API. +| { + shape: rectangle +} + +internet_banking_system.database: |md + ## Database + [Container: Oracle Database Schema] + + Stores user registration information, hashed authentication credentials, access logs, etc. +| { + shape: rectangle +} + +email_system: |md + ## E-mail System + [Software System] + + The internal Microsoft Exchange e-mail system. +| { + shape: rectangle +} + +mainframe: |md + ## Mainframe Banking System + [Software System] + + Stores all of the core banking information about customers, accounts, transactions, etc. +| { + shape: rectangle +} + +# Connections +customer -> internet_banking_system.web_app: "Visits bigbank.com/ib using\n[HTTPS]" +internet_banking_system.web_app -> internet_banking_system.spa: "Delivers to the customer's web browser" +customer -> internet_banking_system.spa: "Views account balances, and makes payments using" +customer -> internet_banking_system.mobile_app: "Views account balances, and makes payments using" +internet_banking_system.spa -> internet_banking_system.api_app: "Makes API calls to\n[JSON/HTTPS]" +internet_banking_system.mobile_app -> internet_banking_system.api_app: "Makes API calls to\n[JSON/HTTPS]" +internet_banking_system.api_app -> mainframe: "Makes API calls to\n[XML/HTTPS]" +customer -> email_system: "Sends e-mails to" +internet_banking_system.api_app -> email_system: "Sends e-mail using" +internet_banking_system.database <-> internet_banking_system.api_app: "Reads from and writes to\n[SQL/TCP]" From 9009e0893ccf21cacf480aac9c20b02ae142b93d Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Sun, 16 Mar 2025 10:04:18 -0600 Subject: [PATCH 35/54] ta --- .../d2sketch/testdata/opacity/sketch.exp.svg | 3 +- .../testdata/opacity_dark/sketch.exp.svg | 3 +- .../testdata/root-fill/sketch.exp.svg | 3 +- .../d2sketch/testdata/twitter/sketch.exp.svg | 5 +- .../testdata/twitter_dark/sketch.exp.svg | 5 +- .../testdata/code/dark_theme.exp.svg | 3 +- .../testdata/opacity/dark_theme.exp.svg | 3 +- .../testdata/twitter/dark_theme.exp.svg | 5 +- .../testdata/TestCLI_E2E/animation.exp.svg | 1 - .../TestCLI_E2E/vars-animation.exp.svg | 1 - .../regression/elk_order/dagre/sketch.exp.svg | 9 +- .../regression/elk_order/elk/sketch.exp.svg | 9 +- .../md_font_weight/dagre/sketch.exp.svg | 3 +- .../md_font_weight/elk/sketch.exp.svg | 3 +- .../md_h1_li_li/dagre/sketch.exp.svg | 3 +- .../regression/md_h1_li_li/elk/sketch.exp.svg | 3 +- .../opacity-on-label/dagre/sketch.exp.svg | 3 +- .../opacity-on-label/elk/sketch.exp.svg | 3 +- .../unconnected/dagre/sketch.exp.svg | 3 +- .../regression/unconnected/elk/sketch.exp.svg | 3 +- .../testdata/stable/br/dagre/sketch.exp.svg | 3 +- .../testdata/stable/br/elk/sketch.exp.svg | 3 +- .../constant_near_stress/dagre/sketch.exp.svg | 3 +- .../constant_near_stress/elk/sketch.exp.svg | 3 +- .../constant_near_title/dagre/sketch.exp.svg | 3 +- .../constant_near_title/elk/sketch.exp.svg | 3 +- .../stable/font_colors/dagre/sketch.exp.svg | 1 - .../stable/font_colors/elk/sketch.exp.svg | 1 - .../giant_markdown_test/dagre/sketch.exp.svg | 3 +- .../giant_markdown_test/elk/sketch.exp.svg | 3 +- .../testdata/stable/hr/dagre/sketch.exp.svg | 3 +- .../testdata/stable/hr/elk/sketch.exp.svg | 3 +- .../testdata/stable/li1/dagre/sketch.exp.svg | 3 +- .../testdata/stable/li1/elk/sketch.exp.svg | 3 +- .../testdata/stable/li2/dagre/sketch.exp.svg | 3 +- .../testdata/stable/li2/elk/sketch.exp.svg | 3 +- .../testdata/stable/li3/dagre/sketch.exp.svg | 3 +- .../testdata/stable/li3/elk/sketch.exp.svg | 3 +- .../testdata/stable/li4/dagre/sketch.exp.svg | 3 +- .../testdata/stable/li4/elk/sketch.exp.svg | 3 +- .../stable/lone_h1/dagre/sketch.exp.svg | 3 +- .../stable/lone_h1/elk/sketch.exp.svg | 3 +- .../stable/markdown/dagre/sketch.exp.svg | 3 +- .../stable/markdown/elk/sketch.exp.svg | 3 +- .../markdown_stroke_fill/dagre/sketch.exp.svg | 1 - .../markdown_stroke_fill/elk/sketch.exp.svg | 1 - .../md_2space_newline/dagre/sketch.exp.svg | 3 +- .../md_2space_newline/elk/sketch.exp.svg | 3 +- .../md_backslash_newline/dagre/sketch.exp.svg | 3 +- .../md_backslash_newline/elk/sketch.exp.svg | 3 +- .../md_code_block_fenced/dagre/sketch.exp.svg | 3 +- .../md_code_block_fenced/elk/sketch.exp.svg | 3 +- .../dagre/sketch.exp.svg | 3 +- .../md_code_block_indented/elk/sketch.exp.svg | 3 +- .../md_code_inline/dagre/sketch.exp.svg | 3 +- .../stable/md_code_inline/elk/sketch.exp.svg | 3 +- .../md_fontsize_10/dagre/sketch.exp.svg | 3 +- .../stable/md_fontsize_10/elk/sketch.exp.svg | 3 +- .../stable/md_mixed/dagre/sketch.exp.svg | 3 +- .../stable/md_mixed/elk/sketch.exp.svg | 3 +- .../dagre/sketch.exp.svg | 3 +- .../elk/sketch.exp.svg | 3 +- .../testdata/stable/p/dagre/sketch.exp.svg | 3 +- e2etests/testdata/stable/p/elk/sketch.exp.svg | 3 +- .../testdata/stable/pre/dagre/sketch.exp.svg | 3 +- .../testdata/stable/pre/elk/sketch.exp.svg | 3 +- .../stable/teleport_grid/dagre/sketch.exp.svg | 3 +- .../stable/teleport_grid/elk/sketch.exp.svg | 3 +- .../dagre/sketch.exp.svg | 3 +- .../elk/sketch.exp.svg | 3 +- .../themes/terminal/dagre/sketch.exp.svg | 3 +- .../themes/terminal/elk/sketch.exp.svg | 3 +- .../dagre/sketch.exp.svg | 3 +- .../elk/sketch.exp.svg | 3 +- .../dagre/sketch.exp.svg | 3 +- .../shape_set_width_height/elk/sketch.exp.svg | 3 +- .../c4-person-label/dagre/sketch.exp.svg | 15 +- .../txtar/c4-person-label/elk/sketch.exp.svg | 15 +- .../c4-person-shape/dagre/sketch.exp.svg | 1 - .../txtar/c4-person-shape/elk/sketch.exp.svg | 1 - .../txtar/c4-theme/dagre/board.exp.json | 2 +- .../txtar/c4-theme/dagre/sketch.exp.svg | 645 ++++++++---------- .../txtar/c4-theme/elk/board.exp.json | 2 +- .../txtar/c4-theme/elk/sketch.exp.svg | 645 ++++++++---------- .../txtar/dark-theme-md/dagre/sketch.exp.svg | 3 +- .../txtar/dark-theme-md/elk/sketch.exp.svg | 3 +- .../txtar/extended-ascii/dagre/sketch.exp.svg | 9 +- .../txtar/extended-ascii/elk/sketch.exp.svg | 9 +- .../txtar/md-label/dagre/sketch.exp.svg | 35 +- .../txtar/md-label/elk/sketch.exp.svg | 35 +- .../txtar/md-tables/dagre/sketch.exp.svg | 21 +- .../txtar/md-tables/elk/sketch.exp.svg | 21 +- .../dagre/sketch.exp.svg | 3 +- .../elk/sketch.exp.svg | 3 +- .../txtar/sql-icon/dagre/sketch.exp.svg | 5 +- .../txtar/sql-icon/elk/sketch.exp.svg | 5 +- .../txtar/unicode/dagre/sketch.exp.svg | 25 +- .../testdata/txtar/unicode/elk/sketch.exp.svg | 25 +- .../var_in_markdown/dagre/sketch.exp.svg | 3 +- .../txtar/var_in_markdown/elk/sketch.exp.svg | 3 +- .../unicode/chinese/dagre/sketch.exp.svg | 3 +- .../unicode/chinese/elk/sketch.exp.svg | 3 +- .../mixed-language/dagre/sketch.exp.svg | 3 +- .../unicode/mixed-language/elk/sketch.exp.svg | 3 +- e2etests/txtar.txt | 100 --- 105 files changed, 769 insertions(+), 1111 deletions(-) diff --git a/d2renderers/d2sketch/testdata/opacity/sketch.exp.svg b/d2renderers/d2sketch/testdata/opacity/sketch.exp.svg index 44e8664c5..d51852d51 100644 --- a/d2renderers/d2sketch/testdata/opacity/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/opacity/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-601677588-font-regular"; font-size: 16px; @@ -855,7 +854,7 @@ -x

linux: because a PC is a terrible thing to waste

+x

linux: because a PC is a terrible thing to waste

auserslast_logindatetime You don't have to know how the computer works,just how to work the computer. diff --git a/d2renderers/d2sketch/testdata/opacity_dark/sketch.exp.svg b/d2renderers/d2sketch/testdata/opacity_dark/sketch.exp.svg index 8a7266c98..1de7cbb6d 100644 --- a/d2renderers/d2sketch/testdata/opacity_dark/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/opacity_dark/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1742880122-font-regular"; font-size: 16px; @@ -852,7 +851,7 @@ -x

linux: because a PC is a terrible thing to waste

+x

linux: because a PC is a terrible thing to waste

auserslast_logindatetime You don't have to know how the computer works,just how to work the computer. diff --git a/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg b/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg index c8fc0dc00..8c982dbe7 100644 --- a/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/root-fill/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1318841297-font-regular"; font-size: 16px; @@ -848,7 +847,7 @@ -Flow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor Warehousecompany WarehouseMasterRegional-1Regional-2Regional-N

company Warehouse

+Flow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor Warehousecompany WarehouseMasterRegional-1Regional-2Regional-N

company Warehouse

  • Asset Tagging
  • Inventory
  • diff --git a/d2renderers/d2sketch/testdata/twitter/sketch.exp.svg b/d2renderers/d2sketch/testdata/twitter/sketch.exp.svg index 8188e20a1..543d8a066 100644 --- a/d2renderers/d2sketch/testdata/twitter/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/twitter/sketch.exp.svg @@ -143,7 +143,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-300145350-font-regular"; font-size: 16px; @@ -863,7 +862,7 @@ -People discovery serviceAd mixerOnboarding serviceTwitter Frontend WebIphoneAndroidTimelineScorerHome RankerTimeline ServiceHome mixerManhattanGizmoduckSocial graphTweety PiePrediction ServiceHome ScorerManhattanMemcacheFetchFeatureScoringPrediction Service...etc

    Timeline mixer

    +People discovery serviceAd mixerOnboarding serviceTwitter Frontend WebIphoneAndroidTimelineScorerHome RankerTimeline ServiceHome mixerManhattanGizmoduckSocial graphTweety PiePrediction ServiceHome ScorerManhattanMemcacheFetchFeatureScoringPrediction Service...etc

    Timeline mixer

    • Inject ads, who-to-follow, onboarding
    • Conversation module
    • @@ -871,7 +870,7 @@
    • Tweat deduplication
    • Served data logging
    -
    GraphQLFederated Strato Column

    Tweet/user content hydration, visibility filtering

    +
    GraphQLFederated Strato Column

    Tweet/user content hydration, visibility filtering

    TLS-API (being deprecated)CrMixerEarlyBirdUtagSpaceCommunities iPhone web HTTP Android Thrift RPC Candidate Fetch Feature Hydration Candidate sources diff --git a/d2renderers/d2sketch/testdata/twitter_dark/sketch.exp.svg b/d2renderers/d2sketch/testdata/twitter_dark/sketch.exp.svg index f875a214b..cf59e2ebb 100644 --- a/d2renderers/d2sketch/testdata/twitter_dark/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/twitter_dark/sketch.exp.svg @@ -143,7 +143,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-151669824-font-regular"; font-size: 16px; @@ -863,7 +862,7 @@ -People discovery serviceAd mixerOnboarding serviceTwitter Frontend WebIphoneAndroidTimelineScorerHome RankerTimeline ServiceHome mixerManhattanGizmoduckSocial graphTweety PiePrediction ServiceHome ScorerManhattanMemcacheFetchFeatureScoringPrediction Service...etc

    Timeline mixer

    +People discovery serviceAd mixerOnboarding serviceTwitter Frontend WebIphoneAndroidTimelineScorerHome RankerTimeline ServiceHome mixerManhattanGizmoduckSocial graphTweety PiePrediction ServiceHome ScorerManhattanMemcacheFetchFeatureScoringPrediction Service...etc

    Timeline mixer

    • Inject ads, who-to-follow, onboarding
    • Conversation module
    • @@ -871,7 +870,7 @@
    • Tweat deduplication
    • Served data logging
    -
    GraphQLFederated Strato Column

    Tweet/user content hydration, visibility filtering

    +
    GraphQLFederated Strato Column

    Tweet/user content hydration, visibility filtering

    TLS-API (being deprecated)CrMixerEarlyBirdUtagSpaceCommunities iPhone web HTTP Android Thrift RPC Candidate Fetch Feature Hydration Candidate sources diff --git a/d2renderers/d2svg/dark_theme/testdata/code/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/code/dark_theme.exp.svg index 1286fa115..f5c0f826a 100644 --- a/d2renderers/d2svg/dark_theme/testdata/code/dark_theme.exp.svg +++ b/d2renderers/d2svg/dark_theme/testdata/code/dark_theme.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-41228547-font-regular"; font-size: 16px; @@ -847,7 +846,7 @@   panic("TODO") }func main() {   panic("TODO") -}

    Five is a sufficiently close approximation to infinity.

    +}

    Five is a sufficiently close approximation to infinity.

    Don't hit me!!  I'm in the Twilight Zone!!!Don't hit me!!  I'm in the Twilight Zone!!! diff --git a/d2renderers/d2svg/dark_theme/testdata/opacity/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/opacity/dark_theme.exp.svg index 2348d3093..cb43dab8f 100644 --- a/d2renderers/d2svg/dark_theme/testdata/opacity/dark_theme.exp.svg +++ b/d2renderers/d2svg/dark_theme/testdata/opacity/dark_theme.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3335880637-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-3335880637 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -x

    linux: because a PC is a terrible thing to waste

    +x

    linux: because a PC is a terrible thing to waste

    auserslast_logindatetime You don't have to know how the computer works,just how to work the computer. diff --git a/d2renderers/d2svg/dark_theme/testdata/twitter/dark_theme.exp.svg b/d2renderers/d2svg/dark_theme/testdata/twitter/dark_theme.exp.svg index fd67b52b8..bad8193d8 100644 --- a/d2renderers/d2svg/dark_theme/testdata/twitter/dark_theme.exp.svg +++ b/d2renderers/d2svg/dark_theme/testdata/twitter/dark_theme.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1329315803-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-1329315803 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -People discovery serviceAd mixerOnboarding serviceTwitter Frontend WebIphoneAndroidTimelineScorerHome RankerTimeline ServiceHome mixerManhattanGizmoduckSocial graphTweety PiePrediction ServiceHome ScorerManhattanMemcacheFetchFeatureScoringPrediction Service...etc

    Timeline mixer

    +People discovery serviceAd mixerOnboarding serviceTwitter Frontend WebIphoneAndroidTimelineScorerHome RankerTimeline ServiceHome mixerManhattanGizmoduckSocial graphTweety PiePrediction ServiceHome ScorerManhattanMemcacheFetchFeatureScoringPrediction Service...etc

    Timeline mixer

    • Inject ads, who-to-follow, onboarding
    • Conversation module
    • @@ -851,7 +850,7 @@
    • Tweat deduplication
    • Served data logging
    -
    GraphQLFederated Strato Column

    Tweet/user content hydration, visibility filtering

    +
    GraphQLFederated Strato Column

    Tweet/user content hydration, visibility filtering

    TLS-API (being deprecated)CrMixerEarlyBirdUtagSpaceCommunities iPhone webHTTP AndroidThrift RPC Candidate FetchFeature HydrationCandidate sources diff --git a/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg b/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg index ed7cdbc16..dcbca7efc 100644 --- a/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg +++ b/e2etests-cli/testdata/TestCLI_E2E/animation.exp.svg @@ -124,7 +124,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2144186222-font-regular"; font-size: 16px; diff --git a/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg b/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg index dc6c04e0c..ff364797c 100644 --- a/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg +++ b/e2etests-cli/testdata/TestCLI_E2E/vars-animation.exp.svg @@ -124,7 +124,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-629739489-font-regular"; font-size: 16px; diff --git a/e2etests/testdata/regression/elk_order/dagre/sketch.exp.svg b/e2etests/testdata/regression/elk_order/dagre/sketch.exp.svg index e785cdab4..a073a5d9a 100644 --- a/e2etests/testdata/regression/elk_order/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/elk_order/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3049291188-font-regular"; font-size: 16px; @@ -836,10 +835,10 @@ .d2-3049291188 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

    Oldest message

    -

    Offset

    -

    Last message

    -

    Next message will be
    +

    Oldest message

    +

    Offset

    +

    Last message

    +

    Next message will be
    inserted here

    M0M1M2M3M4M5M6 diff --git a/e2etests/testdata/regression/elk_order/elk/sketch.exp.svg b/e2etests/testdata/regression/elk_order/elk/sketch.exp.svg index f1f7263f6..9278f1922 100644 --- a/e2etests/testdata/regression/elk_order/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/elk_order/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3542568952-font-regular"; font-size: 16px; @@ -836,10 +835,10 @@ .d2-3542568952 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

    Oldest message

    -

    Offset

    -

    Last message

    -

    Next message will be
    +

    Oldest message

    +

    Offset

    +

    Last message

    +

    Next message will be
    inserted here

    M0M1M2M3M4M5M6 diff --git a/e2etests/testdata/regression/md_font_weight/dagre/sketch.exp.svg b/e2etests/testdata/regression/md_font_weight/dagre/sketch.exp.svg index d306de191..25e5818dc 100644 --- a/e2etests/testdata/regression/md_font_weight/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/md_font_weight/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-147443974-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-147443974 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

    I can do headers

    +

    I can do headers

    • lists
    • lists
    • diff --git a/e2etests/testdata/regression/md_font_weight/elk/sketch.exp.svg b/e2etests/testdata/regression/md_font_weight/elk/sketch.exp.svg index 75d4fe601..90b3f7532 100644 --- a/e2etests/testdata/regression/md_font_weight/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/md_font_weight/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2881380206-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-2881380206 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

      I can do headers

      +

      I can do headers

      • lists
      • lists
      • diff --git a/e2etests/testdata/regression/md_h1_li_li/dagre/sketch.exp.svg b/e2etests/testdata/regression/md_h1_li_li/dagre/sketch.exp.svg index 69644a27d..5c15180ff 100644 --- a/e2etests/testdata/regression/md_h1_li_li/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/md_h1_li_li/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1836715912-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1836715912 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

        hey

        +

        hey

        • they
            diff --git a/e2etests/testdata/regression/md_h1_li_li/elk/sketch.exp.svg b/e2etests/testdata/regression/md_h1_li_li/elk/sketch.exp.svg index 5b9673ea7..d8ee7c442 100644 --- a/e2etests/testdata/regression/md_h1_li_li/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/md_h1_li_li/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3788794681-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-3788794681 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

            hey

            +

            hey

            • they
                diff --git a/e2etests/testdata/regression/opacity-on-label/dagre/sketch.exp.svg b/e2etests/testdata/regression/opacity-on-label/dagre/sketch.exp.svg index 89f900846..13fad6d1f 100644 --- a/e2etests/testdata/regression/opacity-on-label/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/opacity-on-label/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1987627880-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-1987627880 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -x

                linux: because a PC is a terrible thing to waste

                +x

                linux: because a PC is a terrible thing to waste

                a You don't have to know how the computer works,just how to work the computer. diff --git a/e2etests/testdata/regression/opacity-on-label/elk/sketch.exp.svg b/e2etests/testdata/regression/opacity-on-label/elk/sketch.exp.svg index 42374bbd2..99b02c34e 100644 --- a/e2etests/testdata/regression/opacity-on-label/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/opacity-on-label/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-856327487-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-856327487 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -x

                linux: because a PC is a terrible thing to waste

                +x

                linux: because a PC is a terrible thing to waste

                a You don't have to know how the computer works,just how to work the computer. diff --git a/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg b/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg index bcf7b4344..acf74d5fb 100644 --- a/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg +++ b/e2etests/testdata/regression/unconnected/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-4271326716-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-4271326716 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -Workflow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteMasterRegional-1Regional-2Regional-N
                  +Workflow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteMasterRegional-1Regional-2Regional-N
                  • Asset Tagging
                  • Inventory
                  • Staging
                  • diff --git a/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg b/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg index c6858e1b9..a0cc6c80a 100644 --- a/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg +++ b/e2etests/testdata/regression/unconnected/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1235788687-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1235788687 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -Workflow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteMasterRegional-1Regional-2Regional-N
                      +Workflow-I (Warehousing, Installation)OEM FactoryOEM WarehouseDistributor WarehouseGos WarehouseCustomer SiteMasterRegional-1Regional-2Regional-N
                      • Asset Tagging
                      • Inventory
                      • Staging
                      • diff --git a/e2etests/testdata/stable/br/dagre/sketch.exp.svg b/e2etests/testdata/stable/br/dagre/sketch.exp.svg index d136e2968..4b32bcda6 100644 --- a/e2etests/testdata/stable/br/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/br/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3415583374-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-3415583374 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                        Headline 1

                        +

                        Headline 1

                        Headline 2

                        Lorem ipsum dolor

                        diff --git a/e2etests/testdata/stable/br/elk/sketch.exp.svg b/e2etests/testdata/stable/br/elk/sketch.exp.svg index 04d063663..9ca88d88b 100644 --- a/e2etests/testdata/stable/br/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/br/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2354018982-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-2354018982 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                        Headline 1

                        +

                        Headline 1

                        Headline 2

                        Lorem ipsum dolor

                        diff --git a/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg b/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg index 1df7ab4f7..d051dfacb 100644 --- a/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_stress/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1761626757-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1761626757 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -xyThe top of the mountainJoeDonald

                        Cats, no less liquid than their shadows, offer no angles to the wind.

                        +xyThe top of the mountainJoeDonald

                        Cats, no less liquid than their shadows, offer no angles to the wind.

                        If we can't fix it, it ain't broke.

                        Dieters live life in the fasting lane.

                        i am top lefti am top righti am bottom lefti am bottom right diff --git a/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg b/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg index dfcdc388d..89e1ffcea 100644 --- a/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_stress/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1390049335-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1390049335 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -xyThe top of the mountainJoeDonald

                        Cats, no less liquid than their shadows, offer no angles to the wind.

                        +xyThe top of the mountainJoeDonald

                        Cats, no less liquid than their shadows, offer no angles to the wind.

                        If we can't fix it, it ain't broke.

                        Dieters live life in the fasting lane.

                        i am top lefti am top righti am bottom lefti am bottom right diff --git a/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg b/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg index 792d1e688..3adfcdaeb 100644 --- a/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_title/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2364978249-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-2364978249 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                        A winning strategy

                        +

                        A winning strategy

                        poll the peopleresultsunfavorablefavorablewill of the people diff --git a/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg b/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg index ea5956d84..d5b7b3075 100644 --- a/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/constant_near_title/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-4212596512-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-4212596512 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                        A winning strategy

                        +

                        A winning strategy

                        poll the peopleresultsunfavorablefavorablewill of the people diff --git a/e2etests/testdata/stable/font_colors/dagre/sketch.exp.svg b/e2etests/testdata/stable/font_colors/dagre/sketch.exp.svg index 04bbf4f48..3164f3577 100644 --- a/e2etests/testdata/stable/font_colors/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/font_colors/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2362348913-font-regular"; font-size: 16px; diff --git a/e2etests/testdata/stable/font_colors/elk/sketch.exp.svg b/e2etests/testdata/stable/font_colors/elk/sketch.exp.svg index 431a803c0..90397f6b8 100644 --- a/e2etests/testdata/stable/font_colors/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/font_colors/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-664798849-font-regular"; font-size: 16px; diff --git a/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg b/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg index 63f3c768a..4d502a04a 100644 --- a/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/giant_markdown_test/dagre/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-851985161-font-regular"; font-size: 16px; @@ -850,7 +849,7 @@ .d2-851985161 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                        Markdown: Syntax

                        +

                        Markdown: Syntax

                        • Overview
                            diff --git a/e2etests/testdata/stable/giant_markdown_test/elk/sketch.exp.svg b/e2etests/testdata/stable/giant_markdown_test/elk/sketch.exp.svg index 7833bf6cc..d37d1b5b3 100644 --- a/e2etests/testdata/stable/giant_markdown_test/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/giant_markdown_test/elk/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-4122552445-font-regular"; font-size: 16px; @@ -850,7 +849,7 @@ .d2-4122552445 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                            Markdown: Syntax

                            +

                            Markdown: Syntax

                            • Overview
                                diff --git a/e2etests/testdata/stable/hr/dagre/sketch.exp.svg b/e2etests/testdata/stable/hr/dagre/sketch.exp.svg index ed98d022e..0d3428360 100644 --- a/e2etests/testdata/stable/hr/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/hr/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-142627214-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-142627214 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                Note: This document is itself written using Markdown; you +

                                Note: This document is itself written using Markdown; you can see the source for it by adding '.text' to the URL.


                                Overview

                                diff --git a/e2etests/testdata/stable/hr/elk/sketch.exp.svg b/e2etests/testdata/stable/hr/elk/sketch.exp.svg index c87b096fd..a611ba012 100644 --- a/e2etests/testdata/stable/hr/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/hr/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3115974332-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-3115974332 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                Note: This document is itself written using Markdown; you +

                                Note: This document is itself written using Markdown; you can see the source for it by adding '.text' to the URL.


                                Overview

                                diff --git a/e2etests/testdata/stable/li1/dagre/sketch.exp.svg b/e2etests/testdata/stable/li1/dagre/sketch.exp.svg index a75f650ba..94f6601bd 100644 --- a/e2etests/testdata/stable/li1/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/li1/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3521704376-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-3521704376 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                  +
                                  • Overview
                                    • Philosophy
                                    • diff --git a/e2etests/testdata/stable/li1/elk/sketch.exp.svg b/e2etests/testdata/stable/li1/elk/sketch.exp.svg index 12d7f100a..a1082bda1 100644 --- a/e2etests/testdata/stable/li1/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/li1/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2351031357-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-2351031357 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                        +
                                        • Overview
                                          • Philosophy
                                          • diff --git a/e2etests/testdata/stable/li2/dagre/sketch.exp.svg b/e2etests/testdata/stable/li2/dagre/sketch.exp.svg index bd9d9b9bf..f72a29d12 100644 --- a/e2etests/testdata/stable/li2/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/li2/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3835243374-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-3835243374 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                              +
                                              • Overview ok this is all measured
                                                • Philosophy
                                                • diff --git a/e2etests/testdata/stable/li2/elk/sketch.exp.svg b/e2etests/testdata/stable/li2/elk/sketch.exp.svg index 9f0dee141..f635a1a71 100644 --- a/e2etests/testdata/stable/li2/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/li2/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2498775702-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-2498775702 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                                    +
                                                    • Overview ok this is all measured
                                                      • Philosophy
                                                      • diff --git a/e2etests/testdata/stable/li3/dagre/sketch.exp.svg b/e2etests/testdata/stable/li3/dagre/sketch.exp.svg index 7a0b2e864..513a3509d 100644 --- a/e2etests/testdata/stable/li3/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/li3/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1850453634-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1850453634 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                                          +
                                                          • Overview
                                                            • Philosophy
                                                            • diff --git a/e2etests/testdata/stable/li3/elk/sketch.exp.svg b/e2etests/testdata/stable/li3/elk/sketch.exp.svg index 9812d3afe..8ff7c9640 100644 --- a/e2etests/testdata/stable/li3/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/li3/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3625619566-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-3625619566 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                                                +
                                                                • Overview
                                                                  • Philosophy
                                                                  • diff --git a/e2etests/testdata/stable/li4/dagre/sketch.exp.svg b/e2etests/testdata/stable/li4/dagre/sketch.exp.svg index 12cd99727..fee9f3a83 100644 --- a/e2etests/testdata/stable/li4/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/li4/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-95635950-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-95635950 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                    List items may consist of multiple paragraphs. Each subsequent +

                                                                    List items may consist of multiple paragraphs. Each subsequent paragraph in a list item must be indented by either 4 spaces or one tab:

                                                                      diff --git a/e2etests/testdata/stable/li4/elk/sketch.exp.svg b/e2etests/testdata/stable/li4/elk/sketch.exp.svg index 42df125b6..e52b88cb9 100644 --- a/e2etests/testdata/stable/li4/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/li4/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1253393308-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-1253393308 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                      List items may consist of multiple paragraphs. Each subsequent +

                                                                      List items may consist of multiple paragraphs. Each subsequent paragraph in a list item must be indented by either 4 spaces or one tab:

                                                                        diff --git a/e2etests/testdata/stable/lone_h1/dagre/sketch.exp.svg b/e2etests/testdata/stable/lone_h1/dagre/sketch.exp.svg index d559875ba..c5b40c60d 100644 --- a/e2etests/testdata/stable/lone_h1/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/lone_h1/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1741298119-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1741298119 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                        Markdown: Syntax

                                                                        +

                                                                        Markdown: Syntax

                                                                        ab diff --git a/e2etests/testdata/stable/lone_h1/elk/sketch.exp.svg b/e2etests/testdata/stable/lone_h1/elk/sketch.exp.svg index 722c9fcfd..990ef92b2 100644 --- a/e2etests/testdata/stable/lone_h1/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/lone_h1/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1073489527-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1073489527 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                        Markdown: Syntax

                                                                        +

                                                                        Markdown: Syntax

                                                                        ab diff --git a/e2etests/testdata/stable/markdown/dagre/sketch.exp.svg b/e2etests/testdata/stable/markdown/dagre/sketch.exp.svg index 53f6af603..d9d20710d 100644 --- a/e2etests/testdata/stable/markdown/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/markdown/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1466084009-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-1466084009 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                        Every frustum longs to be a cone

                                                                        +

                                                                        Every frustum longs to be a cone

                                                                        • A continuing flow of paper is sufficient to continue the flow of paper
                                                                        • Please remain calm, it's no use both of us being hysterical at the same time
                                                                        • diff --git a/e2etests/testdata/stable/markdown/elk/sketch.exp.svg b/e2etests/testdata/stable/markdown/elk/sketch.exp.svg index 74c9a2cb0..3329ea93e 100644 --- a/e2etests/testdata/stable/markdown/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/markdown/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2237312999-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-2237312999 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                          Every frustum longs to be a cone

                                                                          +

                                                                          Every frustum longs to be a cone

                                                                          • A continuing flow of paper is sufficient to continue the flow of paper
                                                                          • Please remain calm, it's no use both of us being hysterical at the same time
                                                                          • diff --git a/e2etests/testdata/stable/markdown_stroke_fill/dagre/sketch.exp.svg b/e2etests/testdata/stable/markdown_stroke_fill/dagre/sketch.exp.svg index 2217c52da..1ee8a86d8 100644 --- a/e2etests/testdata/stable/markdown_stroke_fill/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/markdown_stroke_fill/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1160608805-font-regular"; font-size: 16px; diff --git a/e2etests/testdata/stable/markdown_stroke_fill/elk/sketch.exp.svg b/e2etests/testdata/stable/markdown_stroke_fill/elk/sketch.exp.svg index e74f24b3c..f001e0fa5 100644 --- a/e2etests/testdata/stable/markdown_stroke_fill/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/markdown_stroke_fill/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-939069974-font-regular"; font-size: 16px; diff --git a/e2etests/testdata/stable/md_2space_newline/dagre/sketch.exp.svg b/e2etests/testdata/stable/md_2space_newline/dagre/sketch.exp.svg index 82a28c28b..42d9b3bfa 100644 --- a/e2etests/testdata/stable/md_2space_newline/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/md_2space_newline/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2553377867-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-2553377867 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -markdown

                                                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                                                                            +markdown

                                                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                                                                            sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

                                                                            diff --git a/e2etests/testdata/stable/md_2space_newline/elk/sketch.exp.svg b/e2etests/testdata/stable/md_2space_newline/elk/sketch.exp.svg index 829ce37f2..479098e96 100644 --- a/e2etests/testdata/stable/md_2space_newline/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/md_2space_newline/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3503638182-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-3503638182 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -markdown

                                                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                                                                            +markdown

                                                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                                                                            sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

                                                                            diff --git a/e2etests/testdata/stable/md_backslash_newline/dagre/sketch.exp.svg b/e2etests/testdata/stable/md_backslash_newline/dagre/sketch.exp.svg index 9c9904725..0e46c4c06 100644 --- a/e2etests/testdata/stable/md_backslash_newline/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/md_backslash_newline/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3081693699-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-3081693699 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -markdown

                                                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                                                                            +markdown

                                                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                                                                            sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

                                                                            diff --git a/e2etests/testdata/stable/md_backslash_newline/elk/sketch.exp.svg b/e2etests/testdata/stable/md_backslash_newline/elk/sketch.exp.svg index 6ac49ef83..19eae2d01 100644 --- a/e2etests/testdata/stable/md_backslash_newline/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/md_backslash_newline/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-4149945950-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-4149945950 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -markdown

                                                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                                                                            +markdown

                                                                            Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                                                                            sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

                                                                            diff --git a/e2etests/testdata/stable/md_code_block_fenced/dagre/sketch.exp.svg b/e2etests/testdata/stable/md_code_block_fenced/dagre/sketch.exp.svg index ad3879b8d..647deb27e 100644 --- a/e2etests/testdata/stable/md_code_block_fenced/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/md_code_block_fenced/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1518250751-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-1518250751 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                                                            {
                                                                            +
                                                                            {
                                                                             	fenced: "block",
                                                                             	of: "json",
                                                                             }
                                                                            diff --git a/e2etests/testdata/stable/md_code_block_fenced/elk/sketch.exp.svg b/e2etests/testdata/stable/md_code_block_fenced/elk/sketch.exp.svg
                                                                            index fc8892b5b..a2c694985 100644
                                                                            --- a/e2etests/testdata/stable/md_code_block_fenced/elk/sketch.exp.svg
                                                                            +++ b/e2etests/testdata/stable/md_code_block_fenced/elk/sketch.exp.svg
                                                                            @@ -135,7 +135,6 @@
                                                                               -ms-text-size-adjust: 100%;
                                                                               -webkit-text-size-adjust: 100%;
                                                                               margin: 0;
                                                                            -  color: var(--color-fg-default);
                                                                               background-color: transparent; /* we don't want to define the background color */
                                                                               font-family: "d2-3638167430-font-regular";
                                                                               font-size: 16px;
                                                                            @@ -843,7 +842,7 @@
                                                                             .d2-3638167430 .md .contains-task-list:dir(rtl) .task-list-item-checkbox {
                                                                               margin: 0 -1.6em 0.25em 0.2em;
                                                                             }
                                                                            -
                                                                            {
                                                                            +
                                                                            {
                                                                             	fenced: "block",
                                                                             	of: "json",
                                                                             }
                                                                            diff --git a/e2etests/testdata/stable/md_code_block_indented/dagre/sketch.exp.svg b/e2etests/testdata/stable/md_code_block_indented/dagre/sketch.exp.svg
                                                                            index 93f7e90e7..8fe1a2c88 100644
                                                                            --- a/e2etests/testdata/stable/md_code_block_indented/dagre/sketch.exp.svg
                                                                            +++ b/e2etests/testdata/stable/md_code_block_indented/dagre/sketch.exp.svg
                                                                            @@ -135,7 +135,6 @@
                                                                               -ms-text-size-adjust: 100%;
                                                                               -webkit-text-size-adjust: 100%;
                                                                               margin: 0;
                                                                            -  color: var(--color-fg-default);
                                                                               background-color: transparent; /* we don't want to define the background color */
                                                                               font-family: "d2-1952230391-font-regular";
                                                                               font-size: 16px;
                                                                            @@ -843,7 +842,7 @@
                                                                             .d2-1952230391 .md .contains-task-list:dir(rtl) .task-list-item-checkbox {
                                                                               margin: 0 -1.6em 0.25em 0.2em;
                                                                             }
                                                                            -

                                                                            a line of text and an

                                                                            +

                                                                            a line of text and an

                                                                            {
                                                                             	indented: "block",
                                                                             	of: "json",
                                                                            diff --git a/e2etests/testdata/stable/md_code_block_indented/elk/sketch.exp.svg b/e2etests/testdata/stable/md_code_block_indented/elk/sketch.exp.svg
                                                                            index 0a14680d2..ba98d85b2 100644
                                                                            --- a/e2etests/testdata/stable/md_code_block_indented/elk/sketch.exp.svg
                                                                            +++ b/e2etests/testdata/stable/md_code_block_indented/elk/sketch.exp.svg
                                                                            @@ -135,7 +135,6 @@
                                                                               -ms-text-size-adjust: 100%;
                                                                               -webkit-text-size-adjust: 100%;
                                                                               margin: 0;
                                                                            -  color: var(--color-fg-default);
                                                                               background-color: transparent; /* we don't want to define the background color */
                                                                               font-family: "d2-538047421-font-regular";
                                                                               font-size: 16px;
                                                                            @@ -843,7 +842,7 @@
                                                                             .d2-538047421 .md .contains-task-list:dir(rtl) .task-list-item-checkbox {
                                                                               margin: 0 -1.6em 0.25em 0.2em;
                                                                             }
                                                                            -

                                                                            a line of text and an

                                                                            +

                                                                            a line of text and an

                                                                            {
                                                                             	indented: "block",
                                                                             	of: "json",
                                                                            diff --git a/e2etests/testdata/stable/md_code_inline/dagre/sketch.exp.svg b/e2etests/testdata/stable/md_code_inline/dagre/sketch.exp.svg
                                                                            index 19278c20c..95947cbcd 100644
                                                                            --- a/e2etests/testdata/stable/md_code_inline/dagre/sketch.exp.svg
                                                                            +++ b/e2etests/testdata/stable/md_code_inline/dagre/sketch.exp.svg
                                                                            @@ -135,7 +135,6 @@
                                                                               -ms-text-size-adjust: 100%;
                                                                               -webkit-text-size-adjust: 100%;
                                                                               margin: 0;
                                                                            -  color: var(--color-fg-default);
                                                                               background-color: transparent; /* we don't want to define the background color */
                                                                               font-family: "d2-1339768961-font-regular";
                                                                               font-size: 16px;
                                                                            @@ -843,7 +842,7 @@
                                                                             .d2-1339768961 .md .contains-task-list:dir(rtl) .task-list-item-checkbox {
                                                                               margin: 0 -1.6em 0.25em 0.2em;
                                                                             }
                                                                            -

                                                                            code

                                                                            +

                                                                            code

                                                                            ab diff --git a/e2etests/testdata/stable/md_code_inline/elk/sketch.exp.svg b/e2etests/testdata/stable/md_code_inline/elk/sketch.exp.svg index edcf5b11e..5a0542978 100644 --- a/e2etests/testdata/stable/md_code_inline/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/md_code_inline/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3881944313-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-3881944313 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                            code

                                                                            +

                                                                            code

                                                                            ab diff --git a/e2etests/testdata/stable/md_fontsize_10/dagre/sketch.exp.svg b/e2etests/testdata/stable/md_fontsize_10/dagre/sketch.exp.svg index 4a6cc6146..769cb2b0e 100644 --- a/e2etests/testdata/stable/md_fontsize_10/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/md_fontsize_10/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2196724626-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-2196724626 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                            Every frustum longs to be a cone

                                                                            +

                                                                            Every frustum longs to be a cone

                                                                            • A continuing flow of paper is sufficient to continue the flow of paper
                                                                            • Please remain calm, it's no use both of us being hysterical at the same time
                                                                            • diff --git a/e2etests/testdata/stable/md_fontsize_10/elk/sketch.exp.svg b/e2etests/testdata/stable/md_fontsize_10/elk/sketch.exp.svg index 1e56c95cb..43378ec0f 100644 --- a/e2etests/testdata/stable/md_fontsize_10/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/md_fontsize_10/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-632982403-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-632982403 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                              Every frustum longs to be a cone

                                                                              +

                                                                              Every frustum longs to be a cone

                                                                              • A continuing flow of paper is sufficient to continue the flow of paper
                                                                              • Please remain calm, it's no use both of us being hysterical at the same time
                                                                              • diff --git a/e2etests/testdata/stable/md_mixed/dagre/sketch.exp.svg b/e2etests/testdata/stable/md_mixed/dagre/sketch.exp.svg index c69fd40a9..3c4bf0894 100644 --- a/e2etests/testdata/stable/md_mixed/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/md_mixed/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2743272479-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-2743272479 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -example

                                                                                one two three!

                                                                                +example

                                                                                one two three!

                                                                                diff --git a/e2etests/testdata/stable/md_mixed/elk/sketch.exp.svg b/e2etests/testdata/stable/md_mixed/elk/sketch.exp.svg index a4895531e..d83f40bb1 100644 --- a/e2etests/testdata/stable/md_mixed/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/md_mixed/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3779428285-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-3779428285 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -example

                                                                                one two three!

                                                                                +example

                                                                                one two three!

                                                                                diff --git a/e2etests/testdata/stable/near_keys_for_container/dagre/sketch.exp.svg b/e2etests/testdata/stable/near_keys_for_container/dagre/sketch.exp.svg index 95d72ca0c..2445048e8 100644 --- a/e2etests/testdata/stable/near_keys_for_container/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/near_keys_for_container/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-968008625-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-968008625 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                Service-Cluster Provisioning ("Outside view")

                                                                                +

                                                                                Service-Cluster Provisioning ("Outside view")

                                                                                diff --git a/e2etests/testdata/stable/near_keys_for_container/elk/sketch.exp.svg b/e2etests/testdata/stable/near_keys_for_container/elk/sketch.exp.svg index 95d72ca0c..2445048e8 100644 --- a/e2etests/testdata/stable/near_keys_for_container/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/near_keys_for_container/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-968008625-font-regular"; font-size: 16px; @@ -829,7 +828,7 @@ .d2-968008625 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                Service-Cluster Provisioning ("Outside view")

                                                                                +

                                                                                Service-Cluster Provisioning ("Outside view")

                                                                                diff --git a/e2etests/testdata/stable/p/dagre/sketch.exp.svg b/e2etests/testdata/stable/p/dagre/sketch.exp.svg index f17d8d962..7d586fc7b 100644 --- a/e2etests/testdata/stable/p/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/p/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3128274021-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-3128274021 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                A paragraph is simply one or more consecutive lines of text, separated +

                                                                                A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines. (A blank line is any line that looks like a blank line -- a line containing nothing but spaces or tabs is considered blank.) Normal paragraphs should not be indented with spaces or tabs.

                                                                                diff --git a/e2etests/testdata/stable/p/elk/sketch.exp.svg b/e2etests/testdata/stable/p/elk/sketch.exp.svg index 85bc75cab..df673875f 100644 --- a/e2etests/testdata/stable/p/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/p/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-979712518-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-979712518 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                A paragraph is simply one or more consecutive lines of text, separated +

                                                                                A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines. (A blank line is any line that looks like a blank line -- a line containing nothing but spaces or tabs is considered blank.) Normal paragraphs should not be indented with spaces or tabs.

                                                                                diff --git a/e2etests/testdata/stable/pre/dagre/sketch.exp.svg b/e2etests/testdata/stable/pre/dagre/sketch.exp.svg index 9ef6d1ab7..0ee1035b1 100644 --- a/e2etests/testdata/stable/pre/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/pre/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3660705295-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-3660705295 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                Here is an example of AppleScript:

                                                                                +

                                                                                Here is an example of AppleScript:

                                                                                tell application "Foo"
                                                                                     beep
                                                                                 end tell
                                                                                diff --git a/e2etests/testdata/stable/pre/elk/sketch.exp.svg b/e2etests/testdata/stable/pre/elk/sketch.exp.svg
                                                                                index eb4b05485..90ed3b2e1 100644
                                                                                --- a/e2etests/testdata/stable/pre/elk/sketch.exp.svg
                                                                                +++ b/e2etests/testdata/stable/pre/elk/sketch.exp.svg
                                                                                @@ -135,7 +135,6 @@
                                                                                   -ms-text-size-adjust: 100%;
                                                                                   -webkit-text-size-adjust: 100%;
                                                                                   margin: 0;
                                                                                -  color: var(--color-fg-default);
                                                                                   background-color: transparent; /* we don't want to define the background color */
                                                                                   font-family: "d2-818404908-font-regular";
                                                                                   font-size: 16px;
                                                                                @@ -843,7 +842,7 @@
                                                                                 .d2-818404908 .md .contains-task-list:dir(rtl) .task-list-item-checkbox {
                                                                                   margin: 0 -1.6em 0.25em 0.2em;
                                                                                 }
                                                                                -

                                                                                Here is an example of AppleScript:

                                                                                +

                                                                                Here is an example of AppleScript:

                                                                                tell application "Foo"
                                                                                     beep
                                                                                 end tell
                                                                                diff --git a/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg
                                                                                index 6382dee61..6a68c6dd2 100644
                                                                                --- a/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg
                                                                                +++ b/e2etests/testdata/stable/teleport_grid/dagre/sketch.exp.svg
                                                                                @@ -135,7 +135,6 @@
                                                                                   -ms-text-size-adjust: 100%;
                                                                                   -webkit-text-size-adjust: 100%;
                                                                                   margin: 0;
                                                                                -  color: var(--color-fg-default);
                                                                                   background-color: transparent; /* we don't want to define the background color */
                                                                                   font-family: "d2-1817135411-font-regular";
                                                                                   font-size: 16px;
                                                                                @@ -843,7 +842,7 @@
                                                                                 .d2-1817135411 .md .contains-task-list:dir(rtl) .task-list-item-checkbox {
                                                                                   margin: 0 -1.6em 0.25em 0.2em;
                                                                                 }
                                                                                -TeleportJust-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

                                                                                Identity Native Proxy

                                                                                +TeleportJust-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

                                                                                Identity Native Proxy

                                                                                Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged diff --git a/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg index b823da1c7..f9b4d1db5 100644 --- a/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/teleport_grid/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3185352814-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-3185352814 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -TeleportJust-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

                                                                                Identity Native Proxy

                                                                                +TeleportJust-in-time Access viaInfrastructureIndentity ProviderEngineersMachinesHTTPS://> kubectl> tsh> apiDB Clients

                                                                                Identity Native Proxy

                                                                                Audit LogCert AuthoritySlackMattermostJiraPagerdutyEmailsshKubernetesMy SQLMongoDBPSQLWindows all connections audited and logged diff --git a/e2etests/testdata/themes/dark_terrastruct_flagship/dagre/sketch.exp.svg b/e2etests/testdata/themes/dark_terrastruct_flagship/dagre/sketch.exp.svg index 9ccbe497e..1dc2c2280 100644 --- a/e2etests/testdata/themes/dark_terrastruct_flagship/dagre/sketch.exp.svg +++ b/e2etests/testdata/themes/dark_terrastruct_flagship/dagre/sketch.exp.svg @@ -149,7 +149,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-85991054-font-regular"; font-size: 16px; @@ -857,7 +856,7 @@ .d2-85991054 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -networkuserapi serverlogsusersidintnamestringemailstringpasswordstringlast_logindatetimeproducts+idint+pricedecimal+skustring+namestring

                                                                                A tale

                                                                                +networkuserapi serverlogsusersidintnamestringemailstringpasswordstringlast_logindatetimeproducts+idint+pricedecimal+skustring+namestring

                                                                                A tale

                                                                                • of
                                                                                • two cities
                                                                                • diff --git a/e2etests/testdata/themes/dark_terrastruct_flagship/elk/sketch.exp.svg b/e2etests/testdata/themes/dark_terrastruct_flagship/elk/sketch.exp.svg index be20c370a..cc0324ffa 100644 --- a/e2etests/testdata/themes/dark_terrastruct_flagship/elk/sketch.exp.svg +++ b/e2etests/testdata/themes/dark_terrastruct_flagship/elk/sketch.exp.svg @@ -149,7 +149,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3004075822-font-regular"; font-size: 16px; @@ -857,7 +856,7 @@ .d2-3004075822 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -networkuserapi serverlogsusersidintnamestringemailstringpasswordstringlast_logindatetimeproducts+idint+pricedecimal+skustring+namestring

                                                                                  A tale

                                                                                  +networkuserapi serverlogsusersidintnamestringemailstringpasswordstringlast_logindatetimeproducts+idint+pricedecimal+skustring+namestring

                                                                                  A tale

                                                                                  • of
                                                                                  • two cities
                                                                                  • diff --git a/e2etests/testdata/themes/terminal/dagre/sketch.exp.svg b/e2etests/testdata/themes/terminal/dagre/sketch.exp.svg index ba9d909e2..4634e5f65 100644 --- a/e2etests/testdata/themes/terminal/dagre/sketch.exp.svg +++ b/e2etests/testdata/themes/terminal/dagre/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1263202776-font-regular"; font-size: 16px; @@ -883,7 +882,7 @@ -NETWORKUSERAPI SERVERLOGSUSERSidintnamestringemailstringpasswordstringlast_logindatetimePRODUCTS+idint+pricedecimal+skustring+namestring

                                                                                    A TALE

                                                                                    +NETWORKUSERAPI SERVERLOGSUSERSidintnamestringemailstringpasswordstringlast_logindatetimePRODUCTS+idint+pricedecimal+skustring+namestring

                                                                                    A TALE

                                                                                    • OF
                                                                                    • TWO CITIES
                                                                                    • diff --git a/e2etests/testdata/themes/terminal/elk/sketch.exp.svg b/e2etests/testdata/themes/terminal/elk/sketch.exp.svg index 19223f112..69733b705 100644 --- a/e2etests/testdata/themes/terminal/elk/sketch.exp.svg +++ b/e2etests/testdata/themes/terminal/elk/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-4226491288-font-regular"; font-size: 16px; @@ -883,7 +882,7 @@ -NETWORKUSERAPI SERVERLOGSUSERSidintnamestringemailstringpasswordstringlast_logindatetimePRODUCTS+idint+pricedecimal+skustring+namestring

                                                                                      A TALE

                                                                                      +NETWORKUSERAPI SERVERLOGSUSERSidintnamestringemailstringpasswordstringlast_logindatetimePRODUCTS+idint+pricedecimal+skustring+namestring

                                                                                      A TALE

                                                                                      • OF
                                                                                      • TWO CITIES
                                                                                      • diff --git a/e2etests/testdata/todo/dagre_container_md_label_panic/dagre/sketch.exp.svg b/e2etests/testdata/todo/dagre_container_md_label_panic/dagre/sketch.exp.svg index 7f08aa30c..76dbf72a3 100644 --- a/e2etests/testdata/todo/dagre_container_md_label_panic/dagre/sketch.exp.svg +++ b/e2etests/testdata/todo/dagre_container_md_label_panic/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3098341505-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-3098341505 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -OEM Factory

                                                                                        company Warehouse

                                                                                        +OEM Factory

                                                                                        company Warehouse

                                                                                        • Asset Tagging
                                                                                        • Inventory
                                                                                        • diff --git a/e2etests/testdata/todo/dagre_container_md_label_panic/elk/sketch.exp.svg b/e2etests/testdata/todo/dagre_container_md_label_panic/elk/sketch.exp.svg index 446e1286b..c94df84f7 100644 --- a/e2etests/testdata/todo/dagre_container_md_label_panic/elk/sketch.exp.svg +++ b/e2etests/testdata/todo/dagre_container_md_label_panic/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1471202586-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1471202586 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -OEM Factory

                                                                                          company Warehouse

                                                                                          +OEM Factory

                                                                                          company Warehouse

                                                                                          • Asset Tagging
                                                                                          • Inventory
                                                                                          • diff --git a/e2etests/testdata/todo/shape_set_width_height/dagre/sketch.exp.svg b/e2etests/testdata/todo/shape_set_width_height/dagre/sketch.exp.svg index 3f971fb83..5320a484e 100644 --- a/e2etests/testdata/todo/shape_set_width_height/dagre/sketch.exp.svg +++ b/e2etests/testdata/todo/shape_set_width_height/dagre/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3326126261-font-regular"; font-size: 16px; @@ -850,7 +849,7 @@ .d2-3326126261 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -containerscloudtall cylinderclass2-numint-timeoutint-pid+getStatus()Enum+getJobs()Job[]+setTimeout(seconds int)voidusersidintnamestringemailstringpasswordstringlast_logindatetimecontainer

                                                                                            markdown text expanded to 800x400

                                                                                            +containerscloudtall cylinderclass2-numint-timeoutint-pid+getStatus()Enum+getJobs()Job[]+setTimeout(seconds int)voidusersidintnamestringemailstringpasswordstringlast_logindatetimecontainer

                                                                                            markdown text expanded to 800x400

                                                                                            := 5 := a + 7 fmt.Printf("%d", b)a := 5 diff --git a/e2etests/testdata/todo/shape_set_width_height/elk/sketch.exp.svg b/e2etests/testdata/todo/shape_set_width_height/elk/sketch.exp.svg index 0fcd82215..c12a36bdb 100644 --- a/e2etests/testdata/todo/shape_set_width_height/elk/sketch.exp.svg +++ b/e2etests/testdata/todo/shape_set_width_height/elk/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-71187753-font-regular"; font-size: 16px; @@ -850,7 +849,7 @@ .d2-71187753 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -containerscloudtall cylinderclass2-numint-timeoutint-pid+getStatus()Enum+getJobs()Job[]+setTimeout(seconds int)voidusersidintnamestringemailstringpasswordstringlast_logindatetimecontainer

                                                                                            markdown text expanded to 800x400

                                                                                            +containerscloudtall cylinderclass2-numint-timeoutint-pid+getStatus()Enum+getJobs()Job[]+setTimeout(seconds int)voidusersidintnamestringemailstringpasswordstringlast_logindatetimecontainer

                                                                                            markdown text expanded to 800x400

                                                                                            := 5 := a + 7 fmt.Printf("%d", b)a := 5 diff --git a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg index 24701726f..04eb5c839 100644 --- a/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-4006266140-font-regular"; font-size: 16px; @@ -829,27 +828,27 @@ .d2-4006266140 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with personal bank accounts

                                                                                            -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with personal bank accounts

                                                                                            -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with personal bank accounts

                                                                                            -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with pekkrsonal bank ccountskks.

                                                                                            -

                                                                                            Personal Banking Customerk

                                                                                            +

                                                                                            Personal Banking Customerk

                                                                                            [person]

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            diff --git a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg index 01c202e6c..6c07ec7b2 100644 --- a/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-label/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2497926651-font-regular"; font-size: 16px; @@ -829,27 +828,27 @@ .d2-2497926651 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with personal bank accounts

                                                                                            -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with personal bank accounts

                                                                                            -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with personal bank accounts

                                                                                            -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with pekkrsonal bank ccountskks.

                                                                                            -

                                                                                            Personal Banking Customerk

                                                                                            +

                                                                                            Personal Banking Customerk

                                                                                            [person]

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with pekkrsonal bank accountskks.

                                                                                            diff --git a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg index 251910a6e..1ad380f87 100644 --- a/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1168851269-font-regular"; font-size: 16px; diff --git a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg index 6305b8c57..3d04164c3 100644 --- a/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1125049512-font-regular"; font-size: 16px; diff --git a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json index b8a4d8dd5..4b80ded31 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/dagre/board.exp.json @@ -3,7 +3,7 @@ "config": { "sketch": false, "themeID": 303, - "darkThemeID": 200, + "darkThemeID": null, "pad": null, "center": null, "layoutEngine": null diff --git a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg index e3cab1bd5..fb2279b45 100644 --- a/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/dagre/sketch.exp.svg @@ -1,20 +1,20 @@ -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with personal bank accounts.

                                                                                            -

                                                                                            Internet Banking System

                                                                                            +

                                                                                            Internet Banking System

                                                                                            [Software System]

                                                                                            -

                                                                                            E-mail System

                                                                                            +

                                                                                            E-mail System

                                                                                            [Software System]

                                                                                            The internal Microsoft Exchange e-mail system.

                                                                                            -

                                                                                            Mainframe Banking System

                                                                                            +

                                                                                            Mainframe Banking System

                                                                                            [Software System]

                                                                                            Stores all of the core banking information about customers, accounts, transactions, etc.

                                                                                            -

                                                                                            Web Application

                                                                                            +

                                                                                            Web Application

                                                                                            [Container: Java and Spring MVC]

                                                                                            Delivers the static content and the Internet banking single page application.

                                                                                            -

                                                                                            Single-Page Application

                                                                                            +

                                                                                            Single-Page Application

                                                                                            [Container: JavaScript and Angular]

                                                                                            Provides all of the Internet banking functionality to customers via their web browser.

                                                                                            -

                                                                                            Mobile App

                                                                                            +

                                                                                            Mobile App

                                                                                            [Container: Xamarin]

                                                                                            Provides a limited subset of the Internet banking functionality to customers via their mobile device.

                                                                                            -

                                                                                            API Application

                                                                                            +

                                                                                            API Application

                                                                                            [Container: Java and Spring MVC]

                                                                                            Provides Internet banking functionality via a JSON/HTTPS API.

                                                                                            -

                                                                                            Database

                                                                                            +

                                                                                            Database

                                                                                            [Container: Oracle Database Schema]

                                                                                            Stores user registration information, hashed authentication credentials, access logs, etc.

                                                                                            -
                                                                                            Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] +
                                                                                            Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] diff --git a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json index a7c6cbe2f..4d6d3ccd8 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/board.exp.json +++ b/e2etests/testdata/txtar/c4-theme/elk/board.exp.json @@ -3,7 +3,7 @@ "config": { "sketch": false, "themeID": 303, - "darkThemeID": 200, + "darkThemeID": null, "pad": null, "center": null, "layoutEngine": null diff --git a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg index d6f366fc8..46f088711 100644 --- a/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/c4-theme/elk/sketch.exp.svg @@ -1,20 +1,20 @@ -

                                                                                            Personal Banking Customer

                                                                                            +

                                                                                            Personal Banking Customer

                                                                                            [person]

                                                                                            A customer of the bank, with personal bank accounts.

                                                                                            -

                                                                                            Internet Banking System

                                                                                            +

                                                                                            Internet Banking System

                                                                                            [Software System]

                                                                                            -

                                                                                            E-mail System

                                                                                            +

                                                                                            E-mail System

                                                                                            [Software System]

                                                                                            The internal Microsoft Exchange e-mail system.

                                                                                            -

                                                                                            Mainframe Banking System

                                                                                            +

                                                                                            Mainframe Banking System

                                                                                            [Software System]

                                                                                            Stores all of the core banking information about customers, accounts, transactions, etc.

                                                                                            -

                                                                                            Web Application

                                                                                            +

                                                                                            Web Application

                                                                                            [Container: Java and Spring MVC]

                                                                                            Delivers the static content and the Internet banking single page application.

                                                                                            -

                                                                                            Single-Page Application

                                                                                            +

                                                                                            Single-Page Application

                                                                                            [Container: JavaScript and Angular]

                                                                                            Provides all of the Internet banking functionality to customers via their web browser.

                                                                                            -

                                                                                            Mobile App

                                                                                            +

                                                                                            Mobile App

                                                                                            [Container: Xamarin]

                                                                                            Provides a limited subset of the Internet banking functionality to customers via their mobile device.

                                                                                            -

                                                                                            API Application

                                                                                            +

                                                                                            API Application

                                                                                            [Container: Java and Spring MVC]

                                                                                            Provides Internet banking functionality via a JSON/HTTPS API.

                                                                                            -

                                                                                            Database

                                                                                            +

                                                                                            Database

                                                                                            [Container: Oracle Database Schema]

                                                                                            Stores user registration information, hashed authentication credentials, access logs, etc.

                                                                                            -
                                                                                            Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] +
                                                                                            Visits bigbank.com/ib using[HTTPS]Delivers to the customer's web browserViews account balances, and makes payments usingViews account balances, and makes payments usingMakes API calls to[JSON/HTTPS]Makes API calls to[JSON/HTTPS]Makes API calls to[XML/HTTPS]Sends e-mails toSends e-mail using Reads from and writes to[SQL/TCP] diff --git a/e2etests/testdata/txtar/dark-theme-md/dagre/sketch.exp.svg b/e2etests/testdata/txtar/dark-theme-md/dagre/sketch.exp.svg index a297d152f..24f2305e8 100644 --- a/e2etests/testdata/txtar/dark-theme-md/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/dark-theme-md/dagre/sketch.exp.svg @@ -193,7 +193,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2914868974-font-regular"; font-size: 16px; @@ -901,7 +900,7 @@ .d2-2914868974 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            hey

                                                                                            +

                                                                                            hey

                                                                                            diff --git a/e2etests/testdata/txtar/dark-theme-md/elk/sketch.exp.svg b/e2etests/testdata/txtar/dark-theme-md/elk/sketch.exp.svg index 6409b8037..bab4d3d33 100644 --- a/e2etests/testdata/txtar/dark-theme-md/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/dark-theme-md/elk/sketch.exp.svg @@ -193,7 +193,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3093086966-font-regular"; font-size: 16px; @@ -901,7 +900,7 @@ .d2-3093086966 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            hey

                                                                                            +

                                                                                            hey

                                                                                            diff --git a/e2etests/testdata/txtar/extended-ascii/dagre/sketch.exp.svg b/e2etests/testdata/txtar/extended-ascii/dagre/sketch.exp.svg index ad52a49f7..194b5f873 100644 --- a/e2etests/testdata/txtar/extended-ascii/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/extended-ascii/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1707443195-font-regular"; font-size: 16px; @@ -829,10 +828,10 @@ .d2-1707443195 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            ÇéþüðæØÅßñò

                                                                                            -

                                                                                            òØõùßÍÿåÆ

                                                                                            -

                                                                                            çÆÐÞ©ßþúí

                                                                                            -

                                                                                            ÉáøÿÑö

                                                                                            +

                                                                                            ÇéþüðæØÅßñò

                                                                                            +

                                                                                            òØõùßÍÿåÆ

                                                                                            +

                                                                                            çÆÐÞ©ßþúí

                                                                                            +

                                                                                            ÉáøÿÑö

                                                                                            diff --git a/e2etests/testdata/txtar/extended-ascii/elk/sketch.exp.svg b/e2etests/testdata/txtar/extended-ascii/elk/sketch.exp.svg index a567f10f4..ecda75aa7 100644 --- a/e2etests/testdata/txtar/extended-ascii/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/extended-ascii/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1588638235-font-regular"; font-size: 16px; @@ -829,10 +828,10 @@ .d2-1588638235 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            ÇéþüðæØÅßñò

                                                                                            -

                                                                                            òØõùßÍÿåÆ

                                                                                            -

                                                                                            çÆÐÞ©ßþúí

                                                                                            -

                                                                                            ÉáøÿÑö

                                                                                            +

                                                                                            ÇéþüðæØÅßñò

                                                                                            +

                                                                                            òØõùßÍÿåÆ

                                                                                            +

                                                                                            çÆÐÞ©ßþúí

                                                                                            +

                                                                                            ÉáøÿÑö

                                                                                            diff --git a/e2etests/testdata/txtar/md-label/dagre/sketch.exp.svg b/e2etests/testdata/txtar/md-label/dagre/sketch.exp.svg index ec78bb5e4..e7d517e10 100644 --- a/e2etests/testdata/txtar/md-label/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/md-label/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1825138808-font-regular"; font-size: 16px; @@ -829,87 +828,87 @@ .d2-1825138808 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world
                                                                                            diff --git a/e2etests/testdata/txtar/md-label/elk/sketch.exp.svg b/e2etests/testdata/txtar/md-label/elk/sketch.exp.svg index 4f349e4dd..85a829529 100644 --- a/e2etests/testdata/txtar/md-label/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/md-label/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1030734791-font-regular"; font-size: 16px; @@ -829,87 +828,87 @@ .d2-1030734791 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world

                                                                                            blah blah

                                                                                            -

                                                                                            hello

                                                                                            +

                                                                                            hello

                                                                                            • world
                                                                                            diff --git a/e2etests/testdata/txtar/md-tables/dagre/sketch.exp.svg b/e2etests/testdata/txtar/md-tables/dagre/sketch.exp.svg index 1ab58f720..39d31759f 100644 --- a/e2etests/testdata/txtar/md-tables/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/md-tables/dagre/sketch.exp.svg @@ -134,7 +134,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1180799665-font-regular"; font-size: 16px; @@ -842,7 +841,7 @@ .d2-1180799665 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                                                                            +
                                                                                            @@ -872,7 +871,7 @@
                                                                                            Month
                                                                                            -
                                                                                            +
                                                                                            @@ -890,7 +889,7 @@
                                                                                            Status
                                                                                            -
                                                                                            +
                                                                                            @@ -934,7 +933,7 @@
                                                                                            Metric
                                                                                            Financial Overview -System HealthProject TrackingTeam Analytics
                                                                                            +System HealthProject TrackingTeam Analytics
                                                                                            @@ -964,7 +963,7 @@
                                                                                            Month
                                                                                            -
                                                                                            +
                                                                                            @@ -988,7 +987,7 @@
                                                                                            Quarter
                                                                                            -
                                                                                            +
                                                                                            @@ -1018,7 +1017,7 @@
                                                                                            Service
                                                                                            -
                                                                                            +
                                                                                            @@ -1048,7 +1047,7 @@
                                                                                            Metric
                                                                                            -
                                                                                            +
                                                                                            @@ -1082,7 +1081,7 @@
                                                                                            Project
                                                                                            -
                                                                                            +
                                                                                            @@ -1112,7 +1111,7 @@
                                                                                            Risk ID
                                                                                            -
                                                                                            +
                                                                                            diff --git a/e2etests/testdata/txtar/md-tables/elk/sketch.exp.svg b/e2etests/testdata/txtar/md-tables/elk/sketch.exp.svg index 1665ba5f7..77b317076 100644 --- a/e2etests/testdata/txtar/md-tables/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/md-tables/elk/sketch.exp.svg @@ -134,7 +134,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3839636311-font-regular"; font-size: 16px; @@ -842,7 +841,7 @@ .d2-3839636311 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -
                                                                                            Sprint
                                                                                            +
                                                                                            @@ -872,7 +871,7 @@
                                                                                            Month
                                                                                            -
                                                                                            +
                                                                                            @@ -890,7 +889,7 @@
                                                                                            Status
                                                                                            -
                                                                                            +
                                                                                            @@ -934,7 +933,7 @@
                                                                                            Metric
                                                                                            Financial Overview -System HealthProject TrackingTeam Analytics
                                                                                            +System HealthProject TrackingTeam Analytics
                                                                                            @@ -964,7 +963,7 @@
                                                                                            Month
                                                                                            -
                                                                                            +
                                                                                            @@ -988,7 +987,7 @@
                                                                                            Quarter
                                                                                            -
                                                                                            +
                                                                                            @@ -1018,7 +1017,7 @@
                                                                                            Service
                                                                                            -
                                                                                            +
                                                                                            @@ -1048,7 +1047,7 @@
                                                                                            Metric
                                                                                            -
                                                                                            +
                                                                                            @@ -1082,7 +1081,7 @@
                                                                                            Project
                                                                                            -
                                                                                            +
                                                                                            @@ -1112,7 +1111,7 @@
                                                                                            Risk ID
                                                                                            -
                                                                                            +
                                                                                            diff --git a/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/sketch.exp.svg b/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/sketch.exp.svg index 9ebd14667..396afe4f4 100644 --- a/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2097271006-font-regular"; font-size: 16px; @@ -850,7 +849,7 @@ .d2-2097271006 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -xy hello

                                                                                            A man who fishes for marlin in ponds

                                                                                            +xy hello

                                                                                            A man who fishes for marlin in ponds

                                                                                            • ...dramatic pause
                                                                                            diff --git a/e2etests/testdata/txtar/sequence-diagram-note-md/elk/sketch.exp.svg b/e2etests/testdata/txtar/sequence-diagram-note-md/elk/sketch.exp.svg index 9ebd14667..396afe4f4 100644 --- a/e2etests/testdata/txtar/sequence-diagram-note-md/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/sequence-diagram-note-md/elk/sketch.exp.svg @@ -142,7 +142,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2097271006-font-regular"; font-size: 16px; @@ -850,7 +849,7 @@ .d2-2097271006 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -xy hello

                                                                                            A man who fishes for marlin in ponds

                                                                                            +xy hello

                                                                                            A man who fishes for marlin in ponds

                                                                                            • ...dramatic pause
                                                                                            diff --git a/e2etests/testdata/txtar/sql-icon/dagre/sketch.exp.svg b/e2etests/testdata/txtar/sql-icon/dagre/sketch.exp.svg index 706b867d0..64a04313d 100644 --- a/e2etests/testdata/txtar/sql-icon/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/sql-icon/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-826738456-font-regular"; font-size: 16px; @@ -843,9 +842,9 @@ .d2-826738456 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -withoutwithtableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            +withoutwithtableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            You will live a long, healthy, happy life and make bags of money.

                                                                                            -
                                                                                            tableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            +
                                                                                            tableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            You will live a long, healthy, happy life and make bags of money.

                                                                                            diff --git a/e2etests/testdata/txtar/sql-icon/elk/sketch.exp.svg b/e2etests/testdata/txtar/sql-icon/elk/sketch.exp.svg index 2044c42c1..8f27c2e08 100644 --- a/e2etests/testdata/txtar/sql-icon/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/sql-icon/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3895587399-font-regular"; font-size: 16px; @@ -843,9 +842,9 @@ .d2-3895587399 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -withoutwithtableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            +withoutwithtableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            You will live a long, healthy, happy life and make bags of money.

                                                                                            -
                                                                                            tableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            +
                                                                                            tableExabclassEx+ab:= 1a := 1

                                                                                            This is for all ill-treated fellows

                                                                                            You will live a long, healthy, happy life and make bags of money.

                                                                                            diff --git a/e2etests/testdata/txtar/unicode/dagre/sketch.exp.svg b/e2etests/testdata/txtar/unicode/dagre/sketch.exp.svg index b58bc204d..2154cc52a 100644 --- a/e2etests/testdata/txtar/unicode/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/unicode/dagre/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2855145504-font-regular"; font-size: 16px; @@ -829,18 +828,18 @@ .d2-2855145504 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            ■ foo bar

                                                                                            -

                                                                                            □ foo bar

                                                                                            -

                                                                                            ● foo bar

                                                                                            -

                                                                                            ○ foo bar

                                                                                            -

                                                                                            ◆ foo bar

                                                                                            -

                                                                                            ◇ foo bar

                                                                                            -

                                                                                            ▲ foo bar

                                                                                            -

                                                                                            △ foo bar

                                                                                            -

                                                                                            ▼ foo bar

                                                                                            -

                                                                                            ▽ foo bar

                                                                                            -

                                                                                            ※ foo bar

                                                                                            -

                                                                                            ◎ foo bar

                                                                                            +

                                                                                            ■ foo bar

                                                                                            +

                                                                                            □ foo bar

                                                                                            +

                                                                                            ● foo bar

                                                                                            +

                                                                                            ○ foo bar

                                                                                            +

                                                                                            ◆ foo bar

                                                                                            +

                                                                                            ◇ foo bar

                                                                                            +

                                                                                            ▲ foo bar

                                                                                            +

                                                                                            △ foo bar

                                                                                            +

                                                                                            ▼ foo bar

                                                                                            +

                                                                                            ▽ foo bar

                                                                                            +

                                                                                            ※ foo bar

                                                                                            +

                                                                                            ◎ foo bar

                                                                                            diff --git a/e2etests/testdata/txtar/unicode/elk/sketch.exp.svg b/e2etests/testdata/txtar/unicode/elk/sketch.exp.svg index fb1d9c406..70bcda3cd 100644 --- a/e2etests/testdata/txtar/unicode/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/unicode/elk/sketch.exp.svg @@ -121,7 +121,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2037265600-font-regular"; font-size: 16px; @@ -829,18 +828,18 @@ .d2-2037265600 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            ■ foo bar

                                                                                            -

                                                                                            □ foo bar

                                                                                            -

                                                                                            ● foo bar

                                                                                            -

                                                                                            ○ foo bar

                                                                                            -

                                                                                            ◆ foo bar

                                                                                            -

                                                                                            ◇ foo bar

                                                                                            -

                                                                                            ▲ foo bar

                                                                                            -

                                                                                            △ foo bar

                                                                                            -

                                                                                            ▼ foo bar

                                                                                            -

                                                                                            ▽ foo bar

                                                                                            -

                                                                                            ※ foo bar

                                                                                            -

                                                                                            ◎ foo bar

                                                                                            +

                                                                                            ■ foo bar

                                                                                            +

                                                                                            □ foo bar

                                                                                            +

                                                                                            ● foo bar

                                                                                            +

                                                                                            ○ foo bar

                                                                                            +

                                                                                            ◆ foo bar

                                                                                            +

                                                                                            ◇ foo bar

                                                                                            +

                                                                                            ▲ foo bar

                                                                                            +

                                                                                            △ foo bar

                                                                                            +

                                                                                            ▼ foo bar

                                                                                            +

                                                                                            ▽ foo bar

                                                                                            +

                                                                                            ※ foo bar

                                                                                            +

                                                                                            ◎ foo bar

                                                                                            diff --git a/e2etests/testdata/txtar/var_in_markdown/dagre/sketch.exp.svg b/e2etests/testdata/txtar/var_in_markdown/dagre/sketch.exp.svg index 784187af7..0415cf700 100644 --- a/e2etests/testdata/txtar/var_in_markdown/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/var_in_markdown/dagre/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2758569173-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-2758569173 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -Kube

                                                                                            Kube is a service

                                                                                            +Kube

                                                                                            Kube is a service

                                                                                            Let ${y} be ${x}
                                                                                             
                                                                                            ba diff --git a/e2etests/testdata/txtar/var_in_markdown/elk/sketch.exp.svg b/e2etests/testdata/txtar/var_in_markdown/elk/sketch.exp.svg index c1f320e40..cac976c17 100644 --- a/e2etests/testdata/txtar/var_in_markdown/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/var_in_markdown/elk/sketch.exp.svg @@ -135,7 +135,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-3193381320-font-regular"; font-size: 16px; @@ -843,7 +842,7 @@ .d2-3193381320 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -Kube

                                                                                            Kube is a service

                                                                                            +Kube

                                                                                            Kube is a service

                                                                                            Let ${y} be ${x}
                                                                                             
                                                                                            ba diff --git a/e2etests/testdata/unicode/chinese/dagre/sketch.exp.svg b/e2etests/testdata/unicode/chinese/dagre/sketch.exp.svg index 12fccda37..170363eda 100644 --- a/e2etests/testdata/unicode/chinese/dagre/sketch.exp.svg +++ b/e2etests/testdata/unicode/chinese/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2865261911-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-2865261911 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            床前明月光,

                                                                                            +

                                                                                            床前明月光,

                                                                                            疑是地上霜。

                                                                                            举头望明月,

                                                                                            低头思故乡。

                                                                                            diff --git a/e2etests/testdata/unicode/chinese/elk/sketch.exp.svg b/e2etests/testdata/unicode/chinese/elk/sketch.exp.svg index dd1d64083..cb250c0ce 100644 --- a/e2etests/testdata/unicode/chinese/elk/sketch.exp.svg +++ b/e2etests/testdata/unicode/chinese/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-1123938073-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-1123938073 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -

                                                                                            床前明月光,

                                                                                            +

                                                                                            床前明月光,

                                                                                            疑是地上霜。

                                                                                            举头望明月,

                                                                                            低头思故乡。

                                                                                            diff --git a/e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg b/e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg index 241e39a4c..764cc9f0b 100644 --- a/e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg +++ b/e2etests/testdata/unicode/mixed-language/dagre/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-2872220387-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-2872220387 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -有一个叫做夏天的季节。 ある季節、夏という名前がついています。한 계절, 여름이란 이름이 있습니다.夏天的时候,天气非常热,人们总是流着汗。

                                                                                            夏になると、とても暑くて、人々は汗を流しています。

                                                                                            +有一个叫做夏天的季节。 ある季節、夏という名前がついています。한 계절, 여름이란 이름이 있습니다.夏天的时候,天气非常热,人们总是流着汗。

                                                                                            夏になると、とても暑くて、人々は汗を流しています。

                                                                                            여름에는 매우 더워서 사람들은 땀을 흘립니다.

                                                                                            diff --git a/e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg b/e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg index cc489394d..fb4388fa5 100644 --- a/e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg +++ b/e2etests/testdata/unicode/mixed-language/elk/sketch.exp.svg @@ -128,7 +128,6 @@ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; margin: 0; - color: var(--color-fg-default); background-color: transparent; /* we don't want to define the background color */ font-family: "d2-40175756-font-regular"; font-size: 16px; @@ -836,7 +835,7 @@ .d2-40175756 .md .contains-task-list:dir(rtl) .task-list-item-checkbox { margin: 0 -1.6em 0.25em 0.2em; } -有一个叫做夏天的季节。 ある季節、夏という名前がついています。한 계절, 여름이란 이름이 있습니다.夏天的时候,天气非常热,人们总是流着汗。

                                                                                            夏になると、とても暑くて、人々は汗を流しています。

                                                                                            +有一个叫做夏天的季节。 ある季節、夏という名前がついています。한 계절, 여름이란 이름이 있습니다.夏天的时候,天气非常热,人们总是流着汗。

                                                                                            夏になると、とても暑くて、人々は汗を流しています。

                                                                                            여름에는 매우 더워서 사람들은 땀을 흘립니다.

                                                                                            diff --git a/e2etests/txtar.txt b/e2etests/txtar.txt index a9b843e26..ac940b683 100644 --- a/e2etests/txtar.txt +++ b/e2etests/txtar.txt @@ -1161,103 +1161,3 @@ customer4: |md | { shape: c4-person } - --- c4-theme -- -vars: { - d2-config: { - theme-id: 303 - dark-theme-id: 200 - } -} - -customer: |md - ## Personal Banking Customer - [person] - - A customer of the bank, with personal bank accounts. -| { - shape: c4-person -} - -internet_banking_system: |md - ## Internet Banking System - [Software System] -| { - shape: rectangle - label.near: bottom-left -} - -internet_banking_system.web_app: |md - ## Web Application - [Container: Java and Spring MVC] - - Delivers the static content and the Internet banking single page application. -| { - shape: rectangle -} - -internet_banking_system.spa: |md - ## Single-Page Application - [Container: JavaScript and Angular] - - Provides all of the Internet banking functionality to customers via their web browser. -| { - shape: rectangle -} - -internet_banking_system.mobile_app: |md - ## Mobile App - [Container: Xamarin] - - Provides a limited subset of the Internet banking functionality to customers via their mobile device. -| { - shape: rectangle -} - -internet_banking_system.api_app: |md - ## API Application - [Container: Java and Spring MVC] - - Provides Internet banking functionality via a JSON/HTTPS API. -| { - shape: rectangle -} - -internet_banking_system.database: |md - ## Database - [Container: Oracle Database Schema] - - Stores user registration information, hashed authentication credentials, access logs, etc. -| { - shape: rectangle -} - -email_system: |md - ## E-mail System - [Software System] - - The internal Microsoft Exchange e-mail system. -| { - shape: rectangle -} - -mainframe: |md - ## Mainframe Banking System - [Software System] - - Stores all of the core banking information about customers, accounts, transactions, etc. -| { - shape: rectangle -} - -# Connections -customer -> internet_banking_system.web_app: "Visits bigbank.com/ib using\n[HTTPS]" -internet_banking_system.web_app -> internet_banking_system.spa: "Delivers to the customer's web browser" -customer -> internet_banking_system.spa: "Views account balances, and makes payments using" -customer -> internet_banking_system.mobile_app: "Views account balances, and makes payments using" -internet_banking_system.spa -> internet_banking_system.api_app: "Makes API calls to\n[JSON/HTTPS]" -internet_banking_system.mobile_app -> internet_banking_system.api_app: "Makes API calls to\n[JSON/HTTPS]" -internet_banking_system.api_app -> mainframe: "Makes API calls to\n[XML/HTTPS]" -customer -> email_system: "Sends e-mails to" -internet_banking_system.api_app -> email_system: "Sends e-mail using" -internet_banking_system.database <-> internet_banking_system.api_app: "Reads from and writes to\n[SQL/TCP]" From 2aed1f44cd54ce2e3fd5a9badccc64aa1570d14d Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 20 Mar 2025 09:53:24 -0600 Subject: [PATCH 36/54] d2ir: allow root URL paths --- d2compiler/compile.go | 2 +- d2compiler/compile_test.go | 16 ++ d2ir/compile.go | 4 +- .../TestCompile/url_relative_link.exp.json | 148 ++++++++++++++++++ 4 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 testdata/d2compiler/TestCompile/url_relative_link.exp.json diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 97f55f4a1..34e49c383 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -1265,7 +1265,7 @@ func (c *compiler) validateBoardLinks(g *d2graph.Graph) { } u, err := url.Parse(html.UnescapeString(obj.Link.Value)) - isRemote := err == nil && u.Scheme != "" + isRemote := err == nil && (u.Scheme != "" || strings.HasPrefix(u.Path, "/")) if isRemote { continue } diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 47183fe9c..c64c18919 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -1658,6 +1658,22 @@ x -> y: { } }, }, + { + name: "url_relative_link", + + text: `x: { + link: /google +} +`, + assertions: func(t *testing.T, g *d2graph.Graph) { + if len(g.Objects) != 1 { + t.Fatal(g.Objects) + } + if g.Objects[0].Link.Value != "/google" { + t.Fatal(g.Objects[0].Link.Value) + } + }, + }, { name: "non_url_link", diff --git a/d2ir/compile.go b/d2ir/compile.go index a239862a8..82f3559d1 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -1146,7 +1146,7 @@ func (c *compiler) extendLinks(m *Map, importF *Field, importDir string) { val := f.Primary().Value.ScalarString() u, err := url.Parse(html.UnescapeString(val)) - isRemote := err == nil && u.Scheme != "" + isRemote := err == nil && (u.Scheme != "" || strings.HasPrefix(u.Path, "/")) if isRemote { continue } @@ -1184,7 +1184,7 @@ func (c *compiler) extendLinks(m *Map, importF *Field, importDir string) { continue } u, err := url.Parse(html.UnescapeString(val)) - isRemoteImg := err == nil && u.Scheme != "" + isRemoteImg := err == nil && (u.Scheme != "" || strings.HasPrefix(u.Path, "/")) if isRemoteImg { continue } diff --git a/testdata/d2compiler/TestCompile/url_relative_link.exp.json b/testdata/d2compiler/TestCompile/url_relative_link.exp.json new file mode 100644 index 000000000..a781e613f --- /dev/null +++ b/testdata/d2compiler/TestCompile/url_relative_link.exp.json @@ -0,0 +1,148 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,0:0:0-3:0:23", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,0:0:0-2:1:22", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,0:3:3-2:1:22", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,1:2:7-1:15:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,1:2:7-1:6:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,1:2:7-1:6:11", + "value": [ + { + "string": "link", + "raw_string": "link" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,1:8:13-1:15:20", + "value": [ + { + "string": "/google", + "raw_string": "/google" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "x", + "id_val": "x", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/url_relative_link.d2,0:0:0-0:1:1", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "x" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "link": { + "value": "/google" + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} From 0e269b7de84016a3dc558e025b053386c86c4b34 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 20 Mar 2025 09:54:57 -0600 Subject: [PATCH 37/54] next --- ci/release/changelogs/next.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 577b13d0e..e42b8be2a 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -28,6 +28,8 @@ - d2cli: - Support `validate` command. [#2415](https://github.com/terrastruct/d2/pull/2415) +- d2compiler: + - `link`s can be set to root path, e.g. `/xyz`. [#2357](https://github.com/terrastruct/d2/issues/2357) #### Bugfixes ⛑️ From 0067298fe7466d56623d8183ac15b07ff67cd038 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Tue, 11 Feb 2025 10:33:59 -0700 Subject: [PATCH 38/54] cli: ignore watch events from backup files --- d2cli/watch.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/d2cli/watch.go b/d2cli/watch.go index 6c240a711..f34dd0a1a 100644 --- a/d2cli/watch.go +++ b/d2cli/watch.go @@ -264,6 +264,12 @@ func (w *watcher) watchLoop(ctx context.Context) error { return errors.New("fsnotify watcher closed") } w.ms.Log.Debug.Printf("received file system event %v", ev) + + if isTemp, reason := isBackupFile(ev.Name); isTemp { + w.ms.Log.Debug.Printf("skipping event for %q: detected as %s", w.ms.HumanPath(ev.Name), reason) + continue + } + mt, err := w.ensureAddWatch(ctx, ev.Name) if err != nil { return err @@ -349,6 +355,11 @@ func (w *watcher) ensureAddWatch(ctx context.Context, path string) (time.Time, e } func (w *watcher) addWatch(ctx context.Context, path string) (time.Time, error) { + if isTemp, reason := isBackupFile(path); isTemp { + w.ms.Log.Debug.Printf("skipping watch for %q: detected as %s", w.ms.HumanPath(path), reason) + return time.Time{}, nil + } + err := w.fw.Add(path) if err != nil { return time.Time{}, err @@ -671,3 +682,41 @@ func (tfs *trackedFS) Open(name string) (fs.File, error) { } return f, err } + +func isBackupFile(path string) (bool, string) { + ext := filepath.Ext(path) + baseName := filepath.Base(path) + + // This list is based off of https://github.com/gohugoio/hugo/blob/master/commands/hugobuilder.go#L795 + switch { + case strings.HasSuffix(ext, "~"): + return true, "generic backup file (~)" + case ext == ".swp": + return true, "vim swap file" + case ext == ".swx": + return true, "vim swap file" + case ext == ".tmp": + return true, "generic temp file" + case ext == ".DS_Store": + return true, "OSX thumbnail" + case ext == ".bck": + return true, "Helix backup" + case baseName == "4913": + return true, "vim temp file" + case strings.HasPrefix(ext, ".goutputstream"): + return true, "GNOME temp file" + case strings.HasSuffix(ext, "jb_old___"): + return true, "IntelliJ old backup" + case strings.HasSuffix(ext, "jb_tmp___"): + return true, "IntelliJ temp file" + case strings.HasSuffix(ext, "jb_bak___"): + return true, "IntelliJ backup" + case strings.HasPrefix(ext, ".sb-"): + return true, "Byword temp file" + case strings.HasPrefix(baseName, ".#"): + return true, "Emacs lock file" + case strings.HasPrefix(baseName, "#"): + return true, "Emacs temp file" + } + return false, "" +} From 7d070d2ca1bc371832f458d861fba0c6180a0efd Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 20 Mar 2025 19:46:46 -0600 Subject: [PATCH 39/54] next --- ci/release/changelogs/next.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index e42b8be2a..9efcc4cc1 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -28,6 +28,7 @@ - d2cli: - Support `validate` command. [#2415](https://github.com/terrastruct/d2/pull/2415) + - Watch mode ignores backup files (e.g. files created by certain editors like Helix). [#2131](https://github.com/terrastruct/d2/issues/2131) - d2compiler: - `link`s can be set to root path, e.g. `/xyz`. [#2357](https://github.com/terrastruct/d2/issues/2357) From 7bd7604b8639454257a4b3f5fb5bf0c416932cc8 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 20 Mar 2025 20:27:17 -0600 Subject: [PATCH 40/54] update changelog --- ci/release/changelogs/next.md | 20 ++++---------------- ci/release/changelogs/template.md | 4 ++++ d2js/js/CHANGELOG.md | 21 ++++++++++++++++++++- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 9efcc4cc1..2c16f2451 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -10,22 +10,6 @@ #### Improvements 🧹 -- d2js: - - Support `d2-config`. Support additional options: [#2343](https://github.com/terrastruct/d2/pull/2343) - - `themeID` - - `darkThemeID` - - `center` - - `pad` - - `scale` - - `forceAppendix` - - `target` - - `animateInterval` - - `salt` - - `noXMLTag` - - Support relative imports. Improve elk error handling: [#2382](https://github.com/terrastruct/d2/pull/2382) - - Support fonts (`fontRegular`, `fontItalic`, `fontBold`, `fontSemiBold`): [#2384](https://github.com/terrastruct/d2/pull/2384) - - Add TypeScript signatures - - d2cli: - Support `validate` command. [#2415](https://github.com/terrastruct/d2/pull/2415) - Watch mode ignores backup files (e.g. files created by certain editors like Helix). [#2131](https://github.com/terrastruct/d2/issues/2131) @@ -42,3 +26,7 @@ - fixes inconsistencies when objects were double quoted [#2390](https://github.com/terrastruct/d2/pull/2390) - CLI: fetch and render remote images of mimetype octet-stream correctly [#2370](https://github.com/terrastruct/d2/pull/2370) - d2js: handle unicode characters [#2393](https://github.com/terrastruct/d2/pull/2393) + +--- + +For the latest d2.js changes, see separate [changelog](https://github.com/terrastruct/d2/blob/master/d2js/js/CHANGELOG.md). diff --git a/ci/release/changelogs/template.md b/ci/release/changelogs/template.md index f3c0d2a77..65780a72c 100644 --- a/ci/release/changelogs/template.md +++ b/ci/release/changelogs/template.md @@ -3,3 +3,7 @@ #### Improvements 🧹 #### Bugfixes ⛑️ + +--- + +For the latest d2.js changes, see separate [changelog](https://github.com/terrastruct/d2/blob/master/d2js/js/CHANGELOG.md). diff --git a/d2js/js/CHANGELOG.md b/d2js/js/CHANGELOG.md index 542c51629..8ca55ec1f 100644 --- a/d2js/js/CHANGELOG.md +++ b/d2js/js/CHANGELOG.md @@ -3,6 +3,25 @@ All notable changes to only the d2.js package will be documented in this file. **Does not include changes to the main d2 project.** -## [0.1.0] - 2025-01-12 +## [0.1.22] +### March 20, 2025 + +- Support `d2-config`. Support additional options. [#2343](https://github.com/terrastruct/d2/pull/2343) + - `themeID` + - `darkThemeID` + - `center` + - `pad` + - `scale` + - `forceAppendix` + - `target` + - `animateInterval` + - `salt` + - `noXMLTag` +- Support relative imports. Improve elk error handling [#2382](https://github.com/terrastruct/d2/pull/2382) +- Support fonts (`fontRegular`, `fontItalic`, `fontBold`, `fontSemiBold`) [#2384](https://github.com/terrastruct/d2/pull/2384) +- Add TypeScript signatures + +## [0.1.21] +### January 12, 2025 First public release From c94605551170a6148bcfa0477d3c280c2e8a0924 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 20 Mar 2025 21:56:41 -0600 Subject: [PATCH 41/54] d2js ci --- .github/workflows/daily.yml | 18 ++++++++++++++++++ d2js/js/README.md | 10 ++++++++++ d2js/js/ci/build.sh | 30 ++++++++++++++++++++++++++++++ d2js/js/package.json | 2 +- 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index 1a7075a1f..1275cfb66 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -25,3 +25,21 @@ jobs: with: name: d2chaos path: ./d2chaos/out + npm-nightly: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Needed for git history and version tags + + - uses: actions/setup-go@v4 + with: + go-version-file: ./go.mod + cache: true + + - name: Publish nightly version to NPM + run: COLOR=1 PUBLISH=1 ./make.sh js + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }} + DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} diff --git a/d2js/js/README.md b/d2js/js/README.md index 55cb9e159..4cf7cf016 100644 --- a/d2js/js/README.md +++ b/d2js/js/README.md @@ -162,6 +162,16 @@ You can browse the examples by running the dev server: Visit `http://localhost:3000` to see the example page. +### Publishing + +WIP. + +Nightly builds are automated by CI upon pull request merging by running: + +```bash +PUBLISH=1 ./make.sh build +``` + ## Contributing Contributions are welcome! diff --git a/d2js/js/ci/build.sh b/d2js/js/ci/build.sh index f081d8e4f..3d78c0433 100755 --- a/d2js/js/ci/build.sh +++ b/d2js/js/ci/build.sh @@ -17,3 +17,33 @@ fi cd d2js/js sh_c bun build.js + +if [ "${PUBLISH:-0}" = "1" ]; then + echo "Publishing nightly version to NPM..." + + DATE_TAG=$(date +'%Y%m%d') + COMMIT_SHORT=$(git rev-parse --short HEAD) + CURRENT_VERSION=$(node -p "require('./package.json').version") + NIGHTLY_VERSION="${CURRENT_VERSION}-nightly.${DATE_TAG}.${COMMIT_SHORT}" + + cp package.json package.json.bak + trap 'rm -f .npmrc; mv package.json.bak package.json' EXIT + + echo "Updating package version to ${NIGHTLY_VERSION}" + npm version "${NIGHTLY_VERSION}" --no-git-tag-version + + echo "Publishing to npm with tag 'nightly'..." + if [ -n "${NPM_TOKEN-}" ]; then + echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc + trap 'rm -f .npmrc' EXIT + if npm publish --tag nightly; then + echo "Successfully published @terrastruct/d2@${NIGHTLY_VERSION} to npm with tag 'nightly'" + else + echoerr "Failed to publish package to npm" + exit 1 + fi + else + echoerr "NPM_TOKEN environment variable is required for publishing to npm" + exit 1 + fi +fi diff --git a/d2js/js/package.json b/d2js/js/package.json index a876c24be..0c3f84c6c 100644 --- a/d2js/js/package.json +++ b/d2js/js/package.json @@ -41,7 +41,7 @@ "test:integration": "bun test test/integration", "test:all": "bun run test && bun run test:integration", "dev": "bun --watch dev-server.js", - "prepublishOnly": "./make.sh all" + "prepublishOnly": "PUBLISH=0 ./make.sh all" }, "keywords": [ "d2", From 36df3344a3b69d165752345d68a855c8247dafdb Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 20 Mar 2025 22:01:56 -0600 Subject: [PATCH 42/54] run daily --- .github/workflows/daily.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index 1275cfb66..1e259799c 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -32,12 +32,25 @@ jobs: with: fetch-depth: 0 # Needed for git history and version tags + - name: Check for changes + id: check_changes + run: | + if [ $(git rev-list --count --since="24 hours ago" HEAD) -gt 0 ]; then + echo "has_changes=true" >> $GITHUB_OUTPUT + echo "Found changes in the last 24 hours, proceeding to publish d2js nightly" + else + echo "has_changes=false" >> $GITHUB_OUTPUT + echo "No changes in the last 24 hours, skipping d2js nightly publish" + fi + - uses: actions/setup-go@v4 + if: steps.check_changes.outputs.has_changes == 'true' with: go-version-file: ./go.mod cache: true - name: Publish nightly version to NPM + if: steps.check_changes.outputs.has_changes == 'true' run: COLOR=1 PUBLISH=1 ./make.sh js env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} From 3536f9846adfb89643f73164fc54b716ddfdf838 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 20 Mar 2025 22:02:49 -0600 Subject: [PATCH 43/54] update readme --- d2js/js/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/d2js/js/README.md b/d2js/js/README.md index 4cf7cf016..bb3166849 100644 --- a/d2js/js/README.md +++ b/d2js/js/README.md @@ -164,9 +164,9 @@ Visit `http://localhost:3000` to see the example page. ### Publishing -WIP. +TODO stable release publishing. -Nightly builds are automated by CI upon pull request merging by running: +Nightly builds are automated by CI by running: ```bash PUBLISH=1 ./make.sh build From e073d06b39039016c1c09c5d3c9e1f9dce0dcad9 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 20 Mar 2025 22:03:37 -0600 Subject: [PATCH 44/54] bump version --- d2js/js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/d2js/js/package.json b/d2js/js/package.json index 0c3f84c6c..4775805e0 100644 --- a/d2js/js/package.json +++ b/d2js/js/package.json @@ -2,7 +2,7 @@ "name": "@terrastruct/d2", "author": "Terrastruct, Inc.", "description": "D2.js is a wrapper around the WASM build of D2, the modern text-to-diagram language.", - "version": "0.1.21", + "version": "0.1.22", "repository": { "type": "git", "url": "git+https://github.com/terrastruct/d2.git", From bb5b0224cba89a042f43937dc24976379591704a Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 20 Mar 2025 22:06:46 -0600 Subject: [PATCH 45/54] readme --- d2js/js/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/d2js/js/README.md b/d2js/js/README.md index bb3166849..76f0132f3 100644 --- a/d2js/js/README.md +++ b/d2js/js/README.md @@ -29,6 +29,16 @@ pnpm add @terrastruct/d2 bun add @terrastruct/d2 ``` +### Nightly + +Use the `@nightly` tag to get the version that is built by daily CI on the master branch. + +For example, + +```bash +yarn add @terrastruct/d2@nightly +``` + ## Usage D2.js uses webworkers to call a WASM file. From 6e5d4c77d41f19d7f7c776262f8275f7aa5170a2 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 21 Mar 2025 10:04:48 -0600 Subject: [PATCH 46/54] change env var to flag --- .github/workflows/daily.yml | 2 +- d2js/js/ci/build.sh | 54 +++++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index 1e259799c..0738b8b75 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -51,7 +51,7 @@ jobs: - name: Publish nightly version to NPM if: steps.check_changes.outputs.has_changes == 'true' - run: COLOR=1 PUBLISH=1 ./make.sh js + run: COLOR=1 ./make.sh --version=nightly js env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }} diff --git a/d2js/js/ci/build.sh b/d2js/js/ci/build.sh index 3d78c0433..7d8771bfd 100755 --- a/d2js/js/ci/build.sh +++ b/d2js/js/ci/build.sh @@ -18,26 +18,52 @@ fi cd d2js/js sh_c bun build.js -if [ "${PUBLISH:-0}" = "1" ]; then - echo "Publishing nightly version to NPM..." - - DATE_TAG=$(date +'%Y%m%d') - COMMIT_SHORT=$(git rev-parse --short HEAD) - CURRENT_VERSION=$(node -p "require('./package.json').version") - NIGHTLY_VERSION="${CURRENT_VERSION}-nightly.${DATE_TAG}.${COMMIT_SHORT}" - +if [ -n "$VERSION" ]; then cp package.json package.json.bak trap 'rm -f .npmrc; mv package.json.bak package.json' EXIT - echo "Updating package version to ${NIGHTLY_VERSION}" - npm version "${NIGHTLY_VERSION}" --no-git-tag-version + if [ "$VERSION" = "nightly" ]; then + echo "Publishing nightly version to npm..." - echo "Publishing to npm with tag 'nightly'..." + DATE_TAG=$(date +'%Y%m%d') + COMMIT_SHORT=$(git rev-parse --short HEAD) + CURRENT_VERSION=$(node -p "require('./package.json').version") + PUBLISH_VERSION="${CURRENT_VERSION}-nightly.${DATE_TAG}.${COMMIT_SHORT}" + NPM_TAG="nightly" + + echo "Updating package version to ${PUBLISH_VERSION}" + else + echo "Publishing official version ${VERSION} to npm..." + PUBLISH_VERSION="$VERSION" + NPM_TAG="latest" + + echo "Setting package version to ${PUBLISH_VERSION}" + fi + + # Update package.json with the new version + npm version "${PUBLISH_VERSION}" --no-git-tag-version + + echo "Publishing to npm with tag '${NPM_TAG}'..." if [ -n "${NPM_TOKEN-}" ]; then + # Create .npmrc file with auth token echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc - trap 'rm -f .npmrc' EXIT - if npm publish --tag nightly; then - echo "Successfully published @terrastruct/d2@${NIGHTLY_VERSION} to npm with tag 'nightly'" + + if npm publish --tag "$NPM_TAG"; then + echo "Successfully published @terrastruct/d2@${PUBLISH_VERSION} to npm with tag '${NPM_TAG}'" + + # For official releases, bump the patch version + if [ "$VERSION" != "nightly" ]; then + # Restore original package.json first + mv package.json.bak package.json + + echo "Bumping version to ${VERSION}" + npm version "${VERSION}" --no-git-tag-version + git add package.json + git commit -m "Bump version to ${VERSION} [skip ci]" + + # Cancel the trap since we manually restored and don't want it to execute on exit + trap - EXIT + fi else echoerr "Failed to publish package to npm" exit 1 From 05f4923d7077e7470a553207940a869d56c31097 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 21 Mar 2025 11:43:54 -0600 Subject: [PATCH 47/54] Bump version to 0.1.23 [skip ci] --- d2js/js/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/d2js/js/package.json b/d2js/js/package.json index 4775805e0..e7923f7b7 100644 --- a/d2js/js/package.json +++ b/d2js/js/package.json @@ -2,7 +2,7 @@ "name": "@terrastruct/d2", "author": "Terrastruct, Inc.", "description": "D2.js is a wrapper around the WASM build of D2, the modern text-to-diagram language.", - "version": "0.1.22", + "version": "0.1.23", "repository": { "type": "git", "url": "git+https://github.com/terrastruct/d2.git", @@ -41,7 +41,7 @@ "test:integration": "bun test test/integration", "test:all": "bun run test && bun run test:integration", "dev": "bun --watch dev-server.js", - "prepublishOnly": "PUBLISH=0 ./make.sh all" + "prepublishOnly": "NPM_VERSION= ./make.sh all" }, "keywords": [ "d2", From b46fbb6270756c737422a4e2ac0f643a69e2ed35 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 21 Mar 2025 11:53:16 -0600 Subject: [PATCH 48/54] update readme --- .github/workflows/daily.yml | 2 +- README.md | 2 ++ ci/release/release-js.sh | 39 +++++++++++++++++++++++++++++++++++++ ci/release/release.sh | 21 ++++++++++++++++++++ d2js/js/ci/build.sh | 16 +++++++-------- 5 files changed, 71 insertions(+), 9 deletions(-) create mode 100755 ci/release/release-js.sh diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index 0738b8b75..0fec115fa 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -51,7 +51,7 @@ jobs: - name: Publish nightly version to NPM if: steps.check_changes.outputs.has_changes == 'true' - run: COLOR=1 ./make.sh --version=nightly js + run: COLOR=1 NPM_VERSION=nightly ./make.sh js env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} GITHUB_TOKEN: ${{ secrets._GITHUB_TOKEN }} diff --git a/README.md b/README.md index 390b1a48a..7a9763a4d 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ [![ci](https://github.com/terrastruct/d2/actions/workflows/ci.yml/badge.svg)](https://github.com/terrastruct/d2/actions/workflows/ci.yml) [![daily](https://github.com/terrastruct/d2/actions/workflows/daily.yml/badge.svg)](https://github.com/terrastruct/d2/actions/workflows/daily.yml) [![release](https://img.shields.io/github/v/release/terrastruct/d2)](https://github.com/terrastruct/d2/releases) +[![changelog](https://img.shields.io/badge/changelog-read-blue)](./CHANGELOG.md) +[![npm version](https://img.shields.io/npm/v/@terrastruct/d2)](https://www.npmjs.com/package/@terrastruct/d2) [![discord](https://img.shields.io/discord/1039184639652265985?label=discord)](https://discord.gg/NF6X8K4eDq) [![twitter](https://img.shields.io/twitter/follow/terrastruct?style=social)](https://twitter.com/terrastruct) [![license](https://img.shields.io/github/license/terrastruct/d2?color=9cf)](./LICENSE.txt) diff --git a/ci/release/release-js.sh b/ci/release/release-js.sh new file mode 100755 index 000000000..5cb5abea6 --- /dev/null +++ b/ci/release/release-js.sh @@ -0,0 +1,39 @@ +#!/bin/sh +set -eu +cd -- "$(dirname "$0")/../.." +. "./ci/sub/lib.sh" + +VERSION="" + +help() { + cat < + +Publishes the d2.js to NPM. + +Flags: + --version Version to publish (e.g., "0.1.2" or "nightly"). Note this is the js version, not related to the d2 version. A non-nightly version will publish to latest. +EOF +} + +for arg in "$@"; do + case "$arg" in + --help|-h) + help + exit 0 + ;; + --version=*) + VERSION="${arg#*=}" + ;; + esac +done + +if [ -z "$VERSION" ]; then + flag_errusage "--version is required" +fi + +FGCOLOR=6 header "Publishing JavaScript package to NPM (version: $VERSION)" + +sh_c "NPM_VERSION=$VERSION ./make.sh js" + +FGCOLOR=2 header 'NPM publish completed' diff --git a/ci/release/release.sh b/ci/release/release.sh index 517ae778d..c85120722 100755 --- a/ci/release/release.sh +++ b/ci/release/release.sh @@ -1,5 +1,26 @@ #!/bin/sh set -eu cd -- "$(dirname "$0")/../.." +. "./ci/sub/lib.sh" + + +NPM_VERSION="" + +for arg in "$@"; do + case "$arg" in + --npm-version=*) + NPM_VERSION="${arg#*=}" + ;; + esac +done + +if [ -z "$NPM_VERSION" ]; then + flag_errusage "--npm-version is required" +fi ./ci/sub/release/release.sh "$@" + +if [ -n "$NPM_VERSION" ]; then + ./ci/release/release-js.sh --version="$NPM_VERSION" +fi + diff --git a/d2js/js/ci/build.sh b/d2js/js/ci/build.sh index 7d8771bfd..031269ed4 100755 --- a/d2js/js/ci/build.sh +++ b/d2js/js/ci/build.sh @@ -18,11 +18,11 @@ fi cd d2js/js sh_c bun build.js -if [ -n "$VERSION" ]; then +if [ -n "$NPM_VERSION" ]; then cp package.json package.json.bak trap 'rm -f .npmrc; mv package.json.bak package.json' EXIT - if [ "$VERSION" = "nightly" ]; then + if [ "$NPM_VERSION" = "nightly" ]; then echo "Publishing nightly version to npm..." DATE_TAG=$(date +'%Y%m%d') @@ -33,8 +33,8 @@ if [ -n "$VERSION" ]; then echo "Updating package version to ${PUBLISH_VERSION}" else - echo "Publishing official version ${VERSION} to npm..." - PUBLISH_VERSION="$VERSION" + echo "Publishing official version ${NPM_VERSION} to npm..." + PUBLISH_VERSION="$NPM_VERSION" NPM_TAG="latest" echo "Setting package version to ${PUBLISH_VERSION}" @@ -52,14 +52,14 @@ if [ -n "$VERSION" ]; then echo "Successfully published @terrastruct/d2@${PUBLISH_VERSION} to npm with tag '${NPM_TAG}'" # For official releases, bump the patch version - if [ "$VERSION" != "nightly" ]; then + if [ "$NPM_VERSION" != "nightly" ]; then # Restore original package.json first mv package.json.bak package.json - echo "Bumping version to ${VERSION}" - npm version "${VERSION}" --no-git-tag-version + echo "Bumping version to ${NPM_VERSION}" + npm version "${NPM_VERSION}" --no-git-tag-version git add package.json - git commit -m "Bump version to ${VERSION} [skip ci]" + git commit -m "Bump version to ${NPM_VERSION} [skip ci]" # Cancel the trap since we manually restored and don't want it to execute on exit trap - EXIT From 7887fb58424c6de7a4134a8dc3f7eab11f878943 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 21 Mar 2025 12:18:32 -0600 Subject: [PATCH 49/54] update --- d2js/js/ci/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/d2js/js/ci/build.sh b/d2js/js/ci/build.sh index 031269ed4..87a692196 100755 --- a/d2js/js/ci/build.sh +++ b/d2js/js/ci/build.sh @@ -18,7 +18,7 @@ fi cd d2js/js sh_c bun build.js -if [ -n "$NPM_VERSION" ]; then +if [ -n "${NPM_VERSION:-}" ]; then cp package.json package.json.bak trap 'rm -f .npmrc; mv package.json.bak package.json' EXIT From 7d2708443373ad3000003eabaeed38ed7adc092f Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 21 Mar 2025 13:51:13 -0600 Subject: [PATCH 50/54] add val link --- d2js/js/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/d2js/js/README.md b/d2js/js/README.md index 76f0132f3..1b7298245 100644 --- a/d2js/js/README.md +++ b/d2js/js/README.md @@ -39,6 +39,8 @@ For example, yarn add @terrastruct/d2@nightly ``` +A demo using the nightly build is hosted [here](https://alixander-d2js.web.val.run/). + ## Usage D2.js uses webworkers to call a WASM file. From fe22eddc6480735b2177a3ef10636fb349cbe5be Mon Sep 17 00:00:00 2001 From: stereobooster Date: Sat, 22 Mar 2025 02:56:18 +0100 Subject: [PATCH 51/54] Fix TypeScript signatures --- d2js/js/CHANGELOG.md | 4 ++++ d2js/js/index.d.ts | 2 +- d2js/js/package.json | 8 ++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/d2js/js/CHANGELOG.md b/d2js/js/CHANGELOG.md index 8ca55ec1f..18767b5cc 100644 --- a/d2js/js/CHANGELOG.md +++ b/d2js/js/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to only the d2.js package will be documented in this file. **Does not include changes to the main d2 project.** +## Next + +- Fix TypeScript signatures + ## [0.1.22] ### March 20, 2025 diff --git a/d2js/js/index.d.ts b/d2js/js/index.d.ts index 9b2977a44..0b455af6e 100644 --- a/d2js/js/index.d.ts +++ b/d2js/js/index.d.ts @@ -47,7 +47,7 @@ export interface CompileRequest { /** A mapping of D2 file paths to their content*/ fs: Record; /** The path of the entry D2 file [default: index]*/ - inputPath: string; + inputPath?: string; /** The CompileOptions to pass to the compiler*/ options: CompileOptions; } diff --git a/d2js/js/package.json b/d2js/js/package.json index e7923f7b7..3eee22350 100644 --- a/d2js/js/package.json +++ b/d2js/js/package.json @@ -23,9 +23,13 @@ "browser": "./dist/browser/index.js", "import": { "browser": "./dist/browser/index.js", - "default": "./dist/node-esm/index.js" + "default": "./dist/node-esm/index.js", + "types": "./index.d.ts" + }, + "require": { + "default": "./dist/node-cjs/index.js", + "types": "./index.d.ts" }, - "require": "./dist/node-cjs/index.js", "default": "./dist/node-esm/index.js" }, "./worker": "./dist/browser/worker.js" From f83459de2bb797fe9e6bd9ef35cc60257f73c6f6 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 21 Mar 2025 20:26:55 -0600 Subject: [PATCH 52/54] add test --- d2compiler/compile_test.go | 18 + .../TestCompile/glob-spread-vars.exp.json | 317 ++++++++++++++++++ 2 files changed, 335 insertions(+) create mode 100644 testdata/d2compiler/TestCompile/glob-spread-vars.exp.json diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index c64c18919..2eafbc63e 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -3141,6 +3141,24 @@ x*: { tassert.Equal(t, "x2.ok", g.Objects[3].AbsID()) }, }, + { + name: "glob-spread-vars", + text: `vars: { + b: { + 1 + } +} + +a: { + ...${b} + **.style.fill: red +} +`, + assertions: func(t *testing.T, g *d2graph.Graph) { + assert.Equal(t, "1", g.Objects[1].Label.Value) + assert.Equal(t, "red", g.Objects[1].Style.Fill.Value) + }, + }, { name: "import-var-chain", diff --git a/testdata/d2compiler/TestCompile/glob-spread-vars.exp.json b/testdata/d2compiler/TestCompile/glob-spread-vars.exp.json new file mode 100644 index 000000000..040ad1106 --- /dev/null +++ b/testdata/d2compiler/TestCompile/glob-spread-vars.exp.json @@ -0,0 +1,317 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,0:0:0-10:0:66", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,0:0:0-4:1:26", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,0:0:0-0:4:4", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,0:0:0-0:4:4", + "value": [ + { + "string": "vars", + "raw_string": "vars" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,0:6:6-4:1:26", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,1:2:10-3:3:24", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,1:2:10-1:3:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,1:2:10-1:3:11", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,1:5:13-3:3:24", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,2:4:19-2:5:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,2:4:19-2:5:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,2:4:19-2:5:20", + "value": [ + { + "string": "1", + "raw_string": "1" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:0:28-9:1:65", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:0:28-6:1:29", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:0:28-6:1:29", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:3:31-9:1:65", + "nodes": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,7:2:35-7:9:42", + "spread": true, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,7:7:40-7:8:41", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:2:45-8:20:63", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:2:45-8:15:58", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:2:45-8:4:47", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:5:48-8:10:53", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:11:54-8:15:58", + "value": [ + { + "string": "fill", + "raw_string": "fill" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:17:60-8:20:63", + "value": [ + { + "string": "red", + "raw_string": "red" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:0:28-6:1:29", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:0:28-6:1:29", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "1", + "id_val": "1", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,2:4:19-2:5:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,2:4:19-2:5:20", + "value": [ + { + "string": "1", + "raw_string": "1" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "1" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} From 9d8418ba15b8e746ea9cd3ea5f4c7e4b86131fbf Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 21 Mar 2025 21:27:17 -0600 Subject: [PATCH 53/54] fix --- d2compiler/compile_test.go | 23 +- d2ir/compile.go | 13 + .../TestCompile/glob-spread-vars.exp.json | 30 +- .../TestCompile/glob-spread-vars/1.exp.json | 319 ++++++++++++ .../TestCompile/glob-spread-vars/2.exp.json | 480 ++++++++++++++++++ 5 files changed, 849 insertions(+), 16 deletions(-) create mode 100644 testdata/d2compiler/TestCompile/glob-spread-vars/1.exp.json create mode 100644 testdata/d2compiler/TestCompile/glob-spread-vars/2.exp.json diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 2eafbc63e..3bc1fd127 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -3142,7 +3142,7 @@ x*: { }, }, { - name: "glob-spread-vars", + name: "glob-spread-vars/1", text: `vars: { b: { 1 @@ -3151,7 +3151,7 @@ x*: { a: { ...${b} - **.style.fill: red + *.style.fill: red } `, assertions: func(t *testing.T, g *d2graph.Graph) { @@ -3159,6 +3159,25 @@ a: { assert.Equal(t, "red", g.Objects[1].Style.Fill.Value) }, }, + { + name: "glob-spread-vars/2", + text: `vars: { + b: { + 1 + } +} + +a: { + ...${b} + ** -> _.ok +} + +ok +`, + assertions: func(t *testing.T, g *d2graph.Graph) { + assert.Equal(t, 1, len(g.Edges)) + }, + }, { name: "import-var-chain", diff --git a/d2ir/compile.go b/d2ir/compile.go index 82f3559d1..19a77c037 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -280,6 +280,19 @@ func (c *compiler) resolveSubstitutions(varsStack []*Map, node Node) (removedFie break } } + + if removedField && len(m.globs) > 0 && !c.lazyGlobBeingApplied { + origGlobStack := c.globContextStack + c.globContextStack = append(c.globContextStack, m.globs) + for _, gctx := range m.globs { + old := c.lazyGlobBeingApplied + c.lazyGlobBeingApplied = true + c.compileKey(gctx.refctx) + c.lazyGlobBeingApplied = old + } + c.globContextStack = origGlobStack + } + } } if resolvedField.Primary() == nil { diff --git a/testdata/d2compiler/TestCompile/glob-spread-vars.exp.json b/testdata/d2compiler/TestCompile/glob-spread-vars.exp.json index 040ad1106..183600210 100644 --- a/testdata/d2compiler/TestCompile/glob-spread-vars.exp.json +++ b/testdata/d2compiler/TestCompile/glob-spread-vars.exp.json @@ -3,7 +3,7 @@ "name": "", "isFolderOnly": false, "ast": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,0:0:0-10:0:66", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,0:0:0-10:0:65", "nodes": [ { "map_key": { @@ -88,7 +88,7 @@ }, { "map_key": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:0:28-9:1:65", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:0:28-9:1:64", "key": { "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:0:28-6:1:29", "path": [ @@ -108,7 +108,7 @@ "primary": {}, "value": { "map": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:3:31-9:1:65", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,6:3:31-9:1:64", "nodes": [ { "substitution": { @@ -131,29 +131,27 @@ }, { "map_key": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:2:45-8:20:63", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:2:45-8:19:62", "key": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:2:45-8:15:58", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:2:45-8:14:57", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:2:45-8:4:47", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:2:45-8:3:46", "value": [ { - "string": "**", - "raw_string": "**" + "string": "*", + "raw_string": "*" } ], "pattern": [ - "*", - "", "*" ] } }, { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:5:48-8:10:53", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:4:47-8:9:52", "value": [ { "string": "style", @@ -164,7 +162,7 @@ }, { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:11:54-8:15:58", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:10:53-8:14:57", "value": [ { "string": "fill", @@ -178,7 +176,7 @@ "primary": {}, "value": { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:17:60-8:20:63", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars.d2,8:16:59-8:19:62", "value": [ { "string": "red", @@ -299,7 +297,11 @@ "width": 0, "height": 0 }, - "style": {}, + "style": { + "fill": { + "value": "red" + } + }, "near_key": null, "shape": { "value": "rectangle" diff --git a/testdata/d2compiler/TestCompile/glob-spread-vars/1.exp.json b/testdata/d2compiler/TestCompile/glob-spread-vars/1.exp.json new file mode 100644 index 000000000..b973d1850 --- /dev/null +++ b/testdata/d2compiler/TestCompile/glob-spread-vars/1.exp.json @@ -0,0 +1,319 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,0:0:0-10:0:65", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,0:0:0-4:1:26", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,0:0:0-0:4:4", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,0:0:0-0:4:4", + "value": [ + { + "string": "vars", + "raw_string": "vars" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,0:6:6-4:1:26", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,1:2:10-3:3:24", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,1:2:10-1:3:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,1:2:10-1:3:11", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,1:5:13-3:3:24", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,2:4:19-2:5:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,2:4:19-2:5:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,2:4:19-2:5:20", + "value": [ + { + "string": "1", + "raw_string": "1" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,6:0:28-9:1:64", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,6:0:28-6:1:29", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,6:0:28-6:1:29", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,6:3:31-9:1:64", + "nodes": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,7:2:35-7:9:42", + "spread": true, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,7:7:40-7:8:41", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,8:2:45-8:19:62", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,8:2:45-8:14:57", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,8:2:45-8:3:46", + "value": [ + { + "string": "*", + "raw_string": "*" + } + ], + "pattern": [ + "*" + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,8:4:47-8:9:52", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,8:10:53-8:14:57", + "value": [ + { + "string": "fill", + "raw_string": "fill" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,8:16:59-8:19:62", + "value": [ + { + "string": "red", + "raw_string": "red" + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,6:0:28-6:1:29", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,6:0:28-6:1:29", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "1", + "id_val": "1", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,2:4:19-2:5:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/1.d2,2:4:19-2:5:20", + "value": [ + { + "string": "1", + "raw_string": "1" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "1" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": { + "fill": { + "value": "red" + } + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} diff --git a/testdata/d2compiler/TestCompile/glob-spread-vars/2.exp.json b/testdata/d2compiler/TestCompile/glob-spread-vars/2.exp.json new file mode 100644 index 000000000..4dd91eb61 --- /dev/null +++ b/testdata/d2compiler/TestCompile/glob-spread-vars/2.exp.json @@ -0,0 +1,480 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:0:0-12:0:62", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:0:0-4:1:26", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:0:0-0:4:4", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:0:0-0:4:4", + "value": [ + { + "string": "vars", + "raw_string": "vars" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:6:6-4:1:26", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,1:2:10-3:3:24", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,1:2:10-1:3:11", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,1:2:10-1:3:11", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,1:5:13-3:3:24", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,2:4:19-2:5:20", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,2:4:19-2:5:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,2:4:19-2:5:20", + "value": [ + { + "string": "1", + "raw_string": "1" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,6:0:28-9:1:57", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,6:0:28-6:1:29", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,6:0:28-6:1:29", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,6:3:31-9:1:57", + "nodes": [ + { + "substitution": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:2:35-7:9:42", + "spread": true, + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:7:40-7:8:41", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:2:45-8:12:55", + "edges": [ + { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:2:45-8:12:55", + "src": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:2:45-8:4:47", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:2:45-8:4:47", + "value": [ + { + "string": "**", + "raw_string": "**" + } + ], + "pattern": [ + "*", + "", + "*" + ] + } + } + ] + }, + "src_arrow": "", + "dst": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:8:51-8:12:55", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:8:51-8:9:52", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:10:53-8:12:55", + "value": [ + { + "string": "ok", + "raw_string": "ok" + } + ] + } + } + ] + }, + "dst_arrow": ">" + } + ], + "primary": {}, + "value": {} + } + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,11:0:59-11:2:61", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,11:0:59-11:2:61", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,11:0:59-11:2:61", + "value": [ + { + "string": "ok", + "raw_string": "ok" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + }, + "root": { + "id": "", + "id_val": "", + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + "edges": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ], + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,6:0:28-6:1:29", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,6:0:28-6:1:29", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "1", + "id_val": "1", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,2:4:19-2:5:20", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,2:4:19-2:5:20", + "value": [ + { + "string": "1", + "raw_string": "1" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "1" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "ok", + "id_val": "ok", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:8:51-8:12:55", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:8:51-8:9:52", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:10:53-8:12:55", + "value": [ + { + "string": "ok", + "raw_string": "ok" + } + ] + } + } + ] + }, + "key_path_index": 1, + "map_key_edge_index": 0 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,11:0:59-11:2:61", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,11:0:59-11:2:61", + "value": [ + { + "string": "ok", + "raw_string": "ok" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:8:51-8:12:55", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:8:51-8:9:52", + "value": [ + { + "string": "_", + "raw_string": "_" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:10:53-8:12:55", + "value": [ + { + "string": "ok", + "raw_string": "ok" + } + ] + } + } + ] + }, + "key_path_index": 1, + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "ok" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": null +} From cc1aad2223e4b8dde8865a8c547c9ea45b2ec1cd Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Fri, 21 Mar 2025 21:27:55 -0600 Subject: [PATCH 54/54] next --- ci/release/changelogs/next.md | 1 + d2compiler/compile_test.go | 3 +- .../TestCompile/glob-spread-vars/2.exp.json | 160 ++++++++++++++---- 3 files changed, 132 insertions(+), 32 deletions(-) diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 2c16f2451..bc2ea0d5c 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -24,6 +24,7 @@ - fixes support for `center` in `d2-config` [#2360](https://github.com/terrastruct/d2/pull/2360) - fixes panic when comment lines appear in arrays [#2378](https://github.com/terrastruct/d2/pull/2378) - fixes inconsistencies when objects were double quoted [#2390](https://github.com/terrastruct/d2/pull/2390) + - fixes globs not applying to spread substitutions [#2426](https://github.com/terrastruct/d2/issues/2426) - CLI: fetch and render remote images of mimetype octet-stream correctly [#2370](https://github.com/terrastruct/d2/pull/2370) - d2js: handle unicode characters [#2393](https://github.com/terrastruct/d2/pull/2393) diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 3bc1fd127..ccd042fad 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -3164,6 +3164,7 @@ a: { text: `vars: { b: { 1 + 2 } } @@ -3175,7 +3176,7 @@ a: { ok `, assertions: func(t *testing.T, g *d2graph.Graph) { - assert.Equal(t, 1, len(g.Edges)) + assert.Equal(t, 2, len(g.Edges)) }, }, { diff --git a/testdata/d2compiler/TestCompile/glob-spread-vars/2.exp.json b/testdata/d2compiler/TestCompile/glob-spread-vars/2.exp.json index 4dd91eb61..52b3ca111 100644 --- a/testdata/d2compiler/TestCompile/glob-spread-vars/2.exp.json +++ b/testdata/d2compiler/TestCompile/glob-spread-vars/2.exp.json @@ -3,11 +3,11 @@ "name": "", "isFolderOnly": false, "ast": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:0:0-12:0:62", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:0:0-13:0:66", "nodes": [ { "map_key": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:0:0-4:1:26", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:0:0-5:1:30", "key": { "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:0:0-0:4:4", "path": [ @@ -27,11 +27,11 @@ "primary": {}, "value": { "map": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:6:6-4:1:26", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,0:6:6-5:1:30", "nodes": [ { "map_key": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,1:2:10-3:3:24", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,1:2:10-4:3:28", "key": { "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,1:2:10-1:3:11", "path": [ @@ -51,7 +51,7 @@ "primary": {}, "value": { "map": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,1:5:13-3:3:24", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,1:5:13-4:3:28", "nodes": [ { "map_key": { @@ -75,6 +75,29 @@ "primary": {}, "value": {} } + }, + { + "map_key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,3:2:23-3:3:24", + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,3:2:23-3:3:24", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,3:2:23-3:3:24", + "value": [ + { + "string": "2", + "raw_string": "2" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } } ] } @@ -88,13 +111,13 @@ }, { "map_key": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,6:0:28-9:1:57", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:0:32-10:1:61", "key": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,6:0:28-6:1:29", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:0:32-7:1:33", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,6:0:28-6:1:29", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:0:32-7:1:33", "value": [ { "string": "a", @@ -108,16 +131,16 @@ "primary": {}, "value": { "map": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,6:3:31-9:1:57", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:3:35-10:1:61", "nodes": [ { "substitution": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:2:35-7:9:42", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:2:39-8:9:46", "spread": true, "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:7:40-7:8:41", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:7:44-8:8:45", "value": [ { "string": "b", @@ -131,16 +154,16 @@ }, { "map_key": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:2:45-8:12:55", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:2:49-9:12:59", "edges": [ { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:2:45-8:12:55", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:2:49-9:12:59", "src": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:2:45-8:4:47", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:2:49-9:4:51", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:2:45-8:4:47", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:2:49-9:4:51", "value": [ { "string": "**", @@ -158,11 +181,11 @@ }, "src_arrow": "", "dst": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:8:51-8:12:55", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:8:55-9:12:59", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:8:51-8:9:52", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:8:55-9:9:56", "value": [ { "string": "_", @@ -173,7 +196,7 @@ }, { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:10:53-8:12:55", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:10:57-9:12:59", "value": [ { "string": "ok", @@ -198,13 +221,13 @@ }, { "map_key": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,11:0:59-11:2:61", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,12:0:63-12:2:65", "key": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,11:0:59-11:2:61", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,12:0:63-12:2:65", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,11:0:59-11:2:61", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,12:0:63-12:2:65", "value": [ { "string": "ok", @@ -245,6 +268,36 @@ "zIndex": 0 }, "edges": [ + { + "index": 0, + "isCurve": false, + "src_arrow": false, + "dst_arrow": true, + "references": [ + { + "map_key_edge_index": 0 + } + ], + "attributes": { + "label": { + "value": "" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, { "index": 0, "isCurve": false, @@ -283,11 +336,11 @@ "references": [ { "key": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,6:0:28-6:1:29", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:0:32-7:1:33", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,6:0:28-6:1:29", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,7:0:32-7:1:33", "value": [ { "string": "a", @@ -367,17 +420,62 @@ }, "zIndex": 0 }, + { + "id": "2", + "id_val": "2", + "references": [ + { + "key": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,3:2:23-3:3:24", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,3:2:23-3:3:24", + "value": [ + { + "string": "2", + "raw_string": "2" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "2" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, { "id": "ok", "id_val": "ok", "references": [ { "key": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:8:51-8:12:55", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:8:55-9:12:59", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:8:51-8:9:52", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:8:55-9:9:56", "value": [ { "string": "_", @@ -388,7 +486,7 @@ }, { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:10:53-8:12:55", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:10:57-9:12:59", "value": [ { "string": "ok", @@ -404,11 +502,11 @@ }, { "key": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,11:0:59-11:2:61", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,12:0:63-12:2:65", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,11:0:59-11:2:61", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,12:0:63-12:2:65", "value": [ { "string": "ok", @@ -424,11 +522,11 @@ }, { "key": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:8:51-8:12:55", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:8:55-9:12:59", "path": [ { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:8:51-8:9:52", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:8:55-9:9:56", "value": [ { "string": "_", @@ -439,7 +537,7 @@ }, { "unquoted_string": { - "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,8:10:53-8:12:55", + "range": "d2/testdata/d2compiler/TestCompile/glob-spread-vars/2.d2,9:10:57-9:12:59", "value": [ { "string": "ok",
                                                                                            Sprint