> ## Documentation Index
> Fetch the complete documentation index at: https://learn.nextedy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Display Multi-Level Hierarchies

> Configure the `levels` array in your sheet configuration to display failure modes, causes, effects, mitigations, and other risk analysis hierarchies in a structured tree with automatic cell merging.

export const LastReviewed = ({date}) => {
  if (!date) return null;
  const formatted = new Date(`${date}T00:00:00Z`).toLocaleDateString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
    timeZone: "UTC"
  });
  return <p className="mt-10 text-sm text-gray-400 dark:text-zinc-500 not-prose">
      Last reviewed on {formatted}
    </p>;
};

## Define Levels in Configuration

Add a `levels` array to your sheet configuration. Each entry defines one visual tier of the hierarchy:

```yaml theme={null}
levels:
  - name: System Element
    controlColumn: sysElement
    zoomColumn: sysElement
    showInMenu: true
  - name: Failure Mode
    controlColumn: failureMode
    zoomColumn: failureMode
    showInMenu: true
  - name: Cause
    controlColumn: cause
    zoomColumn: cause
    showInMenu: false
```

| Property        | Type    | Default  | Description                                                                               |
| --------------- | ------- | -------- | ----------------------------------------------------------------------------------------- |
| `name`          | string  | required | Display name shown in the zoom and "New Item" menus (for example, "Item", "Failure Mode") |
| `controlColumn` | string  | required | Column `id` whose values drive grouping and cell merging at this level                    |
| `zoomColumn`    | string  | required | Column `id` used as the target for zoom and drill-down navigation                         |
| `showInMenu`    | boolean | `true`   | Whether this level appears in the context menu for creating new items                     |

## Assign Columns to Levels

Each column in your `columns` array specifies which `level` it belongs to. Columns at the same level merge vertically when their parent control column values match. Note that the column `level` property is **1-indexed**: `level: 1` maps to the first entry in the `levels` array.

```yaml theme={null}
columns:
  - id: sysElement
    header: System Element
    bindings: title
    level: 1
  - id: failureMode
    header: Failure Mode
    bindings: title
    level: 2
    type: itemLink
  - id: cause
    header: Cause
    bindings: title
    level: 3
    type: itemLink
  - id: sev
    header: Severity
    bindings: severity
    level: 2
    type: rating:severity_scale
```

Task columns (those bound to `task.*` fields) do not have a level assigned -- they follow separate merge logic based on the parent risk item.

<Warning title="Each level must use a unique controlColumn">
  Two different levels must not point to the same `controlColumn` value. Duplicate control columns cause values from previous items to auto-populate into new items and trigger incorrect cell merging.
</Warning>

## Understand Merge Behavior

Nextedy RISKSHEET automatically merges cells based on the levels hierarchy:

| Level 1 (System)     | Level 2 (Failure Mode) | RPN |
| -------------------- | ---------------------- | --- |
| **Braking System**   | Fluid leak             | 120 |
| *(merged cell)*      | Loss of braking        | 180 |
| *(merged cell)*      | Pad contamination      | 240 |
| **Unintended brake** | Sensor short circuit   | 360 |
| *(merged cell)*      | ABS software fault     | 280 |

Key merge rules:

* **Level 2 cells** merge within the same level 1 group when their control column values match
* **Empty cells in control columns act as merge boundaries** -- they stop merge propagation between unrelated groups
* **Downstream and task columns** follow separate merge rules based on work item ID grouping

<Tip title="Merge boundary behavior">
  If a level 1 control column cell is empty, level 2 and higher cells in that row will not merge with adjacent rows. This is intentional and maintains clean visual separation between hierarchy groups.
</Tip>

## Display Multi-Level Linked Items

To display items linked across multiple levels, you have two approaches.

### Approach A: Transitive Linking with `upstreamChains`

The `upstreamChains` property automatically builds transitive link chains across levels:

```yaml theme={null}
upstreamChains:
  - FailureMode-causes-Cause
  - SystemElement-has_failure-FailureMode
```

