Sign in

    #Swimlane geometry

    This package lays out the immutable diagrams/swimlane model. Inputs and output are explicit values. It imports no Mermaid or BPMN document module.

    ///|
    test "measured lanes retain source order and expose checker findings" {
    let view = @model.Swimlane::new(
    "review",
    [
    @model.Node::new("A", lane="Customer"),
    @model.Node::new("B", lane="Support"),
    ],
    [@model.Connection::new("AB", "A", "B")],
    direction=LR,
    lanes=[@model.Lane::new("Customer"), @model.Lane::new("Support")],
    )
    let result = @layout.layout(view)
    let geometry = result.geometry.unwrap()
    let customer = geometry.shapes
    .iter()
    .find_first(s => s.id == "Customer")
    .unwrap()
    let support = geometry.shapes
    .iter()
    .find_first(s => s.id == "Support")
    .unwrap()
    assert_true(customer.box.y < support.box.y)
    assert_eq(geometry.connections[0].connection.id, "AB")
    assert_eq(
    @layout.check(geometry, @layout.palette(@theme.Theme::classic().light)),
    [],
    )
    assert_eq(
    @layout.layout(view, limits=@layout.Limits::new(work=1)).geometry,
    None,
    )
    }

    layout walks nested scopes with an explicit stack. It measures labels, keeps empty lanes, packs unowned nodes separately and ranks condensed cycles. Local scope directions are independent of the global flow direction. Reversing flow never reverses source lane order or connection identities. Minimum-length hints reserve additional rank gaps. Disconnected children retain declaration order.

    Each vector silhouette and edge port share outline. Routing uses bounded orthogonal search around unrelated shapes and label boxes. Return edges, self-loops and parallel handoffs retain distinct paths and ports. Visible edges that cross a collapsed boundary attach to that ancestor while their stored connection keeps its logical endpoints. Hidden internal edges are omitted. Invisible connections constrain placement but do not paint or animate.

    Limits::new(minimum_approach=24.0) reserves every straight endpoint corridor before routing middle segments or placing connection labels. This prevents an earlier edge from blocking a later marker approach. Return and parallel routes use separate collinear channels, while transverse crossings remain available for display bridges. Compact symbols with external labels use a clear side; concave silhouettes retain their actual outline attachment. Larger minima increase the automatic scope spacing. Existing route points remain available separately from the renderer's final styled paths.

    Side ports follow the other endpoints' cross-axis order, with declaration order breaking ties for parallel identities. The bounded grid search indexes obstacle rows and columns and caches segment checks. Optional channels keep room beside existing spans for safe bends and bridges; actual endpoint coordinates stay fixed.

    Limits::new defaults to 10,000 elements, 50,000 connections, depth 256, 1,000,000 work units and 16 Mi UTF-16 output units. Ownership or reference errors, unsupported shapes and exhausted work return no partial geometry. Routing can fail explicitly when those bounds cannot find a clear path.

    check reports Overlap, Fit, Size, Contrast, Containment, Endpoint and Limit findings. Intended container ownership is permitted. It does not move or repair supplied geometry. Use palette on the shared theme palette to apply the exact ink shades used by the swimlane painter. Derived SVG numbers have at most three fractional digits and are stable on all four backends.

    Connection

    pub struct Connection {
    connection :
    Connection

    index : Int
    source : String
    target : String
    line : ReadOnlyArray[Point]
    label : Label?
    } derive(Eq,
    Debug
    )

    Connection::equal

    fn Connection::equal(Connection, Connection) -> Bool

    Connection::not_equal

    fn Connection::not_equal(x : Connection, y : Connection) -> Bool

    ConnectionNote

    pub struct ConnectionNote {
    id : String
    connection : String
    note : String
    }

    A note attached to an actual drawn connection rather than a control node.

    ConnectionNote::new

    fn ConnectionNote::new(id : String, connection : String, note : String) -> ConnectionNote

    Finding

    pub struct Finding {
    rule : Rule
    identities : ReadOnlyArray[String]
    message : String
    } derive(Eq,
    Debug
    )

    Finding::equal

    fn Finding::equal(Finding, Finding) -> Bool

    Finding::not_equal

    fn Finding::not_equal(x : Finding, y : Finding) -> Bool

    Finding::to_repr

    Geometry

    pub struct Geometry {
    view :
    Swimlane

    shapes : ReadOnlyArray[Shape]
    connections : ReadOnlyArray[Connection]
    width : Int
    height : Int
    } derive(Eq,
    Debug
    )

    Geometry::annotate

    fn Geometry::annotate(self : Geometry, notes : ArrayView[ConnectionNote], limits? : Limits) -> Result

    Geometry::equal

    fn Geometry::equal(Geometry, Geometry) -> Bool

    Geometry::not_equal

    fn Geometry::not_equal(x : Geometry, y : Geometry) -> Bool

    Geometry::overlay

    fn Geometry::overlay(self : Geometry, definitions : ArrayView[Overlay], limits? : Limits, direction_hints? : ArrayView[(String,
    Direction
    )]) -> Result

    Reframe crossing containers, then route using the same bounded geometry engine. Ordinary layouts do not use this path and retain their canonical geometry.

    Geometry::to_repr

    Kind

    pub(all) enum Kind {
    Lane
    Group
    Node
    } derive(Eq,
    Debug
    )

    Kind::equal

    fn Kind::equal(Kind, Kind) -> Bool

    Kind::not_equal

    fn Kind::not_equal(x : Kind, y : Kind) -> Bool

    Kind::to_repr

    Label

    pub struct Label {
    text : String
    box : Rect
    size : Double
    weight : Int
    owner : String
    family :
    Family
    ?
    } derive(Eq,
    Debug
    )

    Label::equal

    fn Label::equal(Label, Label) -> Bool

    Label::not_equal

    fn Label::not_equal(x : Label, y : Label) -> Bool

    Label::to_repr

    Limits

    pub struct Limits {
    nodes : Int
    edges : Int
    depth : Int
    work : Int
    output_units : Int
    minimum_approach : Double
    } derive(Eq,
    Debug
    )

    Pure swimlane geometry has no dependency on BPMN document or geometry types.

    Limits::equal

    fn Limits::equal(Limits, Limits) -> Bool

    Limits::new

    fn Limits::new(nodes? : Int, edges? : Int, depth? : Int, work? : Int, output_units? : Int, minimum_approach? : Double) -> Limits

    Limits::not_equal

    fn Limits::not_equal(x : Limits, y : Limits) -> Bool

    Limits::to_repr

    Limits::with_minimum_approach

    fn Limits::with_minimum_approach(self : Limits, minimum_approach : Double) -> Limits

    Retain resource limits while selecting the marked terminal reservation.

    Overlay

    pub struct Overlay {
    id : String
    members : ReadOnlyArray[String]
    parent : String?
    }

    A display container whose membership crosses the primary layout hierarchy. The caller supplies inner containers before their outer containers.

    Overlay::new

    fn Overlay::new(id : String, members : ArrayView[String], parent? : String) -> Overlay

    Point

    pub(all) struct Point {
    x : Double
    y : Double
    } derive(Eq,
    Debug
    )

    Point::equal

    fn Point::equal(Point, Point) -> Bool

    Point::not_equal

    fn Point::not_equal(x : Point, y : Point) -> Bool

    Point::to_repr

    Rect

    pub(all) struct Rect {
    x : Double
    y : Double
    width : Double
    height : Double
    } derive(Eq,
    Debug
    )

    Rect::contains

    fn Rect::contains(self : Rect, other : Rect, tolerance? : Double) -> Bool

    Rect::equal

    fn Rect::equal(Rect, Rect) -> Bool

    Rect::not_equal

    fn Rect::not_equal(x : Rect, y : Rect) -> Bool

    Rect::overlaps

    fn Rect::overlaps(self : Rect, other : Rect) -> Bool

    Rect::to_repr

    Result

    pub struct Result {
    geometry : Geometry?
    diagnostics : ReadOnlyArray[
    Diagnostic
    ]
    } derive(Eq,
    Debug
    )

    Result::equal

    fn Result::equal(Result, Result) -> Bool

    Result::not_equal

    fn Result::not_equal(x : Result, y : Result) -> Bool

    Result::to_repr

    Rule

    pub(all) enum Rule {
    Overlap
    Fit
    Size
    Contrast
    Containment
    Endpoint
    Limit
    } derive(Eq,
    Debug
    )

    Rule::equal

    fn Rule::equal(Rule, Rule) -> Bool

    Rule::not_equal

    fn Rule::not_equal(x : Rule, y : Rule) -> Bool

    Rule::to_repr

    Shape

    pub struct Shape {
    id : String
    index : Int
    kind : Kind
    shape : String
    box : Rect
    outline_box : Rect
    label : Label?
    parent : String?
    lane : String?
    expanded : Bool
    } derive(Eq,
    Debug
    )

    Shape::equal

    fn Shape::equal(Shape, Shape) -> Bool

    Shape::not_equal

    fn Shape::not_equal(x : Shape, y : Shape) -> Bool

    Shape::to_repr

    check

    fn check(geometry : Geometry, palette :
    Palette
    , work_limit? : Int, intentional_containment? : ArrayView[(String, String)]) -> ReadOnlyArray[Finding]

    Check measured geometry independently of its painter. Intended nested containment is allowed; ownership, labels, true outline ports and unrelated line intersections are inspected under one explicit work/finding budget.

    family

    fn family(shape : String) ->
    Family

    label_text

    fn label_text(text : String) -> String

    An inert plain-text projection. Source HTML is never inserted into SVG.

    layout

    fn layout(view :
    Swimlane
    , limits? : Limits, flowchart? : Bool, direction_hints? : ArrayView[(String,
    Direction
    )]) -> Result

    Measured responsibility bands, built bottom-up without recursive ownership walks.

    outline

    fn outline(shape : String, box : Rect) -> ReadOnlyArray[Point]

    Each painted outer boundary and its edge attachment use this same vector. Curves use fixed sampled segments, so path bytes and clipping agree on all targets.

    palette

    Preserve palette hues while making ink readable on opaque canvas and fills.

    project_label

    fn project_label(text : String, kind :
    LabelKind
    ) -> String

    Label kind selects presentation projection explicitly. Plain labels keep operators and formatting-like punctuation; source metadata remains inert.

    svg_number

    fn svg_number(value : Double) -> String

    Canonical coordinates have three fractional digits and never use exponent notation.

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io