diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go
index de5785ffa..838ffe6d7 100644
--- a/d2graph/d2graph.go
+++ b/d2graph/d2graph.go
@@ -20,6 +20,8 @@ import (
"oss.terrastruct.com/d2/lib/textmeasure"
)
+const INNER_LABEL_PADDING int = 5
+
// TODO: Refactor with a light abstract layer on top of AST implementing scenarios,
// variables, imports, substitutions and then a final set of structures representing
// a final graph.
@@ -883,7 +885,7 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
}
var dims *d2target.TextDimensions
- var innerLabelPadding = 5
+ var innerLabelPadding = INNER_LABEL_PADDING
if obj.Attributes.Shape.Value == d2target.ShapeText {
if obj.Attributes.Language == "latex" {
width, height, err := d2latex.Measure(obj.Text().Text)
diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go
index 77214ce3f..2af505713 100644
--- a/d2renderers/d2svg/d2svg.go
+++ b/d2renderers/d2svg/d2svg.go
@@ -22,6 +22,7 @@ import (
"oss.terrastruct.com/util-go/go2"
+ "oss.terrastruct.com/d2/d2graph"
"oss.terrastruct.com/d2/d2renderers/d2fonts"
"oss.terrastruct.com/d2/d2renderers/d2latex"
"oss.terrastruct.com/d2/d2target"
@@ -337,11 +338,11 @@ func pathData(connection d2target.Connection, idToShape map[string]d2target.Shap
return strings.Join(path, " ")
}
-func makeLabelMask(connection d2target.Connection, labelTL, tl, br *geo.Point) string {
+func makeLabelMask(labelTL *geo.Point, width, height int) string {
return fmt.Sprintf(``,
labelTL.X, labelTL.Y,
- connection.LabelWidth,
- connection.LabelHeight,
+ width,
+ height,
)
}
@@ -408,7 +409,7 @@ func drawConnection(writer io.Writer, connection d2target.Connection, markers ma
br.X = math.Max(br.X, labelTL.X+float64(connection.LabelWidth))
br.Y = math.Max(br.Y, labelTL.Y+float64(connection.LabelHeight))
- labelMask = makeLabelMask(connection, labelTL, tl, br)
+ labelMask = makeLabelMask(labelTL, connection.LabelWidth, connection.LabelHeight)
}
}
@@ -582,7 +583,7 @@ func render3dRect(targetShape d2target.Shape) string {
return borderMask + mainRect + renderedSides + renderedBorder
}
-func drawShape(writer io.Writer, targetShape d2target.Shape) error {
+func drawShape(writer io.Writer, targetShape d2target.Shape) (labelMask string, err error) {
fmt.Fprintf(writer, ``, escapeText(targetShape.ID))
tl := geo.NewPoint(float64(targetShape.Pos.X), float64(targetShape.Pos.Y))
width := float64(targetShape.Width)
@@ -620,11 +621,11 @@ func drawShape(writer io.Writer, targetShape d2target.Shape) error {
case d2target.ShapeClass:
drawClass(writer, targetShape)
fmt.Fprintf(writer, ``)
- return nil
+ return labelMask, nil
case d2target.ShapeSQLTable:
drawTable(writer, targetShape)
fmt.Fprintf(writer, ``)
- return nil
+ return labelMask, nil
case d2target.ShapeOval:
if targetShape.Multiple {
fmt.Fprint(writer, renderOval(multipleTL, width, height, style))
@@ -706,19 +707,19 @@ func drawShape(writer io.Writer, targetShape d2target.Shape) error {
case d2target.ShapeCode:
lexer := lexers.Get(targetShape.Language)
if lexer == nil {
- return fmt.Errorf("code snippet lexer for %s not found", targetShape.Language)
+ return labelMask, fmt.Errorf("code snippet lexer for %s not found", targetShape.Language)
}
style := styles.Get("github")
if style == nil {
- return errors.New(`code snippet style "github" not found`)
+ return labelMask, errors.New(`code snippet style "github" not found`)
}
formatter := formatters.Get("svg")
if formatter == nil {
- return errors.New(`code snippet formatter "svg" not found`)
+ return labelMask, errors.New(`code snippet formatter "svg" not found`)
}
iterator, err := lexer.Tokenise(nil, targetShape.Label)
if err != nil {
- return err
+ return labelMask, err
}
svgStyles := styleToSVG(style)
@@ -748,15 +749,15 @@ func drawShape(writer io.Writer, targetShape d2target.Shape) error {
if targetShape.Language == "latex" {
render, err := d2latex.Render(targetShape.Label)
if err != nil {
- return err
+ return labelMask, err
}
fmt.Fprintf(writer, ``, box.TopLeft.X, box.TopLeft.Y, targetShape.Opacity)
- fmt.Fprintf(writer, render)
+ fmt.Fprint(writer, render)
fmt.Fprintf(writer, "")
} else {
render, err := textmeasure.RenderMarkdown(targetShape.Label)
if err != nil {
- return err
+ return labelMask, err
}
fmt.Fprintf(writer, ``,
box.TopLeft.X, box.TopLeft.Y, targetShape.Width, targetShape.Height,
@@ -772,7 +773,7 @@ func drawShape(writer io.Writer, targetShape d2target.Shape) error {
fontColor = targetShape.Color
}
textStyle := fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", "middle", targetShape.FontSize, fontColor)
- x := labelTL.X + float64(targetShape.LabelWidth)/2
+ x := labelTL.X + float64(targetShape.LabelWidth)/2.
// text is vertically positioned at its baseline which is at labelTL+FontSize
y := labelTL.Y + float64(targetShape.FontSize)
fmt.Fprintf(writer, `%s`,
@@ -781,10 +782,13 @@ func drawShape(writer io.Writer, targetShape d2target.Shape) error {
textStyle,
renderText(targetShape.Label, x, float64(targetShape.LabelHeight)),
)
+ if targetShape.Blend {
+ labelMask = makeLabelMask(labelTL, targetShape.LabelWidth, targetShape.LabelHeight-d2graph.INNER_LABEL_PADDING)
+ }
}
}
fmt.Fprintf(writer, ``)
- return nil
+ return labelMask, nil
}
func escapeText(text string) string {
@@ -996,9 +1000,11 @@ func Render(diagram *d2target.Diagram) ([]byte, error) {
labelMasks = append(labelMasks, labelMask)
}
} else if s, is := obj.(d2target.Shape); is {
- err := drawShape(buf, s)
+ labelMask, err := drawShape(buf, s)
if err != nil {
return nil, err
+ } else if labelMask != "" {
+ labelMasks = append(labelMasks, labelMask)
}
} else {
return nil, fmt.Errorf("unknow object of type %T", obj)
diff --git a/e2etests/testdata/stable/sequence_diagram_groups/dagre/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_groups/dagre/sketch.exp.svg
index ec8e7b216..9c0b05ef8 100644
--- a/e2etests/testdata/stable/sequence_diagram_groups/dagre/sketch.exp.svg
+++ b/e2etests/testdata/stable/sequence_diagram_groups/dagre/sketch.exp.svg
@@ -20,6 +20,11 @@ width="1147" height="2268" viewBox="-76 -26 1147 2268">abcdggggroup 1group bchoonested guy lalaeyokayokaywhat would arnold saythis note
+
+
+
+
+
diff --git a/e2etests/testdata/stable/sequence_diagram_groups/elk/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_groups/elk/sketch.exp.svg
index ec8e7b216..9c0b05ef8 100644
--- a/e2etests/testdata/stable/sequence_diagram_groups/elk/sketch.exp.svg
+++ b/e2etests/testdata/stable/sequence_diagram_groups/elk/sketch.exp.svg
@@ -20,6 +20,11 @@ width="1147" height="2268" viewBox="-76 -26 1147 2268">abcdggggroup 1group bchoonested guy lalaeyokayokaywhat would arnold saythis note
+
+
+
+
+
diff --git a/e2etests/testdata/stable/sequence_diagram_nested_groups/dagre/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_nested_groups/dagre/sketch.exp.svg
index e97ce77dc..70e362bbd 100644
--- a/e2etests/testdata/stable/sequence_diagram_nested_groups/dagre/sketch.exp.svg
+++ b/e2etests/testdata/stable/sequence_diagram_nested_groups/dagre/sketch.exp.svg
@@ -18,7 +18,19 @@ width="1116" height="2458" viewBox="-197 -26 1116 2458">abjust an actorthis is a message groupaltand this is a nested message groupcase 1case 2case 3case 4what about more nestingcrazy townwhoa a notea note here to remember that padding must consider notes toojustalongnotehereabjust an actorthis is a message groupaltand this is a nested message groupcase 1case 2case 3case 4what about more nestingcrazy townwhoa a notea note here to remember that padding must consider notes toojustalongnotehere
+
+
+
+
+
+
+
+
+
+
+
+abjust an actorthis is a message groupaltand this is a nested message groupcase 1case 2case 3case 4what about more nestingcrazy townwhoa a notea note here to remember that padding must consider notes toojustalongnotehereabjust an actorthis is a message groupaltand this is a nested message groupcase 1case 2case 3case 4what about more nestingcrazy townwhoa a notea note here to remember that padding must consider notes toojustalongnotehere
+
+
+
+
+
+
+
+
+
+
+
+How this is renderedCLId2astd2compilerd2layoutd2exporterd2themesd2rendererd2sequencelayoutd2dagrelayoutonly if root is not sequence 'How this is rendered: {...}'tokenized ASTcompile ASTobjects and edgesrun layout enginesrun engine on shape: sequence_diagram, temporarily removerun core engine on rest add back in sequence diagramsdiagram with correct positions and dimensionsexport diagram with chosen theme and rendererget theme stylesrender to SVGresulting SVGmeasurements also take place
+
diff --git a/e2etests/testdata/stable/sequence_diagram_real/elk/sketch.exp.svg b/e2etests/testdata/stable/sequence_diagram_real/elk/sketch.exp.svg
index 9e6ceb66d..095df39cf 100644
--- a/e2etests/testdata/stable/sequence_diagram_real/elk/sketch.exp.svg
+++ b/e2etests/testdata/stable/sequence_diagram_real/elk/sketch.exp.svg
@@ -20,6 +20,7 @@ width="2447" height="2536" viewBox="-88 -88 2447 2536">How this is renderedCLId2astd2compilerd2layoutd2exporterd2themesd2rendererd2sequencelayoutd2dagrelayoutonly if root is not sequence 'How this is rendered: {...}'tokenized ASTcompile ASTobjects and edgesrun layout enginesrun engine on shape: sequence_diagram, temporarily removerun core engine on rest add back in sequence diagramsdiagram with correct positions and dimensionsexport diagram with chosen theme and rendererget theme stylesrender to SVGresulting SVGmeasurements also take place
+
diff --git a/e2etests/testdata/todo/sequence_diagram_actor_padding_nested_groups/dagre/sketch.exp.svg b/e2etests/testdata/todo/sequence_diagram_actor_padding_nested_groups/dagre/sketch.exp.svg
index 45f3f9430..9357326e5 100644
--- a/e2etests/testdata/todo/sequence_diagram_actor_padding_nested_groups/dagre/sketch.exp.svg
+++ b/e2etests/testdata/todo/sequence_diagram_actor_padding_nested_groups/dagre/sketch.exp.svg
@@ -18,7 +18,14 @@ width="921" height="1242" viewBox="-147 -26 921 1242">bacthis is a message groupand this is a nested message groupwhat about more nestingyoyo bacthis is a message groupand this is a nested message groupwhat about more nestingyoyo
+
+
+
+
+
+
+bacthis is a message groupand this is a nested message groupwhat about more nestingyoyo bacthis is a message groupand this is a nested message groupwhat about more nestingyoyo
+
+
+
+
+
+
+