diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go
index 4409e6045..042ecc48e 100644
--- a/d2renderers/d2svg/d2svg.go
+++ b/d2renderers/d2svg/d2svg.go
@@ -33,6 +33,8 @@ const (
MIN_ARROWHEAD_STROKE_WIDTH = 2
)
+var multipleOffset = geo.NewVector(10, -10)
+
//go:embed github-markdown.css
var mdCSS string
@@ -442,6 +444,16 @@ func drawConnection(writer io.Writer, connection d2target.Connection, markers ma
}
}
+func renderOval(tl *geo.Point, width, height float64, style string) string {
+ rx := width / 2
+ ry := height / 2
+ cx := tl.X + rx
+ cy := tl.Y + ry
+ return fmt.Sprintf(``,
+ cx, cy, rx, ry, style,
+ )
+}
+
func drawShape(writer io.Writer, targetShape d2target.Shape) error {
tl := geo.NewPoint(float64(targetShape.Pos.X), float64(targetShape.Pos.Y))
width := float64(targetShape.Width)
@@ -451,6 +463,11 @@ func drawShape(writer io.Writer, targetShape d2target.Shape) error {
s := shape.NewShape(shapeType, geo.NewBox(tl, width, height))
+ var multipleTL *geo.Point
+ if targetShape.Multiple {
+ multipleTL = tl.AddVector(multipleOffset)
+ }
+
switch targetShape.Type {
case d2target.ShapeClass:
drawClass(writer, targetShape)
@@ -459,13 +476,10 @@ func drawShape(writer io.Writer, targetShape d2target.Shape) error {
drawTable(writer, targetShape)
return nil
case d2target.ShapeOval:
- rx := width / 2
- ry := height / 2
- cx := tl.X + rx
- cy := tl.Y + ry
- fmt.Fprintf(writer, ``,
- cx, cy, rx, ry, style,
- )
+ if targetShape.Multiple {
+ fmt.Fprint(writer, renderOval(multipleTL, width, height, style))
+ }
+ fmt.Fprint(writer, renderOval(tl, width, height, style))
case d2target.ShapeImage:
fmt.Fprintf(writer, ``,
@@ -475,10 +489,20 @@ func drawShape(writer io.Writer, targetShape d2target.Shape) error {
case d2target.ShapeCode:
// TODO should standardize "" to rectangle
case d2target.ShapeRectangle, "":
+ if targetShape.Multiple {
+ fmt.Fprintf(writer, ``,
+ targetShape.Pos.X+10, targetShape.Pos.Y-10, targetShape.Width, targetShape.Height, style)
+ }
fmt.Fprintf(writer, ``,
targetShape.Pos.X, targetShape.Pos.Y, targetShape.Width, targetShape.Height, style)
default:
+ if targetShape.Multiple {
+ multiplePathData := shape.NewShape(shapeType, geo.NewBox(multipleTL, width, height)).GetSVGPathData()
+ for _, pathData := range multiplePathData {
+ fmt.Fprintf(writer, ``, pathData, style)
+ }
+ }
for _, pathData := range s.GetSVGPathData() {
fmt.Fprintf(writer, ``, pathData, style)
}
diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go
index 3aafba44d..c77d3bf1b 100644
--- a/e2etests/stable_test.go
+++ b/e2etests/stable_test.go
@@ -48,6 +48,53 @@ queue -> package -> step
callout -> stored_data -> person
diamond -> oval -> circle
hexagon -> cloud
+`,
+ },
+ {
+ name: "all_shapes_multiple",
+ script: `
+rectangle: {shape: "rectangle"}
+square: {shape: "square"}
+page: {shape: "page"}
+parallelogram: {shape: "parallelogram"}
+document: {shape: "document"}
+cylinder: {shape: "cylinder"}
+queue: {shape: "queue"}
+package: {shape: "package"}
+step: {shape: "step"}
+callout: {shape: "callout"}
+stored_data: {shape: "stored_data"}
+person: {shape: "person"}
+diamond: {shape: "diamond"}
+oval: {shape: "oval"}
+circle: {shape: "circle"}
+hexagon: {shape: "hexagon"}
+cloud: {shape: "cloud"}
+
+rectangle -> square -> page
+parallelogram -> document -> cylinder
+queue -> package -> step
+callout -> stored_data -> person
+diamond -> oval -> circle
+hexagon -> cloud
+
+rectangle.multiple: true
+square.multiple: true
+page.multiple: true
+parallelogram.multiple: true
+document.multiple: true
+cylinder.multiple: true
+queue.multiple: true
+package.multiple: true
+step.multiple: true
+callout.multiple: true
+stored_data.multiple: true
+person.multiple: true
+diamond.multiple: true
+oval.multiple: true
+circle.multiple: true
+hexagon.multiple: true
+cloud.multiple: true
`,
},
{
diff --git a/e2etests/testdata/stable/all_shapes_multiple/board.exp.json b/e2etests/testdata/stable/all_shapes_multiple/board.exp.json
new file mode 100644
index 000000000..b379936c3
--- /dev/null
+++ b/e2etests/testdata/stable/all_shapes_multiple/board.exp.json
@@ -0,0 +1,1170 @@
+{
+ "name": "",
+ "shapes": [
+ {
+ "id": "rectangle",
+ "type": "rectangle",
+ "pos": {
+ "x": 0,
+ "y": 0
+ },
+ "width": 171,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#F7F8FE",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "rectangle",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 71,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "square",
+ "type": "rectangle",
+ "pos": {
+ "x": 9,
+ "y": 226
+ },
+ "width": 154,
+ "height": 154,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#F7F8FE",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "square",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 54,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "page",
+ "type": "page",
+ "pos": {
+ "x": 16,
+ "y": 489
+ },
+ "width": 139,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#EDF0FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "page",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 39,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "parallelogram",
+ "type": "parallelogram",
+ "pos": {
+ "x": 231,
+ "y": 0
+ },
+ "width": 204,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#F0F3F9",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "parallelogram",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 104,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "document",
+ "type": "document",
+ "pos": {
+ "x": 245,
+ "y": 240
+ },
+ "width": 177,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#EDF0FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "document",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 77,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "cylinder",
+ "type": "cylinder",
+ "pos": {
+ "x": 251,
+ "y": 489
+ },
+ "width": 164,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#EDF0FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "cylinder",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 64,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "queue",
+ "type": "queue",
+ "pos": {
+ "x": 495,
+ "y": 0
+ },
+ "width": 149,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#F0F3F9",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "queue",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 49,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "package",
+ "type": "package",
+ "pos": {
+ "x": 488,
+ "y": 240
+ },
+ "width": 163,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#EDF0FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "package",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 63,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "step",
+ "type": "step",
+ "pos": {
+ "x": 502,
+ "y": 489
+ },
+ "width": 136,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#EDF0FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "step",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 36,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "callout",
+ "type": "callout",
+ "pos": {
+ "x": 729,
+ "y": 0
+ },
+ "width": 155,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#FFFFFF",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "callout",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 55,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "stored_data",
+ "type": "stored_data",
+ "pos": {
+ "x": 711,
+ "y": 240
+ },
+ "width": 191,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#EDF0FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "stored_data",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 91,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "person",
+ "type": "person",
+ "pos": {
+ "x": 730,
+ "y": 489
+ },
+ "width": 153,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#E3E9FD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "person",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 53,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "diamond",
+ "type": "diamond",
+ "pos": {
+ "x": 946,
+ "y": 0
+ },
+ "width": 168,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#CFD2DD",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "diamond",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 68,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "oval",
+ "type": "oval",
+ "pos": {
+ "x": 962,
+ "y": 240
+ },
+ "width": 136,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#F7F8FE",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "oval",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 36,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "circle",
+ "type": "oval",
+ "pos": {
+ "x": 958,
+ "y": 480
+ },
+ "width": 144,
+ "height": 144,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#F7F8FE",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "circle",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 44,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "hexagon",
+ "type": "hexagon",
+ "pos": {
+ "x": 1174,
+ "y": 0
+ },
+ "width": 165,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#F0F3F9",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "hexagon",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 65,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ },
+ {
+ "id": "cloud",
+ "type": "cloud",
+ "pos": {
+ "x": 1184,
+ "y": 240
+ },
+ "width": 145,
+ "height": 126,
+ "level": 1,
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "borderRadius": 0,
+ "fill": "#FFFFFF",
+ "stroke": "#0D32B2",
+ "shadow": false,
+ "3d": false,
+ "multiple": true,
+ "tooltip": "",
+ "link": "",
+ "icon": null,
+ "iconPosition": "",
+ "fields": null,
+ "methods": null,
+ "columns": null,
+ "label": "cloud",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#0A0F25",
+ "italic": false,
+ "bold": true,
+ "underline": false,
+ "labelWidth": 45,
+ "labelHeight": 26,
+ "labelPosition": "INSIDE_MIDDLE_CENTER"
+ }
+ ],
+ "connections": [
+ {
+ "id": "(rectangle -> square)[0]",
+ "src": "rectangle",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "square",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 85.5,
+ "y": 126
+ },
+ {
+ "x": 85.5,
+ "y": 166
+ },
+ {
+ "x": 85.5,
+ "y": 186
+ },
+ {
+ "x": 85.5,
+ "y": 226
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ },
+ {
+ "id": "(square -> page)[0]",
+ "src": "square",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "page",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 85.5,
+ "y": 380
+ },
+ {
+ "x": 85.5,
+ "y": 420
+ },
+ {
+ "x": 85.4,
+ "y": 441.8
+ },
+ {
+ "x": 85,
+ "y": 489
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ },
+ {
+ "id": "(parallelogram -> document)[0]",
+ "src": "parallelogram",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "document",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 333,
+ "y": 126
+ },
+ {
+ "x": 333,
+ "y": 166
+ },
+ {
+ "x": 333,
+ "y": 188.8
+ },
+ {
+ "x": 333,
+ "y": 240
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ },
+ {
+ "id": "(document -> cylinder)[0]",
+ "src": "document",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "cylinder",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 333,
+ "y": 349
+ },
+ {
+ "x": 333,
+ "y": 413.8
+ },
+ {
+ "x": 333,
+ "y": 441.8
+ },
+ {
+ "x": 333,
+ "y": 489
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ },
+ {
+ "id": "(queue -> package)[0]",
+ "src": "queue",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "package",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 569,
+ "y": 126
+ },
+ {
+ "x": 569.4,
+ "y": 166
+ },
+ {
+ "x": 569.6,
+ "y": 188.8
+ },
+ {
+ "x": 570,
+ "y": 240
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ },
+ {
+ "id": "(package -> step)[0]",
+ "src": "package",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "step",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 569,
+ "y": 366
+ },
+ {
+ "x": 569.4,
+ "y": 417.2
+ },
+ {
+ "x": 569.6,
+ "y": 441.8
+ },
+ {
+ "x": 570,
+ "y": 489
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ },
+ {
+ "id": "(callout -> stored_data)[0]",
+ "src": "callout",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "stored_data",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 807,
+ "y": 126
+ },
+ {
+ "x": 806.6,
+ "y": 166
+ },
+ {
+ "x": 806.6,
+ "y": 188.8
+ },
+ {
+ "x": 807,
+ "y": 240
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ },
+ {
+ "id": "(stored_data -> person)[0]",
+ "src": "stored_data",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "person",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 806,
+ "y": 366
+ },
+ {
+ "x": 806.4,
+ "y": 417.2
+ },
+ {
+ "x": 806.6,
+ "y": 441.8
+ },
+ {
+ "x": 807,
+ "y": 489
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ },
+ {
+ "id": "(diamond -> oval)[0]",
+ "src": "diamond",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "oval",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 1030,
+ "y": 126
+ },
+ {
+ "x": 1030,
+ "y": 166
+ },
+ {
+ "x": 1030,
+ "y": 188.8
+ },
+ {
+ "x": 1030,
+ "y": 240
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ },
+ {
+ "id": "(oval -> circle)[0]",
+ "src": "oval",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "circle",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 1030,
+ "y": 366
+ },
+ {
+ "x": 1030,
+ "y": 417.2
+ },
+ {
+ "x": 1030,
+ "y": 440
+ },
+ {
+ "x": 1030,
+ "y": 480
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ },
+ {
+ "id": "(hexagon -> cloud)[0]",
+ "src": "hexagon",
+ "srcArrow": "none",
+ "srcLabel": "",
+ "dst": "cloud",
+ "dstArrow": "triangle",
+ "dstLabel": "",
+ "opacity": 1,
+ "strokeDash": 0,
+ "strokeWidth": 2,
+ "stroke": "#0D32B2",
+ "label": "",
+ "fontSize": 16,
+ "fontFamily": "DEFAULT",
+ "language": "",
+ "color": "#676C7E",
+ "italic": true,
+ "bold": false,
+ "underline": false,
+ "labelWidth": 0,
+ "labelHeight": 0,
+ "labelPosition": "",
+ "labelPercentage": 0,
+ "route": [
+ {
+ "x": 1256,
+ "y": 126
+ },
+ {
+ "x": 1256.4,
+ "y": 166
+ },
+ {
+ "x": 1256.6,
+ "y": 189.2
+ },
+ {
+ "x": 1257,
+ "y": 242
+ }
+ ],
+ "isCurve": true,
+ "animated": false,
+ "tooltip": "",
+ "icon": null
+ }
+ ]
+}
diff --git a/e2etests/testdata/stable/all_shapes_multiple/sketch.exp.svg b/e2etests/testdata/stable/all_shapes_multiple/sketch.exp.svg
new file mode 100644
index 000000000..67c1e00b1
--- /dev/null
+++ b/e2etests/testdata/stable/all_shapes_multiple/sketch.exp.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file