feat: panel拖拽、缩放(部分)

This commit is contained in:
chenjinsong
2020-05-29 21:06:55 +08:00
parent 371d6e4a20
commit b5eecd5926
8 changed files with 1349 additions and 1661 deletions

View File

@@ -1,74 +1,45 @@
<style scoped>
.chartBox {
box-sizing: border-box;
float:left;
padding: 0 10px 10px 10px;
/*position:relative;*/
padding: 0 10px;
margin: 10px 0;
position:relative;
box-sizing: border-box;
}
.noData{
text-align: center
}
.list-width{
width: calc(100% - 14px);
overflow-x:hidden;/*避免鼠标第一次放到曲线时x轴出现滚动条后消失*/
padding: 5px 15px 5px 10px;
box-sizing: border-box;
overflow: hidden;/*避免鼠标第一次放到曲线时x轴出现滚动条后消失*/
}
.drag-chart-class{
cursor:move !important;
/*
border:solid 2px yellow;
color:yellow;
background-color:yellow !important;
*/
/*background-color:red;
opacity:1*/
</style>
<style lang="scss">
.vue-resizable-handle {
position: absolute;
width: 20px;
height: 20px;
bottom: 0;
right: 0;
cursor: se-resize;
box-sizing: border-box;
}
.choose-class{
cursor:move;
/* border:solid 2px purple;
color:purple;
background-color:purple;*/
.vue-resizable-handle:after {
border-right: 2px solid #555;
border-bottom: 2px solid #555;
content: "";
position: absolute;
right: 3px;
bottom: 3px;
width: 5px;
height: 5px;
box-sizing: inherit;
}
.chosen-class .chartTitle{
}
.fallback-class{
cursor:move;
/*background-color:green;
cursor:pointer;*/
}
.chart-ghost {
/*
opacity: 1;
border:solid 2px green;
*/
}
</style>
<template>
<div class="list-width" id="listContainer"><!--v-drag-->
<!--
draggable="true"
@dragstart="handleDragStart($event, item)"
@dragover.prevent="handleDragOver($event, item)"
@dragenter="handleDragEnter($event, item)"
@dragend="handleDragEnd($event, item)"
@mousedown="dragPosition($event,item)"
<draggable v-model="dataList" @chang="change" @start="start" @end="end" :move="move" @choose="choose"
@add="add" @clone="clone" @update="update" @remove="remove" @sort="sort"
:scroll-sensitivity="150"
:options="{
group:{name:'chartGroup',pull:'false'},
dragClass:'drag-chart-class',
fallbackClass:'fallback-class',
forceFallback:true,
ghostClass:'chart-ghost',
chosenClass:'choose-class',
scroll:true,
scrollFn:function(offsetX,offsetY,originalEvent,touchEvt,hoverTargetEI){},
animation:150,
handle:'.chartTitle',
}" >@clone="clone"
-->
<draggable v-model="dataList" @start="start" @end="end" :move="move" :key
:scroll-sensitivity="150"
:options="{
@@ -83,8 +54,7 @@
animation:150,
handle:'.chartTitle',
}" >
<div class="chartBox" v-for="(item, index) in dataList" :key="index" :id="item.title+'_'+item.id"
>
<div class="chartBox" v-for="(item, index) in dataList" :key="index" :id="'chart-' + item.id" :name="item.title">
<line-chart-block v-if="item.type === 'line' || item.type === 'bar' ||item.type == 'stackArea' || item.type === 4" :key="'inner' + item.id"
:ref="'editChart'+item.id"
@on-refresh-data="refreshChart"
@@ -94,7 +64,8 @@
@on-edit-chart-block="editData"
:panel-id="filter.panelId"
:chart-index="index"
:editChartId="'editChartId' + item.id"></line-chart-block>
:chart-data="item"
:step-height="stepHeight"></line-chart-block>
<chart-single-stat v-if="item.type === 'singleStat'" :ref="'editChart'+item.id" :key="'inner' + item.id"
@on-refresh-data="refreshChart"
@@ -103,9 +74,9 @@
@on-duplicate-chart-block="duplicateChart"
@on-drag-chart="editChartForDrag"
@on-edit-chart-block="editData"
:chart-data="item"
:panel-id="filter.panelId"
:chart-index="index"
:editChartId="'editChartId' + item.id"></chart-single-stat>
:chart-index="index"></chart-single-stat>
<chart-table v-if="item.type === 'table'" :ref="'editChart'+item.id" :key="'inner' + item.id"
@on-refresh-data="refreshChart"
@@ -116,7 +87,7 @@
@on-edit-chart-block="editData"
:panel-id="filter.panelId"
:chart-index="index"
:editChartId="'editChartId' + item.id"></chart-table>
:step-height="stepHeight"></chart-table>
<chart-url v-if="item.type === 'url'" :ref="'editChart'+item.id" :key="'inner' + item.id"
@on-refresh-data="refreshChart"
@@ -126,8 +97,7 @@
@on-drag-chart="editChartForDrag"
@on-edit-chart-block="editData"
:panel-id="filter.panelId"
:chart-index="index"
:editChartId="'editChartId' + item.id"></chart-url>
:chart-index="index"></chart-url>
<chart-asset-info v-if="item.type === 'assetInfo'" :ref="'editChart'+item.id" :key="'inner' + item.id"
@on-drag-chart="editChartForDrag"
@@ -153,18 +123,19 @@
<el-row v-if="dataList.length === 0" class="noData"></el-row>
</div>
</template>
<script>
import axios from 'axios';
import bus from '../../libs/bus';
import lineChartBlock from './line-chart-block';
import chartTable from './chart-table';
import chartUrl from './chart-url';
import chartSingleStat from './chart-single-stat';
import chartAssetInfo from './chart-asset-info'
import draggable from 'vuedraggable'
import chartDataFormat from "./chartDataFormat";
import chartAlertList from './chart-alert-list'
export default {
import axios from 'axios';
import bus from '../../libs/bus';
import lineChartBlock from './line-chart-block';
import chartTable from './chart-table';
import chartUrl from './chart-url';
import chartSingleStat from './chart-single-stat';
import chartAssetInfo from './chart-asset-info'
import draggable from 'vuedraggable'
import chartDataFormat from "./chartDataFormat";
import chartAlertList from './chart-alert-list'
export default {
name: 'chartList',
props: {
isModel: {type: Boolean, default: false},
@@ -198,6 +169,7 @@ export default {
pagePanelId:'',//当前分页的panelId
dragging: null,
chartDataCacheGroup:new Map,//图表数据缓存用于查询id:{}
stepHeight: 50,
};
},
computed: {},
@@ -208,99 +180,11 @@ export default {
},
start (event) {
console.log('start', event, this.dataList);
let item = event.item;
let chartTitle = item.querySelector('.chartTitle');
chartTitle.style.background = '#d8dce1';
console.log('start-title',chartTitle);
event.item.querySelector('.chartTitle').style.background = '#d8dce1';
this.dataListDragTmp = [...this.dataList];
let dragClass = document.querySelector('.drag-chart-class');//drag-chart-class:yellow chart-ghost:green fallback-class choose-class:purple
console.log('start---class', dragClass);
//dragClass.style.opacity = 1;
//dragClass.style.pointerEvents = 'auto';
/*
let canvas = item.querySelector('canvas');
console.log('start-canvas',canvas);
let canvasclone = event.clone.querySelector('canvas');
console.log('start-canvas-style',canvasclone.style);
canvasclone.style.border='solid 2px green !importmant';
console.log('start-canvas-style2',canvasclone.style);
if(canvas&&canvasclone) {
let ctx = canvas.getContext("2d");
let image = new Image();
image.src = canvas.toDataURL();
//var a = document.createElement("a");
//a.href=canvas.toDataURL();
//a.download="drcQrcode";
//a.click();
console.log('clone-image', image)
let ctxClone = canvasclone.getContext("2d");
image.onload = function () {
console.log('clone-image-load', image)
//ctxClone.drawImage(image, 0, 0);
}
}
*/
},
end (event) {
let item = event.item;
//console.log('item--old', item);
//console.log('end', event, this.dataList);
//console.log('totalBak', event, this.dataTotalListBak);
/*
let len = this.dataListDragTmp.length;
let endIndex = len-1;
let oldIndex = event.oldIndex;
if(oldIndex===0){//挪动之前为第一个元素
let oldNextItem = this.dataListDragTmp[oldIndex+1];
let nextItem = this.dataList.find(item => item.id === oldNextItem.id);
nextItem.prev = 0;
}else if(oldIndex===endIndex){//挪动之前为最后一个元素
let oldPrevItem = this.dataListDragTmp[oldIndex-1];
let prevItem = this.dataList.find(item => item.id === oldPrevItem.id);
prevItem.next = -1;
}else{//挪动之前为中间元素
let oldPrevItem = this.dataListDragTmp[oldIndex-1];
let oldNextItem = this.dataListDragTmp[oldIndex+1];
let nextItem = this.dataList.find(item => item.id === oldNextItem.id);
let prevItem = this.dataList.find(item => item.id === oldPrevItem.id);
prevItem.next = oldNextItem.id;
nextItem.prev = oldPrevItem.id;
}
let newIndex = event.newIndex;
let newItem = this.dataList[newIndex];
if(newIndex===0){//挪动之后为第一个元素
let newNextItem = this.dataList[newIndex+1];
newNextItem.prev = newItem.id;
}else if(newIndex===endIndex){//挪动之后为最后一个元素
let newPrevItem = this.dataList[newIndex-1];
newPrevItem.next =newItem.id;
}else{//挪动之后为中间元素
let newPrevItem = this.dataList[newIndex-1];
let newNextItem = this.dataList[newIndex+1];
newPrevItem.next = newItem.id;
newNextItem.prev = newItem.id;
}
*/
/*
if(this.dataList.length===1){
newItem.prev = 0;
newItem.next = -1;
}else if(newIndex===0){//挪动之后为第一个元素
let newNextItem = this.dataList[newIndex+1];
newItem.prev = 0;
newItem.next = newNextItem.id;
}else if(newIndex===(this.dataList.length-1)){//挪动之后为最后一个元素
let newPrevItem = this.dataList[newIndex-1];
newItem.prev = newPrevItem.id;
newItem.next = -1;
}else{//挪动之后为中间元素
let newNextItem = this.dataList[newIndex+1];
let newPrevItem = this.dataList[newIndex-1];
newItem.prev = newPrevItem.id;
newItem.next = newNextItem.id;
}
*/
let oldIndex = event.oldIndex;
let newIndex = event.newIndex;
let newItem = this.dataList[newIndex];
@@ -433,8 +317,6 @@ export default {
choose(event ){
console.log('choose', event);
let chartTitle = event.item.querySelector('.chartTitle');
//console.log('choose-title',chartTitle);
//chartTitle.style.background = '#d8dce1';
},
clone(event){
console.log('clone',event );
@@ -447,10 +329,6 @@ export default {
let ctx = canvas.getContext("2d");
let image = new Image();
image.src= canvas.toDataURL();
/*var a = document.createElement("a");
a.href=canvas.toDataURL();
a.download="drcQrcode";
a.click();*/
console.log('clone-image',image);
let ctxClone = canvasclone.getContext("2d");
//ctxClone.drawImage(image,0,0);
@@ -458,7 +336,6 @@ export default {
console.log('clone-image-load',image);
ctxClone.drawImage(image,0,0);
}
}
},
add(event){
@@ -488,31 +365,11 @@ export default {
document.onmousemove=function(e){
e.preventDefault();
console.log('===onmousemove',e.clientY,e.clientX);
//e.preventDefault();
// var distY=Math.abs(e.clientY-startY);
// var distX=Math.abs(e.clientX-startX);
let left=e.clientX-distX;
let top=e.clientY-distY;
odiv.style.top=top+'px';
odiv.style.left=left+'px';
console.log('odiv====',odiv);
/*
//往上方拖动:
if( e.clientY < startY){
targetDiv.style.top=(startY-distY)+'px';
}
if( e.clientX < startX){
targetDiv.style.left=(startX-distX)+'px';
}
//往下方拖动:
if (e.clientY > startY) {
targetDiv.style.top=(startY+distY)+'px';
}
if (e.clientX > startX) {
targetDiv.style.left=(startX+distX)+'px';
}
*/
};
document.onmouseup=function(){
@@ -548,23 +405,17 @@ export default {
this.currentRecordNum = 0;
},
cleanData(){
/*if (this.dataList.length > 0 && this.$refs.editChart) {
this.$refs.editChart.forEach((item) => {
item.clearData();
/*if (this.dataList.length > 0 ) {
this.dataList.forEach((item) => {
if (this.$refs['editChart'+item.id] && this.$refs['editChart'+item.id].length > 0) {
this.$refs['editChart'+item.id][0].clearData();
}
});
}*/
if (this.dataList.length > 0 ) {
this.dataList.forEach((item) => {
this.$refs['editChart'+item.id][0].clearData();
});
}
this.dataList = [];
//console.log("__map__",JSON.stringify(this.chartDataCacheGroup))
this.chartDataCacheGroup.clear();
//console.log("__map22__",JSON.stringify(this.chartDataCacheGroup))
},
initData(filter) {
//this.dataList = [];
this.cleanData();
// 内含 panelId,开始时间,结束时间
this.filter = filter;
@@ -597,12 +448,10 @@ export default {
if (this.dataList.length > 0 ) {
this.dataList.forEach((item,index) => {
this.$refs['editChart'+item.id][0].showLoad(item);//之后要实现
this.setSize(item.span, index);//设置该图表宽度
//获得当前显示在浏览器的图表,从后台获取数据
let chartBox = document.getElementById(item.title+'_'+item.id);//this.$refs['editChart'+item.id][0];
//console.log(item.title,"___searchChart___",JSON.stringify(item))
this.setChartSize(item.span, index);//设置该图表宽度
if(!item.isLoaded ){
//获得当前显示在浏览器的图表,从后台获取数据
let chartBox = document.getElementById('chart-' + item.id);//this.$refs['editChart'+item.id][0];
this.handleElementInViewport(chartBox,0,item,index,true);
}
});
@@ -682,6 +531,7 @@ export default {
}
this.dataTotalListBak = [...this.dataTotalList];
//查询条件带name
if(this.filter.searchName&&this.filter.searchName!=''){
let chartListTmp = [];
let searchTitleStr = this.filter.searchName;
@@ -697,13 +547,11 @@ export default {
this.$nextTick(() => {
if (this.dataList.length > 0 ) {
this.dataList.forEach((item,index) => {
this.$refs['editChart'+item.id][0].showLoad(item);//设置该图表的高
this.setSize(item.span, index);//设置该图表宽度
this.setChartSize(item, index);//设置该图表
if(!item.isLoaded){
//获得当前显示在浏览器的图表,从后台获取数据
let chartBox = document.getElementById(item.title+'_'+item.id);//this.$refs['editChart'+item.id][0];
if( !item.isLoaded ){
this.handleElementInViewport(chartBox,0,item,index);
let chartBox = document.getElementById('chart-' + item.id);//this.$refs['editChart'+item.id][0];
this.handleElementInViewport(chartBox, 0, item, index);
}
});
}
@@ -715,10 +563,9 @@ export default {
if (this.dataList.length > 0 ) {
let chartListInViewport = [];
this.dataList.forEach((item,index) => {
//获得当前显示在浏览器的图表,从后台获取数据
let chartBox = document.getElementById(item.title+'_'+item.id);//this.$refs['editChart'+item.id][0];
//console.log("loadChartData___",item.title,item.isLoaded)
if(!item.isLoaded){
//获得当前显示在浏览器的图表,从后台获取数据
let chartBox = document.getElementById('chart-' + item.id);//this.$refs['editChart'+item.id][0];
this.handleElementInViewport(chartBox,scrollTop,item,index);
}
});
@@ -743,7 +590,7 @@ export default {
if (!isSearch && this.$refs['editChart'+item.id] && this.$refs['editChart'+item.id][0]) {
this.$refs['editChart'+item.id][0].showLoad(item);
}
this.setSize(item.span, realIndex); // 设置该图表宽度
this.setChartSize(item.span, realIndex); // 设置该图表宽度
}
});
}
@@ -751,7 +598,6 @@ export default {
getChartDataForSearch(chartItem,realIndex){
let chartData = this.chartDataCacheGroup.get(chartItem.id);
if(chartData){
this.setSize(chartItem.span, realIndex); // 设置该图表宽度
let filterType = chartData.filterType;
let errorMsg = chartData.errorMsg;
let tableData = chartData.tableData;
@@ -791,57 +637,11 @@ export default {
this.getChartData(chartItem, realIndex);
}
},
/*
getSingleStatRlt(statistics,result){
let dataArray = [];
if(result){
result.forEach((item)=>{
dataArray.push(item[1]);
})
}
let statisticsRlt = '';
if(dataArray.length>0){
if(statistics==='min'){//min最小值
statisticsRlt = dataArray.reduce(function(a , b){
return b < a ? b : a;
});
}else if(statistics==='max'){// max最大值
statisticsRlt = dataArray.reduce(function(a , b){
return b > a ? b : a;
});
}else if(statistics==='average'){// average平均值
let sum = 0;
dataArray.forEach((item)=>{
sum =Number(sum) + Number(item);
})
statisticsRlt = sum/dataArray.length;
}else if(statistics==='total'){//total总计
dataArray.forEach((item)=>{
statisticsRlt =Number(statisticsRlt) + Number(item);
})
}else if(statistics==='first'){//first第一个值
statisticsRlt = dataArray[0];
}else if(statistics==='last'){// last最后一个值
statisticsRlt = dataArray[dataArray.length-1];
}else if(statistics==='range'){//range : max - min
let min = dataArray.reduce(function(a , b){
return b < a ? b : a;
});
let max = dataArray.reduce(function(a , b){
return b > a ? b : a;
});
statisticsRlt = max-min;
}else if(statistics==='different'){//different : last - first
statisticsRlt = dataArray[dataArray.length-1]-dataArray[0];
}
}
return statisticsRlt;
},*/
// 获取一个图表具体数据,图表信息图表位置index
getChartData(chartInfo, pos, filterType) {
const chartItem = chartInfo;
const index = pos; // 指标
this.setSize(chartItem.span, index); // 设置该图表宽度
//this.setChartSize(chartItem.span, index); // 设置该图表宽度
if(chartItem.type === 'assetInfo'){
this.getAssetInfoChartData(chartItem);
return;
@@ -930,8 +730,6 @@ export default {
data: [],
type: chartInfo.type,
},
//visible: true,
//threshold: null,
metric_name: '',
};
@@ -1323,11 +1121,12 @@ export default {
getAlertListChartData:function(chartInfo,filterType){
this.$refs['editChart'+chartInfo.id][0].getAlertList(filterType);
},
// 设置图表的宽度
setSize(size, index) {
// 设置图表的尺寸
setChartSize(item, index) {
this.$nextTick(() => {
const chartBox = document.getElementsByClassName('chartBox');
chartBox[index].style.width = `${(size / 12) * 100}%`;
let chartBox = document.getElementById("chart-" + item.id);
chartBox.style.width = `${(item.span / 12) * 100}%`;
chartBox.style.height = `${item.height}px`;
});
},
getNewTime(time, num) {
@@ -1396,18 +1195,6 @@ export default {
console.log("__chartItem00__",JSON.stringify(chartData))
let duplicateChartData = JSON.parse(JSON.stringify(chartData));
/*
let chartData2 = {
chartItem:chartItem,
series:series,
singleStatRlt:singleStatRlt,
legend:legend,
tableData:tableData,
panelId:this.filter.panelId,
filter:this.filter,
filterType:filterType,
errorMsg:errorMsg,
}*/
duplicateChartData.chartItem = duplicateChart;
this.chartDataCacheGroup.set(duplicateChartId,duplicateChartData);
this.$nextTick(() => {
@@ -1419,7 +1206,7 @@ export default {
if(chartType!=='url'){
this.getChartDataForSearch(duplicateChart,chartNextIndex);
}else {
this.setSize(duplicateChart.span, chartNextIndex); // 设置该图表宽度
this.setChartSize(duplicateChart.span, chartNextIndex); // 设置该图表宽度
}
});
}
@@ -1512,6 +1299,6 @@ export default {
},
destroyed () {
},
};
};
</script>

View File

@@ -39,8 +39,7 @@
background: #FFF;
border: 1px solid #d8dce1;
padding: 0px 0px;
margin-bottom: 10px;
padding-bottom: 3px;
box-sizing: border-box;
.single-stat-container{
padding-left: 8px;
padding-right: 8px;

View File

@@ -9,14 +9,6 @@
<template>
<div class="chart-table" :id="'chartTableDiv'+chartIndex" v-show="divFirstShow" @mouseenter="caretShow=true" @mouseleave="caretShow=false">
<loading :ref="'localLoading'+chartIndex"></loading>
<!--
<div v-show="showLoading" class="el-loading-mask" style="background-color: rgba(0, 0, 0, 0);">
<div class="el-loading-spinner">
<img width="42px" height="42px" src="../../assets/img/loading.gif"/>
<p class="el-loading-text loading-font">loading</p>
</div>
</div>
-->
<div class="clearfix chartTitle" :class="{'dragTitle':dragTitleShow}" :id="'chartTitle'+chartIndex">
<el-popover
v-if="isError"
@@ -53,8 +45,6 @@
</div>
<div class="mt-10 table-container" v-cloak v-show="firstShow">
<el-table class="nz-table" :id="'tableContainer'+chartIndex" ref="tableContainer" :height="290" :data="seriesItem" border tooltip-effect="light" v-cloak v-scrollBar:el-table>
<!-- <el-table-column sortable :show-overflow-tooltip="true" prop="metric" :label="$t('dashboard.panel.chartTableColumn.metric')" ></el-table-column>-->
<!-- <el-table-column sortable :show-overflow-tooltip="true" prop="label" :label="$t('dashboard.panel.chartTableColumn.label')" ></el-table-column>-->
<el-table-column sortable prop="time" :label="$t('dashboard.panel.chartTableColumn.time')" min-width="100" ></el-table-column>
<el-table-column sortable prop="element" :show-overflow-tooltip="true" :label="$t('dashboard.panel.chartTableColumn.element')" min-width="260">
<template slot-scope="scope">

View File

@@ -40,8 +40,7 @@
background: #FFF;
border: 1px solid #d8dce1;
padding: 0px 0px;
margin-bottom: 10px;
padding-bottom: 3px;
box-sizing: border-box;
.url-container{
padding-left: 8px;
padding-right: 8px;

View File

@@ -34,7 +34,7 @@
bottom: 0px;
line-height: 18px;
position: absolute;
padding-bottom:5px;
padding-bottom:3px;
}
.legend-container-screen.legend-container {
max-height: 80px;
@@ -142,37 +142,31 @@
max-width:280px;
border: 1px solid #e02f44;
}
.nz-chart-resize {
height: 100%;
width: 100%;
position: relative;
}
.resize-box {
border: 1px solid #d8dce1;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.resize-shadow {
height: 100%;
width: 100%;
position: absolute;
}
.resize-shadow-active {
background-color: #888;
}
.line-chart-block {
height: 100%;
//min-height: 0px;
position: relative;
background: #FFF;
border: 1px solid #d8dce1;
padding: 0px 0px;
margin-bottom: 10px;
padding-bottom: 3px;
.vue-resizable-handle {
position: absolute;
width: 20px;
height: 20px;
bottom: 0;
right: 0;
cursor: se-resize;
box-sizing: border-box;
}
.vue-resizable-handle:after {
border-right: 2px solid #555;
border-bottom: 2px solid #555;
content: "";
position: absolute;
right: 3px;
bottom: 3px;
width: 5px;
height: 5px;
/*border-right: 2px solid rgba(0,0,0,.4);
border-bottom: 2px solid rgba(0,0,0,.4);*/
box-sizing: inherit;
}
background-color: white;
.chartTitle:hover {
background-color:#d8dce1;
}
@@ -180,7 +174,8 @@
text-align: center;
width: 100%;
line-height: 28px;
padding: 0 3px;
box-sizing: border-box;
.nz-chart-top{
width:100%;
}
@@ -195,7 +190,6 @@
font-size: 18px;
line-height: 26px;
color: #333;
margin: -3px 0 3px 3px;
display:flex;
justify-content:center;
align-items:center;

View File

@@ -2,27 +2,11 @@
@import './line-chart-block.scss';
</style>
<template>
<div class="nz-chart-resize">
<div class="resize-shadow" ref="resizeShadow"></div>
<div class="resize-box" ref="resizeBox">
<div class="line-chart-block" :id="'lineChartDiv'+chartIndex" v-show="divFirstShow" @mouseenter="mouseEnterChart" @mouseleave="mouseLeaveChart">
<loading :ref="'localLoading'+chartIndex"></loading>
<!--<div class="edit">
<div class="list-icon" v-if="firstShow">
<span @click="refreshChart" :title="$t('dashboard.refresh')" class="set-icon" v-if="showSetting">
<i class="el-icon-refresh-right"></i>
</span>
<span @click="editChart" :title="$t('dashboard.edit')" class="set-icon" v-if="showSetting">
<i class="el-icon-edit-outline"></i>
</span>
<span @click="removeChart" :title="$t('dashboard.delete')" class="set-icon" v-if="showSetting">
<i class="el-icon-delete"></i>
</span>
<span @click="showAllScreen" :title="$t('dashboard.screen')" class="set-icon">
<i class="el-icon-full-screen"></i>
</span>
</div>
</div>-->
<div class="clearfix chartTitle" :id="'chartTitle'+chartIndex" >
<el-popover
v-if="isError"
@@ -42,14 +26,6 @@
<span class="chart-title-text">{{data.title}}</span>
<span class="chart-title-icon"><i class="el-icon-caret-bottom el-icon--right" :class="{'visible':caretShow,'hidden':!caretShow}"></i></span>
</span>
<!--
<el-dropdown-menu slot="dropdown" class="nz-chart-dropdown" :popper-append-to-body="false">
<el-dropdown-item @click.native="refreshChart" ><i style="font-size: 16px;" class="global-active-color el-icon-refresh-right"></i>{{$t('dashboard.refresh')}}</el-dropdown-item>
<el-dropdown-item @click.native="editChart"><i style="font-size: 14px;margin-right: 11px;margin-left: 1px;" class="nz-icon nz-icon-edit"></i>{{$t('dashboard.edit')}}</el-dropdown-item>
<el-dropdown-item @click.native="removeChart" ><i style="font-size: 16px;" class="el-icon-delete"></i>{{$t('dashboard.delete')}}</el-dropdown-item>
<el-dropdown-item @click.native="showAllScreen" ><i style="font-size: 16px;" class="el-icon-full-screen"></i>{{$t('dashboard.screen')}}</el-dropdown-item>
</el-dropdown-menu>
-->
<ul slot="dropdown" v-show="dropdownMenuShow" :id="'dropdownUl'+chartIndex" :class="{'el-dropdown-menu nz-chart-dropdown':!isExplore,'el-dropdown-menu nz-chart-dropdown-one':isExplore}" style="position: absolute; top: 30px; left: calc(50% - 79px); transform-origin: center top; z-index: 1000;" >
<li v-show="!isExplore" @click="refreshChart" class="el-dropdown-menu__item">
<i class="global-active-color el-icon-refresh-right" style="font-size: 16px;"></i><span>{{$t('dashboard.refresh')}}</span></li>
@@ -63,19 +39,6 @@
<i class="el-icon-copy-document" style="font-size: 16px;"></i>{{$t('dashboard.duplicate')}}</li>
</ul>
</el-dropdown>
<!--
<div class="chart-title" v-show="firstShow">
{{data.title}}
</div>
<div class="nz-btn-group nz-btn-group-light edit button-panel-height" v-show="firstShow">
<button type="button" @click="refreshChart" style="padding: 6px 14px 5px 14px;" class="nz-btn nz-btn-size-large nz-btn-style-light" v-if="showSetting"><i style="font-size: 16px;" class="global-active-color el-icon-refresh-right"></i></button>
<button @click="editChart" type="button" class="nz-btn nz-btn-size-large nz-btn-style-light" v-if="showSetting"><i class="nz-icon nz-icon-edit"></i></button>
<button @click="removeChart" type="button" class="nz-btn nz-btn-size-large nz-btn-style-light" v-if="showSetting"><i class="el-icon-delete"></i></button>
<button
@click="showAllScreen" type="button" class="nz-btn nz-btn-size-large nz-btn-style-light"><i class="el-icon-full-screen"></i></button>
</div>
-->
</div>
<div class="line-area" ref="lineChartArea" :id="'lineChartArea'+chartIndex" v-show="firstShow" style="width:100%;"></div>
@@ -112,19 +75,6 @@
<div class="float-right panel-calendar dialog-tool">
<time-picker ref="calendarPanel" class="nz-dashboard-picker" style="margin-top: -12px;" @change="dateChange"></time-picker>
<!--
<el-date-picker ref="calendar" prefix-icon=" " size="mini" class="nz-dashboard-picker"
format="yyyy/MM/dd HH:mm"
@change="dateChange"
v-model="searchTime"
type="datetimerange"
:picker-options="pickerOptions"
:range-separator="$t('dashboard.panel.to')"
:start-placeholder="$t('dashboard.panel.startTime')"
:end-placeholder="$t('dashboard.panel.endTime')"
align="right">
</el-date-picker>-->
<!--<button @click="refreshChart" type="button" class="nz-btn nz-btn-size-normal nz-btn-style-light"><i style="font-size: 14px;" class="el-icon-refresh-right"></i></button>-->
</div>
</div>
<div class="line-area" ref="screenShowArea" id="screenShowArea" style="margin-top:0px;" @mouseenter="mouseEnterFullChart" @mouseleave="mouseLeaveFullChart"></div>
@@ -138,9 +88,9 @@
<loading :ref="'localLoadingScreen'+chartIndex"></loading>
</el-dialog>
<!--</Modal>-->
<!--style="touch-action: none;" -->
<span class="vue-resizable-handle" @mousedown="dragResize"></span>
</div>
<span class="vue-resizable-handle" @mousedown="startResize"></span>
</div>
</div>
</template>
<script>
@@ -151,7 +101,6 @@
import chartDataFormat from './chartDataFormat'
import {randomcolor} from '../common/js/radomcolor/randomcolor.js'
import timePicker from '../common/timePicker'
export default {
name: 'lineChartBlock',
components: {
@@ -159,9 +108,8 @@
'time-picker':timePicker
},
props: {
editChartId: {
type: String,
default: 'editChartId',
chartData: {
type: Object
},
// 看板id
panelId: {
@@ -180,7 +128,8 @@
isExplore:{
type:Boolean,
default:false,
}
},
stepHeight: {type: Number}
},
data() {
return {
@@ -232,24 +181,17 @@
searchTime:[new Date().setHours(new Date().getHours()-1),new Date()],
oldSearchTime:[],
minHeight:200,
chartSpaceHeight:5,//top-border: 1,bottom-border: 1,padding-bottome:3
chartSpaceHeight:2,//top-border: 1,bottom-border: 1,padding-bottome:3
titleHeight:28,
screenTitleHeight:58,
legendHeight:80,
screenTitleHeight:58
};
},
computed: {
/*
typeVisible() {
if (this.data.type === 'line' || this.data.type === 'bar' || this.data.type === 4) {
return true;
}
return false;
},
*/
},
watch: {},
methods: {
startResize(e) {
let vm = this;
this.$chartResizeTool.start(vm, this.chartData, e);
},
setDivFirstShow(showDiv){
this.divFirstShow = showDiv;
},
@@ -292,6 +234,10 @@
}
},
dragResize:function(e){
this.$refs.shadow.classList.add("resize-shadow-active");
var diffWidth = 20;//界面的宽度空白的地方的宽度
var chartBoxPadding = 20;
var targetDiv= document.getElementById('lineChartDiv'+this.chartIndex); //
@@ -438,14 +384,6 @@
}
},
clickLegend(legendName,index){
// if (this.echartStore) {
// this.echartStore.dispatchAction({
// type: 'legendToggleSelect',
// name: legendName
// });
// let isGreyTmp = this.isGrey[index];
// this.$set(this.isGrey, index, !isGreyTmp);
// }
//点击图表某一个legend图表只显示当前点击的曲线或柱状图其它隐藏再次点击已选中的legend ,显示全部
let curIsGrey=this.isGrey[index];
@@ -494,14 +432,6 @@
}
},
clickScreenLegend(legendName,index){
// if (this.echartModalStore) {
// this.echartModalStore.dispatchAction({
// type: 'legendToggleSelect',
// name: legendName
// });
// let isGreyTmp = this.isGreyScreen[index];
// this.$set(this.isGreyScreen, index, !isGreyTmp);
// }
//点击图表某一个legend图表只显示当前点击的曲线或柱状图其它隐藏再次点击已选中的legend ,显示全部
let curIsGrey=this.isGreyScreen[index];
if(this.echartModalStore){
@@ -715,11 +645,6 @@
//let str = `<div style='white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis;min-width:150px;max-width:600px;display:inline-block;line-height: 18px;font-size:12px;font-family: Roboto,Helvetica Neue,Arial,sans-serif;'>`;
let sum = 0;
params.forEach((item, i) => {
//alert('tooltip====='+JSON.stringify(item))
//let tip=legend.find((element)=>{
//alert('legend====='+JSON.stringify(element))
//return element.name == item.seriesName;
//});
let tip=legend[item.seriesIndex];
let color = self.bgColorList[item.seriesIndex];
if(i===0){
@@ -740,13 +665,6 @@
str += chartDataFormat.getUnit(chartInfo.unit?chartInfo.unit:2).compute(val,null,2);
str += `</div>`;
str += `</div>`;
/*str += `<div style='max-width:500px;display:inline-block;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis;line-height: 18px;font-size:12px;font-family: Roboto,Helvetica Neue,Arial,sans-serif;'>`;
str +=`<span style='display:inline-block;margin-right:5px;border-radius:10px;width:15px;height:5px;background-color: ${item.color};}'></span>${tip?(tip.alias?tip.alias:tip.name):item.seriesName}: `;
str +=`</div>`;*/
// str +=`<div style="display: inline-block;max-width: 10px; min-width: 5px;line-height: 18px;"></div>`;
/*str += `<div style='max-width:90px;min-width:20px;display:inline-block;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis;line-height: 18px;font-size:12px;font-family: Roboto,Helvetica Neue,Arial,sans-serif;'>`;
str +=chartDataFormat.getUnit(chartInfo.unit?chartInfo.unit:2).compute(val,null,2);
str +=`</div>`;*/
});
if(self.data.type==='stackArea' || self.isStackArea){
sum = parseFloat(Number(sum).toFixed(2));
@@ -762,7 +680,6 @@
str +=`</div>`;
return str;
// return `<div style='width:100%;display:block;word-break:break-all;word-wrap:break-word;white-space:normal'><span style='display:inline-block;margin-right:5px;border-radius:10px;width:15px;height:5px;background-color: ${params[0].color};}'></span> ${params[0].seriesName}:${params[0].data[1]}</div>`;
},
},
legend: {
@@ -773,7 +690,6 @@
itemHeight:5,
itemWidth:15,
formatter:function(name){
//console.log('==========='+name);
if(!name){
return '';
}
@@ -805,9 +721,6 @@
tooltip:{
show:true,
formatter:function(params){
//alert(params.length);
//alert(JSON.stringify(params));
return `<div style='width:100%;display:block;word-break:break-all;word-wrap:break-word;white-space:normal'> ${params.name}</div>`;
},
},
@@ -815,8 +728,6 @@
orient:'vertical',
x:'center',
y:'bottom',
//top:'5%',
//bottom:0
},
grid: {
top: 30,
@@ -825,26 +736,10 @@
containLabel: true,
bottom:8,//156
},
/*
dataZoom: [{
type: 'slider',
show:true,
xAxisIndex: [0],
start: 0,
end: 100,
height:25,
bottom:10,//96
left:40,
right:48,
}
],*/
xAxis: {
type: 'time',
// boundaryGap: false,//line-false; bar-true;
//data: ['20190101', '20190102', '周三', '周四', '周五', '周六', '周日']
axisLabel: {
interval: '0',
//showMinLabel:false,
showMaxLabel:false,
rotate: 0,
formatter: function (value) {
@@ -1118,24 +1013,6 @@
var charNum = `${(chartWidth-100)/(txtWidth/str.length)}`;
return str.slice(0,charNum)+'...';
}
/*
if(txtWidth < (chartWidth-30)){
return str;
}else {
var charNum = `${(chartWidth-200)/(txtWidth/str.length)}`;//一行的字符数
charNum = parseInt(charNum);
if(str.length>charNum){
let num = `${str.length/charNum}`;
num = parseInt(num)+1;
for(let i=0;i<num;i++){
rlt += str.substring(charNum*i,charNum*(i+1))+'\n';
}
}else {
return str;
}
}
*/
//return rlt;
},
setColor(colorNum){
this.bgColorList = [];
@@ -1167,13 +1044,8 @@
this.legend = legend;
//设置高度 chart-table
this.$nextTick(() => {
const chartBox = document.getElementById('lineChartDiv'+this.chartIndex);
let height = Math.round(chartItem.height/10)*10;//图表高度四舍五入
if(height<this.minHeight){
height = this.minHeight;
}
chartBox.style.height = `${height-this.chartSpaceHeight}px`;
let chartBox = document.getElementById('lineChartDiv'+this.chartIndex);
chartBox.style.height = `${this.$chartResizeTool.calculateHeight(chartItem.height)}px`;
});
this.$refs['localLoading'+this.chartIndex].startLoading();
this.divFirstShow = true;
@@ -1468,11 +1340,6 @@
}
}
});
/*
if (series.length && this.data.type === 4) {
series.push(sumData);
}
*/
this.setColor(legend.length);
this.initChart(this.data, series, this.$refs.screenShowArea, 'screen',legend);
}
@@ -1497,20 +1364,11 @@
height = this.minHeight;
}
chartBox.style.height = `${height-this.chartSpaceHeight}px`;
//const tableBox = document.getElementById('tableContainer');
// const chartBox = document.getElementById('lineChartDiv'+this.chartIndex);
//tableBox.style.height = `${height-75}px`;
});
this.clearData();
this.firstShow = false;
this.$refs['localLoading'+this.chartIndex].startLoading();
this.divFirstShow = true;
/*
if (this.echartStore) {
this.echartStore.showLoading();
}
*/
},
dealLegendAlias:function(legend,expression){
if(/\{\{.+\}\}/.test(expression)){
@@ -1538,15 +1396,6 @@
const mbNum = kbNum / 1000;
if (mbNum > 1000) {
const gbNum = mbNum / 1000;
/*
if (gbNum > 1000) {
const tbNum = gbNum / 1000;
if (tbNum > 1000) {
const pbNum = tbNum / 1000;
return `${pbNum.toFixed(2)}PB`;
}
return `${tbNum.toFixed(2)}TB`;
}*/
return `${gbNum.toFixed(2)}B`;
}
return `${mbNum.toFixed(2)}M`;
@@ -1559,14 +1408,6 @@
},
mounted() {
this.firstLoad = false;
/*
let Myecharts2 = echarts.init(document.getElementById('lineChartArea'));
console.log(Myecharts2);
setTimeout(function () {
Myecharts2.resize()
}, 500)
*/
},
beforeDestroy() {
this.clearChart();

View File

@@ -19,7 +19,7 @@ import plTable from 'pl-table'
import 'pl-table/themes/index.css'
import {post, get, put, del} from './http.js'
import {toTop, clickoutside, scrollBar, bottomBoxWindow,stringTimeParseToUnix,unixTimeParseToString} from './tools.js'
import {toTop, clickoutside, scrollBar, bottomBoxWindow, stringTimeParseToUnix, unixTimeParseToString, chartResizeTool} from './tools.js'
import Pagination from "./components/common/pagination"; //引入全局分页组件
@@ -81,6 +81,7 @@ Vue.prototype.$toTop = toTop; //toTop置顶按钮方法
Vue.prototype.$bottomBoxWindow = bottomBoxWindow; //底部上滑框控制
Vue.prototype.$stringTimeParseToUnix = stringTimeParseToUnix;
Vue.prototype.$unixTimeParseToString = unixTimeParseToString;
Vue.prototype.$chartResizeTool = chartResizeTool;
Vue.prototype.$tableHeight = { //列表页表格的高度
normal: 'calc(100% - 100px)', //常规高度,特例在下方定义
openSubList: { //打开二级列表后的高度

View File

@@ -358,3 +358,80 @@ export function unixTimeParseToString(unixTime,fmt='yyyy-MM-dd hh:mm:ss'){
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
return fmt;
}
//chart-resize工具
export const chartResizeTool = {
minHeight: 200, //图表最小高度
chartBlankHeight: 2, //图表空白占位高度
chartBlankWidth: 20, //图表空白占位宽度
containerBlankWidth: 25, //容器空白占位宽度(#listContainer的padding
titleHeight: 28, //标题dom高度
stepHeight: 50, //单元高度
stepWidth(containerWidth) { //单元宽度,参数为容器总宽度
return (containerWidth-this.containerBlankWidth)/12;
},
calculateHeight(original) {
let height = Math.round(original/this.stepHeight)*this.stepHeight;
if (height < this.minHeight) {
height = this.minHeight;
}
return height-this.chartSpaceHeight;
},
start(vm, data, event) {
let shadow; //缩放时底部阴影dom
let box; //图表内容dom
try {
shadow = vm.$refs.resizeShadow;
} catch (e) {
shadow = vm.$refs[0].resizeShadow;
}
try {
box = vm.$refs.resizeBox;
} catch (e) {
box = vm.$refs[0].resizeBox;
}
let chartBlankWidth = this.chartBlankWidth;
let chartBlankHeight = this.chartBlankHeight;
let stepWidth = this.stepWidth(document.getElementById('listContainer').offsetWidth);
let stepHeight = this.stepHeight;
let containerAvailableWidth = document.getElementById('listContainer').offsetWidth-this.containerBlankWidth;
let mouseOriginalX = event.clientX; //鼠标初始坐标
let mouseOriginalY = event.clientY;
let originalHeight = data.height; //图表初始宽高
let originalWidth = stepWidth*data.span;
//console.info("mouseOrigX %s, mouseOrigY %s, chartOrigX %s, chartOrigY %s", mouseOriginalX, mouseOriginalY, originalHeight, originalWidth)
//1.激活背景阴影
shadow.classList.add("resize-shadow-active");
//2.鼠标移动时调整resize-box的宽高同时监听宽高的变化变化量每达到step的50%时改变resize-shadow的尺寸并重绘resize-box内容
document.addEventListener("mousemove", moveListener);
//3.鼠标松开将resize-box宽高改为resize-shadow宽高结束
document.addEventListener("mouseup", mouseupListener);
function moveListener(e) {
let mouseX = e.clientX;
let mouseY = e.clientY;
//调整resize-box的宽高
box.style.height = `${originalHeight+(mouseY-mouseOriginalY)-chartBlankHeight}px`;
box.style.width = `${originalWidth+(mouseX-mouseOriginalX)-chartBlankWidth}px`;
//监听宽高的变化变化量每达到step的50%时改变resize-shadow的尺寸并重绘resize-box内容
let remainderWidth = (box.offsetWidth+chartBlankWidth)%stepWidth; //宽的余数
let remainderHeight = (box.offsetHeight+chartBlankHeight)%stepHeight; //高的余数
}
function mouseupListener(e) {
let remainderWidth = (box.offsetHeight+chartBlankHeight)%stepHeight; //高的余数
let remainderHeight = (box.offsetHeight+chartBlankHeight)%stepHeight; //高的余数
data.height = box.offsetHeight+chartBlankHeight;
data.span = (box.offsetWidth+chartBlankWidth)/(containerAvailableWidth/12);
//关闭背景阴影
shadow.classList.remove("resize-shadow-active");
document.removeEventListener("mousemove", moveListener);
document.removeEventListener("mouseup", mouseupListener);
}
function boxStepHandler(type, op) {
}
}
}