Skip to content

Commit

Permalink
add View->AutoLayout->Implementation to mdl (#545)
Browse files Browse the repository at this point in the history
* add View->AutoLayout->Implementation to mdl

* add View->AutoLayout->Implementation to everything else 😅🤞

* replace Implementation as dedicated function parameter with an own function

* fixed whitespaces and unnecessary test

* fixed missed reverts and formatting
  • Loading branch information
beffge committed Nov 3, 2023
1 parent 8e92b19 commit 6a78441
Show file tree
Hide file tree
Showing 5 changed files with 1,105 additions and 799 deletions.
54 changes: 48 additions & 6 deletions dsl/views.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ type (
// RoutingKind is the enum for possible routing algorithms.
RoutingKind int

// ImplementationKind is the enum for possible automatic layout implementations
ImplementationKind int

// RankDirectionKind is the enum for possible automatic layout rank
// directions.
RankDirectionKind int
Expand All @@ -25,6 +28,13 @@ type (
// DynamicView.
const Global = 0

const (
// ImplementationGraphviz indicates the automatic layout will be using Graphviz
ImplementationGraphviz ImplementationKind = iota + 1
// ImplementationDagre indicates the automatic layout will be using Dagre
ImplementationDagre
)

const (
// RankTopBottom indicates a layout that uses top to bottom rank.
RankTopBottom RankDirectionKind = iota + 1
Expand Down Expand Up @@ -1442,6 +1452,9 @@ func RemoveUnrelated() {
eval.IncompatibleDSL()
}

// DefaultImplementation sets tje default implementation for the auto layout.
var DefaultImplementation = ImplementationDagre

// DefaultRankSeparation sets the default rank separation for auto layout.
var DefaultRankSeparation = 300

Expand All @@ -1451,8 +1464,9 @@ var DefaultNodeSeparation = 600
// DefaultEdgeSeparation sets the default edge separation for auto layout.
var DefaultEdgeSeparation = 200

// AutoLayout enables automatic layout mode for the diagram. The
// first argument indicates the rank direction, it must be one of
// AutoLayout enables automatic layout mode for the diagram.
//
// The First argument indicates the rank direction, it must be one of
// RankTopBottom, RankBottomTop, RankLeftRight or RankRightLeft
//
// AutoLayout must appear in SystemLandscapeView, SystemContextView,
Expand All @@ -1474,6 +1488,7 @@ var DefaultEdgeSeparation = 200
// SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
// AddDefault()
// AutoLayout(RankTopBottom, func() {
// Implementation(ImplementationGraphviz)
// RankSeparation(200)
// NodeSeparation(100)
// EdgeSeparation(10)
Expand All @@ -1496,10 +1511,11 @@ func AutoLayout(rank RankDirectionKind, args ...func()) {
}
}
layout := &expr.AutoLayout{
RankDirection: expr.RankDirectionKind(rank),
RankSep: &DefaultRankSeparation,
NodeSep: &DefaultNodeSeparation,
EdgeSep: &DefaultEdgeSeparation,
RankDirection: expr.RankDirectionKind(rank),
Implementation: expr.ImplementationKind(DefaultImplementation),
RankSep: &DefaultRankSeparation,
NodeSep: &DefaultNodeSeparation,
EdgeSep: &DefaultEdgeSeparation,
}
if dsl != nil {
eval.Execute(dsl, layout)
Expand Down Expand Up @@ -1823,6 +1839,32 @@ func Position(pos int) {
}
}

// Implementation sets the implementation of the automatic layout, defaults to ImplementationDagre.
//
// Implementation must appear in AutoLayout.
//
// Implementation takes one argument: the ImplementationKind.
//
// Example:
//
// var _ = Design(func() {
// var System = SoftwareSystem("Software System", "My software system.")
// Views(func() {
// SystemContextView(SoftwareSystem, "context", "An overview diagram.", func() {
// AutoLayout(func() {
// Implementation(ImplementationGraphviz)
// })
// })
// })
// })
func Implementation(impl ImplementationKind) {
if a, ok := eval.Current().(*expr.AutoLayout); ok {
a.Implementation = expr.ImplementationKind(impl)
return
}
eval.IncompatibleDSL()
}

// RankSeparation sets the separation between ranks in pixels, defaults to 300.
//
// RankSeparation must appear in AutoLayout.
Expand Down
20 changes: 15 additions & 5 deletions expr/view_props.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@ type (

// AutoLayout describes an automatic layout.
AutoLayout struct {
RankDirection RankDirectionKind
RankSep *int
NodeSep *int
EdgeSep *int
Vertices *bool
Implementation ImplementationKind
RankDirection RankDirectionKind
RankSep *int
NodeSep *int
EdgeSep *int
Vertices *bool
}

// Vertex describes the x and y coordinate of a bend in a line.
Expand All @@ -83,6 +84,9 @@ type (
// RoutingKind is the enum for possible routing algorithms.
RoutingKind int

// ImplementationKind is the enum for possible automatic layout implementations
ImplementationKind int

// RankDirectionKind is the enum for possible automatic layout rank
// directions.
RankDirectionKind int
Expand Down Expand Up @@ -120,6 +124,12 @@ const (
RoutingCurved
)

const (
ImplementationUndefined ImplementationKind = iota
ImplementationGraphviz
ImplementationDagre
)

const (
RankUndefined RankDirectionKind = iota
RankTopBottom
Expand Down
11 changes: 6 additions & 5 deletions mdl/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,11 +274,12 @@ func modelizeProps(prop *expr.ViewProps) *ViewProps {
}
if layout := prop.AutoLayout; layout != nil {
props.AutoLayout = &AutoLayout{
RankDirection: RankDirectionKind(layout.RankDirection),
RankSep: layout.RankSep,
NodeSep: layout.NodeSep,
EdgeSep: layout.EdgeSep,
Vertices: layout.Vertices,
Implementation: ImplementationKind(layout.Implementation),
RankDirection: RankDirectionKind(layout.RankDirection),
RankSep: layout.RankSep,
NodeSep: layout.NodeSep,
EdgeSep: layout.EdgeSep,
Vertices: layout.Vertices,
}
}
return props
Expand Down
51 changes: 51 additions & 0 deletions mdl/views.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ type (

// AutoLayout describes an automatic layout.
AutoLayout struct {
// Implementation used for automatic layouting of the view
Implementation ImplementationKind `json:"implementation,omitempty"`
// Algorithm rank direction.
RankDirection RankDirectionKind `json:"rankDirection,omitempty"`
// RankSep defines the separation between ranks in pixels.
Expand Down Expand Up @@ -253,6 +255,9 @@ type (
// RoutingKind is the enum for possible routing algorithms.
RoutingKind int

// ImplementationKind is the enum for possible automatic layout implementations
ImplementationKind int

// RankDirectionKind is the enum for possible automatic layout rank
// directions.
RankDirectionKind int
Expand Down Expand Up @@ -307,6 +312,12 @@ const (
RoutingCurved
)

const (
ImplementationUndefined ImplementationKind = iota
ImplementationGraphviz
ImplementationDagre
)

const (
RankUndefined RankDirectionKind = iota
RankTopBottom
Expand Down Expand Up @@ -575,6 +586,18 @@ func (p *PaperSizeKind) UnmarshalJSON(data []byte) error {
return nil
}

// Name returns the name of the implementation used in the automatic layout of the view.
func (i ImplementationKind) Name() string {
switch i {
case ImplementationGraphviz:
return "Graphviz"
case ImplementationDagre:
return "Dagre"
default:
return "ImplementationUndefined"
}
}

// Name returns the name of the rank direction is specified in the DSL.
func (r RankDirectionKind) Name() string {
switch r {
Expand Down Expand Up @@ -623,6 +646,34 @@ func (r *RoutingKind) UnmarshalJSON(data []byte) error {
return nil
}

// MarshalJSON replaces the constant value with the proper string value.
func (i ImplementationKind) MarshalJSON() ([]byte, error) {
buf := bytes.NewBufferString(`"`)
switch i {
case ImplementationGraphviz:
buf.WriteString("Graphviz")
case ImplementationDagre:
buf.WriteString("Dagre")
}
buf.WriteString(`"`)
return buf.Bytes(), nil
}

// UnmarshalJSON sets the constant from its JSON representation.
func (i *ImplementationKind) UnmarshalJSON(data []byte) error {
var val string
if err := json.Unmarshal(data, &val); err != nil {
return err
}
switch val {
case "Graphviz":
*i = ImplementationGraphviz
case "Dagre":
*i = ImplementationDagre
}
return nil
}

// MarshalJSON replaces the constant value with the proper string value.
func (r RankDirectionKind) MarshalJSON() ([]byte, error) {
buf := bytes.NewBufferString(`"`)
Expand Down
Loading

0 comments on commit 6a78441

Please sign in to comment.