ali-react-table
ali-react-table copied to clipboard
CrossTable 可以对数据排序么?
想对CrossTable的数据进行排序
我们也是:希望支持对CrossTable的排序功能?
收到,我有空了之后看下,如果大家有什么排序的好想法,也可以在这里写一下
交叉表排序有个问题,因为code都一样,会激活多列。 onChangeSorts的参数nextSorts也只有code,无法区分到底是哪一列激活了排序。 目前卡在这里了,需要知道是具体哪一列触发了排序。
可以用buildCrossTable
把 CrossTable
的数据转换成 BaseTable 的 props,然后使用 sort feature
经过一番折腾解决了,大概说一下思路:
1、排序插件提供了 SortHeaderCell
,可以传递 ReactNode
,不过也意味着要完全自己做了;
2、自定义 SortHeaderCell
,可以获取到具体哪一列触发了排序,例如: 福州/利润、厦门/利润,可以获取到具体是福州还是厦门;
3、获取到具体哪列之后,问题就剩下排序算法,可以查看一下 leftDrillTree,这个数据顺序决定了排序;
4、排序 leftDrillTree
,生成新的matrix
,完成排序。
总结一下,现有SortItem
只有code
,order
,对于CrossTable按列值排序的场景不太适用,缺少了关键的dataKey
,自己实现的话比较绕一些,要重复实现排序效果与事件。
const pipeline = useTablePipeline()
.input({ dataSource: dataSource, columns: columns })
.use(
features.sort({
mode: 'single',
highlightColumnWhenActive: false,
keepDataSource: true,
SortHeaderCell: props => (
<SortHeaderCell {...props} {...sortItem} onSort={setSortItem} />
),
}),
);
// 获取当前排序,用于相同code排序的情况
function getCurOrder(
column: any,
dataKey: string,
code: string,
order: SortOrder,
): SortOrder {
const isSameCode = column.code === code;
const isSameDataKey = getDataKey(column) === dataKey;
return isSameCode && isSameDataKey ? order : 'none';
}
// 获取下一个排序
function nextOrder(order: SortOrder): SortOrder {
const orders: SortOrder[] = ['asc', 'desc', 'none'];
const curIdx = orders.findIndex(t => t === order);
return orders[curIdx === orders.length - 1 ? 0 : curIdx + 1];
}
// 获取dataKey
function getDataKey(column: any): string {
return column?.data?.dataKey || '';
}
// 自定义排序表头
function SortHeaderCell({
children,
column,
dataKey,
code,
order,
onSort,
}: AdSortHeaderCellProps) {
const curOrder = getCurOrder(column, dataKey, code, order);
return (
<div
style={{ cursor: 'pointer' }}
onClick={() =>
onSort({
dataKey: getDataKey(column),
code: column.code as string,
order: nextOrder(curOrder),
})
}
>
{children}
<SortIcon size={16} order={curOrder} />
</div>
);
}