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

@aidps/canvas-flow

v1.2.0

Published

基于 X6 2.x 的 React 画布组件库

Readme

@aidps/canvas-flow

基于 X6 2.x 的 React 画布组件库,提供高度封装的画布组件、插件系统、菜单功能和函数封装能力。

特性

  • 🌱 易于使用:提供更符合 React 习惯的组件化 API
  • 🚀 统一状态管理:服务和画布数据统一管理
  • 🧲 多画布支持:每个画布组件拥有独立的状态和实例
  • 💯 开箱即用:内置大量画布组件和插件
  • 🔒 只读模式:支持函数封装模式下的自动只读
  • 📦 函数封装:支持将画布封装为可复用的函数

安装

npm install @aidps/canvas-flow
# 或
pnpm add @aidps/canvas-flow
# 或
yarn add @aidps/canvas-flow

快速开始

基础用法

import React from 'react';
import { XFlow, XFlowGraph, SelectionPlugin, SnaplinePlugin } from '@aidps/canvas-flow';

const App = () => {
  return (
    <XFlow>
      <XFlowGraph
        config={{
          grid: true,
          panning: {
            enabled: true,
          },
        }}
      />
      <SelectionPlugin />
      <SnaplinePlugin />
    </XFlow>
  );
};

完整示例

import React from 'react';
import {
  XFlow,
  XFlowGraph,
  SelectionPlugin,
  SnaplinePlugin,
  KeyboardPlugin,
  ClipboardPlugin,
  HistoryPlugin,
  useXFlow,
} from '@aidps/canvas-flow';

const MyComponent = () => {
  const { graph } = useXFlow();

  const handleAddNode = () => {
    if (graph) {
      graph.addNode({
        shape: 'rect',
        x: 100,
        y: 100,
        width: 80,
        height: 40,
        label: 'Node',
      });
    }
  };

  return (
    <div>
      <button onClick={handleAddNode}>添加节点</button>
    </div>
  );
};

const App = () => {
  return (
    <div style={{ width: '100%', height: '600px' }}>
      <XFlow
        onReady={(graph) => {
          console.log('画布已就绪', graph);
        }}
      >
        <XFlowGraph
          config={{
            grid: true,
            autoResize: true,
            panning: {
              enabled: true,
              eventTypes: ['leftMouseDown'],
            },
            mousewheel: {
              enabled: true,
              modifiers: ['ctrl', 'meta'],
            },
            scaling: {
              min: 0.8,
              max: 3,
            },
          }}
        />
        <SelectionPlugin rubberband showNodeSelectionBox />
        <SnaplinePlugin sharp />
        <KeyboardPlugin />
        <ClipboardPlugin />
        <HistoryPlugin />
        <MyComponent />
      </XFlow>
    </div>
  );
};

API 文档

核心组件

XFlow

根组件,提供画布上下文。所有画布相关组件必须包裹在 XFlow 内部。

Props:

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | children | React.ReactNode | - | 子组件 | | onReady | (graph: Graph) => void | - | 画布就绪回调,返回 Graph 实例 | | enableMenus | boolean | false | 是否启用菜单功能(节点和边的右键菜单) | | showConfigPanel | boolean | true | 是否显示配置面板 | | showOperatorMenu | boolean | true | 是否显示算子菜单 | | showMinimap | boolean | true | 是否显示小地图 |

示例:

<XFlow
  enableMenus={true}
  onReady={(graph) => {
    console.log('画布已就绪', graph);
  }}
>
  <XFlowGraph />
</XFlow>

XFlowGraph

画布组件,封装 X6 Graph。自动支持函数封装模式的只读控制。

Props:

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | config | Partial<GraphConfig> | - | 画布配置,参考 X6 GraphOptions | | onReady | (graph: Graph) => void | - | 画布就绪回调 | | onDestroy | () => void | - | 画布销毁回调 | | className | string | - | 容器类名 | | style | React.CSSProperties | - | 容器样式 | | enableMenus | boolean | false | 是否启用菜单功能 |

