Merge pull request #1774 from alixander/sql_table_icon

allow icon for sql_table, class, code/md
This commit is contained in:
Alexander Wang 2023-12-12 09:32:58 -08:00 committed by GitHub
commit da3fa94689
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 3385 additions and 9 deletions

View file

@ -1,5 +1,7 @@
#### Features 🚀
- Icons can be added for special objects (sql_table, class, code, markdown, latex). [#1774](https://github.com/terrastruct/d2/pull/1774)
#### Improvements 🧹
#### Bugfixes ⛑️

View file

@ -1506,18 +1506,22 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
// give shapes with icons extra padding to fit their label
if obj.Icon != nil {
labelHeight := float64(labelDims.Height + INNER_LABEL_PADDING)
// Evenly pad enough to fit label above icon
if desiredWidth == 0 {
paddingX += labelHeight
}
if desiredHeight == 0 {
paddingY += labelHeight
switch shapeType {
case shape.TABLE_TYPE, shape.CLASS_TYPE, shape.CODE_TYPE, shape.TEXT_TYPE:
default:
labelHeight := float64(labelDims.Height + INNER_LABEL_PADDING)
// Evenly pad enough to fit label above icon
if desiredWidth == 0 {
paddingX += labelHeight
}
if desiredHeight == 0 {
paddingY += labelHeight
}
}
}
if desiredWidth == 0 {
switch shapeType {
case shape.TABLE_TYPE, shape.CLASS_TYPE, shape.CODE_TYPE, shape.IMAGE_TYPE:
case shape.TABLE_TYPE, shape.CLASS_TYPE, shape.CODE_TYPE:
default:
if obj.Link != nil {
paddingX += 32

View file

@ -554,6 +554,8 @@ func positionLabelsIcons(obj *d2graph.Object) {
obj.LabelPosition = go2.Pointer(label.OutsideTopRight.String())
return
}
} else if obj.SQLTable != nil || obj.Class != nil || obj.Language != "" {
obj.IconPosition = go2.Pointer(label.OutsideTopLeft.String())
} else {
obj.IconPosition = go2.Pointer(label.InsideMiddleCenter.String())
}

View file

@ -374,6 +374,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err
if hasTop || hasBottom {
padding := parsePadding(elkNodes[obj].LayoutOptions.Padding)
if hasTop {
// TODO I think this fails to account for a potential inner label of container
padding.top = go2.Max(padding.top, d2target.MAX_ICON_SIZE+2*label.PADDING)
}
if hasBottom {
@ -1207,6 +1208,8 @@ func positionLabelsIcons(obj *d2graph.Object) {
obj.LabelPosition = go2.Pointer(label.InsideTopRight.String())
return
}
} else if obj.SQLTable != nil || obj.Class != nil || obj.Language != "" {
obj.IconPosition = go2.Pointer(label.OutsideTopLeft.String())
} else {
obj.IconPosition = go2.Pointer(label.InsideMiddleCenter.String())
}

View file

@ -2,6 +2,7 @@ package d2svg
import (
"fmt"
"html"
"io"
"oss.terrastruct.com/d2/d2target"
@ -141,4 +142,19 @@ func drawClass(writer io.Writer, diagramHash string, targetShape d2target.Shape)
)
rowBox.TopLeft.Y += rowHeight
}
if targetShape.Icon != nil && targetShape.Type != d2target.ShapeImage {
iconPosition := label.FromString(targetShape.IconPosition)
iconSize := d2target.GetIconSize(box, targetShape.IconPosition)
tl := iconPosition.GetPointOnBox(box, label.PADDING, float64(iconSize), float64(iconSize))
fmt.Fprintf(writer, `<image href="%s" x="%f" y="%f" width="%d" height="%d" />`,
html.EscapeString(targetShape.Icon.String()),
tl.X,
tl.Y,
iconSize,
iconSize,
)
}
}

View file

@ -2,6 +2,7 @@ package d2svg
import (
"fmt"
"html"
"io"
"oss.terrastruct.com/d2/d2target"
@ -163,4 +164,19 @@ func drawTable(writer io.Writer, diagramHash string, targetShape d2target.Shape)
lineEl.Style = "stroke-width:2"
fmt.Fprint(writer, lineEl.Render())
}
if targetShape.Icon != nil && targetShape.Type != d2target.ShapeImage {
iconPosition := label.FromString(targetShape.IconPosition)
iconSize := d2target.GetIconSize(box, targetShape.IconPosition)
tl := iconPosition.GetPointOnBox(box, label.PADDING, float64(iconSize), float64(iconSize))
fmt.Fprintf(writer, `<image href="%s" x="%f" y="%f" width="%d" height="%d" />`,
html.EscapeString(targetShape.Icon.String()),
tl.X,
tl.Y,
iconSize,
iconSize,
)
}
}

View file

@ -999,7 +999,7 @@ func waitLogs(ctx context.Context, buf *bytes.Buffer, pattern *regexp.Regexp) (s
ticker := time.NewTicker(10 * time.Millisecond)
defer ticker.Stop()
var match string
for i := 0; i < 100 && match == ""; i++ {
for i := 0; i < 1000 && match == ""; i++ {
select {
case <-ticker.C:
out := buf.String()

View file

@ -10,6 +10,7 @@ import (
"testing"
"cdr.dev/slog"
"golang.org/x/tools/txtar"
trequire "github.com/stretchr/testify/require"
@ -42,6 +43,7 @@ func TestE2E(t *testing.T) {
t.Run("unicode", testUnicode)
t.Run("root", testRoot)
t.Run("themes", testThemes)
t.Run("txtar", testTxtar)
}
func testSanity(t *testing.T) {
@ -75,6 +77,19 @@ a -> c
runa(t, tcs)
}
func testTxtar(t *testing.T) {
var tcs []testCase
archive, err := txtar.ParseFile("./testdata/txtar.txt")
assert.Success(t, err)
for _, f := range archive.Files {
tcs = append(tcs, testCase{
name: f.Name,
script: string(f.Data),
})
}
runa(t, tcs)
}
type testCase struct {
name string
// if the test is just testing a render/style thing, no need to exercise both engines

49
e2etests/testdata/txtar.txt vendored Normal file
View file

@ -0,0 +1,49 @@
-- sql-icon --
without: {
tableEx: {
shape: sql_table
a: b
}
classEx: {
shape: class
a: b
}
codeEx: |go
a := 1
|
mdEx: |md
# This is for all ill-treated fellows
You will live a long, healthy, happy life and make bags of money.
|
}
with: {
tableEx: {
shape: sql_table
a: b
icon: https://icons.terrastruct.com/essentials%2F213-alarm.svg
}
classEx: {
shape: class
a: b
icon: https://icons.terrastruct.com/essentials%2F213-alarm.svg
}
codeEx: |go
a := 1
| {
icon: https://icons.terrastruct.com/essentials%2F213-alarm.svg
}
mdEx: |md
# This is for all ill-treated fellows
You will live a long, healthy, happy life and make bags of money.
| {
icon: https://icons.terrastruct.com/essentials%2F213-alarm.svg
}
}
without.tableEx -> with.tableEx
without.classEx -> with.classEx
without.codeEx -> with.codeEx
without.mdEx -> with.mdEx

817
e2etests/testdata/txtar/sql-icon/dagre/board.exp.json generated vendored Normal file
View file

@ -0,0 +1,817 @@
{
"name": "",
"isFolderOnly": false,
"fontFamily": "SourceSansPro",
"shapes": [
{
"id": "without",
"type": "rectangle",
"pos": {
"x": 10,
"y": -4
},
"width": 1052,
"height": 198,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "B4",
"stroke": "B1",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "without",
"fontSize": 28,
"fontFamily": "DEFAULT",
"language": "",
"color": "N1",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 93,
"labelHeight": 36,
"labelPosition": "OUTSIDE_TOP_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "without.tableEx",
"type": "sql_table",
"pos": {
"x": 40,
"y": 59
},
"width": 106,
"height": 72,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"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": [
{
"name": {
"label": "a",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 8,
"labelHeight": 26
},
"type": {
"label": "b",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 10,
"labelHeight": 26
},
"constraint": null,
"reference": ""
}
],
"label": "tableEx",
"fontSize": 20,
"fontFamily": "DEFAULT",
"language": "",
"color": "N1",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 81,
"labelHeight": 31,
"zIndex": 0,
"level": 2,
"primaryAccentColor": "B2",
"secondaryAccentColor": "AA2",
"neutralAccentColor": "N2"
},
{
"id": "without.classEx",
"type": "class",
"pos": {
"x": 206,
"y": 26
},
"width": 204,
"height": 138,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "N1",
"stroke": "N7",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": [
{
"name": "a",
"type": "b",
"visibility": "public"
}
],
"methods": null,
"columns": null,
"label": "classEx",
"fontSize": 20,
"fontFamily": "DEFAULT",
"language": "",
"color": "N1",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 99,
"labelHeight": 31,
"zIndex": 0,
"level": 2,
"primaryAccentColor": "B2",
"secondaryAccentColor": "AA2",
"neutralAccentColor": "N2"
},
{
"id": "without.codeEx",
"type": "code",
"pos": {
"x": 470,
"y": 77
},
"width": 74,
"height": 37,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "N7",
"stroke": "N1",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "a := 1",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "golang",
"color": "N1",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 58,
"labelHeight": 21,
"zIndex": 0,
"level": 2
},
{
"id": "without.mdEx",
"type": "text",
"pos": {
"x": 604,
"y": 50
},
"width": 428,
"height": 91,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "transparent",
"stroke": "N1",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "# This is for all ill-treated fellows\n\nYou will live a long, healthy, happy life and make bags of money.",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "markdown",
"color": "N1",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 428,
"labelHeight": 91,
"zIndex": 0,
"level": 2
},
{
"id": "with",
"type": "rectangle",
"pos": {
"x": 10,
"y": 314
},
"width": 1052,
"height": 242,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "B4",
"stroke": "B1",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "with",
"fontSize": 28,
"fontFamily": "DEFAULT",
"language": "",
"color": "N1",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 51,
"labelHeight": 36,
"labelPosition": "OUTSIDE_TOP_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "with.tableEx",
"type": "sql_table",
"pos": {
"x": 40,
"y": 421
},
"width": 106,
"height": 72,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "N1",
"stroke": "N7",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": {
"Scheme": "https",
"Opaque": "",
"User": null,
"Host": "icons.terrastruct.com",
"Path": "/essentials/213-alarm.svg",
"RawPath": "/essentials%2F213-alarm.svg",
"OmitHost": false,
"ForceQuery": false,
"RawQuery": "",
"Fragment": "",
"RawFragment": ""
},
"iconPosition": "OUTSIDE_TOP_LEFT",
"blend": false,
"fields": null,
"methods": null,
"columns": [
{
"name": {
"label": "a",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 8,
"labelHeight": 26
},
"type": {
"label": "b",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 10,
"labelHeight": 26
},
"constraint": null,
"reference": ""
}
],
"label": "tableEx",
"fontSize": 20,
"fontFamily": "DEFAULT",
"language": "",
"color": "N1",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 81,
"labelHeight": 31,
"zIndex": 0,
"level": 2,
"primaryAccentColor": "B2",
"secondaryAccentColor": "AA2",
"neutralAccentColor": "N2"
},
{
"id": "with.classEx",
"type": "class",
"pos": {
"x": 206,
"y": 388
},
"width": 204,
"height": 138,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "N1",
"stroke": "N7",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": {
"Scheme": "https",
"Opaque": "",
"User": null,
"Host": "icons.terrastruct.com",
"Path": "/essentials/213-alarm.svg",
"RawPath": "/essentials%2F213-alarm.svg",
"OmitHost": false,
"ForceQuery": false,
"RawQuery": "",
"Fragment": "",
"RawFragment": ""
},
"iconPosition": "OUTSIDE_TOP_LEFT",
"blend": false,
"fields": [
{
"name": "a",
"type": "b",
"visibility": "public"
}
],
"methods": null,
"columns": null,
"label": "classEx",
"fontSize": 20,
"fontFamily": "DEFAULT",
"language": "",
"color": "N1",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 99,
"labelHeight": 31,
"zIndex": 0,
"level": 2,
"primaryAccentColor": "B2",
"secondaryAccentColor": "AA2",
"neutralAccentColor": "N2"
},
{
"id": "with.codeEx",
"type": "code",
"pos": {
"x": 470,
"y": 439
},
"width": 74,
"height": 37,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "N7",
"stroke": "N1",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": {
"Scheme": "https",
"Opaque": "",
"User": null,
"Host": "icons.terrastruct.com",
"Path": "/essentials/213-alarm.svg",
"RawPath": "/essentials%2F213-alarm.svg",
"OmitHost": false,
"ForceQuery": false,
"RawQuery": "",
"Fragment": "",
"RawFragment": ""
},
"iconPosition": "OUTSIDE_TOP_LEFT",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "a := 1",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "golang",
"color": "N1",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 58,
"labelHeight": 21,
"zIndex": 0,
"level": 2
},
{
"id": "with.mdEx",
"type": "text",
"pos": {
"x": 604,
"y": 412
},
"width": 428,
"height": 91,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "transparent",
"stroke": "N1",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": {
"Scheme": "https",
"Opaque": "",
"User": null,
"Host": "icons.terrastruct.com",
"Path": "/essentials/213-alarm.svg",
"RawPath": "/essentials%2F213-alarm.svg",
"OmitHost": false,
"ForceQuery": false,
"RawQuery": "",
"Fragment": "",
"RawFragment": ""
},
"iconPosition": "OUTSIDE_TOP_LEFT",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "# This is for all ill-treated fellows\n\nYou will live a long, healthy, happy life and make bags of money.",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "markdown",
"color": "N1",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 428,
"labelHeight": 91,
"zIndex": 0,
"level": 2
}
],
"connections": [
{
"id": "(without.tableEx -> with.tableEx)[0]",
"src": "without.tableEx",
"srcArrow": "none",
"dst": "with.tableEx",
"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,
"route": [
{
"x": 93,
"y": 131
},
{
"x": 93,
"y": 197.39999389648438
},
{
"x": 93,
"y": 224
},
{
"x": 93,
"y": 239
},
{
"x": 93,
"y": 254
},
{
"x": 93,
"y": 335.3999938964844
},
{
"x": 93,
"y": 421
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(without.classEx -> with.classEx)[0]",
"src": "without.classEx",
"srcArrow": "none",
"dst": "with.classEx",
"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,
"route": [
{
"x": 308,
"y": 164
},
{
"x": 308,
"y": 204
},
{
"x": 308,
"y": 224
},
{
"x": 308,
"y": 239
},
{
"x": 308,
"y": 254
},
{
"x": 308,
"y": 328.79998779296875
},
{
"x": 308,
"y": 388
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(without.codeEx -> with.codeEx)[0]",
"src": "without.codeEx",
"srcArrow": "none",
"dst": "with.codeEx",
"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,
"route": [
{
"x": 507,
"y": 114.5
},
{
"x": 507,
"y": 194.10000610351562
},
{
"x": 507,
"y": 224
},
{
"x": 507,
"y": 239
},
{
"x": 507,
"y": 254
},
{
"x": 507,
"y": 338.8999938964844
},
{
"x": 507,
"y": 438.5
}
],
"isCurve": true,
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(without.mdEx -> with.mdEx)[0]",
"src": "without.mdEx",
"srcArrow": "none",
"dst": "with.mdEx",
"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,
"route": [
{
"x": 818,
"y": 141.5
},
{
"x": 818,
"y": 199.5
},
{
"x": 818,
"y": 224
},
{
"x": 818,
"y": 239
},
{
"x": 818,
"y": 254
},
{
"x": 818,
"y": 333.5
},
{
"x": 818,
"y": 411.5
}
],
"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": "",
"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
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 50 KiB

733
e2etests/testdata/txtar/sql-icon/elk/board.exp.json generated vendored Normal file
View file

@ -0,0 +1,733 @@
{
"name": "",
"isFolderOnly": false,
"fontFamily": "SourceSansPro",
"shapes": [
{
"id": "without",
"type": "rectangle",
"pos": {
"x": 12,
"y": 12
},
"width": 972,
"height": 238,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "B4",
"stroke": "B1",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "without",
"fontSize": 28,
"fontFamily": "DEFAULT",
"language": "",
"color": "N1",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 93,
"labelHeight": 36,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "without.tableEx",
"type": "sql_table",
"pos": {
"x": 62,
"y": 128
},
"width": 106,
"height": 72,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"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": [
{
"name": {
"label": "a",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 8,
"labelHeight": 26
},
"type": {
"label": "b",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 10,
"labelHeight": 26
},
"constraint": null,
"reference": ""
}
],
"label": "tableEx",
"fontSize": 20,
"fontFamily": "DEFAULT",
"language": "",
"color": "N1",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 81,
"labelHeight": 31,
"zIndex": 0,
"level": 2,
"primaryAccentColor": "B2",
"secondaryAccentColor": "AA2",
"neutralAccentColor": "N2"
},
{
"id": "without.classEx",
"type": "class",
"pos": {
"x": 188,
"y": 62
},
"width": 204,
"height": 138,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "N1",
"stroke": "N7",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": [
{
"name": "a",
"type": "b",
"visibility": "public"
}
],
"methods": null,
"columns": null,
"label": "classEx",
"fontSize": 20,
"fontFamily": "DEFAULT",
"language": "",
"color": "N1",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 99,
"labelHeight": 31,
"zIndex": 0,
"level": 2,
"primaryAccentColor": "B2",
"secondaryAccentColor": "AA2",
"neutralAccentColor": "N2"
},
{
"id": "without.codeEx",
"type": "code",
"pos": {
"x": 412,
"y": 163
},
"width": 74,
"height": 37,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "N7",
"stroke": "N1",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "a := 1",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "golang",
"color": "N1",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 58,
"labelHeight": 21,
"zIndex": 0,
"level": 2
},
{
"id": "without.mdEx",
"type": "text",
"pos": {
"x": 506,
"y": 109
},
"width": 428,
"height": 91,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "transparent",
"stroke": "N1",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "# This is for all ill-treated fellows\n\nYou will live a long, healthy, happy life and make bags of money.",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "markdown",
"color": "N1",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 428,
"labelHeight": 91,
"zIndex": 0,
"level": 2
},
{
"id": "with",
"type": "rectangle",
"pos": {
"x": 12,
"y": 330
},
"width": 972,
"height": 262,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "B4",
"stroke": "B1",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": null,
"iconPosition": "",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "with",
"fontSize": 28,
"fontFamily": "DEFAULT",
"language": "",
"color": "N1",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 51,
"labelHeight": 36,
"labelPosition": "INSIDE_TOP_CENTER",
"zIndex": 0,
"level": 1
},
{
"id": "with.tableEx",
"type": "sql_table",
"pos": {
"x": 62,
"y": 404
},
"width": 106,
"height": 72,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "N1",
"stroke": "N7",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": {
"Scheme": "https",
"Opaque": "",
"User": null,
"Host": "icons.terrastruct.com",
"Path": "/essentials/213-alarm.svg",
"RawPath": "/essentials%2F213-alarm.svg",
"OmitHost": false,
"ForceQuery": false,
"RawQuery": "",
"Fragment": "",
"RawFragment": ""
},
"iconPosition": "OUTSIDE_TOP_LEFT",
"blend": false,
"fields": null,
"methods": null,
"columns": [
{
"name": {
"label": "a",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 8,
"labelHeight": 26
},
"type": {
"label": "b",
"fontSize": 0,
"fontFamily": "",
"language": "",
"color": "",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 10,
"labelHeight": 26
},
"constraint": null,
"reference": ""
}
],
"label": "tableEx",
"fontSize": 20,
"fontFamily": "DEFAULT",
"language": "",
"color": "N1",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 81,
"labelHeight": 31,
"zIndex": 0,
"level": 2,
"primaryAccentColor": "B2",
"secondaryAccentColor": "AA2",
"neutralAccentColor": "N2"
},
{
"id": "with.classEx",
"type": "class",
"pos": {
"x": 188,
"y": 404
},
"width": 204,
"height": 138,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "N1",
"stroke": "N7",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": {
"Scheme": "https",
"Opaque": "",
"User": null,
"Host": "icons.terrastruct.com",
"Path": "/essentials/213-alarm.svg",
"RawPath": "/essentials%2F213-alarm.svg",
"OmitHost": false,
"ForceQuery": false,
"RawQuery": "",
"Fragment": "",
"RawFragment": ""
},
"iconPosition": "OUTSIDE_TOP_LEFT",
"blend": false,
"fields": [
{
"name": "a",
"type": "b",
"visibility": "public"
}
],
"methods": null,
"columns": null,
"label": "classEx",
"fontSize": 20,
"fontFamily": "DEFAULT",
"language": "",
"color": "N1",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 99,
"labelHeight": 31,
"zIndex": 0,
"level": 2,
"primaryAccentColor": "B2",
"secondaryAccentColor": "AA2",
"neutralAccentColor": "N2"
},
{
"id": "with.codeEx",
"type": "code",
"pos": {
"x": 412,
"y": 404
},
"width": 74,
"height": 37,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "N7",
"stroke": "N1",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": {
"Scheme": "https",
"Opaque": "",
"User": null,
"Host": "icons.terrastruct.com",
"Path": "/essentials/213-alarm.svg",
"RawPath": "/essentials%2F213-alarm.svg",
"OmitHost": false,
"ForceQuery": false,
"RawQuery": "",
"Fragment": "",
"RawFragment": ""
},
"iconPosition": "OUTSIDE_TOP_LEFT",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "a := 1",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "golang",
"color": "N1",
"italic": false,
"bold": true,
"underline": false,
"labelWidth": 58,
"labelHeight": 21,
"zIndex": 0,
"level": 2
},
{
"id": "with.mdEx",
"type": "text",
"pos": {
"x": 506,
"y": 404
},
"width": 428,
"height": 91,
"opacity": 1,
"strokeDash": 0,
"strokeWidth": 2,
"borderRadius": 0,
"fill": "transparent",
"stroke": "N1",
"shadow": false,
"3d": false,
"multiple": false,
"double-border": false,
"tooltip": "",
"link": "",
"icon": {
"Scheme": "https",
"Opaque": "",
"User": null,
"Host": "icons.terrastruct.com",
"Path": "/essentials/213-alarm.svg",
"RawPath": "/essentials%2F213-alarm.svg",
"OmitHost": false,
"ForceQuery": false,
"RawQuery": "",
"Fragment": "",
"RawFragment": ""
},
"iconPosition": "OUTSIDE_TOP_LEFT",
"blend": false,
"fields": null,
"methods": null,
"columns": null,
"label": "# This is for all ill-treated fellows\n\nYou will live a long, healthy, happy life and make bags of money.",
"fontSize": 16,
"fontFamily": "DEFAULT",
"language": "markdown",
"color": "N1",
"italic": false,
"bold": false,
"underline": false,
"labelWidth": 428,
"labelHeight": 91,
"zIndex": 0,
"level": 2
}
],
"connections": [
{
"id": "(without.tableEx -> with.tableEx)[0]",
"src": "without.tableEx",
"srcArrow": "none",
"dst": "with.tableEx",
"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,
"route": [
{
"x": 115,
"y": 200
},
{
"x": 115,
"y": 404
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(without.classEx -> with.classEx)[0]",
"src": "without.classEx",
"srcArrow": "none",
"dst": "with.classEx",
"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,
"route": [
{
"x": 290,
"y": 200
},
{
"x": 290,
"y": 404
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(without.codeEx -> with.codeEx)[0]",
"src": "without.codeEx",
"srcArrow": "none",
"dst": "with.codeEx",
"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,
"route": [
{
"x": 449,
"y": 200
},
{
"x": 449,
"y": 404
}
],
"animated": false,
"tooltip": "",
"icon": null,
"zIndex": 0
},
{
"id": "(without.mdEx -> with.mdEx)[0]",
"src": "without.mdEx",
"srcArrow": "none",
"dst": "with.mdEx",
"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,
"route": [
{
"x": 720,
"y": 200
},
{
"x": 720,
"y": 404
}
],
"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": "",
"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
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 50 KiB

1
go.mod generated
View file

@ -24,6 +24,7 @@ require (
golang.org/x/image v0.14.0
golang.org/x/net v0.19.0
golang.org/x/text v0.14.0
golang.org/x/tools v0.16.0
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028
gonum.org/v1/plot v0.14.0
nhooyr.io/websocket v1.8.10

2
go.sum generated
View file

@ -266,6 +266,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=