Skip to content

Commit 6c47f7d

Browse files
authored
Merge pull request #1550 from wbccb/fix/1545
fix(core): snap the text pos of cloneNode to grid(#1545)
2 parents 27ca25b + dc661bd commit 6c47f7d

File tree

3 files changed

+136
-25
lines changed

3 files changed

+136
-25
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import type { NodeConfig, TextConfig } from '../../src/index';
2+
import { LogicFlow } from '../../src/index';
3+
4+
type NodeConfigTextObj = NodeConfig & { text: TextConfig };
5+
describe('#1545', () => {
6+
const dom = document.createElement('div');
7+
dom.id = 'main-graph';
8+
document.body.appendChild(dom);
9+
const lf = new LogicFlow({
10+
container: dom,
11+
width: 1000,
12+
height: 1000,
13+
grid: true,
14+
});
15+
16+
it('clone node text pos should snap to grid', () => {
17+
lf.render({
18+
nodes: [
19+
{
20+
id: 'node_id_1',
21+
type: 'rect',
22+
x: 300,
23+
y: 300,
24+
text: {
25+
x: 32,
26+
y: 19,
27+
value: '文本1',
28+
},
29+
},
30+
],
31+
});
32+
const originNode = lf.getDataById('node_id_1') as NodeConfigTextObj;
33+
const newNode = lf.cloneNode('node_id_1') as NodeConfigTextObj;
34+
expect(originNode.x - originNode.text.x).toEqual(newNode.x - newNode.text.x);
35+
expect(originNode.y - originNode.text.y).toEqual(newNode.y - newNode.text.y);
36+
expect(originNode.text.value).toEqual(newNode.text.value);
37+
});
38+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import type { NodeConfig, TextConfig } from '../../src/index';
2+
import { LogicFlow } from '../../src/index';
3+
4+
type NodeConfigTextObj = NodeConfig & { text: TextConfig };
5+
describe('graphmodel', () => {
6+
const dom = document.createElement('div');
7+
dom.id = 'main-graph';
8+
document.body.appendChild(dom);
9+
const lf = new LogicFlow({
10+
container: dom,
11+
width: 1000,
12+
height: 1000,
13+
keyboard: {
14+
enabled: true,
15+
},
16+
allowRotation: true,
17+
metaKeyMultipleSelected: true,
18+
grid: true,
19+
snapline: true,
20+
});
21+
22+
// 将node节点位置进行grid修正,同时处理node内文字的偏移量,返回一个位置修正过的复制节点NodeModel
23+
test('getModelAfterSnapToGrid', () => {
24+
const rawData = {
25+
nodes: [
26+
{
27+
id: 'node1',
28+
type: 'rect',
29+
x: 111,
30+
y: 123,
31+
text: {
32+
x: 32,
33+
y: 19,
34+
value: '文本1',
35+
},
36+
},
37+
],
38+
};
39+
lf.render(rawData);
40+
41+
const originNode = lf.getDataById('node1') as NodeConfigTextObj;
42+
43+
// grid=true 默认 gridSize=20
44+
const newNode = lf.graphModel.getModelAfterSnapToGrid(originNode) as NodeConfigTextObj;
45+
expect(originNode.x - originNode.text.x).toEqual(newNode.x - newNode.text.x);
46+
expect(originNode.y - originNode.text.y).toEqual(newNode.y - newNode.text.y);
47+
expect(originNode.text.value).toEqual(newNode.text.value);
48+
49+
lf.graphModel.gridSize = 40;
50+
const newNode1 = lf.graphModel.getModelAfterSnapToGrid(originNode) as NodeConfigTextObj;
51+
expect(originNode.x - originNode.text.x).toEqual(newNode1.x - newNode1.text.x);
52+
expect(originNode.y - originNode.text.y).toEqual(newNode1.y - newNode1.text.y);
53+
expect(originNode.text.value).toEqual(newNode1.text.value);
54+
55+
lf.graphModel.gridSize = 1;
56+
const newNode2 = lf.graphModel.getModelAfterSnapToGrid(originNode) as NodeConfigTextObj;
57+
expect(originNode.x - originNode.text.x).toEqual(newNode2.x - newNode2.text.x);
58+
expect(originNode.y - originNode.text.y).toEqual(newNode2.y - newNode2.text.y);
59+
expect(originNode.text.value).toEqual(newNode2.text.value);
60+
61+
lf.graphModel.gridSize = 17;
62+
const newNode3 = lf.graphModel.getModelAfterSnapToGrid(originNode) as NodeConfigTextObj;
63+
expect(originNode.x - originNode.text.x).toEqual(newNode3.x - newNode3.text.x);
64+
expect(originNode.y - originNode.text.y).toEqual(newNode3.y - newNode3.text.y);
65+
expect(originNode.text.value).toEqual(newNode3.text.value);
66+
});
67+
});

packages/core/src/model/GraphModel.ts

+31-25
Original file line numberDiff line numberDiff line change
@@ -380,23 +380,7 @@ class GraphModel {
380380
return;
381381
}
382382
if (graphData.nodes) {
383-
this.nodes = map(graphData.nodes, node => {
384-
const Model = this.getModel(node.type);
385-
if (!Model) {
386-
throw new Error(`找不到${node.type}对应的节点。`);
387-
}
388-
const { x: nodeX, y: nodeY } = node;
389-
// 根据 grid 修正节点的 x, y
390-
if (nodeX && nodeY) {
391-
node.x = snapToGrid(nodeX, this.gridSize);
392-
node.y = snapToGrid(nodeY, this.gridSize);
393-
if (typeof node.text === 'object') {
394-
node.text.x -= getGridOffset(nodeX, this.gridSize);
395-
node.text.y -= getGridOffset(nodeY, this.gridSize);
396-
}
397-
}
398-
return new Model(node, this);
399-
});
383+
this.nodes = map(graphData.nodes, (node: NodeConfig) => this.getModelAfterSnapToGrid(node));
400384
} else {
401385
this.nodes = [];
402386
}
@@ -681,13 +665,7 @@ class GraphModel {
681665
if (nodeOriginData.id && this.nodesMap[nodeConfig.id]) {
682666
delete nodeOriginData.id;
683667
}
684-
const Model = this.getModel(nodeOriginData.type);
685-
if (!Model) {
686-
throw new Error(`找不到${nodeOriginData.type}对应的节点,请确认是否已注册此类型节点。`);
687-
}
688-
nodeOriginData.x = snapToGrid(nodeOriginData.x, this.gridSize);
689-
nodeOriginData.y = snapToGrid(nodeOriginData.y, this.gridSize);
690-
const nodeModel = new Model(nodeOriginData, this);
668+
const nodeModel = this.getModelAfterSnapToGrid(nodeOriginData);
691669
this.nodes.push(nodeModel);
692670
const nodeData = nodeModel.getData();
693671
const eventData: Record<string, any> = { data: nodeData };
@@ -697,7 +675,35 @@ class GraphModel {
697675
this.eventCenter.emit(eventType, eventData);
698676
return nodeModel;
699677
}
700-
678+
/**
679+
* 将node节点位置进行grid修正
680+
* 同时处理node内文字的偏移量
681+
* 返回一个位置修正过的复制节点NodeModel
682+
* @param node
683+
*/
684+
getModelAfterSnapToGrid(node: NodeConfig) {
685+
const Model = this.getModel(node.type);
686+
if (!Model) {
687+
throw new Error(`找不到${node.type}对应的节点,请确认是否已注册此类型节点。`);
688+
}
689+
const { x: nodeX, y: nodeY } = node;
690+
// 根据 grid 修正节点的 x, y
691+
if (nodeX && nodeY) {
692+
node.x = snapToGrid(nodeX, this.gridSize);
693+
node.y = snapToGrid(nodeY, this.gridSize);
694+
if (typeof node.text === 'object') {
695+
// 原来的处理是:node.text.x -= getGridOffset(nodeX, this.gridSize);
696+
// 由于snapToGrid()使用了Math.round()四舍五入的做法,因此无法判断需要执行
697+
// node.text.x = node.text.x + getGridOffset()
698+
// 还是
699+
// node.text.x = node.text.x - getGridOffset()
700+
// 直接改为node.x - nodeX就可以满足上面的要求
701+
node.text.x += (node.x - nodeX);
702+
node.text.y += (node.y - nodeY);
703+
}
704+
}
705+
return new Model(node, this);
706+
}
701707
/**
702708
* 克隆节点
703709
* @param nodeId 节点Id

0 commit comments

Comments
 (0)