The format is `fromType-linkRole-toType`. This creates automatic transitive links so items connected through intermediate levels appear in the correct hierarchy.

<Warning title="Upstream chains only create links">
  The `upstreamChains` property only creates links -- it never deletes them. Once a transitive link is established, it persists even if the intermediate link is removed.
</Warning>

### Approach B: Server-Side Rendering for Read-Only Display

For read-only display of indirectly linked items, use `serverRender` with a Velocity script:

```yaml theme={null}
- id: indirectReq
  header: Linked Requirement
  serverRender: "$item.fields().get('linkedReqField').render().htmlFor().forFrame()"
  level: 1
```

Columns with `serverRender` are automatically read-only and render on the server side.

## Configure Sort Order for Hierarchies

Define the default sort order to align with your hierarchy using `sortBy`:

```yaml theme={null}
sortBy:
  - sysElement
  - failureMode
  - cause
```

This ensures the grid rows are arranged to match the hierarchy structure, which is essential for proper cell merging.

## Complete FMEA Hierarchy Example

A three-level FMEA configuration with System Element, Failure Mode, and Cause:

```yaml theme={null}
levels:
  - name: System Element
    controlColumn: sysElement
    zoomColumn: sysElement
    showInMenu: true
  - name: Failure Mode
    controlColumn: failureMode
    zoomColumn: failureMode
    showInMenu: true
  - name: Cause
    controlColumn: cause
    zoomColumn: cause
    showInMenu: false
columns:
  - { id: sysElement, header: System Element, bindings: title, level: 1 }
  - { id: failureMode, header: Failure Mode, bindings: title, level: 2, type: itemLink }
  - { id: failureEffect, header: Failure Effect, bindings: description, level: 2 }
  - { id: cause, header: Cause, bindings: title, level: 3, type: itemLink }
  - { id: sev, header: S, bindings: severity, level: 2, type: rating:severity_scale }
  - { id: occ, header: O, bindings: occurrence, level: 3, type: rating:occurrence_scale }
  - { id: det, header: D, bindings: detection, level: 3, type: rating:detection_scale }
  - { id: rpn, header: RPN, formula: commonRpn, level: 3 }
sortBy:
  - sysElement
  - failureMode
  - cause
formulas:
  commonRpn: "function(info){ var value = info.item['occ']*info.item['det']*info.item['sev']; return value?value:null;}"
```

## Troubleshooting

| Problem                    | Cause                                         | Solution                                                                      |
| -------------------------- | --------------------------------------------- | ----------------------------------------------------------------------------- |
| Rows are duplicated        | `controlColumn` ID does not match column `id` | Verify exact string match between `levels[].controlColumn` and `columns[].id` |
| Cells do not merge         | Empty values in control column                | Ensure parent-level control columns always have values                        |
| Zoom navigation fails      | Missing `zoomColumn` on level entry           | Add a `zoomColumn` to every level (it can equal `controlColumn`)              |
| New items get wrong values | Duplicate `controlColumn` across levels       | Correct the levels configuration so each level has its own control column     |

## Verification

After configuring your levels hierarchy, you should now see:

* Level 1 cells merging vertically when consecutive rows share the same system element
* Level 2 cells merging within their parent level 1 group
* The context menu showing "New Item" options for levels where `showInMenu` is `true`
* Zoom navigation jumping to the column referenced by each level's `zoomColumn`
* Rows sorted according to the `sortBy` order, preserving the hierarchy structure

## See Also

* [Add a Basic Column](/risksheet/guides/columns/add-basic-column) -- column definition fundamentals
* [Configure Column Sorting](/risksheet/guides/columns/sorting) -- sort order configuration
* [Configure Upstream Traceability Columns](/risksheet/guides/columns/upstream-traceability) -- upstream link columns
* [Configure Downstream Traceability Columns](/risksheet/guides/columns/downstream-traceability) -- downstream link columns
* [Display Sub-Columns](/risksheet/guides/columns/sub-columns) -- nested column display within multi-item links

<LastReviewed date="2026-06-18" />
