二三维拓扑图卡顿?试试 HT 渲染优化方案

By | 2026年7月30日

拓扑图作为抽象化的关系表达工具,以节点连线为核心元素,可直观呈现各领域复杂系统的关联网络,清晰揭示系统内部结构、层级依赖与业务逻辑,为系统理解、运行管理及结构优化提供可视化支撑。

基础拓扑仅通过节点与连线可表达基础连接关系,但视觉上无法直观呈现连接类型、数据流向、业务属性等扩展信息。因此在实际工程应用中,需通过图标、文本、标注等形式对连线信息进行增强表达,完整呈现系统运行逻辑与实时状态。

01 连线信息显示实现方式

在 HT 可视化框架中,节点与连线分别通过 ht.Node 与 ht.Edge 对象进行建模。针对连线信息展示需求,平台提供多种标准化实现方式。

基础文本标注

  • label 属性
    用于在连线对象上直接显示文本信息,是最常用的文本标注方式。
edge.s('label', '文本信息');
  • note 属性
    以气泡提示形式呈现附加说明,常用于状态标注、简要提示等场景。
edge.s('note', '文本信息');
  • 图标与复合信息显示
    如需在连线上显示图标或更为复杂的文本信息时(如状态图标、数据流向符号),通常可以使用连线上的 icons 属性表示。
edge.s({
    "arrow": {
        "position": 17, 
        "keepOrien": true,
        "names": [
            "symbols/拓扑图/arrow.json"
        ]
    }
});

除此之外,当连线信息内容较多的情况,还可以选择直接在页面中添加图标节点来展示信息,这类节点可通过 node.setHost(edge) 吸附在对应连线上。

02 大规模拓扑性能影响分析

在大型系统可视化场景中,大量文本、图标及自定义节点的叠加显示,会带来:

  • 渲染负载提升:过多绘制元素增加画布绘制压力,导致交互卡顿、帧率下降。
  • 信息密度过载:视图元素过于密集,关键信息难以辨识,影响可视化可读性与决策效率。

针对上述问题,HT 拓扑缩放自适应渲染方案,根据视图缩放程度动态控制非必要元素的显隐,平衡信息完整性与渲染性能。

拓扑图渲染实现方案

01 场景缩放控制元素显隐

对于大图纸,用户通常需要放大到一定程度才能看清连线 / 节点的详细信息。因此可设置:当图纸缩放值大于某个阈值时,才展示 label/note/icons 内容

在 HT 的视图组件 ht.graph.GraphView(2D 图纸)和 ht.graph3d.Graph3dView(3D 场景)中,提供了 isNoteVisible 和 isLabelVisible 方法用于控制 label 与 note 的显示逻辑。

  • Label 与 Note 动态控制
    在 2D 图纸中,默认当图纸缩放值(zoom)小于 0.15 时,会自动隐藏所有 label 和 note。如需自定义逻辑,可重写这两个方法。
view.isLabelVisible = function (data) {
    returnthis.getZoom() > 1;
};
  • Icons 动态控制
    通过监听画布缩放事件,动态控制图标可见性,减少非必要渲染。

02 基于图层管理的批量控制

在某些特殊场景下(如附加信息图标需显示在非常规位置),标准方式无法满足需求,可采用更灵活的方案:直接将 ht.Node 放置在连线附近,并可设置吸附于连线目标 / 起始节点。

node.setHost(target/source)

对此类附加信息节点,同样可根据缩放程度控制显示,实现步骤如下:

  • 创建自定义图层
const layer = g2d.getLayers();
layer.push({
    "name": "newLayer",
    "visible": true,
    "selectable": true,
    "movable": true,
    "editable": true
});
  • 绑定附加信息节点至图层
node.setLayer('newLayer');
  • 根据缩放控制图层可见性
g2d.mp(e => {
    if (e.property === 'zoom') {
        const visible = e.newValue > 1;
        if (visible !== g2d._layerVisible) {
            g2d._layerVisible = visible;
            const layer = g2d.getLayers();
            layer[1].visible = visible;
        }
    }
});

03 海量连线优化:ht.Shape 合并渲染

在存在大量连线的场景中,过多 ht.Edge 实例会显著降低渲染效率。可通过 ht.Shape 对象合并多条连线路径,统一渲染以提升帧率与交互流畅度。

实现逻辑

  • 遍历数据模型,筛选所有连线对象;
  • 提取各连线起点、拐点与终点坐标;
  • 构建统一路径并赋值给 ht.Shape;
  • 隐藏原连线,使用 Shape 替代渲染。

核心代码

// 过滤数据模型,获取所有 edges
const edges = dm.toDatas((d) => {
    return d.getClassName() === 'ht.Edge'
})
// 创建 ht.Shape 节点
const shape = new ht.Shape();
let points = [];
let segments = [];
let edgeColor = edges.get(0).s('edge.color'),
    edgeWidth = edges.get(0).s('edge.width');

// 遍历所有的 edge,获取点位信息
edges.each((edge) => {
    const edgeInfo = view.getEdgeInfo(edge);
    if (!edgeInfo) return;
    let edgePoints = [];
    edgePoints.push(edgeInfo.sourcePoint);
    if (edgeInfo.points) {
        edgePoints = edgePoints.concat(edgeInfo.points.toArray());
    }
    edgePoints.push(edgeInfo.targetPoint);

    points = points.concat(edgePoints);
    edgePoints.forEach((item, i) => {
        segments.push(i === 0 ? 1 : 2);
    })
    edge.s('2d.visible', false) // 将 edge 设置为不可见
})
// 设置 shape 的点位和样式
shape.setPoints(points)
shape.setSegments(segments);
shape.s({
    "shape.background": null,
    "shape.border.width": edgeWidth,
    "shape.border.color": edgeColor
})
dm.add(shape);

性能对比

在约 2048 条连线的测试场景中,合并渲染可显著提升高密连线场景下的运行性能。

左为 ht.Shape | 右为 ht.Edge

总结

本文介绍了 HT 平台下拓扑图连线信息的标准化展示方案,以及针对大规模拓扑场景的性能优化策略:

  • 基础信息可通过 label、note 快速实现文本标注;
  • 复杂图标与流向信息可通过 icons 或自定义节点扩展;
  • 大规模视图采用自适应缩放渲染,根据缩放动态控制元素与图层显隐;
  • 海量连线场景使用 ht.Shape 合并路径,降低实例数量,提升渲染效率。

实际开发中,可结合项目业务需求、视图复杂度与性能指标,灵活选用或组合使用上述方案,实现可视化效果与运行效率的最优平衡。