【SpreadJS v16.0 新特性预览】支持表格分层数据及树形展示
SpreadJS V16 新增了对分层数据的支持,并且可以根据用户提供的分层数据自动生成对应的树形表格。对分层数据的支持是在 SpreadJS 的 DataManager 中实现的,并通过集算表进行展示和交互。
相关信息请了解集算表相关特性:
https://demo.grapecity.com.cn/spreadjs/SpreadJSTutorial/features/table-sheet/overview/purejs
分层数据源类型:
1. 记录具有id和parentId的属性:
<div>[
{ id: 1, parentId: -1 },
{ id: 2, parentId: -1 },
{ id: 3, parentId:1 },
{ id: 4, parentId:1 },
{ id: 5, parentId:2 }
]</div>
2. 记录有属性表示层级,层级由记录的顺序确定,每条记录都可以有这个属性作为主键:
<div>[
{ name: 'USA', level: -1, id: 1 },
{ name: 'Texas', level: 0, id: 2 },
{ name: 'Houston', level: 1, id: 3 },
{ name: 'California', level: 0, id: 4 },
{ name: 'San Francisco', level: 1, id: 5 },
{ name: 'Los Angeles', level: 1, id: 6 },
]</div>
3. 记录有属性表示分层子级,记录一直是没有根记录的树数据,每个子级都可以有该属性作为主键:
<div>[
{
name: 'USA',
children: [
{
name: 'Texas',
children: [
{
name: 'Houston',
}
]
}
]
}
]</div>
4. 记录有主键,键可以通过自定义函数解析为层次结构:
<div>[
{ id: '1' },
{ id: '2' },
{ id: '1.1' },
{ id: '1.1.1' },
{ id: '2.1' }
]</div>
分层数据源配置
1. 数据源选项可以配置分层选项:
<div>interface GC.Data.IDataSourceOption {
//others options...
schema?: {
hierarchy: GC.Data.IHierarchyOption // define whether the data source is hierarchical
//others options...
}
}
interface GC.Data.IHierarchyOption {
type: 'Parent' | 'ChildrenPath' | 'Level' | 'Custom', // the hierarchy type
column: string // the hierarachy key that will help to build the hierarchical data
outlineColumn?: string | GC.Data.IHierarchyOutlineColumnOptions; // the options for self-defined outline
summaryFields: GC.Data.IHierarchySummaryFieldCollection // define the formulas for the fields
parse: (options: GC.Data.IHierarchyCustomParseOptions) => any; // parse the primary key of the custom hierarchy type to the parent key
unparse?: (options: GC.Data.IHierarchyCustomUnparseOptions) => any; // build the primary key of the custom hierarchy type
}
interface GC.Data.IHierarchySummaryFieldCollection {
: string; // the key is the field name, and the value is the formula
}
interface GC.Data.IHierarchyCustomParseOptions {
data: any,
index: number,
}
interface GC.Data.IHierarchyCustomUnparseOptions {
data: any,
index: number,
parentData: any
}
interface GC.Data.IOutlineColumnOptions {
showCheckBox?: boolean;
showImage?: boolean;
images?: string[];
showIndicator?: boolean;
expandIndicator?: string;
collapseIndicator?: string;
}
interface GC.Data.IHierarchyOutlineColumnOptions {
value: string; // specify the column name that will be outline column
showCheckBox?: boolean;
showImage?: boolean;
images?: string[];
showIndicator?: boolean;
expandIndicator?: string;
collapseIndicator?: string;
}
interface GC.Data.IColumn {
//other options...
// the rowOrder in the dataType is used for the ordering the records, the value of the column should be a number,
// it's used by the data manager when moving or inserting
// it's better to hide the column for the end user
dataType?: "string" | "number" | "boolean" | "object" | "array" | "date" | "rowOrder";
outlineColumn?: boolean | GC.Data.IOutlineColumnOptions // indicates the column be an outline column or the outline column options, and there should be only one outline column in the columns
}
</div>
<div>var taskTable = dataManager.addTable("Tasks", {
remote: { ... },
schema: {
hierarchy: {
type: 'Parent',
column: 'TaskParentId',
},
columns: {
TaskName: {dataName: 'name' },
TaskId: { dataName: 'id', isPrimaryKey: true }, // using primary key to indicate the hierarchy id
TaskParentId: { dataName: 'parentId' },
TaskRowOrder: { dataName: 'rowOrder', dataType: "rowOrder" }, // optional property for inserting and moving up/down
}
}
});
var taskView = taskTable.addView('TaskView',[
{
value: 'TaskName', outlineColumn: true // this option indicates the column showing as outline column
}
]);
</div>
<div>var taskTable = dataManager.addTable("Tasks", {
remote: { ... },
schema: {
hierarchy: {
type: 'Level',
column: 'TaskLevel',
},
columns: {
TaskName: {dataName: 'name' },
TaskId: { dataName: 'id', isPrimaryKey: true }, // using primary key to indicate the hierarchy id optionally if exist
TaskLevel: { dataName: 'level' },
TaskRowOrder: { dataName: 'rowOrder', dataType: "rowOrder" }, // optional property for inserting and moving up/down
}
}
});
var taskView = taskTable.addView('TaskView',[
{
value: 'TaskName', outlineColumn: true// this option indicates the column showing as outline column
}
]);
</div>
<div>var taskTable = dataManager.addTable("Tasks", {
remote: { ... },
schema: {
hierarchy: {
type: 'ChildrenPath',
column: 'TaskChildren',
},
columns: {
TaskName: {dataName: 'name' },
TaskChildren: { dataName: 'children' },
// other columns in the child
}
}
});
var taskView = taskTable.addView('TaskView',[
{
value: 'TaskName', outlineColumn: true // this option indicates the column showing as outline column
}
]);
</div>
<div>var taskTable = dataManager.addTable("Tasks", {
remote: { ... },
schema: {
hierarchy: {
type: 'Custom',
column: 'TaskId',
parse: function(options){
// parse the primary key "1.1.1" to "1.1"
// the returned value will be treated as parentId
let seg = options.data.TaskId.split('.');
return seg.slice(0,seg.length-1).join('.')
},
unparse: function(options){
let parentIds, currentIndex = options.index, parentData = options.parentData, parentKey = parentData && parentData.TaskId;
if (parentKey) {
let sp = parentKey.split('.');
parentIds = sp;
} else {
parentIds = [];
}
parentIds.push(currentIndex + 1);
return parentIds.join('.');
}
},
columns: {
TaskName: {dataName: 'name' },
TaskId: { dataName: 'id', isPrimaryKey: true }, // using primary key to indicate the hierarchy id optionally
}
}
});
var taskView = taskTable.addView('TaskView',[
{
value: 'TaskName', outlineColumn: true // this option indicates the column showing as outline column
}
]);
</div>
2. 降级记录,将当前记录的 parentId 替换为其上面记录的 id,如果 withChildren 为 true,则当前记录的子级将降低:
<div> /**
* Demote the hierarchy data level of the specified row.
* @param {number} row - The row index.
* @param {boolean} withChildren - Optional, the children will be demoted with the record by default.
* @returns {void}
* @example
* //This example demote the hierarchy data level by specified index.
* tableSheet.demoteHierarchyLevel(8);
*/
function demoteHierarchyLevel(row: number, withChildren?: boolean): void
</div>
3. 上移一条记录:
当列的 dataType 为 rowOrder 且列的 value 类型为 number 时,记录可以上下移动。
在层次数据中,向上移动只能在同一父级下的记录之间移动,
当父记录移动时,子记录将移动。
<div> /**
* Move the hierarchy data by the specified row up.
* @param {number} row - The row index.
* @returns {void}
* @example
* //This example move the hierarchy data by specified index up.
* tableSheet.moveUp(8);
*/
function moveUp(row: number): void</div>
4. 向下移动一个记录,它与向上移动相同:
/**
* Move the hierarchy data by the specified row down.
* @param {number} row - The row index.
* @returns {void}
* @example
* //This example move the hierarchy data by specified index down.
* tableSheet.moveDown(8);
*/
function moveDown(row: number): void
5. 添加记录:
默认情况下,它将在选择位置之前插入一条记录,并且插入的记录应该是选择记录的兄弟。
5.1 选中前添加记录:
<div> /**
* Add a new row data before the specified row.
* @param {number} row - The row index.
* @param {Object} rowData - The row data.
* @returns {void}
* @example
* //This example adds a new row data before the specified row.
* tableSheet.addHierarchyItemBefore(8, {id: 8, name: "grapecity"});
*/
function addHierarchyItemBefore(row: number, rowData: any): void</div>
5.2 选中后添加记录:
<div> /**
* Add a new row data after the specified row.
* @param {number} row - The row index.
* @param {Object} rowData - The row data.
* @returns {void}
* @example
* //This example adds a new row data after the specified row.
* tableSheet.addHierarchyItemAfter(8, {id: 8, name: "grapecity"});
*/
function addHierarchyItemAfter(row: number, rowData: any): void</div>
5.3 在选中的上面添加记录,添加的记录会替换选中记录的位置,选中的记录会是被添加记录的子:
<div> /**
* Add a new row data as the parent of the specified row.
* @param {number} row - The row index.
* @param {Object} rowData - The row data.
* @returns {void}
* @example
* //This example adds a new row data as the parent of the specified row.
* tableSheet.addHierarchyItemAbove(8, {id: 8, name: "grapecity"});
*/
function addHierarchyItemAbove(row: number, rowData: any): void</div>
5.4 在选中的下方添加记录,添加的记录将是选中记录的最后一个子记录:
<div> /**
* Add a new row data as the child of the specified row.
* @param {number} row - The row index.
* @param {Object} rowData - The row data.
* @returns {void}
* @example
* //This example adds a new row data as the child of the specified row.
* tableSheet.addHierarchyItemBelow(8, {id: 8, name: "grapecity"});
*/
function addHierarchyItemBelow(row: number, rowData: any): void</div>
6. 删除一条记录,它会删除子记录和它自己。
7. 展开所有级别:
单击列标题时将显示菜单项。
<div> /**
* Expand the all hierarchy levels.
* @returns {void}
* @example
* //This example expand the all hierarchy levels.
* tableSheet.expandAllHierarchyLevels();
*/
function expandAllHierarchyLevels(): void
</div>
8. 折叠所有级别:
<div> /**
* Collapse the all hierarchy levels.
* @returns {void}
* @example
* //This example collapse the all hierarchy levels.
* tableSheet.collapseAllHierarchyLevels();
*/
function collapseAllHierarchyLevels(): void</div>
9. 将记录扩展到指定级别:
单击列标题时会显示菜单,最多支持9级菜单项。
<div> /**
* Expand the hierarchy data by specified level.
* @param {number} level - The level to expand.
* @returns {void}
* @example
* //This example expand the hierarchy data by specified level.
* tableSheet.expandHierarchyLevel(8);
*/
function expandHierarchyLevel(level: number): void</div>
10. 切换菜单项的可见性:
提升、降级、上移/下移、前/后/上/下添加、展开/折叠级别的菜单项可以通过选项显示或隐藏:
<div>interface GC.Spread.Sheets.TableSheet.ITableSheetOptions {
// other properties...
menuItemVisibility?: {
// the options below be on the row header
promoteMenuItemVisible?: boolean;
demoteMenuItemVisible?: boolean;
// the options below be on the row header
// and the menu items be enable for the dataType of the column be rowOrder
moveUpMenuItemVisible?: boolean;
moveDownMenuItemVisible?: boolean;
addBeforeMenuItemVisible?: boolean;
addAfterMenuItemVisible?: boolean;
addAboveMenuItemVisible?: boolean;
addBelowMenuItemVisible?: boolean;
// the options below be on the column header
expandAllLevelMenuItemVisible?: boolean;
collapseAllLevelMenuItemVisible?: boolean;
expandToLevelMenuItemVisible?: boolean;
};
}
tableSheet.options.menuItemVisibility = {
promoteMenuItemVisible: true,
demoteMenuItemVisible: true,
moveUpMenuItemVisible: true,
moveDownMenuItemVisible: true,
addBeforeMenuItemVisible: true,
addAfterMenuItemVisible: true,
addAboveMenuItemVisible: true,
addBelowMenuItemVisible: true,
expandAllLevelMenuItemVisible: true,
collapseAllLevelMenuItemVisible: true,
expandToLevelMenuItemVisible: true,
}</div>
11. 对层次记录进行排序意味着按级别对记录的任何属性进行排序。
12. 过滤结果将显示父记录及其本身,如果记录有孩子,孩子也会显示。
13. 自定义轮廓列,带有outlineColumn选项的列将在表格中显示轮廓样式,并且只有一列是轮廓:
13.1 . 在架构中:
<div>var taskTable = dataManager.addTable("Tasks", {
remote: { ... },
schema: {
hierarchy: {
type: 'Parent',
column: 'TaskParentId',
outlineColumn: {
value: 'TaskName', // specify the column name that will be outline column
showCheckBox: true
}
},
columns: {
TaskName: {dataName: 'name' },
TaskId: { dataName: 'id', isPrimaryKey: true }, // using primary key to indicate the hierarchy id
TaskParentId: { dataName: 'parentId' },
TaskRowOrder: { dataName: 'rowOrder', dataType: "rowOrder" }, // optional property for inserting and moving up/down
}
}
});</div>
13.2. 在视图列中,优先级更高:
<div>var taskTable = dataManager.addTable("Tasks", {
remote: { ... },
schema: {
hierarchy: {
type: 'Parent',
column: 'TaskParentId',
outlineColumn: 'TaskName'
},
columns: {
TaskName: {dataName: 'name' },
TaskId: { dataName: 'id', isPrimaryKey: true }, // using primary key to indicate the hierarchy id
TaskParentId: { dataName: 'parentId' },
TaskRowOrder: { dataName: 'rowOrder', dataType: "rowOrder" }, // optional property for inserting and moving up/down
}
}
});
var taskView = taskTable.addView('TaskView',[
{
value: 'TaskName', outlineColumn: { showCheckBox: true } // this option indicates the column showing as outline column
}
]);</div>
14. 该功能可能与层次结构发生冲突
14.1 . groupBy 不能处理层次结构数据;
14.2. 固定行不能与层次结构数据一起使用;
14.3 . 对于仅影响当前行数据的特征,resetRow 不能很好地处理层次数据,但一些用于层次特征的属性不会受到影响。
层次结构远程接口
在父层级类型中,远程接口和之前一样,
但如果它是级别或子路径层次结构类型,每个远程接口都会将整个记录发送到远程而不被删除,
因为它不能识别插入记录的父记录。
页:
[1]