配置项(config):

interface GraphConfig {
  grid?: boolean | GridOptions;        // 网格
  autoResize?: boolean;                 // 自动调整大小
  panning?: PanningOptions;             // 平移配置
  background?: BackgroundOptions;       // 背景配置
  mousewheel?: MouseWheelOptions;       // 鼠标滚轮配置
  scaling?: ScalingOptions;             // 缩放配置
  connecting?: ConnectingOptions;       // 连线配置
  translating?: TranslatingOptions;     // 平移限制
  interacting?: InteractingOptions;     // 交互配置
}

示例:

<XFlowGraph
  config={{
    grid: true,
    autoResize: true,
    panning: {
      enabled: true,
      eventTypes: ['leftMouseDown'],
    },
    mousewheel: {
      enabled: true,
      modifiers: ['ctrl', 'meta'],
    },
  }}
/>

只读模式:

当使用 CanvasFunctionProvider 包裹并进入函数封装模式时,XFlowGraph 会自动进入只读模式:

  • 禁止节点移动
  • 禁止连线操作
  • 禁止边的编辑
  • 禁止端点移动
  • 仍可点击节点查看配置
  • 仍可平移和缩放画布

插件组件

SelectionPlugin

框选插件,支持框选多个节点。

Props:

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | rubberband | boolean | false | 是否启用框选 | | showNodeSelectionBox | boolean | false | 是否显示节点选择框 | | modifiers | string[] | - | 触发框选的修饰键,如 ['ctrl', 'meta'] | | strict | boolean | false | 是否严格模式(节点必须完全在框内) |

示例:

<SelectionPlugin 
  rubberband 
  showNodeSelectionBox 
  modifiers={['ctrl', 'meta']} 
/>

SnaplinePlugin

对齐线插件,拖拽节点时显示对齐线。

Props:

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | sharp | boolean | false | 是否启用锐利对齐线 | | resizing | boolean | false | 是否在调整大小时显示对齐线 | | filter | string \| Function | - | 过滤节点 |

示例:

<SnaplinePlugin sharp />

KeyboardPlugin

键盘快捷键插件。

功能:

  • Ctrl/Cmd + Z: 撤销
  • Ctrl/Cmd + Shift + Z: 重做
  • Ctrl/Cmd + A: 全选
  • Backspace: 删除选中元素
  • Ctrl/Cmd + 1: 放大
  • Ctrl/Cmd + 2: 缩小

示例:

<KeyboardPlugin />

ClipboardPlugin

剪贴板插件,支持复制粘贴。

示例:

<ClipboardPlugin />

HistoryPlugin

历史记录插件,支持撤销/重做。

示例:

<HistoryPlugin />

MinimapPlugin

小地图插件。

Props:

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | width | number | 200 | 小地图宽度 | | height | number | 150 | 小地图高度 | | padding | number | 10 | 内边距 | | simple | boolean | false | 是否使用简单模式 | | style | React.CSSProperties | - | 容器样式 |

示例:

<MinimapPlugin
  width={200}
  height={150}
  padding={10}
  simple={false}
  style={{
    position: 'absolute',
    bottom: 16,
    right: 16,
  }}
/>

菜单组件

OperatorMenu

算子菜单组件,提供树状结构的算子菜单,支持拖拽功能。

Props:

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | data | OperatorMenuItem[] | - | 菜单数据 | | draggable | boolean \| { icon: boolean } | false | 是否可拖拽 | | onDragStart | (e: DragEvent, node: OperatorMenuItem) => void | - | 拖拽开始回调 | | showIcon | boolean | true | 是否显示图标 | | showLine | boolean | true | 是否显示连接线 | | enableSearch | boolean | true | 是否启用搜索 | | searchPlaceholder | string | "搜索算子" | 搜索框占位符 | | loading | boolean | false | 加载状态 | | emptyText | string | "暂无算子数据" | 空数据提示 | | onNodeClick | (e: React.MouseEvent, node: OperatorMenuItem) => void | - | 节点点击回调 | | defaultExpandedKeys | React.Key[] | - | 默认展开的节点 |

