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

node-relationship-editor-v1

v0.0.2

Published

可插拔的 React 拓扑图编辑器,提供完整的 TopologyEditorRef 命令式 API(整图读写、CRUD、撤销重做、自动布局、执行日志等)

Readme

node-relationship-editor-v1

通用可自定义拓扑图编辑器 React 组件库(纯通用核心,无内置业务节点)。

技术栈:React 18.3.1 · Ant Design 5.22.1 · @xyflow/react 12.3.6 · TypeScript · Vite · Monaco Editor


文档

| 文档 | 说明 | |------|------| | docs/API.md | 完整 API 参考(Props、Ref 逐方法说明、类型、事件、集成模式、FAQ) | | 本 README | 快速上手与能力概览 |


目录


安装

npm install node-relationship-editor-v1

Peer dependenciesreactreact-dom(^18.3.1)

样式(必填):

import 'node-relationship-editor-v1/style.css';

快速开始

import { useRef } from 'react';
import { TopologyEditor } from 'node-relationship-editor-v1';
import type { TopologyEditorRef, NodeTypeConfig, EdgeTypeConfig, TopologyGraphData } from 'node-relationship-editor-v1';
import 'node-relationship-editor-v1/style.css';

const nodeTypeConfigs: NodeTypeConfig[] = [
  {
    typeId: 'server',
    displayName: '服务器',
    color: '#3B82F6',
    icon: 'CloudServerOutlined',
    propertyFields: [{ key: 'host', label: 'Host', type: 'text' }],
    defaultData: { label: 'Server', properties: { host: '0.0.0.0' } },
  },
];

const edgeTypeConfigs: EdgeTypeConfig[] = [
  { typeId: 'link', displayName: '连接', color: '#8c8c8c' },
];

const initialGraph: TopologyGraphData = {
  nodes: [],
  edges: [],
};

export function App() {
  const ref = useRef<TopologyEditorRef>(null);

  return (
    <div style={{ height: '100vh' }}>
      <TopologyEditor
        ref={ref}
        nodeTypeConfigs={nodeTypeConfigs}
        edgeTypeConfigs={edgeTypeConfigs}
        initialGraph={initialGraph}
        onDataChange={({ nodes, edges }) => console.log('changed', nodes.length, edges.length)}
      />
    </div>
  );
}

初始化 initialGraph

推荐用单个对象 { nodes, edges } 初始化,不必拆成 initialNodes + initialEdges

const initialGraph: TopologyGraphData = {
  nodes: [
    {
      id: 'srv-1',
      type: 'server',
      position: { x: 200, y: 120 },
      data: { label: 'API Server', properties: { host: '10.0.0.1' } },
    },
  ],
  edges: [],
};

<TopologyEditor initialGraph={initialGraph} nodeTypeConfigs={...} />

| 方式 | 说明 | |------|------| | initialGraph | 推荐 非受控初始数据 | | graph | 受控整图(与分开的 nodes/edges 二选一,graph 优先) | | initialNodes + initialEdges | @deprecated,等价于 initialGraph |

持久化典型写法:

// 保存
const data = ref.current?.getGraph();
await api.save(data);

// 回显
const loaded = await api.load();
ref.current?.setGraph(loaded, { fitView: true });

详见 docs/API.md § 集成模式


命令式 API 概览 TopologyEditorRef

通过 ref 调用。请在挂载后或用户事件中访问 ref.current(首次 render 可能为 null)。

完整参数、返回值与示例见 docs/API.md § TopologyEditorRef

整图

| 方法 | 说明 | |------|------| | getGraph() / toJSON() | 读取 { nodes, edges } | | setGraph(data, { fitView?, pushHistory? }) | 整体回显 |

节点 / 边 CRUD

| 实体 | Create | Read | Update | Delete | |------|--------|------|--------|--------| | 节点 | addNode | getNodes | updateNodeData / updateNode | removeNode | | 边 | addEdge | getEdges | updateEdge | removeEdge | | 图 | addNode/addEdge | getGraph | setGraph | setGraph({ nodes:[], edges:[] }) |

历史 · 布局 · 重置

| 方法 | 对应 UI | |------|---------| | undo() / redo() / canUndo() / canRedo() | 顶栏撤销/重做 | | autoLayout({ direction?, fitView?, pushHistory? }) | 左侧自动布局 | | resetToInitial({ fitView?, pushHistory? }) | 左侧刷新(回到 initialGraph) |

日志 · 导入导出 · 选区

| 方法 | 说明 | |------|------| | appendLog(level, msg) / getLogs() / clearLogs() | 底栏执行日志(需 modes'logs' 才可见) | | exportJson({ download? }) / importJson(text \| graph) | JSON 导出/导入 | | getSelection() / clearSelection() / deleteSelection() | 选区 | | toPNG() | 导出图片 |

