SysML v2 Views

SysML v2 views let you define which elements to include in a diagram and how to render them. A view selects elements using expose statements and optionally narrows the results with filter expressions. Syside also supports additional diagram customisation through configurable attributes.

Views work in both Modeler and Modeler CLI.

package MyViews {
    private import Views::asTreeDiagram;

    part def SystemViews {
        view customDroneView {
            expose DroneModel::DroneSystem::myDrone;
            filter @ SysML::PartUsage;

            attribute depth = 2;
            render asTreeDiagram;
        }
    }
}

This view exposes the myDrone element and filters its contents to show only elements which have metadata of type SysML::PartUsage. The view also contains attribute depth, which tells Syside how deep to traverse each subtree, and render asTreeDiagram which tells Syside which rendering style to use. The following subsections cover each of the three view features in detail: configurable attributes, expose, and filter.

Configurable Attributes

The following attributes can be set on each view:

Attribute

Default

Scope

Description

depth

-1

Both 1

How many levels of descendants to show. -1 for infinite depth. Read depth Explained for detailed explanation.

render

Nested Diagram

Both 1

Layout style. Use render Views::asTreeDiagram for tree layout. Omit for nested. Read render Explained for detailed explanation.

fileType

SVG

CLI 2

Output format: PNG, SVG, or PDF. If both fileType and fileName are set, fileType determines the output format

fileName

diagram-${self.name}

CLI 2

Output file name

zoomLevel

3.0

CLI 2

Zoom level for rendering. Applicable only to PNG output

1 Applicable to both Modeler and Modeler CLI.
2 Applicable to Modeler CLI only. These attributes are used for file-based diagram export.

depth Explained

depth controls how many levels of each exposed element’s subtree to traverse. Traversal happens after filtering, so the diagram may include element types that were filtered out. To avoid this, set depth to 0 or 1 when using filters.

0 shows only the filtered elements. Because filtering applies to elements rather than relationships, no relationships between them appear at this depth.

1 shows the filtered elements and the relationships between them — ownership, state transitions, connections, and similar. Use this depth when relationships need to be visible.

-1 (the default) means infinite depth, which is useful for exploratory diagrams but typically too detailed for documentation and may contain elements that should be filtered out.

render Explained

render controls the layout style used to display the diagram. The default Nested style shows child elements inside their parents; Tree arranges them as a branching tree instead. Both correspond to the “Load Children as Nested” and “Load Children as Tree” tools in the interactive Viewer.

To switch to Tree layout, add a render Views::asTreeDiagram; statement to the view.

Understanding Exposing

Each SysML v2 view must have at least one expose statement. It defines the initial set of elements that are shown in the view. A view can have multiple expose statements, and their results are combined. Once all the expose statements are evaluated, the combined list of elements is passed on to filtering, so getting the initial expose right is crucial.

Note

Unlike other customisation options (such as filter), expose is not inherited. If a view definition declares expose, view usages typed by that definition must redeclare it.

There are multiple ways to write expose statements and each will have a different effect. To make them easier to understand, consider the following simple example model.

package ExposeExample {
    occurrence def SystemContext {
        part rocketShip {
            part firstStage;
            part secondStage;
        }
        part missionControl;
    }

    view systemContextView {
        expose <EXPOSE_PLACEHOLDER>;
    }
}

The following four statements can each replace <EXPOSE_PLACEHOLDER> with a different result:

Syntax

Description

Result

SystemContext

Exposes the namespace itself

SystemContext

SystemContext::*

Exposes the direct children of the namespace

rocketShip, missionControl

SystemContext::**

Exposes the namespace and all its descendants recursively

SystemContext, rocketShip, missionControl, firstStage, secondStage

SystemContext::*::**

Exposes all descendants recursively, but not the namespace itself

rocketShip, missionControl, firstStage, secondStage

Multiple expose statements can be combined to select elements not covered by a single statement. For example, to expose SystemContext, rocketShip, and missionControl without their children:

