npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

x6-graph-plugin

v1.0.0

Published

基于 AntV X6 的 Vue 3 图组件库,提供 `X6Graph` 组件。

Readme

x6-graph-plugin

基于 AntV X6 的 Vue 3 图组件库,提供 X6Graph 组件。

本文档整合了以下内容:

  • 快速安装与接入说明
  • X6Graph.vueX6GraphManager.js 的 API
  • 组件实践——基于载荷资源管控系统(商⭐)->进程拓扑模块的 computed 自动更新机制说明

1. 组件概述

X6Graph 是一个 Vue 3 组件,内部封装 X6GraphManager,用于:

  • 初始化 / 销毁 X6 Graph
  • 通过 nodes/edges 数据驱动图内容
  • 输出节点/连线交互事件
  • 在容器尺寸变化时自动重绘并可选自动适配
  • 支持“消息驱动 + computed”自动刷新图

适用于拓扑图、状态图、连线关系图等场景。

2. 开发与构建

npm install
npm run dev
npm run build
npm run build:lib

3. 安装

npm i x6-graph-plugin

宿主项目需要安装 vue(peer 依赖)。

4. 快速使用

4.1 按需引入组件

<template>
  <X6Graph
    :nodes="nodes"
    :edges="edges"
    :graph-options="graphOptions"
    :plugins="plugins"
    :auto-fit="true"
    :fit-options="{ centerX: null, centerY: null, zoom: 0.8 }"
    @nodeClick="onNodeClick"
    @edgeClick="onEdgeClick"
  />
</template>

<script setup>
import { X6Graph } from "x6-graph-plugin";
import "x6-graph-plugin/style.css";

const nodes = [];
const edges = [];
const graphOptions = {};
const plugins = {};

const onNodeClick = (args) => {};
const onEdgeClick = (args) => {};
</script>

4.2 插件方式注册

import { createApp } from "vue";
import X6GraphPlugin from "x6-graph-plugin";
import "x6-graph-plugin/style.css";

const app = createApp(App);
app.use(X6GraphPlugin);

5. X6Graph 组件 API

5.1 Props(必填与默认值)

X6Graph.vue 中所有 props 都是可选;不传会使用默认值。

| 属性名 | 类型 | 必填 | 默认值 | 说明 | |---|---|---|---|---| | graphOptions | Object | 否 | {} | 透传到 X6 Graph 的配置(会与内置默认配置合并) | | plugins | Object | 否 | {} | 插件开关配置:selection/snapline/history/keyboard/transform | | nodes | Array | 否 | [] | 节点配置数组,建议每个节点都提供稳定 id | | edges | Array | 否 | [] | 连线配置数组,强烈建议每条边都提供稳定 id | | autoFit | Boolean | 否 | true | 每次加载数据/尺寸变化后是否自动适配 | | fitOptions | Object | 否 | { centerX: null, centerY: null, zoom: 0.8 } | 缩放适配参数 | | showHint | Boolean | 否 | true | 是否显示左上角提示“按住 Shift 拖动画布,Ctrl+滚轮 缩放” |

graphOptions 在组件层默认是 {},但实际会与 X6GraphManager 的内置默认配置合并。默认项如下:

{
  background: { color: "rgba(10, 22, 44, 0.85)" },
  grid: {
    size: 10,
    visible: true,
    type: "dot",
    args: { color: "#2b3a55", thickness: 1 }
  },
  panning: {
    enabled: true,
    modifiers: "shift"
  },
  mousewheel: {
    enabled: true,
    modifiers: ["ctrl", "meta"],
    minScale: 0.5,
    maxScale: 10
  },
  interacting: {
    nodeMovable: true,
    edgeLabelMovable: true,
    resizing: false
  },
  autoResize: true
}

plugins 的内置默认值如下(组件层默认是 {},最终同样会合并):

{
  selection: true,
  snapline: true,
  history: true,
  keyboard: true,
  transform: true
}

pluginstrue 时的插件内部默认参数

selection: new Selection({ multiple: true, rubberband: true, movable: true })
snapline: new Snapline({ enabled: true, sharp: true })
history: new History()
keyboard: new Keyboard()
transform: new Transform({ rotating: false })

5.2 关键必填项说明(避免误用)

  1. 组件层必填

    • 无强制必填项(都有默认值)。
  2. 业务层强烈建议必填

    • nodes[].id:用于稳定增量更新、删除和回调定位。
    • edges[].id:用于连线差分更新;不传会退化为“清空旧边并重建”。
    • edges[].source/target:创建边时应提供有效连接目标。
  3. fitOptions 使用规则

    • centerXcenterY 都有值时:按 zoom + 中心点定位。
    • 否则:走 zoomToFit({ padding: 20 })
  4. 事件模型

    • 推荐仅使用一种:组件事件(@nodeClick/@edgeClick)或配置回调(onClick)。
    • 两种同时绑定同一逻辑可能重复触发。

