diff --git a/d2renderers/d2sketch/sketch.go b/d2renderers/d2sketch/sketch.go index cbd696505..ea3eb941c 100644 --- a/d2renderers/d2sketch/sketch.go +++ b/d2renderers/d2sketch/sketch.go @@ -328,6 +328,149 @@ func Table(r *Runner, shape d2target.Shape) (string, error) { return output, nil } +func Class(r *Runner, shape d2target.Shape) (string, error) { + output := "" + js := fmt.Sprintf(`node = rc.rectangle(0, 0, %d, %d, { + fill: "%s", + stroke: "%s", + strokeWidth: %d, + %s + });`, shape.Width, shape.Height, shape.Fill, shape.Stroke, shape.StrokeWidth, baseRoughProps) + paths, err := computeRoughPaths(r, js) + if err != nil { + return "", err + } + for _, p := range paths { + output += fmt.Sprintf( + ``, + shape.Pos.X, shape.Pos.Y, p, shapeStyle(shape), + ) + } + + box := geo.NewBox( + geo.NewPoint(float64(shape.Pos.X), float64(shape.Pos.Y)), + float64(shape.Width), + float64(shape.Height), + ) + + rowHeight := box.Height / float64(2+len(shape.Class.Fields)+len(shape.Class.Methods)) + headerBox := geo.NewBox(box.TopLeft, box.Width, 2*rowHeight) + + js = fmt.Sprintf(`node = rc.rectangle(0, 0, %d, %f, { + fill: "%s", + %s + });`, shape.Width, headerBox.Height, shape.Fill, baseRoughProps) + paths, err = computeRoughPaths(r, js) + if err != nil { + return "", err + } + for _, p := range paths { + // TODO header fill + output += fmt.Sprintf( + ``, + shape.Pos.X, shape.Pos.Y, p, "#0a0f25", + ) + } + + output += fmt.Sprintf( + ``, + shape.Pos.X, shape.Pos.Y, shape.Width, headerBox.Height, + ) + + if shape.Label != "" { + tl := label.InsideMiddleLeft.GetPointOnBox( + headerBox, + 0, + float64(shape.LabelWidth), + float64(shape.LabelHeight), + ) + + // TODO header font color + output += fmt.Sprintf(`%s`, + "text", + tl.X+float64(shape.LabelWidth)/2, + tl.Y+float64(shape.LabelHeight)*3/4, + fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", + "middle", + 4+shape.FontSize, + "white", + ), + svg.EscapeText(shape.Label), + ) + } + + rowBox := geo.NewBox(box.TopLeft.Copy(), box.Width, rowHeight) + rowBox.TopLeft.Y += headerBox.Height + for _, f := range shape.Fields { + output += classRow(rowBox, f.VisibilityToken(), f.Name, f.Type, float64(shape.FontSize)) + rowBox.TopLeft.Y += rowHeight + } + + js = fmt.Sprintf(`node = rc.line(%f, %f, %f, %f, { +%s + });`, rowBox.TopLeft.X, rowBox.TopLeft.Y, rowBox.TopLeft.X+rowBox.Width, rowBox.TopLeft.Y, baseRoughProps) + paths, err = computeRoughPaths(r, js) + if err != nil { + return "", err + } + for _, p := range paths { + output += fmt.Sprintf( + ``, + p, "#0a0f25", + ) + } + + for _, m := range shape.Methods { + output += classRow(rowBox, m.VisibilityToken(), m.Name, m.Return, float64(shape.FontSize)) + rowBox.TopLeft.Y += rowHeight + } + + return output, nil +} + +func classRow(box *geo.Box, prefix, nameText, typeText string, fontSize float64) string { + output := "" + prefixTL := label.InsideMiddleLeft.GetPointOnBox( + box, + d2target.PrefixPadding, + box.Width, + fontSize, + ) + typeTR := label.InsideMiddleRight.GetPointOnBox( + box, + d2target.TypePadding, + 0, + fontSize, + ) + + // TODO theme based + accentColor := "rgb(13, 50, 178)" + + output += strings.Join([]string{ + fmt.Sprintf(`%s`, + prefixTL.X, + prefixTL.Y+fontSize*3/4, + fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", "start", fontSize, accentColor), + prefix, + ), + + fmt.Sprintf(`%s`, + prefixTL.X+d2target.PrefixWidth, + prefixTL.Y+fontSize*3/4, + fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s", "start", fontSize, "black"), + svg.EscapeText(nameText), + ), + + fmt.Sprintf(`%s`, + typeTR.X, + typeTR.Y+fontSize*3/4, + fmt.Sprintf("text-anchor:%s;font-size:%vpx;fill:%s;", "end", fontSize, accentColor), + svg.EscapeText(typeText), + ), + }, "\n") + return output +} + func computeRoughPaths(r *Runner, js string) ([]string, error) { if _, err := r.run(js); err != nil { return nil, err diff --git a/d2renderers/d2sketch/testdata/class/sketch.exp.svg b/d2renderers/d2sketch/testdata/class/sketch.exp.svg index 6c8175350..ed2b21d25 100644 --- a/d2renderers/d2sketch/testdata/class/sketch.exp.svg +++ b/d2renderers/d2sketch/testdata/class/sketch.exp.svg @@ -30,19 +30,19 @@ width="553" height="584" viewBox="-100 -100 553 584">