Date parts & binning
You rarely have a year or a revenue_band column sitting in your data — you have an order_date
timestamp and a raw revenue number. Two declarative Dash-config features derive those groupable
dimensions for you: date parts (year / quarter / month / day / weekday / hour from a temporal
column) and numeric bins (labeled ranges from break points). The engine adds the derived column
before grouping, so it behaves like any other dimension — including sorting chronologically or by
range rather than lexically.
This one is best seen in a running app; the config below derives a Year → Revenue-band roll-up
from a flat frame with no pre-computed columns.
from dash_tensor_grid import TensorGrid, build_grid
payload = build_grid(orders, { "date_parts": {"order_date": ["year", "quarter"]}, # -> order_date_year / order_date_quarter "bins": { "revenue": {"edges": [500, 1000], "labels": ["low", "mid", "high"], "as": "revenue_band"}, }, "rows": ["order_date_year", "revenue_band"], "measures": {"revenue": "sum", "units": "sum"}, "formats": {"revenue": "currency:USD"}, "grand_total": True,})TensorGrid(id="grid", row_data=payload["row_data"], column_defs=payload["column_defs"])// Adapters take pre-derived columns — compute the dimension, then group on it.const withDims = data.map((r) => ({ ...r, orderYear: new Date(r.orderDate).getFullYear(), revenueBand: r.revenue > 1000 ? 'high' : r.revenue > 500 ? 'mid' : 'low',}));
<TensorGrid data={withDims} rows={['orderYear', 'revenueBand']} measures={{ revenue: 'sum', units: 'sum' }} formats={{ revenue: '$0,0' }} grandTotal/>;<script setup lang="ts">const withDims = data.map((r) => ({ ...r, orderYear: new Date(r.orderDate).getFullYear(), revenueBand: r.revenue > 1000 ? 'high' : r.revenue > 500 ? 'mid' : 'low',}));</script>
<template> <TensorGrid :data="withDims" :rows="['orderYear', 'revenueBand']" :measures="{ revenue: 'sum', units: 'sum' }" :formats="{ revenue: '$0,0' }" grand-total /></template>const withDims = data.map((r) => ({ ...r, orderYear: new Date(r.orderDate).getFullYear(), revenueBand: r.revenue > 1000 ? 'high' : r.revenue > 500 ? 'mid' : 'low',}));
mountTensorGrid(el, { data: withDims, rows: ['orderYear', 'revenueBand'], measures: { revenue: 'sum', units: 'sum' }, formats: { revenue: '$0,0' }, grandTotal: true,});- Date parts derive
<col>_<part>from adate/datetime/timecolumn. Parts:year(int),quarter(Q1–Q4),month/day/hour(zero-padded),weekday(ISO1=Mon…7=Sun). Labels are chosen to sort chronologically. - Bins derive
<col>_bin(or a customas) via right-closed buckets —<= e0,e0 - e1, …,> e[-1]. Supplylabels(len(edges) + 1of them) to override the auto labels; a null value bins to null. Buckets are kept in range order, so a sort over the bin dimension is not lexical. - Derivation runs before grouping, so a derived column is usable anywhere a column is — in
rows,columns, a named hierarchy, or a filter. - These are declarative Dash-config keys; the adapters accept the equivalent pre-derived columns (compute them in JS, as above). See the full declarative config schema.