Browse Source

框架添加/编辑节点

cxmo 1 year ago
parent
commit
983d4f6b3f

+ 12 - 0
src/views/chartFrame_manage/common/event.js

@@ -0,0 +1,12 @@
+//监听画布事件
+export const myEvents = (graph)=>{
+    //右键节点/边
+    graph.on('cell:contextmenu',({cell,e})=>{
+        console.log('context')
+        graph.select(cell)
+        const dom = $('#context-menu-wrapper')[0];
+        dom.style.left = e.clientX-3 + 'px';
+        dom.style.top = e.clientY-3 + 'px';
+    })
+
+}

+ 34 - 0
src/views/chartFrame_manage/common/gragh.js

@@ -0,0 +1,34 @@
+import {
+    Graph,
+} from '@antv/x6';
+import { myEvents } from './event';
+
+export function myGraph(wrapper) {
+    const graph = new Graph({
+        container: document.getElementById(wrapper),
+        background: {
+            color: '#fff',
+        },
+        snapline: true,
+        scroller: {
+            enabled: true,
+            pannable: true,
+            minVisibleWidth: 50,
+            minVisibleHeight: 50,
+        },
+        resizing: {
+            enabled: true,
+            orthogonal: false,
+        },
+        scaling: {
+            min: 0.5,
+            max: 2
+        },
+        minimap: {
+            enabled: true,
+            container: document.getElementById("frameMinimap"),
+        }
+    })
+    myEvents(graph);
+    return graph
+}

+ 129 - 5
src/views/chartFrame_manage/components/frameContainer.vue

@@ -1,23 +1,147 @@
 <template>
     <!-- 沙盘图区域 -->
-    <div>
-
+    <div class="frame-container-wrap">
+        <div class="frame-container" id="frameContainer"></div>
+        <!-- 缩略图 -->
+        <div class="minimap" id="frameMinimap"></div>
+        <!-- 右键菜单 -->
+        <div id="context-menu-wrapper">
+            <el-dropdown-menu size="medium">
+                <el-dropdown-item v-for="menu in contextMenu" :key="menu.key" @click.native="handleContext(menu.key)">
+                    <i :class="menu.icon" v-if="menu.icon"/> 
+                    {{menu.label}}
+                </el-dropdown-item>
+            </el-dropdown-menu>
+        </div>
     </div>
 </template>
 
 <script>
+import { ElDropdownMenu } from 'element-ui';
+import { myGraph } from '../common/gragh';
 export default {
+    components:{ElDropdownMenu},
     data() {
         return {
-
+            graph:null,
+            contextMenu:[{
+                label: '编辑',
+                key: 'edit',
+                icon: 'el-icon-edit'
+            },
+            {
+                label: '删除',
+                key: 'del',
+                icon: 'el-icon-delete'
+            }],//右键菜单
         };
     },
     methods: {
-
+        init(){
+            this.graph = new myGraph('frameContainer');
+            const rect = this.graph.addNode({
+                x: 40,
+                y: 40,
+                width: 120,
+                height: 50,
+                data:{
+                    myETAId:652
+                },
+                label:'test'
+                })
+            //如果有内容
+            //graph.centerContent()
+            this.graph.scrollToContent({ animation: { duration: 600 }})
+        },
+        editNode(node){
+            //在视口范围内添加一个
+            const position = this.graph.getContentArea()
+            const nodes = this.graph.getNodes()
+            const currentNode = nodes.find(item=>item.id===node.nodeId)
+            if(currentNode){
+                currentNode.data.myETAId=node.nodeLink
+                currentNode.label=node.nodeName
+            }else{
+                this.graph.addNode({
+                    x:100,
+                    y:100,
+                    width:120,
+                    height:50,
+                    data:{
+                        myETAId:node.nodeLink,//存储节点对应的myETA分类id
+                    },
+                    label:node.nodeName||''
+                })
+            }
+        },
+        handleContext(key){
+            //编辑test
+            const select_cell = this.graph.getSelectedCells()
+            if(!select_cell.length) return 
+            const {id} = select_cell[0]
+            const node = this.graph.getNodes().find(item=>item.id===id)
+            this.$emit('editNode',{
+                    nodeId:node.id,
+                    nodeName:node.label,
+                    nodeLink:node.data.myETAId
+                })
+        },
+        deleteNode(){},
     },
+    mounted(){
+        this.init()
+    }
 };
 </script>
 
-<style scoped lang="scss">
+<style lang="scss">
+.frame-container-wrap {
+    width:100%;
+    height:100%;
+    display: flex;
+    overflow: hidden;
+    position: relative;
+    .minimap {
+        position: absolute;
+        right: 6px;
+        bottom: 6px;
+        box-sizing: border-box;
+
+        .x6-widget-minimap-viewport {
+            border-color: red;
 
+            .x6-widget-minimap-viewport-zoom {
+                border-color: red;
+            }
+        }
+
+        .x6-widget-minimap {
+            width: auto !important;
+            height: auto !important;
+        }
+    }
+    #context-menu-wrapper{
+        position: fixed;
+        z-index: 99;
+        top: -9999px;
+        left: -9999px;
+        background: #fff;
+        padding: 10px 0;
+        box-shadow: 0 1px 4px #999;
+
+    }
+    #frameContainer{
+        flex: 1;
+    }
+    .x6-graph-scroller {
+        flex: 1;
+    }
+
+    .x6-port-body {
+        display: none;
+    }
+}
 </style>