视图

fitView · zoomIn · zoomOut · getViewport · setViewport · getFlowInstance()

示例:工具栏按钮驱动 ref

<Button onClick={() => ref.current?.undo()}>撤销</Button>
<Button onClick={() => ref.current?.autoLayout({ fitView: true })}>自动布局</Button>
<Button onClick={() => ref.current?.appendLog('success', '保存成功')}>写日志</Button>

本地 demo(npm run dev → ECU 页)已包含上述按钮示例。


五大板块插槽 slots

| 键 | 值 | 效果 | |----|-----|------| | header | 'default' / ReactNode / false | 顶栏 | | leftToolbar | 同上 | 左侧工具栏 | | propertyPanel | 同上 | 右侧属性区 | | bottomPanel | 同上 | 底部面板 | | canvasOverlay | 同上 | 画布浮层(默认图例) |

<TopologyEditor
  slots={{
    header: <MyHeader />,
    propertyPanel: false,
    bottomPanel: 'default',
  }}
  bottomPanel={{ modes: ['json', 'logs'] }}
/>

画布连线

节点 Handle(小圆点) 为连接点:

| 操作 | 说明 | |------|------| | 拖拽连线 | 源 Handle → 目标 Handle | | 点击连线 | 先点源再点目标(connectOnClick,默认开) | | 重连 | 拖拽已有边端点(edgesReconnectable,默认开) | | 框选 | 空白处左键拖拽;连线进行中自动暂停框选 | | 拖节点 | 拖圆环/节点主体移动(与连线并存) |

可选 Props:connectionMode(默认 Loose)、connectionRadius(默认 24)、isValidConnectionselectionOnDrag

四向连接点:NodeTypeConfig.connectHandles: ['top','right','bottom','left']


事件回调

| 回调 | 触发时机 | |------|----------| | onDataChange | 图数据任意变更(推荐,含 revision) | | onGraphChange | 同 onDataChange(兼容) | | onNodeClick / onEdgeClick | 点击节点/边 | | onNodeAdd / onNodeDelete | 增删节点 | | onEdgeChange | { type: 'add'\|'remove'\|'update', edge, edges } | | onConnect | 新建连线 | | onSelectionChange | { nodes, edges } 选中变化 |


自定义属性面板 renderPropertyPanel

<TopologyEditor
  renderPropertyPanel={({ node, neighbors, updateNodeData }) =>
    node ? (
      <MyForm
        values={node.data.properties}
        onChange={(p) => updateNodeData({ properties: p })}
      />
    ) : (
      <Empty />
    )
  }
/>

优先级:slots.propertyPanel 自定义节点 > renderPropertyPanel > 默认 propertyFields 表单。


节点 / 连线配置

  • NodeTypeConfigtypeIddisplayNamecoloriconpropertyFieldsdefaultDataconnectHandles
  • EdgeTypeConfigtypeIddisplayNamecolorstrokeDasharrayanimated

字段说明见 docs/API.md § 数据类型

图标支持 Ant Design 图标名字符串或 ReactNode


ECU 演示(业务预设,可选)

EcuEditor 通过 forwardRef 暴露与 TopologyEditor 完全相同TopologyEditorRef

import { useRef } from 'react';
import { EcuEditor } from 'node-relationship-editor-v1';
import type { TopologyEditorRef } from 'node-relationship-editor-v1';

const editor = useRef<TopologyEditorRef>(null);

<EcuEditor ref={editor} onDataChange={...} />

editor.current?.fitView();
editor.current?.getGraph();
editor.current?.autoLayout();

若需完全自定义配置,请直接使用 TopologyEditor 并传入 nodeTypeConfigs / edgeTypeConfigs

也可导入演示数据:ECU_NODE_CONFIGSECU_DEMO_NODESECU_DEMO_EDGES 等。


本地开发

npm install
npm run dev          # http://localhost:5173 — ECU / 自定义节点 / 自定义属性面板
npm run typecheck
npm run build:lib    # 输出 dist/

布局示意

┌─────────────────────────────────────────────────────────────┐
│  Header(AI / 撤销重做 / 导出 / 快照)                        │
├──────┬──────────────────────────────────────────┬───────────┤
│ 左侧 │              中央画布 (React Flow)        │ 右侧属性  │
│ 工具 │                                          │ 面板      │
├──────┴──────────────────────────────────────────┴───────────┤
│  Bottom(查询结果 / 执行日志 / JSON / Cypher)                 │
└─────────────────────────────────────────────────────────────┘

License

MIT