view systemContextView {
    expose SystemContext;
    expose SystemContext::*;
}

Understanding Filters

A filter expression inside a view narrows the exposed elements to only those that match a condition. Filters can test an element’s type using classification operators defined in the KerML specification (see section KerML 7.4.9.2). For example, filter @ SysML::PartUsage checks each exposed element and keeps only those whose type matches PartUsage.

There are four classification operators:

  • @ — at least one classification matches (includes subtypes). Returns false on null.

  • istype — all classifications must match (includes subtypes). Returns true on null.

  • hastype — all classifications must match (exact type only, no subtypes). Returns true on null.

  • as (cast) — selects values classified by the given type. Useful for accessing metadata attributes in filter expressions.

Consider the following model. It uses the standard library’s RiskMetadata package and a custom FlightCritical metadata tag:

package FilterExample {
    private import RiskMetadata::*;
    metadata def FlightCritical;

    part def DroneSystem {
        part sensor;
        #FlightCritical part controller;
        part camera { @Risk { technicalRisk = RiskLevelEnum::high; } }
        part radio { @Risk { technicalRisk = RiskLevelEnum::medium; } }
        #FlightCritical part battery { @Risk { technicalRisk = RiskLevelEnum::low; } }

        action processData;
        connection dataLink connect sensor to controller;
        allocate processData to controller;
        connect camera to controller;
    }
}

Applying different filters to expose DroneSystem::* produces different results:

Filter

Matches

@ SysML::PartUsage

sensor, controller, camera, radio, battery, dataLink, allocate *, connect *

istype SysML::PartUsage

sensor, dataLink, allocate *, connect *

hastype SysML::PartUsage

sensor

(as Risk).technicalRisk == RiskLevelEnum::high

camera

(as SysML::PartUsage) hastype SysML::PartUsage

sensor, controller, camera, radio, battery

* Unnamed elements created by allocate and connect statements.

The sections below explain why each filter returns what it does.

Matching types and subtypes

filter @ SysML::PartUsage selects every element whose type is PartUsage or any of its specializations. In SysML v2, several usage types specialize PartUsage, including ConnectionUsage and AllocationUsage. This means a view that filters for parts will also include connections and allocations, as shown in the table above.

Note

This is standard SysML v2 behavior, not specific to Syside. The SysML v2 spec (section SysML 7.26.2) uses filter @SysML::PartUsage in its view examples, so users naturally reach for it first. Be aware of the subtype-inclusive semantics.

istype works the same way but with a stricter condition: @ requires at least one of the element’s classifications to match, while istype requires all of them to match. In practice, this means istype fails on elements with metadata annotations (e.g., #FlightCritical part controller), while @ still matches them.

Matching exact types

filter hastype SysML::PartUsage selects only elements whose declared type is exactly PartUsage, excluding specializations. It also fails on elements with metadata annotations, just like istype.

In the model above, only sensor matches because it is the only part with no metadata and no subtype classification.

Warning

Both hastype and istype fail on elements with metadata annotations (e.g., #FlightCritical part controller). Use @ if metadata is present and you don’t need exact type matching.

Accessing metadata attributes

as casts the element to a metadata type, allowing you to access its attributes in filter expressions:

filter (as Risk).technicalRisk == RiskLevelEnum::high;

This casts each element to the Risk metadata type, then checks the technicalRisk attribute. When elements carry multiple metadata annotations, as ensures the attribute is evaluated on the correct type.

For a complete example of metadata-based filtering, see the Filter Evaluation example.

Combining operators

To filter for an exact type while still matching elements with metadata, combine as with hastype:

filter (as SysML::PartUsage) hastype SysML::PartUsage;

The as cast isolates the PartUsage classification, and hastype checks that it is exactly PartUsage, not a subtype. This returns all five parts regardless of metadata, while keeping connections and allocations out.

Tip

Start with hastype for precise filtering, then broaden to @ if you need subtypes included.