TreeGroup
A feature that allows transforming a flat dataset (or the leaves of a hierarchical) into a tree by specifying a record field per parent level. Parents are generated based on each leaf's value for those fields.
//<code-header>
fiddle.title = 'Tree group';
//</code-header>
const grid = new TreeGrid({
appendTo : targetElement,
// Makes grid as high as it needs to be to fit rows
autoHeight : true,
// Initial dataset, will be transformed by the TreeGroup feature
store : {
fields : [
'name',
'status',
'prio'
],
data : [
{
id : 1,
name : 'Project 1',
expanded : true,
children : [
{ id : 11, name : 'Task 11', status : 'WIP', prio : 'High' },
{ id : 12, name : 'Task 12', status : 'Done', prio : 'Low' },
{ id : 13, name : 'Task 13', status : 'Done', prio : 'High' }
]
},
{
id : 2,
name : 'Project 2',
expanded : true,
children : [
{ id : 21, name : 'Task 21', status : 'WIP', prio : 'High' }
]
}
]
},
columns : [
{ type : 'tree', field : 'name', text : 'Name', flex : 1 }
],
features : {
treeGroup : {
levels : ['status'],
// Customize the cell / row element or the value displayed using parentRenderer
parentRenderer({ value, cellElement, row, grid }) {
const cls = value === 'Done' ? 'check-circle' : 'clock';
return `<i class="fa fa-${cls}" style="margin-inline-end:.5em;color:${cls === 'check-circle' ? 'green' : 'lightgray'}"></i>${value}`;
}
}
},
tbar : [
{
type : 'buttongroup',
toggleGroup : true,
items : [
{
text : 'Status',
pressed : true,
onToggle({ pressed }) {
pressed && grid.group(['status']);
}
},
{
text : 'Prio',
onToggle({ pressed }) {
pressed && grid.group(['prio']);
}
},
{
text : 'Status + Prio',
onToggle({ pressed }) {
pressed && grid.group(['status', 'prio']);
}
},
{
text : 'none',
onToggle({ pressed }) {
pressed && grid.clearGroups();
}
}
]
}
]
});This feature can be used to mimic multi grouping or to generate another view for hierarchical data. The actual
transformation happens in a new store, that contains links to the original records. The original store's structure is
kept intact and will be plugged back in when calling clearGroups. When grouping on a column field,
the column´s format method will be used to format the value to group by (relevant for NumberColumn, DateColumn etc.)
Any modification of the links is relayed to the original store. So cell editing and other features will work as expected and the original data will be updated.
This snippet shows how the sample dataset used in the demo above is transformed:
const grid = new TreeGrid({
// Original data
data : [
{ id : 1, name : 'Project 1', children : [
{ id : 11, name : 'Task 11', status : 'wip', prio : 'high' },
{ id : 12, name : 'Task 12', status : 'done', prio : 'low' },
{ id : 13, name : 'Task 13', status : 'done', prio : 'high' }
]},
{ id : 2, name : 'Project 2', children : [
{ id : 21, name : 'Task 21', status : 'wip', prio : 'high' },
]}
],
features : {
treeGroup : {
// Fields to build a new tree from
levels : [ 'prio', 'status' ]
}
}
});
// Resulting data
[
{ name : 'low', children : [
{ name : 'done', children : [
{ id : 12, name : 'Task 12', status : 'done', prio : 'low' }
]}
]},
{ name : 'high', children : [
{ name : 'done', children : [
{ id : 13, name : 'Task 13', status : 'done', prio : 'high' }
]},
{ name : 'wip', children : [
{ id : 11, name : 'Task 11', status : 'wip', prio : 'high' },
{ id : 21, name : 'Task 21', status : 'wip', prio : 'low' }
]}
]}
]
Generated parent records are indicated with generatedParent and key properties. The first one is set to
true and the latter one has a value for the group the parent represents.
Summaries
You can also show summaries in each group row, by configuring columns with sum.
new Grid({
features : { treeGroup : true },
columns : [
{
text : 'Name',
field : 'name',
flex : 3,
type : 'tree'
},
{
type : 'number',
text : 'Capacity',
field : 'capacity',
flex : 1,
sum : 'add'
},
{
type : 'number',
text : 'Crew',
field : 'crew',
flex : 1,
sum : 'add'
}
]
});
Important information
Using the TreeGroup feature comes with some caveats:
- Generated parents are read-only, they cannot be edited using the default UI.
- Moving nodes manually in the tree is not supported while it is grouped. The linked records have their own
parentIdfields, not linked to the original records value. - The generated structure is not meant to be persisted.
This feature is disabled by default.
Configs
15
Configs
15Other
Specify as true to make generated parents start expanded.
True to hide grouped columns. Only supported when using String to define levels.
An array of model field names or functions used to determine the levels in the resulting tree.
When supplying a function, it will be called for each leaf in the original data, and it is expected to return an atomic value used to determine which parent the leaf will be added to at that level.
const grid = new TreeGrid({
features : {
treeGroup : {
levels : [
// First level is determined by the value of the status field
'status',
// Second level by the result of this function
// (which puts percentdone 0-9 in one group, 10-19 into another and so on)
record => (record.percentDone % 10) * 10
]
}
}
});
The function form can also be used as a formatter/renderer of sorts, simply by returning a string:
const grid = new TreeGrid({
features : {
treeGroup : {
levels : [
record => `Status: ${record.status}`
]
}
}
});
Assigning null restores the tree structure to its original state.
CSS class to apply to the generated parents.
A function letting you format the text shown in the generated parent group levels. This method will be provided
with the value produced by the column representing the grouped level. Each column's renderer method will be
provided an extra isTreeGroup param to indicate that the value will be used for a generated parent. cellElement
and other DOM specific args will be in the context of the tree column.
const grid = new Grid({
features : {
treeGroup : {
hideGroupedColumns : true,
levels : [
'priority'
],
parentRenderer({ field, value, column, record }) {
// For generated group parent, prefix with the grouped column text
return column.text + ': ' + value;
}
}
}
})
| Parameter | Type | Description |
|---|---|---|
data | Object | The rendering data representing the generated tree parent record |
data.field | String | The field representing this group level (e.g. 'priority') |
data.value | * | The value representing this group level (e.g. 'high') |
renderData | Object | Object containing renderer parameters |
renderData.cellElement | HTMLElement | Cell element, for adding CSS classes, styling etc. Can be |
data.column | Column | The value representing this group level (e.g. 'high') |
renderData.grid | GridBase | This grid |
data.record | Model | The first record for this parent |
renderData.isExport | Boolean |
|
renderData.row | Row | The parent Row object. Can be |
Optional sort function for the generated parent tree nodes.
const grid = new Grid({
features : {
treeGroup : {
parentSortFn(parentA, parentB) {
return parentB.name.localeCompare(parentA.name, undefined, { numeric : true });
}
}
}
})
| Parameter | Type | Description |
|---|---|---|
parentA | TreeParentNode | The first node to be compared |
parentB | TreeParentNode | The second node to be compared |
A negative value means parentA comes before parentB, a positive after, and 0 or NaN
means they are equal
Misc
Properties
18
Properties
18Common
Class hierarchy
Other
Indicates if the feature has applied grouping and the component uses a transformed version of the store.
An array of model field names or functions used to determine the levels in the resulting tree.
When supplying a function, it will be called for each leaf in the original data, and it is expected to return an atomic value used to determine which parent the leaf will be added to at that level.
const grid = new TreeGrid({
features : {
treeGroup : {
levels : [
// First level is determined by the value of the status field
'status',
// Second level by the result of this function
// (which puts percentdone 0-9 in one group, 10-19 into another and so on)
record => (record.percentDone % 10) * 10
]
}
}
});
The function form can also be used as a formatter/renderer of sorts, simply by returning a string:
const grid = new TreeGrid({
features : {
treeGroup : {
levels : [
record => `Status: ${record.status}`
]
}
}
});
Assigning null restores the tree structure to its original state.
The original store used by the component before applying grouping. Use this to modify / load data while tree grouping is active.
Functions
30
Functions
30Tree grouping
Clears the previously applied transformation, restoring data to its initial state.
Yields the same result as assigning null to levels.
// Restore original data
grid.clearGroups();
Transforms the data according to the supplied levels.
Yields the same result as assigning to levels.
// Transform into a tree with two parent levels
grid.group('status', record => (record.percentDone % 10) * 10);
| Parameter | Type | Description |
|---|---|---|
levels | (String|Column|Model): any)[] | Field names or functions use to generate parents in resulting tree. |
Configuration
Events
Misc
Other
Events
5
Events
5Event handlers
5
Event handlers
5Typedefs
2
Typedefs
2An object that represents a tree parent node.
| Parameter | Type | Description |
|---|---|---|
id | String | Id of the parent node |
field | String | Which field is being used for the group level |
expanded | Boolean |
|
key | String | Grouping key identifier for the group level |
path | String | String that represents the path to that group level |
cls | String | CSS classes for the group level |
children | Model[] | Array of the children nodes |
readOnly | Boolean |
|