Add double circle shape
This commit is contained in:
parent
5abde05b86
commit
8bb86250fb
6 changed files with 74 additions and 7 deletions
|
|
@ -804,7 +804,7 @@ func (c *compiler) validateKey(obj *d2graph.Object, m *d2ast.Map, mk *d2ast.Key)
|
|||
if reserved == "" {
|
||||
c.errorf(mk.Range.Start, mk.Range.End, "image shapes cannot have children.")
|
||||
}
|
||||
case d2target.ShapeCircle, d2target.ShapeSquare:
|
||||
case d2target.ShapeCircle, d2target.ShapeSquare, d2target.ShapeDoubleCircle:
|
||||
checkEqual := (reserved == "width" && obj.Attributes.Height != nil) ||
|
||||
(reserved == "height" && obj.Attributes.Width != nil)
|
||||
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ func (obj *Object) GetFill(theme *d2themes.Theme) string {
|
|||
|
||||
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 shape == "" || strings.EqualFold(shape, d2target.ShapeSquare) || strings.EqualFold(shape, d2target.ShapeCircle) || strings.EqualFold(shape, d2target.ShapeDoubleCircle) || strings.EqualFold(shape, d2target.ShapeOval) || strings.EqualFold(shape, d2target.ShapeRectangle) {
|
||||
if level == 1 {
|
||||
if !obj.IsContainer() {
|
||||
return theme.Colors.B6
|
||||
|
|
@ -1138,7 +1138,7 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler
|
|||
paddingX, paddingY := obj.GetPadding()
|
||||
|
||||
switch shapeType {
|
||||
case d2target.ShapeSquare, d2target.ShapeCircle:
|
||||
case d2target.ShapeSquare, d2target.ShapeCircle, d2target.ShapeDoubleCircle:
|
||||
if desiredWidth != 0 || desiredHeight != 0 {
|
||||
paddingX = 0.
|
||||
paddingY = 0.
|
||||
|
|
|
|||
|
|
@ -589,6 +589,17 @@ func renderOval(tl *geo.Point, width, height float64, style string) string {
|
|||
return fmt.Sprintf(`<ellipse class="shape" cx="%f" cy="%f" rx="%f" ry="%f" style="%s" />`, cx, cy, rx, ry, style)
|
||||
}
|
||||
|
||||
func renderDoubleCircle(tl *geo.Point, width, height float64, style string) string {
|
||||
rx := width / 2
|
||||
ry := height / 2
|
||||
cx := tl.X + rx
|
||||
cy := tl.Y + ry
|
||||
return fmt.Sprintf(`<ellipse class="shape" cx="%f" cy="%f" rx="%f" ry="%f" style="%s" />
|
||||
<ellipse class="shape" cx="%f" cy="%f" rx="%f" ry="%f" style="%s" />`,
|
||||
cx, cy, rx-2, ry-2, style,
|
||||
cx, cy, rx-10, ry-10, style)
|
||||
}
|
||||
|
||||
func defineShadowFilter(writer io.Writer) {
|
||||
fmt.Fprint(writer, `<defs>
|
||||
<filter id="shadow-filter" width="200%" height="200%" x="-50%" y="-50%">
|
||||
|
|
@ -772,6 +783,19 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske
|
|||
} else {
|
||||
fmt.Fprint(writer, renderOval(tl, width, height, style))
|
||||
}
|
||||
case d2target.ShapeDoubleCircle:
|
||||
if targetShape.Multiple {
|
||||
fmt.Fprint(writer, renderDoubleCircle(multipleTL, width, height, style))
|
||||
}
|
||||
if sketchRunner != nil {
|
||||
out, err := d2sketch.Oval(sketchRunner, targetShape)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
fmt.Fprintf(writer, out)
|
||||
} else {
|
||||
fmt.Fprint(writer, renderDoubleCircle(tl, width, height, style))
|
||||
}
|
||||
|
||||
case d2target.ShapeImage:
|
||||
fmt.Fprintf(writer, `<image href="%s" x="%d" y="%d" width="%d" height="%d" style="%s" />`,
|
||||
|
|
|
|||
|
|
@ -427,6 +427,7 @@ const (
|
|||
ShapeSQLTable = "sql_table"
|
||||
ShapeImage = "image"
|
||||
ShapeSequenceDiagram = "sequence_diagram"
|
||||
ShapeDoubleCircle = "double_circle"
|
||||
)
|
||||
|
||||
var Shapes = []string{
|
||||
|
|
@ -453,6 +454,7 @@ var Shapes = []string{
|
|||
ShapeSQLTable,
|
||||
ShapeImage,
|
||||
ShapeSequenceDiagram,
|
||||
ShapeDoubleCircle,
|
||||
}
|
||||
|
||||
func IsShape(s string) bool {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ const (
|
|||
CIRCLE_TYPE = "Circle"
|
||||
HEXAGON_TYPE = "Hexagon"
|
||||
CLOUD_TYPE = "Cloud"
|
||||
DOUBLE_CIRCLE_TYPE = "DoubleCircle"
|
||||
|
||||
TABLE_TYPE = "Table"
|
||||
CLASS_TYPE = "Class"
|
||||
|
|
@ -108,6 +109,8 @@ func NewShape(shapeType string, box *geo.Box) Shape {
|
|||
return NewCallout(box)
|
||||
case CIRCLE_TYPE:
|
||||
return NewCircle(box)
|
||||
case DOUBLE_CIRCLE_TYPE:
|
||||
return NewDoubleCircle(box)
|
||||
case CLASS_TYPE:
|
||||
return NewClass(box)
|
||||
case CLOUD_TYPE:
|
||||
|
|
@ -164,10 +167,11 @@ func NewShape(shapeType string, box *geo.Box) Shape {
|
|||
// p is the prev point (used to calculate slope)
|
||||
// s is the point on the actual shape border that'll be returned
|
||||
//
|
||||
// p
|
||||
// │
|
||||
// │
|
||||
// ▼
|
||||
// p
|
||||
// │
|
||||
// │
|
||||
// ▼
|
||||
//
|
||||
// ┌────r─────────────────────────┐
|
||||
// │ │
|
||||
// │ │ │
|
||||
|
|
|
|||
37
lib/shape/shape_double_circle.go
Normal file
37
lib/shape/shape_double_circle.go
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
package shape
|
||||
|
||||
import (
|
||||
"oss.terrastruct.com/d2/lib/geo"
|
||||
"oss.terrastruct.com/d2/lib/svg"
|
||||
)
|
||||
|
||||
type shapeDoubleCircle struct {
|
||||
*baseShape
|
||||
}
|
||||
|
||||
func NewDoubleCircle(box *geo.Box) Shape {
|
||||
return shapeDoubleCircle{
|
||||
baseShape: &baseShape{
|
||||
Type: DOUBLE_CIRCLE_TYPE,
|
||||
Box: box,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func doubleCirclePath(box *geo.Box) *svg.SvgPathContext {
|
||||
// halfYFactor := 43.6 / 87.3
|
||||
pc := svg.NewSVGPathContext(box.TopLeft, box.Width, box.Height)
|
||||
pc.StartAt(pc.Absolute(0.25, 0))
|
||||
// pc
|
||||
return pc
|
||||
}
|
||||
|
||||
func (s shapeDoubleCircle) Perimeter() []geo.Intersectable {
|
||||
return doubleCirclePath(s.Box).Path
|
||||
}
|
||||
|
||||
func (s shapeDoubleCircle) GetSVGPathData() []string {
|
||||
return []string{
|
||||
doubleCirclePath(s.Box).PathData(),
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue