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

ra-arch

v1.0.1

Published

架构设计工具

Readme

前言

这是一款基于antv/x6的用于系统架构设计可视化的一款工具。

效果图

效果图.png

快速上手

说明

本组件是在react框架下的前端组件,推荐[email protected]以上版本。推荐使用[email protected]脚手架。其他必要依赖见下文。

目前,作品还有很多需要完善的地方,有些兼容没有处理,推荐使用 mac + 谷歌最新浏览器。这样能体验到更好的滚动效果。

安装方式

通过 npm 安装 npm i ra-arch -S

必要依赖

"dependencies": {
    "@antv/x6": "^1.28.1",
    "ahooks": "^2.10.12",
    "antd": "^4.17.1",
    "ra-arch": "0.0.2"
  }

使用方式

import React from 'react';
import RaArch from 'ra-arch';
import { Button } from 'antd';
import 'ra-arch/es/components/assets/font/iconfont.js';
import appIcon from './icon/app.png';
....
import bmsIcon from './icon/bms.png';

const data = {
  "lanes": [
    { "id": "user", "name": "用户层", "height": 120 },
    { "id": "access", "name": "接入层", "height": 150 },
    { "id": "app", "name": "应用逻辑层", "height": 200 },
    { "id": "store", "name": "存储层", "height": 150 }
  ],
  "nodes": [
    {
      "id": "1",
      "x": 100,
      "y": 180,
      "name": "ARCH-VIEW-DUBBO-K8S-SIT",
      "moduleType": "bmr",
      "systemType": "inner",
      "preId": "access"
    },
    {
      "id": "2",
      "x": 100,
      "y": 380,
      "name": "ARCH-VIEW-DUBBO-K8S-SIT",
      "moduleType": "tidb",
      "systemType": "inner",
      "preId": "app"
    },
    {
      "id": "3",
      "x": 300,
      "y": 380,
      "name": "ARCH-VIEW-DUBBO-K8S-SIT",
      "moduleType": "browser",
      "systemType": "outer",
      "preId": "app"
    },
    {
      "id": "4",
      "x": 300,
      "y": 30,
      "name": "ARCH-VIEW-DUBBO-K8S-SIT",
      "moduleType": "app",
      "systemType": "outer",
      "preId": "user"
    },
    {
      "moduleType": "jetty",
      "name": "ceshi2222",
      "systemType": "inner",
      "x": 450,
      "y": 380,
      "preId": "app",
      "id": "1flj7sg14",
      "label": "Jetty",
      "icon": "jetty",
      "value": "jetty",
      "type": "node",
      "image": "jettyModule",
      "bgImage": "innerSystem"
    },
    {
      "moduleType": "jetty",
      "name": "ceshi11111",
      "systemType": "inner",
      "x": 600,
      "y": 380,
      "preId": "app",
      "id": "1flj7sg1422",
      "label": "Jetty",
      "icon": "jetty",
      "value": "jetty",
      "type": "node",
      "image": "jettyModule",
      "bgImage": "innerSystem"
    },
  ],
  "links": [{ "source": "1", "target": "2" }]
}
const moduleConfig = {
  title: '架构自助设计系统',
  search: {
    placeholder: '请输入组件名称',
  },
  options: [
    {
      label: '用户层组件',
      value: 'userLayer',
      children: [
        {
          label: 'USER',
          icon: 'user',
          moduleType: 'user',
          moduleImage: 'user',
          value: 'user',
          target: ['user'],
          moduleProp: [
            {
              type: 'INPUT',
              label: '用户名称',
              name: 'userName',
              inputProps: {
                allowClear: true,
                placeholder: '请输入用户名称',
                className: 'search-input',
              },
              rules: [
                {
                  required: true,
                  message: '请选择使用时长',
                },
              ],
            },
            {
              label: '使用时长',
              value: '',
              name: 'time',
              type: 'SELECT',
              inputProps: {
                placeholder: '请选择使用时长',
                options: [
                  { label: '1周', value: '1week' },
                  { label: '1月', value: '1month' },
                  { label: '1年', value: '1year' },
                ],
              },
              rules: [
                {
                  required: true,
                  message: '请选择使用时长',
                },
              ],
            },
            {
              type: 'REMOTESELECT',
              label: '负责人',
              name: 'ownerId',
              inputProps: {
                allowClear: true,
                remote: async (val: string) => {
                  if (!val) return [];
                  return [
                    { label: val, value: val },
                    { label: `${val}1`, value: `${val}1` },
                    { label: `${val}2`, value: `${val}2` },
                    { label: `${val}3`, value: `${val}3` },
                  ];
                },
                className: 'search-ownerId',
                placeholder: '请输入负责人ID',
              },
              rules: [
                {
                  required: true,
                  message: '请选择使用时长',
                },
              ],
            },
          ],
        },
      ],
    },
    {
      label: '云主机',
      value: 'clound',
      children: [
        {
          label: 'Jetty',
          icon: 'jetty',
          value: 'jetty',
          moduleProp: [],
        },
        {
          label: 'Nginx',
          icon: 'nginx',
          value: 'nginx',
          moduleProp: [],
        },
      ],
    },
    {
      label: 'K8S容器',
      value: 'k8s',
      children: [
        {
          label: 'Dubbo',
          icon: 'dubbo',
          value: 'dubbo',
          moduleProp: [],
        },
        {
          label: 'SpringBoot',
          icon: 'springboot',
          value: 'springboot',
          moduleProp: [],
        },
        {
          label: 'NODEJS',
          icon: 'nodejs',
          value: 'nodejs',
          moduleProp: [],
        },
        {
          label: 'PYTHON',
          icon: 'python',
          value: 'python',
          moduleProp: [],
        },
        {
          label: 'Jetty',
          icon: 'jetty',
          value: 'jetty',
          moduleProp: [],
        },
        {
          label: 'Nginx',
          icon: 'nginx',
          value: 'nginx',
          moduleProp: [],
        },
      ],
    },
    ...
  ],
};
const assets = {
    appIcon,
    bmsIcon,
    ....
}
export default function IndexPage() {
  return (
      <RaArch data={data} moduleConfig={moduleConfig} assets={assets} />
  );
}

注意

需要通过以下方式引入 iconfont

import 'ra-arch/es/components/assets/font/iconfont.js';

功能说明

  • 生成节点,拖拽左侧组件到右侧,会有弹窗让用户填写相关信息然后生成节点。
  • 调整节点尺寸,单击节点,出现工具端口,拖动端口调整节点尺寸。
  • 右键删除节点 右键点击节点,在右键菜单中点击删除。触发 onRemoveNode
  • 右键编辑节点 右键单击节点,在右键菜单中点击编辑,在弹窗中对数据进行编辑。但是节点层级和组件类型不能编辑,触发 onUpdateNode
  • 调整层级高度,鼠标移入层级下侧拖拽线,点击鼠标左键进行拖动对层级高度进行调整。
  • 生成连线,在画布中从源端节点的端口拖拽连线到目标节点的端口。相同两个节点不能有重复的连线,生成节点前会调用 onAddLink
  • 删除连线,鼠标移入链接出现删除按钮。点击按钮会触发 onRemoveLink
  • 组件过滤,在左侧搜索框中输入内容,对下面的组件模版进行过滤
  • 撤销重做,画布上的操作都可以通过撤销重做来操作。会触发 onUndoOrRedo 回调
  • 放大 最多放大到当前画布的 1.5
  • 缩小 最小缩小到当前画布的 0.5
  • 全屏 展开整个编辑器到全屏操作
  • 取消全屏
  • 本地导入数据 在弹窗中拖入 RaArchData 结构的 .json 文件
  • 本地导出数据 生成 RaArchData 结果的.json 文件
  • 本地导出图片 将画布区域生成 png 图片
  • 上传数据 触发 onSave
  • 复制节点 左键单击节点,再点击复制节点按钮,节点信息将放入剪贴板中
  • 粘贴节点 点击粘贴节点按钮,将触发 onCreateNode
  • 删除节点 左键单击节点,再点击删除节点按钮。触发 onRemoveNode
  • 清理缓存 点击清理缓存,将清除缓存数据,并触发 reload ,而使用 data 传入的数据

快捷键

  • 复制节点到剪贴板 ctrl+c/commond+c
  • 粘贴节点 ctrl+v/commond+v
  • 撤销 ctrl+z/commond+z
  • 重做 ctrl+shift+z/commond+shift+z
  • 删除节点 backspace/backspace
  • 放大 ctrl+1/commond+1
  • 缩小 ctrl+2/commond+2
  • 清理缓存 ctrl+e/commond+e

API

| 参数 | 说明 | 类型 | 默认值 | | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------- | | assets | 图片资源键值对 | Object | {} | | data | 需要加载的数据,如果要更新数据,需要获取数据后,清理掉缓存 | RaArchData | undefined | | moduleConfig | 画布左侧的组件模版,包含申请组件需要填写的数据 | ModuleConfig | undefined | | saveInterval | 自动缓存数据,便于刷新页面时恢复数据单位 ms | number\|undefined | 10000 | | onAddLink | 在画布中添加链接的回调,返回 promise<boolaen>。如果 resolve(true) 则建立链接,如果 resolve(false)则不会产生链接。 | (link: Edge) => Promise<boolean> | undefined | | onRemoveLink | 在画布中移除链接的回调,返回 promise<boolaen>。如果 resolve(true) 则移除链接,如果 resolve(false)则不会移除链接。 | (links: Edge[]) => Promise<boolean> | undefined | | onRemoveNode | 在画布中移除节点的回调,返回 promise<boolaen>。如果 resolve(true) 则移除节点,如果 resolve(false)则不会移除节点。 | (nodes: Node[]) => Promise<boolean> | undefined | | onCreateNode | 在画布中新建节点的回调,返回 promise<boolaen>。如果 resolve(true) 则创建新节点,如果 resolve(false)则不会创建节点。 | (nodeData: any) => Promise<boolean> | undefined | | onUpdateNode | 在画布中编辑节点的回调,返回 promise<boolaen>。如果 resolve(true) 则更新节点数据,如果 resolve(false)则不会更新节点数据。 | (nodeData: any) => Promise<boolean> | undefined | | onUndoOrRedo | 在画布中撤销和重做的回调。因为数据是之前已经产生过的,不需要用户再次确认,但可能存在与后端的交互,所以开放给开发者进行处理。节点数据更新不会放入撤销和重做队列中 | (type: 'undo' \| 'redo',graph: Graph,args: { cmds: any[]; options: any }) => Promise<boolean> | undefined | | onSave | 将画布中数据保存至后端,返回 promise<boolaen>。如果 resolve(true) 则保存成功,如果 resolve(false)则保存失败。 | (data: any) => Promise<boolean> | undefined |

RaArchData 输入数据结构

| 参数 | 说明 | 类型 | | -------- | ------------ | ------------ | | width | 画布宽度 | number | | height | 画布高度 | number | | lanes | 节点层级配置 | NodeData[] | | nodes | 组件节点 | NodeData[] | | links | 组件连线 | LinkData[] |

NodeData 数据结构

| 参数 | 说明 | 类型 | | ------------ | --------------------------------------------------------------- | ------------------------------ | | id | 节点 ID (必需) | string | | name | 节点名称 (必需) | string | | type | 节点类型 | "lane"\|"node" | | width | 节点宽度 | number | | height | 节点高度 | number | | zIndex | 节点层级 默认 1 | number | | x | 节点 x 坐标 | number | | y | 节点 y 坐标 | number | | moduleType | 节点组件类型 (必需) | string | | systemType | 节点系统类型 (必需) 内部系统(inner) 外部系统(outer) | "inner"\|"outer" | | preId | 节点所在层级的 ID (必需) | string | | image | 节点组件图形,可根据${moduleType.toLowerCase()}Module自动生成 | string | | bgImage | 节点系统图形,可根据${systemType.toLowerCase()}System自动生成 | "innerSystem"\|"outerSystem" |

LinkData 数据结构

| 参数 | 说明 | 类型 | | -------- | ---------------------- | ------------------- | | source | 链接源端节点 ID | string \| number | | target | 链接目标端节点 ID | string \| number | | zIndex | 链接所在层次(非必需) | number |

ModuleConfig 左侧组件类型定义

| 参数 | 说明 | 类型 | | --------- | ------------------------------------ | ------------------------------------ | | title | 左侧组件标题 | string | | search | 是否需要搜索组件,以及搜索功能的配置 | undefined\|{placeholder?: string;} | | options | 左侧组件 | ModuleGropuItem[] |

ModuleGropuItem

| 参数 | 说明 | 类型 | | ---------- | -------- | -------------------- | | label | 显示内容 | string | | value | 标记 | string | | children | 组件群 | ModuleConfigItem[] |

ModuleConfigItem

| 参数 | 说明 | 类型 | | ------------- | ------------------------------------------------------------------------------------------------------------ | -------------------- | | label | 显示内容 | string | | value | 标记 | string | | moduleImage | 图标 可根据assets[moduleImage]\|\| assets[${moduleType ? moduleType : value}Module\|\|moduleImage 获取图片 | ModuleConfigItem[] | | target | 组件只能放入哪些层级,如果为 undefined 或者[]默认可以放入所有层级 | string[] | | moduleProp | 组件模版参数表单使用 | ModulePropItem[] |

ModulePropItem

| 参数 | 说明 | 类型 | | ----------- | --------------------- | ----- | | InputProp | antd 表单录入组件属性 | any | | ... | antd FormItem 属性 | any |