示例:

import { OperatorMenu, OperatorMenuItem } from '@aidps/canvas-flow';

const menuData: OperatorMenuItem[] = [
  {
    id: '1',
    pid: null,
    label: '数据源',
    children: [
      {
        id: '1-1',
        pid: '1',
        label: 'CSV读取',
        shape: 'csv',
      },
    ],
  },
];

function App() {
  const handleDragStart = (e: React.DragEvent, node: OperatorMenuItem) => {
    // 处理拖拽逻辑
  };

  return (
    <OperatorMenu
      data={menuData}
      draggable={{ icon: false }}
      onDragStart={handleDragStart}
      showIcon={true}
      enableSearch={true}
    />
  );
}

NodeMenu / EdgeMenu

节点/边配置弹窗组件(Modal)。默认在节点/边点击时打开(需启用 enableMenus)。

右键上下文菜单

启用 enableMenus 后,画布会提供内置的右键上下文菜单:

  • 节点右键:删除节点、克隆一份、居中到该节点、复制节点 JSON
  • 边右键:删除边
  • 画布空白右键:在此处新增节点、从缓存粘贴节点、撤销/重做、居中、放大/缩小

示例:

import { XFlow, XFlowGraph } from '@aidps/canvas-flow';

export default () => (
  <XFlow enableMenus>
    <XFlowGraph enableMenus />
  </XFlow>
);

NodeMenu Props:

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | open | boolean | - | 是否打开 | | onClose | () => void | - | 关闭回调 | | node | Node \| null | - | 节点实例 | | title | string | - | 菜单标题 | | children | React.ReactNode | - | 菜单内容 |

EdgeMenu Props:

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | open | boolean | - | 是否打开 | | onClose | () => void | - | 关闭回调 | | edge | Edge \| null | - | 边实例 | | children | React.ReactNode | - | 菜单内容 |

示例:

import { NodeMenu, EdgeMenu, useMenu } from '@aidps/canvas-flow';

const CustomNodeMenu = () => {
  const { nodeMenuOpen, selectedNode, closeNodeMenu } = useMenu();

  return (
    <NodeMenu
      open={nodeMenuOpen}
      onClose={closeNodeMenu}
      node={selectedNode}
      title={`节点配置: ${selectedNode?.getData()?.label || ''}`}
    >
      <Button>编辑节点</Button>
      <Button>删除节点</Button>
    </NodeMenu>
  );
};

画布函数封装

CanvasFunctionProvider

函数封装上下文提供者,用于管理函数封装状态。

示例:

import { CanvasFunctionProvider, FunctionModeToolbar } from '@aidps/canvas-flow';

function App() {
  return (
    <CanvasFunctionProvider>
      <XFlow>
        <FunctionModeToolbar />
        <XFlowGraph />
      </XFlow>
    </CanvasFunctionProvider>
  );
}

FunctionModeToolbar

函数封装模式工具栏,用于切换参数选择模式。

Props:

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | size | 'small' \| 'middle' \| 'large' | 'middle' | 按钮尺寸 | | style | React.CSSProperties | - | 自定义样式 | | className | string | - | 自定义类名 | | entryType | 'node' \| 'function' \| 'both' | 'both' | 入口按钮显示控制 |

示例:

<FunctionModeToolbar size="small" />
<FunctionModeToolbar entryType="node" />
<FunctionModeToolbar entryType="function" />

OutputPortsPanel

输出链接桩面板,显示所有节点的输出链接桩。

Props:

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | title | string | "选择输出链接桩" | 面板标题 | | embedded | boolean | false | 是否以嵌入模式显示 | | style | React.CSSProperties | - | 自定义样式 | | className | string | - | 自定义类名 |

示例:

<OutputPortsPanel embedded />

FunctionSummaryModal

