react引入ggEditor流程图
遇到的问题
1.propsAPI获取不到内容:withPropsAPI包裹的组件必须是GGEditor的子组件。
2.自定义组件如何使用:正确的办法是通过config配置,参照上面的代码(之前我在在内部RegisterCommand以后,在onAfterExecuteCommand中截获命令,通过函数控制图例操作。这中间需要下钻到内部组件调用propsAPI,我就通过setState去设置状态传递到子组件。)
3.如何设置拖拽组件:太羞耻了,居然不晓得在Item双标签内放名称。
4.操作流程图后获取数据延迟:如果获取数据有延迟,尝试使用setTimeout,时间间隔设为0后再调propsAPI属性的方法操作。
1. 两种不同颜色的线
用onAfterChange监听,然后用先的更新设置不同的颜色即可。
2. 节点和线的更新
import React, { Fragment } from 'react';
import { Card, Form, Input, Select } from 'antd';
import { withPropsAPI } from 'gg-editor';
import upperFirst from 'lodash/upperFirst';
const { Item } = Form;
const { Option } = Select;
const inlineFormItemLayout = {
labelCol: {
sm: { span: 8 },
},
wrapperCol: {
sm: { span: 16 },
},
};
class DetailForm extends React.Component {
get item() {
const { propsAPI } = this.props;
return propsAPI.getSelected()[0];
}
handleSubmit = (e) => {
if (e && e.preventDefault) {
e.preventDefault();
}
const { form, propsAPI } = this.props;
const { getSelected, executeCommand, update } = propsAPI;
setTimeout(() => {
form.validateFieldsAndScroll((err, values) => {
if (err) {
return;
}
const item = getSelected()[0];
if (!item) {
return;
}
console.log(item,values,'values')
executeCommand(() => {
update(item, {
...values,
});
});
});
}, 0);
};
renderEdgeShapeSelect = () => {
return (
<Select onChange={this.handleSubmit}>
<Option value="flow-smooth">Smooth</Option>
<Option value="flow-polyline">Polyline</Option>
<Option value="flow-polyline-round">Polyline Round</Option>
</Select>
);
};
renderNodeDetail = () => {
const { form } = this.props;
const { label } = this.item.getModel();
return (
<Item label="Label" {...inlineFormItemLayout}>
{form.getFieldDecorator('label', {
initialValue: label.text ? label.text : label,
})(<Input onBlur={this.handleSubmit} />)}
</Item>
);
};
renderEdgeDetail = () => {
const { form } = this.props;
const { label = '', shape = 'flow-smooth' } = this.item.getModel();
return (
<Fragment>
<Item label="Label" {...inlineFormItemLayout}>
{form.getFieldDecorator('label', {
initialValue: label,
})(<Input onBlur={this.handleSubmit} />)}
</Item>
<Item label="Shape" {...inlineFormItemLayout}>
{form.getFieldDecorator('shape', {
initialValue: shape,
})(this.renderEdgeShapeSelect())}
</Item>
</Fragment>
);
};
renderGroupDetail = () => {
const { form } = this.props;
const { label = '新建分组' } = this.item.getModel();
return (
<Item label="Label" {...inlineFormItemLayout}>
{form.getFieldDecorator('label', {
initialValue: label,
})(<Input onBlur={this.handleSubmit} />)}
</Item>
);
};
render() {
const { type } = this.props;
if (!this.item) {
return null;
}
return (
<Card type="inner" size="small" title={upperFirst(type)} bordered={false}>
<Form onSubmit={this.handleSubmit}>
{type === 'node' && this.renderNodeDetail()}
{type === 'edge' && this.renderEdgeDetail()}
{type === 'group' && this.renderGroupDetail()}
</Form>
</Card>
);
}
}
export default Form.create()(withPropsAPI(DetailForm));
3. 提交数据
4. 自定义节点,注册节点
EditorCustomFlowMap组件
import React from 'react'; import { Col } from 'antd'; import { Flow } from 'gg-editor'; import { withPropsAPI } from 'gg-editor'; import CustomNode from '../EditorCustomNode'; const FlowMap = (props) => {return ( <Col span={21} className='editorContent'> <Flow className='flow' data={props.data} // 已有节点那数据结构 noEndEdge={false}/> <CustomNode /> </Col> ); }; export default withPropsAPI(FlowMap);
CustomNode 组件,注册节点
import React from "react"; import { RegisterNode } from "gg-editor"; class CustomNode extends React.Component { render() { const config = { draw(item) { const keyShape = this.drawKeyShape(item); // 绘制图标 const group = item.getGraphicGroup(); const model = item.getModel(); group.addShape("image", { attrs: { x: -35, y: -10, width: 20, height: 20, img: model.icon } }); // 绘制标签 this.drawLabel(item); return keyShape; }, anchor: [ [0.5, 0], // 上边中点 [1, 0.5], // 右边中点 [0.5, 1], // 底边中点 [0, 0.5] // 左边中点 ] }; return ( <RegisterNode name="custom-node" config={config} extend={"flow-circle"} /> ); } } export default CustomNode;
5.已有节点的数据结构
{
"nodes": [
{
"id": "1",
"flowType":"flow-circle", // 节点使用的形状
"label":"开始",
"x": 100, // 节点X轴坐标位置
"y": 50,// 节点Y轴坐标位置
"color":"blue", // 节点的颜色
"size ": "80*48", // 节点的宽度和高度
"shape ": "flow-rect"
}
],
"edges": [
{
"source":"1",
"sourceAnchor": 1,
"target":"2",
"targetAnchor": 3,
"id": "d1",
"color":"red" // 连线的颜色
}
]
}
6.左侧待拖动的节点
这里的节点和flow图里面的节点样式控制不一样,这里的节点样式是靠css来控制。
flow图里面的节点样式,1,已有节点,靠的是已有节点的数据来控制,2,即将拖拽到flow区域的节点,是靠这里的Item属性来控制样式。
1 import React from 'react'; 2 import { Card } from 'antd'; 3 import { ItemPanel, Item } from 'gg-editor'; 4 import './index.less'; 6 7 const FlowItemPanel = () => { 8 return ( 10 <ItemPanel className='itemPanel'> 11 <Card bordered={false}> 12 <Item 13 type="node" 14 size="72*72"15 shape="custom-node" // 自定义注册节点名称 16 model={{ 17 icon:'//img.alicdn.com/tfs/TB1OzAmyyLaK1RjSZFxXXamPFXa-200-200.svg', 18 color: '#FA8C16', 19 label:{ 20 text:'流程', 21 fill: 'green' 22 }, 23 }} 24 > 25 <div className="flow-node">流程</div> 26 </Item> 27 28 <Item 29 type="node" 30 size="80*48"31 shape="flow-rect" 32 model={{ 33 color: '#1890FF', 34 label:{ 35 text:'文档', 36 fill: '#000' 37 }, 38 }} 39 > 40 <div className="document-node">文档</div> 41 </Item> 42 </Card> 43 </ItemPanel> 44 ); 45 }; 46 47 export default FlowItemPanel;
1 .flow-node{ 2 border: 1px solid #fed49a; 3 background-color: #fef6e7; 4 border-radius: 50%; 5 padding: 20px; 6 color: green; 7 -webkit-user-select: none; 8 -ms-user-select: none; /* Internet Explorer/Edge */ 9 } 10 11 .document-node{ 12 border-radius: 10%; 13 border: 1px solid #a7dafe; 14 background-color: #e7f6fe; 15 padding: 15px 20px; 16 -webkit-user-select: none; 17 -ms-user-select: none; /* Internet Explorer/Edge */ 18 }
7.操作栏的设置
import React from 'react'; import { Divider } from 'antd'; import { Toolbar } from 'gg-editor'; import ToolbarButton from './ToolbarButton'; import './index.less'; const FlowToolbar = () => { return ( <Toolbar className='toolbar'> <ToolbarButton command="undo" text="回退一步" /> <ToolbarButton command="redo" text="前进一步" /> <Divider type="vertical" /> <ToolbarButton command="copy" text="复制" /> <ToolbarButton command="paste" text="粘贴" /> <ToolbarButton command="delete" text="删除" /> <Divider type="vertical" /> <ToolbarButton command="zoomIn" icon="zoom-in" text="Zoom In" /> <ToolbarButton command="zoomOut" icon="zoom-out" text="Zoom Out" /> <ToolbarButton command="autoZoom" icon="fit-map" text="Fit Map" /> <ToolbarButton command="resetZoom" icon="actual-size" text="Actual Size" /> <Divider type="vertical" /> <ToolbarButton command="toBack" icon="to-back" text="To Back" /> <ToolbarButton command="toFront" icon="to-front" text="To Front" /> <Divider type="vertical" /> <ToolbarButton command="multiSelect" icon="multi-select" text="Multi Select" /> <ToolbarButton command="addGroup" icon="group" text="Add Group" /> <ToolbarButton command="unGroup" icon="ungroup" text="Ungroup" /> </Toolbar> ); }; export default FlowToolbar;
8. 总
import React from 'react'; import { Row, Col } from 'antd'; import GGEditor from 'gg-editor'; import EditorMinimap from '../components/EditorMinimap'; import { FlowContextMenu } from '../components/EditorContextMenu'; import { FlowToolbar } from '../components/EditorToolbar'; import { FlowItemPanel } from '../components/EditorItemPanel'; import { FlowDetailPanel } from '../components/EditorDetailPanel'; import './index.less'; import EditorCustomDetailPanel from '../components/EditorCustomDetailPanel'; import EditorCustomFlowMap from '../components/EditorCustomFlowMap'; const flowData = {nodes:[],edges:[]}; const FlowPage = (props) => {return ( <GGEditor className='editor' style={{height:props.height}}> <Row type="flex" className='editorHd'> <Col span={24}> <FlowToolbar /> </Col> </Row> <Row type="flex" className='editorBd'> <Col span={3} className='editorSidebar'> <FlowItemPanel /> </Col> <EditorCustomFlowMap data={flowData} onNodeClick={props.handleNodeClick} onNodeDragEnd ={props.handleNodeDragEnd} handleAfterChange={props.handleAfterChange} /> <Col span={4} className='editorSidebar'> <FlowDetailPanel /> <EditorMinimap /> </Col></Row> <FlowContextMenu /> <EditorCustomDetailPanel visibleDetailPanel={props.visibleDetailPanel} hideVisibleDetailPanel={props.hideVisibleDetailPanel} detailPanel={props.detailPanel} currentNode={props.currentNode} changeDetailPanel={props.changeDetailPanel} submitCurrentNode={props.submitCurrentNode} /> </GGEditor> ); }; export default FlowPage;
快乐学习,积累在于一点一滴。
希望能够帮到你,如果有问题,请多多指教,谢谢!

浙公网安备 33010602011771号