Merge pull request #899 from alixander/prevent-bad-sequence
fixes 3 bugs: near sequence child, class font, class in sequence
|
|
@ -4,7 +4,11 @@
|
|||
|
||||
#### Improvements 🧹
|
||||
|
||||
- `near` key set to sequence diagram children get an appropriate error message. [#899](https://github.com/terrastruct/d2/issues/899)
|
||||
- `class` and `sql_table` shape respect `font-color` styling as header font color. [#899](https://github.com/terrastruct/d2/issues/899)
|
||||
|
||||
#### Bugfixes ⛑️
|
||||
|
||||
- Error reported when no actors are declared in sequence diagram. [#886](https://github.com/terrastruct/d2/pull/886)
|
||||
- Fixed img bundling on image shapes. [#889](https://github.com/terrastruct/d2/issues/889)
|
||||
- `class` shape as sequence diagram actors had wrong colors. [#899](https://github.com/terrastruct/d2/issues/899)
|
||||
|
|
|
|||
|
|
@ -678,6 +678,10 @@ func (c *compiler) validateNear(g *d2graph.Graph) {
|
|||
c.errorf(obj.Attributes.NearKey, "near keys cannot be set to an descendant")
|
||||
continue
|
||||
}
|
||||
if nearObj.OuterSequenceDiagram() != nil {
|
||||
c.errorf(obj.Attributes.NearKey, "near keys cannot be set to an object within sequence diagrams")
|
||||
continue
|
||||
}
|
||||
} else if isConst {
|
||||
is := false
|
||||
for _, e := range g.Edges {
|
||||
|
|
|
|||
|
|
@ -1774,6 +1774,17 @@ dst.id <-> src.dst_id
|
|||
assert.String(t, "sequence_diagram", g.Objects[0].Attributes.Shape.Value)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "near_sequence",
|
||||
|
||||
text: `x: {
|
||||
shape: sequence_diagram
|
||||
a
|
||||
}
|
||||
b.near: x.a
|
||||
`,
|
||||
expErr: `d2/testdata/d2compiler/TestCompile/near_sequence.d2:5:9: near keys cannot be set to an object within sequence diagrams`,
|
||||
},
|
||||
{
|
||||
name: "sequence-timestamp",
|
||||
|
||||
|
|
|
|||
|
|
@ -338,6 +338,12 @@ func (l ContainerLevel) LabelSize() int {
|
|||
|
||||
func (obj *Object) GetFill() string {
|
||||
level := int(obj.Level())
|
||||
shape := obj.Attributes.Shape.Value
|
||||
|
||||
if strings.EqualFold(shape, d2target.ShapeSQLTable) || strings.EqualFold(shape, d2target.ShapeClass) {
|
||||
return color.N1
|
||||
}
|
||||
|
||||
if obj.IsSequenceDiagramNote() {
|
||||
return color.N7
|
||||
} else if obj.IsSequenceDiagramGroup() {
|
||||
|
|
@ -366,8 +372,6 @@ func (obj *Object) GetFill() string {
|
|||
return color.N7
|
||||
}
|
||||
|
||||
shape := obj.Attributes.Shape.Value
|
||||
|
||||
if shape == "" || strings.EqualFold(shape, d2target.ShapeSquare) || strings.EqualFold(shape, d2target.ShapeCircle) || strings.EqualFold(shape, d2target.ShapeOval) || strings.EqualFold(shape, d2target.ShapeRectangle) {
|
||||
if level == 1 {
|
||||
if !obj.IsContainer() {
|
||||
|
|
@ -409,10 +413,6 @@ func (obj *Object) GetFill() string {
|
|||
return color.N5
|
||||
}
|
||||
|
||||
if strings.EqualFold(shape, d2target.ShapeSQLTable) || strings.EqualFold(shape, d2target.ShapeClass) {
|
||||
return color.N1
|
||||
}
|
||||
|
||||
return color.N7
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -382,7 +382,7 @@ func Table(r *Runner, shape d2target.Shape) (string, error) {
|
|||
textEl := d2themes.NewThemableElement("text")
|
||||
textEl.X = tl.X
|
||||
textEl.Y = tl.Y + float64(shape.LabelHeight)*3/4
|
||||
textEl.Fill = shape.Stroke
|
||||
textEl.Fill = shape.GetFontColor()
|
||||
textEl.ClassName = "text"
|
||||
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx",
|
||||
"start", 4+shape.FontSize,
|
||||
|
|
@ -532,7 +532,7 @@ func Class(r *Runner, shape d2target.Shape) (string, error) {
|
|||
textEl := d2themes.NewThemableElement("text")
|
||||
textEl.X = tl.X + float64(shape.LabelWidth)/2
|
||||
textEl.Y = tl.Y + float64(shape.LabelHeight)*3/4
|
||||
textEl.Fill = shape.Stroke
|
||||
textEl.Fill = shape.GetFontColor()
|
||||
textEl.ClassName = "text-mono"
|
||||
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx",
|
||||
"middle",
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ func classHeader(shape d2target.Shape, box *geo.Box, text string, textWidth, tex
|
|||
textEl := d2themes.NewThemableElement("text")
|
||||
textEl.X = tl.X + textWidth/2
|
||||
textEl.Y = tl.Y + textHeight*3/4
|
||||
textEl.Fill = shape.Stroke
|
||||
textEl.Fill = shape.GetFontColor()
|
||||
textEl.ClassName = "text-mono"
|
||||
textEl.Style = fmt.Sprintf(`text-anchor:%s;font-size:%vpx;`,
|
||||
"middle", 4+fontSize,
|
||||
|
|
|
|||
|
|
@ -562,11 +562,6 @@ func drawConnection(writer io.Writer, labelMaskID string, connection d2target.Co
|
|||
} else if connection.Italic {
|
||||
fontClass += "-italic"
|
||||
}
|
||||
fontColor := color.N1
|
||||
if connection.Color != color.Empty {
|
||||
fontColor = connection.Color
|
||||
}
|
||||
|
||||
if connection.Fill != color.Empty {
|
||||
rectEl := d2themes.NewThemableElement("rect")
|
||||
rectEl.X, rectEl.Y = labelTL.X, labelTL.Y
|
||||
|
|
@ -578,7 +573,7 @@ func drawConnection(writer io.Writer, labelMaskID string, connection d2target.Co
|
|||
textEl := d2themes.NewThemableElement("text")
|
||||
textEl.X = labelTL.X + float64(connection.LabelWidth)/2
|
||||
textEl.Y = labelTL.Y + float64(connection.FontSize)
|
||||
textEl.Fill = fontColor
|
||||
textEl.Fill = connection.GetFontColor()
|
||||
textEl.ClassName = fontClass
|
||||
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "middle", connection.FontSize)
|
||||
textEl.Content = RenderText(connection.Label, textEl.X, float64(connection.LabelHeight))
|
||||
|
|
@ -1112,10 +1107,6 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske
|
|||
fmt.Fprint(writer, mdEl.Render())
|
||||
fmt.Fprint(writer, `</foreignObject></g>`)
|
||||
} else {
|
||||
fontColor := color.N1
|
||||
if targetShape.Color != color.Empty {
|
||||
fontColor = targetShape.Color
|
||||
}
|
||||
if targetShape.LabelFill != "" {
|
||||
rectEl := d2themes.NewThemableElement("rect")
|
||||
rectEl.X = labelTL.X
|
||||
|
|
@ -1129,7 +1120,7 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske
|
|||
textEl.X = labelTL.X + float64(targetShape.LabelWidth)/2
|
||||
// text is vertically positioned at its baseline which is at labelTL+FontSize
|
||||
textEl.Y = labelTL.Y + float64(targetShape.FontSize)
|
||||
textEl.Fill = fontColor
|
||||
textEl.Fill = targetShape.GetFontColor()
|
||||
textEl.ClassName = fontClass
|
||||
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx", "middle", targetShape.FontSize)
|
||||
textEl.Content = RenderText(targetShape.Label, textEl.X, float64(targetShape.LabelHeight))
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ func tableHeader(shape d2target.Shape, box *geo.Box, text string, textWidth, tex
|
|||
textEl := d2themes.NewThemableElement("text")
|
||||
textEl.X = tl.X
|
||||
textEl.Y = tl.Y + textHeight*3/4
|
||||
textEl.Fill = shape.Stroke
|
||||
textEl.Fill = shape.GetFontColor()
|
||||
textEl.ClassName = "text"
|
||||
textEl.Style = fmt.Sprintf("text-anchor:%s;font-size:%vpx",
|
||||
"start", 4+fontSize,
|
||||
|
|
|
|||
|
|
@ -197,6 +197,19 @@ type Shape struct {
|
|||
NeutralAccentColor string `json:"neutralAccentColor,omitempty"`
|
||||
}
|
||||
|
||||
func (s Shape) GetFontColor() string {
|
||||
if s.Type == ShapeClass || s.Type == ShapeSQLTable {
|
||||
if !color.IsThemeColor(s.Color) {
|
||||
return s.Color
|
||||
}
|
||||
return s.Stroke
|
||||
}
|
||||
if s.Color != color.Empty {
|
||||
return s.Color
|
||||
}
|
||||
return color.N1
|
||||
}
|
||||
|
||||
func (s Shape) CSSStyle() string {
|
||||
out := ""
|
||||
|
||||
|
|
@ -302,6 +315,13 @@ func BaseConnection() *Connection {
|
|||
}
|
||||
}
|
||||
|
||||
func (c Connection) GetFontColor() string {
|
||||
if c.Color != color.Empty {
|
||||
return c.Color
|
||||
}
|
||||
return color.N1
|
||||
}
|
||||
|
||||
func (c Connection) CSSStyle() string {
|
||||
out := ""
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,17 @@ group.nested: {
|
|||
`,
|
||||
expErr: "no actors declared in sequence diagram",
|
||||
},
|
||||
{
|
||||
name: "class_font_style_sequence",
|
||||
script: `shape: sequence_diagram
|
||||
a: {
|
||||
shape: class
|
||||
style: {
|
||||
font-color: red
|
||||
}
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "nested_steps",
|
||||
script: `a: {
|
||||
|
|
|
|||
91
e2etests/testdata/regression/class_font_style_sequence/dagre/board.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
{
|
||||
"name": "",
|
||||
"fontFamily": "SourceSansPro",
|
||||
"shapes": [
|
||||
{
|
||||
"id": "a",
|
||||
"type": "class",
|
||||
"pos": {
|
||||
"x": 12,
|
||||
"y": 52
|
||||
},
|
||||
"width": 117,
|
||||
"height": 92,
|
||||
"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": null,
|
||||
"label": "a",
|
||||
"fontSize": 20,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "red",
|
||||
"italic": false,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 12,
|
||||
"labelHeight": 31,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1,
|
||||
"primaryAccentColor": "B2",
|
||||
"secondaryAccentColor": "AA2",
|
||||
"neutralAccentColor": "N2"
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"id": "(a -- )[0]",
|
||||
"src": "a",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "a-lifeline-end-2251863791",
|
||||
"dstArrow": "none",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 6,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "B2",
|
||||
"label": "",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N2",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 0,
|
||||
"labelHeight": 0,
|
||||
"labelPosition": "",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 70.5,
|
||||
"y": 144
|
||||
},
|
||||
{
|
||||
"x": 70.5,
|
||||
"y": 214
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
43
e2etests/testdata/regression/class_font_style_sequence/dagre/sketch.exp.svg
vendored
Normal file
|
After Width: | Height: | Size: 186 KiB |
91
e2etests/testdata/regression/class_font_style_sequence/elk/board.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
{
|
||||
"name": "",
|
||||
"fontFamily": "SourceSansPro",
|
||||
"shapes": [
|
||||
{
|
||||
"id": "a",
|
||||
"type": "class",
|
||||
"pos": {
|
||||
"x": 12,
|
||||
"y": 52
|
||||
},
|
||||
"width": 117,
|
||||
"height": 92,
|
||||
"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": null,
|
||||
"label": "a",
|
||||
"fontSize": 20,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "red",
|
||||
"italic": false,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 12,
|
||||
"labelHeight": 31,
|
||||
"labelPosition": "INSIDE_MIDDLE_CENTER",
|
||||
"zIndex": 0,
|
||||
"level": 1,
|
||||
"primaryAccentColor": "B2",
|
||||
"secondaryAccentColor": "AA2",
|
||||
"neutralAccentColor": "N2"
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"id": "(a -- )[0]",
|
||||
"src": "a",
|
||||
"srcArrow": "none",
|
||||
"srcLabel": "",
|
||||
"dst": "a-lifeline-end-2251863791",
|
||||
"dstArrow": "none",
|
||||
"dstLabel": "",
|
||||
"opacity": 1,
|
||||
"strokeDash": 6,
|
||||
"strokeWidth": 2,
|
||||
"stroke": "B2",
|
||||
"label": "",
|
||||
"fontSize": 16,
|
||||
"fontFamily": "DEFAULT",
|
||||
"language": "",
|
||||
"color": "N2",
|
||||
"italic": true,
|
||||
"bold": false,
|
||||
"underline": false,
|
||||
"labelWidth": 0,
|
||||
"labelHeight": 0,
|
||||
"labelPosition": "",
|
||||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 70.5,
|
||||
"y": 144
|
||||
},
|
||||
{
|
||||
"x": 70.5,
|
||||
"y": 214
|
||||
}
|
||||
],
|
||||
"animated": false,
|
||||
"tooltip": "",
|
||||
"icon": null,
|
||||
"zIndex": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
43
e2etests/testdata/regression/class_font_style_sequence/elk/sketch.exp.svg
vendored
Normal file
|
After Width: | Height: | Size: 186 KiB |
4
e2etests/testdata/stable/sequence_diagram_all_shapes/dagre/board.exp.json
generated
vendored
|
|
@ -97,7 +97,7 @@
|
|||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "B5",
|
||||
"fill": "N1",
|
||||
"stroke": "N7",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
|
|
@ -819,7 +819,7 @@
|
|||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "B5",
|
||||
"fill": "N1",
|
||||
"stroke": "N7",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 849 KiB After Width: | Height: | Size: 849 KiB |
4
e2etests/testdata/stable/sequence_diagram_all_shapes/elk/board.exp.json
generated
vendored
|
|
@ -97,7 +97,7 @@
|
|||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "B5",
|
||||
"fill": "N1",
|
||||
"stroke": "N7",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
|
|
@ -819,7 +819,7 @@
|
|||
"strokeDash": 0,
|
||||
"strokeWidth": 2,
|
||||
"borderRadius": 0,
|
||||
"fill": "B5",
|
||||
"fill": "N1",
|
||||
"stroke": "N7",
|
||||
"shadow": false,
|
||||
"3d": false,
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 849 KiB After Width: | Height: | Size: 849 KiB |
|
Before Width: | Height: | Size: 517 KiB After Width: | Height: | Size: 517 KiB |
|
Before Width: | Height: | Size: 517 KiB After Width: | Height: | Size: 517 KiB |
12
testdata/d2compiler/TestCompile/near_sequence.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"graph": null,
|
||||
"err": {
|
||||
"ioerr": null,
|
||||
"errs": [
|
||||
{
|
||||
"range": "d2/testdata/d2compiler/TestCompile/near_sequence.d2,4:8:45-4:11:48",
|
||||
"errmsg": "d2/testdata/d2compiler/TestCompile/near_sequence.d2:5:9: near keys cannot be set to an object within sequence diagrams"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||