Skip to content
GitHub

Tree

Tree manifests describe hierarchical tree diagrams where nodes are connected by edges. They are commonly used for driver trees, decomposition diagrams, and organizational charts.

Unlike ChartStructure and ChartTime, tree charts are structure-driven rather than data-driven. The tree layout is defined by edges connecting node IDs, and the node content is specified separately.

This is the smallest well-formed Tree: the required edges array and the nodes that give every node ID its content. operator is optional per edge, but without it the calculation between siblings stays invisible.

apiVersion: bino.bi/v1alpha1
kind: Tree
metadata:
  name: roi_driver_tree
spec:
  edges:
    - { from: "roi", to: "ros", operator: "x" }
    - { from: "roi", to: "capital-turnover" }
  nodes:
    - id: roi
      kind: Label
      spec:
        value: "<strong>ROI</strong><br/>12.5%"
    - id: ros
      kind: Label
      spec:
        value: "<strong>ROS</strong><br/>8.3%"
    - id: capital-turnover
      kind: Label
      spec:
        value: "<strong>Capital Turnover</strong><br/>1.5x"

Instead of a Label, a node can hold a Table, a chart or a LayoutCard, inline or by ref — see Node kinds. All attributes are listed in the Attribute Reference below.

Array of edge objects defining connections between nodes. Each edge requires:

  • from – source node ID (string, required)
  • to – target node ID (string, required)
  • operator – mathematical operator displayed between siblings: *, /, +, -, x, ÷, or none
  • label – custom label to display instead of operator symbol
  • style – custom edge styling object:
    • color – edge color (string)
    • width – edge width in pixels (number)
    • dasharray – SVG dash pattern (string)

The tree must have exactly one root node (a node that appears only as a from value, never as a to value).

Layout direction of the tree:

  • ltr (default) – left to right, root on left
  • rtl – right to left, root on right
  • ttb – top to bottom, root on top
  • btt – bottom to top, root on bottom

Spacing between hierarchy levels in pixels. Default: 60.

Spacing between sibling nodes in pixels. Default: 20.

Style of connection lines between nodes:

  • straight – direct lines between nodes
  • orthogonal (default) – right-angle lines
  • curved – smooth bezier curves

Whether to display operator symbols between sibling nodes. Default: true.

Optional name of a ComponentStyle to apply; merged over the _system and _default styles.

Optional i18n namespace inherited by the node components of this tree; their own i18nNamespace wins. Resolved from the enclosing artefact, page or card when not set.

Array of node definitions. Each node specifies what component to render at that position in the tree.

  • id (required) – unique identifier matching from/to values in edges
  • kind (required) – type of component: Label, Table, ChartStructure, ChartTime, ChartScatter, ChartBubble, ChartBullet, Image, or LayoutCard
  • ref – reference to a standalone document by name (not supported for Label)
  • params – parameter values (string map) passed to the referenced document; only valid together with ref (see LayoutPage parameters)
  • optional – when true and the referenced document is missing, the node is skipped instead of failing the build (default false)
  • spec – inline component specification (required if no ref)

Tree nodes can contain different types of components. ChartScatter, ChartBubble and ChartBullet are not shown below; they work like ChartTime, inline with their own spec or by ref.

Simple text or HTML content. Labels are defined inline only (no ref support).

nodes:
  - id: roi
    kind: Label
    spec:
      value: "<strong>ROI</strong><br/>12.5%"
      dataset: metrics_dataset  # optional for template interpolation
      scale: auto               # optional font-size scaling
PropertyTypeRequiredDefaultDescriptionSample
nodes[].spec.valuestringyesText or HTML content to display in the label.value: "<strong>ROI</strong>"
nodes[].spec.datasetstring or objectnoDataset binding for template interpolation in the value.dataset: metrics_dataset
nodes[].spec.scalestring or numbernoauto-scale with warningFont-size scaling mode. none disables scaling, auto auto-scales silently, a positive number sets an explicit factor.scale: 0.8

Embed a Table component in a tree node. Can be defined inline or by reference.

nodes:
  # Inline table
  - id: details
    kind: Table
    spec:
      dataset: revenue_breakdown
      scenarios: ["ac1", "py1"]

  # Reference to standalone Table document
  - id: summary
    kind: Table
    ref: revenue_summary_table

Embed a structure chart (bar, pie, etc.) in a tree node.

nodes:
  # Inline chart
  - id: breakdown
    kind: ChartStructure
    spec:
      dataset: cost_breakdown
      scenarios: ["ac1"]
      level: category

  # Reference with overrides
  - id: revenue_chart
    kind: ChartStructure
    ref: base_revenue_chart
    spec:
      filter: "region = 'EMEA'"  # Override filter