5.3 Events(defineEmits

| 事件名 | 参数 | 说明 | |---|---|---| | init | graphManager | 图初始化并首次加载后触发 | | nodeClick | args | 节点点击 | | nodeDblClick | args | 节点双击 | | edgeClick | args | 连线点击 | | graphChange | args | 图变化事件 |

5.4 Expose(通过组件 ref

| 字段/方法 | 说明 | |---|---| | graphManager | X6GraphManager 实例(初始化前为 null) | | loadData() | 手动触发一次 updateGraph({ nodes, edges }) | | handleResize() | 手动触发尺寸重算与可选 autoFit |

推荐通过 @init 获取管理器实例,时机更稳定。

6. 数据结构规范(nodes / edges

6.1 前提说明

节点或边的属性配置,本组件并没有封装,所以相关属性仍是AntV X6原生属性,具体请查看官方文档

https://x6-v2.antv.vision/api/model/node

以下是本组件使用的AntV X6的版本信息

  • "@antv/x6": "^2.18.1",
  • "@antv/x6-plugin-history": "^2.2.4",
  • "@antv/x6-plugin-keyboard": "^2.2.3",
  • "@antv/x6-plugin-scroller": "^2.0.10",
  • "@antv/x6-plugin-selection": "^2.2.2",
  • "@antv/x6-plugin-snapline": "^2.1.7",
  • "@antv/x6-plugin-transform": "^2.1.8"

6.2 节点 nodes[] 常用字段

| 字段名 | 类型 | 说明 | |---|---|---| | id | string \| number | 必填且稳定唯一 | | shape | string | 节点形状 | | x/y | number | 节点位置 | | width/height | number | 节点尺寸 | | attrs | Object | 样式(支持深合并) | | interacting | Object | 交互配置 | | ports | Object | 端口配置 | | onClick | Function | 节点点击回调(配置回调模型) | | onDblClick | Function | 节点双击回调 | | onDoubleClick | Function | 双击回调兼容别名 |

节点默认值(X6GraphManager.createNode

当某个节点字段未传时,会使用以下默认值:

{
  shape: "rect",
  width: 100,
  height: 60,
  attrs: {
    body: {
      rx: 4,
      ry: 4,
      stroke: "#333",
      fill: "#fff"
    },
    label: {
      text: externalNodeId || "",
      fill: "#333",
      fontSize: 14
    }
  },
  interacting: {
    nodeMovable: true,
    edgeLabelMovable: true,
    resizing: false
  }
}

说明:节点 id 在内部会做字符串规范化(例如 1 会转为 "1")。

6.3 连线 edges[] 常用字段

| 字段名 | 类型 | 说明 | |---|---|---| | id | string \| number | 建议必填且稳定唯一 | | source | string \| { cell, port } | 源节点/端口 | | target | string \| { cell, port } | 目标节点/端口 | | router | Object | 路由策略 | | connector | Object | 连接器策略 | | zIndex | number | 层级 | | attrs | Object | 样式(支持深合并) | | labels | Array | 边标签 | | data | Object | 自定义数据 | | onClick | Function | 连线点击回调(配置回调模型) |

连线默认值(X6GraphManager.createEdge

当某个连线字段未传时,会使用以下默认值:

{
  router: { name: "orth" },
  connector: { name: "rounded" },
  zIndex: 2,
  attrs: {
    line: {
      strokeWidth: 2,
      stroke: "#999",
      targetMarker: null
    }
  }
}

额外行为:

  • 若未提供 edge.id,管理器会自动生成临时 id(内部计数)写入 edge.data.edgeId
  • 该临时 id 可用于点击回调命中,但不适合作为长期稳定差分 key,建议给定唯一id。

7. 更新机制(updateGraph

X6Graph 通过 watch(() => [props.nodes, props.edges], { deep: true }) 自动调用:

graphManager.updateGraph({ nodes, edges })

7.1 节点更新策略

  • 新数据有、旧图无 -> 创建
  • 新旧都有 -> 增量更新(只改传入字段)
  • 旧图有、新数据无 -> 删除
  • attrs 以顶层 key 深合并
  • x/y/width/height 仅在字段非 undefined 时更新
  • 用户拖拽后的节点位置会缓存,后续消息更新可避免被旧坐标覆盖

7.2 连线更新策略

  • 当所有边都有稳定 id:按 id 做差分保留/删除/更新
  • 当存在边缺失 id:退化为“清空旧边并全量重建”
  • attrs/source/target/router/connector/zIndex 仅对传入字段生效

7.3 其他内部默认/约定行为

  • ID 规范化:节点和边的 id 会统一转字符串比较,避免 1"1" 被视为不同。
  • attrs 深合并规则:只对你传入的 attrs 顶层 key 执行深合并,未传 key 保留原值。
  • 拖拽保持:节点触发 node:moved 后会记录位置,后续外部更新若仍带旧 x/y,可避免把节点拉回初始点。

8. 两种事件回调模型

为兼容不同用法,支持两种事件模型,建议项目内统一一种。

模型 A:组件事件(推荐)

  • @nodeClick
  • @nodeDblClick
  • @edgeClick

通常通过 args.cell.id 判断当前节点/连线。

模型 B:配置回调(可选)

  • 节点配置中写 onClick/onDblClick
  • 连线配置中写 onClick

注意

如果模型 A + 模型 B 同时写了同一套逻辑,可能重复触发。

9. X6GraphManager API

9.1 生命周期

new X6GraphManager(options)

  • options.container: 容器 DOM(必填)
  • options.graphOptions: 图配置(可选)
  • options.plugins: 插件配置(可选)

init(): boolean

  • 初始化 Graph,挂载插件并绑定内部事件

destroy(): void

  • 销毁图并清空缓存(节点、连线、事件、拖拽位置)

9.2 数据 API

  • createNode(config)
  • createNodes(nodes)
  • getNode(nodeId)
  • updateNode(nodeId, updates)
  • removeNode(nodeId)
  • createEdge(config)
  • createEdges(edges)
  • updateEdge(edgeId, updates)
  • removeEdge(edgeId)
  • clear()
  • updateGraph({ nodes, edges })

9.3 视图 API

  • zoomFit(centerX, centerY, zoom = 0.8): number
  • resize(width, height): void

9.4 事件 API

  • on(event, handler)
  • off(event, handler)
  • emit(event, data)

10. 结合载荷资源管控系统(商⭐)进程拓扑 的自动更新功能说明

该项目中的进程拓扑采用了“消息驱动 + computed 渲染”模式,流程如下:

  1. 通过 pubSub.subscribe(...) 监听多类消息(多波束、地检、综合处理器、数字仿真、地址变更)
  2. 在回调中更新响应式状态:
    • statusData
    • groundDetectionStatusData
    • integratedProcessorStatusData
    • dsStatusData
    • queryDateMap
  3. graphNodesgraphEdgescomputed)基于状态自动重算
  4. X6Graph 接收新 nodes/edges,触发内部 watch
  5. graphManager.updateGraph(...) 自动把变化同步到画布

即:不需要手动调用刷新,消息变化即可自动更新图。

注:本项目中也将其核心文件移入供参考,文件路径如下

x6-graph/src/components/UsedDemoOfPps/index.vue

实战建议

1.初始化加载效果-对于需要后端返回初始化数据的情况

  • 在页面初始化时,如果后端接口没有及时返回状态信息,就会导致节点等已按你给定的初始值在页面上展示, 而正确的状态要在得到后端状态数据时才能在正确显示,所以推荐做"加载中"处理,这点也可参考上面提到的文件

11. 最小接入示例

<template>
  <X6Graph
    :nodes="graphNodes"
    :edges="graphEdges"
    :graph-options="graphOptions"
    :plugins="plugins"
    @init="onInit"
    @nodeClick="onNodeClick"
  />
</template>

<script setup>
import { ref, computed } from "vue";
import X6Graph from "@/components/KydX6Graph/X6Graph.vue";

const graphManagerRef = ref(null);
const status = ref({ online: 1 });

const graphNodes = computed(() => [
  {
    id: "a",
    x: 80,
    y: 80,
    width: 140,
    height: 80,
    attrs: {
      body: { fill: "#123", stroke: status.value.online ? "#00ff00" : "#ff0000" },
      label: { text: "节点A", fill: "#fff" },
    },
  },
]);

const graphEdges = computed(() => [
  {
    id: "e-a-b",
    source: "a",
    target: "b",
    attrs: { line: { stroke: "#00ff00", strokeWidth: 2 } },
  },
]);

const graphOptions = {};
const plugins = {};

const onInit = (manager) => {
  graphManagerRef.value = manager;
};

const onNodeClick = (args) => {
  console.log("node click:", args.cell?.id);
};
</script>

12. FAQ

Q1: 为什么更新 edges 会偶尔闪动?

edges 存在缺失 id 的项时,updateGraph 会走“删旧重建”策略。请为每条边补稳定 id

Q2: 可以同时用 @nodeClicknode.onClick 吗?

可以,但不建议同一逻辑双绑定,避免重复执行。

Q3: 如何外部手动触发适配?

可通过组件 ref 调用 handleResize(),或在 @init 拿到 manager 后调用 manager.zoomFit(...)

13. 作者及版本信息

  • author: lixiang
  • version: 1.0.1
  • date: 2026/3/20
  • author: lixiang
  • version: 1.0.2
  • date: 2026/3/26