<template> <div> <div class="main"> <el-card shadow="hover"> <div class="choice"> <el-select v-model="choiceRange" @change="selectChange"> <el-option v-for="(item, index) in timeOptions" :key="index" :label="item.label" :value="index" > <span style="float: left">{{ item.label }}</span> </el-option> </el-select> <el-select v-model="choicePeriod" @change="periodChange"> <el-option v-for="(item, index) in periodOptions" :key="index" :label="item.label" :value="item.value" > <span style="float: left">{{ item.label }}</span> </el-option> </el-select> <el-date-picker v-model="TimeValue" :picker-options="pickerOptions" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" id="IndexTime" value-format="yyyy-MM-dd HH:mm:ss" ></el-date-picker> <el-button size="" type="primary" ><i class="el-icon-refresh" @click="refresh"></i ></el-button> </div> <p class="describeP"> <i class="el-icon-info" style="font-size:14px"></i >注释:Max、Min和Avg数值统计为当前折线图内所有点的最大值、最小值和平均值<a href="javascript:void(0)" style="float:right" @click="downAll" class="export" >导出数据</a > </p> <!-- <div class="mian-item"> <div class="title"> 系统平衡负载 </div> <div class="contentAll"> <div class="content"> <div class="describe"> cpu平衡负载 <el-tooltip class="item" effect="dark" content="Bottom Left 提示文字" placement="bottom-start"> <i class="el-icon-info" style="font-size:14px"></i> </el-tooltip> </div> <div class="echarts" ref="echarts0"></div> <div class="smallField"><p>max:</p><p>{{ echartsData1.max === null ? '': echartsData1.max}}%</p></div> <div class="smallField"><p>max:</p><p>{{echartsData1.min === null ? '': echartsData1.min}}%</p></div> <div class="smallField"><p>max:</p><p>{{echartsData1.avg}}%</p></div> <div class="option"> <el-button size="mini" icon="el-icon-rank" @click="showBigEcharts"></el-button> <el-button size="mini"><i class="el-icon-picture" @click="downImg"></i></el-button> <el-button size="mini"><i class="el-icon-download"></i></el-button> </div> </div> </div> </div> --> <div class="mian-item" v-for="(member, indexOut) in dataAll" :key="indexOut" > <div class="title"> {{ member.name }} </div> <div class="contentAll"> <div class="content" v-for="(item, indexInt) in member.data" :key="indexInt" > <div class="describe"> {{ item.name }} <el-tooltip class="item" effect="dark" :content="item.tip" placement="bottom-start" > <i class="el-icon-info" style="font-size:14px"></i> </el-tooltip> </div> <div class="echarts" :ref="item.target"></div> <div class="smallField"> <p>max:</p> <p> <span v-if="item.echartsData && item.echartsData.max" >{{ item.echartsData && item.echartsData.max }}{{ item.unit }}</span ><span v-if="!(item.echartsData && item.echartsData.max)" >-</span > </p> </div> <div class="smallField"> <p>min:</p> <p> <span v-if="item.echartsData && item.echartsData.min" >{{ item.echartsData && item.echartsData.min }}{{ item.unit }}</span ><span v-if="!(item.echartsData && item.echartsData.min)" >-</span > </p> </div> <div class="smallField"> <p>avg:</p> <p> <span v-if="item.echartsData && item.echartsData.avg" >{{ item.echartsData && item.echartsData.avg }}{{ item.unit }}</span ><span v-if="!(item.echartsData && item.echartsData.avg)" >-</span > </p> </div> <div class="option"> <el-tooltip class="item" effect="dark" content="展开大图图表" placement="top-end" > <el-button type="primary" @click="showBigEcharts(item.target)" class="optionbtn" ><img src="../../../../static/img/zk_icon.png" /></el-button> </el-tooltip> <el-tooltip class="item" effect="dark" content="下载图片文件" placement="top-end" > <el-button type="primary" class="optionbtn" @click="downImg(item.target)" > <img src="../../../../static/img/tpxz_icon.png" /> </el-button> </el-tooltip> <el-tooltip class="item" effect="dark" content="下载xls文件" placement="top-end" > <el-button type="primary" class="optionbtn" @click="downXls(item.target, item.name)" > <img src="../../../../static/img/wjxz_icon.png" /> </el-button> </el-tooltip> </div> </div> </div> </div> </el-card> <!-- <el-button type="text" @click="dialogVisible = true">点击打开 Dialog</el-button> --> <el-dialog title="详细图表" :visible.sync="dialogVisible" modal-append-to-body width="70%" > <div id="bigEacharts" ref="bigEacharts"></div> <!-- <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="dialogVisible = false">确 定</el-button> </span> --> </el-dialog> </div> </div> </template> <script> import html2canvas from 'html2canvas' import { dataAll } from "./monitor01.js"; import fileDownload from 'js-file-download' import axios from "axios"; // import ExportJsonExcel from "js-export-excel" export default { data() { return { dataAll, timeOptions: [ { label: "实时", value: 0, mark: 0 }, { label: "24小时", value: 1, mark: 1 }, { label: "7天", value: 2, mark: 2 } ], choiceRange: 0, choicePeriod: 10, TimeValue: [ this.moment() .subtract(1, "hour") .format("YYYY-MM-DD HH:mm:ss"), this.moment().format("YYYY-MM-DD HH:mm:ss") ], //起止日期 pickerOptions: { shortcuts: [ { text: "实时", onClick(picker) { const end = new Date(); const start = new Date(); start.setTime(start.getTime() - 3600 * 1000); picker.$emit("pick", [start, end]); } }, { text: "最近24小时", onClick(picker) { const end = new Date(); const start = new Date(); start.setTime(start.getTime() - 3600 * 1000 * 24); picker.$emit("pick", [start, end]); } }, { text: "最近7天", onClick(picker) { const end = new Date(); const start = new Date(); start.setTime(start.getTime() - 3600 * 1000 * 24 * 7); picker.$emit("pick", [start, end]); } } ] }, //时间框的快捷选项 dialogVisible: false, bigEachartsTest: {}, test: 0, echartsData1: {}, targetAll: [ "CPUUsage", "BaseCpuUsage", "CpuLoadavg", "MemUsed", "MemUsage", "LanOuttraffic", "LanIntraffic", "LanOutpkg", "LanInpkg", "TcpCurrEstab", "WanOuttraffic", "WanIntraffic", "WanOutpkg", "WanInpkg", "AccOuttraffic" ] }; }, computed: { periodOptions() { let arr = [ { label: "10秒", value: 10 }, { label: "1分钟", value: 60 }, { label: "5分钟", value: 300 }, { label: "1小时", value: 3600 }, { label: "1天", value: 3600 * 24 } ]; if (this.choiceRange === 0) return arr.slice(0, 3); if (this.choiceRange === 1) return arr.slice(1); if (this.choiceRange === 2) return arr.slice(3); } }, methods: { selectChange(val) { if (val === 0) this.TimeValue = [ this.moment() .subtract(1, "hour") .format("YYYY-MM-DD HH:mm:ss"), this.moment().format("YYYY-MM-DD HH:mm:ss") ]; if (val === 1) this.TimeValue = [ this.moment() .subtract(24, "hour") .format("YYYY-MM-DD HH:mm:ss"), this.moment().format("YYYY-MM-DD HH:mm:ss") ]; if (val === 2) this.TimeValue = [ this.moment() .subtract(7, "day") .format("YYYY-MM-DD HH:mm:ss"), this.moment().format("YYYY-MM-DD HH:mm:ss") ]; this.choicePeriod = this.periodOptions[0].value; }, periodChange() {}, refresh() { this.targetAll.forEach(item => { this.getInterface(item); }); }, showBigEcharts(target) { this.dialogVisible = true; this.getInterface(target); // this.test =1 var echartsObj; this.dataAll.forEach(item => { item.data.forEach(member => { if (member.target === target) { echartsObj = member.echartsData; setTimeout(() => { this.bigEachartsTest = this.$echarts.init(this.$refs.bigEacharts); // 指定图表的配置项和数据 var option = { color: ["#3398DB", "red"], tooltip: { show: true, trigger: "axis", axisPointer: { type: "line", crossStyle: { color: "#ccc" }, snap: true, axis: "x" } // formatter: params => { // // let axisValue = this.moment(params['axisValueLabel']).format("YYYY-MM-DD HH:mm:ss") // // return `<p style="color:#333">${axisValue}</p><p style="font-weight:bold;color:black">${params[0].value}%</p>` // var res = params[0].name; // for (var i = 0; i < params.length; i++) { // res += // "<br>" + // params[i].marker + // params[i].seriesName + // ":" + // params[i].data; // } // return res; // } }, dataZoom: [ { type: "inside" } ], title: { // text: `${item.instanceId}/${item.name}` text: `${item.name}` }, // legend: { // data:['销量'] // }, xAxis: { // show:false, data: echartsObj.timeList, splitLine: { show: false }, axisTick: { // alignWithLabel: true } }, yAxis: { axisLine: { show: false }, // splitNumber: 1, // minInterval: 10, // maxInterval: 20, splitLine: { show: false }, // color: rgb(0, 119, 254) // boundaryGap: [0, '100%'] axisLabel: { color: "#3398DB" } }, series: [ { // name: '销量1', type: "line", data: echartsObj.valueList, markPoint: { data: [ { type: "max", name: "最大值" }, { type: "min", name: "最小值" } ], itemStyle: { color: "pink" } }, markLine: { data: [{ type: "average", name: "平均值" }], lineStyle: { color: "red" } } } // { // name: '销量2', // type: 'bar', // data: [5, 20, 36, 10, 10, 20,70,200,12,24] // }, ] }; // 使用刚指定的配置项和数据显示图表。 this.bigEachartsTest.setOption(option); }, 0); } }); }); }, // 点击导出 downImg(target) { this.showBigEcharts(target); // this.bigEachartsTest.on('finished', function () { // }); setTimeout(() => { // var img = new Image(); // img.src = this.bigEacharts.getDataURL({ // pixelRatio: 2, // backgroundColor: '#fff' // }); // // const dataImg = new Image() // // dataImg.src = canvas.toDataURL('image/png') // const alink = document.createElement('a') // alink.href = img.src // alink.download = 'Img.jpg' // alink.click() // this.dialogVisible =false window.pageYoffset = 0; document.documentElement.scrollTop = 0; document.body.scrollTop = 0; const targetDom = this.$refs.bigEacharts; // console.log(11111) html2canvas(targetDom, { useCORS: true, allowTaint: true, height: targetDom.scrollHeight, width: targetDom.scrollWidth }).then(canvas => { const dataImg = new Image(); dataImg.src = canvas.toDataURL("image/png"); const alink = document.createElement("a"); alink.href = dataImg.src; alink.download = "Img.jpg"; alink.click(); this.dialogVisible = false; }); }, 2000); // this.dialogVisible=true // this.$nextTick(()=>{ // }) }, downAll() { var arr = []; this.dataAll.forEach(item => { item.data.forEach(element => { arr.push({ id: element.target, name: element.name }); }); }); // console.log(arr, "arr"); var param = { regionId: "ap-chengdu", instanceId: this.$route.query.instanceId, period: this.choicePeriod, startTime: this.TimeValue[0], endTime: this.TimeValue[1], metricListStr: JSON.stringify(arr) }; axios .post(this.nozzle.downloadMonitor, param, { responseType: "blob" }) .then(res => { fileDownload(res, `${this.$route.query.instanceId}-${name}.xls`); // console.log('res', res); }) .catch(err => { console.log(err.message); }); }, downXls(target, name) { var param = { regionId: "ap-chengdu", instanceId: this.$route.query.instanceId, // "metricName":target, period: this.choicePeriod, startTime: this.TimeValue[0], endTime: this.TimeValue[1], metricListStr: JSON.stringify([{ id: target, name: name }]) }; // // console.log(param,'str') // postDownloadFile(this.nozzle.downloadMonitor, param); // 直接导出文件 // const ExportJsonExcel = require("js-export-excel"); axios .post(this.nozzle.downloadMonitor, param, { responseType: "blob" }) .then(res => { console.log(121212); fileDownload(res, `${this.$route.query.instanceId}-${name}.xls`) // var elink = document.createElement("a"); // elink.download = `${this.$route.query.instanceId}-${name}657.xls`; // elink.style.display = "none"; // var blob = new Blob([res], { type: "application/vnd.ms-excel" }); // elink.href = URL.createObjectURL(blob); // document.body.appendChild(elink); // elink.click(); // document.body.removeChild(elink); // console.log('res', res); }) .catch(err => { console.log(err.message); }); // var str='?' // for(var i in param){ // str += i + '=' + param[i] + '&' // } // str= str.slice(0,-1) // window.open(`${this.nozzle.downloadMonitor}?${JSON.stringify(param)}`, '_blank'); // console.log(this.nozzle.downloadMonitor,'this.nozzle.downloadMonitor') // console.log('http://192.168.16.254:8080/download/monitor','this.nozzle.downloadMonitor') // postDownloadFile('http://192.168.16.254:8080/download/monitor', { // "regionId":"ap-chengdu", // "instanceId":this.$route.query.instanceId, // "metricName":target, // "period":this.choicePeriod, // "startTime":this.TimeValue.length && this.TimeValue[0], // "endTime":this.TimeValue.length && this.TimeValue[1], // "metricList":[{"id":target,"name":name}] // }); // this.$http.post(this.nozzle.downloadMonitor, { // "regionId":"ap-chengdu", // "instanceId":this.$route.query.instanceId, // "metricName":target, // "period":this.choicePeriod, // "startTime":this.TimeValue.length && this.TimeValue[0], // "endTime":this.TimeValue.length && this.TimeValue[1], // "metricList":[{"id":target,"name":name}] // }, // { responseType: "blob" } // ).then(res=>{ // console.log(res.data); // // var option = {}; // // option.fileName = "excel"; // // option.datas = res // // var toExcel = new ExportJsonExcel(option); //new // // toExcel.saveExcel(); //保存 // // const blob = res.data; // // const reader = new FileReader(); // // reader.readAsDataURL(blob); // // reader.onload = (e) => { // // const a = document.createElement('a'); // // a.download = `文件名称.xls`; // // // 后端设置的文件名称在res.headers的 "content-disposition": "form-data; name=\"attachment\"; filename=\"20181211191944.zip\"", // // a.href = e.target.result; // // document.body.appendChild(a); // // a.click(); // // document.body.removeChild(a); // // }; // // fileDownload(res.data, `${name}.xls`) // // console.log(res,'resss') // }) }, createSmallEcharts(target) { var echartsObj; this.dataAll.forEach(item => { item.data.forEach(member => { if (member.target === target) { echartsObj = member.echartsData; // console.log(this.$refs[target],'this.$refs') var myChart = this.$echarts.init(this.$refs[target][0]); // console.log(document.getElementsByClassName('echarts')[0],'document.getElementsByCl') // var myChart = this.$echarts.init(document.getElementsByClassName('echarts')[0]); // 指定图表的配置项和数据 var option = { color: ["#3398DB", "red"], tooltip: { show: true, trigger: "axis", axisPointer: { type: "line", crossStyle: { color: "#333" }, snap: true, axis: "x" } }, dataZoom: [ { type: "inside" } ], title: { // text: 'ECharts 入门示例' }, // legend: { // data:['销量'] // }, xAxis: { show: false, data: echartsObj.timeList, splitLine: { show: false }, axisTick: { // alignWithLabel: true } }, yAxis: { axisLine: { show: false }, splitNumber: 2, // minInterval: 10, // maxInterval: 20, splitLine: { show: false }, axisLabel: { color: "#3398DB" } // boundaryGap: [0, '100%'] }, series: [ { // name: '销量1', type: "line", data: echartsObj.valueList } ] }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); } }); }); }, getInterface(target) { this.$http .post(this.nozzle.monitorInfoList, { regionId: "ap-chengdu", instanceId: this.$route.query.instanceId, metricName: target, period: this.choicePeriod, startTime: this.TimeValue && this.TimeValue[0], endTime: this.TimeValue && this.TimeValue[1] }) .then(res => { // console.log(res,'resss') var echartsObj; this.dataAll.forEach(item => { item.data.forEach(member => { if (member.target === target) { echartsObj = member.echartsData; // console.log('target') } }); }); for (var i in echartsObj) { delete echartsObj[i]; } for (var i in res.data.data) { echartsObj[i] = res.data.data[i]; } // arr.sort(function(a,b){return a - b;}) function maxCreate(arr) { arr = arr.filter(item => !_isNaN(item)); return arr.length ? Math.max.apply(null, arr) : undefined; } // var echartsObValueList= JSON.parse(JSON.stringify(echartsObj.valueList)) let echartsObValueList = [...echartsObj.valueList]; // try { // } catch(err){ // }arr.sort(function(a,b){return a - b;}); // let max = Math.max(echartsObValueList) let max = echartsObValueList.sort(function(a, b) { return a - b; })[echartsObValueList.length - 1]; let min = echartsObValueList.sort(function(a, b) { return a - b; })[0]; // let min = Math.min(echartsObValueList) // console.log(echartsObValueList,max,'001') const arrayAverage = arr => arr.reduce((acc, val) => acc + val, 0) / arr.length; let avg = arrayAverage(echartsObValueList); this.$set(echartsObj, "max", max); this.$set(echartsObj, "min", min); this.$set(echartsObj, "avg", avg.toFixed(3)); // this.echartsData1['max']=max // this.echartsData1['min']=min // this.echartsData1['avg']=avg.toFixed(3) this.createSmallEcharts(target); // console.log(max,min,avg,'res') }); }, downloadMonitor() { console.log(123); } }, mounted() { // this.createSmallEcharts() }, beforeDestroy() { if (this.bigEacharts && Object.keys(this.bigEacharts).length !== 0) { this.bigEacharts.dispose(); } }, beforeCreate() {}, created() { this.$http.post(this.nozzle.monitorMetricInfo).then(res => { var arr = res.data.data.map(item => { return item.id; }); // this.targetAll = arr // console.log(res.data.data,arr,'ress') // this.targetAll=res.data.data }); this.refresh(); } }; </script> <style lang="scss" scoped> .mian { margin-bottom: -10px; } .describeP { text-align: left; margin: 30px 0 10px 0; font-size: 12px; color: var(--white); } .mian-item { /* height: 150px; */ display: flex; text-align: left; /* margin: 30px 0 0 0; */ border-bottom: 1px solid var(--white); } .mian-item .title { /* text-align: left; */ font-weight: bold; font-size: 14px; color: var(--white); padding: 10px; width: 10%; } .mian-item .contentAll { flex: 1; /* display: flex; */ /* position: relative; */ } .mian-item .contentAll .content { border-top: 1px solid var(--white); } .mian-item .contentAll > :first-child { border-top: initial; } .mian-item .content { /* flex: 1; */ display: flex; position: relative; } .mian-item .content .describe { height: 78px; width: 10%; font-size: 12px; font-weight: 700; padding: 10px; color: var(--white); } .tooltip { display: inline; } .mian-item .content .echarts { height: 78px; flex: 1; /* padding: 10px; */ } .mian-item .content .smallField { height: 78px; width: 10%; padding: 10px; } .mian-item .content .smallField p { height: 18px; line-height: 18px; } .mian-item .content .smallField p:nth-child(1) { font-size: 14px; color: var(--white); } .mian-item .content .smallField p:nth-child(2) { margin: 10px 0 0 0; font-size: 14px; color: var(--white); } .mian-item .content .option { height: 78px; width: 10%; padding: 10px; } .choice { text-align: left; } #bigEacharts { width: 100%; height: 400px; } /* /deep/.el-select .el-input__inner{ color: black !important; } /deep/.el-date-editor .el-range-input{ color: black !important; } /deep/.el-date-editor .el-range-separator{ color: black !important; } */ /* /deep/.el-button { */ /* margin-top: 2px; */ /* } */ /deep/.el-button + .el-button { margin-left: 0; } .export { color: var(--yellow); } .optionbtn { position: relative; // background-color: rgb(2, 120, 254) !important; // border: 1px solid rgb(2, 120, 254) !important; padding: 12px 20px; } .optionbtn img { position: absolute; top: calc(50% - 10px); left: calc(50% - 10px); } </style>