JavaScript is required

折线标签样式与位置调节

这是一个紧凑树图查看器,使用简洁正交连线与分离的盒状标签,背景为渐变画布。用户可旋转树方向、调整全局线标签偏移,并复用同一模式实现连接器上的数值徽章或注释。

正交树连线上的独立背景标签

这个示例构建了什么

这个示例构建了一个小型树形查看器,它的连线采用正交布线,并使用分离式文本徽标,而不是把文字直接绘制在路径上。画布经过了刻意的风格化处理,具有暖色渐变背景、半透明节点以及带边框的连线标签,因此这个示例的主要视觉要点既包括几何布局,也包括可读性。

用户可以将树旋转到左、右、上或下方向,然后通过一个浮动控制面板微调每个内置连线标签的 x 和 y 偏移量。这个共享窗口还暴露了通用画布设置和截图导出功能,但本示例的核心仍然是正交布线、盒状标签以及面向方向的布局预设这三者的组合。

数据如何组织

图数据以内联方式声明为一个 RGJsonData 对象,其中包含 rootId: 'a'、一个扁平的 nodes 数组和一个扁平的 lines 数组。每条连线都带有一个 text 值,例如 ¥30.23 K,因此这些标签来自普通关系数据,而不是来自自定义 slot 渲染器。

在初始 setJsonData() 调用之前,这里没有 fetch 层,也没有预处理步骤。唯一的运行时转换发生在图加载之后:当布局方向变化时,组件会计算一组新的默认标签偏移量,然后重新应用图选项。在真实项目中,相同的数据结构也可以表示审批金额、转账数值、依赖注释,或任何其他需要在连接线上保持可读的短标签。

relation-graph 的使用方式

这个 demo 被包裹在 RGProvider 中,然后 MyGraph 通过 RGHooks.useGraphInstance() 获取当前活动实例。RelationGraph 组件接收一个选项对象,用于固定节点尺寸、线宽和 RGLineShape.SimpleOrthogonal,同时将 defaultLineTextOnPath 设置为 false,这样标签就会作为可由 CSS 样式化的分离元素渲染。

在运行时,这个示例使用 graphInstance.updateOptions() 推送新的标签偏移量、一个按方向变化的 defaultJunctionPoint,以及当方向变化时新的树间距。之后它会调用 doLayout()moveToCenter()zoomToFit() 来重建树并重新调整视口。这个示例是一个查看器,而不是编辑器:它不会创建节点、修改单独的连线,也不会提供自定义节点或连线 slot。

大部分视觉定制来自样式表覆写,而不是自定义渲染组件。SCSS 会针对 .rg-map.rg-node.rg-line-label 这样的 relation-graph 内置类进行样式设置,以产生渐变画布、玻璃质感节点和徽标式标签。共享的 DraggableWindow 辅助组件再次通过 graph hooks 提供滚轮模式、拖拽模式和图像导出功能,但这个覆盖层只是辅助脚手架,并不是这里演示的独特技术本体。

关键交互

布局方向选择器是最重要的交互。在 leftrighttopbottom 之间切换时,会改变树的朝向,在水平和垂直之间切换正交连接点模式,调整树间距,并在重新布局后将视图重新居中。

两个滑块允许用户通过 defaultLineTextOffsetXdefaultLineTextOffsetY 全局调节分离式标签的位置。当同一种标签样式需要适配多个布局方向,而又不想逐条编辑连线记录时,这会让这个 demo 很有用。

控制面板中还包含一个折线圆角半径滑块。在这段代码里,这个值会存储在组件状态中,并包含在选项载荷里,但显式的重新应用流程是绑定到方向和偏移量更新上的,而不是绑定到专门的半径 effect。

共享设置面板还提供了关于滚轮行为、拖拽行为以及下载图谱图片的次级交互。这些控件确实存在于该示例中,但它们来自可复用的 demo 基础设施,而不是来自连线标签特有的逻辑。

关键代码片段

这个片段表明,该示例始终使用 relation-graph 的内置选项,而不是用自定义 slot 替换连线渲染。

