diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index d91d354d46..2b7c9df88c 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -32,10 +32,15 @@ var setupJS string var dagreJS string const ( - MIN_RANK_SEP = 60 + // Edge and spacing constants EDGE_LABEL_GAP = 20 - DEFAULT_PADDING = 30. + DEFAULT_PADDING = 20. MIN_SPACING = 10. + + // Rank separation thresholds + MIN_RANK_SEP = 70 + RANK_GAP_BUFFER = 20 + SPACING_THRESHOLD = 100. ) type ConfigurableOpts struct { @@ -125,14 +130,9 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err } if !isHorizontal { - rootAttrs.ranksep = go2.Max(100, maxLabelHeight+40) + rootAttrs.ranksep = go2.Max(MIN_RANK_SEP, maxLabelHeight+RANK_GAP_BUFFER) } else { - rootAttrs.ranksep = go2.Max(100, maxLabelWidth+40) - // use existing config - // rootAttrs.NodeSep = rootAttrs.EdgeSep - // // configure vertical padding - // rootAttrs.EdgeSep = maxLabelHeight + 40 - // Note: non-containers have both of these as padding (rootAttrs.NodeSep + rootAttrs.EdgeSep) + rootAttrs.ranksep = go2.Max(MIN_RANK_SEP, maxLabelWidth+RANK_GAP_BUFFER) } configJS := setGraphAttrs(rootAttrs) @@ -781,7 +781,6 @@ func shiftReachableDown(g *d2graph.Graph, obj *d2graph.Object, start, distance f } // if object below is within this distance after shifting, also shift it - threshold := 100. checkBelow := func(curr *d2graph.Object) { currBottom := curr.TopLeft.Y + curr.Height currRight := curr.TopLeft.X + curr.Width @@ -795,7 +794,7 @@ func shiftReachableDown(g *d2graph.Graph, obj *d2graph.Object, start, distance f continue } if originalRight < other.TopLeft.X && - other.TopLeft.X < originalRight+distance+threshold && + other.TopLeft.X < originalRight+distance+SPACING_THRESHOLD && curr.TopLeft.Y < other.TopLeft.Y+other.Height && other.TopLeft.Y < currBottom { queue(other) @@ -811,7 +810,7 @@ func shiftReachableDown(g *d2graph.Graph, obj *d2graph.Object, start, distance f continue } if originalBottom < other.TopLeft.Y && - other.TopLeft.Y < originalBottom+distance+threshold && + other.TopLeft.Y < originalBottom+distance+SPACING_THRESHOLD && curr.TopLeft.X < other.TopLeft.X+other.Width && other.TopLeft.X < currRight { queue(other) @@ -1052,7 +1051,7 @@ func shiftReachableDown(g *d2graph.Graph, obj *d2graph.Object, start, distance f // above and within threshold if other.TopLeft.X < moved.TopLeft.X && - moved.TopLeft.X < other.TopLeft.X+other.Width+threshold { + moved.TopLeft.X < other.TopLeft.X+other.Width+SPACING_THRESHOLD { counts = false break } @@ -1065,7 +1064,7 @@ func shiftReachableDown(g *d2graph.Graph, obj *d2graph.Object, start, distance f // above and within threshold if other.TopLeft.Y < moved.TopLeft.Y && - moved.TopLeft.Y < other.TopLeft.Y+other.Height+threshold { + moved.TopLeft.Y < other.TopLeft.Y+other.Height+SPACING_THRESHOLD { counts = false break } diff --git a/d2layouts/d2elklayout/layout.go b/d2layouts/d2elklayout/layout.go index 6d4c335f14..50c68cbcc9 100644 --- a/d2layouts/d2elklayout/layout.go +++ b/d2layouts/d2elklayout/layout.go @@ -28,6 +28,19 @@ import ( "oss.terrastruct.com/d2/lib/shape" ) +const ( + // Layout options + DEFAULT_NODE_SPACING = 30 + DEFAULT_THOROUGHNESS = 8 + DEFAULT_EDGE_EDGE_SPACING = 20 + DEFAULT_PORT_SPACING = 20.0 + DEFAULT_EDGE_NODE_SPACING = 20 + DEFAULT_SELF_LOOP_SPACING = 50 + CONTAINER_PADDING = 20 + MIN_ENDPOINT_MARGIN = 10 + MIN_SEGMENT_PADDING = 5 +) + //go:embed elk.js var elkJS string @@ -119,15 +132,12 @@ type ConfigurableOpts struct { var DefaultOpts = ConfigurableOpts{ Algorithm: "layered", - NodeSpacing: 70.0, - Padding: "[top=50,left=50,bottom=50,right=50]", - EdgeNodeSpacing: 40.0, - SelfLoopSpacing: 50.0, + NodeSpacing: DEFAULT_NODE_SPACING, + Padding: fmt.Sprintf("[top=%d,left=%d,bottom=%d,right=%d]", CONTAINER_PADDING, CONTAINER_PADDING, CONTAINER_PADDING, CONTAINER_PADDING), + EdgeNodeSpacing: DEFAULT_EDGE_NODE_SPACING, + SelfLoopSpacing: DEFAULT_SELF_LOOP_SPACING, } -var port_spacing = 40. -var edge_node_spacing = 40 - type elkOpts struct { EdgeNode int `json:"elk.spacing.edgeNode,omitempty"` FixedAlignment string `json:"elk.layered.nodePlacement.bk.fixedAlignment,omitempty"` @@ -179,9 +189,9 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err elkGraph := &ELKGraph{ ID: "", LayoutOptions: &elkOpts{ - Thoroughness: 8, - EdgeEdgeBetweenLayersSpacing: 50, - EdgeNode: edge_node_spacing, + Thoroughness: DEFAULT_THOROUGHNESS, + EdgeEdgeBetweenLayersSpacing: DEFAULT_EDGE_EDGE_SPACING, + EdgeNode: DEFAULT_EDGE_NODE_SPACING, HierarchyHandling: "INCLUDE_CHILDREN", FixedAlignment: "BALANCED", ConsiderModelOrder: "NODES_AND_EDGES", @@ -197,8 +207,7 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err }, } if elkGraph.LayoutOptions.ConfigurableOpts.SelfLoopSpacing == DefaultOpts.SelfLoopSpacing { - // +5 for a tiny bit of padding - elkGraph.LayoutOptions.ConfigurableOpts.SelfLoopSpacing = go2.Max(elkGraph.LayoutOptions.ConfigurableOpts.SelfLoopSpacing, childrenMaxSelfLoop(g.Root, g.Root.Direction.Value == "down" || g.Root.Direction.Value == "" || g.Root.Direction.Value == "up")/2+5) + elkGraph.LayoutOptions.ConfigurableOpts.SelfLoopSpacing = go2.Max(elkGraph.LayoutOptions.ConfigurableOpts.SelfLoopSpacing, childrenMaxSelfLoop(g.Root, g.Root.Direction.Value == "down" || g.Root.Direction.Value == "" || g.Root.Direction.Value == "up")/2+MIN_SEGMENT_PADDING) } switch g.Root.Direction.Value { case "down": @@ -248,11 +257,11 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err switch g.Root.Direction.Value { case "right", "left": if obj.Attributes.HeightAttr == nil { - obj.Height = math.Max(obj.Height, math.Max(incoming, outgoing)*port_spacing) + obj.Height = math.Max(obj.Height, math.Max(incoming, outgoing)*DEFAULT_PORT_SPACING) } default: if obj.Attributes.WidthAttr == nil { - obj.Width = math.Max(obj.Width, math.Max(incoming, outgoing)*port_spacing) + obj.Width = math.Max(obj.Width, math.Max(incoming, outgoing)*DEFAULT_PORT_SPACING) } } } @@ -276,11 +285,11 @@ func Layout(ctx context.Context, g *d2graph.Graph, opts *ConfigurableOpts) (err if len(obj.ChildrenArray) > 0 { n.LayoutOptions = &elkOpts{ ForceNodeModelOrder: true, - Thoroughness: 8, - EdgeEdgeBetweenLayersSpacing: 50, + Thoroughness: DEFAULT_THOROUGHNESS, + EdgeEdgeBetweenLayersSpacing: DEFAULT_EDGE_EDGE_SPACING, HierarchyHandling: "INCLUDE_CHILDREN", FixedAlignment: "BALANCED", - EdgeNode: edge_node_spacing, + EdgeNode: DEFAULT_EDGE_NODE_SPACING, ConsiderModelOrder: "NODES_AND_EDGES", CycleBreakingStrategy: "GREEDY_MODEL_ORDER", NodeSizeConstraints: "MINIMUM_SIZE", @@ -720,17 +729,17 @@ func deleteBends(g *d2graph.Graph) { continue } case isHorizontal: - if end.Y <= endpoint.TopLeft.Y+10-dy { + if end.Y <= endpoint.TopLeft.Y+MIN_ENDPOINT_MARGIN-dy { continue } - if end.Y >= endpoint.TopLeft.Y+endpoint.Height-10 { + if end.Y >= endpoint.TopLeft.Y+endpoint.Height-MIN_ENDPOINT_MARGIN { continue } default: - if end.X <= endpoint.TopLeft.X+10 { + if end.X <= endpoint.TopLeft.X+MIN_ENDPOINT_MARGIN { continue } - if end.X >= endpoint.TopLeft.X+endpoint.Width-10+dx { + if end.X >= endpoint.TopLeft.X+endpoint.Width-MIN_ENDPOINT_MARGIN+dx { continue } } @@ -906,7 +915,7 @@ func countObjectIntersects(g *d2graph.Graph, src, dst *d2graph.Object, s geo.Seg if g.Objects[i] == src || g.Objects[i] == dst { continue } - if o.Intersects(s, float64(edge_node_spacing)-1) { + if o.Intersects(s, float64(DEFAULT_EDGE_NODE_SPACING)-1) { count++ } } @@ -931,9 +940,9 @@ func countEdgeIntersects(g *d2graph.Graph, sEdge *d2graph.Edge, s geo.Segment) ( if isHorizontal == otherIsHorizontal { if s.Overlaps(*otherS, !isHorizontal, 0.) { if isHorizontal { - if math.Abs(s.Start.Y-otherS.Start.Y) < float64(edge_node_spacing)/2. { + if math.Abs(s.Start.Y-otherS.Start.Y) < float64(DEFAULT_EDGE_NODE_SPACING)/2. { overlapsCount++ - if math.Abs(s.Start.Y-otherS.Start.Y) < float64(edge_node_spacing)/4. { + if math.Abs(s.Start.Y-otherS.Start.Y) < float64(DEFAULT_EDGE_NODE_SPACING)/4. { closeOverlapsCount++ if math.Abs(s.Start.Y-otherS.Start.Y) < 1. { touchingCount++ @@ -941,9 +950,9 @@ func countEdgeIntersects(g *d2graph.Graph, sEdge *d2graph.Edge, s geo.Segment) ( } } } else { - if math.Abs(s.Start.X-otherS.Start.X) < float64(edge_node_spacing)/2. { + if math.Abs(s.Start.X-otherS.Start.X) < float64(DEFAULT_EDGE_NODE_SPACING)/2. { overlapsCount++ - if math.Abs(s.Start.X-otherS.Start.X) < float64(edge_node_spacing)/4. { + if math.Abs(s.Start.X-otherS.Start.X) < float64(DEFAULT_EDGE_NODE_SPACING)/4. { closeOverlapsCount++ if math.Abs(s.Start.Y-otherS.Start.Y) < 1. { touchingCount++ diff --git a/e2etests/testdata/txtar/padding/dagre/board.exp.json b/e2etests/testdata/txtar/padding/dagre/board.exp.json new file mode 100644 index 0000000000..8e05b8e655 --- /dev/null +++ b/e2etests/testdata/txtar/padding/dagre/board.exp.json @@ -0,0 +1,1642 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "logs", + "type": "page", + "pos": { + "x": 24, + "y": 1233 + }, + "width": 73, + "height": 87, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AB4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": true, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "logs", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 28, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "user", + "type": "person", + "pos": { + "x": 366, + "y": 51 + }, + "width": 48, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "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": "User", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 33, + "labelHeight": 21, + "labelPosition": "OUTSIDE_BOTTOM_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "network", + "type": "rectangle", + "pos": { + "x": 213, + "y": 327 + }, + "width": 284, + "height": 1023, + "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": "Network", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 99, + "labelHeight": 36, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "network.tower", + "type": "rectangle", + "pos": { + "x": 233, + "y": 368 + }, + "width": 180, + "height": 309, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "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": "Cell Tower", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 106, + "labelHeight": 31, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "network.tower.satellites", + "type": "stored_data", + "pos": { + "x": 253, + "y": 398 + }, + "width": 130, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AA5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": true, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "satellites", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 65, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "network.tower.transmitter", + "type": "rectangle", + "pos": { + "x": 254, + "y": 591 + }, + "width": 128, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "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": "transmitter", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 83, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "network.processor", + "type": "rectangle", + "pos": { + "x": 247, + "y": 788 + }, + "width": 151, + "height": 168, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "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": "Data Processor", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 150, + "labelHeight": 31, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "network.processor.storage", + "type": "cylinder", + "pos": { + "x": 267, + "y": 818 + }, + "width": 101, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AA5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": true, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Storage", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 56, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "network.portal", + "type": "rectangle", + "pos": { + "x": 378, + "y": 1224 + }, + "width": 99, + "height": 106, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "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": "Online Portal", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 132, + "labelHeight": 31, + "labelPosition": "OUTSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "network.portal.UI", + "type": "rectangle", + "pos": { + "x": 398, + "y": 1244 + }, + "width": 59, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "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": "UI", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 14, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "server", + "type": "rectangle", + "pos": { + "x": 10, + "y": 1041 + }, + "width": 120, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "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": "API Server", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 75, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "costumes", + "type": "sql_table", + "pos": { + "x": 578, + "y": -6 + }, + "width": 294, + "height": 180, + "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": "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": "silliness", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 66, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": null, + "reference": "" + }, + { + "name": { + "label": "monster", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 70, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": null, + "reference": "" + }, + { + "name": { + "label": "last_updated", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 110, + "labelHeight": 26 + }, + "type": { + "label": "timestamp", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 91, + "labelHeight": 26 + }, + "constraint": null, + "reference": "" + } + ], + "label": "costumes", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 101, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + }, + { + "id": "monsters", + "type": "sql_table", + "pos": { + "x": 578, + "y": 341 + }, + "width": 294, + "height": 180, + "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": "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": "movie", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 51, + "labelHeight": 26 + }, + "type": { + "label": "string", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 48, + "labelHeight": 26 + }, + "constraint": null, + "reference": "" + }, + { + "name": { + "label": "weight", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 58, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": null, + "reference": "" + }, + { + "name": { + "label": "last_updated", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 110, + "labelHeight": 26 + }, + "type": { + "label": "timestamp", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 91, + "labelHeight": 26 + }, + "constraint": null, + "reference": "" + } + ], + "label": "monsters", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 99, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + } + ], + "connections": [ + { + "id": "network.tower.(satellites -> transmitter)[0]", + "src": "network.tower.satellites", + "srcArrow": "none", + "dst": "network.tower.transmitter", + "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": 304, + "y": 464 + }, + { + "x": 272.79998779296875, + "y": 537.5999755859375 + }, + { + "x": 270.3999938964844, + "y": 563 + }, + { + "x": 292, + "y": 591 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "network.tower.(satellites -> transmitter)[1]", + "src": "network.tower.satellites", + "srcArrow": "none", + "dst": "network.tower.transmitter", + "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": 317, + "y": 464 + }, + { + "x": 317.3999938964844, + "y": 537.5999755859375 + }, + { + "x": 317.5, + "y": 563 + }, + { + "x": 317.5, + "y": 591 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "network.tower.(satellites -> transmitter)[2]", + "src": "network.tower.satellites", + "srcArrow": "none", + "dst": "network.tower.transmitter", + "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": 331, + "y": 464 + }, + { + "x": 362.20001220703125, + "y": 537.5999755859375 + }, + { + "x": 364.6000061035156, + "y": 563 + }, + { + "x": 343, + "y": 591 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "network.(tower.transmitter -> processor)[0]", + "src": "network.tower.transmitter", + "srcArrow": "none", + "dst": "network.processor", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "phone logs", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 74, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 317.5, + "y": 657 + }, + { + "x": 317.5, + "y": 685 + }, + { + "x": 317.5, + "y": 740.5 + }, + { + "x": 317.5, + "y": 752.5 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(user -> network.tower)[0]", + "src": "user", + "srcArrow": "none", + "dst": "network.tower", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Make call", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 62, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 368.5, + "y": 123.5 + }, + { + "x": 327.70001220703125, + "y": 200.3000030517578 + }, + { + "x": 317.5, + "y": 278.3999938964844 + }, + { + "x": 317.5, + "y": 332 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(network.processor -> server)[0]", + "src": "network.processor", + "srcArrow": "none", + "dst": "server", + "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": 282.25, + "y": 956 + }, + { + "x": 282.25, + "y": 996 + }, + { + "x": 251.85000610351562, + "y": 1015.7999877929688 + }, + { + "x": 130.25, + "y": 1055 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(network.processor -> server)[1]", + "src": "network.processor", + "srcArrow": "none", + "dst": "server", + "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": 317.5, + "y": 956 + }, + { + "x": 317.5, + "y": 996 + }, + { + "x": 279.8999938964844, + "y": 1016.4000244140625 + }, + { + "x": 129.5, + "y": 1058 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(network.processor -> server)[2]", + "src": "network.processor", + "srcArrow": "none", + "dst": "server", + "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": 362.75, + "y": 956 + }, + { + "x": 362.75, + "y": 996 + }, + { + "x": 316.1499938964844, + "y": 1016.7999877929688 + }, + { + "x": 129.75, + "y": 1060 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(server -> logs)[0]", + "src": "server", + "srcArrow": "none", + "dst": "logs", + "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": 44.5, + "y": 1106.5 + }, + { + "x": 27.700000762939453, + "y": 1143.300048828125 + }, + { + "x": 25.799999237060547, + "y": 1203 + }, + { + "x": 35, + "y": 1223 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(server -> logs)[1]", + "src": "server", + "srcArrow": "none", + "dst": "logs", + "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": 53.5, + "y": 1106.5 + }, + { + "x": 45.5, + "y": 1143.300048828125 + }, + { + "x": 44.599998474121094, + "y": 1203 + }, + { + "x": 49, + "y": 1223 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(server -> logs)[2]", + "src": "server", + "srcArrow": "none", + "dst": "logs", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "persist", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 46, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 75.5, + "y": 1106.5 + }, + { + "x": 92.30000305175781, + "y": 1143.300048828125 + }, + { + "x": 94.19999694824219, + "y": 1203 + }, + { + "x": 85, + "y": 1223 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(server -> network.portal.UI)[0]", + "src": "server", + "srcArrow": "none", + "dst": "network.portal.UI", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "display", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 48, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 130.25, + "y": 1088.5 + }, + { + "x": 350.25, + "y": 1139.699951171875 + }, + { + "x": 407.79998779296875, + "y": 1207.0999755859375 + }, + { + "x": 418.0010070800781, + "y": 1243.5 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(user -> network.portal.UI)[0]", + "src": "user", + "srcArrow": "none", + "dst": "network.portal.UI", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 3, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "access", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 44, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 411, + "y": 131.5 + }, + { + "x": 443.79998779296875, + "y": 201.89999389648438 + }, + { + "x": 452, + "y": 228.60000610351562 + }, + { + "x": 452, + "y": 242.25 + }, + { + "x": 452, + "y": 255.89999389648438 + }, + { + "x": 452, + "y": 273.20001220703125 + }, + { + "x": 452, + "y": 285.5 + }, + { + "x": 452, + "y": 297.79998779296875 + }, + { + "x": 452, + "y": 331 + }, + { + "x": 452, + "y": 368.5 + }, + { + "x": 452, + "y": 406 + }, + { + "x": 452, + "y": 456 + }, + { + "x": 452, + "y": 493.5 + }, + { + "x": 452, + "y": 531 + }, + { + "x": 452, + "y": 569.5999755859375 + }, + { + "x": 452, + "y": 590 + }, + { + "x": 452, + "y": 610.4000244140625 + }, + { + "x": 452, + "y": 637.5999755859375 + }, + { + "x": 452, + "y": 658 + }, + { + "x": 452, + "y": 678.4000244140625 + }, + { + "x": 452, + "y": 701.0999755859375 + }, + { + "x": 452, + "y": 714.75 + }, + { + "x": 452, + "y": 728.4000244140625 + }, + { + "x": 452, + "y": 746.5999755859375 + }, + { + "x": 452, + "y": 760.25 + }, + { + "x": 452, + "y": 773.9000244140625 + }, + { + "x": 452, + "y": 801.7999877929688 + }, + { + "x": 452, + "y": 830 + }, + { + "x": 452, + "y": 858.2000122070312 + }, + { + "x": 452, + "y": 895.7999877929688 + }, + { + "x": 452, + "y": 924 + }, + { + "x": 452, + "y": 952.2000122070312 + }, + { + "x": 452, + "y": 978 + }, + { + "x": 452, + "y": 988.5 + }, + { + "x": 452, + "y": 999 + }, + { + "x": 452, + "y": 1019.5999755859375 + }, + { + "x": 452, + "y": 1040 + }, + { + "x": 452, + "y": 1060.4000244140625 + }, + { + "x": 452, + "y": 1089.699951171875 + }, + { + "x": 452, + "y": 1113.25 + }, + { + "x": 452, + "y": 1136.800048828125 + }, + { + "x": 449.1300048828125, + "y": 1207.0999755859375 + }, + { + "x": 437.65399169921875, + "y": 1243.5 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(costumes -> monsters)[0]", + "src": "costumes", + "srcArrow": "none", + "dst": "monsters", + "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": 724.75, + "y": 173.5 + }, + { + "x": 724.75, + "y": 210.3000030517578 + }, + { + "x": 724.75, + "y": 228.60000610351562 + }, + { + "x": 724.75, + "y": 242.25 + }, + { + "x": 724.75, + "y": 255.89999389648438 + }, + { + "x": 724.75, + "y": 313 + }, + { + "x": 724.75, + "y": 341 + } + ], + "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 + } +} diff --git a/e2etests/testdata/txtar/padding/dagre/sketch.exp.svg b/e2etests/testdata/txtar/padding/dagre/sketch.exp.svg new file mode 100644 index 0000000000..eb9e34058d --- /dev/null +++ b/e2etests/testdata/txtar/padding/dagre/sketch.exp.svg @@ -0,0 +1,124 @@ +logsUserNetworkAPI ServercostumesidintPKsillinessintmonsterintlast_updatedtimestampmonstersidintPKmoviestringweightintlast_updatedtimestampCell TowerData ProcessorOnline PortalsatellitestransmitterStorageUI phone logsMake callpersistdisplay access + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/e2etests/testdata/txtar/padding/elk/board.exp.json b/e2etests/testdata/txtar/padding/elk/board.exp.json new file mode 100644 index 0000000000..f806abc346 --- /dev/null +++ b/e2etests/testdata/txtar/padding/elk/board.exp.json @@ -0,0 +1,1420 @@ +{ + "name": "", + "isFolderOnly": false, + "fontFamily": "SourceSansPro", + "shapes": [ + { + "id": "logs", + "type": "page", + "pos": { + "x": 221, + "y": 1323 + }, + "width": 73, + "height": 87, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AB4", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": true, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "logs", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 28, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "user", + "type": "person", + "pos": { + "x": 164, + "y": 100 + }, + "width": 48, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B3", + "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": "User", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 33, + "labelHeight": 21, + "labelPosition": "OUTSIDE_BOTTOM_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "network", + "type": "rectangle", + "pos": { + "x": 12, + "y": 457 + }, + "width": 425, + "height": 584, + "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": "Network", + "fontSize": 28, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 99, + "labelHeight": 36, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "network.tower", + "type": "rectangle", + "pos": { + "x": 39, + "y": 503 + }, + "width": 180, + "height": 243, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "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": "Cell Tower", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 106, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "network.tower.satellites", + "type": "stored_data", + "pos": { + "x": 59, + "y": 554 + }, + "width": 130, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AA5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": true, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "satellites", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 65, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "network.tower.transmitter", + "type": "rectangle", + "pos": { + "x": 65, + "y": 660 + }, + "width": 128, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "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": "transmitter", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 83, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "network.processor", + "type": "rectangle", + "pos": { + "x": 32, + "y": 832 + }, + "width": 195, + "height": 189, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "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": "Data Processor", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 150, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "network.processor.storage", + "type": "cylinder", + "pos": { + "x": 74, + "y": 883 + }, + "width": 101, + "height": 118, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "AA5", + "stroke": "B1", + "shadow": false, + "3d": false, + "multiple": true, + "double-border": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "blend": false, + "fields": null, + "methods": null, + "columns": null, + "label": "Storage", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 56, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "network.portal", + "type": "rectangle", + "pos": { + "x": 239, + "y": 508 + }, + "width": 177, + "height": 127, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B5", + "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": "Online Portal", + "fontSize": 24, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 132, + "labelHeight": 31, + "labelPosition": "INSIDE_TOP_CENTER", + "zIndex": 0, + "level": 2 + }, + { + "id": "network.portal.UI", + "type": "rectangle", + "pos": { + "x": 298, + "y": 549 + }, + "width": 59, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "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": "UI", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 14, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 3 + }, + { + "id": "server", + "type": "rectangle", + "pos": { + "x": 202, + "y": 1146 + }, + "width": 120, + "height": 66, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "B6", + "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": "API Server", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 75, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "zIndex": 0, + "level": 1 + }, + { + "id": "costumes", + "type": "sql_table", + "pos": { + "x": 232, + "y": 12 + }, + "width": 294, + "height": 180, + "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": "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": "silliness", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 66, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": null, + "reference": "" + }, + { + "name": { + "label": "monster", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 70, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": null, + "reference": "" + }, + { + "name": { + "label": "last_updated", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 110, + "labelHeight": 26 + }, + "type": { + "label": "timestamp", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 91, + "labelHeight": 26 + }, + "constraint": null, + "reference": "" + } + ], + "label": "costumes", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 101, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + }, + { + "id": "monsters", + "type": "sql_table", + "pos": { + "x": 566, + "y": 232 + }, + "width": 294, + "height": 180, + "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": "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": "movie", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 51, + "labelHeight": 26 + }, + "type": { + "label": "string", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 48, + "labelHeight": 26 + }, + "constraint": null, + "reference": "" + }, + { + "name": { + "label": "weight", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 58, + "labelHeight": 26 + }, + "type": { + "label": "int", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 23, + "labelHeight": 26 + }, + "constraint": null, + "reference": "" + }, + { + "name": { + "label": "last_updated", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 110, + "labelHeight": 26 + }, + "type": { + "label": "timestamp", + "fontSize": 0, + "fontFamily": "", + "language": "", + "color": "", + "italic": false, + "bold": false, + "underline": false, + "labelWidth": 91, + "labelHeight": 26 + }, + "constraint": null, + "reference": "" + } + ], + "label": "monsters", + "fontSize": 20, + "fontFamily": "DEFAULT", + "language": "", + "color": "N1", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 99, + "labelHeight": 31, + "zIndex": 0, + "level": 1, + "primaryAccentColor": "B2", + "secondaryAccentColor": "AA2", + "neutralAccentColor": "N2" + } + ], + "connections": [ + { + "id": "network.tower.(satellites -> transmitter)[0]", + "src": "network.tower.satellites", + "srcArrow": "none", + "dst": "network.tower.transmitter", + "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": 97, + "y": 620 + }, + { + "x": 97.5, + "y": 660 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "network.tower.(satellites -> transmitter)[1]", + "src": "network.tower.satellites", + "srcArrow": "none", + "dst": "network.tower.transmitter", + "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": 130, + "y": 620 + }, + { + "x": 129, + "y": 660 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "network.tower.(satellites -> transmitter)[2]", + "src": "network.tower.satellites", + "srcArrow": "none", + "dst": "network.tower.transmitter", + "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": 161, + "y": 620 + }, + { + "x": 161.5, + "y": 660 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "network.(tower.transmitter -> processor)[0]", + "src": "network.tower.transmitter", + "srcArrow": "none", + "dst": "network.processor", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "phone logs", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 74, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 129.5, + "y": 726 + }, + { + "x": 129.5, + "y": 832 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(user -> network.tower)[0]", + "src": "user", + "srcArrow": "none", + "dst": "network.tower", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "Make call", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 62, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 180.83299255371094, + "y": 192 + }, + { + "x": 180.83299255371094, + "y": 212 + }, + { + "x": 156.83299255371094, + "y": 212 + }, + { + "x": 156.83299255371094, + "y": 503 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(network.processor -> server)[0]", + "src": "network.processor", + "srcArrow": "none", + "dst": "server", + "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": 99.625, + "y": 1021 + }, + { + "x": 99.625, + "y": 1126 + }, + { + "x": 226.83299255371094, + "y": 1126 + }, + { + "x": 226.83299255371094, + "y": 1146 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(network.processor -> server)[1]", + "src": "network.processor", + "srcArrow": "none", + "dst": "server", + "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": 129.5, + "y": 1021 + }, + { + "x": 129.5, + "y": 1106 + }, + { + "x": 250.83299255371094, + "y": 1106 + }, + { + "x": 250.83299255371094, + "y": 1146 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(network.processor -> server)[2]", + "src": "network.processor", + "srcArrow": "none", + "dst": "server", + "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": 178.25, + "y": 1021 + }, + { + "x": 178.25, + "y": 1066 + }, + { + "x": 287.2080078125, + "y": 1066 + }, + { + "x": 287.2080078125, + "y": 1146 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(server -> logs)[0]", + "src": "server", + "srcArrow": "none", + "dst": "logs", + "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": 237.45799255371094, + "y": 1212 + }, + { + "x": 237, + "y": 1323 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(server -> logs)[1]", + "src": "server", + "srcArrow": "none", + "dst": "logs", + "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": 262.8330078125, + "y": 1212 + }, + { + "x": 263, + "y": 1313 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(server -> logs)[2]", + "src": "server", + "srcArrow": "none", + "dst": "logs", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "persist", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 46, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 306.8330078125, + "y": 1212 + }, + { + "x": 306.8330078125, + "y": 1293 + }, + { + "x": 283.5830078125, + "y": 1293 + }, + { + "x": 284, + "y": 1313 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(server -> network.portal.UI)[0]", + "src": "server", + "srcArrow": "none", + "dst": "network.portal.UI", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "B1", + "borderRadius": 10, + "label": "display", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 48, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 298.8330078125, + "y": 1146 + }, + { + "x": 298.8330078125, + "y": 1106 + }, + { + "x": 480.5, + "y": 1106 + }, + { + "x": 480.5, + "y": 432 + }, + { + "x": 337.8330078125, + "y": 432 + }, + { + "x": 337.8330078125, + "y": 549 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(user -> network.portal.UI)[0]", + "src": "user", + "srcArrow": "none", + "dst": "network.portal.UI", + "dstArrow": "triangle", + "opacity": 1, + "strokeDash": 3, + "strokeWidth": 2, + "stroke": "B2", + "borderRadius": 10, + "label": "access", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "N2", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 44, + "labelHeight": 21, + "labelPosition": "INSIDE_MIDDLE_CENTER", + "labelPercentage": 0, + "route": [ + { + "x": 196.83299255371094, + "y": 192 + }, + { + "x": 196.83299255371094, + "y": 432 + }, + { + "x": 318.1659851074219, + "y": 432 + }, + { + "x": 318.1659851074219, + "y": 549 + } + ], + "animated": false, + "tooltip": "", + "icon": null, + "zIndex": 0 + }, + { + "id": "(costumes -> monsters)[0]", + "src": "costumes", + "srcArrow": "none", + "dst": "monsters", + "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": 526.8330078125, + "y": 138 + }, + { + "x": 546.8330078125, + "y": 138 + }, + { + "x": 546.8330078125, + "y": 286 + }, + { + "x": 566.8330078125, + "y": 286 + } + ], + "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 + } +} diff --git a/e2etests/testdata/txtar/padding/elk/sketch.exp.svg b/e2etests/testdata/txtar/padding/elk/sketch.exp.svg new file mode 100644 index 0000000000..16796e9632 --- /dev/null +++ b/e2etests/testdata/txtar/padding/elk/sketch.exp.svg @@ -0,0 +1,124 @@ +logsUserNetworkAPI ServercostumesidintPKsillinessintmonsterintlast_updatedtimestampmonstersidintPKmoviestringweightintlast_updatedtimestampCell TowerData ProcessorOnline PortalsatellitestransmitterStorageUI phone logsMake callpersistdisplay access + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/e2etests/txtar.txt b/e2etests/txtar.txt index d669dcc18a..3d3c55a18d 100644 --- a/e2etests/txtar.txt +++ b/e2etests/txtar.txt @@ -49,7 +49,6 @@ without.codeEx -> with.codeEx without.mdEx -> with.mdEx -- theme-overrides -- - direction: right vars: { d2-config: { @@ -469,3 +468,67 @@ colors: { style.font-color: "linear-gradient(to bottom right, red 0%, yellow 25%, green 50%, cyan 75%, blue 100%)" } gradient -> colors + +-- padding -- +logs: { + shape: page + style.multiple: true +} +user: User {shape: person} +network: Network { + tower: Cell Tower { + satellites: { + shape: stored_data + style.multiple: true + } + + satellites -> transmitter + satellites -> transmitter + satellites -> transmitter + transmitter + } + processor: Data Processor { + storage: Storage { + shape: cylinder + style.multiple: true + } + } + portal: Online Portal { + UI + } + + tower.transmitter -> processor: phone logs +} +server: API Server + +user -> network.tower: Make call +network.processor -> server +network.processor -> server +network.processor -> server + +server -> logs +server -> logs +server -> logs: persist + +server -> network.portal.UI: display +user -> network.portal.UI: access { + style.stroke-dash: 3 +} + +costumes: { + shape: sql_table + id: int {constraint: primary_key} + silliness: int + monster: int + last_updated: timestamp +} + +monsters: { + shape: sql_table + id: int {constraint: primary_key} + movie: string + weight: int + last_updated: timestamp +} + +costumes.monster -> monsters.id