import { type HeatmapAggregate } from './heatmap-scale'; /** One row of the heatmap. */ export interface HeatmapRow { /** Stable, opaque id. Emitted in DOM hooks, so never a name. */ id: string; /** Visible label. Masked in privacy mode. */ label: string; /** * Group id. Rows that share it are grouped when `groupRows` is on. Without * a matching entry in `groups` the id doubles as the visible label, so it * may be a name: privacy mode masks it, and DOM hooks and agent state * carry an index-based id (`group-1`, `group-2` in order of first * appearance), never this one. */ group?: string; } /** One column of the heatmap. */ export interface HeatmapColumn { /** * Stable, opaque id. Emitted in DOM hooks (`data-heatmap-cell-id`) and in * agent state, so never a name. */ id: string | number; /** * Visible label. Masked in privacy mode only with `privacyScope="all"`: * columns are usually hours or days, which privacy mode keeps. */ label: string; } /** A group's visible label, keyed by the id rows carry in `group`. */ export interface HeatmapGroup { /** Stable, opaque id. Emitted in DOM hooks and agent state, so never a name. */ id: string; /** * Visible label. Masked in privacy mode only with `privacyScope="all"`: * groups are usually practices or sites, which privacy mode keeps. */ label: string; } /** * The id each group shows to DOM hooks and agents. A group listed in * `groups` keeps its own (opaque) id. One that is not has only its id for a * label, which may be a name, so it gets `group-` by order of first * appearance instead. */ export declare function publicGroupIds(rows: readonly HeatmapRow[], groups: readonly HeatmapGroup[] | undefined): Map; /** The data behind one cell. */ export interface HeatmapCellData { /** * The value to colour. `null` means no data, or, with a `count` above 0 but * below `minCount`, a value withheld as too few to show. */ value: number | null; /** * How many records the value rests on (the denominator of a rate). Weights * the mean totals and drives `minCount`. */ count?: number; /** * Text shown and announced instead of the formatted value, for example * "Closed". Replaced by the formatted value in privacy mode. */ label?: string; } /** What `getCell` or the `cells` matrix may hold for a cell. */ export type HeatmapCellInput = HeatmapCellData | number | null | undefined; /** How a cell renders: a coloured value, no data, or too few records. */ export type HeatmapCellStatus = 'value' | 'empty' | 'low-sample'; /** Addresses one cell. */ export interface HeatmapCellKey { rowId: string; columnId: string | number; } /** Everything known about one cell, as passed to callbacks. */ export interface HeatmapCellInfo extends HeatmapCellKey { row: HeatmapRow; column: HeatmapColumn; /** Index into the `rows` prop. */ rowIndex: number; /** Index into the `columns` prop. */ columnIndex: number; value: number | null; count?: number; label?: string; status: HeatmapCellStatus; /** * Colour step, 0 to 9, when `status` is `'value'`; otherwise null. On a * diverging scale a value exactly on the midpoint keeps step 5 but is * painted in the neutral `--heatmap-midpoint` colour: compare `value` * with the midpoint to tell it from the palest step above. */ step: number | null; } /** A cell after normalisation. */ export interface ModelCell { value: number | null; count?: number; label?: string; status: HeatmapCellStatus; /** A total withheld to protect hidden cells. Its status stays * `low-sample`, but it may rest on many records, so it is worded apart * from a cell that is too few to show. */ withheld?: true; } /** How rows are ordered (within their group when grouped). */ export type HeatmapSortRows = 'none' | 'label' | 'total-asc' | 'total-desc'; /** Whether a cell or total falls below the sample threshold. */ export declare function isLowSample(count: number | undefined, minCount: number | undefined): boolean; /** Normalises one cell input. */ export declare function toModelCell(input: HeatmapCellInput, minCount: number | undefined): ModelCell; /** Builds the `[row][column]` matrix in the order of the props. */ export declare function buildMatrix(rows: readonly HeatmapRow[], columns: readonly HeatmapColumn[], getCell: ((row: HeatmapRow, column: HeatmapColumn, rowIndex: number, columnIndex: number) => HeatmapCellInput) | undefined, cells: readonly (readonly HeatmapCellInput[])[] | undefined, minCount: number | undefined): ModelCell[][]; /** The values that render a colour, for the scale's domain. */ export declare function shownValues(matrix: readonly ModelCell[][]): number[]; /** Whether at least one cell carries data (a value or a low sample). */ export declare function hasAnyData(matrix: readonly ModelCell[][]): boolean; /** * Which total `getTotal` is asked for, with the rows, columns and group it * covers. `method` is how the kit combines the cells for it: the * `rowTotals` method for a row, a group and the grand total, the * `columnTotals` method for a column, and the column method (else the row * method) for a group header cell. */ export type HeatmapTotalScope = { /** A row's total, in the totals column. */ kind: 'row'; method: HeatmapAggregate; row: HeatmapRow; rowId: string; /** Index into the `rows` prop. */ rowIndex: number; } | { /** A column's total, in the totals row. */ kind: 'column'; method: HeatmapAggregate; column: HeatmapColumn; columnId: string | number; /** Index into the `columns` prop. */ columnIndex: number; } | { /** A group's total, in the totals column of its header row. */ kind: 'group'; method: HeatmapAggregate; /** The id the group's rows carry in `group`. */ groupId: string; /** The group's entry in `groups`, when it has one. */ group?: HeatmapGroup; /** The group's rows, in the order of the `rows` prop. */ rows: readonly HeatmapRow[]; rowIndexes: readonly number[]; } | { /** One column's total within a group, in the group's header row. */ kind: 'group-column'; method: HeatmapAggregate; groupId: string; group?: HeatmapGroup; rows: readonly HeatmapRow[]; rowIndexes: readonly number[]; column: HeatmapColumn; columnId: string | number; columnIndex: number; } | { /** The grand total of every cell, in the corner. */ kind: 'grand'; method: HeatmapAggregate; }; /** Returns a total, or undefined to let the kit work it out from the cells. */ export type HeatmapGetTotal = (scope: HeatmapTotalScope) => HeatmapCellInput | undefined; /** * Every margin, ready to render. A withheld total is `{ value: null, * status: 'low-sample', withheld: true }`: no value and no count, so * nothing that reads it (the grid, the table view, a sort by total) can * pass one on. */ export interface HeatmapTotals { /** Per row index (props order), by the row method. */ rows: ModelCell[]; /** Per column index, by the column method. */ columns: ModelCell[]; /** Every cell, by the row method (it sits in the row-totals column). */ grand: ModelCell; /** Per group id, whenever rows carry a group: one per column, by the * group column method. */ groupColumns: Map; /** Per group id, whenever rows carry a group: every cell in the group, * by the row method (it sits in the row-totals column). */ groups: Map; } /** Which totals the viewer sees: drawn, or, for rows, ordering the rows. */ export interface ShownTotals { rows: boolean; columns: boolean; grand: boolean; groups: boolean; groupColumns: boolean; } export interface TotalsOptions { rowMethod: HeatmapAggregate; columnMethod: HeatmapAggregate; groupColumnMethod: HeatmapAggregate; groups?: readonly HeatmapGroup[]; minCount?: number; getTotal?: HeatmapGetTotal; /** `rate` values are proportions of their count. Default `number`. */ valueType?: 'number' | 'rate'; /** Which totals the viewer sees. Default: every one. */ shown?: ShownTotals; } /** * Works out every margin, then withholds whatever would let someone work * out a hidden cell (status `low-sample`), alone or with any combination * of the other totals shown, the shown cells and the known bounds. A total * in the row-totals column (a row's, a group's, the grand total) uses the * row method, so the column means one thing; a group's per-column totals * use the group column method. Low-sample cells count: their data is real, * only too thin to show on its own. `getTotal` may supply any total * instead; the same rule applies. * * Primary: a total under minCount on its own count, one the kit would work * out over a value it never had, and one whose hidden cells hold fewer * than minCount records. Secondary: the disclosure audit in * heatmap-disclosure.ts, over every total the viewer sees. */ export declare function computeTotals(matrix: readonly ModelCell[][], rows: readonly HeatmapRow[], columns: readonly HeatmapColumn[], options: TotalsOptions): HeatmapTotals; /** A row the grid body renders. */ export type BodyRow = { kind: 'group'; /** Navigation key, unique among body rows. */ key: string; groupId: string; collapsed: boolean; /** Row indexes (props order) in display order. */ rowIndexes: number[]; } | { kind: 'data'; key: string; rowIndex: number; groupId?: string; }; export declare const dataRowKey: (rowId: string) => string; export declare const groupRowKey: (groupId: string) => string; export declare const FOOTER_ROW_KEY = "f"; /** Orders row indexes. Ties keep the props order (a stable sort). */ export declare function sortRowIndexes(indexes: readonly number[], rows: readonly HeatmapRow[], totals: readonly ModelCell[], sort: HeatmapSortRows, collator: Intl.Collator): number[]; /** Builds the body: group headers (when grouping) and data rows. */ export declare function buildBodyRows(rows: readonly HeatmapRow[], sortedIndexes: readonly number[], groupRows: boolean, collapsed: ReadonlySet): BodyRow[]; //# sourceMappingURL=heatmap-model.d.ts.map