const graphOptions: RGOptions = {
    defaultLineWidth: 2,
    defaultLineShape: RGLineShape.SimpleOrthogonal,
    defaultLineTextOffsetX: defaultLineTextOffsetX,
    defaultLineTextOffsetY: defaultLineTextOffsetY,
    defaultPolyLineRadius: defaultPolyLineRadius,
    defaultLineTextOnPath: false,
    layout: {
        layoutName: 'tree',
        from: 'left',
        treeNodeGapH: 50,
        treeNodeGapV: 50
    }
};

这个片段表明,数据是一个普通的 RGJsonData 树结构,标签文本直接嵌入在连线记录中。

const myJsonData: RGJsonData = {
    rootId: 'a',
    nodes: [
        { id: 'a', text: 'a' },
        { id: 'b', text: 'b' },
        // ...
    ],
    lines: [
        { from: 'a', to: 'b', text: '¥30.23 K' },
        // ...
    ]
};
await graphInstance?.setJsonData(myJsonData);

这个片段展示了重新布局的调用序列,它让方向变化同时更新几何布局和视口 framing。

const updateOptionAndReLayout = async () => {
    await updateOptions();
    await graphInstance.doLayout();
    graphInstance.moveToCenter();
    graphInstance.zoomToFit();
};

这个片段展示了组件会针对不同的树方向分配不同的标签偏移预设,然后再重新应用选项。

useEffect(() => {
    let lineTextOffsetX = 0;
    let lineTextOffsetY = 0;
    if (layoutFrom === 'left') {
        lineTextOffsetX = -50;
        lineTextOffsetY = 0;
    } else if (layoutFrom === 'right') {
        lineTextOffsetX = 10;
        lineTextOffsetY = 0;
    } else if (layoutFrom === 'top') {
        lineTextOffsetY = -10;
    } else if (layoutFrom === 'bottom') {
        lineTextOffsetY = 40;
    }

这个片段证明,盒状标签来自对内置 .rg-line-label 元素施加的 CSS,而不是来自自定义 SVG 文本。

.rg-line-peel {
    .rg-line-label {
        border: #fff 1px solid;
        background-color: #e94057;
        color: #fff;
    }
}

.rg-line-peel.rg-line-checked {
    .rg-line-label {
        background-color: rgba(255, 255, 255, 1);
        color: #e94057;
    }
}

这个示例的独特之处

与附近的 text-on-orthogonalbothway-tree2 等示例相比,这个示例更聚焦于全局标签样式,而不是逐线修改或分支级逻辑。它最主要的可复用思路是:通过组合 defaultLineTextOnPath = false、针对 .rg-line-label 的 CSS,以及按方向变化的偏移预设,可以让分离式标签在多个树方向下都保持可读。

这个示例的风格化程度也高于中性的几何布局 demo。渐变地图背景、半透明节点以及选中状态下的颜色反转,让内置连线标签呈现为醒目的徽标,因此当目标是成品级展示风格而不是纯布局实验时,它会是一个更强的参考。

相较于 line 这类更广泛的连线展示示例,它的范围是刻意收窄的。它并不尝试比较许多箭头、标记或逐线形状,而是固定在一种正交树模式上,并展示如何通过图级选项和重新布局调用来调节它。相对于 canvas-bg2,它的独特价值在于主题样式工作直接绑定到了运行时标签位置调节,而不仅仅是画布皮肤。

这种模式还适用于哪些场景

这种模式非常适合金融或运营类树图,在这些图里每条连接线都需要一个简短的数值徽标,例如预算拆分、佣金流向、审批金额或依赖成本。它同样适用于组织架构图或流程树,因为在这些场景下,当用户为了展示需要切换布局方向后,边标签仍然必须保持可见。

同样的方法也可以扩展到连接线上的状态 chip、SLA 标签或风险评分,而无需引入自定义连线 slot。当标签渲染器可以继续保持内置实现时,团队就能保持数据模型简单,并将大部分展示工作放到图选项加 CSS 上。