$npx -y skills add antvis/chart-visualization-skills --skill antv-x6-editorX6 图编辑引擎代码生成技能,支持流程图、DAG、ER图、血缘图等图编辑场景的节点/边/端口/交互/插件配置
| 1 | # X6 图编辑引擎代码生成技能 |
| 2 | |
| 3 | ## 核心约束(必须遵守) |
| 4 | |
| 5 | <!-- CONSTRAINTS:START --> |
| 6 | |
| 7 | ### X6 3.x 关键约束(强制) |
| 8 | |
| 9 | - **`graph.render()` 不存在**:X6 3.x 中 `new Graph()` / `addNode` / `addEdge` / `fromJSON` 均自动渲染,代码中不得出现 `graph.render()`。 |
| 10 | - **不得声明 `container` 变量**:运行环境会作为函数参数注入 `container`。Graph 初始化只使用字符串字面量 `container: 'container'`,禁止 `const/let/var container = ...`,也禁止 `document.getElementById('container')`。 |
| 11 | - **使用插件方法前必须先 `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`。未注册插件时对应方法不存在。 |
| 12 | - **自定义 shape 必须先注册再使用**:`Graph.registerNode(name, def)` / `Graph.registerEdge(name, def)` / `Shape.HTML.register({ shape, ... })` 必须在首次 `addNode / addEdge` 之前完成。 |
| 13 | - **`@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'] }`。 |
| 14 | - **节点/边动画使用 `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`),并非独立方法。示例: |
| 15 | ```javascript |
| 16 | // 通用动画 |
| 17 | node.animate( |
| 18 | { fill: ['#fff', '#1890ff'], transform: ['scale(1)', 'scale(1.2)'] }, |
| 19 | { duration: 500, iterations: 1, fill: 'forwards' }, |
| 20 | ); |
| 21 | // 仅平移过渡 |
| 22 | node.translate(120, 0, { transition: { duration: 500, easing: 'ease-in-out' } }); |
| 23 | ``` |
| 24 | 多步属性变更可用 `graph.startBatch('animate'); cell.attr(...); graph.stopBatch('animate');` 包装。 |
| 25 | |
| 26 | ### 初始化规范 |
| 27 | - `container` 参数必填,**必须使用字符串形式** `container: 'container'`,运行时环境会自动解析为 DOM 元素 |
| 28 | - **必须设置背景色**:`background: { color: '#F2F7FA' }`,所有画布都需要统一的浅蓝灰色背景 |
| 29 | - **不要添加 `grid` 配置**,除非用户明确要求显示网格 |
| 30 | - **不要设置 `width` / `height`**,除非用户明确指定画布尺寸;画布默认自适应容器大小 |
| 31 | - 导入方式:`import { Graph } from '@antv/x6'`,**仅导入实际使用到的类** |
| 32 | - **禁止**无条件导入 `Shape`:仅在使用 `Shape.HTML.register()` 等 Shape 静态方法时才导入 `Shape` |
| 33 | - 插件从 `'@antv/x6'` 直接导入,如 `import { Graph, Selection, History } from '@antv/x6'` |
| 34 | - **禁止**使用 `@antv/x6-plugin-xxx` 独立包导入(已废弃) |
| 35 | - 标准初始化模板: |
| 36 | ```javascript |
| 37 | import { Graph } from '@antv/x6'; |
| 38 | const graph = new Graph({ |
| 39 | container: 'container', |
| 40 | background: { color: '#F2F7FA' }, |
| 41 | }); |
| 42 | ``` |
| 43 | |
| 44 | ### 节点操作规范 |
| 45 | - **优先使用 `graph.addNode()`** 逐个添加节点,而非 `graph.fromJSON()` 批量导入(除非用户明确要求批量加载数据) |
| 46 | - 内置 shape:`'rect'`、`'circle'`、`'ellipse'`、`'polygon'`、`'polyline'`、`'path'`、`'text'`、`'text-block'`、`'image'`、`'html'` |
| 47 | - 节点样式通过 `attrs` 配置,遵循 SVG 属性命名 |
| 48 | - 节点位置通过 `x`、`y` 设置(左上角坐标),尺寸通过 `width`、`height` 设置 |
| 49 | - **默认节点样式**(除非用户指定其他样式,所有节点统一使用此默认样式): |
| 50 | ```javascript |
| 51 | attrs: { |
| 52 | body: { stroke: '#8f8f8f', strokeWidth: 1, fill: '#fff', rx: 6, ry: 6 }, |
| 53 | } |
| 54 | ``` |
| 55 | - **禁止**在 attrs 中使用 CSS 属性名(如 `background-color`),必须用 SVG 属性(如 `fill`) |
| 56 | |
| 57 | ### 边操作规范 |
| 58 | - 使用 `graph.addEdge({ source, target, ... })` 添加边 |
| 59 | - `source`/`target` 可以是:节点实例、节点 ID 字符串、`{ cell: node, port: 'portId' }` 对象、坐标 `{ x, y }` |
| 60 | - 边样式:`attrs: { line: { stroke, strokeWidth, strokeDasharray, targetMarker, sourceMarker } }` |
| 61 | - **默认边样式**(除非用户指定其他样式):`attrs: { line: { stroke: '#8f8f8f', strokeWidth: 1 } }` |
| 62 | - 箭头:`targetMarker: 'classic'`(经典箭头)、`'block'`、`'circle'`、`'diamond'` |
| 63 | - 路由器:`router: 'orth'`(正交)、`'manhattan'`、`'metro'`、`'er'` |
| 64 | - 连接器:`connector: 'rounded'`(圆角)、`'smooth'`(贝塞尔曲线)、`'jumpover'` |
| 65 | |
| 66 | ### 连接桩(Ports)规范 |
| 67 | - 连接桩定义在节点配置的 `ports` 字段中 |
| 68 | - 端口组:`ports: { groups: { groupName: { position, attrs, ... } }, items: [{ id, group }] }` |
| 69 | - position 取值:`'top'`、`'bottom'`、`'left'`、`'right'` |
| 70 | - 端口是连线的锚点,设置 `attrs: { circle: { magnet: true } }` 允许从端口拖出连线 |
| 71 | - **必须设置 `magnet: true`** 才能从该端口发起或接收连线 |
| 72 | |
| 73 | ### 交互配置规范 |
| 74 | - 连线交互在 Graph 配置中通过 `connecting` 字段设置 |
| 75 | - `connecting: { allowBlank: false, router: 'orth', connector: 'rounded', createEdge() {...} }` |
| 76 | - 节点移动限制:`translating: { restrict: true }` 或传函数限制区域 |
| 77 | - 嵌入:`embedding: { enabled: true }` 允许节点拖入分组 |
| 78 | |
| 79 | ### 插件使用规范 |
| 80 | - 插件从 `@antv/x6` 导入,通过 `graph.use(new Plugin(options))` 注册 |
| 81 | - 可用插件:`Selection`、`Snapline`、`History`、`Clipboard`、`Keyboard`、`Scroller`、`MiniMap`、`Transform`、`Export`、`Stencil`、`Dnd` |
| 82 | - Selection: `graph.use(new Selection({ enabled: true, rubberband: true }))` |
| 83 | - Snapline: `graph.use(new Snapline({ enabled: true }))` |
| 84 | - History: `graph.use(new History({ enabled: true }))` |
| 85 | - Clipboard: `graph.use(new Clipboard({ enabled: true }))` |
| 86 | - Keyboard: `graph.use(new Keyboard({ enabled: true }))` |
| 87 | - Scroller: `graph.use(new Scroller({ enabled: true }))` |
| 88 | - MiniMap: `graph.use(new MiniMap({ enabled: true, container: minimapContainer }))` |
| 89 | - Transform: `graph.use(new Transform({ resizing: { enabled: true }, rotating: { enabled: true } }))` |
| 90 | - Export: `graph.use(new Export( |