<template>
    <!-- 沙盘图区域 -->
    <div class="frame-container-wrap">
        <!-- 工具栏 -->
        <FrameToolBar v-if="$route.path!=='/chartframe'&&graph"
            :is-select-edge="isSelectEdge"
            :is-select-node="isSelectNode"
            :canUndo="canUndo"
            :canRedo="canRedo"
            :graph="graph"
            :current-cell="currentCell||baseNode"
        ></FrameToolBar>
        <div class="frame-container" id="frameContainer"></div>
        <!-- 缩略图 -->
        <div class="minimap" id="frameMinimap"></div>
        <!-- 右键菜单 -->
        <div id="context-menu-wrapper" @mouseleave="hideContextMenu">
            <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 class="empty" v-if="!FrameworkContent.length&&$route.path==='/chartframe'">
            <tableNoData text="框架内无节点"/>
        </div>
    </div>
</template>

<script>
import { ElDropdownMenu } from 'element-ui';
import { myGraph } from '../common/graph';
import { baseNode } from '../common/config';
import FrameToolBar from './frameToolBar.vue';
export default {
    components:{ElDropdownMenu,FrameToolBar},
    props:{
        FrameworkContent:{ //框架内容
            type:String,
            default:''
        }
    },
    data() {
        this.baseNode = baseNode //默认节点样式
        return {
            graph:null,//画布对象
            /* contextMenu:[{
                label: '编辑',
                key: 'edit',
                icon: 'el-icon-edit'
            },
            {
                label: '删除',
                key: 'del',
                icon: 'el-icon-delete'
            }], *///右键菜单
            isSelectEdge:false,//是否选择了边
            isSelectNode:false,//是否选择了节点
            currentCell:null,//当前选中的元素
            canRedo:false,//是否能前进
            canUndo:false,//是否能后退
            cleanSelect:false,//是否清除选区
        };
    },
    watch:{
        cleanSelect(newVal){
            if(newVal){
                this.currentCell = null
            }
        },
        FrameworkContent(newVal){//当框架内容发生改变时,画布内容也发生改变
            newVal.length&&this.gragh&&this.graph.fromJSON(JSON.parse(newVal))
        }
    },
    computed:{
        contextMenu(){//右键菜单,根据权限配置
            const editOption = {label: '编辑',key: 'edit',icon: 'el-icon-edit'}
            const deleteOption = {label: '删除',key: 'del',icon: 'el-icon-delete'}
            let MenuArr = []
            if(this.permissionBtn.isShowBtn('chartFramePermission','chartframe_my_editNode')){
                MenuArr.push(editOption)
            }
            MenuArr.push(deleteOption)
            return MenuArr
        }
    },
    methods: {
        //初始化画布
        init(){
            //如果需要在内部调用vue实例,则初始化时就将this传入
            this.graph = new myGraph('frameContainer',this)
            //如果有内容,初始化画布内容
            this.FrameworkContent.length&&this.graph.fromJSON(JSON.parse(this.FrameworkContent))
            //如果有内容,将画布内容居中
            this.FrameworkContent.length&&this.graph.scrollToContent({ animation: { duration: 600 }})
            //如果是非编辑页,加载完成画布内容后冻结画布
            window.location.pathname.startsWith('/chartframe')&&this.graph.freeze()
            //如果是编辑页，加载完成后清除历史数据
            !window.location.pathname.startsWith('/chartframe')&&this.graph.cleanHistory()
        },
        //销毁画布
        dispose(){
            this.graph&&this.graph.dispose()
        },
        //添加/编辑节点
        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.id=node.nodeLink.MyChartClassifyId
                currentNode.label=node.nodeName
                currentNode.data.nodeLink = node.nodeLink
            }else{
                //在视口范围内添加节点
                this.graph.addNode({
                    ...baseNode,
                    ...{
                    x:position.x+position.width/2+20,
                    y:position.y+position.height/2+20,
                    width:120,
                    height:50,
                    data:{
                        id:node.nodeLink.MyChartClassifyId,//存储节点对应的myETA分类id
                        nodeLink:node.nodeLink
                    },
                    label:node.nodeName||''
                }})
            }
        },
        //点击右键菜单事件
        handleContext(key){
            const select_cell = this.graph.getSelectedCells()
            if(!select_cell.length) return 

            if(key==='edit'){
                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.nodeLink
                })
            }
            if(key==='del'){
                this.graph.removeCells(select_cell)
                this.hideContextMenu()
            }
            //清除选区
            this.graph.cleanSelection()
        },
        hideContextMenu(){
            const dom = $('#context-menu-wrapper')[0];
            dom.style.left = '-9999px';
            dom.style.top = '-9999px';
        },
        //获取画布内容的svg数据
        getContentPic(){
            const { cells } = this.graph.toJSON();
            let svgData = ''
            this.graph.toSVG((dataUri) => {
                svgData = dataUri 
                
            },{
                preserveDimensions:true,//让svg为实际图片大小
                beforeSerialize:(svg)=>{
                    const {x,y,width,height} = this.graph.getContentBBox(cells)
                    let {tx,ty} = this.graph.translate() // 画布偏移量
                    //给导出的svg增加一点宽高
                    svg.setAttribute('width',width+50)
                    svg.setAttribute('height',height+50) 
                    //设置viewBox使图像居中
                    svg.setAttribute('viewBox',`${x-25} ${y-25} ${width+50} ${height+50}`)
                },
                copyStyles:false,
                stylesheet: `
                    svg{
                        background-color:white;
                    }
                    .x6-port {
                        visibility: hidden;
                    }
                    ` 
            })
            return svgData
        },
        //获取画布节点并转换成对应格式
        getContentNodes(){
            return this.graph.getNodes().map(node=>{
                return {
                    NodeName:node.label,
                    MyChartClassifyId:Number(node.data.id)
                }
            })
        }
    },
    mounted(){
        //this.init()
    }
};
</script>

<style lang="scss">
.frame-container-wrap {
    width:100%;
    height:100%;
    display: flex;
    overflow: hidden;
    position: relative;
    padding-top: 26px;
    .minimap {
        position: absolute;
        right: 16px;
        bottom: 16px;
        box-sizing: border-box;

        .x6-widget-minimap-viewport {
            border-color: #0052D9;

            .x6-widget-minimap-viewport-zoom {
                border-color: #0052D9;
            }
        }

        .x6-widget-minimap {
            width: auto !important;
            height: auto !important;
            overflow: visible !important;
            padding:0 !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;
        width:auto !important;
        height:auto !important;
    }

    .x6-port-body {
        display: none;
    }
    .empty{
        position:absolute;
        left:50%;
        top:0;
        transform: translateX(-50%);
    }
}
</style>
<style scoped lang="scss">

</style>