Grouping types
`GanttGroupBy`, `GanttRow`, `GanttRowGroup`
GanttGroupBy is the type of the groupBy prop. GanttRow and GanttRowGroup describe the row
model the chart builds from your tasks — one entry per rendered row, group header rows included.
All three come from the package root.
import type { GanttGroupBy, GanttRow, GanttRowGroup } from '@jaeungkim/gantt-chart';For what grouping does and how lanes pack, see Grouping and swimlanes.
GanttGroupBy
/**
* How rows are grouped into swimlanes
*
* A string reads that field off the task; a function returns the group value
* itself, which doubles as the header label. Anything empty, null or undefined
* lands in the "Ungrouped" bucket.
*/
export type GanttGroupBy =
| string
| ((task: TaskTransformed) => string | null | undefined);| Form | Meaning |
|---|---|
string | A field name, read off the task with an unchecked index. Any field of TaskTransformed works, not only the ones Task declares. A name no task carries yields undefined for every task, so every task lands in one Ungrouped group. |
(task: TaskTransformed) => string | null | undefined | Returns the group value. The value is also the header label. |
Non-string return values are passed through String(value). Only null, undefined and ""
produce the Ungrouped bucket — 0 becomes the group "0" and false becomes the group
"false".
The accessor receives a TaskTransformed, not the Task you passed in, so it also sees depth,
order, isSummary, barLeft, barWidth, and the scheduling fields the chart adds. See
Task.
GanttRowGroup
export interface GanttRowGroup {
/** The raw value `groupBy` produced ("" for the ungrouped bucket) */
key: string;
/** What the header shows */
label: string;
/** How many tasks the group holds (rows can be fewer - lanes share a row) */
count: number;
}| Field | Type | Notes |
|---|---|---|
key | string | The stringified groupBy value. "" for the Ungrouped bucket. |
label | string | Equal to key, except for the Ungrouped bucket, where it is the ungroupedLabel prop — "Ungrouped" when the prop is not set. |
count | number | Tasks in the group, counted among the tasks the chart currently renders. Not a row count: lane-mates share a row. |
GanttRow
/**
* One rendered row
*
* Normally one task, several when they share a `lane`, none when the row is a
* group header. The tree numbers (`level`/`posinset`/`setsize`) are the ARIA
* values for the row, so the render never has to work them out again.
*/
export interface GanttRow {
/** Stable key - the group id for a header, otherwise the ids on the row */
id: string;
tasks: TaskTransformed[];
/** Indentation level, 0-based */
depth: number;
/** `aria-level`, 1-based */
level: number;
/** `aria-posinset` among the rows that share a parent */
posinset: number;
/** `aria-setsize` for that same set */
setsize: number;
/** Set only on a group header row */
group?: GanttRowGroup;
}| Field | Type | Notes |
|---|---|---|
id | string | See Row ids. |
tasks | TaskTransformed[] | Empty on a group header row. One entry on a normal row, several when tasks share a lane. |
depth | number | 0-based. Group headers are 0; every task row inside a group sits at its task depth + 1. |
level | number | aria-level. Always depth + 1. |
posinset | number | aria-posinset among the rows sharing this row's parent. A row's parent is the nearest row above it one depth shallower. |
setsize | number | aria-setsize for that same set. Counts visible rows only. |
group | GanttRowGroup | undefined | Present only on a group header row. Its absence is how a task row is told apart from a header. |
Row ids
| Row kind | id | Example |
|---|---|---|
| Group header | `group:${key}` | groupBy yields "Dev" → "group:Dev" |
| Ungrouped header | "group:" | The key is "", so nothing follows the colon. The label plays no part — "group:Ungrouped" matches nothing. |
| Task row | the task id | "a" |
| Lane row | the packed task ids joined with "+" | "a+b" |
Group header ids go in the same flat collapsedIds / defaultCollapsedIds array as task ids.
Collapsing the Ungrouped group means collapsedIds={['group:']}.
Not exported
src/utils/grouping.ts also holds buildGanttRows, packLanes, groupRowId,
GROUP_ROW_PREFIX, DEFAULT_UNGROUPED_LABEL and BuildGanttRowsOptions. None of them are
re-exported from the package, and none are part of the headless core — grouping runs on the
render side. Build a group id as the literal string `group:${key}` rather than importing a
helper for it.
Notes
- No prop or callback hands you a
GanttRow. The two row types are exported so host code can name the shape the chart works in — for readingTaskTransformed.order, or for matching acollapsedIdsentry. orderon aTaskTransformedis the 1-based row number, assigned after grouping. Group header rows consume numbers, and every task on a lane row reports the sameorder.countis taken before a collapse is applied to the group itself, so a collapsed group still shows its full number. It is taken after collapsed subtrees are removed, so collapsing a summary row inside the group lowers it.ungroupedLabel=""produces an empty header label. The"Ungrouped"default only fills in forundefined.- Group headers are always at
depth: 0. There are no nested groups:groupBytakes one value, not a list.
Next: Task for TaskTransformed, or GanttProps for groupBy and
ungroupedLabel in the prop index.