函数封装汇总弹窗,显示所有已选择的输入参数和输出链接桩。

Props:

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | title | string | "画布函数封装" | 弹窗标题 | | width | number \| string | 800 | 弹窗宽度 | | onClose | () => void | - | 关闭回调 | | onConfirm | (data: { inputs: SelectedParam[]; outputs: SelectedOutput[] }) => void | - | 确认回调 |

示例:

<FunctionSummaryModal
  onConfirm={(data) => {
    console.log('函数封装数据:', data);
  }}
/>

其他组件

CanvasPreview

画布预览组件,用于只读预览画布内容。

Props:

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | data | GraphData | - | 画布数据 | | width | number \| string | - | 预览宽度 | | height | number \| string | - | 预览高度 | | padding | number | 10 | 内边距 | | style | React.CSSProperties | - | 自定义样式 |

示例:

<CanvasPreview
  data={graphData}
  width={300}
  height={200}
  padding={10}
/>

Hooks 文档

useXFlow

获取画布上下文,包括 Graph 实例和选中节点。

返回值:

interface XFlowContextValue {
  graph: Graph | null;              // 画布实例
  setGraph: (graph: Graph | null) => void;
  selectedNode: Node | null;        // 当前选中的节点
  setSelectedNode: (node: Node | null) => void;
  showConfigPanel: boolean;          // 是否显示配置面板
  setShowConfigPanel: (show: boolean) => void;
  showOperatorMenu: boolean;         // 是否显示算子菜单
  setShowOperatorMenu: (show: boolean) => void;
  showMinimap: boolean;              // 是否显示小地图
  setShowMinimap: (show: boolean) => void;
}

示例:

import { useXFlow } from '@aidps/canvas-flow';

const MyComponent = () => {
  const { graph, selectedNode } = useXFlow();

  const handleAddNode = () => {
    if (graph) {
      graph.addNode({
        shape: 'rect',
        x: 100,
        y: 100,
        width: 80,
        height: 40,
      });
    }
  };

  return (
    <div>
      <p>当前选中节点: {selectedNode?.id}</p>
      <button onClick={handleAddNode}>添加节点</button>
    </div>
  );
};

useGraph

获取画布实例的快捷 Hook。

返回值:

Graph | null

示例:

import { useGraph } from '@aidps/canvas-flow';

const MyComponent = () => {
  const graph = useGraph();

  const handleCenter = () => {
    if (graph) {
      graph.centerContent();
    }
  };

  return <button onClick={handleCenter}>居中</button>;
};

useNode

获取当前选中节点的快捷 Hook。

返回值:

{
  node: Node | null;                // 节点实例
  nodeData: {                       // 节点数据
    node: Node;
    data: any;
    shape: string;
    id: string;
    position: { x: number; y: number };
    size: { width: number; height: number };
  } | null;
  graph: Graph | null;               // 画布实例
  hasNode: boolean;                 // 是否有选中节点
}

示例:

import { useNode } from '@aidps/canvas-flow';

const NodeInfo = () => {
  const { node, nodeData, hasNode } = useNode();

  if (!hasNode) {
    return <div>请选择一个节点</div>;
  }

  return (
    <div>
      <p>节点ID: {nodeData?.id}</p>
      <p>节点标签: {nodeData?.data?.label}</p>
      <p>位置: ({nodeData?.position.x}, {nodeData?.position.y})</p>
    </div>
  );
};

useMenu

获取菜单上下文,用于控制节点和边的右键菜单。

返回值:

interface MenuContextValue {
  // 节点菜单
  nodeMenuOpen: boolean;                    // 节点菜单是否打开
  selectedNode: Node | null;                // 当前选中的节点
  openNodeMenu: (node: Node) => void;       // 打开节点菜单
  closeNodeMenu: () => void;                // 关闭节点菜单
  
  // 边菜单
  edgeMenuOpen: boolean;                    // 边菜单是否打开
  selectedEdge: Edge | null;                 // 当前选中的边
  openEdgeMenu: (edge: Edge) => void;       // 打开边菜单
  closeEdgeMenu: () => void;                // 关闭边菜单
  
