diff --git a/nezha-fronted/src/components/page/dashboard/overview/chart.vue b/nezha-fronted/src/components/page/dashboard/overview/chart.vue index 30b176dc5..d01ee6e3e 100644 --- a/nezha-fronted/src/components/page/dashboard/overview/chart.vue +++ b/nezha-fronted/src/components/page/dashboard/overview/chart.vue @@ -30,6 +30,7 @@ 'loading':loading, }, props:{ + name: {type: String}, chartTitle:{type:String}, showToolbox:{type:Boolean,default:true}, chartType:{type:String,default:'line'}, @@ -41,7 +42,7 @@ return { chart:null, option:{}, - chartId:new uuidv1()+'-'+new Date().getTime(), + chartId: this.name + new uuidv1()+'-'+new Date().getTime(), legend:[], } }, @@ -64,9 +65,9 @@ }, setSeries:function(series){ if(!this.chart){ - this.chart=echarts.init(document.getElementById(this.chartId)); + this.chart = echarts.init(document.getElementById(this.chartId)); } - this.series=series; + this.series = series; if(this.chartType == 'map'){ if(this.map){ echarts.registerMap(this.map.name,this.map.geoJson); @@ -85,7 +86,7 @@ if (this.tooltipFormatter) { this.modifyOption('tooltip', 'formatter', this.tooltipFormatter) } else { - this.modifyOption('tooltip', 'formatter', this.defaultTooltipFormatter) + //this.modifyOption('tooltip', 'formatter', this.defaultTooltipFormatter) } if(this.chartType == 'line'){ diff --git a/nezha-fronted/src/components/page/dashboard/overview/chartConfig.vue b/nezha-fronted/src/components/page/dashboard/overview/chartConfig.vue index 08dfbb15b..967a3338c 100644 --- a/nezha-fronted/src/components/page/dashboard/overview/chartConfig.vue +++ b/nezha-fronted/src/components/page/dashboard/overview/chartConfig.vue @@ -90,7 +90,7 @@ }, useUTC: false,//使用本地时间 series: [], - } + }; const mapOptions={ geo:{ map:'', @@ -133,11 +133,44 @@ borderWidth: 1, padding: 0, }, - } + }; + const assetTypePie = { + title: { + show: false, + }, + color: bgColorList, + legend: { + show: false, + }, + grid: {}, + series: [], + tooltip : {} + }; + const alertMessageBar = { + title: { + show: false, + }, + color: bgColorList, + legend: { + show: false, + }, + grid: {}, + series: [], + tooltip : {}, + xAxis: { + type: 'value' + }, + yAxis: { + type: 'category', + data: [] + }, + }; const chartTypes={ line:{name:'line',option:commonOption}, map:{name:'map',option:mapOptions}, - } + pie: {name: 'assetType', option: assetTypePie}, + bar: {name: 'alertMessage', option: alertMessageBar} + }; export default { getOption:function(type){ return Object.assign({},chartTypes[type].option); diff --git a/nezha-fronted/src/components/page/dashboard/overview/overview2.scss b/nezha-fronted/src/components/page/dashboard/overview/overview2.scss index 404a4f748..e4fc06c23 100644 --- a/nezha-fronted/src/components/page/dashboard/overview/overview2.scss +++ b/nezha-fronted/src/components/page/dashboard/overview/overview2.scss @@ -72,6 +72,9 @@ .overview-content .content-row-box:nth-of-type(3) { height: 39%; } +.overview-content .content-row-box:nth-of-type(2) .content-col-box { + width: calc(50% - 10px); +} .content-row-box .content-col-box{ margin: 5px; display: inline-block; @@ -79,21 +82,58 @@ flex: 1; } .content-col-title { - height: 25px; - line-height: 25px; + height: 1.6rem; + line-height: 1.6rem; border-bottom: 1px solid #f2f2f2; color: #333; - font-size: 16px; + font-size: 1rem; padding-left: 8px; } +.dropdown-btn { + position: relative; +} +.dropdown-btn .el-popper { + top: 20px; + left: unset; + right: 0; +} +.dropdown-btn .el-popper::after { + content: ''; + display: block; + width:0; + height:0; + overflow: hidden; + font-size: 0; + line-height: 0; + border: 5px; + border-style: dashed dashed solid dashed; + border-color: transparent transparent #fff transparent; + position: absolute; + left: 50%; + bottom: 0; + transform: translate(-50%, -54px); +} .content-col-content { display: flex; align-items: center; - height: calc(100% - 26px); + height: calc(100% - 1.6rem); justify-content: center; + padding: 0 8px; +} +.content-row-box:nth-of-type(2) .content-col-content:last-of-type { + padding: 0; +} +.content-row-box:first-of-type .content-col-content:last-of-type { + position: relative; +} +.content-row-box:first-of-type .content-col-content:last-of-type span { + position: absolute; + bottom: 5%; + right: 5%; + font-size: 0.9rem; } .content-col-content-num { - font-size: 40px; + font-size: 2.5rem; color: #333; } diff --git a/nezha-fronted/src/components/page/dashboard/overview/overview2.vue b/nezha-fronted/src/components/page/dashboard/overview/overview2.vue index 86b0aaeec..cfc9b4422 100644 --- a/nezha-fronted/src/components/page/dashboard/overview/overview2.vue +++ b/nezha-fronted/src/components/page/dashboard/overview/overview2.vue @@ -29,58 +29,86 @@
+
{{$t("dashboard.overview.asset.title")}}
-
- {{(assetData ? assetData.totalStat.total : "") | numberFormat}} +
+
{{(assetData ? assetData.totalStat.total : "") | numberFormat}}
{{$t("dashboard.overview.project.project")}}
-
- {{(projectData ? projectData.projectStat.length : "") | numberFormat}} +
+
{{(projectData ? projectData.projectStat.length : "") | numberFormat}}
{{$t("dashboard.overview.module.module")}}
-
- {{(moduleData ? moduleData.moduleStat.length : "") | numberFormat}} +
+
{{(moduleData ? moduleData.moduleStat.length : "") | numberFormat}}
{{$t("dashboard.overview.endpoint.endpoint")}}
-
- {{(endpointData ? endpointData.total : "") | numberFormat}} +
+
{{(endpointData ? endpointData.total : "") | numberFormat}}
{{$t("dashboard.overview.alert.alertMessage")}}
-
- {{(alertMessageData ? alertMessageData.alertMessageTotal : "") | numberFormat}} +
+
{{(alertMessageData ? alertMessageData.alertMessageTotal : "") | numberFormat}}
+ {{$t("dashboard.overview.alert.ruleNum")}}  {{(alertRuleData ? alertRuleData.alertRuleTotal : "") | numberFormat}}
+
{{$t("dashboard.overview.alert.chart.chartTitle")}}
+
+ +
{{$t("dashboard.overview.dataCenter.dataCenter")}}
- +
+
{{$t("dashboard.overview.asset.assetType")}}
+
+ +
{{$t("dashboard.overview.alert.alertRuleTopN")}}
+
+ +
-
{{$t("dashboard.overview.alert.assetTopN")}}
+
+ {{$t("dashboard.overview.alert.assetTopN")}} + + + +
    + + +
+
+
+
+
+ + +
@@ -93,7 +121,7 @@ import chart from "./chart"; import chartDataFormat from "../../../charts/chartDataFormat"; import axios from 'axios'; - + var timeout; export default { name: "overview2", components:{ @@ -119,10 +147,18 @@ endpointData: '', alertMessageLoading: false, alertMessageData: '', + alertRuleData: '', map: null, - chartSeries:[], - alertRuleStatData:{}, - dataCenterMapSeries:[], + chartSeries: [], + assetTypeSeries: [], + messageByRuleSeries: [], + messageByAssetSeries: [], + messageByModuleSeries: [], + alertRuleStatData: {}, + dataCenterMapSeries: [], + + alertMessageShow: 'asset', //asset/module + bottom3DropdownShow: false, //最底部行第三列的下拉选择框 } }, filters: { @@ -134,9 +170,9 @@ if (num < 1000) { return num; } else if (num < 1000000) { - return (num/1000).toFixed(fixed); + return (num/1000).toFixed(fixed) + "K"; } else if (num < 1000000000) { - return (num/1000000).toFixed(fixed); + return (num/1000000).toFixed(fixed) + "M"; } } catch (err) { return 0; @@ -153,8 +189,12 @@ this.queryModuleData(); this.queryEndpointData(); this.queryAlertMessageData(); + this.queryAlertRuleData(); this.queryDatacenterData(); + this.queryAlertTrendData(); this.queryMapChartGeoJson(); + this.queryAlertStatByRule(); + this.queryAlertStatByAsset(); }, queryAssetData() { this.assetLoading = true; @@ -162,6 +202,20 @@ this.assetLoading = false; if (response.code === 200) { this.assetData = response.data; + + /*饼图*/ + this.$refs.assetTypePie.startLoading(); + let seriesData = []; + this.assetData.typeStat.forEach(item => { + seriesData.push({name: item.name, value: item.total}); + }); + let series = { + name: 'nz_alert_nums', + data: seriesData, + type: 'pie' + }; + this.$refs.assetTypePie.setSeries(series); + this.$refs.assetTypePie.endLoading(); } }) }, @@ -201,6 +255,13 @@ } }) }, + queryAlertRuleData() { + this.$get('overview/alertRuleStat').then(response => { + if (response.code === 200) { + this.alertRuleData = response.data; + } + }) + }, queryDatacenterData() { this.$get('overview/datacenterStat').then(response => { if (response.code === 200) { @@ -208,7 +269,45 @@ } }) }, - queryMapChartGeoJson:function(){ + queryAlertTrendData() { + this.$refs.chartbox.startLoading(); + let cur=this.dateFormat('yyyy-mm-dd HH:MM:SS',new Date()); + let beforeDate=new Date(); + beforeDate.setHours(new Date().getHours()-1); + let before=this.dateFormat('yyyy-mm-dd HH:MM:SS',beforeDate); + let params={ + query:'sum(nz_alert_nums)', + start:before, + end:cur, + step:'15s' + } + this.$get('/prom/api/v1/query_range',params).then(response=>{ + if(response.status == 'success'){ + if(response.data.result){ + let series={ + name: 'nz_alert_nums', + symbol:'none', //去掉点 + smooth:true, //曲线变平滑 + data: [], + type:'line', + // areaStyle:{} + } + series.data=response.data.result[0].values.map((item)=>{ + return [item[0]*1000,item[1]]; + }) + this.chartSeries=[series]; + this.$refs.chartbox.modifyOption('tooltip','formatter',this.tooltipFormatter); + this.$refs.chartbox.modifyOption('tooltip','position',this.tooltipPosition); + this.$refs.chartbox.modifyOption('yAxis','formatter',this.yAxisFormatter); + this.$refs.chartbox.setSeries(this.chartSeries); + this.$refs.chartbox.endLoading(); + } + }else{ + console.error(response) + } + }) + }, + queryMapChartGeoJson() { this.$get('/sysConfig?paramKey=geoJson').then(response=>{ if(response.code == 200){ this.map={ @@ -221,7 +320,7 @@ } }) }, - queryDataCenterMapData:function(){ + queryDataCenterMapData() { let language=localStorage.getItem("nz-language") ? localStorage.getItem("nz-language") : 'en'; let requests=[axios.get('/idc?pageSize=-1'),axios.get('/overview/datacenterStat')]; axios.all(requests).then((result)=>{ @@ -270,12 +369,11 @@ symbolSize=smallScatter; } - console.log(dcStat.name+'-->'+ symbolSize) seriesDatas.push({ name:areaName, value:[areaInfo.longitude,areaInfo.latitude,dcStat], symbolSize:symbolSize, - }) + }); } } } @@ -303,8 +401,81 @@ } }) }, - + queryAlertStatByRule() { + this.$get('overview/alertStatByRule').then(response => { + if (response.code === 200) { + this.$refs.ruleMessage.startLoading(); + let seriesData = []; + let categoryData = []; + response.data.list.forEach(item => { + seriesData.push(item.nums); + categoryData.push(item.alertName); + }); + this.messageByRuleSeries = { + name: 'alertStatByRule', + data: seriesData, + type: 'bar' + }; + this.$refs.ruleMessage.modifyOption('yAxis', 'data', categoryData); + this.$refs.ruleMessage.setSeries(this.messageByRuleSeries); + this.$refs.ruleMessage.endLoading(); + } + }); + }, + queryAlertStatByAsset() { + this.$get('overview/alertStatByAsset').then(response => { + if (response.code === 200) { + this.$refs.assetMessage.startLoading(); + let seriesData = []; + let categoryData = []; + response.data.list.forEach(item => { + seriesData.push(item.nums); + categoryData.push(item.host); + }); + this.messageByAssetSeries = { + name: 'alertStatByAsset', + data: seriesData, + type: 'bar' + }; + this.$refs.assetMessage.modifyOption('yAxis', 'data', categoryData); + this.$refs.assetMessage.setSeries(this.messageByAssetSeries); + this.$refs.assetMessage.endLoading(); + } + }); + }, + queryAlertStatByModule() { + this.$get('overview/alertStatByModule').then(response => { + if (response.code === 200) { + this.$refs.moduleMessage.startLoading(); + let seriesData = []; + let categoryData = []; + response.data.list.forEach(item => { + seriesData.push(item.nums); + categoryData.push(item.module); + }); + this.messageByModuleSeries = { + name: 'alertStatByModule', + data: seriesData, + type: 'bar' + }; + this.$refs.moduleMessage.modifyOption('yAxis', 'data', categoryData); + this.$refs.moduleMessage.setSeries(this.messageByModuleSeries); + this.$refs.moduleMessage.endLoading(); + } + }); + }, /*初始化数据 end*/ + alertMessageChange(type) { + this.bottom3DropdownShow = false; + this.alertMessageShow = type; + this.$nextTick(() => { + if (type == 'asset') { + this.queryAlertStatByAsset(); + } else if (type == 'module') { + this.queryAlertStatByModule(); + } + }); + }, mapTooltipFormatter(params){ let dcStat = params.data.value[2]; @@ -410,6 +581,16 @@ } } }, + alertMessageDropdownHandler(show) { + if (show) { + clearTimeout(timeout); + this.bottom3DropdownShow = true; + } else { + timeout = setTimeout(() => { + this.bottom3DropdownShow = false; + }, 700); + } + }, /*header 时间处理 start*/ initDate:function(){ this.sysTime=this.getTime(); @@ -485,6 +666,14 @@ mounted() { this.initDate(); this.initData(); + window.onresize = () => { + setTimeout(() => { + this.$parent.$parent.update(); + }, 100); + } + }, + destroyed() { + window.onresize = null; } }