diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 16345ed6f..0e3db323c 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -181,9 +181,10 @@ func (a *Attributes) ToArrowhead() d2target.Arrowhead { return d2target.NoArrowhead } - filled := false + var filled *bool if a.Style.Filled != nil { - filled, _ = strconv.ParseBool(a.Style.Filled.Value) + v, _ := strconv.ParseBool(a.Style.Filled.Value) + filled = go2.Pointer(v) } return d2target.ToArrowhead(a.Shape.Value, filled) } diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index 2e910d658..69b439bac 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -138,6 +138,28 @@ func arrowheadMarker(isTarget bool, id string, connection d2target.Connection) s ) } path = polygonEl.Render() + case d2target.UnfilledTriangleArrowhead: + polygonEl := d2themes.NewThemableElement("polygon") + polygonEl.Fill = d2target.BG_COLOR + polygonEl.Stroke = connection.Stroke + polygonEl.ClassName = "connection" + polygonEl.Attributes = fmt.Sprintf(`stroke-width="%d"`, connection.StrokeWidth) + + if isTarget { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f", + 0., 0., + width, height/2.0, + 0., height, + ) + } else { + polygonEl.Points = fmt.Sprintf("%f,%f %f,%f %f,%f", + width, 0., + 0., height/2.0, + width, height, + ) + } + path = polygonEl.Render() + case d2target.TriangleArrowhead: polygonEl := d2themes.NewThemableElement("polygon") polygonEl.Fill = connection.Stroke diff --git a/d2target/d2target.go b/d2target/d2target.go index 9b69ff472..a20352bb7 100644 --- a/d2target/d2target.go +++ b/d2target/d2target.go @@ -720,13 +720,14 @@ func (c Connection) GetID() string { type Arrowhead string const ( - NoArrowhead Arrowhead = "none" - ArrowArrowhead Arrowhead = "arrow" - TriangleArrowhead Arrowhead = "triangle" - DiamondArrowhead Arrowhead = "diamond" - FilledDiamondArrowhead Arrowhead = "filled-diamond" - CircleArrowhead Arrowhead = "circle" - FilledCircleArrowhead Arrowhead = "filled-circle" + NoArrowhead Arrowhead = "none" + ArrowArrowhead Arrowhead = "arrow" + UnfilledTriangleArrowhead Arrowhead = "unfilled-triangle" + TriangleArrowhead Arrowhead = "triangle" + DiamondArrowhead Arrowhead = "diamond" + FilledDiamondArrowhead Arrowhead = "filled-diamond" + CircleArrowhead Arrowhead = "circle" + FilledCircleArrowhead Arrowhead = "filled-circle" // For fat arrows LineArrowhead Arrowhead = "line" @@ -740,29 +741,28 @@ const ( DefaultArrowhead Arrowhead = TriangleArrowhead ) +// valid values for arrowhead.shape var Arrowheads = map[string]struct{}{ - string(NoArrowhead): {}, - string(ArrowArrowhead): {}, - string(TriangleArrowhead): {}, - string(DiamondArrowhead): {}, - string(FilledDiamondArrowhead): {}, - string(CircleArrowhead): {}, - string(FilledCircleArrowhead): {}, - string(CfOne): {}, - string(CfMany): {}, - string(CfOneRequired): {}, - string(CfManyRequired): {}, + string(NoArrowhead): {}, + string(ArrowArrowhead): {}, + string(TriangleArrowhead): {}, + string(DiamondArrowhead): {}, + string(CircleArrowhead): {}, + string(CfOne): {}, + string(CfMany): {}, + string(CfOneRequired): {}, + string(CfManyRequired): {}, } -func ToArrowhead(arrowheadType string, filled bool) Arrowhead { +func ToArrowhead(arrowheadType string, filled *bool) Arrowhead { switch arrowheadType { case string(DiamondArrowhead): - if filled { + if filled != nil && *filled { return FilledDiamondArrowhead } return DiamondArrowhead case string(CircleArrowhead): - if filled { + if filled != nil && *filled { return FilledCircleArrowhead } return CircleArrowhead @@ -771,6 +771,9 @@ func ToArrowhead(arrowheadType string, filled bool) Arrowhead { case string(ArrowArrowhead): return ArrowArrowhead case string(TriangleArrowhead): + if filled != nil && !(*filled) { + return UnfilledTriangleArrowhead + } return TriangleArrowhead case string(CfOne): return CfOne @@ -794,7 +797,7 @@ func (arrowhead Arrowhead) Dimensions(strokeWidth float64) (width, height float6 baseHeight = 4 widthMultiplier = 4 heightMultiplier = 4 - case TriangleArrowhead: + case TriangleArrowhead, UnfilledTriangleArrowhead: baseWidth = 4 baseHeight = 4 widthMultiplier = 3