FreeGridv1.6.0한국어

Summary rows

Summary rows show totals, averages and other aggregates. Put them at the top or bottom; keep them pinned outside the scroll area, or let them scroll with…

Live demoSummary rows

Totals and averages at the top or bottom, pinned or scrolling.

Code for this demo
import { createGrid, type SummaryOptions } from '@freegridjs/core';
import { demoColumns, makeRows } from '../data';
import { search, select, tr, type DemoContext } from '../ui';

export default function mount(ctx: DemoContext) {
  const { lang } = ctx;
  const quarters = { q1: 'sum', q2: 'sum', q3: 'sum', q4: 'sum', total: 'sum' } as const;
  let summary: SummaryOptions = {
    position: 'bottom',
    pinned: true,
    scope: 'filtered',
    rows: [
      { label: tr(lang, { en: 'Total', ko: '합계' }), columns: { ...quarters, id: 'count' } },
      {
        label: tr(lang, { en: 'Average', ko: '평균' }),
        columns: { q1: 'avg', q2: 'avg', q3: 'avg', q4: 'avg', total: 'avg', growth: { agg: 'avg', format: '0.0%' } },
      },
      {
        label: tr(lang, { en: 'Range', ko: '범위' }),
        columns: {
          total: { agg: 'max', prefix: tr(lang, { en: 'max', ko: '최대' }) },
          country: values => tr(lang, { en: `${new Set(values).size} countries`, ko: `${new Set(values).size}개 국가` }),
        },
      },
    ],
  };
  const grid = createGrid(ctx.host, { columns: demoColumns(lang), data: makeRows(10_000), rowSelection: 'multiple', locale: lang, summary });

  const update = (patch: Partial<SummaryOptions>) => {
    summary = { ...summary, ...patch };
    grid.setSummary(summary);
    ctx.log(`setSummary → position: ${summary.position}, pinned: ${summary.pinned}, scope: ${summary.scope}`);
  };
  select(ctx, tr(lang, { en: 'Position', ko: '위치' }), [['bottom', tr(lang, { en: 'Bottom', ko: '하단' })], ['top', tr(lang, { en: 'Top', ko: '상단' })]], 'bottom',
    v => update({ position: v }));
  select(ctx, tr(lang, { en: 'Mode', ko: '방식' }), [['pinned', tr(lang, { en: 'Pinned', ko: '고정' })], ['scroll', tr(lang, { en: 'Scrolls with rows', ko: '스크롤과 함께' })]], 'pinned',
    v => update({ pinned: v === 'pinned' }));
  select(ctx, tr(lang, { en: 'Rows', ko: '집계 대상' }), [
    ['filtered', tr(lang, { en: 'Filtered rows', ko: '필터된 행' })],
    ['all', tr(lang, { en: 'All rows', ko: '전체 행' })],
    ['selected', tr(lang, { en: 'Selected rows', ko: '선택한 행' })],
  ], 'filtered', v => update({ scope: v }));
  search(ctx, tr(lang, { en: 'Filter, e.g. "japan"', ko: '필터 예: "japan"' }), q => grid.setQuickFilter(q));
  return grid;
}

Summary rows show totals, averages and other aggregates. Put them at the top or bottom; keep them pinned outside the scroll area, or let them scroll with the data. They recalculate when data, filters or (with scope: 'selected') the selection change, and use each column's format unless a cell sets its own.

createGrid(el, {
  columns,
  data,
  summary: {
    position: 'bottom',   // 'top' | 'bottom'
    pinned: true,         // true: fixed; false: scrolls with the rows
    scope: 'filtered',    // 'filtered' | 'all' | 'selected'
    rows: [
      { label: 'Total', columns: { qty: 'sum', amount: 'sum', id: 'count' } },
      { label: 'Average', columns: { amount: { agg: 'avg', format: '#,##0.0' } } },
      { columns: {
        amount: { agg: 'max', prefix: 'max' },
        country: values => `${new Set(values).size} countries`, // custom
      } },
    ],
  },
});

grid.setSummary({ position: 'top', rows: [...] }); // change at runtime
grid.setSummary(null);                              // remove
grid.getSummaryValues();                            // [{ qty: 1234, amount: 99000, id: 50 }, …]
  • sum, avg, min, max use numeric values and skip blanks; min/max also compare dates.
  • count is the number of rows in scope.
  • A function receives the column's values and the rows; return a number to have it formatted, or a string to show as is.
  • The row label appears in the first visible column without an aggregate in that row.