  // 通用
  closeAllMenus: () => void;                // 关闭所有菜单
}

注意: 必须在 XFlow 组件设置 enableMenus={true} 时才能使用。

示例:

import { useMenu } from '@aidps/canvas-flow';

const CustomNodeMenu = () => {
  const { 
    nodeMenuOpen, 
    selectedNode, 
    openNodeMenu, 
    closeNodeMenu 
  } = useMenu();

  return (
    <NodeMenu
      open={nodeMenuOpen}
      onClose={closeNodeMenu}
      node={selectedNode}
    >
      <Button onClick={() => {
        console.log('编辑节点:', selectedNode);
        closeNodeMenu();
      }}>
        编辑节点
      </Button>
    </NodeMenu>
  );
};

useCanvasFunction

获取画布函数封装上下文,用于管理函数封装状态。

返回值:

interface CanvasFunctionContextValue {
  // 模式控制
  isSelectionMode: boolean;                  // 是否处于参数选择模式
  setSelectionMode: (mode: boolean) => void; // 开启/关闭参数选择模式
  toggleSelectionMode: () => void;          // 切换参数选择模式
  
  // 面板视图
  panelView: 'node-config' | 'output-ports'; // 当前面板视图
  setPanelView: (view: PanelViewType) => void; // 设置面板视图
  
  // 输入参数
  selectedParams: SelectedParam[];           // 已选择的输入参数列表
  addParam: (param: SelectedParam) => void;   // 添加输入参数
  removeParam: (nodeId: string, fieldName: string) => void; // 移除输入参数
  clearParams: () => void;                   // 清空所有输入参数
  isParamSelected: (nodeId: string, fieldName: string) => boolean; // 检查参数是否已选择
  
  // 输出链接桩
  selectedOutputs: SelectedOutput[];         // 已选择的输出链接桩列表
  addOutput: (output: SelectedOutput) => void; // 添加输出链接桩
  removeOutput: (nodeId: string, portId: string) => void; // 移除输出链接桩
  clearOutputs: () => void;                  // 清空所有输出链接桩
  isOutputSelected: (nodeId: string, portId: string) => boolean; // 检查输出是否已选择
  
  // 通用
  clearAll: () => void;                      // 清空所有选择
  showSummaryModal: boolean;                 // 是否显示汇总弹窗
  setShowSummaryModal: (show: boolean) => void; // 设置汇总弹窗显示状态
  getFunctionData: () => {                   // 获取函数封装数据
    inputs: SelectedParam[];
    outputs: SelectedOutput[];
  };
}

示例:

import { useCanvasFunction } from '@aidps/canvas-flow';

const MyComponent = () => {
  const {
    isSelectionMode,
    toggleSelectionMode,
    selectedParams,
    selectedOutputs,
    getFunctionData,
  } = useCanvasFunction();

  const handleExport = () => {
    const data = getFunctionData();
    console.log('函数封装数据:', data);
    // 导出或保存数据
  };

  return (
    <div>
      <button onClick={toggleSelectionMode}>
        {isSelectionMode ? '退出选择模式' : '进入选择模式'}
      </button>
      <p>已选择 {selectedParams.length} 个输入参数</p>
      <p>已选择 {selectedOutputs.length} 个输出链接桩</p>
      <button onClick={handleExport}>导出函数数据</button>
    </div>
  );
};

useCanvasFunctionSafe

安全获取画布函数封装上下文,不会抛出错误(当 CanvasFunctionProvider 不存在时返回 null)。

返回值:

CanvasFunctionContextValue | null

示例:

import { useCanvasFunctionSafe } from '@aidps/canvas-flow';

const MyComponent = () => {
  const canvasFunction = useCanvasFunctionSafe();

  // 安全使用,不会抛出错误
  if (canvasFunction) {
    return (
      <div>
        <p>选择模式: {canvasFunction.isSelectionMode ? '开启' : '关闭'}</p>
      </div>
    );
  }

  return <div>函数封装功能未启用</div>;
};

