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(extension/label): 修复isMultiple设置false后仍能创建多个label的问题&增加input回调事件&增加便签示例 #1981

Merged
merged 1 commit into from
Dec 3, 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
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import LogicFlow, { TextMode } from '@logicflow/core'
import { Label, DndPanel } from '@logicflow/extension'
import '@logicflow/core/es/index.css'
// import '@logicflow/extension/es/index.css'
import '@logicflow/extension/es/index.css'
import noteNode from './noteNode'

import { Button, Card, Divider, Flex } from 'antd'
import { useEffect, useRef } from 'react'
Expand Down Expand Up @@ -134,10 +135,18 @@ const data = {
},
{
id: '7',
type: 'html',
type: 'note',
x: 150,
y: 400,
text: 'html节点',
text: '便签节点',
properties: {
width: 150,
height: 140,
_labelOption: {
isMultiple: false,
maxCount: 1,
},
},
},
],
edges: [
Expand Down Expand Up @@ -176,6 +185,7 @@ export default function BasicNode() {
size: 5,
},
})
lf.register(noteNode)
lf.extension.dndPanel.setPatternItems([
{
type: 'circle',
Expand All @@ -200,6 +210,20 @@ export default function BasicNode() {
label: '结束节点',
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',
},
{
type: 'note',
text: '便签',
label: '便签节点',
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAnBJREFUOBGdVL1rU1EcPfdGBddmaZLiEhdx1MHZQXApraCzQ7GKLgoRBxMfcRELuihWKcXFRcEWF8HBf0DdDCKYRZpnl7p0svLe9Zzbd29eQhTbC8nv+9zf130AT63jvooOGS8Vf9Nt5zxba7sXQwODfkWpkbjTQfCGUd9gIp3uuPP8bZ946g56dYQvnBg+b1HB8VIQmMFrazKcKSvFW2dQTxJnJdQ77urmXWOMBCmXM2Rke4S7UAW+/8ywwFoewmBps2tu7mbTdp8VMOkIRAkKfrVawalJTtIliclFbaOBqa0M2xImHeVIfd/nKAfVq/LGnPss5Kh00VEdSzfwnBXPUpmykNss4lUI9C1ga+8PNrBD5YeqRY2Zz8PhjooIbfJXjowvQJBqkmEkVnktWhwu2SM7SMx7Cj0N9IC0oQXRo8xwAGzQms+xrB/nNSUWVveI48ayrFGyC2+E2C+aWrZHXvOuz+CiV6iycWe1Rd1Q6+QUG07nb5SbPrL4426d+9E1axKjY3AoRrlEeSQo2Eu0T6BWAAr6COhTcWjRaYfKG5csnvytvUr/WY4rrPMB53Uo7jZRjXaG6/CFfNMaXEu75nG47X+oepU7PKJvvzGDY1YLSKHJrK7vFUwXKkaxwhCW3u+sDFMVrIju54RYYbFKpALZAo7sB6wcKyyrd+aBMryMT2gPyD6GsQoRFkGHr14TthZni9ck0z+Pnmee460mHXbRAypKNy3nuMdrWgVKj8YVV8E7PSzp1BZ9SJnJAsXdryw/h5ctboUVi4AFiCd+lQaYMw5z3LGTBKjLQOeUF35k89f58Vv/tGh+l+PE/wG0rgfIUbZK5AAAAABJRU5ErkJggg==',
properties: {
width: 180,
height: 180,
_labelOption: {
isMultiple: false,
maxCount: 1,
},
},
},
])
lf.render(data)
lfRef.current = lf
Expand Down
122 changes: 122 additions & 0 deletions examples/engine-browser-examples/src/pages/extension/label/noteNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import LogicFlow, { RectNode, RectNodeModel, h } from '@logicflow/core'

export class NoteView extends RectNode {
getShape() {
const { model } = this.props
const { x, y, width, height, cornerSize } = model
const style = model.getNodeStyle()
const strokeWidth = style.strokeWidth || 1
const startPosition = strokeWidth / 2
const noteMainPath = `
${startPosition},${startPosition}
${startPosition + width},${startPosition}
${startPosition + width},${startPosition + height - cornerSize}
${startPosition + width - cornerSize},${startPosition + height}
${startPosition},${startPosition + height}`
const noteCornerPath = `
${width - cornerSize},${startPosition + height - cornerSize}
${width},${height - cornerSize}
${width - cornerSize},${height}`
return h(
'svg',
{
...style,
x: x - width / 2,
y: y - height / 2,
width: width + strokeWidth,
height: height + strokeWidth,
viewBox: `-1 -1 ${width + strokeWidth + 2} ${height + strokeWidth + 2}`,
},
[
h('polygon', {
points: noteMainPath,
fill: style.fill,
stroke: style.stroke,
strokeWidth,
}),
h('polygon', {
points: noteCornerPath,
fill: style.fill,
stroke: style.stroke,
strokeWidth,
}),
],
)
}
}
export class NoteModel extends RectNodeModel {
initNodeData(data: LogicFlow.NodeConfig<LogicFlow.PropertiesType>) {
super.initNodeData(data)
const { properties } = data
// const { x, y } = this;
if (!properties) return
const { width, height } = properties
this.width = width || this.width
this.height = height || this.height
this.defaultHeight = height
this.cornerSize = Math.min(this.width, this.height) * 0.1
// 监听label:input事件输入时实时更新label的高度
this.graphModel.eventCenter.on('label:input', ({ data: labelData }) => {
const domId = `editor-container-${labelData.id}`
const domElement = document.getElementById(domId) // 当前输入的label容器元素
if (!domElement) return
const contentDom = domElement.children[0] as HTMLElement // 当前输入的label容器元素的内容(因为便签只有一个文本,所以内容元素即第一个子元素)
if (!contentDom) return
const lineHeight = window.getComputedStyle(contentDom).lineHeight
if (contentDom.offsetHeight > this.defaultHeight) {
this.setProperty(
'height',
contentDom.offsetHeight + parseFloat(lineHeight),
)
} else {
this.setProperty(
'height',
contentDom.offsetHeight < this.defaultHeight
? this.defaultHeight
: contentDom.offsetHeight + parseFloat(lineHeight),
)
}
})
}

getNodeStyle() {
const { cornerSize } = this
const style = super.getNodeStyle()
const { style: { fill, stroke, strokeWidth } = {} } = this.properties
style.fill = fill || '#fff'
style.stroke = stroke || '#2961EF'
style.strokeWidth = strokeWidth || cornerSize / 20
return style
}

updateLabelInfo() {
const { width, height, x, y } = this
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { labelWidth } = this.properties._labelOption as any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.properties._label?.forEach((label: any) => {
label.labelWidth = labelWidth || width - width * 0.2
label.x = x
label.y = y
label.style = {
minHeight: `${height - height * 0.2}px`,
minWidth: `${labelWidth || width - width * 0.15}px`,
textAlign: 'left',
}
console.log('label', label)
})
}

setAttributes() {
super.setAttributes()
this.updateLabelInfo()
}
}

export const note = {
type: 'note',
view: NoteView,
model: NoteModel,
}

export default note
9 changes: 9 additions & 0 deletions packages/extension/src/tools/label/Label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,14 @@ export class Label extends Component<ILabelProps, ILabelState> {
})
}

handleInput = (e: InputEvent) => {
const { label, graphModel } = this.props
graphModel.eventCenter.emit('label:input', {
e,
data: label.getData(),
})
}

setElementModelLabelInfo(data) {
const { label, element, graphModel } = this.props
const {
Expand Down Expand Up @@ -330,6 +338,7 @@ export class Label extends Component<ILabelProps, ILabelState> {
'lf-label-editor-hover': !isEditing && (isHovered || isSelected),
[`lf-label-editor-${textOverflowMode}`]: !isEditing,
})}
onInput={this.handleInput}
style={{
maxWidth: `${maxLabelWidth}px`,
boxSizing: 'border-box',
Expand Down
8 changes: 6 additions & 2 deletions packages/extension/src/tools/label/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,12 @@ export class Label implements Extension {
editable: true,
vertical: false,
}

if (!isMultiple || len >= (curLabelOption?.maxCount ?? maxCount)) {
// 全局的isMultiple为false,或全局isMultiple为true但局部isMultiple指明是false,或当前label长度已经达到上线时,不允许添加多个 label
if (
!isMultiple ||
(isMultiple && curLabelOption.isMultiple === false) ||
len >= (curLabelOption?.maxCount ?? maxCount)
) {
return
}

Expand Down