feat: sql_table border radius

This commit is contained in:
donglixiaoche 2023-03-06 13:00:40 +08:00
parent 6670e1967c
commit 4850038406
No known key found for this signature in database
GPG key ID: F235CD35048B3752
2 changed files with 36 additions and 3 deletions

View file

@ -877,6 +877,11 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske
if targetShape.Opacity != 1.0 { if targetShape.Opacity != 1.0 {
opacityStyle = fmt.Sprintf(" style='opacity:%f'", targetShape.Opacity) opacityStyle = fmt.Sprintf(" style='opacity:%f'", targetShape.Opacity)
} }
// this clipPath must be defined outside `g` element
if targetShape.BorderRadius != 0 {
fmt.Fprint(writer, tableHeaderBorderRadius(targetShape))
}
fmt.Fprintf(writer, `<g id="%s"%s>`, svg.EscapeText(targetShape.ID), opacityStyle) fmt.Fprintf(writer, `<g id="%s"%s>`, svg.EscapeText(targetShape.ID), opacityStyle)
tl := geo.NewPoint(float64(targetShape.Pos.X), float64(targetShape.Pos.Y)) tl := geo.NewPoint(float64(targetShape.Pos.X), float64(targetShape.Pos.Y))
width := float64(targetShape.Width) width := float64(targetShape.Width)

View file

@ -3,6 +3,7 @@ package d2svg
import ( import (
"fmt" "fmt"
"io" "io"
"strings"
"oss.terrastruct.com/d2/d2target" "oss.terrastruct.com/d2/d2target"
"oss.terrastruct.com/d2/d2themes" "oss.terrastruct.com/d2/d2themes"
@ -12,6 +13,23 @@ import (
"oss.terrastruct.com/util-go/go2" "oss.terrastruct.com/util-go/go2"
) )
func tableHeaderBorderRadius(shape d2target.Shape) string {
box := geo.NewBox(
geo.NewPoint(float64(shape.Pos.X), float64(shape.Pos.Y)),
float64(shape.Width),
float64(shape.Height),
)
topX, topY := box.TopLeft.X+box.Width, box.TopLeft.Y
out := fmt.Sprintf(`<clipPath id="%v">`, shape.ID)
out += fmt.Sprintf(`<path d="M %f %f L %f %f S %f %f %f %f `, box.TopLeft.X, box.TopLeft.Y+float64(shape.BorderRadius), box.TopLeft.X, box.TopLeft.Y+float64(shape.BorderRadius), box.TopLeft.X, box.TopLeft.Y, box.TopLeft.X+float64(shape.BorderRadius), box.TopLeft.Y)
out += fmt.Sprintf(`L %f %f L %f %f `, box.TopLeft.X+box.Width-float64(shape.BorderRadius), box.TopLeft.Y, topX-float64(shape.BorderRadius), topY)
out += fmt.Sprintf(`S %f %f %f %f `, topX, topY, topX, topY+float64(shape.BorderRadius))
out += fmt.Sprintf(`L %f %f L %f %f `, topX, topY+box.Height, box.TopLeft.X, box.TopLeft.Y+box.Height)
out += fmt.Sprintf(`Z %f %f" `, box.TopLeft.X, box.TopLeft.Y)
return out + `fill="none" /> </clipPath>`
}
func tableHeader(shape d2target.Shape, box *geo.Box, text string, textWidth, textHeight, fontSize float64) string { func tableHeader(shape d2target.Shape, box *geo.Box, text string, textWidth, textHeight, fontSize float64) string {
rectEl := d2themes.NewThemableElement("rect") rectEl := d2themes.NewThemableElement("rect")
rectEl.X, rectEl.Y = box.TopLeft.X, box.TopLeft.Y rectEl.X, rectEl.Y = box.TopLeft.X, box.TopLeft.Y
@ -19,6 +37,9 @@ func tableHeader(shape d2target.Shape, box *geo.Box, text string, textWidth, tex
rectEl.Fill = shape.Fill rectEl.Fill = shape.Fill
rectEl.ClassName = "class_header" rectEl.ClassName = "class_header"
str := rectEl.Render() str := rectEl.Render()
if shape.BorderRadius != 0 {
str = strings.Replace(str, "/>", fmt.Sprintf(`clip-path="url(#%v)" />`, shape.ID), 1)
}
if text != "" { if text != "" {
tl := label.InsideMiddleLeft.GetPointOnBox( tl := label.InsideMiddleLeft.GetPointOnBox(
@ -91,6 +112,8 @@ func drawTable(writer io.Writer, targetShape d2target.Shape) {
rectEl.Fill, rectEl.Stroke = d2themes.ShapeTheme(targetShape) rectEl.Fill, rectEl.Stroke = d2themes.ShapeTheme(targetShape)
rectEl.ClassName = "shape" rectEl.ClassName = "shape"
rectEl.Style = targetShape.CSSStyle() rectEl.Style = targetShape.CSSStyle()
rectEl.Rx = float64(targetShape.BorderRadius)
rectEl.Ry = float64(targetShape.BorderRadius)
fmt.Fprint(writer, rectEl.Render()) fmt.Fprint(writer, rectEl.Render())
box := geo.NewBox( box := geo.NewBox(
@ -113,15 +136,20 @@ func drawTable(writer io.Writer, targetShape d2target.Shape) {
rowBox := geo.NewBox(box.TopLeft.Copy(), box.Width, rowHeight) rowBox := geo.NewBox(box.TopLeft.Copy(), box.Width, rowHeight)
rowBox.TopLeft.Y += headerBox.Height rowBox.TopLeft.Y += headerBox.Height
for _, f := range targetShape.Columns { for idx, f := range targetShape.Columns {
fmt.Fprint(writer, fmt.Fprint(writer,
tableRow(targetShape, rowBox, f.Name.Label, f.Type.Label, f.ConstraintAbbr(), float64(targetShape.FontSize), float64(longestNameWidth)), tableRow(targetShape, rowBox, f.Name.Label, f.Type.Label, f.ConstraintAbbr(), float64(targetShape.FontSize), float64(longestNameWidth)),
) )
rowBox.TopLeft.Y += rowHeight rowBox.TopLeft.Y += rowHeight
lineEl := d2themes.NewThemableElement("line") lineEl := d2themes.NewThemableElement("line")
lineEl.X1, lineEl.Y1 = rowBox.TopLeft.X, rowBox.TopLeft.Y if idx == len(targetShape.Columns)-1 && targetShape.BorderRadius != 0 {
lineEl.X2, lineEl.Y2 = rowBox.TopLeft.X+rowBox.Width, rowBox.TopLeft.Y lineEl.X1, lineEl.Y1 = rowBox.TopLeft.X+float64(targetShape.BorderRadius), rowBox.TopLeft.Y
lineEl.X2, lineEl.Y2 = rowBox.TopLeft.X+rowBox.Width-float64(targetShape.BorderRadius), rowBox.TopLeft.Y
} else {
lineEl.X1, lineEl.Y1 = rowBox.TopLeft.X, rowBox.TopLeft.Y
lineEl.X2, lineEl.Y2 = rowBox.TopLeft.X+rowBox.Width, rowBox.TopLeft.Y
}
lineEl.Stroke = targetShape.Fill lineEl.Stroke = targetShape.Fill
lineEl.Style = "stroke-width:2" lineEl.Style = "stroke-width:2"
fmt.Fprint(writer, lineEl.Render()) fmt.Fprint(writer, lineEl.Render())