Embed a time series chart in a tree node.

nodes:
  - id: trend
    kind: ChartTime
    spec:
      dataset: monthly_revenue
      type: line
      dateInterval: month

Embed an image in a tree node. Can be defined inline or by reference.

nodes:
  # Inline image
  - id: logo
    kind: Image
    spec:
      source: "./assets/company-logo.png"

  # Reference to standalone Image document
  - id: icon
    kind: Image
    ref: status_icon

Embed a card container in a tree node. Cards wrap one or more child components (charts, tables, text). Can be defined inline or by reference.

nodes:
  # Inline card with children
  - id: summary
    kind: LayoutCard
    spec:
      children:
        - kind: Text
          spec:
            value: "Quarterly summary"
        - kind: Table
          spec:
            dataset: revenue_breakdown

  # Reference to standalone LayoutCard document
  - id: kpis
    kind: LayoutCard
    ref: kpi_card
---
apiVersion: bino.bi/v1alpha1
kind: Tree
metadata:
  name: roi_driver_tree
  description: Return on Investment decomposition
spec:
  edges:
    - { from: "roi", to: "ros", operator: "x" }
    - { from: "roi", to: "capital-turnover" }
    - { from: "ros", to: "profit", operator: "/" }
    - { from: "ros", to: "revenue" }
    - { from: "capital-turnover", to: "revenue", operator: "/" }
    - { from: "capital-turnover", to: "capital" }
  direction: ltr
  edgeStyle: orthogonal
  levelSpacing: 80
  nodeSpacing: 30
  showOperators: true
  nodes:
    - id: roi
      kind: Label
      spec:
        value: "<div class='kpi-box'><span class='label'>ROI</span><span class='value'>12.5%</span></div>"
    - id: ros
      kind: Label
      spec:
        value: "<div class='kpi-box'><span class='label'>ROS</span><span class='value'>8.3%</span></div>"
    - id: capital-turnover
      kind: Label
      spec:
        value: "<div class='kpi-box'><span class='label'>Capital Turnover</span><span class='value'>1.5x</span></div>"
    - id: profit
      kind: Label
      spec:
        value: "<div class='kpi-box'><span class='label'>Profit</span><span class='value'>50M EUR</span></div>"
    - id: revenue
      kind: Label
      spec:
        value: "<div class='kpi-box'><span class='label'>Revenue</span><span class='value'>600M EUR</span></div>"
    - id: capital
      kind: Label
      spec:
        value: "<div class='kpi-box'><span class='label'>Capital</span><span class='value'>400M EUR</span></div>"

Example: Mixed content with charts and tables

Section titled “Example: Mixed content with charts and tables”
---
apiVersion: bino.bi/v1alpha1
kind: Tree
metadata:
  name: sales_analysis_tree
spec:
  edges:
    - { from: "total", to: "by-region", operator: "=" }
    - { from: "total", to: "by-product" }
    - { from: "by-region", to: "trend" }
  direction: ttb
  levelSpacing: 100
  nodeSpacing: 40
  nodes:
    # Root: simple label
    - id: total
      kind: Label
      spec:
        value: "<h3>Total Sales</h3><p>$12.5M</p>"

    # Child: structure chart showing regional breakdown
    - id: by-region
      kind: ChartStructure
      spec:
        dataset: sales_by_region
        scenarios: ["ac1"]
        level: category
        limit: 5

    # Child: table with product details
    - id: by-product
      kind: Table
      ref: product_sales_table

    # Grandchild: time series trend
    - id: trend
      kind: ChartTime
      spec:
        dataset: monthly_sales
        type: line
        dateInterval: month

Tree charts can be embedded directly in a LayoutPage:

---
apiVersion: bino.bi/v1alpha1
kind: LayoutPage
metadata:
  name: driver_analysis_page
spec:
  pageLayout: full
  children:
    - kind: Tree
      spec:
        edges:
          - { from: "sales", to: "price", operator: "x" }
          - { from: "sales", to: "volume" }
        direction: ttb
        nodes:
          - id: sales
            kind: Label
            spec:
              value: "<strong>Sales</strong>"
          - id: price
            kind: Label
            spec:
              value: "Price"
          - id: volume
            kind: Label
            spec:
              value: "Volume"

Individual edges can have custom styling:

edges:
  - from: "root"
    to: "child1"
    operator: "+"
    style:
      color: "#ff0000"
      width: 2
      dasharray: "5,5"  # dashed line
  - from: "root"
    to: "child2"
    style:
      color: "#00ff00"

The tree chart supports directed acyclic graphs (DAGs), where a node can have multiple parents:

