> ## 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.

# Calculated Columns

> Calculated columns derive their values from JavaScript formula expressions defined in the sheet configuration.

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>;
};

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/yWl5nA2D0IzEnZC1/risksheet/diagrams/reference/columns/calculated-columns/diagram-1.svg?fit=max&auto=format&n=yWl5nA2D0IzEnZC1&q=85&s=50f3320e171cb1bcafd7c3ec61e4c2eb" alt="diagram" style={{ maxWidth: "520px", width: "100%" }} width="520" height="320" data-path="risksheet/diagrams/reference/columns/calculated-columns/diagram-1.svg" />
</Frame>

## Column Properties

Calculated columns use the standard column properties plus the `formula` property that references a named formula definition.

| Property         | Type      | Description                                                                                                         |
| ---------------- | --------- | ------------------------------------------------------------------------------------------------------------------- |
| `id`             | `string`  | Unique identifier for the column. Used as the data binding name.                                                    |
| `header`         | `string`  | Display text shown in the column header                                                                             |
| `formula`        | `string`  | Name of a formula defined in the top-level `formulas` object. When set, the column becomes read-only automatically. |
| `width`          | `number`  | Column width in pixels                                                                                              |
| `minWidth`       | `number`  | Minimum width in pixels the column can be resized to                                                                |
| `readOnly`       | `boolean` | Automatically set to `true` when `formula` is specified. Cannot be overridden to `false` for formula columns.       |
| `type`           | `string`  | Data type for the column. For calculated columns producing numeric results, typically inferred automatically.       |
| `level`          | `number`  | Hierarchical level at which this column appears (1 = top level, 2 = second level). Not set for task columns.        |
| `headerGroup`    | `string`  | Name of the header group this column belongs to for multi-level headers                                             |
| `collapseTo`     | `boolean` | When `true`, this column remains visible when its header group is collapsed.                                        |
| `cellCss`        | `string`  | CSS class name(s) to apply to cells in this column                                                                  |
| `headerGroupCss` | `string`  | CSS class name(s) to apply to the header group row                                                                  |
| `filterable`     | `boolean` | Controls whether users can filter the grid by values in this column                                                 |
| `format`         | `string`  | Display format string for the column data (e.g., number format)                                                     |
| `cellRenderer`   | `string`  | Name of a custom cell renderer function for this column                                                             |

<Warning title="Automatic Read-Only">
  When a column has a `formula` property set, the column is **automatically marked as read-only**. This is enforced by the configuration manager and cannot be overridden. Users see computed values but cannot edit cells in formula columns.
</Warning>

<Note title="Text wrapping and HTML rendering">
  Cell text wrapping is controlled via CSS rules in the top-level `styles` section, not by column-level boolean properties. HTML rendering in cells is handled by `serverRender` (Velocity templates) or by the column type system, not by a boolean toggle on the column.
</Note>

## Formula Definitions

Formulas are defined in the top-level `formulas` object of the sheet configuration. Each formula is a named JavaScript function that receives an `info` context object and returns the computed value.

| Property   | Type     | Description                                                                                                                                                              |
| ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `formulas` | `object` | Collection of named JavaScript functions for calculating derived values in cells. Each key is a formula name, and the value is the JavaScript function body as a string. |

### Formula Function Signature

Each formula function receives an `info` object:

| Parameter    | Type     | Description                                                                                            |
| ------------ | -------- | ------------------------------------------------------------------------------------------------------ |
| `info.item`  | `object` | The complete data item (work item) for the current row. Access any field via `info.item['fieldId']`.   |
| `info.value` | `any`    | The current value of the cell (typically `null` or `undefined` for formula columns before computation) |

The function must return the computed value. Return `null` to display an empty cell.

### RPN Formula Examples

The two most common formulas in FMEA risk analysis are the initial RPN and the revised (post-mitigation) RPN:

**Initial RPN** (`commonRpn`):

```yaml theme={null}
formulas:
  commonRpn: "function(info){ var value = info.item['occ']*info.item['det']*info.item['sev']; return value?value:null;}"
```

| Input Field        | Description       | Typical Range |
| ------------------ | ----------------- | ------------- |
| `info.item['occ']` | Occurrence rating | 1-10          |
| `info.item['det']` | Detection rating  | 1-10          |
| `info.item['sev']` | Severity rating   | 1-10          |

