Show values as % or running total
Show a number column as a share of the total, a share of its group or a running total, from the header menu or code; the values themselves, sorting, filters and exports stay as they are.
Live demoValues as % or running total
Sales by region as shares of the group and running totals.
Code for this demo
import { createGrid, type ColumnDef, type Row } from '@freegridjs/core';
import { makeRows } from '../data';
import { button, separator, text, tr, type DemoContext } from '../ui';
export default function mount(ctx: DemoContext) {
const h = (en: string, ko: string) => tr(ctx.lang, { en, ko });
const grid = createGrid(ctx.host, {
columns: [
{ field: 'country', header: h('Country', '국가'), width: 160 },
{ field: 'name', header: h('Name', '이름'), width: 170 },
{ field: 'q1', header: h('Q1 sales', '1분기 매출'), type: 'number', format: '#,##0', aggFunc: 'sum', width: 150 },
],
data: makeRows(300), locale: ctx.lang, groupBy: ['country'], headerContextMenu: true,
summary: { rows: [{ label: h('Total', '합계'), columns: { q1: 'sum' } }] },
});
grid.expandAll();
const mode = (label: string, m: 'percentOfTotal' | 'percentOfParent' | 'runningTotal' | null) => button(ctx, label, () => { grid.setColumnValuesAs('q1', m); ctx.log(`valuesAs = ${m}`); });
mode(h('Values', '값 그대로'), null);
mode(h('% of total', '합계 대비 %'), 'percentOfTotal');
mode(h('% of group', '그룹 대비 %'), 'percentOfParent');
mode(h('Running total', '누계'), 'runningTotal');
text(ctx, h('Group rows show their share; the Total row keeps the real sum. Right-click the Q1 header for the same choices.',
'그룹 행은 비율을 보이고, 합계 행은 실제 합계를 유지합니다. 1분기 헤더를 우클릭해도 같은 선택이 있습니다.'));
return grid;
}A number column can show each number as a share or as a running total instead of the value — "what part of the total is this region?", "how much so far?" — without adding a column. Only the display changes: sorting, filters, edits, the summary row and exports use the real values.
Modes
| valuesAs | Data rows | Group rows |
|---|---|---|
| 'percentOfTotal' | value ÷ the column total (rows shown) | group sum ÷ the column total |
| 'percentOfParent' | value ÷ its group sum (the total when not grouped) | group sum ÷ the parent group sum |
| 'runningTotal' | the sum so far in the shown order, starting again in each group | the group value |
Setting it
const columns = [
{ field: 'region' },
{ field: 'sales', type: 'number', aggFunc: 'sum', valuesAs: 'percentOfParent' }, // from the start
];
const grid = createGrid(el, { columns, data, groupBy: ['region'], headerContextMenu: true });
grid.setColumnValuesAs('sales', 'runningTotal'); // change it
grid.setColumnValuesAs('sales', null); // back to the valuesWith headerContextMenu, a right-click on a number column header has Show values as with the four choices (the current one checked).
Details
- Shares show as percents with one decimal, in the grid language (25%, 33.3%). Running totals use the column format.
- The total is over the rows that pass the filters, so filtering changes the shares.
- Cells shown this way are drawn in the accent colour so people can tell.
- Not for a datasource (the grid does not have every row).