可视化官方
Skill 文件
Skill
references
SKILL.md
SKILL.md
| name | antv-x6-editor |
|---|---|
| title | AntV X6 图编辑 |
| description | X6 图编辑引擎代码生成技能,支持流程图、DAG、ER图、血缘图等图编辑场景的节点/边/端口/交互/插件配置 |
| version | 3.x |
X6 图编辑引擎代码生成技能
核心约束(必须遵守)
<!-- CONSTRAINTS:START -->
X6 3.x 关键约束(强制)
graph.render()不存在:X6 3.x 中new Graph()/addNode/addEdge/fromJSON均自动渲染,代码中不得出现graph.render()。- 不得声明
container变量:运行环境会作为函数参数注入container。Graph 初始化只使用字符串字面量container: 'container',禁止const/let/var container = ...,也禁止document.getElementById('container')。 - 使用插件方法前必须先
graph.use(new Plugin(...))注册对应插件:graph.toPNG / toSVG / toJPEG依赖Export;graph.select / unselect依赖Selection;graph.undo / redo依赖History;graph.copy / paste / cut依赖Clipboard;graph.bindKey依赖Keyboard。未注册插件时对应方法不存在。 - 自定义 shape 必须先注册再使用:
Graph.registerNode(name, def)/Graph.registerEdge(name, def)/Shape.HTML.register({ shape, ... })必须在首次addNode / addEdge之前完成。 @antv/x6仅导出 11 个插件类:Clipboard、Dnd、Export、History、Keyboard、MiniMap、Scroller、Selection、Snapline、Stencil、Transform。mousewheel、embedding、panning、connecting、translating、interacting、background、grid是new Graph()的构造选项,不是插件,不得 import 同名类、不得graph.use(new XxxClass())。例:滚轮缩放写在 Graph 构造中mousewheel: { enabled: true, zoomAtMousePosition: true, modifiers: ['ctrl'] }。- 节点/边动画使用
cell.animate(keyframes, options)(Web Animations API 风格):X6 3.x 没有node.transition(path, target, options)方法。源码中transition仅作为node.translate(tx, ty, { transition })/node.rotate(deg, { transition })的 options 字段存在(boolean | KeyframeEffectOptions),并非独立方法。示例: 多步属性变更可用graph.startBatch('animate'); cell.attr(...); graph.stopBatch('animate');包装。
初始化规范
container参数必填,必须使用字符串形式container: 'container',运行时环境会自动解析为 DOM 元素- 必须设置背景色:
background: { color: '#F2F7FA' },所有画布都需要统一的浅蓝灰色背景 - 不要添加
grid配置,除非用户明确要求显示网格 - 不要设置
width/height,除非用户明确指定画布尺寸;画布默认自适应容器大小 - 导入方式:
import { Graph } from '@antv/x6',仅导入实际使用到的类 - 禁止无条件导入
Shape:仅在使用Shape.HTML.register()等 Shape 静态方法时才导入Shape - 插件从
'@antv/x6'直接导入,如import { Graph, Selection, History } from '@antv/x6' - 禁止使用
@antv/x6-plugin-xxx独立包导入(已废弃) - 标准初始化模板:
节点操作规范
- 优先使用
graph.addNode()逐个添加节点,而非graph.fromJSON()批量导入(除非用户明确要求批量加载数据) - 内置 shape:
'rect'、'circle'、'ellipse'、'polygon'、'polyline'、'path'、'text'、'text-block'、'image'、'html' - 节点样式通过
attrs配置,遵循 SVG 属性命名 - 节点位置通过
x、y设置(左上角坐标),尺寸通过width、height设置 - 默认节点样式(除非用户指定其他样式,所有节点统一使用此默认样式):
- 禁止在 attrs 中使用 CSS 属性名(如
background-color),必须用 SVG 属性(如fill)
边操作规范
- 使用
graph.addEdge({ source, target, ... })添加边 source/target可以是:节点实例、节点 ID 字符串、{ cell: node, port: 'portId' }对象、坐标{ x, y }- 边样式:
attrs: { line: { stroke, strokeWidth, strokeDasharray, targetMarker, sourceMarker } } - 默认边样式(除非用户指定其他样式):
attrs: { line: { stroke: '#8f8f8f', strokeWidth: 1 } } - 箭头:
targetMarker: 'classic'(经典箭头)、'block'、'circle'、'diamond' - 路由器:
router: 'orth'(正交)、'manhattan'、'metro'、'er' - 连接器:
connector: 'rounded'(圆角)、'smooth'(贝塞尔曲线)、'jumpover'
连接桩(Ports)规范
- 连接桩定义在节点配置的
ports字段中 - 端口组:
ports: { groups: { groupName: { position, attrs, ... } }, items: [{ id, group }] } - position 取值:
'top'、'bottom'、'left'、'right' - 端口是连线的锚点,设置
attrs: { circle: { magnet: true } }允许从端口拖出连线 - 必须设置
magnet: true才能从该端口发起或接收连线
交互配置规范
- 连线交互在 Graph 配置中通过
connecting字段设置 connecting: { allowBlank: false, router: 'orth', connector: 'rounded', createEdge() {...} }- 节点移动限制:
translating: { restrict: true }或传函数限制区域 - 嵌入:
embedding: { enabled: true }允许节点拖入分组
插件使用规范
- 插件从
@antv/x6导入,通过graph.use(new Plugin(options))注册 - 可用插件:
Selection、Snapline、History、Clipboard、Keyboard、Scroller、MiniMap、Transform、Export、Stencil、Dnd - Selection:
graph.use(new Selection({ enabled: true, rubberband: true })) - Snapline:
graph.use(new Snapline({ enabled: true })) - History:
graph.use(new History({ enabled: true })) - Clipboard:
graph.use(new Clipboard({ enabled: true })) - Keyboard:
graph.use(new Keyboard({ enabled: true })) - Scroller:
graph.use(new Scroller({ enabled: true })) - MiniMap:
graph.use(new MiniMap({ enabled: true, container: minimapContainer })) - Transform:
graph.use(new Transform({ resizing: { enabled: true }, rotating: { enabled: true } })) - Export:
graph.use(new Export())(注册后可调用graph.toPNG()/graph.toSVG()) - 动态控制:
graph.enablePlugins('selection')/graph.disablePlugins('selection') - 禁止在 Graph 构造函数中直接传入
selecting、snapline等选项(3.x 不支持)
序列化规范
- 导出:
const data = graph.toJSON()返回{ cells: [...] }对象 - 导入:
graph.fromJSON(data)加载整个图数据 - 清空:
graph.clearCells()清除所有元素 - 禁止手动构造 cells 数组中的内部字段(如
zIndex、parent),应通过 API 操作
事件规范
- 节点事件:
graph.on('node:click', ({ node, e }) => {...}) - 边事件:
graph.on('edge:click', ({ edge, e }) => {...}) - 画布事件:
graph.on('blank:click', ({ e }) => {...}) - 变更事件:
graph.on('node:moved', ({ node }) => {...}) - 事件回调参数是对象,不是位置参数:
({ node, e })而非(node, e)
导入规范
- 所有使用到的类都必须出现在 import 语句中:如使用
Selection,必须import { Graph, Selection } from '@antv/x6' - 禁止使用
Graph.Selection、Graph.Keyboard等命名空间写法(不存在) - 禁止使用未导入的类:
new Selection(...)必须对应import { Selection } from '@antv/x6' - import 自检清单(强制,输出代码前必须逐行核对):对代码中每一个
new XxxYyy(...)调用,XxxYyy必须字面出现在第一行import { ..., XxxYyy } from '@antv/x6'的花括号内。常见漏写:Selection、Keyboard、History、Clipboard、Snapline、MiniMap、Transform、Scroller、Export、Stencil、Dnd、Shape(用到Shape.HTML.register时)。 - import 漏写为何会变成
Illegal constructor等运行时错:评测/Playground 环境用 UMD 构建(window.X6)执行代码,而不是真正的 ES Module。Selection、Keyboard等会根据 import 列表从window.X6解构出来;如果 import 漏写,标识符Selection会回退到window.Selection(浏览器原生 Selection 接口),new Selection({...})会抛Failed to construct 'Selection': Illegal constructor。Keyboard/History等同理(会is not a constructor)。 - import 漏写的标准修法:把所有用到的插件类合并到同一行
import { Graph, Selection, Keyboard, History, ... } from '@antv/x6';,不要分多行 import,也不要遗漏。
节点工具(Tools)规范
- 添加工具:
node.addTools([{ name: 'button-remove', args: { x: 0, y: 0 } }])或graph.addTools(node, [...]) - 移除工具:
node.removeTools()或graph.removeTools(node) - 检查工具:
node.hasTools() - 禁止使用
node.hideTools()/node.showTools()(3.x 不存在此 API) - 悬停显示/隐藏工具的正确方式:
渐变色规范
- X6 attrs 中
fill支持渐变对象语法,禁止直接操作graph.defs或document.createElementNS创建 SVG 渐变 - 线性渐变正确写法:
代码输出规范
- 必须输出纯 JavaScript,禁止使用 TypeScript 语法(如
private、类型注解: string、as类型断言) - HTML 自定义节点使用
Shape.HTML.register({ shape, html, effect })注册自定义 shape,禁止使用class extends Node方式 - 禁止
Graph.registerHTMLComponent(name, factory)—— 这是 X6 2.x 旧 API,3.x 源码已无此方法。所有 HTML 节点统一通过Shape.HTML.register注册(详见references/core/x6-core-html-shape.md) effect数组指定哪些属性变化时触发重新渲染(如['data']);纯静态展示节点不要加 effect- HTML 节点正确写法:
Stencil 插件规范
- Stencil 通过
graph.use(new Stencil({ target: graph, groups: [...] }))注册 - 注册后通过
graph.getPlugin('stencil')获取实例,将stencil.container挂载到 DOM - Stencil 内的节点模板使用
graph.createNode(...)创建(非graph.addNode),再通过stencil.load(nodes, groupName)加载
动态端口规范
- 使用
node.addPort()动态添加端口时,必须在节点初始化时预定义对应的 ports.groups - 如果没有预定义 group,端口无法正确定位,可能导致渲染异常
- 正确写法:
registerNode+addNode的 ports 合并陷阱(强约束):Graph.registerNode(name, { ports: { items: [{ id: 'in1', group: 'in' }] } })之后,如果再graph.addNode({ shape: name, ports: { items: [{ id: 'in1', group: 'in' }] } }),X6 内部Cell构造时ObjectExt.merge(defaults, metadata)会按数组下标合并、node.addPorts走的也是[...current, ...new]简单拼接,不会去重,运行时直接抛Error: Duplicitied port id.。正确做法二选一:- 在
registerNode里只声明ports.groups,把ports.items留给addNode/ 后续node.addPort提供; - 或在
registerNode里完整声明ports.items,addNode时不再传ports.items(如需追加端口,调用node.addPort({ id: '新id', group: 'xxx' }),且新 id 不能与 registry 里已声明的重名)。
- 在
DOM/CSS 操作规范(HTML 节点 / Stencil / 自定义工具)
- HTML 节点
html(node)回调里给 DOM 设样式时,禁止直接写连字符属性:el.style.box-sizing = '...'、el.style.font-size = '...'会被 JS 解析为el.style.box - sizing = ...,抛Invalid left-hand side in assignment。正确写法二选一:- 驼峰:
el.style.boxSizing = 'border-box'、el.style.fontSize = '14px'、el.style.backgroundColor = '#fff'; - 方括号:
el.style['box-sizing'] = 'border-box'、el.style['font-size'] = '14px'; - 多条样式优先用
el.style.cssText = 'box-sizing:border-box;font-size:14px;'或Object.assign(el.style, { boxSizing: 'border-box', fontSize: '14px' })。
- 驼峰:
- 同理,
el.classList.add('...')/el.setAttribute('data-x', '...')是合法 API;禁止el.class = '...'/el['class-name'] = ...。
不存在的 API(禁止使用)
- 禁止
graph.scrollToCell()→ 正确方式:graph.centerCell(cell)滚动并居中到指定 cell - 禁止
graph.highlightCell()/graph.highlightNode()→ 正确方式:通过node.attr('body/stroke', '#f00')或添加 CSS class 实现高亮 - 禁止
Shape.Cylinder/Shape.Diamond等不存在的内置 Shape → 用'rect'+rx/ry或'polygon'自定义 - 禁止
Shape.Edge.define()/Shape.Node.define()→ 正确方式:Graph.registerEdge()/Graph.registerNode() - 禁止
Shape.Group/Shape.Group.define()/new Shape.Group()→ X6 3.x 的Shape命名空间没有Group导出(实际只有Circle / Edge / Ellipse / HTML / Image / Path / Polygon / Polyline / Rect / TextBlock,运行时会报Cannot read properties of undefined (reading 'define'))。父子分组的正确方式:直接graph.addNode({ shape: 'rect', ... })创建一个普通节点作为父节点,再通过parent.addChild(child)/parent.embed(child)建立父子关系;或用Graph.registerNode('my-group', { inherit: 'rect', markup: [...], attrs: {...} })注册一个自定义分组形状再addNode({ shape: 'my-group' })。 - 禁止 把
Embedding当插件 import / new /graph.use(new Embedding(...))→ X6 3.x 没有Embedding插件类(运行时会报Embedding is not a constructor)。节点嵌入是 Graph 构造选项:new Graph({ container, embedding: { enabled: true, findParent: 'bbox', frontOnly: false, validate: ({ child, parent }) => true } })。Hover 高亮通过highlighting.embedding配置,嵌入/解除嵌入事件为node:embedding/node:embedded。 - 禁止
history.batch()→ 正确方式:graph.startBatch('custom'); ...; graph.stopBatch('custom');或graph.batchUpdate(() => { ... }) - 禁止
graph.defs/graph.svgDoc/document.createElementNS('...', 'linearGradient' | 'defs' | 'marker')→ X6 3.x 不暴露graph.defs/graph.svgDoc,运行时会报Cannot read properties of undefined。正确方式:- 节点/边普通
fill渐变:直接用 attrs 中的渐变对象语法(fill: { type: 'linearGradient', stops: [...] }) - 自定义 marker 需要渐变填充:先
const id = graph.defineGradient({ type: 'linearGradient', stops: [{ offset: 0, color: '#f00' }, { offset: 1, color: '#0f0' }] }),再在 marker 对象里写fill: \url(#${id})`` - 自定义 marker / filter 同理使用
graph.defineMarker(options)/graph.defineFilter(options)
- 节点/边普通
渲染输出规范(必须遵守)
- 画布初始化后必须存在至少一个
graph.addNode/graph.addEdge/graph.fromJSON调用,确保画布有可视内容。即使用户 query 只描述了交互(panning / mousewheel / 插件等)配置,也必须自行补 2~3 个示例节点 + 1 条边作为渲染载体,否则视觉验证会被判定为「白屏」。 - 所有节点/边添加完成后,必须在末尾调用
graph.centerContent()(或在画布需要随内容缩放时使用graph.zoomToFit({ padding: 20, maxScale: 1 }))。X6 默认不会自动居中,缺失该调用会导致内容偏向左上角、视觉评分不通过。两者二选一,不可同时调用。 - 多个交互(
panning+mousewheel+Selectionrubberband)同时启用时,必须用modifiers错开触发条件(例如:panning 用'shift',mousewheel 用'ctrl',rubberband 留空)。禁止把'mouseWheel'放进panning.eventTypes同时又启用mousewheel,两者会争抢滚轮事件。
<!-- CONSTRAINTS:END -->
禁止的错误模式
❌ 使用已废弃的独立插件包
❌ 在构造函数中传入插件选项
❌ 混淆 CSS 属性和 SVG 属性
❌ 缺少 container
❌ 连接桩未设置 magnet
❌ 事件回调使用位置参数
基础结构模板
场景选择指南
内置节点类型
路由器与连接器
路由器(Router)— 决定边的路径走向
连接器(Connector)— 决定边的线条样式
插件速查
Ln 1, Col 1MarkdownSpaces: 2
No errors