From 5130ccb9edd9ed68a70c41b6154e9430c924de15 Mon Sep 17 00:00:00 2001 From: ChangeSuger Date: Thu, 10 Oct 2024 18:39:36 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=9C=A8?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E5=90=8E=E5=8A=A8=E6=80=81=E4=BF=AE?= =?UTF-8?q?=E6=94=B9gird=E7=9A=84=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/model/GraphModel.ts | 13 ++++++++++++- packages/core/src/view/Graph.tsx | 3 +-- packages/core/src/view/overlay/Grid.tsx | 20 ++++++++++++-------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/packages/core/src/model/GraphModel.ts b/packages/core/src/model/GraphModel.ts index b28cc09a9..75508b9a2 100644 --- a/packages/core/src/model/GraphModel.ts +++ b/packages/core/src/model/GraphModel.ts @@ -1,4 +1,4 @@ -import { find, forEach, map } from 'lodash-es' +import { find, forEach, map, merge } from 'lodash-es' import { action, computed, observable } from 'mobx' import { BaseEdgeModel, @@ -36,6 +36,7 @@ import { updateTheme, } from '../util' import EventEmitter from '../event/eventEmitter' +import { Grid } from '../view/overlay' import Position = LogicFlow.Position import PointTuple = LogicFlow.PointTuple import GraphData = LogicFlow.GraphData @@ -55,6 +56,8 @@ export class GraphModel { // 流程图主题配置 theme: LogicFlow.Theme + // 网格配置 + @observable grid: Grid.GridOptions // 事件中心 readonly eventCenter: EventEmitter // 维护所有节点和边类型对应的 model @@ -142,6 +145,7 @@ export class GraphModel { this.gridSize = grid.size || 1 // 默认 gridSize 设置为 1 } this.theme = setupTheme(options.style) + this.grid = Grid.getGridOptions(grid ?? false) this.edgeType = options.edgeType || 'polyline' this.animation = setupAnimation(animation) this.overlapMode = options.overlapMode || OverlapMode.DEFAULT @@ -1407,6 +1411,13 @@ export class GraphModel { this.theme = updateTheme({ ...this.theme, ...style }) } + /** + * 更新网格配置 + */ + updateGridOptions(options: Partial) { + merge(this.grid, options) + } + /** * 重新设置画布的宽高 */ diff --git a/packages/core/src/view/Graph.tsx b/packages/core/src/view/Graph.tsx index c98626082..a1262a1c2 100644 --- a/packages/core/src/view/Graph.tsx +++ b/packages/core/src/view/Graph.tsx @@ -87,7 +87,6 @@ class Graph extends Component { if (options.height) { style.height = `${graphModel.height}px` } - const grid = options.grid && Grid.getGridOptions(options.grid) const { fakeNode, editConfigModel } = graphModel const { adjustEdge } = editConfigModel return ( @@ -117,7 +116,7 @@ class Graph extends Component { )} {/* 画布网格 */} - {grid && } + ) } diff --git a/packages/core/src/view/overlay/Grid.tsx b/packages/core/src/view/overlay/Grid.tsx index 22b199c72..80161cafc 100644 --- a/packages/core/src/view/overlay/Grid.tsx +++ b/packages/core/src/view/overlay/Grid.tsx @@ -5,19 +5,24 @@ import { createUuid } from '../../util' import { GraphModel } from '../../model' import { DEFAULT_GRID_SIZE } from '../../constant' -import GridOptions = Grid.GridOptions - -type IProps = GridOptions & { +type IProps = { graphModel: GraphModel } @observer export class Grid extends Component { + gridOptions: Grid.GridOptions + readonly id = createUuid() + constructor(props: IProps) { + super(props) + this.gridOptions = this.props.graphModel.grid + } + // 网格类型为点状 renderDot() { - const { config, size = 1, visible } = this.props + const { config, size = 1, visible } = this.gridOptions const { color, thickness = 2 } = config ?? {} @@ -37,7 +42,7 @@ export class Grid extends Component { // 网格类型为交叉线 // todo: 采用背景缩放的方式,实现更好的体验 renderMesh() { - const { config, size = 1, visible } = this.props + const { config, size = 1, visible } = this.gridOptions const { color, thickness = 1 } = config ?? {} // 对于交叉线网格,线的宽度不能大于网格大小的一半 @@ -57,10 +62,9 @@ export class Grid extends Component { render() { const { - type, - size = 1, graphModel: { transformModel }, } = this.props + const { type, size = 1 } = this.gridOptions const { SCALE_X, SKEW_Y, SKEW_X, SCALE_Y, TRANSLATE_X, TRANSLATE_Y } = transformModel const matrixString = [ @@ -124,7 +128,7 @@ export namespace Grid { /** * 网格的颜色 */ - color: string + color?: string /** * 网格的宽度 * - 对于 `dot` 点状网格,表示点的大小 From eef298a5aae773d209e15efc900c67e9eb14338a Mon Sep 17 00:00:00 2001 From: ChangeSuger Date: Thu, 10 Oct 2024 18:40:10 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat(example):=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=BD=91=E6=A0=BC=E5=8A=A8=E6=80=81=E9=85=8D=E7=BD=AE=E7=9A=84?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/feature-examples/.umirc.ts | 11 + .../src/pages/grid/index.less | 5 + .../feature-examples/src/pages/grid/index.tsx | 219 ++++++++++++++++++ 3 files changed, 235 insertions(+) create mode 100644 examples/feature-examples/src/pages/grid/index.less create mode 100644 examples/feature-examples/src/pages/grid/index.tsx diff --git a/examples/feature-examples/.umirc.ts b/examples/feature-examples/.umirc.ts index db71f011f..24b5a3673 100644 --- a/examples/feature-examples/.umirc.ts +++ b/examples/feature-examples/.umirc.ts @@ -185,5 +185,16 @@ export default defineConfig({ }, ], }, + { + name: 'grid', + path: '/grid', + routes: [ + { + path: '/grid', + name: '动态调整网格配置', + component: './grid', + }, + ], + }, ], }) diff --git a/examples/feature-examples/src/pages/grid/index.less b/examples/feature-examples/src/pages/grid/index.less new file mode 100644 index 000000000..b63a5423f --- /dev/null +++ b/examples/feature-examples/src/pages/grid/index.less @@ -0,0 +1,5 @@ +.viewport { + position: relative; + height: calc(100vh - 300px); + overflow: hidden; +} diff --git a/examples/feature-examples/src/pages/grid/index.tsx b/examples/feature-examples/src/pages/grid/index.tsx new file mode 100644 index 000000000..22f02e0f1 --- /dev/null +++ b/examples/feature-examples/src/pages/grid/index.tsx @@ -0,0 +1,219 @@ +import LogicFlow from '@logicflow/core' + +import { Card, Flex, Form, Radio, Divider, Slider, ColorPicker } from 'antd' +import { useState, useEffect, useRef } from 'react' +import styles from './index.less' + +import '@logicflow/core/es/index.css' +import '@logicflow/extension/es/index.css' + +const config: Partial = { + isSilentMode: false, + stopScrollGraph: false, + stopZoomGraph: false, + stopMoveGraph: true, + style: { + rect: { + rx: 5, + ry: 5, + strokeWidth: 2, + }, + circle: { + fill: '#f5f5f5', + stroke: '#666', + }, + ellipse: { + fill: '#dae8fc', + stroke: '#6c8ebf', + }, + polygon: { + fill: '#d5e8d4', + stroke: '#82b366', + }, + diamond: { + fill: '#ffe6cc', + stroke: '#d79b00', + }, + text: { + color: '#b85450', + fontSize: 12, + }, + }, + allowRotate: true, + allowResize: true, +} + +const data = { + nodes: [ + { + id: '1', + type: 'rect', + x: 150, + y: 100, + text: '矩形', + }, + { + id: '2', + type: 'circle', + x: 350, + y: 100, + text: '圆形', + }, + { + id: '3', + type: 'ellipse', + x: 550, + y: 100, + text: '椭圆', + }, + { + id: '4', + type: 'polygon', + x: 150, + y: 250, + text: '多边形', + }, + { + id: '5', + type: 'diamond', + x: 350, + y: 250, + text: '菱形', + }, + { + id: '6', + type: 'text', + x: 550, + y: 250, + text: '纯文本节点', + }, + { + id: '7', + type: 'html', + x: 150, + y: 400, + text: 'html节点', + }, + ], + edges: [ + { + id: 'e_1', + type: 'polyline', + sourceNodeId: '1', + targetNodeId: '2', + }, + { + id: 'e_2', + type: 'polyline', + sourceNodeId: '2', + targetNodeId: '3', + }, + { + id: 'e_3', + type: 'polyline', + sourceNodeId: '4', + targetNodeId: '5', + }, + ], +} + +export default function SelectionSelectExample() { + const lfRef = useRef() + const [gridVisible, setGridVisible] = useState(true) + const [gridType, setGridType] = useState<'dot' | 'mesh'>('dot') + const [gridSize, setGridSize] = useState(10) + const containerRef = useRef(null) + + // 初始化 LogicFlow + useEffect(() => { + if (!lfRef.current) { + const lf = new LogicFlow({ + ...config, + container: containerRef.current!, + grid: { + size: 20, + }, + }) + + lf.render(data) + lf.translateCenter() + lfRef.current = lf + } + }, []) + + useEffect(() => { + lfRef.current?.graphModel.updateGridOptions({ visible: gridVisible }) + }, [gridVisible]) + + useEffect(() => { + lfRef.current?.graphModel.updateGridOptions({ type: gridType }) + }, [gridType]) + + return ( + + +
+ + setGridVisible(e.target.value)} + > + 显示网格 + 隐藏网格 + + + + setGridType(e.target.value)} + > + 点状网格 + 线状网格 + + + +
+ { + setGridSize(value) + lfRef.current?.graphModel.updateGridOptions({ size: value }) + }} + /> +
+
+ +
+ { + lfRef.current?.graphModel.updateGridOptions({ + config: { thickness: value }, + }) + }} + /> +
+
+ + { + lfRef.current?.graphModel.updateGridOptions({ + config: { color: color.toHexString() }, + }) + }} + /> + +
+
+ +
+
+ ) +}