edges:
  - { from: "a", to: "c" }
  - { from: "b", to: "c" }  # 'c' has two parents
  - { from: "c", to: "d" }

This is useful for showing shared dependencies or converging flows.

For reusable components, define them as standalone documents and reference them in nodes:

---
# Standalone table definition
apiVersion: bino.bi/v1alpha1
kind: Table
metadata:
  name: cost_breakdown_table
spec:
  dataset: cost_data
  scenarios: ["ac1", "py1"]
  variances: ["dpy1_ac1_neg"]
---
# Tree using the reference
apiVersion: bino.bi/v1alpha1
kind: Tree
metadata:
  name: cost_tree
spec:
  edges:
    - { from: "total", to: "breakdown" }
  nodes:
    - id: total
      kind: Label
      spec:
        value: "Total Costs"
    - id: breakdown
      kind: Table
      ref: cost_breakdown_table
      spec:
        limit: 5  # Override: show only top 5
AttributeTypeRequiredDefaultDescription
apiVersionstringyesMust be bino.bi/v1alpha1.
kindstringyesMust be Tree.
metadata.namestringyesUnique identifier.
metadata.labelsobjectnoKey-value pairs for categorization and constraint matching.
metadata.annotationsobjectnoArbitrary key-value metadata, not used by the system.
metadata.descriptionstringnoFree-form description.
metadata.constraintsarraynoConditional inclusion rules. See Constraints.
AttributeTypeRequiredDefaultDescriptionSample
spec.edgesarray or stringyesEdge definitions connecting nodes. JSON string or YAML array.see below
spec.directionstringnoltrTree layout direction. Values: ltr (left-to-right), rtl (right-to-left), ttb (top-to-bottom), btt (bottom-to-top).direction: ttb
spec.levelSpacingnumberno60Spacing between hierarchy levels in pixels. Minimum: 0.levelSpacing: 80
spec.nodeSpacingnumberno20Spacing between sibling nodes in pixels. Minimum: 0.nodeSpacing: 30
spec.edgeStylestringnoorthogonalStyle of connection lines. Values: straight, orthogonal, curved.edgeStyle: curved
spec.showOperatorsbooleannotrueDisplay operator symbols between sibling nodes.showOperators: true
spec.selectedStylestringnoName of a ComponentStyle manifest to apply. Merged over the _system and _default styles. Maps to the selected-style HTML attribute.selectedStyle: corporate-style
spec.i18nNamespacestringnoinheritedI18n namespace inherited by the node components; their own i18nNamespace wins. Resolved from the enclosing artefact, page or card when not set. Maps to the i18n-namespace HTML attribute.i18nNamespace: finance
spec.nodesarraynoNode definitions specifying what component to render at each position.see below
spec:
  edges:
    - from: "roi"
      to: "ros"
      operator: "x"        # * | / | + | - | x | ÷ | none
      label: ""             # optional custom label instead of operator
      style:                # optional custom styling
        color: "#ff0000"
        width: 2
        dasharray: "5,5"
PropertyTypeRequiredDefaultDescriptionSample
edges[].fromstringyesSource node ID.from: "roi"
edges[].tostringyesTarget node ID.to: "ros"
edges[].operatorstringnoOperator symbol. Values: *, /, +, -, x, ÷, none.operator: "x"
edges[].labelstringnoCustom label displayed instead of operator.label: "per unit"
edges[].styleobjectnoCustom edge styling: color (string), width (number), dasharray (string).style: { color: "#ff0000", width: 2, dasharray: "5,5" }
spec:
  nodes:
    - id: roi
      kind: Label           # see the node kind enum in the table below
      spec:
        value: "<strong>ROI</strong><br/>12.5%"
    - id: detail
      kind: Table
      ref: my_table         # reference to standalone document
      spec:
        limit: 5            # optional override
PropertyTypeRequiredDefaultDescriptionSample
nodes[].idstringyesUnique identifier matching from/to values in edges.id: roi
nodes[].kindstringyesComponent type. Values: Label, Table, ChartStructure, ChartTime, ChartScatter, ChartBubble, ChartBullet, Image, LayoutCard.kind: Label
nodes[].refstringnoReference to standalone document by name (not supported for Label).ref: my_table
nodes[].paramsobjectnoParameter values (string map) passed to the referenced document. Only valid together with ref.params: { region: EMEA }
nodes[].optionalbooleannofalseWhen true and the ref is missing, the node is skipped gracefully instead of erroring.optional: true
nodes[].specobjectconditionalInline component spec, or overrides for the referenced document. Required if no ref is provided. For Label see Label, otherwise the spec of the referenced kind.see Node kinds