曲线连线路径文字控制
这个示例渲染一棵固定的左到右树图,默认让较长关系标签沿曲线边路径显示。悬浮控制窗可调整曲线族、连接锚点、路径贴合位置、文本对齐、偏移和最大可见文本长度,并提供共享画布设置与图片导出。
控制曲线关系图连线上的文本
这个示例构建了什么
这个示例构建了一棵固定的、从左到右展开的树,关系标签直接渲染在曲线边路径上。画布本身保持简洁,但一个悬浮控制窗口允许用户比较三种曲线连线族、切换连接锚点、沿路径移动标签、修改文本对齐方式,并调节偏移量与可见文本长度。
重点不在于自定义绘制,而是在于作为一个聚焦的参考示例,展示如何借助 relation-graph 内置的连线渲染器和实时实例 API,让曲线连接器上的长边标签更易读。
数据是如何组织的
图数据是在 MyGraph.tsx 中以内联方式定义的一个静态 RGJsonData 对象。它使用 rootId: 'a',包含十六个硬编码节点和十五条硬编码连线,并且每条连线都重复相同的长文本:These relationship texts are very long。
这里没有获取数据的步骤,也没有在调用 setJsonData() 之前做预处理。准备工作发生在 options 对象中:连线形状、连接点、连线文本长度以及布局设置,都会在图渲染之前根据 React state 或本地字面量推导出来。在真实应用中,同样的结构可以用来表示依赖说明、审批条件、归属关系,或者任何边文本承载实际业务语义的树形结构。
relation-graph 是如何使用的
这个示例包裹在 RGProvider 中,RGHooks.useGraphInstance() 提供实时 graph 实例。RelationGraph 接收一个由 state 推导出的 graphOptions 对象,使布局固定为一棵从左向右生长的树,并设置 treeNodeGapH: 200 与 treeNodeGapV: 30。同一个 options 对象还会设置统一的节点尺寸、将内置工具栏放在右下角、启用 defaultLineTextOnPath,并把默认曲线连线族与连接点策略绑定到组件 state。
图的初始化是显式完成的。initializeGraph() 会调用 setJsonData(),随后执行 moveToCenter() 和 zoomToFit(),因此每次重新加载时都会立即把示例树调整到合适视图中。当所选的 lineShape 发生变化时,代码会重新执行 initializeGraph(),因为 defaultLineShape 会在创建连线时生效。对于其他标签控制项,组件会保持当前图实例挂载不变,并使用 graphInstance.updateOptions() 配合 graphInstance.getLines() 与 graphInstance.updateLine(),就地重写实时连线。
这个演示里没有自定义节点、连线、画布或视口插槽,也没有图事件处理器。示例尽量贴近内置渲染器,通过 options、实例 API 和 SCSS 来完成定制。my-relation-graph.scss 会放大节点文本,并将 .rg-line-text 着色为蓝色,让路径标签始终成为视觉重点。
悬浮面板由共享的 DraggableWindow 辅助组件提供,而不是由示例专属的图代码实现。这个共享辅助组件增加了拖拽、最小化、设置覆盖层、画布滚轮与拖拽模式切换,以及通过 prepareForImageGeneration()、domToImageByModernScreenshot() 和 restoreAfterImageGeneration() 实现的图片导出能力。
关键交互
Line Shape选择器可在RGLineShape.StandardCurve、RGLineShape.Curve2和RGLineShape.Curve5之间切换,然后重新加载图,使所选默认曲线应用到所有边上。Junction Point选择器可在RGJunctionPoint.border与RGJunctionPoint.lr之间切换,从而改变曲线连线附着到节点的方式。Line Text Anchor选择器会把当前每条连线重写为使用start、middle或end对齐。placeText选择器会重写当前每条连线,使标签位于路径的起始、中间或末端附近。- x 和 y 范围输入会更新全局图级别的连线文本偏移量,而无需重建数据。
- 最大长度滑块会修改图 options 中配置的标签长度限制。
- 悬浮工具窗口可以拖动或最小化,它的共享设置面板还可以修改画布滚轮与拖拽行为,或将图导出为图片。
关键代码片段
这段代码表明,核心行为由 relation-graph options 驱动,而不是依赖自定义 SVG 渲染。
const graphOptions: RGOptions = {
defaultLineShape: lineShape,
defaultJunctionPoint: junctionPoint,
defaultLineTextOnPath: true,
lineTextMaxLength: lineTextMaxLength,
defaultLineTextOffsetX: 2,
defaultLineTextOffsetY: -3,
layout: {
layoutName: 'tree',
from: 'left',
treeNodeGapH: 200,
treeNodeGapV: 30
}
};
这段代码证明,该示例使用了一棵小型静态树,并重复使用长边标签,以便单独观察文本可读性。
const myJsonData: RGJsonData = {
rootId: 'a',
nodes: [
{ id: 'a', text: 'a' },
{ id: 'b', text: 'b' },
// ...
],
lines: [
{ from: 'a', to: 'b', text: 'These relationship texts are very long' },
// ...
]
};
这段代码展示了加载路径:它会插入 JSON 数据,并立即在视口中完成定位。
const initializeGraph = async () => {
await graphInstance.setJsonData(myJsonData);
graphInstance.moveToCenter();
graphInstance.zoomToFit();
};
这段代码展示了实时调整标签的关键运行时模式:先更新 graph options,然后逐条重写已挂载连线的标签位置与锚点对齐。
graphInstance.updateOptions({
defaultJunctionPoint: junctionPoint as RGJunctionPoint,
lineTextMaxLength: lineTextMaxLength,
defaultLineTextOffsetX: textOffsetX,
defaultLineTextOffsetY: textOffsetY
});
const lines = graphInstance.getLines();
lines.forEach(line => {
graphInstance.updateLine(line.id, {
placeText,
textAnchor: lineTextAnchor
});
});
这段代码表明,更改曲线族时是通过重新加载图来处理的,而不只是修改已经挂载的 options。
useEffect(() => {
initializeGraph();
}, [lineShape]);
这段代码展示了悬浮设置面板使用的共享图片导出流程。
const canvasDom = await graphInstance.prepareForImageGeneration();
let graphBackgroundColor = graphInstance.getOptions().backgroundColor;
if (!graphBackgroundColor || graphBackgroundColor === 'transparent') {
graphBackgroundColor = '#ffffff';
}
const imageBlob = await domToImageByModernScreenshot(canvasDom, {
backgroundColor: graphBackgroundColor
});
await graphInstance.restoreAfterImageGeneration();
这个示例的独特之处
对比数据表明,这个示例的突出点在于它从一开始就专注于曲线路径上的文本标签,并通过一个小型悬浮面板暴露出多项可读性控制。与 line-text-position 相比,它对方向对比涉及较少,但在固定的从左到右树结构上,更深入地展示了始终启用的曲线路径文本,包括 placeText、textAnchor、连接点切换以及最大长度调节。
它也不同于附近的若干连线表现示例,例如 custom-line-style、line-style2 和 custom-line-animation。那些示例更偏向于 CSS 类族、选中连线强调或运动预设;而这个示例则在视觉上保持内置渲染器的朴素外观,把几何与标签 options 作为主要教学面。最有辨识度的实现模式,是通过全图范围的 getLines() 加 updateLine() 遍历,对已经渲染出来的曲线边路径标签位置进行重写。
这种模式还能用在哪里
这种模式非常适合那些关系文本本身具有业务含义、并且必须在曲线连接器上保持可读的系统。例如带规则描述的审批树、带说明性边文本的依赖图、归属关系图、流程分支,以及边上的短语与节点标签同样重要的知识图谱。
它也可以作为设计评审沙盒。团队可以替换成自己的代表性树数据,保留同样的控制界面,快速判断哪一种曲线族、锚点策略、截断长度和文本偏移量最适合让长边标签保持可读,然后再去构建更复杂的自定义渲染。