Pivot context (percent-of)
In a cross-tab you usually want each cell’s share, not just its value. Turn on context and the
engine injects three total dicts into every calculated measure — _col (this column’s total across
all rows), _row (this row’s total across all columns), and _grand (the whole-frame total) — so a
measure can divide by any of them. The totals are precomputed once over the source frame and the
ratio is evaluated per cell in the engine; the frontend does zero math.
The demo below reads share visually as a heatmap (each cell coloured by revenue); the code adds an explicit numeric “% of column” measure.
from dash_tensor_grid import TensorGrid, build_grid
# `context: True` injects _grand / _col / _row totals into each calculated measure.# Subscripting a context dict needs a {python_code} measure, so pass allow_code=True.payload = build_grid(sales, { "rows": ["region"], "columns": ["category"], "measures": {"revenue": "sum"}, "calculated": { # each region's share of the COLUMN total (this category across all regions) "pct_col": {"python_code": "lambda m: m['revenue'] / (m['_col']['revenue'] or 1)"}, }, "context": True, "formats": {"revenue": "currency:USD", "pct_col": "percentage:1"}, "headers": {"pct_col": "% of Col"},}, allow_code=True)
TensorGrid(id="grid", row_data=payload["row_data"], column_defs=payload["column_defs"])import { pivotGrid } from '@tensorgrid/core';
// The percent-of `context` path lives in the shared engine core that every adapter wraps.// `context` injects _grand / _col / _row totals; the ratio is computed per cell in the engine.const { row_data, column_defs } = pivotGrid( data, ['region'], ['category'], { revenue: 'sum' }, { context: true, calculated: { pctCol: (m) => m.revenue / (m._col.revenue || 1) }, formats: { revenue: '$0,0', pctCol: '0.0%' }, },);// Feed row_data / column_defs to <TensorPivot> (or your own renderer).<script setup lang="ts">import { pivotGrid } from '@tensorgrid/core';
// Same shared-core call. `context` exposes _grand / _col / _row to each calculated measure.const { row_data, column_defs } = pivotGrid( props.data, ['region'], ['category'], { revenue: 'sum' }, { context: true, calculated: { pctCol: (m) => m.revenue / (m._col.revenue || 1) }, formats: { revenue: '$0,0', pctCol: '0.0%' }, },);</script>import { pivotGrid, renderPivotHtml } from '@tensorgrid/core';
const pivot = pivotGrid(data, ['region'], ['category'], { revenue: 'sum' }, { context: true, calculated: { pctCol: (m) => m.revenue / (m._col.revenue || 1) }, formats: { revenue: '$0,0', pctCol: '0.0%' },});el.innerHTML = renderPivotHtml(pivot, ['region'], { groupHeader: 'Region' });- Which denominator?
_colgives percent-of-column (share within a category),_rowgives percent-of-row (a region’s mix across categories), and_grandgives percent-of-grand-total. Each is a{ measure: total }dict, som['_col']['revenue']is the base you divide by. - The engine stores a fraction (e.g.
0.42); format it withpercentage:1(Dash DSL) or'0.0%'(adapter numeral pattern) so it renders as42.0%. - Why
allow_codein Dash? A share measure must subscript the injected context dict, which the safe DSL / SQL / JS calculated forms cannot do — so it is a trusted{python_code}callable. Enableallow_codeonly for configs you author. contextis a data-layer feature of the shared engine — see thepivotGridcore reference. Start from a plain pivot and pair the share measure with a heatmap for a visual read.