diff --git a/react-ui/config/defaultSettings.ts b/react-ui/config/defaultSettings.ts index 0d58faa1..91930d6e 100644 --- a/react-ui/config/defaultSettings.ts +++ b/react-ui/config/defaultSettings.ts @@ -18,7 +18,7 @@ const Settings: ProLayoutProps & { colorWeak: false, title: '复杂智能软件', pwa: true, - logo: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg', + logo: '/assets/images/left-top-logo.png', iconfontUrl: '', token: { // 参见ts声明,demo 见文档,通过token 修改样式 diff --git a/react-ui/public/assets/images/compoent-icon-6.png b/react-ui/public/assets/images/compoent-icon-6.png new file mode 100644 index 00000000..47e7fa9b Binary files /dev/null and b/react-ui/public/assets/images/compoent-icon-6.png differ diff --git a/react-ui/public/assets/images/component-icon-1.png b/react-ui/public/assets/images/component-icon-1.png index 5e5d7149..4568e3b2 100644 Binary files a/react-ui/public/assets/images/component-icon-1.png and b/react-ui/public/assets/images/component-icon-1.png differ diff --git a/react-ui/public/assets/images/component-icon-2.png b/react-ui/public/assets/images/component-icon-2.png index 2f4fba75..634a8762 100644 Binary files a/react-ui/public/assets/images/component-icon-2.png and b/react-ui/public/assets/images/component-icon-2.png differ diff --git a/react-ui/public/assets/images/component-icon-3.png b/react-ui/public/assets/images/component-icon-3.png index 941b323a..43d88c00 100644 Binary files a/react-ui/public/assets/images/component-icon-3.png and b/react-ui/public/assets/images/component-icon-3.png differ diff --git a/react-ui/public/assets/images/component-icon-4.png b/react-ui/public/assets/images/component-icon-4.png index fd240707..4c004faf 100644 Binary files a/react-ui/public/assets/images/component-icon-4.png and b/react-ui/public/assets/images/component-icon-4.png differ diff --git a/react-ui/public/assets/images/component-icon-5.png b/react-ui/public/assets/images/component-icon-5.png index b86bd925..e1c284e4 100644 Binary files a/react-ui/public/assets/images/component-icon-5.png and b/react-ui/public/assets/images/component-icon-5.png differ diff --git a/react-ui/public/assets/images/component-icon-7.png b/react-ui/public/assets/images/component-icon-7.png index 28c1803d..c0c1087c 100644 Binary files a/react-ui/public/assets/images/component-icon-7.png and b/react-ui/public/assets/images/component-icon-7.png differ diff --git a/react-ui/public/assets/images/mindspore模型转换.png b/react-ui/public/assets/images/mindspore模型转换.png new file mode 100644 index 00000000..73620da3 Binary files /dev/null and b/react-ui/public/assets/images/mindspore模型转换.png differ diff --git a/react-ui/public/assets/images/pipelieEditIcon.png b/react-ui/public/assets/images/pipelieEditIcon.png new file mode 100644 index 00000000..936bf97c Binary files /dev/null and b/react-ui/public/assets/images/pipelieEditIcon.png differ diff --git a/react-ui/public/assets/images/pipeline-canvas-back.png b/react-ui/public/assets/images/pipeline-canvas-back.png new file mode 100644 index 00000000..c7e9864e Binary files /dev/null and b/react-ui/public/assets/images/pipeline-canvas-back.png differ diff --git a/react-ui/public/assets/images/pipeline-edit-icon.png b/react-ui/public/assets/images/pipeline-edit-icon.png new file mode 100644 index 00000000..936bf97c Binary files /dev/null and b/react-ui/public/assets/images/pipeline-edit-icon.png differ diff --git a/react-ui/public/assets/images/pytorch推理.png b/react-ui/public/assets/images/pytorch推理.png new file mode 100644 index 00000000..11f2d37f Binary files /dev/null and b/react-ui/public/assets/images/pytorch推理.png differ diff --git a/react-ui/public/assets/images/pytorch训练.png b/react-ui/public/assets/images/pytorch训练.png new file mode 100644 index 00000000..81677987 Binary files /dev/null and b/react-ui/public/assets/images/pytorch训练.png differ diff --git a/react-ui/public/assets/images/tensorflow模型转换.png b/react-ui/public/assets/images/tensorflow模型转换.png new file mode 100644 index 00000000..4e58c5d7 Binary files /dev/null and b/react-ui/public/assets/images/tensorflow模型转换.png differ diff --git a/react-ui/public/assets/images/发送通知.png b/react-ui/public/assets/images/发送通知.png new file mode 100644 index 00000000..9e4d563a Binary files /dev/null and b/react-ui/public/assets/images/发送通知.png differ diff --git a/react-ui/src/global.less b/react-ui/src/global.less index 725af969..4e109ebf 100644 --- a/react-ui/src/global.less +++ b/react-ui/src/global.less @@ -31,7 +31,38 @@ body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } - +.ant-pro-layout .ant-pro-layout-content{ + padding: 10px; +} +.ant-pro-layout .ant-pro-layout-bg-list{ + background:#f9fafb; +} +.ant-table-wrapper .ant-table-thead >tr>th{ + background-color: #fff; +} +.ant-table-wrapper .ant-table-thead >tr>td{ + background-color: #fff; +} +.ant-menu-light .ant-menu-item-selected{ + background:rgba(197, 232, 255, 0.8)!important; +} +.ant-pro-base-menu-inline{ + // height: 87vh; + background:#f2f5f7; +border-radius:0px 20px 20px 0px; +} +.ant-pro-layout .ant-pro-layout-content{ + background-color: #fff; +} +.ant-pro-global-header-logo img{ + height: 21px; +} +.ant-pro-layout .ant-layout-sider.ant-pro-sider{ + height: 87vh; +} +.ant-pro-layout .ant-pro-layout-container{ + height: 98vh; +} ul, ol { list-style: none; @@ -53,3 +84,5 @@ ol { } } } + + diff --git a/react-ui/src/pages/Experiment/experimentText/index.jsx b/react-ui/src/pages/Experiment/experimentText/index.jsx index 8a961f04..354f349c 100644 --- a/react-ui/src/pages/Experiment/experimentText/index.jsx +++ b/react-ui/src/pages/Experiment/experimentText/index.jsx @@ -51,7 +51,7 @@ const ExperimentText = React.FC = () => { return { display: 'flex', backgroundColor:'#fff', - height:'81vh' + height:'98vh' }; }); const graphStyle = useEmotionCss(() => { @@ -158,98 +158,78 @@ const ExperimentText = React.FC = () => { },[]) const initGraph=()=>{ G6.registerNode( - 'rect-node', - { - // draw anchor-point circles according to the anchorPoints in afterDraw - getAnchorPoints(cfg) { - return ( - cfg.anchorPoints || [ - // 上下各3,左右各1 - [0.1, 0.05], - [0.5, 0.05], - [0.9, 0.05], - [0, 0.5], - [1, 0.5], - [0.1, 1], - [0.5, 1], - [0.9, 1], - - // 四边中间 - // [0.5, 0.05], - // [0, 0.5], - // [1, 0.5], - // [0.5, 1], - // 四个角落 - // [0.05, 0.05], - // [0.9, 0.05], - // [0.05, 1], - // [0.9, 1], - ] - ); - }, - afterDraw(cfg, group) { - // console.log(group, cfg, 12312); - const image = group.addShape('image', { + 'rect-node', + { + // draw anchor-point circles according to the anchorPoints in afterDraw + getAnchorPoints(cfg) { + return ( + cfg.anchorPoints || [ + // 上下各3,左右各1 + [0.5, 0], + [0.5, 1], + + ] + ); + }, + afterDraw(cfg, group) { + // console.log(group, cfg, 12312); + const image = group.addShape('image', { + attrs: { + x: -45, + y: -10, + width: 20, + height: 20, + img: cfg.img, + cursor: 'pointer', + }, + draggable: true, + }); + // if (cfg.label) { + // group.addShape('text', { + // attrs: { + // x: 0, + // y: cfg.height / 2 - 5, + // textAlign: 'center', + // textBaseline: 'middle', + // text: cfg.label, + // fill: '#fff', + // }, + // draggable: true, + // }); + // } + const bbox = group.getBBox(); + const anchorPoints = this.getAnchorPoints(cfg); + // console.log(anchorPoints); + anchorPoints.forEach((anchorPos, i) => { + group.addShape('circle', { attrs: { - x: -25, - y: -13, - width: 23, - height: 21, - img: cfg.img, - cursor: 'pointer', + r: 3, + x: bbox.x + bbox.width * anchorPos[0], + y: bbox.y + bbox.height * anchorPos[1], + fill: '#fff', + stroke: '#a4a4a5', }, - draggable: true, - }); - // if (cfg.label) { - // group.addShape('text', { - // attrs: { - // x: 0, - // y: cfg.height / 2 - 5, - // textAlign: 'center', - // textBaseline: 'middle', - // text: cfg.label, - // fill: '#fff', - // }, - // draggable: true, - // }); - // } - const bbox = group.getBBox(); - const anchorPoints = this.getAnchorPoints(cfg); - // console.log(anchorPoints); - anchorPoints.forEach((anchorPos, i) => { - group.addShape('circle', { - attrs: { - r: 5, - x: bbox.x + bbox.width * anchorPos[0], - y: bbox.y + bbox.height * anchorPos[1], - fill: '#000', - stroke: '#000', - }, - name: `anchor-point`, // the name, for searching by group.find(ele => ele.get('name') === 'anchor-point') - anchorPointIdx: i, // flag the idx of the anchor-point circle - links: 0, // cache the number of edges connected to this shape - visible: false, // invisible by default, shows up when links > 1 or the node is in showAnchors state - draggable: true, // allow to catch the drag events on this shape - }); + name: `anchor-point`, // the name, for searching by group.find(ele => ele.get('name') === 'anchor-point') + anchorPointIdx: i, // flag the idx of the anchor-point circle + links: 0, // cache the number of edges connected to this shape + visible: false, // invisible by default, shows up when links > 1 or the node is in showAnchors state }); - return image; - }, - - // response the state changes and show/hide the link-point circles - setState(name, value, item) { - // 默认显示全部锚点,防止过宽导致锚点无法被选中 - // if (name === 'showAnchors') { + }); + return image; + }, + + // response the state changes and show/hide the link-point circles + setState(name, value, item) { const anchorPoints = item.getContainer().findAll(ele => ele.get('name') === 'anchor-point'); anchorPoints.forEach(point => { - // if (value) point.show(); - // else point.hide(); - point.show(); - }); - // } - }, + if (value || point.get('links') > 0) point.show() + else point.hide() + }) + // } }, - 'rect' - ); + }, + 'rect' + ); console.log(graphRef,'graphRef'); graph = new G6.Graph({ container: graphRef.current, @@ -258,13 +238,27 @@ const ExperimentText = React.FC = () => { height: graphRef.current.clientHeight||760, animate: false, groupByTypes: false, - - plugins: [], + fitView:true, enabledStack: true, modes: { default: [ + // config the shouldBegin for drag-node to avoid node moving while dragging on the anchor-point circles + { + type: 'drag-node', + shouldBegin: e => { + if (e.target.get('name') === 'anchor-point') return false; + return true; + }, + // shouldEnd: e => { + // console.log(e); + // return false; + // }, + }, + // config the shouldBegin and shouldEnd to make sure the create-edge is began and ended at anchor-point circles 'drag-canvas', 'zoom-canvas', + // 'brush-select', + 'drag-combo', ], altSelect: [ { @@ -277,49 +271,53 @@ const ExperimentText = React.FC = () => { defaultNode: { type: 'rect-node', - size: 70, + size: [110,36], labelCfg: { style: { fill: '#000', - fontSize: 12, + fontSize: 10, + cursor: 'pointer', - x: 0, + x: -20, y: 0, textAlign: 'left', textBaseline: 'middle', }, }, style: { - fill: 'transparent', - stroke: 'transparent', + fill: '#fff', + stroke: '#fff', + radius:10, + lineWidth:0.5 + }, + }, + nodeStateStyles: { + nodeSelected: { + fill: 'red', + shadowColor: 'red', + stroke: 'red', + 'text-shape': { + fill: 'red', + stroke: 'red', + }, }, }, - // nodeStateStyles: { - // nodeSelected: { - // fill: 'red', - // shadowColor: 'red', - // stroke: 'red', - // 'text-shape': { - // fill: 'red', - // stroke: 'red', - // }, - // }, - // }, defaultEdge: { // type: 'quadratic', - type: 'polyline', + type: 'cubic-vertical', style: { - endArrow: { - path: G6.Arrow.triangle(), + endArrow: { // 设置终点箭头 + path: G6.Arrow.triangle(3, 3, 3), // 使用内置箭头路径函数,参数为箭头的 宽度、长度、偏移量(默认为 0,与 d 对应) + d: 4.5, + fill:'#a2a6b5' }, cursor: 'pointer', - endArrow: true, lineWidth: 1, opacity: 1, stroke: '#a2a6b5', - radius: 10, + radius: 1, }, nodeStateStyle: { hover: { @@ -346,7 +344,7 @@ const ExperimentText = React.FC = () => { cursor: 'pointer', }, }, - linkCenter: true, + // linkCenter: true, fitView: true, fitViewPadding: [60, 60, 60, 80], }); diff --git a/react-ui/src/pages/Experiment/index.jsx b/react-ui/src/pages/Experiment/index.jsx index 2fd83114..79274b7f 100644 --- a/react-ui/src/pages/Experiment/index.jsx +++ b/react-ui/src/pages/Experiment/index.jsx @@ -1,6 +1,6 @@ import React ,{ useState,useEffect,useRef }from 'react'; import { Space, Table, Tag,Button,Modal, Form, Input ,message, Select,} from 'antd'; -import { PlusOutlined, EditOutlined ,PlayCircleOutlined,DeleteOutlined,FieldTimeOutlined} from '@ant-design/icons'; +import { PlusOutlined,PlusCircleOutlined, EditOutlined ,PlayCircleOutlined,DeleteOutlined,FieldTimeOutlined} from '@ant-design/icons'; import {getWorkflow,} from '@/services/pipeline/index.js' import {getExperiment,runExperiments,getExperimentById,postExperiment,putExperiment,getQueryByExperimentId,deleteExperimentById,deleteQueryByExperimentInsId,putQueryByExperimentInsId} from '@/services/experiment/index.js' import Styles from './index.less' @@ -49,6 +49,7 @@ const Experiment = React.FC = () => { size:10000, name:null }); + const [disableFlag,setDisableFlag]=useState(false) const timers=(time)=>{ let timer=new Date(time) let hours = timer.getHours(); //转换成时 @@ -96,6 +97,7 @@ const Experiment = React.FC = () => { } const showModal = () => { setDialogTitle('新建实验') + setDisableFlag(false) console.log(workflowList); setIsModalOpen(true); }; @@ -103,6 +105,7 @@ const Experiment = React.FC = () => { getExperimentById(id).then(ret=>{ if(ret.code==200){ form.setFieldsValue({...ret.data}) + setDisableFlag(true) setFormId(ret.data.id) setDialogTitle('编辑实验') getWorkflowList() @@ -262,6 +265,7 @@ const Experiment = React.FC = () => { { title: '操作', key: 'action', + width:300, render: (_, record) => ( + */} +
+
( @@ -340,7 +351,7 @@ const Experiment = React.FC = () => {
状态
运行时长
开始时间
-
操作
+
操作
:''} {experimentInList&&experimentInList.length>0?experimentInList.map((item,index)=>( @@ -349,7 +360,7 @@ const Experiment = React.FC = () => {
{statusObj[item.status]}
{item.finish_time?timers(new Date(item.finish_time).getTime()-new Date(item.create_time).getTime()):timers(new Date().getTime()-new Date(item.create_time).getTime())}
{momnet(item.create_time).format('YYYY-MM-DD HH:mm:ss')}
-
+
} open={isModalOpen} okButtonProps={{ htmlType: 'submit', form: 'form', }} onCancel={handleCancel}> @@ -417,15 +431,6 @@ const Experiment = React.FC = () => { name="form" form={form} layout="vertical" - labelCol={{ - span: 8, - }} - wrapperCol={{ - span: 16, - }} - style={{ - maxWidth: 600, - }} initialValues={{ remember: true, }} @@ -460,6 +465,7 @@ const Experiment = React.FC = () => { { // }, ]} > - + {workflowList&&workflowList.length>0?workflowList.map(item=>{return {item.name}}):''} {/* Demo */} diff --git a/react-ui/src/pages/Experiment/index.less b/react-ui/src/pages/Experiment/index.less index b015521e..f1fc5a1f 100644 --- a/react-ui/src/pages/Experiment/index.less +++ b/react-ui/src/pages/Experiment/index.less @@ -7,22 +7,34 @@ height: 49px; background-size: 100% 100%; background-image: url(/assets/images/pipeline-back.png); + +} +.pipelineTopBox{ + display: flex; + align-items: center; + justify-content: flex-end; + padding-right: 30px; + width: 100%; + height: 49px; + background-size: 100% 100%; + background-image: url(/assets/images/pipeline-back.png); + margin-bottom: 10px; +} +.plusButton{ + background:rgba(22, 100, 255, 0.06); + border:1px solid; + border-color:rgba(22, 100, 255, 0.11); + border-radius:4px; + color:#1d1d20; + font-size:14px; + font-family: 'Alibaba'; +} +.plusButton:hover{ + background:rgba(22, 100, 255, 0.06)!important; + border:1px solid!important; + border-color:rgba(22, 100, 255, 0.11)!important; + color:#1d1d20!important; } -// .plusButton{ -// background:rgba(22, 100, 255, 0.06); -// border:1px solid; -// border-color:rgba(22, 100, 255, 0.11); -// border-radius:4px; -// color:#1d1d20; -// font-size:15px; -// font-family: 'Alibaba'; -// } -// .plusButton:hover{ -// background:rgba(22, 100, 255, 0.06); -// border:1px solid; -// border-color:rgba(22, 100, 255, 0.11); -// border-radius:4px; -// } .tableExpandBox{ width: 100%; display: flex; @@ -44,4 +56,45 @@ } .statusBox:hover .statusIcon{ visibility: visible; +} +.modal { + :global { + .ant-modal-content { + background:linear-gradient(180deg,#cfdfff 0%,#d4e2ff 9.77%,#ffffff 40%,#ffffff 100%); + border-radius:21px; + padding: 20px 67px; + width: 825px; + + } + .ant-modal-header{ + background-color: transparent; + margin: 20px 0; + } + .ant-input{ + border-color:#e6e6e6; + height: 40px; + + } + .ant-select-single{ + height: 40px; + } + .ant-form-item .ant-form-item-label >label{ + color:rgba(29, 29, 32, 0.8); + } + .ant-modal-footer{ + margin: 40px 0 30px 0; + display: flex; + justify-content: center; + } + .ant-btn{ + width:123px; + height:40px; + font-size:18px; + background:rgba(22, 100, 255, 0.06); + border-radius:10px; + } + .ant-btn-primary{ + background:#1664ff; + } + } } \ No newline at end of file diff --git a/react-ui/src/pages/Pipeline/editPipeline/editPipeline.less b/react-ui/src/pages/Pipeline/editPipeline/editPipeline.less index d0562f67..1fd2df8b 100644 --- a/react-ui/src/pages/Pipeline/editPipeline/editPipeline.less +++ b/react-ui/src/pages/Pipeline/editPipeline/editPipeline.less @@ -9,6 +9,7 @@ width: 100%; height:43px; background:#f8fbff; + color:#1d1d20; font-size:15px; font-family: 'Alibaba'; @@ -22,9 +23,31 @@ .buttonList{ display: flex; align-items: center; + justify-content: end; padding: 0 30px; width: 100%; height:45px; background:#ffffff; box-shadow:0px 3px 6px rgba(146, 146, 146, 0.09); +} +.rightmenu { + position: absolute; + width: 120px; + height: 146px; + left: 0px; + top: 0px; + + background-color: #ffffff; + font-size: 12px; + color: #333333; + overflow-y: auto; +} + +.rightmenuItem { + padding: 10px 20px; + cursor: pointer; +} +.rightmenuItem:hover { + background-color: rgba(24, 144, 255, 0.3); + color: #ffffff; } \ No newline at end of file diff --git a/react-ui/src/pages/Pipeline/editPipeline/index.jsx b/react-ui/src/pages/Pipeline/editPipeline/index.jsx index c3f37b14..a34d7bdf 100644 --- a/react-ui/src/pages/Pipeline/editPipeline/index.jsx +++ b/react-ui/src/pages/Pipeline/editPipeline/index.jsx @@ -13,20 +13,42 @@ import { useNavigate} from 'react-router-dom'; const editPipeline = React.FC = () => { const propsRef=useRef() const navgite=useNavigate(); - const [contextMenu,setContextMenu]=useState({}) + // const [contextMenu,setContextMenu]=useState({}) + let contextMenu={} const locationParams =useParams () //新版本获取路由参数接口 let graph=null + let sourceAnchorIdx, targetAnchorIdx; const pipelineContainer = useEmotionCss(() => { return { display: 'flex', backgroundColor:'#fff', - height:'81vh' + height:'98vh' }; }); + const rightmenu= useEmotionCss(() => { + return { + position: 'absolute', + width: '120px', + height: '146px', + left: '0px', + top: '0px', + + color: '#333333', + overflowY: 'auto' + }; + }); + const rightmenuItem =useEmotionCss(() => { + return { + padding: '10px 20px', + cursor: 'pointer', + fontSize: '12px', + }; + }); const graphStyle = useEmotionCss(() => { return { width:'100%', - backgroundColor:'#f9fafb', + backgroundSize: '100% 100%', + backgroundImage: 'url(/assets/images/pipeline-canvas-back.png)', flex:1 }; }); @@ -61,7 +83,7 @@ const editPipeline = React.FC = () => { data.nodes[index] = val; graph.changeData(data) } - const savePipeline=()=>{ + const savePipeline=(val)=>{ const data = graph.save(); console.log(data); let params={ @@ -70,14 +92,22 @@ const editPipeline = React.FC = () => { } saveWorkflow(params).then(ret=>{ console.log(ret); - message.success('保存成功') + if(ret.code==200){ + message.success('保存成功') setTimeout(()=>{ - navgite({pathname:`/pipeline`,}); + if(val){ + navgite({pathname:`/pipeline`,}); + } },500) + } + else{ + message.error('保存失败') + } }) console.log(params); } const handlerClick=(e)=>{ + e.stopPropagation() console.log(propsRef,graph); // let cache = []; // let json_str = JSON.stringify(graph, function(key, value) { @@ -104,6 +134,106 @@ const editPipeline = React.FC = () => { },500) } } + const processParallelEdgesOnAnchorPoint = ( + edges, + offsetDiff = 15, + multiEdgeType = 'cubic-vertical', + singleEdgeType = undefined, + loopEdgeType = undefined + ) => { + const len = edges.length; + const cod = offsetDiff * 2; + const loopPosition = [ + 'top', + 'top-right', + 'right', + 'bottom-right', + 'bottom', + 'bottom-left', + 'left', + 'top-left', + ]; + const edgeMap = {}; + const tags = []; + const reverses = {}; + for (let i = 0; i < len; i++) { + const edge = edges[i]; + const { source, target, sourceAnchor, targetAnchor } = edge; + const sourceTarget = `${source}|${sourceAnchor}-${target}|${targetAnchor}`; + + if (tags[i]) continue; + if (!edgeMap[sourceTarget]) { + edgeMap[sourceTarget] = []; + } + tags[i] = true; + edgeMap[sourceTarget].push(edge); + for (let j = 0; j < len; j++) { + if (i === j) continue; + const sedge = edges[j]; + const { source: src, target: dst, sourceAnchor: srcAnchor, targetAnchor: dstAnchor } = sedge; + + // 两个节点之间共同的边 + // 第一条的source = 第二条的target + // 第一条的target = 第二条的source + if (!tags[j]) { + if (source === dst && sourceAnchor === dstAnchor + && target === src && targetAnchor === srcAnchor) { + edgeMap[sourceTarget].push(sedge); + tags[j] = true; + reverses[`${src}|${srcAnchor}|${dst}|${dstAnchor}|${edgeMap[sourceTarget].length - 1}`] = true; + } else if (source === src && sourceAnchor === srcAnchor + && target === dst && targetAnchor === dstAnchor) { + edgeMap[sourceTarget].push(sedge); + tags[j] = true; + } + } + } + } + + for (const key in edgeMap) { + const arcEdges = edgeMap[key]; + const { length } = arcEdges; + for (let k = 0; k < length; k++) { + const current = arcEdges[k]; + if (current.source === current.target) { + if (loopEdgeType) current.type = loopEdgeType; + // 超过8条自环边,则需要重新处理 + current.loopCfg = { + position: loopPosition[k % 8], + dist: Math.floor(k / 8) * 20 + 50, + }; + continue; + } + if (length === 1 && singleEdgeType && (current.source !== current.target || current.sourceAnchor !== current.targetAnchor)) { + current.type = singleEdgeType; + continue; + } + current.type = multiEdgeType; + const sign = + (k % 2 === 0 ? 1 : -1) * (reverses[`${current.source}|${current.sourceAnchor}|${current.target}|${current.targetAnchor}|${k}`] ? -1 : 1); + if (length % 2 === 1) { + current.curveOffset = sign * Math.ceil(k / 2) * cod; + } else { + current.curveOffset = sign * (Math.floor(k / 2) * cod + offsetDiff); + } + } + } + return edges; + }; + const cloneElement=(item)=>{ + console.log(item); + let data=graph.save() + const nodeId = s8(); + console.log(item.getModel()); + data.nodes.push({ + ...item.getModel(), + label: item.getModel().label+'-copy', + x: item.getModel().x + 150, + y: item.getModel().y, + id: item.getModel().component_name+'-'+nodeId, + }); + graph.changeData(data) + } const getFirstWorkflow=(val)=>{ getWorkflowById(val).then(ret=>{ console.log(ret); @@ -125,43 +255,65 @@ const editPipeline = React.FC = () => { } const initMenu=()=> { // const selectedNodes = this.selectedNodes; - setContextMenu(new G6.Menu({ + contextMenu=new G6.Menu({ getContent(evt) { - console.log(11111, evt); - - let ul = `
- + {dialogTitle} + } open={isModalOpen} className={Styles.modal} okButtonProps={{ htmlType: 'submit', form: 'form', }} onCancel={handleCancel}> @@ -242,15 +249,6 @@ const Pipeline = React.FC = () => { name="form" form={form} layout="vertical" - labelCol={{ - span: 8, - }} - wrapperCol={{ - span: 16, - }} - style={{ - maxWidth: 600, - }} initialValues={{ remember: true, }} @@ -282,18 +280,6 @@ const Pipeline = React.FC = () => { > - -