diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 62ba2bbb6..68939d98c 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -9,6 +9,7 @@ - Improved label placements for shapes with images to avoid overlapping container labels. [#474](https://github.com/terrastruct/d2/pull/474) - Themes are applied to sql_table and class shapes. [#521](https://github.com/terrastruct/d2/pull/521) +- `class` shapes use monospaced font. [#521](https://github.com/terrastruct/d2/pull/521) - Sequence diagram edge group labels have more reasonable padding. [#512](https://github.com/terrastruct/d2/pull/512) - ELK layout engine preserves order of nodes. [#282](https://github.com/terrastruct/d2/issues/282) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 9f7d6fd3a..956244dc9 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -913,6 +913,8 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler } } innerLabelPadding = 0 + } else if obj.Attributes.Shape.Value == d2target.ShapeClass { + dims = getTextDimensions(mtexts, ruler, obj.Text(), go2.Pointer(d2fonts.SourceCodePro)) } else { dims = getTextDimensions(mtexts, ruler, obj.Text(), fontFamily) } @@ -968,7 +970,7 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler maxWidth := dims.Width for _, f := range obj.Class.Fields { - fdims := getTextDimensions(mtexts, ruler, f.Text(), fontFamily) + fdims := getTextDimensions(mtexts, ruler, f.Text(), go2.Pointer(d2fonts.SourceCodePro)) if fdims == nil { return fmt.Errorf("dimensions for class field %#v not found", f.Text()) } @@ -978,7 +980,7 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler } } for _, m := range obj.Class.Methods { - mdims := getTextDimensions(mtexts, ruler, m.Text(), fontFamily) + mdims := getTextDimensions(mtexts, ruler, m.Text(), go2.Pointer(d2fonts.SourceCodePro)) if mdims == nil { return fmt.Errorf("dimensions for class method %#v not found", m.Text()) } @@ -997,7 +999,7 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler } if anyRowText != nil { // 10px of padding top and bottom so text doesn't look squished - rowHeight := getTextDimensions(mtexts, ruler, anyRowText, fontFamily).Height + 20 + rowHeight := getTextDimensions(mtexts, ruler, anyRowText, go2.Pointer(d2fonts.SourceCodePro)).Height + 20 obj.Height = float64(rowHeight * (len(obj.Class.Fields) + len(obj.Class.Methods) + 2)) } // Leave room for padding diff --git a/d2renderers/d2sketch/sketch.go b/d2renderers/d2sketch/sketch.go index afb71c87f..4c4913a2b 100644 --- a/d2renderers/d2sketch/sketch.go +++ b/d2renderers/d2sketch/sketch.go @@ -372,7 +372,7 @@ func Class(r *Runner, shape d2target.Shape) (string, error) { ) if shape.Label != "" { - tl := label.InsideMiddleLeft.GetPointOnBox( + tl := label.InsideMiddleCenter.GetPointOnBox( headerBox, 0, float64(shape.LabelWidth), @@ -380,7 +380,7 @@ func Class(r *Runner, shape d2target.Shape) (string, error) { ) output += fmt.Sprintf(`%s`, - "text", + "text-mono", tl.X+float64(shape.LabelWidth)/2, tl.Y+float64(shape.LabelHeight)*3/4, fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", @@ -437,21 +437,21 @@ func classRow(shape d2target.Shape, box *geo.Box, prefix, nameText, typeText str ) output += strings.Join([]string{ - fmt.Sprintf(`%s`, + fmt.Sprintf(`%s`, prefixTL.X, prefixTL.Y+fontSize*3/4, fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", "start", fontSize, shape.PrimaryAccentColor), prefix, ), - fmt.Sprintf(`%s`, + fmt.Sprintf(`%s`, prefixTL.X+d2target.PrefixWidth, prefixTL.Y+fontSize*3/4, fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", "start", fontSize, shape.Fill), svg.EscapeText(nameText), ), - fmt.Sprintf(`%s`, + fmt.Sprintf(`%s`, typeTR.X, typeTR.Y+fontSize*3/4, fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s;", "end", fontSize, shape.SecondaryAccentColor), diff --git a/d2renderers/d2sketch/testdata/class/sketch.exp.svg b/d2renderers/d2sketch/testdata/class/sketch.exp.svg index 827658e48..5dd1ee1a5 100644 --- a/d2renderers/d2sketch/testdata/class/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/class/sketch.exp.svg @@ -2,7 +2,7 @@ \ No newline at end of file diff --git a/d2renderers/d2svg/class.go b/d2renderers/d2svg/class.go index 8e8f707ed..85205db32 100644 --- a/d2renderers/d2svg/class.go +++ b/d2renderers/d2svg/class.go @@ -24,11 +24,10 @@ func classHeader(shape d2target.Shape, box *geo.Box, text string, textWidth, tex ) str += fmt.Sprintf(`%s`, - // TODO use monospace font - "text", + "text-mono", tl.X+textWidth/2, tl.Y+textHeight*3/4, - fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", + fmt.Sprintf(`text-anchor:%s;font-size:%vpx;fill:%s`, "middle", 4+fontSize, shape.Stroke, @@ -56,21 +55,21 @@ func classRow(shape d2target.Shape, box *geo.Box, prefix, nameText, typeText str ) return strings.Join([]string{ - fmt.Sprintf(`%s`, + fmt.Sprintf(`%s`, prefixTL.X, prefixTL.Y+fontSize*3/4, fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", "start", fontSize, shape.PrimaryAccentColor), prefix, ), - fmt.Sprintf(`%s`, + fmt.Sprintf(`%s`, prefixTL.X+d2target.PrefixWidth, prefixTL.Y+fontSize*3/4, fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", "start", fontSize, shape.Fill), svg.EscapeText(nameText), ), - fmt.Sprintf(`%s`, + fmt.Sprintf(`%s`, typeTR.X, typeTR.Y+fontSize*3/4, fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", "end", fontSize, shape.SecondaryAccentColor), diff --git a/e2etests/testdata/stable/class/dagre/board.exp.json b/e2etests/testdata/stable/class/dagre/board.exp.json index 41edbb9ad..ada2bfc60 100644 --- a/e2etests/testdata/stable/class/dagre/board.exp.json +++ b/e2etests/testdata/stable/class/dagre/board.exp.json @@ -9,7 +9,7 @@ "x": 0, "y": 0 }, - "width": 339, + "width": 422, "height": 368, "opacity": 1, "strokeDash": 0, @@ -68,7 +68,7 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 150, + "labelWidth": 175, "labelHeight": 36, "zIndex": 0, "level": 1, diff --git a/e2etests/testdata/stable/class/dagre/sketch.exp.svg b/e2etests/testdata/stable/class/dagre/sketch.exp.svg index e016700c8..f47e1aea0 100644 --- a/e2etests/testdata/stable/class/dagre/sketch.exp.svg +++ b/e2etests/testdata/stable/class/dagre/sketch.exp.svg @@ -2,7 +2,7 @@ BatchManager- +num +int- +timeout +int- +pid ++ +getStatus() +Enum+ +getJobs() +Job[]+ +setTimeout(seconds int) +void + \ No newline at end of file diff --git a/e2etests/testdata/stable/class/elk/board.exp.json b/e2etests/testdata/stable/class/elk/board.exp.json index b6a2b2864..438953ee7 100644 --- a/e2etests/testdata/stable/class/elk/board.exp.json +++ b/e2etests/testdata/stable/class/elk/board.exp.json @@ -9,7 +9,7 @@ "x": 12, "y": 12 }, - "width": 339, + "width": 422, "height": 368, "opacity": 1, "strokeDash": 0, @@ -68,7 +68,7 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 150, + "labelWidth": 175, "labelHeight": 36, "zIndex": 0, "level": 1, diff --git a/e2etests/testdata/stable/class/elk/sketch.exp.svg b/e2etests/testdata/stable/class/elk/sketch.exp.svg index 522347026..a433f42f0 100644 --- a/e2etests/testdata/stable/class/elk/sketch.exp.svg +++ b/e2etests/testdata/stable/class/elk/sketch.exp.svg @@ -2,7 +2,7 @@ BatchManager- +num +int- +timeout +int- +pid ++ +getStatus() +Enum+ +getJobs() +Job[]+ +setTimeout(seconds int) +void + \ No newline at end of file