恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
JointJS 链接标签编辑工具实战指南:RotateLabel 与 Button 的配置、原理与运行方法
首页
资讯中心
/
JointJS 链接标签编辑工具实战指南:RotateLabel 与 Button 的配置、原理与运行方法
JointJS 链接标签编辑工具实战指南:RotateLabel 与 Button 的配置、原理与运行方法
发布时间:2026/10/6 15:48:14
前端UI组件【免费下载链接】jointA proven SVG-based JavaScript diagramming library powering exceptional UIs项目地址https://gitcode.com/gh_mirrors/jo/joint点击查看免费下载本指南基于joint/demo-link-labels-tsTypeScript 版链接标签演示展开系统讲解 JointJS 中两类链接Link标签编辑工具**RotateLabel旋转标签**与Button增删标签按钮。你将掌握工具与dia.ToolsView的挂载方式、每个可配置参数的语义与默认值、通过interactive.labelMove、snapLabels启用标签交互的方法以及源码级的运行原理RotateLabel.mjs、Button.mjs、Link.mjs并学会从零构建、启动该示例。示例概览它演示了什么examples/link-labels-ts是一个 TypeScript Webpack 的 JointJS 演示项目核心代码集中在 src/index.ts对应 index.html 中 id 为paper的挂载容器。它包含两个独立示例示例一旋转标签—— 在一条连线上放置 3 个自定义标签每个标签通过linkTools.RotateLabel提供独立的旋转手柄其中第 2 个标签的手柄还演示了自定义颜色与缩放。示例二增删标签—— 通过linkTools.Button在连线中点放置加号 / 减号按钮根据当前连线是否已有标签动态切换可见性点击后分别执行appendLabel()与removeLabel()。环境准备与运行步骤构建依赖Yarn Workspacespackage.jsonpackage.json声明该示例依赖joint/core: workspace:^说明它是 monorepo 工作区的一部分。README 明确要求使用 Yarn 运行且必须先构建根目录的 JointJS 核心包。在仓库根目录依次执行yarn install yarn run build首次yarn install会根据根目录的 yarn.lock 安装全部 workspace 依赖yarn run build用于构建joint/core等本地包确保示例能链接到实际构建产物。启动演示构建完成后进入本示例目录并启动开发服务器cd examples/link-labels-ts yarn startstart脚本在 package.json 中定义为webpack-dev-server编译后的 bundle 输出为dist/bundle.js见 index.html 中的script srcdist/bundle.js。浏览器打开开发服务器地址即可看到两个示例画面。初始化开启标签交互的 Paper 配置示例首先创建dia.Graph与dia.Paper其中与标签编辑相关的关键配置如下const paper new dia.Paper({ el: document.getElementById(paper), width: 800, height: 900, overflow: true, model: graph, cellViewNamespace: shapes, interactive: { labelMove: true // 允许直接拖拽移动标签 }, snapLabels: true, // 拖拽标签时吸附到网格 gridSize: 10, // 吸附网格尺寸 async: true, });interactive.labelMove: true开启标签的拖拽移动能力用户可以直接拖动标签沿连线改变distance距连线起点的比例/长度位置。snapLabels: true与gridSize: 10标签拖拽时以 10 像素网格吸附对齐。async: true启用异步渲染适合大量元素场景。另外示例还用dia.Graph({}, { cellNamespace: shapes })指定了元素命名空间并将cellViewNamespace设置为shapes保证标准形状可被正确解析。示例一用 RotateLabel 旋转连线标签自定义标签定义连线l1是shapes.standard.Link通过labels数组一次性声明 3 个标签。每个标签使用util.svg模板字符串自定义 markup包含labelPath图形路径与labelCircle装饰圆两个 selector并配合position定位labels: [{ markup: util.svg/* xml */ path selectorlabelPath / circle selectorlabelCircle / , attrs: { labelPath: { fill: none, stroke: #333, strokeWidth: 4, strokeLinecap: round, strokeLinejoin: round, d: M 0 0 V -100 M -20 -100 v 20 H 20 v -20 }, labelCircle: { fill: #333, stroke: #FFF, r: 3 } }, position: { distance: 0.5, args: { keepGradient: true } } }, { // 第 2 个标签distance 0.8、虚线路径 position: { distance: 0.8, args: { keepGradient: true } } }, { // 第 3 个标签distance 0.2、keepGradient: false position: { distance: 0.2, args: { keepGradient: false } } }]三个标签通过不同的position.distance0.5、0.8、0.2分布在连线不同位置并用args.keepGradient控制标签是否随连线切线方向保持倾斜。第 3 个标签显式设置keepGradient: false用于对比标签不跟随连线斜率的效果。挂载 RotateLabel 工具工具通过视图的addTools()挂载到dia.ToolsViewl1.findView(paper).addTools(new dia.ToolsView({ tools: [ new linkTools.RotateLabel({ labelIndex: 0, offset: -60 }), new linkTools.RotateLabel({ labelIndex: 1, offset: -125, buttonColor: #fff, iconColor: #333, outlineColor: #333, scale: 1.5, }), new linkTools.RotateLabel({ labelIndex: 2, offset: -115 }) ] }));RotateLabel 参数说明RotateLabel定义在 packages/joint-core/src/linkTools/RotateLabel.mjs继承自cellTools.Control。各参数语义如下参数类型/默认值说明labelIndexnumber默认0指定操作哪条标签对应labels数组下标实现见getLabelIndex()RotateLabel.mjsoffsetnumber 或{x, y}默认0手柄相对标签位置的偏移示例中用负数将手柄抬离标签本身数值型时{x:0, y:offset}见getPosition()RotateLabel.mjsbuttonColor默认#333手柄圆形按钮的填充色iconColor默认#fff手柄旋转箭头图标的颜色outlineColor默认#fff圆形按钮描边颜色scalenumber默认null手柄整体缩放倍数示例中第 2 个手柄设为1.5颜色与图标模板在children()中定义RotateLabel.mjs默认手柄是一个半径 10、填充buttonColor、描边outlineColor的圆加上一个弧形箭头路径与箭头尖。旋转原理从拖拽到angle属性拖动旋转手柄时setPosition()会以标签位置为原点计算拖拽方向与水平轴的夹角并把结果写入模型属性const angle 90 - position.theta(coordinates); model.prop([labels, index, position, angle], angle);即最终持久化到labels[i].position.angleRotateLabel.mjs。resetPosition()则把angle重置为 0。此外getPosition()中若标签args.keepGradient为真会通过view.getTangentAtRatio()获取标签处连线切线方向将标签自身角度叠加到连线斜率上保证手柄贴合标签RotateLabel.mjs。computeVisibility()被重写当对应下标不存在标签时手柄自动隐藏RotateLabel.mjs防止出现悬空工具。示例二用 Button 按钮增删标签挂载两个互斥按钮第二个示例创建连线l2后同样通过addTools()挂载两个linkTools.Buttonl2.findView(paper).addTools(new dia.ToolsView({ tools: [ new linkTools.Button({ attributes: { cursor: pointer }, markup: util.svg/* xml */ circle r10 fill#266DD3 / path dM -5 0 5 0 M 0 -5 0 5 stroke#fff stroke-width2 / , distance: 50%, visibility: (view) !view.model.hasLabels(), action: (_evt, view) { view.model.appendLabel({ /* 新增标签的 markup 与 attrs */ }); }, }), new linkTools.Button({ attributes: { cursor: pointer }, markup: util.svg/* xml */ circle r10 fill#ED2637 / path dM -5 0 5 0 stroke#fff stroke-width2 / , distance: 50%, offset: -30, visibility: (view) view.model.hasLabels(), action: (_evt, view) { view.model.removeLabel(0); } }) ] }));Button 参数说明Button定义在 packages/joint-core/src/cellTools/Button.mjs核心参数参数类型/默认值说明markupSVG 字符串按钮外观模板可用selector声明子元素示例用蓝色圆形 加号路径、红色圆形 减号路径distancenumber 或百分比字符串默认0按钮在连线上的位置。50%表示连线中点数字表示从起点起的长度。底层调用getTangentAtRatio()/getTangentAtLength()求切线点Button.mjsoffsetnumber默认0沿连线切线法向垂直方向的位移示例中减号按钮offset: -30让两个按钮错开显示scalenumber默认null按钮缩放倍数rotateboolean默认false按钮是否随连线切线方向旋转visibility函数动态显隐函数返回true才显示ToolView.mjs。示例用hasLabels()实现加号/减号互斥action函数点击回调签名(evt, view, tool)由onPointerDown触发Button.mjs。示例中view.model即连线模型用到的 Link 标签 API示例二的核心动作依赖dia.Link的标签 API全部位于 packages/joint-core/src/dia/Link.mjshasLabels()判断labels属性是否为非空数组Link.mjs。appendLabel(label, opt)向标签数组末尾追加标签内部等价于insertLabel(-1, ...)Link.mjs。removeLabel(idx, opt)按索引删除标签Link.mjs。读取单个标签用label(idx)读取全部用labels()Link.mjs。新增标签同样使用util.svg自定义 markup矩形labelBody 文本labelText并通过attrs中基于引用文本的ref: labelText与calc(...)表达式自动计算矩形尺寸例如width: calc(w 10)、x: calc(x - 5)使矩形背景刚好包裹文字无需手动量算尺寸。工具可用性机制补充dia.ToolsView负责管理一组工具视图。除显式传入tools数组外也可在Paper上配置defaultLinkTools等默认工具让每条连线自动获得工具。工具显隐统一由ToolView.computeVisibility()决定先判断visibility选项函数则调用并取真值再执行各工具自身的附加逻辑ToolView.mjs。这也解释了示例中有标签时显示减号、无标签时显示加号的行为。小结与进一步探索RotateLabel用于让用户直观旋转连线标签核心是labelIndex指定标签、offset手柄偏移与外观参数旋转结果写入labels[i].position.angle。Button是通用连线/元素按钮通过distance定位、markup定制外观、visibility动态显隐、action绑定行为可组合出增删标签、增删顶点等交互。两者都通过view.addTools(new dia.ToolsView({ tools: [...] }))挂载。若需深入实现细节可继续阅读工具源码RotateLabel.mjs、Button.mjs、Control.mjs、ToolView.mjs标签 APILink.mjs示例入口与构建配置src/index.ts、webpack.config.js、package.json更多标签相关演示可参考 link-labels-ts 目录 及同仓库其他标签示例如 element-port-and-link-label-markup-js运行环境方面本示例为 TypeScript Webpack 项目需 Node.js项目通过 Volta 声明 node 22.14.0 / yarn 4.18.0依赖joint/core工作区包务必先执行根目录的yarn install与yarn run build。赞分享前端UI组件【免费下载链接】jointA proven SVG-based JavaScript diagramming library powering exceptional UIs项目地址https://gitcode.com/gh_mirrors/jo/joint点击查看免费下载相关推荐VitePress 默认主题 Edit Link编辑链接完整指南配置、原理与实战VitePress 默认主题 Edit Link编辑链接完整指南配置、原理与实战 Edit Link 是 VitePress 默认主题内置的一项文档站点能前端文档VitePress 编辑链接Edit Link功能完整指南配置、自定义与实现原理VitePress 编辑链接Edit Link功能完整指南配置、自定义与实现原理 导读 本指南围绕 VitePress 默认主题的 Edit Link前端文档Omarchy 开发工具链完全指南编辑器、运行时环境、Docker 与 GitHub CLI 的安装与配置Omarchy 开发工具链完全指南编辑器、运行时环境、Docker 与 GitHub CLI 的安装与配置 本指南以 manual/18 developmen操作系统开发工具AI 应用CLI上一篇Windows 11系统精简革命Tiny11Builder技术架构深度解析下一篇obs-vkcapture开发指南如何为插件贡献代码与添加新功能创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考