{"id":26919180,"url":"https://github.com/wsfe/flowchart","last_synced_at":"2025-07-09T15:37:07.263Z","repository":{"id":37636536,"uuid":"230092060","full_name":"wsfe/flowchart","owner":"wsfe","description":"Vue 流程图组件 (本项目不在维护状态，请勿在生产环境使用。如果有相关组件需求，欢迎开 issue 讨论，感谢支持。)","archived":false,"fork":false,"pushed_at":"2022-12-11T18:22:46.000Z","size":4290,"stargazers_count":28,"open_issues_count":25,"forks_count":11,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-04-14T06:42:04.996Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wsfe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-12-25T11:19:14.000Z","updated_at":"2023-04-17T03:13:17.000Z","dependencies_parsed_at":"2023-01-27T04:45:54.760Z","dependency_job_id":null,"html_url":"https://github.com/wsfe/flowchart","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wsfe%2Fflowchart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wsfe%2Fflowchart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wsfe%2Fflowchart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wsfe%2Fflowchart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wsfe","download_url":"https://codeload.github.com/wsfe/flowchart/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246712883,"owners_count":20821810,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-04-01T21:30:32.614Z","updated_at":"2025-04-01T21:30:33.102Z","avatar_url":"https://github.com/wsfe.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ws-flowchart\n\n**0.x 版本为不稳定版本，不推荐在项目中试毒**\n\n[在线 demo](https://wsfe.github.io/flowchart/)\n\n## 安装\n\n暂未发布到 npm 。\n\n## 使用\n\n```javascript\n// 引入的是 Vue 组件\nimport FlowChart from '@wsfe/flowchart'\n```\n\n## TODO\n\n- [ ] 单元测试\n- [ ] 预留导入流程图元素的接口，且支持分组\n- [ ] 手动调用的方法中不应触发事件，例如 `deleteChart`\n- [ ] 缩放画布时以鼠标位置为中心点\n- [ ] 新增缩放画布到自适应的方法\n- [ ] 缩略图导航\n- [ ] 按住空格拖动画布\n- [ ] 节点内部可触发事件改变节点大小\n- [ ] 曲线连线类型\n\n## 约定的概念\n\n在编写代码的时候设计还没完善，有些概念慢慢改变，这边记录下来供参考\n\n1. 流程图上只有两种东西 —— 节点与连线，统称为元素\n2. chart: 元素，chart = node | link\n3. node: 节点\n4. link: 连线\n5. 每个节点的实现称为一个 “控件” ，即 control ，因此 node 里有个字段 `controlName` 即是记录这个节点是用的哪个控件\n6. anchor: 锚点，有两种，一种是可以拉出连线的锚点，一种是缩放节点用的锚点，位置都是用 0-1 的数字来记录的\n\n## 快捷键\n\n- `Delete` 删除选中元素\n- `Ctrl + Z` 撤销\n- `Ctrl + Y` 重做\n- `Ctrl + A` 全选\n- `方向键` 移动选中元素，步长为 10\n- `Ctrl + 方向键` 或 `Shift + 方向键` 移动选中元素，步长为 1\n- `Space + 鼠标移动` 拖动画布（未实现）\n- `鼠标滚轮` 画布缩放（未实现，目前缩放通过修改 `canvasScale` Prop 来实现）\n\n## API\n\n### 类型说明\n\n具体可以看 `src/interfaces`\n\n```typescript\n/** 预先定义的控件信息 */\nexport interface IControl {\n  /** 控件名称 */\n  controlName: string,\n  /** 对应 Vue 组件 */\n  component: VueConstructor,\n  /** 控件是否在拖拽区域显示 */\n  hidden?: boolean,\n  /** 控件拥有的锚点列表 */\n  anchors?: IControlAnchor[],\n  /** 控件标签 */\n  label?: string,\n  /** 控件默认宽度 */\n  defaultWidth?: number,\n  /** 控件默认高度 */\n  defaultHeight?: number,\n  /** 控件最小宽度 */\n  minWidth?: number,\n  /** 控件最小高度 */\n  minHeight?: number,\n  /** 控件最大宽度 */\n  maxWidth?: number,\n  /** 控件最大高度 */\n  maxHeight?: number,\n  /** 禁止连接自身 */\n  disableLinkSelf?: boolean,\n  /** 最大输入连线条数 */\n  maxLinkIn?: number,\n  /** 最大输出连线条数 */\n  maxLinkOut?: number,\n  /** 在 isEditing 状态改变时拍摄快照，默认 true */\n  takeSnapshotOnEditChange?: boolean,\n  /** 节点遮罩宽 */\n  maskWidth?: number | string,\n  /** 节点遮罩高 */\n  maskHeight?: number | string,\n  /** 节点遮罩 x 方向偏移量 */\n  maskOffsetX?: number | string,\n  /** 节点遮罩 y 方向偏移量 */\n  maskOffsetY?: number | string,\n  /** 是否可缩放 */\n  resizable: boolean,\n}\n```\n\n```typescript\n/** 节点 */\nexport interface IFlowChartNode {\n  id?: string,\n  /** 控件名称 */\n  controlName: string,\n  /** 节点位置信息 */\n  style: Partial\u003cIControlStyle\u003e,\n  /** 节点额外数据，在每个控件中可自定义 */\n  nodeData?: {\n    [key: string]: any,\n  },\n}\n\n/** 连线 */\nexport interface IFlowChartLink {\n  id?: string,\n  /** 连线类型 */\n  linkType?: keyof typeof linkTypeEnum,\n  /** 折线正交拐点 */\n  polylinePoints?: ICanvasCoordinate[],\n  /** 起始节点 id */\n  startNodeId?: string | null,\n  /** 起始锚点 */\n  startAnchor?: IControlAnchor,\n  /** 如果不是连接节点，则需要提供相对于画布的坐标 */\n  startCoordinate?: ICanvasCoordinate,\n  /** 终止节点 id */\n  endNodeId?: string | null,\n  /** 终止锚点 */\n  endAnchor?: IControlAnchor,\n  /** 如果不是连接节点，则需要提供相对于画布的坐标 */\n  endCoordinate?: ICanvasCoordinate,\n  /** 连线编辑器位置，0-1 的数字 */\n  editorPosition?: number,\n  /** 图层顺序 */\n  z?: number,\n  /** 连线额外数据 */\n  linkData?: {\n    [key: string]: any,\n    /** 连线文字 */\n    text: string,\n  },\n}\n\n/** flowchart 数据格式 */\nexport interface IFlowChartData {\n  nodes: IFlowChartNode[],\n  links: IFlowChartLink[],\n}\n```\n\n### FlowChart API\n\n#### Props\n\n| 属性                 | 说明                     | 类型                                                                                 | 默认值                          |\n| :------------------- | :----------------------- | :----------------------------------------------------------------------------------- | :------------------------------ |\n| data                 | 流程图数据               | `{ nodes: IFlowChartNode[], links: IFlowChartLink[] }`                               | `{ nodes: [], links: [] }`      |\n| controlList          | 控件列表                 | `IControl[]`                                                                         | []                              |\n| linkType             | 连线类型                 | `'straight' \\| 'bezier' \\| 'polyline'`                                               | 'straight'                      |\n| linkEditor           | 连线编辑器组件           | `VueConstructor`                                                                     | 无                              |\n| linkEditorWidth      | 连线编辑区域宽           | `number`                                                                             | 170                             |\n| linkEditorHeight     | 连线编辑区域高           | `number`                                                                             | 70                              |\n| allowFreeLink        | 是否允许自由连线         | `boolean`                                                                            | true                            |\n| maxSnapshots         | 最大快照数               | `number`                                                                             | 10                              |\n| readonly             | 是否只读                 | `boolean`                                                                            | 无                              |\n| chartClassNameMethod | 给每个元素上附加的 class | `(chart: FlowChartNode \\| FlowChartLink) =\u003e object \\| Array\u003cobject \\| string\u003e \\| string` | `() =\u003e ({})`                    |\n| isChartDeletable     | 判断元素是否可被删除     | `(chart: FlowChartNode \\| FlowChartLink) =\u003e boolean`                                  | `() =\u003e true`                    |\n| isChartEditable      | 判断元素是否可编辑       | `(chart: FlowChartNode \\| FlowChartLink) =\u003e boolean`                                  | `() =\u003e true`                    |\n| canvasScale          | 画布缩放大小，须大于 0   | `number`                                                                             | 1                               |\n| canvasSize           | 画布尺寸                 | `{ width: number, height: number }`                                                  | `{ width: 1050, height: 1500 }` |\n| canvasPadding        | 画布内边距               | `number`                                                                             | 1000                            |\n| linkArrowWidth       | 连线末尾箭头长度         | `number`                                                                             | 11                              |\n| linkArrowHeight      | 连线末尾箭头高度         | `number`                                                                             | 10                              |\n\n#### Events\n\n| 事件名       | 说明           | 返回值                                |\n| :----------- | :------------- | :------------------------------------ |\n| chart-delete | 删除元素时触发 | 被删除元素的 id 数组                  |\n| undo-change  | 撤销时触发     | 返回一个 `boolean` 表示后续是否可撤销 |\n| redo-change  | 重做时触发     | 返回一个 `boolean` 表示后续是否可重做 |\n\n...事件需要再整理，待补充\n\n#### Methods\n\n| 方法                | 说明                 | 参数                                                                                                                        | 返回值                                  |\n| :------------------ | :------------------- | :-------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------- |\n| getFlowChart        | 获取实时的流程图数据 | 无                                                                                                                          | `FlowChartData`                         |\n| getSelectedCharts   | 获取选中的元素       | 无                                                                                                                          | `Array\u003cFlowChartNode \\| FlowChartLink\u003e` |\n| clearSelectedCharts | 清除选中的元素       | 无                                                                                                                          | 无                                      |\n| getStartCharts      | 获取起始元素         | 无                                                                                                                          | `FlowChartData`                         |\n| addNode             | 添加节点             | `node: IFlowChartNode`: 节点数据\u003cbr/\u003e`takeSnapshot: boolean = true`: 是否拍摄快照                                           | 返回新创建的节点                        |\n| addLink             | 添加连线             | `link: IFlowChartLink`: 节点数据\u003cbr/\u003e`takeSnapshot: boolean = true`: 是否拍摄快照                                           | 返回新创建的连线                        |\n| deleteCharts        | 删除节点与连线       | `ids: string[]`: 待删除元素 id\u003cbr/\u003e`takeSnapshot: boolean = true`: 是否拍摄快照                                             | 无                                      |\n| deleteChart         | 删除单个节点或连线   | `id: string`: 待删除元素 id\u003cbr/\u003e`takeSnapshot: boolean = true`: 是否拍摄快照                                                | 无                                      |\n| setChartData        | 设置某个元素数据     | `id: string`: 元素 id\u003cbr/\u003e`valueObj: { [key: string]: any }`: 待设置的数据\u003cbr/\u003e`takeSnapshot: boolean = true`: 是否拍摄快照 | 无                                      |\n| deleteChartData     | 删除某个元素数据     | `id: string`: 元素 id\u003cbr/\u003e`keys: string[]`: 待删除的数据 key\u003cbr/\u003e`takeSnapshot: boolean = true`: 是否拍摄快照               | 无                                      |\n\n### 流程图节点 API\n\n#### 节点能接收到的 Props\n\n| 属性          | 说明             | 类型                     | 默认值         |\n| :------------ | :--------------- | :----------------------- | :------------- |\n| isEditing     | 是否处于编辑状态 | `boolean`                | false          |\n| readonly      | 是否只读         | `boolean`                | 无             |\n| flowChartData | 完整流程图数据   | `FlowChartData`          | 默认流程图数据 |\n| data          | 节点数据         | `{ [key: string]: any }` | 无             |\n| node          | 节点             | `FlowChartNode`          | 无             |\n| isThumbnail   | 节点是否是缩略图 | `boolean`                | false          |\n\n#### 节点能触发的事件\n\n| 事件名           | 说明         | 返回值                                                                                                 |\n| :--------------- | :----------- | :----------------------------------------------------------------------------------------------------- |\n| update-data      | 更新节点数据 | `valueObj: { [key: string]: any }`: 要更新的数据对象\u003cbr/\u003e`takeSnapshot: boolean = false`: 是否拍摄快照 |\n| delete-data      | 删除节点数据 | `keys: string[]`: 待删除的数据 key\u003cbr/\u003e`takeSnapshot: boolean = false`: 是否拍摄快照                   |\n| take-snapshot    | 拍摄快照     | 无                                                                                                     |\n| replace-snapshot | 替换当前快照 | 无                                                                                                     |\n\n## 如何开发流程图元素\n\n### 单个元素\n\n1. 每个控件是一个 Vue 组件，因此首先创建一个 Vue 组件\n2. 根据上述 API 中，节点能接收到的 Props 与节点能触发的事件，来实现节点的功能，比如当 `isEditing` 为 `true` 时进入编辑状态，组件相应改变显示的内容等\n\n### 一组元素\n\n多个元素组成一个数组按要求的格式塞到 `FlowChart` 的 `controlList` 里即可使用\n\n### 多组元素\n\n暂未实现接口\n\n## 存在的问题与矛盾点\n\n1. 想加入旋转，但逻辑没理清楚，又急着投入使用，因此有的方法兼容了旋转，有的地方比较复杂就按没有旋转来实现\n2. 吸附对齐功能，在 resize 节点的时候，中点的计算是 `x + width / 2` ，所以会有 0.5px 的情况导致对不齐\n3. 涉及坐标的地方基本都用了 `Math.trunc` 方法取整，因为是中途加上的，没有考虑是否有隐藏问题\n4. 每个节点的锚点，一开始设想是不限位置与个数的，但是写到这里已经按照固定上下左右 4 个来做了，有些方法也是写死了，如果写控件的时候把锚点写在内部或者四个角落，是会出问题的\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwsfe%2Fflowchart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwsfe%2Fflowchart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwsfe%2Fflowchart/lists"}