+<style scoped lang="scss">
+
+</style>

+ 76 - 15
src/views/chartFrame_manage/frameEditor.vue

@@ -3,12 +3,17 @@
     <div class="frame-editor-wrap">
         <div class="option-wrap">
             <el-input style="width:240px;" placeholder="请输入框架名称"></el-input>
-            <el-button type="primary" style="margin-left:auto;" @click="handleEditNode">添加节点</el-button>
+            <el-button type="primary" style="margin-left:auto;" @click="handleEditNode({})">添加节点</el-button>
             <el-button type="primary" style="margin-left:20px;">保存</el-button>
         </div>
         <div class="editor-wrap">
             <div class="tool-wrap">工具栏</div>
-            <div class="frame-wrap"></div>
+            <div class="frame-wrap">
+                <!-- 沙盘图组件 -->
+                <FrameContainer ref="container"
+                    @editNode="handleEditNode"
+                />
+            </div>
         </div>
         <!-- 添加/编辑节点弹窗 -->
         <el-dialog
@@ -22,13 +27,31 @@
             center
         >
             <div class="dialog-container">
-                <el-form>
-
+                <el-form
+                    ref="refForm"
+                    :model="modifyNode"
+                    :rules="rules"
+                >
+                    <el-form-item label="节点名称" prop="nodeName">
+                        <el-input v-model="modifyNode.nodeName" placeholder="请输入节点名称" style="width:217px;"></el-input>
+                    </el-form-item>
+                    <el-form-item label="节点链接" prop="nodeLink">
+                        <el-select v-model="modifyNode.nodeLink" placeholder="请选择节点链接" style="width:217px;">
+                            <el-option v-for="item in mockMyList" 
+                                :key="item.classifyId"
+                                :label="item.name"
+                                :value="item.classifyId">
+                                <span style="float:left;">{{item.name}}</span>
+                                <span style="float:right;color: #8492a6; font-size: 13px"
+                                @click="goToList(item)"><i class="el-icon-view"></i></span>
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
                 </el-form>
             </div>
             <div class="dialog-footer">
                 <el-button>取消</el-button>
-                <el-button type="primary">确定</el-button>
+                <el-button type="primary" @click="editNode">确定</el-button>
             </div>
 
         </el-dialog>
@@ -36,23 +59,46 @@
 </template>
 
 <script>
+import FrameContainer from './components/frameContainer.vue';
+
 export default {
+    components: { FrameContainer },
     data() {
         return {
-            modifyNode:{},
-            isModifyNodeDialogShow:false,
-            rules:{
-                nodeName:[{required: true,message: "请输入节点名称",trigger: "blur"}],
-                nodeLink:[{required: true,message: "请选择节点链接",trigger: "blur"}]
-            }
+            modifyNode: {},
+            isModifyNodeDialogShow: false,
+            rules: {
+                nodeName: [{ required: true, message: "请输入节点名称", trigger: "blur" }],
+                nodeLink: [{ required: true, message: "请选择节点链接", trigger: "blur" }]
+            },
+            mockMyList: [
+                {
+                    classifyId: 652,
+                    name: '框架1'
+                },
+                {
+                    classifyId: 651,
+                    name: '框架2'
+                }
+            ]
         };
     },
     methods: {
-        handleEditNode(node={}){
-            this.modifyNode = node
-            this.isModifyNodeDialogShow = true
+        handleEditNode(node = {}) {
+            this.$refs.refForm && this.$refs.refForm.resetFields();
+            this.modifyNode = _.cloneDeep(node);
+            this.isModifyNodeDialogShow = true;
+        },
+        async editNode() {
+            await this.$refs.refForm.validate();
+            if(!this.$refs.container) return
+            this.$refs.container.editNode(this.modifyNode)
+            this.$message.success(`${this.modifyNode.nodeId ? '编辑' : '添加'}成功`);
+            this.isModifyNodeDialogShow = false;
         },
-        addNode(){},
+        goToList(item) {
+            window.open(`/mychart?frameId=${item.classifyId}`);
+        }
     },
 };
 </script>
@@ -79,6 +125,21 @@ export default {
         }
         .frame-wrap{
             flex:1;
+            background-color: #F2F6FA;
+        }
+    }
+    .el-dialog{
+        .dialog-container{
+           .el-form{
+               .el-form-item{
+                   display: flex;
+                   justify-content: center;
+               }
+           }
+        }
+        .dialog-footer{
+            text-align: center;
+            padding-bottom:25px;
         }
     }
 }

+ 4 - 0
src/views/mychart_manage/index.vue

@@ -882,6 +882,10 @@ export default {
       : 0;
     this.ispublic=sessionStorage.getItem('myChartIspublic')? Number(sessionStorage.getItem('myChartIspublic')): '';
     }
+    if(this.$route.query.frameId){
+        this.select_classify = Number(this.$route.query.frameId)
+        this.ispublic = ''
+    }
     this.getClassify();
     this.getPublicClassify();
   },