Merge branch 'codeCheck' of https://git.mesalab.cn/nezha/nezha-fronted into codeCheck

This commit is contained in:
zhangyu
2020-09-22 09:41:39 +08:00
14 changed files with 460 additions and 150 deletions

View File

@@ -561,7 +561,6 @@ li{
align-items : center; align-items : center;
position: relative; position: relative;
flex-direction: row-reverse; flex-direction: row-reverse;
z-index: 2;
} }
.top-tools>div { .top-tools>div {
margin-top: 2px; margin-top: 2px;

View File

@@ -35,6 +35,15 @@
position: absolute; position: absolute;
padding-bottom:3px; padding-bottom:3px;
} }
.legend-container .option-th{
color:#33a2e5;
}
.legend-container .option-th:hover{
cursor:pointer;
}
.legend-option-cell{
white-space: nowrap;padding: 0px 5px 0px 5px;
}
.nz-icon-warning{ .nz-icon-warning{
color: #e6a23c; color: #e6a23c;
} }

View File

@@ -431,7 +431,7 @@ let unitOptions=[
{ {
value:4, value:4,
compute:percent02, compute:percent02,
label:'percent(0.0-0.1)' label:'percent(0.0-1.0)'
}, },
{ {
value:5, value:5,

View File

@@ -79,12 +79,41 @@
<div id="chartEchartPreview" @mouseenter="mouseEnterFullChart" @mouseleave="mouseLeaveFullChart"> <div id="chartEchartPreview" @mouseenter="mouseEnterFullChart" @mouseleave="mouseLeaveFullChart">
<div class="line-area" ref="screenShowArea" id="screenShowArea" style="margin-top:0px;"></div> <div class="line-area" ref="screenShowArea" id="screenShowArea" style="margin-top:0px;"></div>
<div class="chart-no-data" v-show="noData">No Data</div> <div class="chart-no-data" v-show="noData">No Data</div>
<div class="legend-container legend-container-screen" id="screenLegendArea" ref="screenLegendArea" v-show="showLegend" v-scrollBar:legend>
<div v-for="(item, index) in screenLegendList" :title="item.alias?item.alias:item.name" @click="clickScreenLegend(item.name,index)" class="legend-item" :class="{'ft-gr':isGreyScreen[index]}" :key="'legend_' + item.name+'_'+index"> <template v-if="!hasLegendOptions">
<span class="legend-shape" :style="{background:(isGreyScreen[index]?'#D3D3D3':bgColorList[index])}"></span>{{item.alias?item.alias:item.name}} <div class="legend-container legend-container-screen" ref="screenLegendArea" @mouseenter="mouseEnterFullChart" @mouseleave="mouseLeaveFullChart" v-show="showLegend" v-scrollBar:legend>
<br/> <div v-for="(item, index) in screenLegendList" :title="item.alias?item.alias:item.name" @click="clickScreenLegend(item.name,index)" class="legend-item" :class="{'ft-gr':isGreyScreen[index]}" :key="'legend_' + item.name+'_'+index">
<span class="legend-shape" :style="{background:(isGreyScreen[index]?'#D3D3D3':item.color)}"></span>{{item.alias?item.alias:item.name}}
<br/><!--bgColorList[index]-->
</div>
</div> </div>
</div> </template>
<template v-else>
<div class="legend-container legend-container-screen" ref="screenLegendArea" @mouseenter="mouseEnterFullChart" @mouseleave="mouseLeaveFullChart" v-show="showLegend" v-scrollBar:legend>
<table style="width: 100%">
<th style="width: 100%"></th>
<template v-for="legendOption in screenLegendOptions">
<th v-if="legendOption.value == 'on'" class="option-th legend-option-cell" >
<span @click="legendValueSort(legendOption,screenLegendList,screenLegendOptions)">{{legendOption.option}}</span>
<span ><i style="font-size: 12px !important;" :class="{'nz-icon nz-icon-arrow-down':legendOption.sort =='asc','nz-icon nz-icon-arrow-up':legendOption.sort=='desc'}" ></i></span>
</th>
</template>
<tbody>
<tr v-for="(item, index) in screenLegendList" :key="'legend_' + item.name+'_'+index">
<td>
<div :title="item.alias?item.alias:item.name" @click="clickScreenLegend(item.name,index)" class="legend-item" :class="{'ft-gr':isGreyScreen[index]}" >
<span class="legend-shape" :style="{background:(isGreyScreen[index]?'#D3D3D3':item.color)}"></span>{{item.alias?item.alias:item.name}}
</div>
</td>
<template v-for="legendOption in screenLegendOptions">
<td v-if="legendOption.value == 'on'" class="legend-option-cell">{{formatLegendData(item[legendOption.option])}}</td>
</template>
</tr>
</tbody>
</table>
</div>
</template>
</div> </div>
</template> </template>
@@ -212,6 +241,8 @@
titleHeight:58, titleHeight:58,
legendHeight:80, legendHeight:80,
pageHeight:40, pageHeight:40,
hasLegendOptions:false,
screenLegendOptions:[],
}; };
}, },
computed: { computed: {
@@ -266,7 +297,6 @@
chartDiv.style.height = `${height-this.chartSpaceHeight-this.titleHeight-15}px`; chartDiv.style.height = `${height-this.chartSpaceHeight-this.titleHeight-15}px`;
} }
}); });
this.setSize(chartInfo.span); // 设置该图表宽度
this.screenModal = true; this.screenModal = true;
@@ -321,15 +351,6 @@
this.setLoadFrame(); this.setLoadFrame();
} }
}, },
// 设置图表的宽度
setSize(size) {
this.$nextTick(() => {
const listContainer = document.getElementById('listContainer');
//chartBox.style.width = `${(size / 12) * 100}%`;
let containerWidth= listContainer.clientWidth;
this.dailogWidth = `${containerWidth*(size / 12)}px`;
});
},
getAlertListChartData:function(chartInfo,filterType){ getAlertListChartData:function(chartInfo,filterType){
this.$refs.alertListChart.getAlertList(filterType,true,this.chart); this.$refs.alertListChart.getAlertList(filterType,true,this.chart);
this.$refs.loadingPreview.endLoading(); this.$refs.loadingPreview.endLoading();
@@ -524,7 +545,19 @@
}else if(chartItem.type ==='singleStat'){ }else if(chartItem.type ==='singleStat'){
if(Number(singleStatRlt)){ if(Number(singleStatRlt)){
let singleStatTmp =parseFloat(Number(singleStatRlt).toFixed(2)); let singleStatTmp =parseFloat(Number(singleStatRlt).toFixed(2));
this.serieSingleStat = chartDataFormat.getUnit(chartItem.unit?chartItem.unit:2).compute(singleStatTmp,null,2); if(chartItem.param.valueMapping && chartItem.param.valueMapping.type){
let type=chartItem.param.valueMapping.type;
let mappings=chartItem.param.valueMapping.mapping?chartItem.param.valueMapping.mapping:[];
let mapping;
if(type == 'value'){
mapping=mappings.find(item=>{return item.value == singleStatTmp})
}else{
mapping=mappings.find(item=>{return item.from <= singleStatTmp&& item.to >= singleStatTmp});
}
this.serieSingleStat = mapping?mapping.text:chartDataFormat.getUnit(chartItem.unit?chartItem.unit:2).compute(singleStatTmp,null,2);
}else{
this.serieSingleStat = chartDataFormat.getUnit(chartItem.unit?chartItem.unit:2).compute(singleStatTmp,null,2);
}
}else { }else {
this.serieSingleStat =singleStatRlt; this.serieSingleStat =singleStatRlt;
} }
@@ -773,78 +806,15 @@
}, },
}, },
legend: { legend: {
type:'scroll',
height:80,
show:false, show:false,
icon:"roundRect",
itemHeight:5,
itemWidth:15,
formatter:function(name){
//console.log('==========='+name);
if(!name){
return '';
}
//计算宽度
var span = document.createElement("span");
var result = {};
result.width = span.offsetWidth;
result.height = span.offsetHeight;
span.style.visibility = "hidden";
span.style.fontSize = 14;
span.style.fontFamily = "Arial";
span.style.display = "inline-block";
document.body.appendChild(span);
if(typeof span.textContent != "undefined"){
span.textContent = name;
}else{
span.innerText = name;
}
var txtWidth = parseFloat(window.getComputedStyle(span).width) - result.width;
document.body.removeChild(span);
if(txtWidth < chartWidth){
return name;
}else {
var charNum = `${(chartWidth-100)/(txtWidth/name.length)}`;
return name.slice(0,charNum)+'...';
}
},
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>`;
},
},
data: legend,
orient:'vertical',
x:'center',
y:'bottom',
//top:'5%',
//bottom:0
}, },
grid: { grid: {
top: 30, top: 30,
left: 0, left: 0,
right: 30, right: 30,
containLabel: true, containLabel: true,
bottom:8,//156 bottom: 8,//156
},/* },
dataZoom: [{
type: 'slider',
show:true,
xAxisIndex: [0],
start: 0,
end: 100,
height:25,
bottom:10,//96
left:40,
right:48,
}
],*/
xAxis: { xAxis: {
type: 'time', type: 'time',
// boundaryGap: false,//line-false; bar-true; // boundaryGap: false,//line-false; bar-true;
@@ -929,12 +899,16 @@
let _legend = { let _legend = {
name:item.name, name:item.name,
alias:item.alias, alias:item.alias,
color:item.color,
showText:this.formatLegend(chartWidth,item.alias?item.alias:item.name) showText:this.formatLegend(chartWidth,item.alias?item.alias:item.name)
}; };
this.screenLegendList.push(_legend); this.screenLegendList.push(_legend);
this.isGreyScreen.push(false); this.isGreyScreen.push(false);
}); });
} }
if(this.hasLegendOptions){
this.computeLegendData(this.screenLegendList,dataArg,'screen');
}
this.$nextTick(() => { this.$nextTick(() => {
let divHeight = this.$refs.screenLegendArea.offsetHeight; let divHeight = this.$refs.screenLegendArea.offsetHeight;
this.echartModalStore.resize({height:(chartInfo.height-this.chartSpaceHeight-divHeight-this.titleHeight)}); this.echartModalStore.resize({height:(chartInfo.height-this.chartSpaceHeight-divHeight-this.titleHeight)});
@@ -1031,11 +1005,16 @@
// 设置数据 // 设置数据
setData(chartItem, seriesItem,legend) { setData(chartItem, seriesItem,legend) {
this.setColor(legend.length); this.setColor(legend.length);
legend.forEach((t,i)=>{t.color = this.bgColorList[i]})
this.legend = legend; this.legend = legend;
//this.data = chartItem; //this.data = chartItem;
//this.seriesItem = seriesItem; //this.seriesItem = seriesItem;
this.seriesItemScreen = seriesItem; this.seriesItemScreen = seriesItem;
this.hasLegendOptions=this.findLegendOptions()
if(this.hasLegendOptions){
let sortedOptionKeys=['min','max','avg','last','total']
this.screenLegendOptions=sortedOptionKeys.map(item=>{ return {option:item,sort:'',value:chartItem.param.legendValue[item]}})
}
this.initChart(chartItem, seriesItem, this.$refs.screenShowArea,legend); this.initChart(chartItem, seriesItem, this.$refs.screenShowArea,legend);
}, },
// 设置数据 // 设置数据
@@ -1264,6 +1243,125 @@
this.screenModal = false; this.screenModal = false;
this.clearChart(); this.clearChart();
}, },
findLegendOptions:function(){
if((!this.chart.param.legendValue) || Object.keys(this.chart.param.legendValue)<1) return false;
let legendOptions= this.chart.param.legendValue;
let onVal=Object.keys(legendOptions).find(item=>{return legendOptions[item] == 'on'});
return onVal;
},
computeLegendData:function(legend,dataArr){
let options=this.screenLegendOptions;
let keys=options.filter(item=>{return item.value == 'on'}).map(item=>{return item.option});
let $self=this;
keys.forEach(item=>{
switch (item) {
case 'min':
$self.legendMinValue(legend,dataArr);
break;
case 'max':
$self.legendMaxValue(legend,dataArr);
break;
case 'avg':
$self.legendAvgValue(legend,dataArr);
break;
case 'last':
$self.legendLastValue(legend,dataArr);
break;
case 'total':
$self.legendTotalValue(legend,dataArr);
break;
}
})
},
legendMinValue:function(legend,dataArr){
return new Promise(resolve => {
legend.forEach(item=>{
let data=dataArr.find(t=>t.name == item.name)
if(data&&data.data){
let copy=JSON.parse(JSON.stringify(data.data));
let min =copy.sort((x,y)=>{return parseFloat(x[1]) - parseFloat(y[1])})[0][1]
item['min']=parseFloat(min)
}
})
resolve();
})
},
legendMaxValue:function(legend,dataArr){
return new Promise(resolve => {
legend.forEach(item=>{
let data=dataArr.find(t=>t.name == item.name)
if(data&&data.data){
let copy=JSON.parse(JSON.stringify(data.data));
let max =copy.sort((x,y)=>{return parseFloat(y[1]) - parseFloat(x[1])})[0][1]
item['max']=parseFloat(max)
}
})
resolve();
})
},
legendAvgValue:function(legend,dataArr){
return new Promise(resolve => {
legend.forEach(item=>{
let data=dataArr.find(t=>t.name == item.name)
if(data&&data.data){
let copy=JSON.parse(JSON.stringify(data.data));
copy = copy.map(t=>parseFloat(t[1]))
let sum = eval(copy.join('+'));
let avg = sum / copy.length;
item['avg'] = avg;
}
})
resolve();
})
},
legendLastValue:function(legend,dataArr){
return new Promise(resolve => {
legend.forEach(item=>{
let data=dataArr.find(t=>t.name == item.name)
if(data&&data.data){
let copy=JSON.parse(JSON.stringify(data.data));
let last =copy.sort((x,y)=>{return parseFloat(y[0]) - parseFloat(x[0])})[0][1]
item['last']=parseFloat(last)
}
})
resolve();
})
},
legendTotalValue:function(legend,dataArr){
return new Promise(resolve => {
legend.forEach(item=>{
let data=dataArr.find(t=>t.name == item.name)
if(data&&data.data){
let copy=JSON.parse(JSON.stringify(data.data));
copy = copy.map(t=>parseFloat(t[1]))
let sum = eval(copy.join('+'));
item['total'] = sum;
}
})
resolve();
})
},
formatLegendData:function(data){
return chartDataFormat.getUnit(this.chart.unit).compute(data,null,2)
},
legendValueSort:function(option,legend,options){
options.forEach(item=>{
if(item.option != option.option){
item.sort='';
}
})
if(!option.sort || option.sort == 'asc'){
legend.sort((x,y)=>x[option.option] - y[option.option])
option.sort = 'desc'
}else{
legend.sort((x,y)=>y[option.option] - x[option.option])
option.sort = 'asc'
}
}
}, },
mounted() { mounted() {

View File

@@ -57,11 +57,38 @@
<!--<div v-if="seriesItem.length!==seriesItemArr.length" class="more"><i class="el-icon-warning"></i> {{$t('dashboard.panel.moreFirstTitle')}} {{seriesLength}}{{$t('dashboard.panel.moreSecondTitle')}}<span @click="loadMore" class="moreClick">{{$t('dashboard.panel.moreThirdTitle')}}{{seriesItem.length}}</span></div>--> <!--<div v-if="seriesItem.length!==seriesItemArr.length" class="more"><i class="el-icon-warning"></i> {{$t('dashboard.panel.moreFirstTitle')}} {{seriesLength}}{{$t('dashboard.panel.moreSecondTitle')}}<span @click="loadMore" class="moreClick">{{$t('dashboard.panel.moreThirdTitle')}}{{seriesItem.length}}</span></div>-->
<div class="line-area" ref="lineChartArea" :id="'lineChartArea'+chartIndex" v-show="firstShow" style="width:100%;"></div> <div class="line-area" ref="lineChartArea" :id="'lineChartArea'+chartIndex" v-show="firstShow" style="width:100%;"></div>
<div class="chart-no-data" v-show="noData">No Data</div> <div class="chart-no-data" v-show="noData">No Data</div>
<div class='legend-container' id="legendArea" ref="legendArea" v-show="firstShow" v-scrollBar:legend> <template v-if="!hasLegendOptions">
<div v-for="(item, index) in legendListMore" :title="item.alias?item.alias:item.name" @click="clickLegend(item.name,index)" class="legend-item" :class="{'ft-gr':isGrey[index]}" :key="'legend_' + item.name+'_'+index"> <div class='legend-container' ref="legendArea" v-show="firstShow" v-scrollBar:legend>
<span class="legend-shape" :style="{background:(isGrey[index]?'#D3D3D3':bgColorList[index])}"></span>{{item.alias?item.alias:item.name}} <div v-for="(item, index) in legendListMore" :title="item.alias?item.alias:item.name" @click="clickLegend(item.name,index)" class="legend-item" :class="{'ft-gr':isGrey[index]}" :key="'legend_' + item.name+'_'+index">
<span class="legend-shape" :style="{background:(isGrey[index]?'#D3D3D3':item.color)}"></span>{{item.alias?item.alias:item.name}}
</div>
</div> </div>
</div> </template>
<template v-else>
<div class='legend-container' ref="legendArea" v-show="firstShow" v-scrollBar:legend>
<table style="width: 100%">
<th style="width: 100%"></th>
<template v-for="legendOption in legendOptions">
<th v-if="legendOption.value == 'on'" class="option-th legend-option-cell" >
<span @click="legendValueSort(legendOption,legendListMore,legendOptions)">{{legendOption.option}}</span>
<span ><i style="font-size: 12px !important;" :class="{'nz-icon nz-icon-arrow-down':legendOption.sort =='asc','nz-icon nz-icon-arrow-up':legendOption.sort=='desc'}" ></i></span>
</th>
</template>
<tbody>
<tr v-for="(item, index) in legendListMore" :key="'legend_' + item.name+'_'+index">
<td>
<div :title="item.alias?item.alias:item.name" @click="clickLegend(item.name,index)" class="legend-item" :class="{'ft-gr':isGrey[index]}" >
<span class="legend-shape" :style="{background:(isGrey[index]?'#D3D3D3':item.color)}"></span>{{item.alias?item.alias:item.name}}
</div>
</td>
<template v-for="legendOption in legendOptions">
<td v-if="legendOption.value == 'on'" class="legend-option-cell">{{formatLegendData(item[legendOption.option])}}</td>
</template>
</tr>
</tbody>
</table>
</div>
</template>
<!-- <!--
<Modal title="查看" v-model="screenModal" width="96%" class="line-chart-block-modal">--> <Modal title="查看" v-model="screenModal" width="96%" class="line-chart-block-modal">-->
<el-dialog class="line-chart-block-modal nz-dialog" <el-dialog class="line-chart-block-modal nz-dialog"
@@ -107,12 +134,39 @@
</div> </div>
<div class="line-area" ref="screenShowArea" id="screenShowArea" style="margin-top:0px;" @mouseenter="mouseEnterFullChart" @mouseleave="mouseLeaveFullChart"></div> <div class="line-area" ref="screenShowArea" id="screenShowArea" style="margin-top:0px;" @mouseenter="mouseEnterFullChart" @mouseleave="mouseLeaveFullChart"></div>
<div class="chart-no-data" v-show="noData">No Data</div> <div class="chart-no-data" v-show="noData">No Data</div>
<div class="legend-container legend-container-screen" :id="'screenLegendArea'+chartIndex" @mouseenter="mouseEnterFullChart" @mouseleave="mouseLeaveFullChart" v-show="showLegend" v-scrollBar:legend> <template v-if="!hasLegendOptions">
<div v-for="(item, index) in screenLegendListMore" :title="item.alias?item.alias:item.name" @click="clickScreenLegend(item.name,index)" class="legend-item" :class="{'ft-gr':isGreyScreen[index]}" :key="'legend_' + item.name+'_'+index"> <div class="legend-container legend-container-screen" :id="'screenLegendArea'+chartIndex" @mouseenter="mouseEnterFullChart" @mouseleave="mouseLeaveFullChart" v-show="showLegend" v-scrollBar:legend>
<span class="legend-shape" :style="{background:(isGreyScreen[index]?'#D3D3D3':bgColorList[index])}"></span>{{item.alias?item.alias:item.name}} <div v-for="(item, index) in screenLegendListMore" :title="item.alias?item.alias:item.name" @click="clickScreenLegend(item.name,index)" class="legend-item" :class="{'ft-gr':isGreyScreen[index]}" :key="'legend_' + item.name+'_'+index">
<br/><!--bgColorList[index]--> <span class="legend-shape" :style="{background:(isGreyScreen[index]?'#D3D3D3':item.color)}"></span>{{item.alias?item.alias:item.name}}
<br/><!--bgColorList[index]-->
</div>
</div> </div>
</div> </template>
<template v-else>
<div class="legend-container legend-container-screen" :id="'screenLegendArea'+chartIndex" @mouseenter="mouseEnterFullChart" @mouseleave="mouseLeaveFullChart" v-show="showLegend" v-scrollBar:legend>
<table style="width: 100%">
<th style="width: 100%"></th>
<template v-for="legendOption in screenLegendOptions">
<th v-if="legendOption.value == 'on'" class="option-th legend-option-cell" >
<span @click="legendValueSort(legendOption,screenLegendListMore,screenLegendOptions)">{{legendOption.option}}</span>
<span ><i style="font-size: 12px !important;" :class="{'nz-icon nz-icon-arrow-down':legendOption.sort =='asc','nz-icon nz-icon-arrow-up':legendOption.sort=='desc'}" ></i></span>
</th>
</template>
<tbody>
<tr v-for="(item, index) in screenLegendListMore" :key="'legend_' + item.name+'_'+index">
<td>
<div :title="item.alias?item.alias:item.name" @click="clickScreenLegend(item.name,index)" class="legend-item" :class="{'ft-gr':isGreyScreen[index]}" >
<span class="legend-shape" :style="{background:(isGreyScreen[index]?'#D3D3D3':item.color)}"></span>{{item.alias?item.alias:item.name}}
</div>
</td>
<template v-for="legendOption in screenLegendOptions">
<td v-if="legendOption.value == 'on'" class="legend-option-cell">{{formatLegendData(item[legendOption.option])}}</td>
</template>
</tr>
</tbody>
</table>
</div>
</template>
<loading :ref="'localLoadingScreen'+chartIndex"></loading> <loading :ref="'localLoadingScreen'+chartIndex"></loading>
</el-dialog> </el-dialog>
@@ -217,7 +271,10 @@
showLegend:true, showLegend:true,
searchTime:[new Date().setHours(new Date().getHours()-1),new Date()], searchTime:[new Date().setHours(new Date().getHours()-1),new Date()],
oldSearchTime:[], oldSearchTime:[],
screenTitleHeight:58 screenTitleHeight:58,
hasLegendOptions:false,
legendOptions:[],
screenLegendOptions:[],
}; };
}, },
watch: {}, watch: {},
@@ -268,10 +325,11 @@
} }
}, },
clickLegend(legendName,index){ clickLegend(legendName,index){
console.log('cur index',index,legendName)
//点击图表某一个legend图表只显示当前点击的曲线或柱状图其它隐藏再次点击已选中的legend ,显示全部 //点击图表某一个legend图表只显示当前点击的曲线或柱状图其它隐藏再次点击已选中的legend ,显示全部
let curIsGrey=this.isGrey[index]; let curIsGrey=this.isGrey[index];
if(this.echartStore){ if(this.echartStore){
this.legendList.forEach((item,i)=>{ this.legendListMore.forEach((item,i)=>{
let isGrey = this.isGrey[i]; let isGrey = this.isGrey[i];
if(index != i){ if(index != i){
if(!curIsGrey && !isGrey){ if(!curIsGrey && !isGrey){
@@ -318,7 +376,7 @@
//点击图表某一个legend图表只显示当前点击的曲线或柱状图其它隐藏再次点击已选中的legend ,显示全部 //点击图表某一个legend图表只显示当前点击的曲线或柱状图其它隐藏再次点击已选中的legend ,显示全部
let curIsGrey=this.isGreyScreen[index]; let curIsGrey=this.isGreyScreen[index];
if(this.echartModalStore){ if(this.echartModalStore){
this.screenLegendList.forEach((item,i)=>{ this.screenLegendListMore.forEach((item,i)=>{
let isGrey = this.isGreyScreen[i]; let isGrey = this.isGreyScreen[i];
if(index != i){ if(index != i){
if(!curIsGrey && !isGrey){ if(!curIsGrey && !isGrey){
@@ -404,6 +462,7 @@
if ( chartInfo.type === 4) {//line,bar if ( chartInfo.type === 4) {//line,bar
this.chartType = 'line'; this.chartType = 'line';
} }
console.log('chartData',chartInfo,legend,dataArg)
let minTime = null; let minTime = null;
let maxTime = null; let maxTime = null;
if(dataArg.length>0 && dataArg[0].data if(dataArg.length>0 && dataArg[0].data
@@ -620,51 +679,7 @@
}, },
}, },
legend: { legend: {
type:'scroll',
height:80,
show:false, show:false,
icon:"roundRect",
itemHeight:5,
itemWidth:15,
formatter:function(name){
if(!name){
return '';
}
//计算宽度
var span = document.createElement("span");
var result = {};
result.width = span.offsetWidth;
result.height = span.offsetHeight;
span.style.visibility = "hidden";
span.style.fontSize = 14;
span.style.fontFamily = "Arial";
span.style.display = "inline-block";
document.body.appendChild(span);
if(typeof span.textContent != "undefined"){
span.textContent = name;
}else{
span.innerText = name;
}
var txtWidth = parseFloat(window.getComputedStyle(span).width) - result.width;
document.body.removeChild(span);
if(txtWidth < chartWidth){
return name;
}else {
var charNum = `${(chartWidth-100)/(txtWidth/name.length)}`;
return name.slice(0,charNum)+'...';
}
},
tooltip:{
show:true,
formatter:function(params){
return `<div style='width:100%;display:block;word-break:break-all;word-wrap:break-word;white-space:normal'> ${params.name}</div>`;
},
},
data: legend,
orient:'vertical',
x:'center',
y:'bottom',
}, },
grid: { grid: {
top: 30, top: 30,
@@ -773,6 +788,7 @@
const legend = { const legend = {
name:item.name, name:item.name,
alias:item.alias, alias:item.alias,
color:item.color,
showText:this.formatLegend(chartWidth,item.name) showText:this.formatLegend(chartWidth,item.name)
}; };
this.legendList.push(legend); this.legendList.push(legend);
@@ -780,6 +796,9 @@
}); });
} }
this.legendListMore=this.legendList.filter((item,index)=>index<this.seriesLength); this.legendListMore=this.legendList.filter((item,index)=>index<this.seriesLength);
if(this.hasLegendOptions){
this.computeLegendData(this.legendListMore,dataArg,'local');
}
this.$nextTick(() => { this.$nextTick(() => {
setTimeout(function () { setTimeout(function () {
let divHeight = self.$refs.legendArea.offsetHeight; let divHeight = self.$refs.legendArea.offsetHeight;
@@ -886,6 +905,7 @@
const legend = { const legend = {
name:item.name, name:item.name,
alias:item.alias, alias:item.alias,
color:item.color,
showText:this.formatLegend(chartWidth,item.name) showText:this.formatLegend(chartWidth,item.name)
}; };
this.screenLegendList.push(legend); this.screenLegendList.push(legend);
@@ -895,6 +915,9 @@
if(this.screenLegendListMore.length!==this.screenLegendList.length){ if(this.screenLegendListMore.length!==this.screenLegendList.length){
this.screenLegendListMore=this.screenLegendList.filter((item,index)=>index<this.seriesLength); this.screenLegendListMore=this.screenLegendList.filter((item,index)=>index<this.seriesLength);
} }
if(this.hasLegendOptions){
this.computeLegendData(this.screenLegendListMore,dataArg,'screen');
}
if(self.echartModalStore){ if(self.echartModalStore){
self.echartModalStore.clear(); self.echartModalStore.clear();
option.title = {}; option.title = {};
@@ -1052,6 +1075,7 @@
// 设置数据, filter区分 // 设置数据, filter区分
setData(chartItem, seriesItem, panelId, filter,legend,area,errorMsg) { setData(chartItem, seriesItem, panelId, filter,legend,area,errorMsg) {
this.setColor(legend.length); this.setColor(legend.length);
legend.forEach((t,i)=>{t.color = this.bgColorList[i]})
this.filter.from = filter.from; this.filter.from = filter.from;
if(errorMsg && errorMsg!==''){ if(errorMsg && errorMsg!==''){
this.isError = true; this.isError = true;
@@ -1080,6 +1104,13 @@
this.seriesItem = seriesItem; this.seriesItem = seriesItem;
this.seriesItemScreen = seriesItem; this.seriesItemScreen = seriesItem;
this.hasLegendOptions=this.findLegendOptions()
if(this.hasLegendOptions){
let sortedOptionKeys=['min','max','avg','last','total']
this.legendOptions=sortedOptionKeys.map(item=>{ return {option:item,sort:'',value:chartItem.param.legendValue[item]}})
this.screenLegendOptions=sortedOptionKeys.map(item=>{ return {option:item,sort:'',value:chartItem.param.legendValue[item]}})
}
if (filter) { // 保存数据,用于同步时间 if (filter) { // 保存数据,用于同步时间
this.stableFilter = filter; this.stableFilter = filter;
this.searchTime[0] = filter.start_time; this.searchTime[0] = filter.start_time;
@@ -1097,6 +1128,7 @@
}else{ }else{
this.seriesItemArr=seriesItem this.seriesItemArr=seriesItem
} }
this.initChart(chartItem, seriesItemArr, this.$refs.lineChartArea, 'local',legend); this.initChart(chartItem, seriesItemArr, this.$refs.lineChartArea, 'local',legend);
} }
@@ -1465,6 +1497,9 @@
this.echartStore.setOption({ this.echartStore.setOption({
series:this.seriesItem series:this.seriesItem
}); });
if(this.hasLegendOptions){
this.computeLegendData(this.legendListMore,this.seriesItemArr,'local')
}
this.$nextTick(()=>{ this.$nextTick(()=>{
let divHeight = this.$refs.legendArea.offsetHeight; let divHeight = this.$refs.legendArea.offsetHeight;
if(!this.chartInfo.height){ if(!this.chartInfo.height){
@@ -1481,6 +1516,9 @@
this.echartModalStore.setOption({ this.echartModalStore.setOption({
series:this.seriesItemScreen series:this.seriesItemScreen
}); });
if(this.hasLegendOptions){
this.computeLegendData(this.screenLegendListMore,this.seriesItemArrScreen,'screen')
}
this.$nextTick(()=>{ this.$nextTick(()=>{
let legendDiv = document.getElementById('screenLegendArea'+this.chartIndex); let legendDiv = document.getElementById('screenLegendArea'+this.chartIndex);
let divHeight = legendDiv.offsetHeight; let divHeight = legendDiv.offsetHeight;
@@ -1490,6 +1528,125 @@
this.$refs.screenShowArea.style.height = `${sumHeight - divHeight - this.screenTitleHeight}px`; this.$refs.screenShowArea.style.height = `${sumHeight - divHeight - this.screenTitleHeight}px`;
this.echartModalStore.resize({height: (sumHeight - divHeight - this.screenTitleHeight)});//图表的高度 this.echartModalStore.resize({height: (sumHeight - divHeight - this.screenTitleHeight)});//图表的高度
}) })
},
findLegendOptions:function(){
if((!this.data.param.legendValue) || Object.keys(this.data.param.legendValue)<1) return false;
let legendOptions= this.data.param.legendValue;
let onVal=Object.keys(legendOptions).find(item=>{return legendOptions[item] == 'on'});
return onVal;
},
computeLegendData:function(legend,dataArr,where){
let options=where =='local'?this.legendOptions:this.screenLegendOptions;
let keys=options.filter(item=>{return item.value == 'on'}).map(item=>{return item.option});
let $self=this;
keys.forEach(item=>{
switch (item) {
case 'min':
$self.legendMinValue(legend,dataArr);
break;
case 'max':
$self.legendMaxValue(legend,dataArr);
break;
case 'avg':
$self.legendAvgValue(legend,dataArr);
break;
case 'last':
$self.legendLastValue(legend,dataArr);
break;
case 'total':
$self.legendTotalValue(legend,dataArr);
break;
}
})
},
legendMinValue:function(legend,dataArr){
return new Promise(resolve => {
legend.forEach(item=>{
let data=dataArr.find(t=>t.name == item.name)
if(data&&data.data){
let copy=JSON.parse(JSON.stringify(data.data));
let min =copy.sort((x,y)=>{return parseFloat(x[1]) - parseFloat(y[1])})[0][1]
item['min']=parseFloat(min)
}
})
resolve();
})
},
legendMaxValue:function(legend,dataArr){
return new Promise(resolve => {
legend.forEach(item=>{
let data=dataArr.find(t=>t.name == item.name)
if(data&&data.data){
let copy=JSON.parse(JSON.stringify(data.data));
let max =copy.sort((x,y)=>{return parseFloat(y[1]) - parseFloat(x[1])})[0][1]
item['max']=parseFloat(max)
}
})
resolve();
})
},
legendAvgValue:function(legend,dataArr){
return new Promise(resolve => {
legend.forEach(item=>{
let data=dataArr.find(t=>t.name == item.name)
if(data&&data.data){
let copy=JSON.parse(JSON.stringify(data.data));
copy = copy.map(t=>parseFloat(t[1]))
let sum = eval(copy.join('+'));
let avg = sum / copy.length;
item['avg'] = avg;
}
})
resolve();
})
},
legendLastValue:function(legend,dataArr){
return new Promise(resolve => {
legend.forEach(item=>{
let data=dataArr.find(t=>t.name == item.name)
if(data&&data.data){
let copy=JSON.parse(JSON.stringify(data.data));
let last =copy.sort((x,y)=>{return parseFloat(y[0]) - parseFloat(x[0])})[0][1]
item['last']=parseFloat(last)
}
})
resolve();
})
},
legendTotalValue:function(legend,dataArr){
return new Promise(resolve => {
legend.forEach(item=>{
let data=dataArr.find(t=>t.name == item.name)
if(data&&data.data){
let copy=JSON.parse(JSON.stringify(data.data));
copy = copy.map(t=>parseFloat(t[1]))
let sum = eval(copy.join('+'));
item['total'] = sum;
}
})
resolve();
})
},
formatLegendData:function(data){
return chartDataFormat.getUnit(this.chartInfo.unit).compute(data,null,2)
},
legendValueSort:function(option,legend,options){
options.forEach(item=>{
if(item.option != option.option){
item.sort='';
}
})
if(!option.sort || option.sort == 'asc'){
legend.sort((x,y)=>x[option.option] - y[option.option])
option.sort = 'desc'
}else{
legend.sort((x,y)=>y[option.option] - x[option.option])
option.sort = 'asc'
}
} }
}, },
mounted() { mounted() {

View File

@@ -18,7 +18,7 @@
</el-dropdown>--> </el-dropdown>-->
</div> </div>
<el-dialog :visible.sync="importBox.show" :title="importBox.title" :modal-append-to-body='false' :show-close="true" :width="importBox.width" @close="closeDialog" class="nz-dialog" :close-on-click-modal="importBox.type!=3"> <el-dialog :visible.sync="importBox.show" :title="importBox.title" modal-append-to-body append-to-body :modal-append-to-body='false' :show-close="true" :width="importBox.width" @close="closeDialog" class="nz-dialog" :close-on-click-modal="importBox.type!=3">
<div v-if="importBox.type==1"> <div v-if="importBox.type==1">
<div class="upload-body"> <div class="upload-body">
<el-upload drag class="upload-demo" ref="uploadExcel" action="" :file-list="importFileList" :on-change="importChange" :auto-upload="false" accept=".xlsx,.xls"> <el-upload drag class="upload-demo" ref="uploadExcel" action="" :file-list="importFileList" :on-change="importChange" :auto-upload="false" accept=".xlsx,.xls">
@@ -141,6 +141,7 @@
this.$delete(url + '?seq='+this.importResult.seq).then(response=>{ this.$delete(url + '?seq='+this.importResult.seq).then(response=>{
if(response.code == 200 ){ if(response.code == 200 ){
this.$message({duration: 2000, type: 'success', message: this.$t("tip.saveSuccess")}); this.$message({duration: 2000, type: 'success', message: this.$t("tip.saveSuccess")});
this.$emit('afterImport')
}else{ }else{
this.$message.error(response.msg); this.$message.error(response.msg);
} }
@@ -161,6 +162,8 @@
this.$message.error(response.msg); this.$message.error(response.msg);
} }
}) })
}else{
this.$message.error(this.$t('tip.noImportFile'));
} }
}, },
exportMenuHandler(show) { exportMenuHandler(show) {
@@ -210,6 +213,9 @@
exportAll:function(){ exportAll:function(){
let params=JSON.parse(JSON.stringify(this.params)); let params=JSON.parse(JSON.stringify(this.params));
params.pageSize=-1; params.pageSize=-1;
if (this.importUrl.indexOf('panel') > -1){
delete params.panelId
}
params.language=localStorage.getItem('nz-language') || 'en'; params.language=localStorage.getItem('nz-language') || 'en';
this.exportExcel(this.exportUrl,params,this.exportFileName+'-'+this.getTimeString()+'.xlsx'); this.exportExcel(this.exportUrl,params,this.exportFileName+'-'+this.getTimeString()+'.xlsx');

View File

@@ -178,7 +178,16 @@ const cn = {
alertRule:'告警规则', alertRule:'告警规则',
level:'级别', level:'级别',
state:'状态' state:'状态'
} },
valMapping:{
name:'Value mapping',
from:'From',
to:'To',
text:'Text',
value:'Value',
range:'Range',
},
legendValue:'Legend option'
}, },
chartTableColumn: { chartTableColumn: {
metric: "指标", metric: "指标",
@@ -372,7 +381,8 @@ const cn = {
pressEnterToAdd: "回车添加新行", pressEnterToAdd: "回车添加新行",
resetSuccess: "重置成功", resetSuccess: "重置成功",
syncSuccess:'同步成功', syncSuccess:'同步成功',
syncTip:"此操作可能造成原有数据或图表被覆盖,确认同步吗?" syncTip:"此操作可能造成原有数据或图表被覆盖,确认同步吗?",
noImportFile:'没有可导入的文件'
}, },
asset: { asset: {
asset: "资产", asset: "资产",

View File

@@ -192,7 +192,8 @@ const en = {
text:'Text', text:'Text',
value:'Value', value:'Value',
range:'Range', range:'Range',
} },
legendValue:'Legend option'
}, },
chartTableColumn:{ chartTableColumn:{
metric:'Metric', //'指标' metric:'Metric', //'指标'
@@ -380,10 +381,11 @@ const en = {
testSuccess:'Test success', testSuccess:'Test success',
downloadSuccess : 'Download success', downloadSuccess : 'Download success',
uploadSuccess: 'Upload success', uploadSuccess: 'Upload success',
pressEnterToAdd: 'Press enter to add new此操作可能造成原有数据或图表被覆盖,确认同步吗? line', pressEnterToAdd: 'Press enter to add new line',
resetSuccess:'Reset success', resetSuccess:'Reset success',
syncSuccess:'Synchronize success', syncSuccess:'Synchronize success',
syncTip:'This operation may cause the original data or chart to be overwritten. Are you sure to synchronize?', syncTip:'This operation may cause the original data or chart to be overwritten. Are you sure to synchronize?',
noImportFile:'No import file found'
}, },
asset:{ asset:{
asset: 'Asset', asset: 'Asset',

View File

@@ -30,12 +30,12 @@
<div class="right-child-box-title">{{$t('asset.asset')}}</div> <div class="right-child-box-title">{{$t('asset.asset')}}</div>
<!--end--标题--> <!--end--标题-->
<!--begin--搜索框--> <!--begin--搜索框-->
<div style="display: inline-block"> <div style="float: right;padding: 9px 0px 0px 0px;">
<div class="nz-btn-group nz-btn-group-size-small nz-btn-group-light endpoint-asset-search"> <div class="nz-btn-group nz-btn-group-size-small nz-btn-group-light endpoint-asset-search">
<button id="search-asset-drop" type="button" class="nz-btn nz-btn-size-small nz-btn-style-light nz-btn-style-square nz-input-group-prepend" @click="assetSearch.dropdownShow = !assetSearch.dropdownShow"> <button id="search-asset-drop" type="button" class="nz-btn nz-btn-size-small nz-btn-style-light nz-btn-style-square nz-input-group-prepend" @click="assetSearch.dropdownShow = !assetSearch.dropdownShow">
<span class="endpoint-asset-label-txt">{{assetSearch.label}}</span> <span class="endpoint-asset-label-txt">{{assetSearch.label}}</span>
<span> <span>
<i v-if="assetSearch.dropdownShow" class="nz-icon nz-icon-caret-top"></i> <i v-if="assetSearch.dropdownShow" class="nz-icon nz-icon-caret-up"></i>
<i v-if="!assetSearch.dropdownShow" class="nz-icon nz-icon-caret-bottom"></i> <i v-if="!assetSearch.dropdownShow" class="nz-icon nz-icon-caret-bottom"></i>
</span> </span>
</button><el-input style="width: 100px;" class="input-x-mini-24 nz-input-group-middle" placeholder="" v-model="assetSearch.text"></el-input><button </button><el-input style="width: 100px;" class="input-x-mini-24 nz-input-group-middle" placeholder="" v-model="assetSearch.text"></el-input><button

View File

@@ -35,7 +35,7 @@
</el-form-item> </el-form-item>
<!--threshold--> <!--threshold-->
<el-form-item :label="$t('alert.config.threshold')" prop="threshold" style="width: 415px;display: inline-block;"> <el-form-item :label="$t('alert.config.threshold')" prop="threshold" style="width: 415px;display: inline-block;">
<el-input type="text" placeholder="" v-model.number="editAlertRule.threshold" size="small"> <el-input type="text" placeholder="" v-model="editAlertRule.threshold" size="small">
</el-input> </el-input>
</el-form-item> </el-form-item>
<!--unit--> <!--unit-->
@@ -152,7 +152,6 @@
], ],
threshold:[ threshold:[
{required:true,message:this.$t('validate.required'),trigger:'blur'}, {required:true,message:this.$t('validate.required'),trigger:'blur'},
{type:'number',message:this.$t('validate.number')}
], ],
}, },
operators:[ operators:[

View File

@@ -430,6 +430,9 @@
getTableData() { getTableData() {
this.searchLabel = Object.assign(this.searchLabel, this.pageObj); this.searchLabel = Object.assign(this.searchLabel, this.pageObj);
this.tools.loading = true; this.tools.loading = true;
if(this.searchLabel.tags && this.searchLabel.tags!=''){
this.searchLabel.tags=encodeURIComponent(this.searchLabel.tags)
}
this.$get('asset', this.searchLabel).then(response => { this.$get('asset', this.searchLabel).then(response => {
this.tools.loading = false; this.tools.loading = false;
if (response.code === 200) { if (response.code === 200) {

View File

@@ -245,6 +245,27 @@
</template> </template>
<!--value mapping end--> <!--value mapping end-->
<template v-if="editChart.type == 'line' || editChart.type == 'bar' || editChart.type == 'stackArea'">
<div class="right-box-sub-title" >
<span>{{$t('dashboard.panel.chartForm.legendValue')}}</span>
</div>
<div class="line-100" style="margin-bottom: 20px;" ></div>
<div style="display: flex;">
<span style="margin-left: 50px;"></span>
<template v-for="item in sortedOptionKeys">
<div style="flex: 1">
<span style="margin-right: 10px;">{{item.label}}</span>
<el-switch
v-model="editChart.param.legendValue[item.key]"
active-value="on"
inactive-value="off"
active-color="#ee9d3f"
@change="">
</el-switch>
</div>
</template>
</div>
</template>
</el-form> </el-form>
</el-scrollbar> </el-scrollbar>
@@ -369,6 +390,7 @@
}, },
heightSuggestions:['300','400','500','600'], heightSuggestions:['300','400','500','600'],
unitOptions:chartDataFormat.unitOptions(), unitOptions:chartDataFormat.unitOptions(),
sortedOptionKeys:[{key:'min',label:'Min'},{key:'max',label:'Max'},{key:'avg',label:'Avg'},{key:'last',label:'Last'},{key:'total',label:'Total'}]
} }
}, },
components:{ components:{
@@ -1005,6 +1027,7 @@
param.url=''; param.url='';
param.threshold=''; param.threshold='';
param.valueMapping={type:'text',mapping:[{value:'',text:''}]}; param.valueMapping={type:'text',mapping:[{value:'',text:''}]};
param.legendValue={min:'off',max:'off',avg:'off',last:'off',total:'off'}
this.$set(this.editChart, "param", param); this.$set(this.editChart, "param", param);
this.elements = [1]; this.elements = [1];
this.elementTarget = []; this.elementTarget = [];
@@ -1125,11 +1148,13 @@
}; };
if(this.editChart.type === 'singleStat'){ if(this.editChart.type === 'singleStat'){
params.param.statistics=this.statistics; params.param.statistics=this.statistics;
params.param.valueMapping=this.editChart.param.valueMapping;
} else { } else {
delete params.param.statistics; delete params.param.statistics;
} }
if(this.editChart.type==='line'||this.editChart.type==='bar'||this.editChart.type==='stackArea'){ if(this.editChart.type==='line'||this.editChart.type==='bar'||this.editChart.type==='stackArea'){
params.param.threshold=this.editChart.param.threshold; params.param.threshold=this.editChart.param.threshold;
params.param.legendValue=this.editChart.param.legendValue;
} else { } else {
delete params.param.threshold; delete params.param.threshold;
} }
@@ -1229,6 +1254,7 @@
this.setIsSingleStat(); this.setIsSingleStat();
} else { } else {
this.setIsOtherChart(); this.setIsOtherChart();
n.param&&!n.param.legendValue&&this.$set(this.editChart.param,'legendValue',{min:'off',max:'off',avg:'off',last:'off',total:'off'})
} }
//console.info(this.showPanel); //console.info(this.showPanel);
this.$set(this.editChart, "panelName", this.showPanel.name); this.$set(this.editChart, "panelName", this.showPanel.name);

View File

@@ -55,7 +55,7 @@
export-url="/panel/export" export-url="/panel/export"
import-url="/panel/import" import-url="/panel/import"
:params="filter" :params="filter"
@afterImport="Refresh" @afterImport="dateChange"
> >
<template slot="optionZone"> <template slot="optionZone">
<button @click="addChart" :title="$t('overall.createChart')" <button @click="addChart" :title="$t('overall.createChart')"

View File

@@ -573,6 +573,7 @@
}); });
bus.$on("current-module-change", module => { bus.$on("current-module-change", module => {
this.currentModule = module; this.currentModule = module;
this.bottomBox.showSubList=false;
}); });
bus.$on("project-list-change", () => { bus.$on("project-list-change", () => {
this.getProjectList(); this.getProjectList();