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

fix(core): 网格对齐改为开关控制 & 修复初始化时流程图偏移问题 #2006

Merged
merged 5 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function CustomPolylineEdge() {
...config,
container: containerRef.current as HTMLElement,
grid: {
size: 10,
size: 20,
},
})

Expand Down Expand Up @@ -307,6 +307,23 @@ export default function CustomPolylineEdge() {
>
开关动画
</Button>
<Button
key="resizeGraph"
type="primary"
onClick={() => {
if (lfRef.current) {
const graphData = lfRef.current?.getEditConfig()
const { snapGrid } = graphData
console.log('snapGrid --->>>', snapGrid)
lfRef.current.updateEditConfig({
snapGrid: !snapGrid,
})
console.log('snapGrid after --->>>', lfRef.current)
}
}}
>
修改网格对齐状态
</Button>
<Select
placeholder="修改边文本位置"
className={styles.select}
Expand Down
27 changes: 19 additions & 8 deletions examples/feature-examples/src/pages/graph/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import OnDragNodeConfig = LogicFlow.OnDragNodeConfig

const config: Partial<LogicFlow.Options> = {
isSilentMode: false,
stopScrollGraph: true,
stopZoomGraph: true,
// stopScrollGraph: true,
// stopZoomGraph: true,
// textDraggable: true, // TODO: 节点旋转状态下,拖动文本移动是有问题的!!!
edgeTextDraggable: true,
style: {
Expand Down Expand Up @@ -255,10 +255,10 @@ export default function BasicNode() {
background: {
color: '#FFFFFF',
},
grid: true,
// grid: {
// size: 1,
// },
// grid: true,
grid: {
size: 60,
},
edgeTextDraggable: true,
edgeType: 'bezier',
// 全局自定义id
Expand Down Expand Up @@ -599,12 +599,23 @@ export default function BasicNode() {
>
切换allowResize
</Button>
<Button key="resizeGraph" type="primary" onClick={handleChangeSize}>
更新画布大小
</Button>
<Button
key="resizeGraph"
type="primary"
onClick={handleChangeSize}
onClick={() => {
if (lfRef.current) {
const graphData = lfRef.current?.getEditConfig()
const { snapGrid } = graphData
lfRef.current.updateEditConfig({
snapGrid: !snapGrid,
})
}
}}
>
更新画布大小
修改网格对齐状态
</Button>
</Flex>
<Divider orientation="left" orientationMargin="5" plain>
Expand Down
18 changes: 17 additions & 1 deletion packages/core/src/LogicFlow.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ComponentType, createElement as h, render } from 'preact/compat'
import { cloneDeep, forEach, indexOf } from 'lodash-es'
import { cloneDeep, forEach, indexOf, isNil } from 'lodash-es'
import { observer } from '.'
import { Options as LFOptions } from './options'
import * as _Model from './model'
Expand Down Expand Up @@ -885,12 +885,28 @@ export class LogicFlow {
*/
updateEditConfig(config: Partial<IEditConfigType>) {
const { editConfigModel, transformModel } = this.graphModel
const currentSnapGrid = editConfigModel.snapGrid

editConfigModel.updateEditConfig(config)
if (config?.stopMoveGraph !== undefined) {
transformModel.updateTranslateLimits(config.stopMoveGraph)
}

// 静默模式切换时,修改快捷键的启用状态
config?.isSilentMode ? this.keyboard.disable() : this.keyboard.enable(true)

// 切换网格对齐状态时,修改网格尺寸
if (!isNil(config?.snapGrid) && config.snapGrid !== currentSnapGrid) {
const {
grid: { size = 1 },
editConfigModel: { snapGrid },
gridSize,
} = this.graphModel
// 开启网格对齐且当前画布网格尺寸与网格对齐尺寸不一致时,或者关闭网格对齐且当前画布网格尺寸不为1时,更新画布网格尺寸
if ((snapGrid && gridSize !== size) || (!snapGrid && gridSize !== 1)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这块儿的判断有点绕,梳理了一下感觉是不是可以不用

删除之后确认一下

this.graphModel.updateGridSize(snapGrid ? size : 1)
}
}
}

/**
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/model/EditConfigModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ export interface IEditConfigType {
nodeTextMode: TextMode
// 边文本类型
edgeTextMode: TextMode
// 开启网格对齐
snapGrid: boolean
}

export type IConfigKeys = keyof IEditConfigType
Expand Down Expand Up @@ -154,6 +156,7 @@ const allKeys = [
'stopZoomGraph', // 禁止缩放画布
'stopScrollGraph', // 禁止鼠标滚动移动画布
'stopMoveGraph', // 禁止拖动画布
'snapGrid', // 是否开启网格对齐
'adjustEdge', // 允许调整边
'adjustEdgeMiddle', // 允许调整边中点
'adjustEdgeStartAndEnd', // 允许调整边起点和终点
Expand Down Expand Up @@ -198,6 +201,7 @@ export class EditConfigModel {
@observable stopZoomGraph = false
@observable stopMoveGraph = false
@observable stopScrollGraph = false
@observable snapGrid = false
/*********************************************************
* 文本相关配置(全局)
********************************************************/
Expand Down
71 changes: 13 additions & 58 deletions packages/core/src/model/GraphModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
merge,
isBoolean,
debounce,
isEqual,
isNil,
} from 'lodash-es'
import { action, computed, observable } from 'mobx'
Expand Down Expand Up @@ -50,7 +49,6 @@ import Position = LogicFlow.Position
import PointTuple = LogicFlow.PointTuple
import GraphData = LogicFlow.GraphData
import NodeConfig = LogicFlow.NodeConfig
import AnchorConfig = Model.AnchorConfig
import BaseNodeModelCtor = LogicFlow.BaseNodeModelCtor
import BaseEdgeModelCtor = LogicFlow.BaseEdgeModelCtor

Expand Down Expand Up @@ -162,7 +160,8 @@ export class GraphModel {
this.rootEl = container
this.partial = !!partial
this.background = background
if (typeof grid === 'object') {
if (typeof grid === 'object' && options.snapGrid) {
// 开启网格对齐时才根据网格尺寸设置步长
this.gridSize = grid.size || 1 // 默认 gridSize 设置为 1
DymoneLewis marked this conversation as resolved.
Show resolved Hide resolved
}
this.theme = setupTheme(options.style)
Expand Down Expand Up @@ -490,58 +489,6 @@ export class GraphModel {
throw new Error(`找不到${edge.type}对应的边。`)
}
const edgeModel = new Model(edge, this)
// 根据edgeModel中存储的数据找到当前画布上的起终锚点坐标
// 判断当前起终锚点数据和Model中存储的起终点数据是否一致,不一致更新起终点信息
const {
sourceNodeId,
targetNodeId,
sourceAnchorId = '',
targetAnchorId = '',
startPoint,
endPoint,
text,
textPosition,
} = edgeModel
const updateAnchorPoint = (
node: BaseNodeModel | undefined,
anchorId: string,
point: Position,
updatePoint: (anchor: AnchorConfig) => void,
) => {
const anchor = node?.anchors.find((anchor) => anchor.id === anchorId)
if (anchor && !isEqual(anchor, point)) {
updatePoint(anchor)
}
}

const sourceNode = this.getNodeModelById(sourceNodeId)
const targetNode = this.getNodeModelById(targetNodeId)

updateAnchorPoint(
sourceNode,
sourceAnchorId,
startPoint,
edgeModel.updateStartPoint.bind(edgeModel),
)
updateAnchorPoint(
targetNode,
targetAnchorId,
endPoint,
edgeModel.updateEndPoint.bind(edgeModel),
)

// 而文本需要先算一下文本与默认文本位置之间的相对位置差
// 再计算新路径的文本默认位置,加上相对位置差,得到调整后边的文本的位置
if (text) {
const { x, y } = text
const { x: defaultX, y: defaultY } = textPosition
if (x && y && defaultX && defaultY) {
const deltaX = x - defaultX
const deltaY = y - defaultY
edgeModel.resetTextPosition()
edgeModel.moveText(deltaX, deltaY)
}
}
this.edgeModelMap.set(edgeModel.id, edgeModel)
this.elementsModelMap.set(edgeModel.id, edgeModel)

Expand Down Expand Up @@ -900,6 +847,7 @@ export class GraphModel {
*/
getModelAfterSnapToGrid(node: NodeConfig) {
const Model = this.getModel(node.type) as BaseNodeModelCtor
const { snapGrid } = this.editConfigModel
if (!Model) {
throw new Error(
`找不到${node.type}对应的节点,请确认是否已注册此类型节点。`,
Expand All @@ -908,8 +856,8 @@ export class GraphModel {
const { x: nodeX, y: nodeY } = node
// 根据 grid 修正节点的 x, y
if (nodeX && nodeY) {
node.x = snapToGrid(nodeX, this.gridSize)
node.y = snapToGrid(nodeY, this.gridSize)
node.x = snapToGrid(nodeX, this.gridSize, snapGrid)
node.y = snapToGrid(nodeY, this.gridSize, snapGrid)
if (typeof node.text === 'object' && node.text !== null) {
// 原来的处理是:node.text.x -= getGridOffset(nodeX, this.gridSize)
// 由于snapToGrid()使用了Math.round()四舍五入的做法,因此无法判断需要执行
Expand Down Expand Up @@ -1526,7 +1474,14 @@ export class GraphModel {
}

/**
* 更新网格配置
* 更新网格尺寸
*/
updateGridSize(size: number) {
this.gridSize = size
}

/**
* 更新背景配置
*/
updateBackgroundOptions(
options: boolean | Partial<LFOptions.BackgroundConfig>,
Expand Down
8 changes: 8 additions & 0 deletions packages/core/src/model/edge/PolylineEdgeModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ export class PolylineEdgeModel extends BaseEdgeModel {

initEdgeData(data: LogicFlow.EdgeConfig): void {
this.offset = 30
if (data.pointsList) {
this.pointsList = data.pointsList
}
super.initEdgeData(data)
}

Expand Down Expand Up @@ -315,6 +318,11 @@ export class PolylineEdgeModel extends BaseEdgeModel {
return list
}

updatePath(pointList: Point[]) {
this.pointsList = pointList
this.points = this.getPath(this.pointsList)
}

getData() {
const data = super.getData()
const pointsList = this.pointsList.map(({ x, y }) => ({
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/util/geometry.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import LogicFlow from '../LogicFlow'
import PointTuple = LogicFlow.PointTuple

export function snapToGrid(point: number, gridSize: number) {
export function snapToGrid(point: number, gridSize: number, snapGrid: boolean) {
// 开启节网格对齐时才根据网格尺寸校准坐标
if (!snapGrid) return point
// 保证 x, y 的值为 gridSize 的整数倍
return gridSize * Math.round(point / gridSize) || point
}
Expand Down
7 changes: 5 additions & 2 deletions packages/core/src/view/behavior/dnd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@ export class Dnd {
})
// 处理缩放和偏移
const { x: x1, y: y1 } = position.canvasOverlayPosition
const {
editConfigModel: { snapGrid },
} = this.lf.graphModel
// x, y 对齐到网格的 size
return {
x: snapToGrid(x1, gridSize),
y: snapToGrid(y1, gridSize),
x: snapToGrid(x1, gridSize, snapGrid),
y: snapToGrid(y1, gridSize, snapGrid),
}
}

Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/view/node/BaseNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ export abstract class BaseNode<P extends IProps = IProps> extends Component<
onDragging = ({ event }: IDragParams) => {
const { model, graphModel } = this.props
const {
editConfigModel: { stopMoveGraph, autoExpand },
editConfigModel: { stopMoveGraph, autoExpand, snapGrid },
transformModel,
selectNodes,
width,
Expand All @@ -261,9 +261,9 @@ export abstract class BaseNode<P extends IProps = IProps> extends Component<
// 2. 考虑鼠标位置不再节点中心
x = x + (this.moveOffset?.dx ?? 0)
y = y + (this.moveOffset?.dy ?? 0)
// 将x, y移动到grid上
x = snapToGrid(x, gridSize)
y = snapToGrid(y, gridSize)
// 校准坐标
x = snapToGrid(x, gridSize, snapGrid)
y = snapToGrid(y, gridSize, snapGrid)
if (!width || !height) {
graphModel.moveNode2Coordinate(model.id, x, y)
return
Expand Down
11 changes: 6 additions & 5 deletions packages/core/src/view/overlay/CanvasOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ export class CanvasOverlay extends Component<IProps, IState> {
graphModel,
} = this.props
const { deltaX: eX, deltaY: eY } = ev
const { stopScrollGraph, stopZoomGraph } = editConfigModel
// 如果没有禁止滚动移动画布, 并且当前触发的时候ctrl键、cmd键没有按住, 那么移动画布
if (!editConfigModel.stopScrollGraph && !ev.ctrlKey && !ev.metaKey) {
if (!stopScrollGraph && !ev.ctrlKey && !ev.metaKey) {
ev.preventDefault()
this.stepScrollX += eX
this.stepScrollY += eY
Expand All @@ -85,7 +86,7 @@ export class CanvasOverlay extends Component<IProps, IState> {
return
}
// 如果没有禁止缩放画布,那么进行缩放. 在禁止缩放画布后,按住 ctrl、cmd 键也不能缩放了。
if (!editConfigModel.stopZoomGraph) {
if (!stopZoomGraph) {
ev.preventDefault()
const position = graphModel.getPointByClient({
x: ev.clientX,
Expand Down Expand Up @@ -133,11 +134,11 @@ export class CanvasOverlay extends Component<IProps, IState> {
gridSize,
},
} = this.props
const { adjustEdge, adjustNodePosition, stopMoveGraph } = editConfigModel
const target = ev.target as HTMLElement
const isFrozenElement =
!editConfigModel.adjustEdge && !editConfigModel.adjustNodePosition
const isFrozenElement = !adjustEdge && !adjustNodePosition
if (target.getAttribute('name') === 'canvas-overlay' || isFrozenElement) {
if (editConfigModel.stopMoveGraph !== true) {
if (stopMoveGraph !== true) {
this.stepDrag.setStep(gridSize * SCALE_X)
this.stepDrag.handleMouseDown(ev)
} else {
Expand Down