diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 98a09eb46..f69885d70 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -1,4 +1,5 @@ #### Features ๐Ÿš€ +- `border-radius` is now supported on both shape class and sql_table. [#982](https://github.com/terrastruct/d2/pull/982) #### Improvements ๐Ÿงน diff --git a/d2renderers/d2sketch/sketch_test.go b/d2renderers/d2sketch/sketch_test.go index 1d6f44b82..ae7c94049 100644 --- a/d2renderers/d2sketch/sketch_test.go +++ b/d2renderers/d2sketch/sketch_test.go @@ -1005,6 +1005,49 @@ normal: { something `, }, + { + name: "class_and_sqlTable_border_radius", + script: ` + a: { + shape: sql_table + id: int {constraint: primary_key} + disk: int {constraint: foreign_key} + + json: jsonb {constraint: unique} + last_updated: timestamp with time zone + + style: { + fill: red + border-radius: 0 + } + } + + b: { + shape: class + + field: "[]string" + method(a uint64): (x, y int) + + style: { + border-radius: 0 + } + } + + c: { + shape: class + style: { + border-radius: 0 + } + } + + d: { + shape: sql_table + style: { + border-radius: 0 + } + } + `, + }, } runa(t, tcs) } diff --git a/d2renderers/d2sketch/testdata/class_and_sqlTable_border_radius/sketch.exp.svg b/d2renderers/d2sketch/testdata/class_and_sqlTable_border_radius/sketch.exp.svg new file mode 100644 index 000000000..e747821c9 --- /dev/null +++ b/d2renderers/d2sketch/testdata/class_and_sqlTable_border_radius/sketch.exp.svg @@ -0,0 +1,46 @@ + + + + + + + + +aidintPKdiskintFKjsonjsonbUNQlast_updatedtimestamp with time zoneb+field[]string+method(a uint64)(x, y int)cd + + + \ No newline at end of file diff --git a/d2renderers/d2svg/class.go b/d2renderers/d2svg/class.go index 6cf8e6889..7a560f225 100644 --- a/d2renderers/d2svg/class.go +++ b/d2renderers/d2svg/class.go @@ -11,12 +11,15 @@ import ( "oss.terrastruct.com/d2/lib/svg" ) -func classHeader(shape d2target.Shape, box *geo.Box, text string, textWidth, textHeight, fontSize float64) string { +func classHeader(diagramHash string, shape d2target.Shape, box *geo.Box, text string, textWidth, textHeight, fontSize float64) string { rectEl := d2themes.NewThemableElement("rect") rectEl.X, rectEl.Y = box.TopLeft.X, box.TopLeft.Y rectEl.Width, rectEl.Height = box.Width, box.Height rectEl.Fill = shape.Fill rectEl.ClassName = "class_header" + if shape.BorderRadius != 0 { + rectEl.ClipPath = fmt.Sprintf("%v-%v", diagramHash, shape.ID) + } str := rectEl.Render() if text != "" { @@ -81,7 +84,7 @@ func classRow(shape d2target.Shape, box *geo.Box, prefix, nameText, typeText str return out } -func drawClass(writer io.Writer, targetShape d2target.Shape) { +func drawClass(writer io.Writer, diagramHash string, targetShape d2target.Shape) { el := d2themes.NewThemableElement("rect") el.X = float64(targetShape.Pos.X) el.Y = float64(targetShape.Pos.Y) @@ -89,6 +92,10 @@ func drawClass(writer io.Writer, targetShape d2target.Shape) { el.Height = float64(targetShape.Height) el.Fill, el.Stroke = d2themes.ShapeTheme(targetShape) el.Style = targetShape.CSSStyle() + if targetShape.BorderRadius != 0 { + el.Rx = float64(targetShape.BorderRadius) + el.Ry = float64(targetShape.BorderRadius) + } fmt.Fprint(writer, el.Render()) box := geo.NewBox( @@ -100,7 +107,7 @@ func drawClass(writer io.Writer, targetShape d2target.Shape) { headerBox := geo.NewBox(box.TopLeft, box.Width, 2*rowHeight) fmt.Fprint(writer, - classHeader(targetShape, headerBox, targetShape.Label, float64(targetShape.LabelWidth), float64(targetShape.LabelHeight), float64(targetShape.FontSize)), + classHeader(diagramHash, targetShape, headerBox, targetShape.Label, float64(targetShape.LabelWidth), float64(targetShape.LabelHeight), float64(targetShape.FontSize)), ) rowBox := geo.NewBox(box.TopLeft.Copy(), box.Width, rowHeight) @@ -113,8 +120,15 @@ func drawClass(writer io.Writer, targetShape d2target.Shape) { } lineEl := d2themes.NewThemableElement("line") - lineEl.X1, lineEl.Y1 = rowBox.TopLeft.X, rowBox.TopLeft.Y - lineEl.X2, lineEl.Y2 = rowBox.TopLeft.X+rowBox.Width, rowBox.TopLeft.Y + + if targetShape.BorderRadius != 0 && len(targetShape.Methods) == 0 { + lineEl.X1, lineEl.Y1 = rowBox.TopLeft.X+float64(targetShape.BorderRadius), rowBox.TopLeft.Y + lineEl.X2, lineEl.Y2 = rowBox.TopLeft.X+rowBox.Width-float64(targetShape.BorderRadius), rowBox.TopLeft.Y + } else { + lineEl.X1, lineEl.Y1 = rowBox.TopLeft.X, rowBox.TopLeft.Y + lineEl.X2, lineEl.Y2 = rowBox.TopLeft.X+rowBox.Width, rowBox.TopLeft.Y + } + lineEl.Stroke = targetShape.Fill lineEl.Style = "stroke-width:1" fmt.Fprint(writer, lineEl.Render()) diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index 2846c7587..66de5a515 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -865,7 +865,7 @@ func render3dHexagon(targetShape d2target.Shape) string { return borderMask + mainShapeRendered + renderedSides + renderedBorder } -func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2sketch.Runner) (labelMask string, err error) { +func drawShape(writer io.Writer, diagramHash string, targetShape d2target.Shape, sketchRunner *d2sketch.Runner) (labelMask string, err error) { closingTag := "" if targetShape.Link != "" { @@ -877,6 +877,11 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske 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)) + } fmt.Fprintf(writer, ``, svg.EscapeText(targetShape.ID), opacityStyle) tl := geo.NewPoint(float64(targetShape.Pos.X), float64(targetShape.Pos.Y)) width := float64(targetShape.Width) @@ -920,7 +925,7 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske } fmt.Fprint(writer, out) } else { - drawClass(writer, targetShape) + drawClass(writer, diagramHash, targetShape) } addAppendixItems(writer, targetShape) fmt.Fprint(writer, ``) @@ -934,7 +939,7 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske } fmt.Fprint(writer, out) } else { - drawTable(writer, targetShape) + drawTable(writer, diagramHash, targetShape) } addAppendixItems(writer, targetShape) fmt.Fprint(writer, ``) @@ -1675,7 +1680,7 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) { labelMasks = append(labelMasks, labelMask) } } else if s, is := obj.(d2target.Shape); is { - labelMask, err := drawShape(buf, s, sketchRunner) + labelMask, err := drawShape(buf, labelMaskID, s, sketchRunner) if err != nil { return nil, err } else if labelMask != "" { diff --git a/d2renderers/d2svg/table.go b/d2renderers/d2svg/table.go index e4f0695ac..e159a4155 100644 --- a/d2renderers/d2svg/table.go +++ b/d2renderers/d2svg/table.go @@ -12,12 +12,43 @@ import ( "oss.terrastruct.com/util-go/go2" ) -func tableHeader(shape d2target.Shape, box *geo.Box, text string, textWidth, textHeight, fontSize float64) string { +// this func helps define a clipPath for shape class and sql_table to draw border-radius +func clipPathForBorderRadius(diagramHash string, shape d2target.Shape) string { + box := geo.NewBox( + geo.NewPoint(float64(shape.Pos.X), float64(shape.Pos.Y)), + float64(shape.Width), + float64(shape.Height), + ) + topX, topY := box.TopLeft.X+box.Width, box.TopLeft.Y + + out := fmt.Sprintf(``, diagramHash, shape.ID) + out += fmt.Sprintf(` ` +} + +func tableHeader(diagramHash string, shape d2target.Shape, box *geo.Box, text string, textWidth, textHeight, fontSize float64) string { rectEl := d2themes.NewThemableElement("rect") rectEl.X, rectEl.Y = box.TopLeft.X, box.TopLeft.Y rectEl.Width, rectEl.Height = box.Width, box.Height rectEl.Fill = shape.Fill rectEl.ClassName = "class_header" + if shape.BorderRadius != 0 { + rectEl.ClipPath = fmt.Sprintf("%v-%v", diagramHash, shape.ID) + } str := rectEl.Render() if text != "" { @@ -82,7 +113,7 @@ func tableRow(shape d2target.Shape, box *geo.Box, nameText, typeText, constraint return out } -func drawTable(writer io.Writer, targetShape d2target.Shape) { +func drawTable(writer io.Writer, diagramHash string, targetShape d2target.Shape) { rectEl := d2themes.NewThemableElement("rect") rectEl.X = float64(targetShape.Pos.X) rectEl.Y = float64(targetShape.Pos.Y) @@ -91,6 +122,10 @@ func drawTable(writer io.Writer, targetShape d2target.Shape) { rectEl.Fill, rectEl.Stroke = d2themes.ShapeTheme(targetShape) rectEl.ClassName = "shape" rectEl.Style = targetShape.CSSStyle() + if targetShape.BorderRadius != 0 { + rectEl.Rx = float64(targetShape.BorderRadius) + rectEl.Ry = float64(targetShape.BorderRadius) + } fmt.Fprint(writer, rectEl.Render()) box := geo.NewBox( @@ -102,7 +137,7 @@ func drawTable(writer io.Writer, targetShape d2target.Shape) { headerBox := geo.NewBox(box.TopLeft, box.Width, rowHeight) fmt.Fprint(writer, - tableHeader(targetShape, headerBox, targetShape.Label, + tableHeader(diagramHash, targetShape, headerBox, targetShape.Label, float64(targetShape.LabelWidth), float64(targetShape.LabelHeight), float64(targetShape.FontSize)), ) @@ -113,15 +148,20 @@ func drawTable(writer io.Writer, targetShape d2target.Shape) { rowBox := geo.NewBox(box.TopLeft.Copy(), box.Width, rowHeight) rowBox.TopLeft.Y += headerBox.Height - for _, f := range targetShape.Columns { + for idx, f := range targetShape.Columns { fmt.Fprint(writer, tableRow(targetShape, rowBox, f.Name.Label, f.Type.Label, f.ConstraintAbbr(), float64(targetShape.FontSize), float64(longestNameWidth)), ) rowBox.TopLeft.Y += rowHeight lineEl := d2themes.NewThemableElement("line") - lineEl.X1, lineEl.Y1 = rowBox.TopLeft.X, rowBox.TopLeft.Y - lineEl.X2, lineEl.Y2 = rowBox.TopLeft.X+rowBox.Width, rowBox.TopLeft.Y + if idx == len(targetShape.Columns)-1 && targetShape.BorderRadius != 0 { + lineEl.X1, lineEl.Y1 = rowBox.TopLeft.X+float64(targetShape.BorderRadius), rowBox.TopLeft.Y + lineEl.X2, lineEl.Y2 = rowBox.TopLeft.X+rowBox.Width-float64(targetShape.BorderRadius), rowBox.TopLeft.Y + } else { + lineEl.X1, lineEl.Y1 = rowBox.TopLeft.X, rowBox.TopLeft.Y + lineEl.X2, lineEl.Y2 = rowBox.TopLeft.X+rowBox.Width, rowBox.TopLeft.Y + } lineEl.Stroke = targetShape.Fill lineEl.Style = "stroke-width:2" fmt.Fprint(writer, lineEl.Render()) diff --git a/d2themes/element.go b/d2themes/element.go index e881c0d78..319c0143a 100644 --- a/d2themes/element.go +++ b/d2themes/element.go @@ -45,7 +45,8 @@ type ThemableElement struct { Style string Attributes string - Content string + Content string + ClipPath string } func NewThemableElement(tag string) *ThemableElement { @@ -84,6 +85,7 @@ func NewThemableElement(tag string) *ThemableElement { "", "", "", + "", } } @@ -201,8 +203,13 @@ func (el *ThemableElement) Render() string { out += fmt.Sprintf(` %s`, el.Attributes) } + if len(el.ClipPath) > 0 { + out += fmt.Sprintf(` clip-path="url(#%s)"`, el.ClipPath) + } + if len(el.Content) > 0 { return fmt.Sprintf("%s>%s", out, el.Content, el.tag) } + return out + " />" } diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go index 5f3794027..60ec154ac 100644 --- a/e2etests/stable_test.go +++ b/e2etests/stable_test.go @@ -12,6 +12,49 @@ var testMarkdown string func testStable(t *testing.T) { tcs := []testCase{ + { + name: "class_and_sqlTable_border_radius", + script: ` + a: { + shape: sql_table + id: int {constraint: primary_key} + disk: int {constraint: foreign_key} + + json: jsonb {constraint: unique} + last_updated: timestamp with time zone + + style: { + fill: red + border-radius: 10 + } + } + + b: { + shape: class + + field: "[]string" + method(a uint64): (x, y int) + + style: { + border-radius: 10 + } + } + + c: { + shape: class + style: { + border-radius: 5 + } + } + + d: { + shape: sql_table + style: { + border-radius: 5 + } + } + `, + }, { name: "elk_border_radius", script: ` diff --git a/e2etests/testdata/stable/class_and_sqlTable_border_radius/dagre/board.exp.json b/e2etests/testdata/stable/class_and_sqlTable_border_radius/dagre/board.exp.json new file mode 100644 index 000000000..0836aabed --- /dev/null +++ b/e2etests/testdata/stable/class_and_sqlTable_border_radius/dagre/board.exp.json @@ -0,0 +1,345 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "sql_table", + "pos": { + "x": 0, + "y": 2 + }, + "width": 439, + "height": 180, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 10, + "fill": "red", + "stroke": "N7", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": [ + { + "name": { + "label": "id", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 15, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": "primary_key", + "reference": "" + }, + { + "name": { + "label": "disk", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 35, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": "foreign_key", + "reference": "" + }, + { + "name": { + "label": "json", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 36, + "labelHeight": 26 + }, + "type": { + "label": "jsonb", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 48, + "labelHeight": 26 + }, + "constraint": "unique", + "reference": "" + }, + { + "name": { + "label": "last_updated", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 110, + "labelHeight": 26 + }, + "type": { + "label": "timestamp with time zone", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 219, + "labelHeight": 26 + }, + "constraint": "", + "reference": "" + } + ], + "label": "a", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + }, + { + "id": "b", + "type": "class", + "pos": { + "x": 499, + "y": 0 + }, + "width": 407, + "height": 184, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 10, + "fill": "N1", + "stroke": "N7", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": [ + { + "name": "field", + "type": "[]string", + "visibility": "public" + } + ], + "methods": [ + { + "name": "method(a uint64)", + "return": "(x, y int)", + "visibility": "public" + } + ], + "columns": null, + "label": "b", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + }, + { + "id": "c", + "type": "class", + "pos": { + "x": 966, + "y": 46 + }, + "width": 117, + "height": 92, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 5, + "fill": "N1", + "stroke": "N7", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + }, + { + "id": "d", + "type": "sql_table", + "pos": { + "x": 1143, + "y": 74 + }, + "width": 50, + "height": 36, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 5, + "fill": "N1", + "stroke": "N7", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "d", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 13, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "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/stable/class_and_sqlTable_border_radius/dagre/sketch.exp.svg b/e2etests/testdata/stable/class_and_sqlTable_border_radius/dagre/sketch.exp.svg new file mode 100644 index 000000000..f8bb1122c --- /dev/null +++ b/e2etests/testdata/stable/class_and_sqlTable_border_radius/dagre/sketch.exp.svg @@ -0,0 +1,30 @@ + aidintPKdiskintFKjsonjsonbUNQlast_updatedtimestamp with time zone b+field[]string+method(a uint64)(x, y int) c d + + + \ No newline at end of file diff --git a/e2etests/testdata/stable/class_and_sqlTable_border_radius/elk/board.exp.json b/e2etests/testdata/stable/class_and_sqlTable_border_radius/elk/board.exp.json new file mode 100644 index 000000000..557561b09 --- /dev/null +++ b/e2etests/testdata/stable/class_and_sqlTable_border_radius/elk/board.exp.json @@ -0,0 +1,345 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "a", + "type": "sql_table", + "pos": { + "x": 12, + "y": 14 + }, + "width": 439, + "height": 180, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 10, + "fill": "red", + "stroke": "N7", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": [ + { + "name": { + "label": "id", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 15, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": "primary_key", + "reference": "" + }, + { + "name": { + "label": "disk", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 35, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": "foreign_key", + "reference": "" + }, + { + "name": { + "label": "json", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 36, + "labelHeight": 26 + }, + "type": { + "label": "jsonb", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 48, + "labelHeight": 26 + }, + "constraint": "unique", + "reference": "" + }, + { + "name": { + "label": "last_updated", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 110, + "labelHeight": 26 + }, + "type": { + "label": "timestamp with time zone", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 219, + "labelHeight": 26 + }, + "constraint": "", + "reference": "" + } + ], + "label": "a", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + }, + { + "id": "b", + "type": "class", + "pos": { + "x": 471, + "y": 12 + }, + "width": 407, + "height": 184, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 10, + "fill": "N1", + "stroke": "N7", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": [ + { + "name": "field", + "type": "[]string", + "visibility": "public" + } + ], + "methods": [ + { + "name": "method(a uint64)", + "return": "(x, y int)", + "visibility": "public" + } + ], + "columns": null, + "label": "b", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 11, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + }, + { + "id": "c", + "type": "class", + "pos": { + "x": 898, + "y": 58 + }, + "width": 117, + "height": 92, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 5, + "fill": "N1", + "stroke": "N7", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "c", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 12, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + }, + { + "id": "d", + "type": "sql_table", + "pos": { + "x": 1035, + "y": 86 + }, + "width": 50, + "height": 36, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 5, + "fill": "N1", + "stroke": "N7", + "shadow": false, + "3d": false, + "multiple": false, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "d", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 13, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + } + ], + "connections": [], + "root": { + "id": "", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 0, + "height": 0, + "opacity": 0, + "strokeDash": 0, + "strokeWidth": 0, + "borderRadius": 0, + "fill": "N7", + "stroke": "", + "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/stable/class_and_sqlTable_border_radius/elk/sketch.exp.svg b/e2etests/testdata/stable/class_and_sqlTable_border_radius/elk/sketch.exp.svg new file mode 100644 index 000000000..2b678bc5d --- /dev/null +++ b/e2etests/testdata/stable/class_and_sqlTable_border_radius/elk/sketch.exp.svg @@ -0,0 +1,30 @@ + aidintPKdiskintFKjsonjsonbUNQlast_updatedtimestamp with time zone b+field[]string+method(a uint64)(x, y int) c d + + + \ No newline at end of file