Skip to content

Commit 4fc34d4

Browse files
committed
fix: new selection select
1 parent 1acbb3a commit 4fc34d4

File tree

7 files changed

+121
-92
lines changed

7 files changed

+121
-92
lines changed

docs/guide/extension/component-dnd-panel.md

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,8 @@
11
# 拖拽面板
22

3-
## 启用
3+
### 自定义拖拽面板内容
44

5-
```ts
6-
import LogicFlow from '@logicflow/core';
7-
import { DndPanel } from '@logicflow/extension';
8-
import '@logicflow/extension/lib/style/index.css'
9-
10-
LogicFlow.use(DndPanel);
11-
```
12-
13-
注册`DndPanel`组件后,Logic Flow 会在画布左上方创建一个拖拽面板,如下所示
14-
15-
<example href="/examples/#/extension/components/dnd-panel"></example>
16-
17-
## 自定义拖拽面板内容
18-
19-
### lf.setPatternItems
5+
**lf.setPatternItems(patternItems)**
206

217
设置拖拽面板组件内容
228

@@ -34,8 +20,6 @@ lf.setPatternItems(patternItems: PatternItem[])
3420

3521
```
3622

37-
38-
3923
PatternItem:
4024

4125
| 名称 | 类型 | 必选 | 默认值 | 描述 |
@@ -48,19 +32,27 @@ PatternItem:
4832
|className|string|非必须||额外传入可以拖拽项的class, 用于自定义拖拽项的样式|
4933
|callback|fn|非必须||用户鼠标按下拖拽项后触发的回调|
5034

35+
### 使用示例
36+
5137
```js
38+
import LogicFlow from '@logicflow/core';
39+
import { DndPanel, SelectionSelect } from '@logicflow/extension';
40+
import '@logicflow/extension/lib/style/index.css'
41+
5242
LogicFlow.use(DndPanel);
5343
LogicFlow.use(SelectionSelect);
5444
const lf = new LogicFlow({
5545
container: document.querySelector('#graph') as HTMLElement
5646
});
47+
5748
lf.setPatternItems([
5849
{
59-
text: '选区',
50+
label: '选区',
6051
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAOVJREFUOBGtVMENwzAIjKP++2026ETdpv10iy7WFbqFyyW6GBywLCv5gI+Dw2Bluj1znuSjhb99Gkn6QILDY2imo60p8nsnc9bEo3+QJ+AKHfMdZHnl78wyTnyHZD53Zzx73MRSgYvnqgCUHj6gwdck7Zsp1VOrz0Uz8NbKunzAW+Gu4fYW28bUYutYlzSa7B84Fh7d1kjLwhcSdYAYrdkMQVpsBr5XgDGuXwQfQr0y9zwLda+DUYXLaGKdd2ZTtvbolaO87pdo24hP7ov16N0zArH1ur3iwJpXxm+v7oAJNR4JEP8DoAuSFEkYH7cAAAAASUVORK5CYII=',
6152
callback: () => {
62-
lf.updateEditConfig({
63-
stopMoveGraph: true,
53+
lf.openSelectionSelect();
54+
lf.once('selection:selected', () => {
55+
lf.closeSelectionSelect();
6456
});
6557
}
6658
},
@@ -74,7 +66,7 @@ lf.setPatternItems([
7466
type: 'rect',
7567
label: '用户任务',
7668
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==',
77-
cls: 'important-node'
69+
className: 'important-node'
7870
},
7971
{
8072
type: 'rect',
@@ -89,10 +81,15 @@ lf.setPatternItems([
8981
},
9082
{
9183
type: 'circle',
84+
text: '结束',
9285
label: '结束节点',
93-
text: '结束'
9486
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAA1BJREFUOBFtVE1IVUEYPXOf+tq40Y3vPcmFIdSjIorWoRG0ERWUgnb5FwVhYQSl72oUoZAboxKNFtWiwKRN0M+jpfSzqJAQclHo001tKkjl3emc8V69igP3znzfnO/M9zcDcKT67azmjYWTwl9Vn7Vumeqzj1DVb6cleQY4oAVnIOPb+mKAGxQmKI5CWNJ2aLPatxWa3aB9K7/fB+/Z0jUF6TmMlFLQqrkECWQzOZxYGjTlOl8eeKaIY5yHnFn486xBustDjWT6dG7pmjHOJd+33t0iitTPkK6tEvjxq4h2MozQ6WFSX/LkDUGfFwfhEZj1Auz/U4pyAi5Sznd7uKzznXeVHlI/Aywmk6j7fsUsEuCGADrWARXXwjxWQsUbIupDHJI7kF5dRktg0eN81IbiZXiTESic50iwS+t1oJgL83jAiBupLDCQqwziaWSoAFSeIR3P5Xv5az00wyIn35QRYTwdSYbz8pH8fxUUAtxnFvYmEmgI0wYXUXcCCSpeEVpXlsRhBnCEATxWylL9+EKCAYhe1NGstUa6356kS9NVvt3DU2fd+Wtbm/+lSbylJqsqkSm9CRhvoJVlvKPvF1RKY/FcPn5j4UfIMLn8D4UYb54BNsilTDXKnF4CfTobA0FpoW/LSp306wkXM+XaOJhZaFkcNM82ASNAWMrhrUbRfmyeI1FvRBTpN06WKxa9BK0o2E4Pd3zfBBEwPsv9sQBnmLVbLEIZ/Xe9LYwJu/Er17W6HYVBc7vmuk0xUQ+pqxdom5Fnp55SiytXLPYoMXNM4u4SNSCFWnrVIzKG3EGyMXo6n/BQOe+bX3FClY4PwydVhthOZ9NnS+ntiLh0fxtlUJHAuGaFoVmttpVMeum0p3WEXbcll94l1wM/gZ0Ccczop77VvN2I7TlsZCsuXf1WHvWEhjO8DPtyOVg2/mvK9QqboEth+7pD6NUQC1HN/TwvydGBARi9MZSzLE4b8Ru3XhX2PBxf8E1er2A6516o0w4sIA+lwURhAON82Kwe2iDAC1Watq4XHaGQ7skLcFOtI5lDxuM2gZe6WFIotPAhbaeYlU4to5cuarF1QrcZ/lwrLaCJl66JBocYZnrNlvm2+MBCTmUymPrYZVbjdlr/BxlMjmNmNI3SAAAAAElFTkSuQmCC',
9587
}
9688
]);
9789
```
9890

91+
### 效果
92+
93+
使用`DndPanel`组件,可以快捷的拖拽面板,如下所示
94+
95+
<example href="/examples/#/extension/components/dnd-panel"></example>
Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,40 @@
11
# 框选
22

3-
## 启用
4-
53
```ts
64
import LogicFlow from '@logicflow/core';
75
import { SelectionSelect } from '@logicflow/extension';
86
import '@logicflow/extension/lib/style/index.css'
97

108
LogicFlow.use(SelectionSelect);
9+
1110
```
11+
### 开启
1212

13-
## 开启
13+
```ts
14+
lf.openSelectionSelect();
15+
```
1416

15-
引入组件后默认开启。
17+
### 关闭
1618

1719
```ts
18-
SelectionSelect.open();
20+
lf.closeSelectionSelect();
1921
```
2022

21-
> 使用多选组件时,需要在初始化 LogicFLow 时将编辑属性`stopMoveGraph`设置为`true`,或者使用[updateEditConfig](/api/logicFlowApi.html#updateeditconfig) API 来动态开启或关闭`stopMoveGraph`
23+
<example href="/examples/#/extension/components/selection" :height="300" ></example>
24+
### 默认状态
2225

23-
## 关闭
26+
默认是否开启框选功能,受到页面是否允许拖动画布影响。画布可以拖动与选区不能同时存在。
2427

25-
```ts
26-
SelectionSelect.close();
28+
```js
29+
const lf = new LogicFlow({
30+
container: document.querySelector('#app'),
31+
stopMoveGraph: true,
32+
})
2733
```
2834

29-
<example href="/examples/#/extension/components/selection" :height="300" ></example>
35+
如果`stopMoveGraph`为true,也就是不允许拖动画布,那么默认则可以进行框选。
36+
37+
如果`stopMoveGraph`不为true, 也就是允许拖动画布,那么默认则不可以进行框选。
38+
39+
大多数情况下,我们期望允许拖动画布,当用户点击拖拽面板后才开启选区。请参考[拖拽面板插件](/guide/extension/component-dnd-panel.html)
40+

examples/src/pages/extension/components/dnd-panel/index.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ export default function DndPanelExample() {
2525
label: '选区',
2626
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAOVJREFUOBGtVMENwzAIjKP++2026ETdpv10iy7WFbqFyyW6GBywLCv5gI+Dw2Bluj1znuSjhb99Gkn6QILDY2imo60p8nsnc9bEo3+QJ+AKHfMdZHnl78wyTnyHZD53Zzx73MRSgYvnqgCUHj6gwdck7Zsp1VOrz0Uz8NbKunzAW+Gu4fYW28bUYutYlzSa7B84Fh7d1kjLwhcSdYAYrdkMQVpsBr5XgDGuXwQfQr0y9zwLda+DUYXLaGKdd2ZTtvbolaO87pdo24hP7ov16N0zArH1ur3iwJpXxm+v7oAJNR4JEP8DoAuSFEkYH7cAAAAASUVORK5CYII=',
2727
callback: () => {
28-
lf.updateEditConfig({
29-
stopMoveGraph: true,
28+
lf.openSelectionSelect();
29+
lf.once('selection:selected', () => {
30+
lf.closeSelectionSelect();
3031
});
3132
}
3233
},

examples/src/pages/extension/components/selection/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ export default function DndPanelExample() {
6161

6262
function handleSwitch() {
6363
if (isOpened) {
64-
SelectionSelect.close();
64+
lf.closeSelectionSelect();
6565
} else {
66-
SelectionSelect.open();
66+
lf.openSelectionSelect();
6767
}
6868
setIsOpened(!isOpened);
6969
}

packages/core/src/LogicFlow.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,10 @@ export default class LogicFlow {
117117
off(evt: string, callback: CallbackType) {
118118
this.eventCenter.off(evt, callback);
119119
}
120-
emit(evt: string, arg: Record<string, string | number | object>) {
120+
once(evt: string, callback: CallbackType) {
121+
this.eventCenter.once(evt, callback);
122+
}
123+
emit(evt: string, arg: any) {
121124
this.eventCenter.emit(evt, arg);
122125
}
123126

packages/extension/examples/bpmn/index.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ window.onload = function () {
55
container: document.querySelector('#app'),
66
edgeTextDraggable: true,
77
nodeTextDraggable: true,
8+
// stopMoveGraph: true,
89
metaKeyMultipleSelected: true,
910
grid: {
1011
type: 'dot',
@@ -44,13 +45,15 @@ window.onload = function () {
4445
// },
4546
// ]
4647
// })
48+
// lf.closeSelectionSelect();
4749
lf.setPatternItems([
4850
{
4951
label: '选区',
5052
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAOVJREFUOBGtVMENwzAIjKP++2026ETdpv10iy7WFbqFyyW6GBywLCv5gI+Dw2Bluj1znuSjhb99Gkn6QILDY2imo60p8nsnc9bEo3+QJ+AKHfMdZHnl78wyTnyHZD53Zzx73MRSgYvnqgCUHj6gwdck7Zsp1VOrz0Uz8NbKunzAW+Gu4fYW28bUYutYlzSa7B84Fh7d1kjLwhcSdYAYrdkMQVpsBr5XgDGuXwQfQr0y9zwLda+DUYXLaGKdd2ZTtvbolaO87pdo24hP7ov16N0zArH1ur3iwJpXxm+v7oAJNR4JEP8DoAuSFEkYH7cAAAAASUVORK5CYII=',
5153
callback: () => {
52-
lf.updateEditConfig({
53-
stopMoveGraph: true,
54+
lf.openSelectionSelect();
55+
lf.once('selection:selected', () => {
56+
lf.closeSelectionSelect();
5457
});
5558
}
5659
},
@@ -106,12 +109,6 @@ window.onload = function () {
106109
// stopMoveGraph: true,
107110
// });
108111
// });
109-
110-
lf.on('selection:selected', () => {
111-
lf.updateEditConfig({
112-
stopMoveGraph: false,
113-
});
114-
});
115112
// document.querySelector('#start-node-pattern').addEventListener('mousedown', () => {
116113
// lf.dnd.startDrag({
117114
// type: 'bpmn:startEvent',
Lines changed: 66 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,77 @@
1-
import { Extension } from '@logicflow/core';
1+
import LogicFlow, { Extension } from '@logicflow/core';
22

33
interface SelectionSelectPlugin extends Extension {
44
open: () => void;
55
close: () => void;
66
[x: string]: any;
77
}
88

9-
const SelectionSelect: SelectionSelectPlugin = {
10-
pluginName: 'selection-select',
11-
__domContainer: null,
12-
wrapper: null,
13-
lf: null,
9+
class SelectionSelect {
10+
__domContainer: HTMLElement;
11+
wrapper: HTMLElement;
12+
lf: LogicFlow;
1413
startPoint: {
15-
x: 0,
16-
y: 0,
17-
},
14+
x: number,
15+
y: number,
16+
};
1817
endPoint: {
19-
x: 0,
20-
y: 0,
21-
},
22-
__disabled: false,
23-
install() {},
18+
x: number,
19+
y: number,
20+
};
21+
__disabled = false;
22+
isDefalutStopMoveGraph = false;
23+
static pluginName = 'selection-select';
24+
constructor({ lf }) {
25+
this.lf = lf;
26+
lf.openSelectionSelect = () => {
27+
const { stopMoveGraph } = lf.getEditConfig();
28+
if (!stopMoveGraph) {
29+
this.isDefalutStopMoveGraph = false;
30+
lf.updateEditConfig({
31+
stopMoveGraph: true,
32+
});
33+
}
34+
this.open();
35+
};
36+
lf.closeSelectionSelect = () => {
37+
if (!this.isDefalutStopMoveGraph) {
38+
lf.updateEditConfig({
39+
stopMoveGraph: false,
40+
});
41+
}
42+
this.close();
43+
};
44+
}
2445
render(lf, domContainer) {
25-
SelectionSelect.__domContainer = domContainer;
26-
SelectionSelect.lf = lf;
46+
this.__domContainer = domContainer;
2747
lf.on('blank:mousedown', ({ e }) => {
2848
const config = lf.getEditConfig();
2949
// 鼠标控制滚动移动画布的时候,不能选区。
30-
if (!config.stopMoveGraph || SelectionSelect.__disabled) {
50+
if (!config.stopMoveGraph || this.__disabled) {
3151
return;
3252
}
3353
const {
3454
domOverlayPosition: { x, y },
3555
} = lf.getPointByClient(e.clientX, e.clientY);
36-
SelectionSelect.startPoint = { x, y };
37-
SelectionSelect.endPoint = { x, y };
56+
this.startPoint = { x, y };
57+
this.endPoint = { x, y };
3858
const wrapper = document.createElement('div');
3959
wrapper.className = 'lf-selection-select';
40-
wrapper.style.top = `${SelectionSelect.startPoint.y}px`;
41-
wrapper.style.left = `${SelectionSelect.startPoint.x}px`;
60+
wrapper.style.top = `${this.startPoint.y}px`;
61+
wrapper.style.left = `${this.startPoint.x}px`;
4262
domContainer.appendChild(wrapper);
43-
SelectionSelect.wrapper = wrapper;
44-
document.addEventListener('mousemove', SelectionSelect.__draw);
45-
document.addEventListener('mouseup', SelectionSelect.__drawOff);
63+
this.wrapper = wrapper;
64+
document.addEventListener('mousemove', this.__draw);
65+
document.addEventListener('mouseup', this.__drawOff);
4666
});
47-
},
48-
__draw(ev) {
67+
}
68+
__draw = (ev) => {
4969
const {
5070
domOverlayPosition: { x: x1, y: y1 },
51-
} = SelectionSelect.lf.getPointByClient(ev.clientX, ev.clientY);
52-
SelectionSelect.endPoint = { x: x1, y: y1 };
53-
const { x, y } = SelectionSelect.startPoint;
54-
const { style } = SelectionSelect.wrapper;
71+
} = this.lf.getPointByClient(ev.clientX, ev.clientY);
72+
this.endPoint = { x: x1, y: y1 };
73+
const { x, y } = this.startPoint;
74+
const { style } = this.wrapper;
5575
let left = x;
5676
let top = y;
5777
let width = x1 - x;
@@ -68,27 +88,27 @@ const SelectionSelect: SelectionSelectPlugin = {
6888
style.top = `${top}px`;
6989
style.width = `${width}px`;
7090
style.height = `${height}px`;
71-
},
72-
__drawOff() {
73-
document.removeEventListener('mousemove', SelectionSelect.__draw);
74-
document.removeEventListener('mouseup', SelectionSelect.__drawOff);
75-
SelectionSelect.__domContainer.removeChild(SelectionSelect.wrapper);
76-
const { x, y } = SelectionSelect.startPoint;
77-
const { x: x1, y: y1 } = SelectionSelect.endPoint;
91+
};
92+
__drawOff = () => {
93+
document.removeEventListener('mousemove', this.__draw);
94+
document.removeEventListener('mouseup', this.__drawOff);
95+
this.__domContainer.removeChild(this.wrapper);
96+
const { x, y } = this.startPoint;
97+
const { x: x1, y: y1 } = this.endPoint;
7898
const lt = [Math.min(x, x1), Math.min(y, y1)];
7999
const rt = [Math.max(x, x1), Math.max(y, y1)];
80-
const elements = SelectionSelect.lf.getAreaElement(lt, rt);
100+
const elements = this.lf.getAreaElement(lt, rt);
81101
elements.forEach((element) => {
82-
SelectionSelect.lf.select(element.id, true);
102+
this.lf.select(element.id, true);
83103
});
84-
SelectionSelect.lf.emit('selection:selected', elements);
85-
},
104+
this.lf.emit('selection:selected', elements);
105+
};
86106
open() {
87-
SelectionSelect.__disabled = false;
88-
},
107+
this.__disabled = false;
108+
}
89109
close() {
90-
SelectionSelect.__disabled = true;
91-
},
92-
};
110+
this.__disabled = true;
111+
}
112+
}
93113

94114
export { SelectionSelect };

0 commit comments

Comments
 (0)