**Revised RPN** (`commonRpnNew`):

```yaml theme={null}
formulas:
  commonRpnNew: "function(info){ var value = info.item['occNew']*info.item['detNew']*info.item['sevNew']; return value?value:null; }"
```

| Input Field           | Description                                   | Typical Range |
| --------------------- | --------------------------------------------- | ------------- |
| `info.item['occNew']` | Revised occurrence rating (after mitigations) | 1-10          |
| `info.item['detNew']` | Revised detection rating (after mitigations)  | 1-10          |
| `info.item['sevNew']` | Revised severity rating (after mitigations)   | 1-10          |

<Tip title="Null Handling">
  Both RPN formulas return `null` when the computed value is `0` (falsy). This prevents displaying `0` in the grid when input fields have not been filled in yet. The `return value?value:null` pattern is the standard approach for null-safe formula results.
</Tip>

### Cross-Type Severity References

Risk calculations can reference properties from different work item types in the hierarchy. For example, you can configure a formula to use the severity from the Risk item itself rather than from a linked Accident or Harm work item. The formula accesses the field through `info.item['fieldId']` regardless of which work item type provides the value -- the data binding resolves the correct source.

<Info title="Verify in application">
  The exact behavior of cross-type field references depends on your data type configuration and level hierarchy. The severity source can be changed by modifying which field ID the formula references. Consult your `dataTypes` configuration to understand which fields are available on each work item type.
</Info>

## Connecting Formulas to Columns

To create a calculated column, define the formula in `formulas` and reference it by name in the column's `formula` property:

```yaml theme={null}
formulas:
  commonRpn: "function(info){ var value = info.item['occ']*info.item['det']*info.item['sev']; return value?value:null;}"
columns:
  - id: rpn
    header: RPN
    formula: commonRpn
    width: 80
```

The column `id` serves as the data binding. The `formula` property value must exactly match a key in the `formulas` object.

## Combining Formulas with Cell Decorators

Calculated columns are frequently paired with cell decorators to apply conditional formatting based on the computed value. The cell decorator function references the formula column's output value.

```yaml theme={null}
formulas:
  commonRpn: "function(info){ var value = info.item['occ']*info.item['det']*info.item['sev']; return value?value:null;}"
cellDecorators:
  rpn: "function(info){ var val = info.value; $(info.cell).toggleClass('boldCol', true); $(info.cell).toggleClass('rpn1', val>0 && val <= 150); $(info.cell).toggleClass('rpn2', val > 150 && val <= 250); $(info.cell).toggleClass('rpn3', val > 250);}"
styles:
  ".boldCol": "{font-weight:600;}"
  ".rpn1": "{background-color: #eaf5e9 !important;color: #1d5f20 !important;}"
  ".rpn2": "{background-color: #fff3d2 !important; color: #735602 !important;}"
  ".rpn3": "{background-color: #f8eae7 !important;color: #ab1c00 !important;}"
```

The decorator applies CSS classes based on RPN risk thresholds. Thresholds shown here are illustrative -- real deployments configure them to match each organization's risk acceptance policy:

| RPN Range | CSS Class | Visual Effect                                               |
| --------- | --------- | ----------------------------------------------------------- |
| 1 -- 150  | `rpn1`    | Green background (`#eaf5e9`), dark green text (`#1d5f20`)   |
| 151–250   | `rpn2`    | Yellow background (`#fff3d2`), dark yellow text (`#735602`) |
| > 250     | `rpn3`    | Red background (`#f8eae7`), dark red text (`#ab1c00`)       |

See [Cell Decorators](/risksheet/reference/styling/cell-decorators) and [Item Colors](/risksheet/reference/styling/item-colors) for complete decorator configuration reference.

## Data Persistence and Export Behavior

Calculated column values are computed **client-side in the browser** by the JavaScript formula. The grid renders the result, but the value does not automatically exist in Polarion until it is persisted as a work item field. Because all Nextedy RISKSHEET data lives in Polarion work items -- Risksheet does not maintain a separate data store -- persistence to Polarion is required for the value to participate in audit trails, queries, exports, and downstream traceability.

