Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 支持动态修改 Grid 的配置 #1901

Merged
merged 2 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions examples/feature-examples/.umirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,5 +185,16 @@ export default defineConfig({
},
],
},
{
name: 'grid',
path: '/grid',
routes: [
{
path: '/grid',
name: '动态调整网格配置',
component: './grid',
},
],
},
],
})
5 changes: 5 additions & 0 deletions examples/feature-examples/src/pages/grid/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.viewport {
position: relative;
height: calc(100vh - 300px);
overflow: hidden;
}
219 changes: 219 additions & 0 deletions examples/feature-examples/src/pages/grid/index.tsx
Original file line number Diff line number Diff line change
@@ -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<LogicFlow.Options> = {
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<LogicFlow>()
const [gridVisible, setGridVisible] = useState(true)
const [gridType, setGridType] = useState<'dot' | 'mesh'>('dot')
const [gridSize, setGridSize] = useState(10)
const containerRef = useRef<HTMLDivElement>(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 (
<Card title="LogicFlow - Grid">
<Flex wrap="wrap" gap="middle" align="center" justify="space-between">
<Form layout="inline">
<Form.Item label="网格显隐">
<Radio.Group
value={gridVisible}
onChange={(e) => setGridVisible(e.target.value)}
>
<Radio.Button value={true}>显示网格</Radio.Button>
<Radio.Button value={false}>隐藏网格</Radio.Button>
</Radio.Group>
</Form.Item>
<Form.Item label="网格类型">
<Radio.Group
value={gridType}
onChange={(e) => setGridType(e.target.value)}
>
<Radio.Button value={'dot'}>点状网格</Radio.Button>
<Radio.Button value={'mesh'}>线状网格</Radio.Button>
</Radio.Group>
</Form.Item>
<Form.Item label="网格大小">
<div style={{ width: '100px' }}>
<Slider
min={5}
max={40}
step={1}
value={gridSize}
onChange={(value) => {
setGridSize(value)
lfRef.current?.graphModel.updateGridOptions({ size: value })
}}
/>
</div>
</Form.Item>
<Form.Item label="网格宽度">
<div style={{ width: '100px' }}>
<Slider
min={1}
max={gridSize / 4}
step={1}
defaultValue={1}
onChange={(value) => {
lfRef.current?.graphModel.updateGridOptions({
config: { thickness: value },
})
}}
/>
</div>
</Form.Item>
<Form.Item label="网格颜色">
<ColorPicker
value={'#ababab'}
onChange={(color) => {
lfRef.current?.graphModel.updateGridOptions({
config: { color: color.toHexString() },
})
}}
/>
</Form.Item>
</Form>
</Flex>
<Divider />
<div ref={containerRef} id="graph" className={styles.viewport}></div>
</Card>
)
}
13 changes: 12 additions & 1 deletion packages/core/src/model/GraphModel.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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
Expand All @@ -55,6 +56,8 @@ export class GraphModel {

// 流程图主题配置
theme: LogicFlow.Theme
// 网格配置
@observable grid: Grid.GridOptions
// 事件中心
readonly eventCenter: EventEmitter
// 维护所有节点和边类型对应的 model
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1407,6 +1411,13 @@ export class GraphModel {
this.theme = updateTheme({ ...this.theme, ...style })
}

/**
* 更新网格配置
*/
updateGridOptions(options: Partial<Grid.GridOptions>) {
merge(this.grid, options)
}

/**
* 重新设置画布的宽高
*/
Expand Down
3 changes: 1 addition & 2 deletions packages/core/src/view/Graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ class Graph extends Component<IGraphProps> {
if (options.height) {
style.height = `${graphModel.height}px`
}
const grid = options.grid && Grid.getGridOptions(options.grid)
const { fakeNode, editConfigModel } = graphModel
const { adjustEdge } = editConfigModel
return (
Expand Down Expand Up @@ -117,7 +116,7 @@ class Graph extends Component<IGraphProps> {
<BackgroundOverlay background={options.background} />
)}
{/* 画布网格 */}
{grid && <Grid {...grid} graphModel={graphModel} />}
<Grid graphModel={graphModel} />
</div>
)
}
Expand Down
20 changes: 12 additions & 8 deletions packages/core/src/view/overlay/Grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<IProps> {
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 ?? {}

Expand All @@ -37,7 +42,7 @@ export class Grid extends Component<IProps> {
// 网格类型为交叉线
// todo: 采用背景缩放的方式,实现更好的体验
renderMesh() {
const { config, size = 1, visible } = this.props
const { config, size = 1, visible } = this.gridOptions
const { color, thickness = 1 } = config ?? {}

// 对于交叉线网格,线的宽度不能大于网格大小的一半
Expand All @@ -57,10 +62,9 @@ export class Grid extends Component<IProps> {

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 = [
Expand Down Expand Up @@ -124,7 +128,7 @@ export namespace Grid {
/**
* 网格的颜色
*/
color: string
color?: string
/**
* 网格的宽度
* - 对于 `dot` 点状网格,表示点的大小
Expand Down