一、3.1.3版本
1. 自定义节点RegisterNode
<RegisterNode
name="customStartNode"
config={{
getCustomConfig(model) {
return {
size: [80, 40],
wrapperStyle: {
fill: '#5E6A7D', // 节点最外层边框填充的颜色
},
contentStyle: {
fill: '#5E6A7D', // 节点内容区域填充的颜色
},
labelStyle: {
fill: '#FFFFFF', // 节点内部文案的颜色
},
};
},
getAnchorPoints() { // 节点可选的连接点集合,该点有4个可选的连接点
return [
[0.5, 0], // 上边中点
[0.5, 1], // 下边中点
[0, 0.5], // 左边中点
[1, 0.5], // 右边中点
];
},
}}
extend="bizFlowNode" // 要继承的节点类型
/>
2. 自定义边RegisterEdge
用法和RegisterNode类似,初始节点渲染到画布上可以显示自定义的边,但是从节点上新拉出的线死活都是默认的。文档没有提到,Issue也没相关的,尝试了n久,差点自闭。最后在放弃的边缘挣扎了下,看源码注意到个shape
,灵感来了
重点来了:在Flow
的graphConfig
属性的defaultEdge
中加上shape
为自定义边的name就成了,成了成了成了……
// 1. 自定义边
<RegisterEdge
name="testEdge"
config={CustomFlowEdge}
extend="polyline"
/>
// 2. 把自定义边组件加到<GGEditor />标签内
<GGEditor style={{ height: '100%' }}>
<div className={styles.content}>
{/* 2. 中间部分 */}
<div className={styles.middle}>
{/* 中间上部分 - 工具栏 */}
<div className={styles['editor-toolbar']}>
<FlowToolbar />
</div>
{/* 中间下部分 - 绘制面板 */}
<div className={styles['editor-panel']}>
<Flow
className={styles.graph}
data={data}
style={{ backgroundColor: '#F8F8F8' }}
graphConfig={{
defaultNode: {
type: 'startNode',
},
defaultEdge: {
type: 'testEdge',
shape: 'testEdge',
},
}}
/>
<StartNode />
{/* <EditableLabel /> 节点标签编辑,好像只能编辑节点的,线的不行,位置有点问题 */}
<FlowContextMenu />
</div>
</div>
{/* 1. 左边部分 - 元素面板 */}
<div className={styles['editor-item']}>
<FlowItemPanel {...props} />
</div>
{/* 3. 右边部分 - 属性面板 */}
<div className={styles[`detail-panel`]}>
<FlowDetailPanel />
</div>
</div>
<TestEdge />
</GGEditor>
3. 自定义命令RegisterCommand
<RegisterCommand
name="saveFlow"
config={{
canExecute() {
return true;
},
shouldExecute() {
return true;
},
canUndo() {
return false;
},
init() { },
execute: () => {
const { onSave, graph } = this.props;
const data = graph.save();
onSave(data);
},
undo() { },
shortcuts: [],
}}
/>
4. Item
自定义节点元素
它有4个属性,1个必须的属性model;5种状态
// Item的4个属性
style?: React.CSSProperties;
className?: string;
type?: ItemType; // 可选node和edge
model: Partial<NodeModel>;
// Item的5种状态
Active = 'active',
ActiveAnchorPoints = 'activeAnchorPoints',
Selected = 'selected',
HighLight = 'highLight',
Error = 'error',
<Item
className={styles.item}
model={{
type: 'circle',
size: 50,
label: 'circle',
}}
>
<img
src="https://gw.alicdn.com/tfs/TB1IRuSnRr0gK0jSZFnXXbRRXXa-110-112.png"
width="55"
height="56"
draggable={false}
/>
</Item>
5. ContextMenu右键菜单
好像有个bug:鼠标右键连续调出不同类型的菜单会多个同时显示
// 菜单类型,可取值 canvas,node,edge;默认取canvas
type?: ContextMenuType;
// 菜单内容
renderContent: (item: Item, position: { x: number; y: number }, hide: () => void) => React.ReactNode;
<ContextMenu
type='node'
renderContent={(item, position, hide) => {
const { x: left, y: top } = position;
return (
<div
className={styles[`flow-context-menu`]}
style={{ position: 'absolute', top: top + 80, left: left + 200 }}
>
{NODE_COMMAND_LIST.map((commandItem) => {
const { _key, _name, _description, _icon } = commandItem;
return (
<Command
key={_key}
name={_name}
className={styles.command}
disabledClassName={styles.commandDisabled}
>
<div onClick={hide}>
<Icon type={_icon} />
<span>{_description}</span>
</div>
</Command>
);
})}
</div>
);
}}
/>
6. setAnchorPointsState设置连接点(锚点)的状态样式
// 自定义节点时
setState(name, value, item) {
const group = item.getContainer();
const shape = group.get('children')[0]; // 顺序根据 draw 时确定
// 选中节点时的状态
if (name === 'selected') {
if (value) {
shape.attr({
fill: 'white',
stroke: '#29BECE',
opacity: 1,
});
} else {
shape.attr({
fill: 'white',
stroke: 'rgba(41,190,206,0.50)',
});
}
}
setAnchorPointsState.call(
this,
name,
value,
item,
(point, anchorPoint) => {
const { width, height } = point.getKeyShape().getBBox();
const [x, y] = anchorPoint;
// 覆盖默认锚点的样式
return {
x: width * x - width / 2,
y: height * y - height / 2,
lineWidth: 1,
fill: '#FFFFFF',
stroke: '#29BECE',
};
},
(point, anchorPoint) => {
const { width, height } = point.getKeyShape().getBBox();
const [x, y] = anchorPoint;
return {
x: width * x - width / 2,
y: height * y - height / 2,
lineWidth: 1,
fill: '#FFFFFF',
stroke: '#29BECE',
};
}
);
},
二、2.0.4版本
1. 复制、粘贴快捷键无效问题
RegisterCommand自定义新命令继承原有复制、粘贴命令,设置快捷键
import { RegisterCommand, withPropsAPI } from 'gg-editor';
class PasteItemCommand extends React.Component {
render() {
const config = {
// 快捷按键配置
shortcutCodes: [["metaKey", "v"], ["ctrlKey", "v"]],
};
return <RegisterCommand name="pasteItem" config={config} extend="paste" />;
}
}
export default withPropsAPI(PasteItemCommand);
2. 自定义保存命令,执行后,命令行的撤销、重做命令错乱并且执行撤销或者重做后控制台报错如下
image.png解决方法:定义命令时,queue属性设置为false(queue 表示 是否进入命令队列,进入命令队列则可以执行撤销、重做)
3. 流程图保存(异步操作之后),原先选中的元素失去焦点问题
解决方法:保存之前把选中的元素保存下来,执行保存方法之后手动把之前选中的元素设置成选中状态
// 1.保存前把选中的元素存下来
const { page } = flowRef.current; // flowRef为Flow的实例
const selectedItems = page.getSelected().map(i => i.id); // 获取保存之前选中的元素
// 2. 保存完(我这是再调获取流程图数据后)把之前存下来的选中的元素设置成选中状态
page.setSelected(selectedItems, true);
page.focusGraphWrapper();
4. 自定义命令
import React from "react";
import { RegisterCommand } from "gg-editor";
class CustomCommand extends React.Component {
render() {
const config = {
// 是否进入列队,默认为 true
queue: true,
// 命令是否可用
enable(/* editor */) {
return true;
},
// 正向命令逻辑
execute(/* editor */) {
console.log("执行正向命令");
},
// 反向命令逻辑
back(/* editor */) {
console.log("执行反向命令");
},
// 快捷按键配置
shortcutCodes: [["metaKey", "s"], ["ctrlKey", "s"]]
};
return <RegisterCommand name="customCommand" config={config} />;
}
}
export default CustomCommand;
网友评论