### Client-Side Computation, Server-Side Audit

| Concern                         | Where it happens                                    |
| ------------------------------- | --------------------------------------------------- |
| Formula evaluation              | Browser, on every render                            |
| Display in the grid             | Browser, real time                                  |
| Audit trail, history, revisions | Polarion (only after the value is saved to a field) |
| Excel/CSV export of the value   | Polarion (reads the stored field value)             |

For regulated workflows (ISO 26262, ISO 14971, IEC 61508, ISO/SAE 21434), the calculated value MUST be persisted to a Polarion custom field so that it can be reviewed, signed off, baselined, and exported.

### Persisting Calculated Values

Calculated column values are written to the underlying Polarion field when:

* A user edits any field in the row within Risksheet, which triggers a save that includes formula results
* A **bulk recalculation** is performed across the document -- this evaluates all formula columns and writes the results to their bound Polarion fields in a single operation. Use this after importing rows from outside Risksheet (CSV import, SOAP API, copy from template) or after changing a formula definition so that all stored values reflect the new logic.
* The data sync feature (introduced in version 24.5.1) explicitly stores formula column values to Polarion

<Warning title="Empty Formula Values in Exports">
  If you import work items into Polarion (e.g., via CSV import or API) without editing them in Risksheet, the calculated column values will appear **empty in Excel exports**. This occurs because the formula values exist only in the browser during the Risksheet session but have not been written to the underlying Polarion fields. Run bulk recalculation to populate the stored values before export.
</Warning>

### Comparing Revisions

Because calculated values are persisted as standard Polarion fields, you can use the **compare** feature to inspect how a formula's stored result changed between two revisions of the document. This is useful for change-control reviews -- you can see, for example, that an RPN went from 240 (yellow) at the previous baseline to 96 (green) after a mitigation was added, with both numbers backed by the corresponding stored field values.

### Export Behavior by Format

| Export Format         | Formula Value Source              | Notes                                                                           |
| --------------------- | --------------------------------- | ------------------------------------------------------------------------------- |
| Risksheet grid (live) | Computed client-side in real time | Always displays current calculated values                                       |
| PDF export            | Computed during export            | Values calculated at export time; matches live grid                             |
| Excel export          | Read from Polarion fields         | Values are **empty** for items not edited in Risksheet or not bulk-recalculated |

### Row Header Styling with Formula Values

The row header renderer can also reference formula column values. For example, the `rowHeaderRpnNew` renderer accesses `info.item['rpnNew']` to color row headers based on the revised RPN:

```yaml theme={null}
headers:
  rowHeader:
    renderer: rowHeaderRpnNew
cellDecorators:
  rowHeaderRpnNew: "function(info){ var val = info.item['rpnNew']; $(info.cell).toggleClass('rpn1', val>0 && val <= 150); $(info.cell).toggleClass('rpn2', val>0 && val > 150 && val <= 250); $(info.cell).toggleClass('rpn3', val>0 && val > 250);}"
```

<Note title="Enum and Rating Values in Row Headers">
  When using enum or rating field values in row header styling, access the value using `info.item['fieldId']` and compare against the option **IDs** (not display names). Ratings are defined as Polarion enumerations (Administration -> Enumerations) and bound to risk work item fields; their option IDs are typically integers for severity/occurrence/detection scales.
</Note>

## Limitations and Edge Cases

### Dependent Enums Not Driven by Formulas

Dependent enum dropdowns (where child enum options filter based on a parent enum selection) are a column-level feature (v25.3.1+) for `enum`/`multiEnum` columns. They cannot be driven by a formula -- a formula column produces a single computed value, not a filtered option set.

### Ratings Use Integer IDs

Rating scales are defined as Polarion enumerations and bound to risk work item fields. Their option IDs are typically integers. When writing formulas that reference rating values, `info.item['fieldId']` returns the integer option ID of the selected rating, which can be used directly in arithmetic (e.g., multiplying severity, occurrence, and detection ratings to compute RPN).

### Formula-Calculated Dropdowns Not Available

Creating a dropdown column whose options are determined by a formula is not currently supported. Dropdown columns must reference Polarion enumerations via `type: enum:<enumId>`, `type: multiEnum:<enumId>`, or `type: rating:<enumId>`. Formula columns produce computed scalar values only -- they cannot generate dynamic option lists.

