<template>
|
<div class="pageWarp" ref="pageWarp">
|
<div ref="demo"></div>
|
<vue-draggable-resizable :w="item.w" :h="item.h" :x="item.x" :y="item.y" @dragging="onDrag" @dragstop="onDragstop"
|
@resizing="onResize" @resizestop="onResizstop" :parent="true" :debug="false" :snap="true" :snapTolerance="5"
|
:draggable="draggable" :resizable="resizable" style="transition: none; will-change: transform;"
|
@activated="onActived(item)" v-for="(item,i) in nowlayOut.children" :key="i">
|
<div @contextmenu.prevent.stop="openMenu(item,$event)" style="width:100%;height:100%;">
|
<layout-box :title="item.name">
|
<div style="width:100%;height:100%" :id="'layout-box'+item.id" :ref="'layout-box'+item.id"></div>
|
</layout-box>
|
</div>
|
</vue-draggable-resizable>
|
|
<!--<div class="chartCon">
|
<layout-box title="电源状态">
|
<div class="chartItem">
|
<pross-pie-chart id="prossPieChart1" ref="prossPieChart1"></pross-pie-chart>
|
</div>
|
<div class="chartItem">
|
<pross-pie-chart id="prossPieChart2" ref="prossPieChart2"></pross-pie-chart>
|
</div>
|
<div class="chartItem">
|
<pross-pie-chart id="prossPieChart3" ref="prossPieChart3"></pross-pie-chart>
|
</div>
|
<div class="chartItem">
|
<pross-pie-chart id="prossPieChart4" ref="prossPieChart4"></pross-pie-chart>
|
</div>
|
</layout-box>
|
</div> -->
|
<!-- <span class="ref-line v-line" v-for="(item,index) in vLine" :key="'vLine'+index" v-show="item.display"
|
:style="{ left: item.position, top: item.origin, height: item.lineLength}"></span>
|
<span class="ref-line h-line" v-for="(item,index) in hLine" :key="'hLine'+index" v-show="item.display"
|
:style="{ top: item.position, left: item.origin, width: item.lineLength}"></span> -->
|
<ul v-show="rightMenuVisible" :style="{left:contextmenuLeft+'px',top:contextmenuTop+'px'}" class="contextmenu">
|
<li><i class="el-icon-refresh-right"></i> 重新加载</li>
|
<li @click="removeModular"><i class="el-icon-delete"></i> 删除</li>
|
</ul>
|
</div>
|
</template>
|
|
<script>
|
import Vue from "vue";
|
import VueDraggableResizable from 'vue-draggable-resizable-gorkys'
|
import 'vue-draggable-resizable-gorkys/dist/VueDraggableResizable.css'
|
import LayoutBox from "@/components/LayoutBox";
|
// import prossPieChart from '../components/charts/prossPieChart.vue';
|
let clientWidth, clientHeight;
|
export default {
|
props: ['layOut', 'draggable', 'resizable'],
|
components: {
|
VueDraggableResizable,
|
LayoutBox,
|
// prossPieChart,
|
},
|
data() {
|
return {
|
draggableActived: null,
|
vLine: [],
|
hLine: [],
|
rightMenuVisible: false,
|
contextmenuTop: 0,
|
contextmenuLeft: 0,
|
clickItem: null,
|
parentByValue: false,
|
nowlayOut: {},
|
modularArr: []
|
}
|
},
|
watch: {
|
rightMenuVisible(value) {
|
if (value) {
|
document.body.addEventListener('click', this.closeMenu)
|
} else {
|
document.body.removeEventListener('click', this.closeMenu)
|
}
|
},
|
'layOut': {
|
handler(val) {
|
this.nowlayOut = JSON.parse(JSON.stringify(val));
|
this.loadLayout();
|
},
|
deep: true
|
}
|
},
|
mounted() {
|
//禁止鼠标右键菜单
|
document.oncontextmenu = function () {
|
return false;
|
};
|
this.$nextTick(() => {
|
clientWidth = this.$refs.pageWarp.clientWidth;
|
clientHeight = this.$refs.pageWarp.clientHeight;
|
})
|
// this.$refs.prossPieChart1.setData({
|
// title: '交流停电数量',
|
// data: 56,
|
// color: '#37a9b3'
|
// });
|
},
|
methods: {
|
// 选中要调整的面板时
|
onActived(panel) {
|
this.draggableActived = panel;
|
},
|
//面板改变大小时
|
onResize(x, y, width, height) {
|
this.nowlayOut.children.filter((card) => {
|
if (this.draggableActived.id === card.id) {
|
card.w = width;
|
card.h = height;
|
card.x = x;
|
card.y = y;
|
this.modularArr.map(item => {
|
if (item.id == `chart${this.draggableActived.id}`) {
|
item.resize();
|
}
|
})
|
}
|
return true;
|
});
|
},
|
onResizstop(x, y, width, height) {
|
this.nowlayOut.children.filter((card) => {
|
if (this.draggableActived.id === card.id) {
|
card.w = width;
|
card.h = height;
|
card.x = x;
|
card.y = y;
|
this.modularArr.map(item => {
|
if (item.id == `chart${this.draggableActived.id}`) {
|
item.resize();
|
}
|
})
|
}
|
return true;
|
});
|
let sendData = JSON.parse(JSON.stringify(this.nowlayOut));
|
sendData.children.map((item) => {
|
item.x = item.x / clientWidth;
|
item.y = item.y / clientHeight;
|
item.w = item.w / clientWidth;
|
item.h = item.h / clientHeight;
|
})
|
this.$emit('onDragstop', sendData);
|
},
|
//面板改变位置时
|
onDrag(x, y) {
|
this.nowlayOut.children.filter((card) => {
|
if (this.draggableActived.id === card.id) {
|
card.x = x;
|
card.y = y;
|
}
|
return true;
|
});
|
},
|
onDragstop(x, y) {
|
this.nowlayOut.children.filter((card) => {
|
if (this.draggableActived.id === card.id) {
|
card.x = x;
|
card.y = y;
|
}
|
return true;
|
});
|
let sendData = JSON.parse(JSON.stringify(this.nowlayOut));
|
sendData.children.map((item) => {
|
item.x = item.x / clientWidth;
|
item.y = item.y / clientHeight;
|
item.w = item.w / clientWidth;
|
item.h = item.h / clientHeight;
|
})
|
this.$emit('onDragstop', sendData);
|
},
|
// 辅助线回调事件
|
// getRefLineParams(params) {
|
// const {
|
// vLine,
|
// hLine
|
// } = params
|
// this.vLine = vLine
|
// this.hLine = hLine
|
// },
|
//模块右键菜单打开
|
openMenu(clickItem, e) {
|
this.clickItem = clickItem;
|
this.contextmenuLeft = e.clientX
|
this.contextmenuTop = e.clientY
|
this.rightMenuVisible = true
|
},
|
//模块右键菜单关闭
|
closeMenu() {
|
this.rightMenuVisible = false
|
},
|
//删除大屏数据模块
|
removeModular() {
|
this.nowlayOut.children.map((item, i) => {
|
if (item.name == this.clickItem.name) {
|
this.nowlayOut.children.splice(i, 1);
|
this.modularArr.splice(i, 1);
|
}
|
})
|
let sendData = JSON.parse(JSON.stringify(this.nowlayOut));
|
sendData.children.map((item) => {
|
item.x = item.x / clientWidth;
|
item.y = item.y / clientHeight;
|
item.w = item.w / clientWidth;
|
item.h = item.h / clientHeight;
|
})
|
this.$emit('removeModular', sendData);
|
},
|
// 加载布局数据
|
loadLayout() {
|
this.$nextTick(() => {
|
this.nowlayOut.children.map((item) => {
|
console.log(item)
|
item.x *= clientWidth;
|
item.y *= clientHeight;
|
item.w *= clientWidth;
|
item.h *= clientHeight;
|
let nowBox = this.$refs[`layout-box${item.id}`];
|
let modular = require(`./charts/${item.type}.vue`).default;
|
let modularExtend = Vue.extend(modular);
|
let chartModular = new modularExtend().$mount();
|
chartModular.id = `chart${item.id}`
|
if (nowBox[0].children.length > 0) {
|
nowBox[0].replaceChild(chartModular.$el, nowBox[0].children[0])
|
} else {
|
nowBox[0].appendChild(chartModular.$el)
|
this.modularArr.push(chartModular);
|
}
|
chartModular.setData(item.setData);
|
chartModular.resize();
|
})
|
})
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
.pageWarp {
|
width: 100%;
|
height: calc(100% - 52px);
|
}
|
|
.chartCon {
|
width: 33.33%;
|
height: 50%;
|
padding: 10px;
|
float: left;
|
box-sizing: border-box;
|
}
|
|
.flexCon {
|
width: 100%;
|
height: 100%;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
}
|
|
.flexCon .con {
|
width: 100%;
|
height: 60%;
|
}
|
|
.chartCon .chartItem {
|
width: 50%;
|
height: 48%;
|
float: left;
|
margin-bottom: 2%;
|
}
|
|
.contextmenu {
|
margin: 0;
|
background: #27343e;
|
z-index: 3000;
|
position: absolute;
|
list-style-type: none;
|
padding: 5px 0;
|
border-radius: 4px;
|
font-size: 12px;
|
font-weight: 400;
|
color: #bcc9d4;
|
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
|
}
|
|
.contextmenu li {
|
padding: 0 6px;
|
line-height: 28px;
|
height: 28px;
|
border-left: 2px solid transparent;
|
cursor: pointer;
|
overflow: hidden;
|
padding-right: 3em;
|
display: flex;
|
align-items: center;
|
}
|
|
.contextmenu li i {
|
margin-right: 8px;
|
}
|
|
.contextmenu li:hover {
|
background-color: #1d262e;
|
color: #2681ff;
|
border-left: 2px solid #2681ff;
|
}
|
|
.flexCon {
|
width: 100%;
|
height: 100%;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
}
|
|
.flexCon .con {
|
width: 100%;
|
height: 60%;
|
}
|
</style>
|