工具函数

封装模式

模式概览

  • 节点封装:对选中的子图进行封装,支持“参数 + 输入 + 输出”三类配置,适合把一段流程封成可复用模块。
  • 函数封装:对选中的子图进行封装,但仅支持“参数 + 输出”,适合把内部参数作为函数入参,输出作为函数返回。

操作流程

  • 进入封装模式:在工具栏点击“节点封装”或“函数封装”,第一步为“节点选择”
  • 框选节点:在“节点选择”步骤直接拖拽框选(无需按修饰键)
  • 配置步骤:点击“下一步”进入参数/输入/输出配置
    • 参数:选择并可重命名需要透出的节点参数
    • 输入:选择子图边界的输入端口(仅节点封装)
    • 输出:选择子图边界的输出端口
  • 返回修改:随时点击“上一步”返回节点选择增删参与封装节点,系统自动校验并清理失效项
  • 完成预览:点击“查看选择”或“完成”查看当前汇总

相关组件

  • FunctionModeToolbar:封装模式工具栏,提供“节点封装/函数封装”入口与上一步/下一步、查看选择、清空、完成等操作
  • EncapsulationTabsPanel:封装步骤中显示“参数/输入/输出”三类面板
  • EncapsulationSelection:封装模式下的框选配置,根据步骤自动启用/禁用
  • FunctionEncapsulationBridge:桥接 X6 事件与封装状态,负责子图快照、边界端口计算与选择校验

使用示例

import { CanvasFunctionProvider, FunctionModeToolbar, XFlow, XFlowGraph } from '@aidps/canvas-flow';

export default () => (
  <CanvasFunctionProvider>
    <XFlow>
      <FunctionModeToolbar />
      <XFlowGraph />
    </XFlow>
  </CanvasFunctionProvider>
);

行为与交互说明

  • 框选:在“节点选择”步骤中启用 rubberband 框选,直接拖拽即可框选
  • 只读:在参数/输入/输出步骤中画布进入只读,避免误操作导致选择丢失
  • 校验:当子图结构或选择变化时,系统会自动清理不在子图或边界的已选项
  • 汇总:支持查看当前选择的参数、输入、输出的列表

常用配置(内部)

封装模式入口支持如下配置:

type EnterEncapsulationModeOptions = {
  focus?: 'nodes' | 'params' | 'inputs' | 'outputs';
  preserveOutputs?: boolean;
  enabledTabs?: Array<'params' | 'inputs' | 'outputs'>;
  selection?: {
    enabled?: boolean;
    rubberband?: boolean;
    modifiers?: null | Array<'alt'|'ctrl'|'meta'|'shift'>; // 设为 null 代表无需按键即可框选
    eventTypes?: string[];                                  // 默认 ['leftMouseDown']
  };
  panningWhenSelecting?: 'disable' | { modifiers: string[] };
};

提示:

  • “节点选择”步骤默认 selection.modifiers = null,可直接拖拽框选
  • 参数/输入/输出步骤禁用框选并进入只读交互,避免误点击

节点工厂工具

createNodeConfig

创建节点配置。

createNodeConfig(
  graph: Graph,
  nodeData: OperatorMenuItem,
  point: { x: number; y: number },
  count: number
): Node.Metadata

createNodeForDrag

创建用于拖拽的节点。

createNodeForDrag(
  graph: Graph,
  nodeData: OperatorMenuItem,
  point: { x: number; y: number },
  count: number
): Node

getPortsFromInfo

从节点信息中提取端口配置。

getPortsFromInfo(
  info: any,
  isGroup?: boolean
): PortInfo[]

端口类型工具

isPortTypeCompatible

检查两个端口类型是否兼容。

isPortTypeCompatible(sourceType: PortType, targetType: PortType): boolean

getPortType

获取端口类型。

