commit
42e11d1e63
9 changed files with 2913 additions and 1 deletions
|
|
@ -3,7 +3,9 @@
|
|||
- Icons: connections can include icons [#12](https://github.com/terrastruct/d2/issues/12)
|
||||
- Syntax: `suspend`/`unsuspend` to define models and instantiate them [#2394](https://github.com/terrastruct/d2/pull/2394)
|
||||
- Globs: support for filtering edges based on properties of endpoint nodes (e.g., `&src.style.fill: blue`) [#2395](https://github.com/terrastruct/d2/pull/2395)
|
||||
- Render: markdown, latex, and code can be used as object labels [#2204](https://github.com/terrastruct/d2/pull/2204/files)
|
||||
- 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)
|
||||
|
||||
#### Improvements 🧹
|
||||
|
||||
|
|
|
|||
|
|
@ -933,6 +933,7 @@ const (
|
|||
ShapeCallout = "callout"
|
||||
ShapeStoredData = "stored_data"
|
||||
ShapePerson = "person"
|
||||
ShapeC4Person = "c4-person"
|
||||
ShapeDiamond = "diamond"
|
||||
ShapeOval = "oval"
|
||||
ShapeCircle = "circle"
|
||||
|
|
@ -960,6 +961,7 @@ var Shapes = []string{
|
|||
ShapeCallout,
|
||||
ShapeStoredData,
|
||||
ShapePerson,
|
||||
ShapeC4Person,
|
||||
ShapeDiamond,
|
||||
ShapeOval,
|
||||
ShapeCircle,
|
||||
|
|
@ -1028,6 +1030,7 @@ var DSL_SHAPE_TO_SHAPE_TYPE = map[string]string{
|
|||
ShapeCallout: shape.CALLOUT_TYPE,
|
||||
ShapeStoredData: shape.STORED_DATA_TYPE,
|
||||
ShapePerson: shape.PERSON_TYPE,
|
||||
ShapeC4Person: shape.C4_PERSON_TYPE,
|
||||
ShapeDiamond: shape.DIAMOND_TYPE,
|
||||
ShapeOval: shape.OVAL_TYPE,
|
||||
ShapeCircle: shape.CIRCLE_TYPE,
|
||||
|
|
|
|||
502
e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json
generated
vendored
Normal file
502
e2etests/testdata/txtar/c4-person-shape/dagre/board.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,502 @@
|
|||
{
|
||||
"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": 544
|
||||
},
|
||||
"width": 312,
|
||||
"height": 350,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 1,
|
||||
"borderRadius": 0,
|
||||
"fill": "#08427b",
|
||||
"stroke": "black",
|
||||
"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\\\npersonal bank accounts",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "markdown",
|
||||
"color": "white",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 287,
|
||||
"labelHeight": 143,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "c4person",
|
||||
"type": "c4-person",
|
||||
"pos": {
|
||||
"x": 244,
|
||||
"y": 0
|
||||
},
|
||||
"width": 135,
|
||||
"height": 152,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 1,
|
||||
"borderRadius": 0,
|
||||
"fill": "#08427b",
|
||||
"stroke": "black",
|
||||
"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 Style Person",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "white",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 110,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "regular_person",
|
||||
"type": "person",
|
||||
"pos": {
|
||||
"x": 89,
|
||||
"y": 339
|
||||
},
|
||||
"width": 134,
|
||||
"height": 89,
|
||||
"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": "Standard Person",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 119,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "OUTSIDE_BOTTOM_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "styling",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 362,
|
||||
"y": 293
|
||||
},
|
||||
"width": 210,
|
||||
"height": 546,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "B4",
|
||||
"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": "styling",
|
||||
"fontSize": 28,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 78,
|
||||
"labelHeight": 36,
|
||||
"labelPosition": "OUTSIDE_TOP_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "styling.c4styled",
|
||||
"type": "c4-person",
|
||||
"pos": {
|
||||
"x": 425,
|
||||
"y": 323
|
||||
},
|
||||
"width": 85,
|
||||
"height": 121,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 1,
|
||||
"borderRadius": 0,
|
||||
"fill": "#08427b",
|
||||
"stroke": "black",
|
||||
"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": "c4styled",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "white",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 60,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 2
|
||||
},
|
||||
{
|
||||
"id": "styling.c4sized",
|
||||
"type": "c4-person",
|
||||
"pos": {
|
||||
"x": 392,
|
||||
"y": 629
|
||||
},
|
||||
"width": 150,
|
||||
"height": 180,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 1,
|
||||
"borderRadius": 0,
|
||||
"fill": "#08427b",
|
||||
"stroke": "black",
|
||||
"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": "Custom Size",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "white",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 87,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 2
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"id": "(regular_person -> c4mdperson)[0]",
|
||||
"src": "regular_person",
|
||||
"srcArrow": "none",
|
||||
"dst": "c4mdperson",
|
||||
"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": 156,
|
||||
"y": 454
|
||||
},
|
||||
{
|
||||
"x": 156,
|
||||
"y": 486
|
||||
},
|
||||
{
|
||||
"x": 156,
|
||||
"y": 502.79998779296875
|
||||
},
|
||||
{
|
||||
"x": 156,
|
||||
"y": 538
|
||||
}
|
||||
],
|
||||
"isCurve": true,
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "(c4person -> regular_person)[0]",
|
||||
"src": "c4person",
|
||||
"srcArrow": "none",
|
||||
"dst": "regular_person",
|
||||
"dstArrow": "triangle",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "B1",
|
||||
"borderRadius": 10,
|
||||
"label": "Compare shapes",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N2",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 111,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"link": "",
|
||||
"route": [
|
||||
{
|
||||
"x": 245,
|
||||
"y": 135
|
||||
},
|
||||
{
|
||||
"x": 173.8000030517578,
|
||||
"y": 197
|
||||
},
|
||||
{
|
||||
"x": 156,
|
||||
"y": 286.20001220703125
|
||||
},
|
||||
{
|
||||
"x": 156,
|
||||
"y": 339
|
||||
}
|
||||
],
|
||||
"isCurve": true,
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "(c4person -> styling.c4styled)[0]",
|
||||
"src": "c4person",
|
||||
"srcArrow": "none",
|
||||
"dst": "styling.c4styled",
|
||||
"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": 379,
|
||||
"y": 135
|
||||
},
|
||||
{
|
||||
"x": 449.3999938964844,
|
||||
"y": 197
|
||||
},
|
||||
{
|
||||
"x": 467,
|
||||
"y": 283.6000061035156
|
||||
},
|
||||
{
|
||||
"x": 467,
|
||||
"y": 326
|
||||
}
|
||||
],
|
||||
"isCurve": true,
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "styling.(c4styled -> c4sized)[0]",
|
||||
"src": "styling.c4styled",
|
||||
"srcArrow": "none",
|
||||
"dst": "styling.c4sized",
|
||||
"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": 467,
|
||||
"y": 445
|
||||
},
|
||||
{
|
||||
"x": 467,
|
||||
"y": 484.20001220703125
|
||||
},
|
||||
{
|
||||
"x": 467,
|
||||
"y": 520.7990112304688
|
||||
},
|
||||
{
|
||||
"x": 467,
|
||||
"y": 628
|
||||
}
|
||||
],
|
||||
"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
|
||||
}
|
||||
}
|
||||
859
e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg
vendored
Normal file
859
e2etests/testdata/txtar/c4-person-shape/dagre/sketch.exp.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 46 KiB |
482
e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json
generated
vendored
Normal file
482
e2etests/testdata/txtar/c4-person-shape/elk/board.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,482 @@
|
|||
{
|
||||
"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": 975
|
||||
},
|
||||
"width": 312,
|
||||
"height": 350,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 1,
|
||||
"borderRadius": 0,
|
||||
"fill": "#08427b",
|
||||
"stroke": "black",
|
||||
"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\\\npersonal bank accounts",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "markdown",
|
||||
"color": "white",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 287,
|
||||
"labelHeight": 143,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "c4person",
|
||||
"type": "c4-person",
|
||||
"pos": {
|
||||
"x": 201,
|
||||
"y": 12
|
||||
},
|
||||
"width": 135,
|
||||
"height": 152,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 1,
|
||||
"borderRadius": 0,
|
||||
"fill": "#08427b",
|
||||
"stroke": "black",
|
||||
"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 Style Person",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "white",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 110,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "regular_person",
|
||||
"type": "person",
|
||||
"pos": {
|
||||
"x": 101,
|
||||
"y": 790
|
||||
},
|
||||
"width": 134,
|
||||
"height": 89,
|
||||
"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": "Standard Person",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 119,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "OUTSIDE_BOTTOM_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "styling",
|
||||
"type": "rectangle",
|
||||
"pos": {
|
||||
"x": 244,
|
||||
"y": 249
|
||||
},
|
||||
"width": 250,
|
||||
"height": 471,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "B4",
|
||||
"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": "styling",
|
||||
"fontSize": 28,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N1",
|
||||
"italic": false,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 78,
|
||||
"labelHeight": 36,
|
||||
"labelPosition": "INSIDE_TOP_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1
|
||||
},
|
||||
{
|
||||
"id": "styling.c4styled",
|
||||
"type": "c4-person",
|
||||
"pos": {
|
||||
"x": 327,
|
||||
"y": 299
|
||||
},
|
||||
"width": 85,
|
||||
"height": 121,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 1,
|
||||
"borderRadius": 0,
|
||||
"fill": "#08427b",
|
||||
"stroke": "black",
|
||||
"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": "c4styled",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "white",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 60,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 2
|
||||
},
|
||||
{
|
||||
"id": "styling.c4sized",
|
||||
"type": "c4-person",
|
||||
"pos": {
|
||||
"x": 294,
|
||||
"y": 490
|
||||
},
|
||||
"width": 150,
|
||||
"height": 180,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 1,
|
||||
"borderRadius": 0,
|
||||
"fill": "#08427b",
|
||||
"stroke": "black",
|
||||
"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": "Custom Size",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "white",
|
||||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 87,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 2
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"id": "(regular_person -> c4mdperson)[0]",
|
||||
"src": "regular_person",
|
||||
"srcArrow": "none",
|
||||
"dst": "c4mdperson",
|
||||
"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": 168,
|
||||
"y": 905
|
||||
},
|
||||
{
|
||||
"x": 168,
|
||||
"y": 969
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "(c4person -> regular_person)[0]",
|
||||
"src": "c4person",
|
||||
"srcArrow": "none",
|
||||
"dst": "regular_person",
|
||||
"dstArrow": "triangle",
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "B1",
|
||||
"borderRadius": 10,
|
||||
"label": "Compare shapes",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N2",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 111,
|
||||
"labelHeight": 21,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"labelPercentage": 0,
|
||||
"link": "",
|
||||
"route": [
|
||||
{
|
||||
"x": 246,
|
||||
"y": 165
|
||||
},
|
||||
{
|
||||
"x": 246.25,
|
||||
"y": 204
|
||||
},
|
||||
{
|
||||
"x": 168,
|
||||
"y": 204
|
||||
},
|
||||
{
|
||||
"x": 168,
|
||||
"y": 790
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "(c4person -> styling.c4styled)[0]",
|
||||
"src": "c4person",
|
||||
"srcArrow": "none",
|
||||
"dst": "styling.c4styled",
|
||||
"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": 291,
|
||||
"y": 165
|
||||
},
|
||||
{
|
||||
"x": 291.25,
|
||||
"y": 204
|
||||
},
|
||||
{
|
||||
"x": 369.5,
|
||||
"y": 204
|
||||
},
|
||||
{
|
||||
"x": 370,
|
||||
"y": 302
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 0
|
||||
},
|
||||
{
|
||||
"id": "styling.(c4styled -> c4sized)[0]",
|
||||
"src": "styling.c4styled",
|
||||
"srcArrow": "none",
|
||||
"dst": "styling.c4sized",
|
||||
"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": 369,
|
||||
"y": 421
|
||||
},
|
||||
{
|
||||
"x": 370,
|
||||
"y": 489
|
||||
}
|
||||
],
|
||||
"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
|
||||
}
|
||||
}
|
||||
859
e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg
vendored
Normal file
859
e2etests/testdata/txtar/c4-person-shape/elk/sketch.exp.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 46 KiB |
|
|
@ -978,3 +978,51 @@ cloud: |md
|
|||
|
||||
blah blah
|
||||
|
|
||||
|
||||
-- c4-person-shape --
|
||||
c4mdperson.shape: c4-person
|
||||
c4mdperson: |md
|
||||
## Personal Banking Customer
|
||||
|
||||
[person]
|
||||
|
||||
A customer of the bank, with\
|
||||
personal bank accounts
|
||||
|
|
||||
c4person: {
|
||||
shape: c4-person
|
||||
label: "C4 Style Person"
|
||||
}
|
||||
regular_person -> c4mdperson
|
||||
|
||||
regular_person: {
|
||||
shape: person
|
||||
label: "Standard Person"
|
||||
}
|
||||
|
||||
c4person -> regular_person: "Compare shapes"
|
||||
|
||||
styling: {
|
||||
c4styled: {
|
||||
shape: c4-person
|
||||
style.fill: "#91BEEA"
|
||||
style.stroke: "#2E6195"
|
||||
style.stroke-width: 2
|
||||
}
|
||||
|
||||
c4sized: {
|
||||
shape: c4-person
|
||||
width: 150
|
||||
height: 180
|
||||
label: "Custom Size"
|
||||
}
|
||||
}
|
||||
|
||||
c4person -> styling.c4styled -> styling.c4sized
|
||||
**: {
|
||||
&shape: c4-person
|
||||
style.fill: "#08427b"
|
||||
style.stroke: black
|
||||
style.font-color: white
|
||||
style.stroke-width: 1
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ const (
|
|||
CALLOUT_TYPE = "Callout"
|
||||
STORED_DATA_TYPE = "StoredData"
|
||||
PERSON_TYPE = "Person"
|
||||
C4_PERSON_TYPE = "c4-person"
|
||||
DIAMOND_TYPE = "Diamond"
|
||||
OVAL_TYPE = "Oval"
|
||||
CIRCLE_TYPE = "Circle"
|
||||
|
|
@ -155,6 +156,8 @@ func NewShape(shapeType string, box *geo.Box) Shape {
|
|||
return NewParallelogram(box)
|
||||
case PERSON_TYPE:
|
||||
return NewPerson(box)
|
||||
case C4_PERSON_TYPE:
|
||||
return NewC4Person(box)
|
||||
case QUEUE_TYPE:
|
||||
return NewQueue(box)
|
||||
case REAL_SQUARE_TYPE:
|
||||
|
|
|
|||
154
lib/shape/shape_c4_person.go
Normal file
154
lib/shape/shape_c4_person.go
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
package shape
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"oss.terrastruct.com/d2/lib/geo"
|
||||
"oss.terrastruct.com/d2/lib/svg"
|
||||
"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
|
||||
|
||||
type shapeC4Person struct {
|
||||
*baseShape
|
||||
}
|
||||
|
||||
func NewC4Person(box *geo.Box) Shape {
|
||||
shape := shapeC4Person{
|
||||
baseShape: &baseShape{
|
||||
Type: C4_PERSON_TYPE,
|
||||
Box: box,
|
||||
},
|
||||
}
|
||||
shape.FullShape = go2.Pointer(Shape(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
|
||||
|
||||
tl := s.Box.TopLeft.Copy()
|
||||
horizontalPadding := width * 0.1
|
||||
tl.X += horizontalPadding
|
||||
tl.Y += bodyTop + height*0.05
|
||||
|
||||
innerWidth := width - (horizontalPadding * 2)
|
||||
innerHeight := height - tl.Y + s.Box.TopLeft.Y - (height * 0.05)
|
||||
|
||||
return geo.NewBox(tl, innerWidth, innerHeight)
|
||||
}
|
||||
|
||||
func bodyPath(box *geo.Box) *svg.SvgPathContext {
|
||||
width := box.Width
|
||||
height := box.Height
|
||||
|
||||
pc := svg.NewSVGPathContext(box.TopLeft, 1, 1)
|
||||
|
||||
headRadius := width * 0.22
|
||||
headCenterY := height * 0.18
|
||||
bodyTop := headCenterY + headRadius*0.8
|
||||
bodyWidth := width
|
||||
bodyHeight := height - bodyTop
|
||||
bodyLeft := 0
|
||||
cornerRadius := width * 0.175
|
||||
|
||||
pc.StartAt(pc.Absolute(float64(bodyLeft), bodyTop+cornerRadius))
|
||||
|
||||
pc.C(true, 0, -kCircleApprox*cornerRadius, kCircleApprox*cornerRadius, -cornerRadius, cornerRadius, -cornerRadius)
|
||||
pc.H(true, bodyWidth-2*cornerRadius)
|
||||
pc.C(true, kCircleApprox*cornerRadius, 0, cornerRadius, kCircleApprox*cornerRadius, cornerRadius, cornerRadius)
|
||||
pc.V(true, bodyHeight-2*cornerRadius)
|
||||
pc.C(true, 0, kCircleApprox*cornerRadius, -kCircleApprox*cornerRadius, cornerRadius, -cornerRadius, cornerRadius)
|
||||
pc.H(true, -(bodyWidth - 2*cornerRadius))
|
||||
pc.C(true, -kCircleApprox*cornerRadius, 0, -cornerRadius, -kCircleApprox*cornerRadius, -cornerRadius, -cornerRadius)
|
||||
pc.Z()
|
||||
|
||||
return pc
|
||||
}
|
||||
|
||||
func headPath(box *geo.Box) *svg.SvgPathContext {
|
||||
width := box.Width
|
||||
height := box.Height
|
||||
|
||||
pc := svg.NewSVGPathContext(box.TopLeft, 1, 1)
|
||||
|
||||
headRadius := width * 0.22
|
||||
headCenterX := width / 2
|
||||
headCenterY := height * 0.18
|
||||
|
||||
pc.StartAt(pc.Absolute(headCenterX, headCenterY-headRadius))
|
||||
|
||||
pc.C(false,
|
||||
headCenterX+headRadius*kCircleApprox, headCenterY-headRadius,
|
||||
headCenterX+headRadius, headCenterY-headRadius*kCircleApprox,
|
||||
headCenterX+headRadius, headCenterY)
|
||||
|
||||
pc.C(false,
|
||||
headCenterX+headRadius, headCenterY+headRadius*kCircleApprox,
|
||||
headCenterX+headRadius*kCircleApprox, headCenterY+headRadius,
|
||||
headCenterX, headCenterY+headRadius)
|
||||
|
||||
pc.C(false,
|
||||
headCenterX-headRadius*kCircleApprox, headCenterY+headRadius,
|
||||
headCenterX-headRadius, headCenterY+headRadius*kCircleApprox,
|
||||
headCenterX-headRadius, headCenterY)
|
||||
|
||||
pc.C(false,
|
||||
headCenterX-headRadius, headCenterY-headRadius*kCircleApprox,
|
||||
headCenterX-headRadius*kCircleApprox, headCenterY-headRadius,
|
||||
headCenterX, headCenterY-headRadius)
|
||||
|
||||
return pc
|
||||
}
|
||||
|
||||
func (s shapeC4Person) Perimeter() []geo.Intersectable {
|
||||
width := s.Box.Width
|
||||
height := s.Box.Height
|
||||
|
||||
bodyPerimeter := bodyPath(s.Box).Path
|
||||
|
||||
headRadius := width * 0.22
|
||||
headCenterX := s.Box.TopLeft.X + width/2
|
||||
headCenterY := s.Box.TopLeft.Y + height*0.18
|
||||
headCenter := geo.NewPoint(headCenterX, headCenterY)
|
||||
|
||||
headEllipse := geo.NewEllipse(headCenter, headRadius, headRadius)
|
||||
|
||||
return append(bodyPerimeter, headEllipse)
|
||||
}
|
||||
|
||||
func (s shapeC4Person) GetSVGPathData() []string {
|
||||
return []string{
|
||||
bodyPath(s.Box).PathData(),
|
||||
headPath(s.Box).PathData(),
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
totalHeight *= 1.4
|
||||
|
||||
totalWidth, totalHeight = LimitAR(totalWidth, totalHeight, C4_PERSON_AR_LIMIT)
|
||||
return math.Ceil(totalWidth), math.Ceil(totalHeight)
|
||||
}
|
||||
|
||||
func (s shapeC4Person) GetDefaultPadding() (paddingX, paddingY float64) {
|
||||
return 20, defaultPadding * 1.5
|
||||
}
|
||||
Loading…
Reference in a new issue