展示全部按钮
前置加载节点的显示全部选项 - 预加载所有数据但初始仅显示有限节点,按需显示全部
前置加载节点的显示全部选项
功能概述
本示例演示了显示大量子节点的"显示全部"模式。它不是使用分页延迟加载,而是预加载所有数据但初始隐藏超出默认可见数量(每个分类 3 个节点)的节点。用户可以点击"显示更多"按钮一次性显示所有隐藏的节点。这种方法提供对完整数据集的快速访问,同时保持简洁的初始视图。
核心特性实现
部分可见的初始数据加载
appendTypeData 函数加载所有节点但将大部分标记为隐藏:
const appendTypeData = async (myType: string) => {
const typeNode = graphInstance.getNodes().find(n => n.data.myType === myType);
const defaultVisibleCount = 3;
const allItems = await loadMockCompanys(myType);
const total = allItems.length;
const thisTypeJsonData: RGJsonData = { nodes: [], lines: [] };
for (const entItem of allItems) {
const companyNode: JsonNode = {
id: entItem.companyId,
text: entItem.companyName,
data: { ownerType: myType }
};
// 隐藏超出默认可见数量的节点
if (thisTypeJsonData.nodes.length > defaultVisibleCount) {
companyNode.hidden = true;
}
thisTypeJsonData.nodes.push(companyNode);
thisTypeJsonData.lines.push({ from: typeNodeId, to: companyNode.id });
}
updateLoadMoreButtonNode(typeNodeId, myType, defaultVisibleCount - 1, total, thisTypeJsonData);
// 将新节点定位在父节点位置以实现平滑动画
thisTypeJsonData.nodes.forEach((n: JsonNode) => {
n.x = typeNode.x;
n.y = typeNode.y;
});
graphInstance.addNodes(thisTypeJsonData.nodes);
graphInstance.addLines(thisTypeJsonData.lines);
};
关键要点:
- 所有数据预加载:预先获取完整数据集
- 选择性可见:默认仅显示前 3 个节点
- 隐藏属性:使用
node.hidden = true隐藏多余节点 - 批量添加:一次性将所有节点添加到图中以提高效率
显示全部功能
showAllNodes 函数显示某个分类的所有隐藏节点:
const showAllNodes = async(buttonNode: RGNode) => {
const myType = buttonNode.data.loadType;
const typeNodes = graphInstance.getNodes().filter(n => n.data.ownerType === myType);
// 取消隐藏此类型的所有节点
typeNodes.forEach(n => {
graphInstance.updateNode(n.id, { hidden: false });
});
// 删除"显示更多"按钮
graphInstance.removeNodeById(buttonNode.id);
await graphInstance.doLayout();
};
关键要点:
- 按类型过滤:仅检索匹配分类类型的节点
- 批量更新:一次性更新所有相关节点的可见性
- 按钮移除:显示节点后删除"显示更多"按钮
- 布局刷新:显示所有节点后重新计算位置
显示更多按钮管理
updateLoadMoreButtonNode 函数添加显示剩余数量的按钮:
const updateLoadMoreButtonNode = (
typeNodeId: string,
myType: string,
fromIndex: number,
total: number,
currentPageGraphJsonData: RGJsonData
) => {
const loadNextPageButtonNodeId = `${myType}-next-button`;
graphInstance.removeNodeById(loadNextPageButtonNodeId);
const remainingItemCount = total - fromIndex + 1;
if (remainingItemCount > 0) {
const loadNextPageButtonNode = {
id: loadNextPageButtonNodeId,
text: `Show More(${remainingItemCount})`,
data: { myType: 'more-btn', loadType: myType, fromIndex: (fromIndex + 1) }
};
currentPageGraphJsonData.nodes.push(loadNextPageButtonNode);
currentPageGraphJsonData.lines.push({
from: typeNodeId,
to: loadNextPageButtonNode.id
});
}
};
带点击处理器的自定义节点插槽
NodeSlot 组件处理"显示更多"按钮点击:
const NodeSlot: React.FC<RGNodeSlotProps & {showAllNodes: (n: RGNode) => void|Promise<void>}> = ({ node, showAllNodes }) => {
const myType = node.data.myType;
const buttonTypes = ['investment-button', 'shareholder-button', 'historical-investment-button', 'historical-shareholder-button'];
return (
<>
{buttonTypes.includes(myType) && (
<div className="my-node my-button-node">{node.text}</div>
)}
{myType === 'root' && (
<div className="my-node my-root">{node.text}</div>
)}
{myType === 'more-btn' && (
<div className="my-node more-btn px-2" onClick={() => {showAllNodes(node)}}>
{node.text}
</div>
)}
{!myType && (
<div className="my-node">{node.text}</div>
)}
</>
);
};
多分类初始化
图初始化时有四个分类节点,每个都有预加载的隐藏子节点:
const initializeGraph = async () => {
const myJsonData: RGJsonData = {
rootId: 'root',
nodes: [
{ id: 'root', text: 'Tian Technology Co., Ltd.', expandHolderPosition: 'hide', data: { myType: 'root' } },
{ id: 'root-invs', text: 'Investment', disablePointEvent: true, data: { myType: 'investment-button', childrenLoaded: false } },
{ id: 'root-history-invs', text: 'Historical Investment', data: { myType: 'historical-investment-button', childrenLoaded: false } },
{ id: 'root-sh', text: 'Share Holder', disablePointEvent: true, data: { myType: 'shareholder-button', childrenLoaded: false } },
{ id: 'root-history-shareholder', text: 'Historical Share Holder', data: { myType: 'historical-shareholder-button', childrenLoaded: false } }
],
lines: [
{ from: 'root', to: 'root-invs', showEndArrow: false },
{ from: 'root', to: 'root-history-invs', showEndArrow: false },
{ from: 'root', to: 'root-sh', showEndArrow: false },
{ from: 'root', to: 'root-history-shareholder', showEndArrow: false }
]
};
graphInstance.loading();
await graphInstance.setJsonData(myJsonData);
// 使用部分可见性预加载所有分类
await appendTypeData('investment-button');
await appendTypeData('shareholder-button');
await appendTypeData('historical-investment-button');
await appendTypeData('historical-shareholder-button');
await graphInstance.sleep(400);
await graphInstance.doLayout();
graphInstance.clearLoading();
graphInstance.moveToCenter();
graphInstance.zoomToFit();
};
树形布局配置
const graphOptions: RGOptions = {
defaultExpandHolderPosition: 'right',
defaultNodeShape: RGNodeShape.rect,
defaultNodeBorderWidth: 0,
defaultLineShape: RGLineShape.StandardOrthogonal,
defaultPolyLineRadius: 5,
defaultJunctionPoint: RGJunctionPoint.lr,
reLayoutWhenExpandedOrCollapsed: true,
layout: {
layoutName: 'tree',
from: 'left',
treeNodeGapH: 100,
treeNodeGapV: 10,
alignItemsX: 'start',
alignParentItemsX: 'end',
}
};
创意使用场景
企业结构可视化: 显示企业集团的所有子公司,但初始仅显示关键部门。高管可以在需要详细分析时展开查看所有子单元。
产品目录浏览: 显示每个分类的前 3 个产品,隐藏其余产品。购物者可以点击"显示更多"来显示他们感兴趣的分类中的完整产品线。
组织架构图浏览器: 渲染公司层级结构,直接报告限制为 3 个。用户可以在需要完整可见性时显示部门内的所有团队成员。
网络依赖关系图: 可视化系统依赖关系,初始仅显示关键依赖项。开发人员在排查复杂系统问题时可以展开查看所有连接。
文件系统浏览器: 显示文件夹内容,仅前 3 个文件可见。用户可以在搜索特定项目时显示目录中的所有文件,而无需导航离开。