d2/d2graph/seqdiagram.go

109 lines
2.3 KiB
Go
Raw Normal View History

2022-12-05 04:26:37 +00:00
package d2graph
import "oss.terrastruct.com/d2/d2target"
func (obj *Object) IsSequenceDiagram() bool {
return obj != nil && obj.Attributes != nil && obj.Attributes.Shape.Value == d2target.ShapeSequenceDiagram
2022-12-05 04:26:37 +00:00
}
2022-12-05 18:46:06 +00:00
func (obj *Object) OuterSequenceDiagram() *Object {
2022-12-05 04:26:37 +00:00
for obj != nil {
obj = obj.Parent
if obj.IsSequenceDiagram() {
return obj
}
}
return nil
}
2022-12-05 05:12:59 +00:00
// groups are objects in sequence diagrams that have no messages connected
// and does not have a note as a child (a note can appear within a group, but it's a child of an actor)
2022-12-05 05:57:59 +00:00
func (obj *Object) IsSequenceDiagramGroup() bool {
2022-12-05 18:46:06 +00:00
if obj.OuterSequenceDiagram() == nil {
2022-12-05 05:57:59 +00:00
return false
}
for _, e := range obj.Graph.Edges {
2022-12-05 05:12:59 +00:00
if e.Src == obj || e.Dst == obj {
return false
}
}
for _, ch := range obj.ChildrenArray {
// if the child contains a message, it's a span, not a note
2022-12-05 05:57:59 +00:00
if !ch.ContainsAnyEdge(obj.Graph.Edges) {
2022-12-05 05:12:59 +00:00
return false
}
}
2023-02-02 18:30:54 +00:00
return len(obj.ChildrenArray) > 0 || obj.ContainsAnyEdge(obj.Graph.Edges)
2022-12-05 05:12:59 +00:00
}
2022-12-05 04:26:37 +00:00
// notes are descendant of actors with no edges and no children
func (obj *Object) IsSequenceDiagramNote() bool {
2022-12-05 18:46:06 +00:00
if obj.OuterSequenceDiagram() == nil {
2022-12-05 04:26:37 +00:00
return false
}
2022-12-05 20:09:32 +00:00
return !obj.hasEdgeRef() && !obj.ContainsAnyEdge(obj.Graph.Edges) && len(obj.ChildrenArray) == 0 && !obj.ContainsAnyObject(obj.Graph.Objects)
2022-12-05 04:26:37 +00:00
}
func (obj *Object) hasEdgeRef() bool {
for _, ref := range obj.References {
if ref.MapKey != nil && len(ref.MapKey.Edges) > 0 {
return true
}
}
return false
}
2022-12-05 19:36:19 +00:00
func (obj *Object) ContainsAnyObject(objects []*Object) bool {
for _, o := range objects {
if o.ContainedBy(obj) {
return true
}
}
return false
}
func (o *Object) ContainedBy(obj *Object) bool {
for _, ref := range o.References {
2023-01-24 05:48:43 +00:00
curr := ref.ScopeObj
2022-12-05 19:36:19 +00:00
for curr != nil {
if curr == obj {
return true
}
curr = curr.Parent
}
}
return false
}
2022-12-05 04:26:37 +00:00
func (obj *Object) ContainsAnyEdge(edges []*Edge) bool {
for _, e := range edges {
if e.ContainedBy(obj) {
return true
}
}
return false
}
func (e *Edge) ContainedBy(obj *Object) bool {
for _, ref := range e.References {
curr := ref.ScopeObj
for curr != nil {
if curr == obj {
return true
}
curr = curr.Parent
}
}
return false
}
func (e *Edge) GetGroup() *Object {
for _, ref := range e.References {
2023-01-27 02:39:33 +00:00
if ref.ScopeObj.IsSequenceDiagramGroup() {
return ref.ScopeObj
}
}
return nil
}