### Drag and Drop Not Supported

Inserting existing work items into a Risksheet via drag and drop is not supported. Work items must be created through the grid's "New" menu or linked via item link columns. This is relevant for calculated columns because items created outside Risksheet may not have formula values persisted until they are edited within the grid or bulk-recalculated.

## Configuration Interaction Summary

| Interacting Property         | Effect on Calculated Columns                                                         |
| ---------------------------- | ------------------------------------------------------------------------------------ |
| `formula` on column          | Column becomes read-only automatically                                               |
| `serverRender` on column     | Column uses server-side rendering instead; not compatible with client-side `formula` |
| `cellDecorators`             | Apply conditional formatting based on the formula's computed value                   |
| `styles`                     | Define CSS classes referenced by cell decorators (including text-wrap rules)         |
| `headers.rowHeader.renderer` | Row header can reference formula column values via `info.item['fieldId']`            |
| `views`                      | Calculated columns can be shown/hidden via saved view presets                        |
| `filterable`                 | Users can filter the grid by computed values in formula columns                      |
| `collapseTo`                 | When `true`, keeps the calculated column visible when its header group is collapsed  |

## Complete Example

A complete FMEA risk analysis configuration with initial and revised RPN calculated columns, conditional formatting, and row header coloring:

```yaml theme={null}
formulas:
  commonRpn: "function(info){ var value = info.item['occ']*info.item['det']*info.item['sev']; return value?value:null;}"
  commonRpnNew: "function(info){ var value = info.item['occNew']*info.item['detNew']*info.item['sevNew']; return value?value:null; }"
columns:
  - id: sev
    header: Severity
    type: rating:severity
    width: 100
  - id: occ
    header: Occurrence
    type: rating:occurrence
    width: 100
  - id: det
    header: Detection
    type: rating:detection
    width: 100
  - id: rpn
    header: Initial RPN
    formula: commonRpn
    width: 80
  - id: sevNew
    header: Severity (New)
    type: rating:severity
    width: 100
  - id: occNew
    header: Occurrence (New)
    type: rating:occurrence
    width: 100
  - id: detNew
    header: Detection (New)
    type: rating:detection
    width: 100
  - id: rpnNew
    header: Revised RPN
    formula: commonRpnNew
    width: 80
cellDecorators:
  rpn: "function(info){ var val = info.value; $(info.cell).toggleClass('boldCol', true); $(info.cell).toggleClass('rpn1', val>0 && val <= 150); $(info.cell).toggleClass('rpn2', val > 150 && val <= 250); $(info.cell).toggleClass('rpn3', val > 250);}"
  rowHeaderRpnNew: "function(info){ var val = info.item['rpnNew']; $(info.cell).toggleClass('rpn1', val>0 && val <= 150); $(info.cell).toggleClass('rpn2', val>0 && val > 150 && val <= 250); $(info.cell).toggleClass('rpn3', val>0 && val > 250);}"
styles:
  ".boldCol": "{font-weight:600;}"
  ".rpn1": "{background-color: #eaf5e9 !important;color: #1d5f20 !important;}"
  ".rpn2": "{background-color: #fff3d2 !important; color: #735602 !important;}"
  ".rpn3": "{background-color: #f8eae7 !important;color: #ab1c00 !important;}"
headers:
  rowHeader:
    renderer: rowHeaderRpnNew
  columnHeader:
    height: 32
```

## Related Pages

* [Formula Syntax](/risksheet/reference/formulas/formula-syntax) -- detailed formula language reference
* [Formula Functions](/risksheet/reference/formulas/formula-functions) -- available built-in functions
* [Formula Examples](/risksheet/reference/formulas/formula-examples) -- additional formula patterns and use cases
* [Cell Decorators](/risksheet/reference/styling/cell-decorators) -- conditional formatting based on formula values
* [Item Colors](/risksheet/reference/styling/item-colors) -- RPN color scheme configuration
* [Column Type Reference](/risksheet/reference/columns/column-types) -- all column types and their properties
* [Configuration Properties Index](/risksheet/reference/configuration/properties-index) -- full property reference

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