getPortType(port: Port): PortType

getPortLabel

获取端口标签。

getPortLabel(port: Port): string

类型定义

核心类型

// 画布配置
type GraphConfig = Partial<Graph.Options>;

// 算子菜单项
interface OperatorMenuItem {
  id: string;
  pid: string | null;
  label: string;
  shape?: string;
  children?: OperatorMenuItem[];
  [key: string]: any;
}

// 选中的参数
interface SelectedParam {
  nodeId: string;
  nodeName: string;
  fieldName: string;
  fieldLabel: string;
  fieldType: string;
  currentValue?: any;
  nodeShape?: string;
}

// 选中的输出链接桩
interface SelectedOutput {
  nodeId: string;
  nodeName: string;
  portId: string;
  portLabel: string;
  portType?: string;
  nodeShape?: string;
}

完整示例:函数封装

import React from 'react';
import {
  XFlow,
  XFlowGraph,
  CanvasFunctionProvider,
  FunctionModeToolbar,
  FunctionSummaryModal,
  useCanvasFunction,
} from '@aidps/canvas-flow';

const FunctionEncapsulationDemo = () => {
  return (
    <CanvasFunctionProvider>
      <XFlow>
        {/* 工具栏 - 切换函数封装模式 */}
        <FunctionModeToolbar />
        
        {/* 画布 - 自动支持只读模式 */}
        <XFlowGraph
          config={{
            grid: true,
            autoResize: true,
          }}
        />
        
        {/* 汇总弹窗 */}
        <FunctionSummaryModal
          onConfirm={(data) => {
            console.log('函数封装数据:', data);
            // 处理函数封装数据
          }}
        />
      </XFlow>
    </CanvasFunctionProvider>
  );
};

开发

# 安装依赖
pnpm install

# 启动开发服务器(可视化查看组件效果)
pnpm dev

# 开发模式(监听文件变化,用于库开发)
pnpm dev:watch

# 构建组件库
pnpm build

# 构建预览界面
pnpm build:demo

# 预览构建结果(组件库)
pnpm preview

# 预览构建后的预览界面
pnpm preview:demo

# 清理构建产物
pnpm clean          # 清理库构建产物
pnpm clean:demo     # 清理预览界面构建产物
pnpm clean:all      # 清理所有构建产物

开发服务器

运行 pnpm dev 会启动 Vite 开发服务器,自动打开浏览器显示组件示例页面。

开发页面包含:

  • 工具栏(添加节点、清空、居中、缩放等)
  • 画布区域(可拖拽、缩放、框选)
  • 信息面板(显示节点数、边数、缩放比例)
  • 所有插件功能(框选、对齐线、快捷键、剪贴板、撤销重做)
  • 函数封装功能演示

打包和发布

构建

构建组件库

# 构建生产版本
pnpm build

构建产物:

  • dist/index.js - CommonJS 格式
  • dist/index.esm.js - ES Module 格式
  • dist/index.d.ts - TypeScript 类型声明

构建预览界面

构建开发示例页面(预览界面),用于独立部署和展示:

# 构建预览界面(会自动先构建组件库)
pnpm build:demo

构建产物:

  • dist-demo/index.html - 预览界面入口
  • dist-demo/assets/ - 静态资源(JS、CSS 等)

预览构建后的界面:

pnpm preview:demo

清理构建产物

# 清理库构建产物
pnpm clean

# 清理预览界面构建产物
pnpm clean:demo

# 清理所有构建产物
pnpm clean:all

### 发布到 npm

```bash
# 登录 npm(首次发布需要)
npm login

# 发布(会自动执行 prepublishOnly 脚本进行构建)
npm publish

# 发布到私有仓库
npm publish --registry=https://your-registry.com

版本管理

# 更新版本号
npm version patch  # 1.0.0 -> 1.0.1
npm version minor  # 1.0.0 -> 1.1.0
npm version major  # 1.0.0 -> 2.0.0

# 然后发布
npm publish

License

MIT