d2/d2graph/seqdiagram.go
2023-04-13 20:04:55 -07:00

108 lines
2.3 KiB
Go

package d2graph
import "oss.terrastruct.com/d2/d2target"
func (obj *Object) IsSequenceDiagram() bool {
return obj != nil && obj.Shape.Value == d2target.ShapeSequenceDiagram
}
func (obj *Object) OuterSequenceDiagram() *Object {
for obj != nil {
obj = obj.Parent
if obj.IsSequenceDiagram() {
return obj
}
}
return nil
}
// 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)
func (obj *Object) IsSequenceDiagramGroup() bool {
if obj.OuterSequenceDiagram() == nil {
return false
}
for _, e := range obj.Graph.Edges {
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
if !ch.ContainsAnyEdge(obj.Graph.Edges) {
return false
}
}
return obj.ContainsAnyObject(obj.Graph.Objects) || obj.ContainsAnyEdge(obj.Graph.Edges)
}
// notes are descendant of actors with no edges and no children
func (obj *Object) IsSequenceDiagramNote() bool {
if obj.OuterSequenceDiagram() == nil {
return false
}
return !obj.hasEdgeRef() && !obj.ContainsAnyEdge(obj.Graph.Edges) && len(obj.ChildrenArray) == 0 && !obj.ContainsAnyObject(obj.Graph.Objects)
}
func (obj *Object) hasEdgeRef() bool {
for _, ref := range obj.References {
if ref.MapKey != nil && len(ref.MapKey.Edges) > 0 {
return true
}
}
return false
}
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 {
curr := ref.ScopeObj
for curr != nil {
if curr == obj {
return true
}
curr = curr.Parent
}
}
return false
}
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 {
if ref.ScopeObj.IsSequenceDiagramGroup() {
return ref.ScopeObj
}
}
return nil
}