ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

X6 MiniMap 插件实战指南:为图形画布添加可交互的小地图导航

X6 MiniMap 插件实战指南:为图形画布添加可交互的小地图导航 X6 MiniMap 插件实战指南为图形画布添加可交互的小地图导航【免费下载链接】X6 JavaScript diagramming library that uses SVG and HTML for rendering.项目地址: https://gitcode.com/GitHub_Trending/x6/X6MiniMap 是 X6 官方提供的一颗图编辑插件它在主画布之外渲染一个缩略视图让用户通过移动/缩放小地图视口即可快速定位与缩放主画布非常适合大图、长流程编辑场景。阅读本文后你将掌握 MiniMap 的接入方式、全部配置项含义以及它在源码层的工作机制内部 Graph 复用模型、视口比例换算、与 Scroller 的联动并能直接复刻官方示例中的简单视图/详细视图切换能力。MiniMap 是什么MiniMap小地图插件为Graph实例提供一块独立的缩略图区域它把当前画布中的所有节点、边渲染到一个更小的内部 Graph 中并在其上叠加一个高亮视口viewport矩形用于表示主画布当前可见区域。通过小地图用户可以拖动小地图视口来平移主画布拖动视口右下角的缩放圆柄来缩放主画布在scalable开启时。该功能在 X6 中由 src/plugin/minimap/index.ts 中的MiniMap类实现类名name minimap实现了GraphPlugin接口因此可以通过graph.use(...)安装并由 src/plugin/index.ts 作为MiniMap统一导出。基本使用启用小地图非常简单从antv/x6导入MiniMap实例化后通过graph.use()挂载到图上。官方教程给出的最小示例import { Graph, MiniMap } from antv/x6 const graph new Graph({ background: { color: #F2F7FA, }, }) graph.use( new MiniMap({ container: document.getElementById(minimap), }), )其中container是唯一的必选参数用于指定小地图挂载的 DOM 容器。MiniMap 会在该容器内创建自己的 DOM 结构容器根节点x6-widget-minimap、内部 Graph 区域与视口层无需额外编写样式。交互行为官方演示演示源码展示了小地图的两类核心交互移动小地图视口来移动画布鼠标按下视口区域并拖拽时主画布会同步平移若安装了 Scroller 插件则移动的是滚动容器的滚动位置。缩放小地图视口来缩放画布视口右下角有一个圆形缩放手柄拖动它即可连续缩放主画布缩放范围由minScale与maxScale约束。在源码中这两类交互由startAction→doAction→stopAction这套事件流完成见 src/plugin/minimap/index.tsmousedown/touchstart触发startAction根据事件目标是视口还是缩放手柄将action标记为panning或zooming并记录初始坐标、滚动位置、缩放值与视口几何信息之后的mousemove/touchmove进入doActionpanning分支根据鼠标位移换算成主画布的平移量或滚动容器的scrollLeft/scrollTopzooming分支通过requestAnimationFrame按位移增量调用sourceGraph.zoom(delta, { absolute: true, minScale, maxScale })mouseup/touchend触发stopAction解绑文档级事件并结束本次操作。另外在小地图空白区域内部 Graph 区域直接点击会触发scrollTo将主画布中心移动到对应位置src/plugin/minimap/index.ts。配置选项MiniMap 支持以下配置项下表完整来自官方文档并已对照 src/plugin/minimap/type.ts 与 src/plugin/minimap/index.ts 中的DefaultOptions进行核实属性名类型默认值必选描述containerHTMLElement-✓挂载小地图的容器widthnumber300小地图的宽度heightnumber200小地图的高度paddingnumber10小地图容器的 padding 边距scalablebooleantrue是否启用缩放false 时隐藏缩放手柄minScalenumber0.01最小缩放比例maxScalenumber16最大缩放比例graphOptionsGraph.Options{}小地图内部 Graph 的选项createGraph(options: Graph.Options) Graphoptions new Graph(options)自定义创建小地图内部 Graph 的方法各选项的实际作用container必填小地图挂载的容器源码中通过this.options.container.appendChild(this.container)插入width/height/padding决定小地图根容器的尺寸与内边距同时参与视口比例计算maxWidth width - 2 * paddingmaxHeight height - 2 * padding见updatePapersrc/plugin/minimap/index.tsscalable为true时才会创建视口右下角的缩放圆柄zoomHandlesrc/plugin/minimap/index.tsminScale/maxScale在doAction的zooming分支中作为graph.zoom(..., { minScale, maxScale })的参数传入用于限制缩放范围graphOptions透传给内部小地图 Graph 的选项见下文内部实现createGraph默认是options new Graph(options)可替换为自定义 Graph 工厂方法如接入自定义子类。内部实现小地图如何工作了解实现细节有助于在复杂场景下正确使用 MiniMap。以下是 src/plugin/minimap/index.ts 的核心机制内部 Graph 与模型共享MiniMap在初始化时会创建一个内部目标 GraphtargetGraph其关键点是与源 Graph 共享同一个 modelmodel: this.sourceGraph.model因此主画布上的任何增删改都会自动反映在小地图中。同时内部 Graph 会强制关闭大部分交互与辅助能力见 src/plugin/minimap/index.tsconst targetGraphOptions: Options { ...this.options.graphOptions, container: graphContainer, model: this.sourceGraph.model, interacting: false, grid: false, background: false, embedding: false, panning: false, }视口比例换算updatePaper会根据源画布与容器的尺寸计算缩放比例ratio Math.min(maxWidth / width, maxHeight / height)即在小地图可用区域内等比放下整张画布随后对内部 Graph 执行resize、translate与scale有 Scroller 时直接scale(ratio, ratio)否则zoomToFit()并在源画布resize时同步更新。这也解释了为什么小地图始终能看到整张图的缩略全貌。事件联动startListeningsrc/plugin/minimap/index.ts按是否安装 Scroller 插件区分了监听策略安装了 Scroller直接监听滚动容器的scroll事件来更新视口位置未安装 Scroller监听源 Graph 的translate、scale事件以及model:updated事件模型更新时对内部 Graph 执行zoomToFit。视口位置的更新updateViewport使用了FunctionExt.debounce(..., 0)防抖避免高频事件导致布局抖动并通过计算源画布可见区域在小地图坐标系中的几何信息top/left/width/height来设置视口 div 的 CSS。视觉样式小地图的外观由 src/plugin/minimap/index.less运行时通过CssLoader.ensure(minimap, content)注入控制关键样式包括根容器x6-widget-minimapoverflow: hidden、居中显示、白色背景视口x6-widget-minimap-viewport2px solid #31d0c6青绿色边框、cursor: move并通过margin: -2px 0 0 -2px抵消边框对外部布局的影响缩放手柄x6-widget-minimap-viewport-zoom12×12 的白色圆形圆柄位于视口右下角cursor: nwse-resize。进阶自定义小地图视图简单视图官方演示还展示了小地图的高级用法通过graphOptions.createCellView自定义内部 Graph 对单元格的渲染方式实现简单视图 / 详细视图切换site/src/tutorial/plugins/minimap/index.tsx。this.graph.disposePlugins(minimap) // 先销毁已有小地图 this.graph.use( new MiniMap({ container: this.minimapContainer, width: 200, height: 160, padding: 10, graphOptions: { createCellView(cell) { // 返回三种类型数据 // 1. null: 不渲染该单元格 // 2. undefined: 使用 X6 默认渲染方式 // 3. CellView: 自定义渲染 if (cell.isEdge()) { return null // 不渲染边小地图更干净 } if (cell.isNode()) { return SimpleNodeView // 自定义节点视图 } }, }, }), )配套的SimpleNodeViewsite/src/tutorial/plugins/minimap/simple-view.tsx继承自NodeView只渲染一个rect并以灰色填充从而获得更扁平的缩略效果export class SimpleNodeView extends NodeView { protected renderMarkup() { return this.renderJSONMarkup({ tagName: rect, selector: body, }) } update() { super.update({ body: { refWidth: 100%, refHeight: 100%, fill: #8f8f8f }, }) } }这种简单视图在节点数量极大的场景下能显著提升小地图的渲染与交互性能。插件生命周期与 APIMiniMap 作为标准 Graph 插件支持完整的生命周期管理实现在 src/graph/graph.tsgraph.use(new MiniMap({ ... }))安装插件等价于调用plugin.init(graph, ...options)graph.getPlugin(minimap)获取 MiniMap 实例注意插件名固定为minimapgraph.disposePlugins(minimap)销毁插件会调用MiniMap.dispose()依次执行remove()内部会stopListening()并targetGraph.dispose(false)与CssLoader.clean(minimap)src/plugin/minimap/index.ts。在官方演示中简单视图/详细视图切换正是通过disposePlugins(minimap)后重新use(new MiniMap(...))实现的这是动态调整小地图渲染策略的推荐做法。测试与验证仓库内置了 MiniMap 的完整测试tests/plugin/minimap.spec.ts覆盖三类典型场景基础场景安装 MiniMap 后添加带端口的节点验证实例类型与 DOM 快照minimap-1.html/minimap-2.html并验证addClass/removeClass方法配合 Scroller同时安装Transform与Scroller设置滚动位置、平移与缩放graph.scale(0.1, 0.2)后校验快照minimap-scroller.html仅配合 Transform不安装 Scroller仅做translate与scale校验快照minimap-transform.html。这些测试印证了 MiniMap 在有 Scroller / 无 Scroller两种布局模式下都能正确同步画布状态可以作为你集成小地图时的行为基准。完整可运行示例结合官方演示site/src/tutorial/plugins/minimap/index.tsx一个同时使用 Scroller 与 MiniMap 的完整示例import { Graph, MiniMap, Scroller } from antv/x6 const graph new Graph({ container: document.getElementById(container), width: 600, height: 320, panning: false, background: { color: #F2F7FA }, }) // 先启用滚动容器让主画布可平移、可滚动 graph.use( new Scroller({ enabled: true, pageVisible: true, pageBreak: false, pannable: true, }), ) // 再挂载小地图 graph.use( new MiniMap({ container: document.getElementById(minimap), width: 200, height: 160, padding: 10, }), ) // 添加节点与边 graph.addNode({ x: 200, y: 100, width: 100, height: 40, label: Rect, attrs: { body: { stroke: #8f8f8f, strokeWidth: 1, fill: #fff, rx: 6, ry: 6 } }, }) const source graph.addNode({ x: 32, y: 32, width: 100, height: 40, label: Hello, attrs: { body: { stroke: #8f8f8f, strokeWidth: 1, fill: #fff, rx: 6, ry: 6 } }, }) const target graph.addNode({ shape: circle, x: 160, y: 180, width: 60, height: 60, label: World, attrs: { body: { stroke: #8f8f8f, strokeWidth: 1, fill: #fff } }, }) graph.addEdge({ source, target, attrs: { line: { stroke: #8f8f8f, strokeWidth: 1 } }, })运行后即可体验拖动小地图视口平移画布拖动视口右下角圆柄缩放画布点击小地图任意位置将主画布中心定位到该处。建议在此基础上按需组合width/height/padding、minScale/maxScale与graphOptions.createCellView为大图编辑场景打造流畅的导航体验。【免费下载链接】X6 JavaScript diagramming library that uses SVG and HTML for rendering.项目地址: https://gitcode.com/GitHub_Trending/x6/X6创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表