事件 Event
当我们使用鼠标或其他方式与画布交互时,会触发对应的事件。通过监听这些事件,可以获取其在触发时所产生的数据,根据这些数据来实现需要的功能。详细可监听事件见事件API。
监听事件
lf
实例上提供on
方法支持监听事件。
lf.on("node:dnd-add", (data) => {});
LogicFlow 支持用逗号分割事件名。
lf.on("node:click,edge:click", (data) => {});
自定义事件
除了 lf 上支持的监听事件外,还可以使用eventCenter对象来监听和触发事件。eventCenter
是一个graphModel
上的一个属性。所以在自定义节点的时候,我们可以使用eventCenter
触发自定义事件。
class ButtonNode extends HtmlNode {
setHtml(rootEl) {
const { properties } = this.props.model;
const el = document.createElement("div");
el.className = "uml-wrapper";
const html = `
<div>
<div class="uml-head">Head</div>
<div class="uml-body">
<div><button οnclick="setData()">+</button> ${properties.name}</div>
<div>${properties.body}</div>
</div>
<div class="uml-footer">
<div>setHead(Head $head)</div>
<div>setBody(Body $body)</div>
</div>
</div>
`;
el.innerHTML = html;
rootEl.innerHTML = "";
rootEl.appendChild(el);
window.setData = () => {
const { graphModel, model } = this.props;
graphModel.eventCenter.emit("custom:button-click", model);
};
}
}
例子:
新建 src/views/Example/LogicFlow/component/CustomNode/index.ts
代码如下:
import { HtmlNode, HtmlNodeModel } from '@logicflow/core'
// 扩展全局 Window 接口
declare global {
interface Window {
stopPropagation: (ev: Event) => void
setDatas: () => void
}
}
class ButtonNode extends HtmlNode {
setHtml(rootEl: HTMLElement): void {
const properties = this.props.model.properties
const el: HTMLDivElement = document.createElement('div')
el.className = 'uml-wrapper'
const html: string = `
<div>
<div class="uml-head">Head</div>
<div class="uml-body">
<div><button οnclick="setDatas()" οnmοusedοwn="stopPropagation(event)">+</button> ${properties.name}</div>
<div>${properties.body}</div>
</div>
<div class="uml-footer">
<div>setHead(Head $head)</div>
<div>setBody(Body $body)</div>
</div>
</div>
`
el.innerHTML = html
rootEl.innerHTML = ''
rootEl.appendChild(el)
// 实现这些方法
window.stopPropagation = (ev: Event) => {
ev.stopPropagation()
}
window.setDatas = () => {
const { graphModel, model } = this.props
graphModel.eventCenter.emit('custom:button-click', model)
}
}
}
class ButtonNodeModel extends HtmlNodeModel {
setAttributes(): void {
this.width = 300
this.height = 150
this.text.editable = false
}
}
// TypeScript 中不使用 default export 时,需要显式地声明每个被导出的成员。
export const CustomNode = {
type: 'CustomNode',
view: ButtonNode,
model: ButtonNodeModel
}
新建 src/views/Example/LogicFlow/Example13.vue
代码如下:
<script setup lang="ts">
import LogicFlow from '@logicflow/core'
import '@logicflow/core/dist/style/index.css'
import { CustomNode } from './component/CustomNode'
import { onMounted } from 'vue'
const data = {
nodes: [
{
id: '1',
type: 'CustomNode',
x: 300,
y: 100,
properties: {
name: 'hello',
body: 'world'
}
}
],
edges: []
}
// 在组件挂载时执行
onMounted(() => {
// 创建 LogicFlow 实例
const lf = new LogicFlow({
container: document.getElementById('container')!, // 指定容器元素
grid: true // 启用网格
})
lf.register(CustomNode)
// 渲染图表数据
lf.render(data)
lf.on('custom:button-click', (model) => {
console.log(model.properties)
switch (model.properties.body) {
case 'world':
lf.setProperties(model.id, {
body: 'LogicFlow'
})
break
default:
lf.setProperties(model.id, {
body: 'world'
})
}
})
})
</script>
<template>
<h3>Example13</h3>
<div id="container"></div>
<!-- 用于显示 LogicFlow 图表的容器 -->
</template>
<style>
#container {
/* 容器宽度 */
width: 100%;
/* 容器高度 */
height: 500px;
}
.uml-wrapper {
background: #68fce2;
width: 100%;
height: 100%;
border-radius: 10px;
border: 2px solid #838382;
box-sizing: border-box;
}
.uml-head {
text-align: center;
line-height: 30px;
font-size: 16px;
font-weight: bold;
}
.uml-body {
border-top: 1px solid #838382;
border-bottom: 1px solid #838382;
padding: 5px 10px;
font-size: 12px;
}
.uml-footer {
padding: 5px 10px;
font-size: 14px;
}
</style>
效果如下:
样例代码: GITUHB