logicFlow 使用之自定义节点
应用场景:vue3中使用logicFlow绘制流程图
技术碎片应用:
logicFlow:节点,边,锚点,事件。(getEdgeModelById,getNodeModelById,updateText)
js:getElementsByClassName offsetHeight
解决问题:
1.定义节点文本内容遮挡或编辑内容未及时刷新渲染问题。
2.添加节点时边未能及时更新坐标路径问题
3.子节点或分支的锚点坐标与边坐标不对应问题
4.边上渲染文本
官网:logicFlow
一.注册,渲染自定义节点,边
import Edge from "./edge.js";
import Node from "./node.js";
lf.register(Edge);
lf.register(Node);
lf.render(data);
二.动态设置内容高度
setHtml(rootEl) {
...//do some
let contentHeight= 0;
let editElementIndex = 0;
let decmentList = document.getElementsByClassName("conten-text")
if (content) {
for (var i = 0; i < contentElementList.length; i++) {
if (contentElementList[i].textContent == content) {
editElementIndex = i;
}
}
contentHeight = contentElementList[editElementIndex].offsetHeight
}
let itemHeight = 0;
let itemElementList = document.getElementsByClassName("item-cell);
if (items) {
itemHeight = itemElementList[editElementIndex].offsetHeight;
}
if (contentHeight == 0) {
rootEl.style.height = 61 + 'px';
this.props.model._height = 61;
} else {
rootEl.style.height = 36 + contentHeight + itemHeight + 'px';
this.props.model._height = 36 + contentHeight + itemHeight;
}
}
解决方法:获取元素根据内容容器的offsetHeight设置文本框和多个子节点的高度,以解决编辑文本内容过多时,
节点内容遮挡或节点不刷新问题
三.自动更新边坐标路径
调用边更新方法
graphData.edges.forEach((edge) => {
lf.getEdgeModelById(edge.id).updatePathByAnchor()
})
数据变动或更新渲染时调用
lf.on("history:change", ({ data }) => {
... //边更新
});
自定义边刷新
initEdgeData(data) {
this.updatePathByAnchor();
}
updatePathByAnchor() {
const sourceNodeModel = this.graphModel.getNodeModelById(this.sourceNodeId);
const targetNodeModel = this.graphModel.getNodeModelById(this.targetNodeId);
const sourceAnchor = sourceNodeModel.getDefaultAnchor().find((anchor) => anchor.id === this.sourceAnchorId && anchor.type== 'right');
const targetAnchor = targetNodeModel.getDefaultAnchor().find((anchor) => anchor.id === this.targetAnchorId && anchor.type == 'left');
if (sourceAnchor != undefined) {
const startPoint = {
x: sourceAnchor.x,
y: sourceAnchor.y,
};
this.updateStartPoint(startPoint);
}
if (targetAnchor != undefined) {
const endPoint = {
x: targetAnchor.x,
y: targetAnchor.y,
};
this.updateEndPoint(endPoint);
}
this.pointsList = [];
this.initPoints();
}
解决方法:获取起始锚点,更新坐标
添加节点时调用
addField(item) {
this.properties.items.unshift(item);
this.setAttributes();
this.move(0, 24 / 2);
this.incoming.edges.forEach((egde) => {
egde.updatePathByAnchor();
});
this.outgoing.edges.forEach((edge) => {
edge.updatePathByAnchor();
});
}
四.自动更新子节点或分支的坐标位置
getDefaultAnchor() {
const {
id,
x,
y,
width,
height,
isHovered,
isSelected,
properties: { Items, isConnection, content }
} = this;
const anchors = [];
Items.forEach((item, index) => {
if (!isConnection || !(isHovered || isSelected)) {
anchors.push({
x: x - width / 2 + 1,
y: y,
id: `${id}`,
edgeAddable: false,
type: "left"
});
}
if (!isConnection) {
const calcY = Items.length > 1 ? y + height / 2 + (index + (-(Items.length - 2))) * 26 - 41 : y + height / 2 + (Items.length - index) * 26 - 41;
anchors.push({
x: x + width / 2 +26,
y: calcY,
id: `${id}_${item.name}`,
type: "right"
});
}
});
return anchors;
}
解决办法:据子节点高度计算出其对应坐标。
五.边上渲染文本
lf.on("edge:add", ({ data, e, position }) => {
if(data&&lf.getEdgeModelById(data.id)!=undefined){
lf.getEdgeModelById(data.id).updateText("从A节点连入B节点");
}
});
小结至此,还请多多关注。