CN-738: 蜂窝图开发
This commit is contained in:
@@ -146,4 +146,34 @@ if (openMock) {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Mock.mock(new RegExp(BASE_CONFIG.baseUrl + 'interface/linkMonitor/analysis1.*'), 'get', function (requestObj) {
|
||||
const linkData = []
|
||||
for (let i = 0; i < 10; i++) {
|
||||
linkData.push({ linkId: 'Hundredgige' + (i + 1), egressBytes: Math.floor(Math.pow(1.3, i) * 1000000000), ingressBytes: Math.floor(Math.pow(1.5, i) * 1000000000) })
|
||||
}
|
||||
return {
|
||||
msg: 'success',
|
||||
code: 200,
|
||||
data: {
|
||||
result: linkData
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Mock.mock(new RegExp(BASE_CONFIG.baseUrl + 'interface/linkMonitor/nextHopAnalysis1.*'), 'get', function (requestObj) {
|
||||
const linkData = [
|
||||
{ linkDirection: '西安', egressBytes: 1024000000000, ingressBytes: 1224000000000 },
|
||||
{ linkDirection: '太原', egressBytes: 102400000000, ingressBytes: 142400000000 },
|
||||
{ linkDirection: '西宁', egressBytes: 1024000000, ingressBytes: 1024000000 }
|
||||
]
|
||||
|
||||
return {
|
||||
msg: 'success',
|
||||
code: 200,
|
||||
data: {
|
||||
result: linkData
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -206,8 +206,13 @@ export const api = {
|
||||
quadrupleEgressAnalysis: '/interface/link/overview/quadrupleEgressAnalysis', // 出口
|
||||
bigramAnalysis: '/interface/link/overview/bigramAnalysis',
|
||||
bigramNextHopAnalysis: '/interface/link/overview/bigramNextHopAnalysis',
|
||||
analysis: '/interface/link/overview/analysis',
|
||||
nextHopAnalysis: '/interface/link/overview/nextHopAnalysis',
|
||||
// todo 以下几个接口因接口返回数据为空,故造模拟接口平替
|
||||
bigramAnalysis1: 'interface/linkMonitor/bigramAnalysis1',
|
||||
bigramNextHopAnalysis1: '/interface/linkMonitor/bigramNextHopAnalysis1'
|
||||
bigramNextHopAnalysis1: '/interface/linkMonitor/bigramNextHopAnalysis1',
|
||||
analysis1: '/interface/linkMonitor/analysis1',
|
||||
nextHopAnalysis1: '/interface/linkMonitor/nextHopAnalysis1'
|
||||
},
|
||||
dnsInsight: {
|
||||
recentEvents: '/interface/dnsInsight/recentEvents',
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
trigger="hover"
|
||||
popper-class="link-block__popper"
|
||||
v-for="(item, index) in linkData"
|
||||
:width="220"
|
||||
:width="285"
|
||||
:key="index"
|
||||
>
|
||||
<template #reference>
|
||||
@@ -64,26 +64,43 @@
|
||||
<div class="popper-content__link-id">Link ID: {{ item.linkId }}</div>
|
||||
<div class="popper-content__link-info">
|
||||
<div class="info__label">{{ $t('linkMonitor.linkBlock.total') }}</div>
|
||||
<div class="info__value">{{unitConvert(item.totalBitsRate, unitTypes.bps).join('')}}</div>
|
||||
<div class="info__value" style="margin-left: 8px">
|
||||
{{ unitConvert(item.totalBitsRate, unitTypes.bps).join('') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="popper-content__link-info">
|
||||
<div class="info__label">{{ $t('linkMonitor.linkBlock.bandwidthUsage') }}</div>
|
||||
<div class="info__value">50%</div>
|
||||
<div class="info__value" style="display: flex">
|
||||
<div>
|
||||
<svg class="icon item-popover-up" aria-hidden="true">
|
||||
<use xlink:href="#cn-icon-egress"></use>
|
||||
</svg>
|
||||
{{ unitConvert(item.egressUsage, unitTypes.percent).join('') }}
|
||||
</div>
|
||||
<div>
|
||||
<svg class="icon item-popover-down" aria-hidden="true">
|
||||
<use xlink:href="#cn-icon-ingress"></use>
|
||||
</svg>
|
||||
{{ unitConvert(item.ingressUsage, unitTypes.percent).join('') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="block-list">
|
||||
<!--todo 此处应将linkid改成nextHop显示-->
|
||||
<div class="block-list__title">{{ $t('linkMonitor.nextHopInternet') }}</div>
|
||||
<div class="block-list__list">
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
trigger="hover"
|
||||
popper-class="link-block__popper"
|
||||
v-for="(item, index) in linkData"
|
||||
:width="220"
|
||||
v-for="(item, index) in nextHopData"
|
||||
:width="285"
|
||||
:key="index"
|
||||
>
|
||||
<template #reference>
|
||||
@@ -95,14 +112,29 @@
|
||||
</template>
|
||||
<template #default>
|
||||
<div class="popper-content">
|
||||
<div class="popper-content__link-id">Link ID: {{item.linkId}}</div>
|
||||
<div class="popper-content__link-id">Link ID: {{ item.linkDirection }}</div>
|
||||
<div class="popper-content__link-info">
|
||||
<div class="info__label">{{ $t('linkMonitor.linkBlock.total') }}</div>
|
||||
<div class="info__value">{{unitConvert(item.totalBitsRate, unitTypes.bps).join('')}}</div>
|
||||
<div class="info__value" style="margin-left: 8px">
|
||||
{{ unitConvert(item.totalBitsRate, unitTypes.bps).join('') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="popper-content__link-info">
|
||||
<div class="info__label">{{ $t('linkMonitor.linkBlock.bandwidthUsage') }}</div>
|
||||
<div class="info__value">50%</div>
|
||||
<div class="info__value" style="display: flex">
|
||||
<div>
|
||||
<svg class="icon item-popover-up" aria-hidden="true">
|
||||
<use xlink:href="#cn-icon-egress"></use>
|
||||
</svg>
|
||||
{{ unitConvert(item.egressUsage, unitTypes.percent).join('') }}
|
||||
</div>
|
||||
<div>
|
||||
<svg class="icon item-popover-down" aria-hidden="true">
|
||||
<use xlink:href="#cn-icon-ingress"></use>
|
||||
</svg>
|
||||
{{ unitConvert(item.ingressUsage, unitTypes.percent).join('') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -121,7 +153,8 @@ import { get } from '@/utils/http'
|
||||
import { api } from '@/utils/api'
|
||||
import { colorGradientCalculation } from '@/utils/tools'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
import { storageKey, unitTypes } from '@/utils/constants'
|
||||
import { getSecond } from '@/utils/date-util'
|
||||
|
||||
export default {
|
||||
name: 'LinkBlock',
|
||||
@@ -133,7 +166,9 @@ export default {
|
||||
return {
|
||||
unitTypes,
|
||||
linkData: [],
|
||||
gradientColor: ['#FF005C', '#40537E'] // [start, end]
|
||||
nextHopData: [],
|
||||
gradientColor: ['#FF005C', '#40537E'], // [start, end]
|
||||
gradientColor1: ['#793973', '#654277', '#40537E'] // [start, end]
|
||||
}
|
||||
},
|
||||
setup () {
|
||||
@@ -143,6 +178,14 @@ export default {
|
||||
tab
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
timeFilter: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.init()
|
||||
},
|
||||
@@ -150,18 +193,73 @@ export default {
|
||||
unitConvert,
|
||||
init () {
|
||||
this.toggleLoading(true)
|
||||
get(api.linkMonitor.links).then(res => {
|
||||
if (res.code === 200) {
|
||||
this.isNoData = res.data.result.length === 0
|
||||
// 链路基本信息
|
||||
let linkInfo = localStorage.getItem(storageKey.linkInfo)
|
||||
linkInfo = JSON.parse(linkInfo)
|
||||
const params = {
|
||||
startTime: getSecond(this.timeFilter.startTime),
|
||||
endTime: getSecond(this.timeFilter.endTime)
|
||||
}
|
||||
|
||||
const dataRequest = get(api.linkMonitor.analysis1, params)
|
||||
const nextHopRequest = get(api.linkMonitor.nextHopAnalysis1, params)
|
||||
|
||||
Promise.all([dataRequest, nextHopRequest]).then(res => {
|
||||
if (res[0].code === 200 && res[1].code === 200) {
|
||||
const data = res[0].data.result
|
||||
const nextHopData = res[1].data.result
|
||||
this.isNoData = data.length === 0
|
||||
if (this.isNoData) {
|
||||
return
|
||||
}
|
||||
const sorted = res.data.result.sort((a, b) => b.totalBitsRate - a.totalBitsRate)
|
||||
|
||||
data.forEach((item) => {
|
||||
item.totalBitsRate = item.egressBytes + item.ingressBytes
|
||||
})
|
||||
|
||||
nextHopData.forEach((item) => {
|
||||
item.totalBitsRate = item.egressBytes + item.ingressBytes
|
||||
})
|
||||
|
||||
const sorted = data.sort((a, b) => b.totalBitsRate - a.totalBitsRate)
|
||||
const colors = colorGradientCalculation(this.gradientColor[0], this.gradientColor[1], sorted.map(s => s.totalBitsRate))
|
||||
sorted.forEach((s, i) => {
|
||||
s.color = colors[i]
|
||||
|
||||
const ingressLink = linkInfo.find(l => l.linkId === s.linkId && l.direction === 'ingress')
|
||||
const egressLink = linkInfo.find(l => l.linkId === s.linkId && l.direction === 'egress')
|
||||
if (ingressLink && egressLink) {
|
||||
// 上行使用情况计算
|
||||
const egressUsage = this.computeUsage(s.egressBytes, egressLink.bandwidth)
|
||||
// 下行使用情况计算
|
||||
const ingressUsage = this.computeUsage(s.ingressBytes, ingressLink.bandwidth)
|
||||
s.egressUsage = egressUsage
|
||||
s.ingressUsage = ingressUsage
|
||||
}
|
||||
})
|
||||
this.linkData = sorted
|
||||
|
||||
const nextHopSorted = nextHopData.sort((a, b) => b.totalBitsRate - a.totalBitsRate)
|
||||
|
||||
nextHopSorted.forEach((s, i) => {
|
||||
s.color = this.gradientColor1[i]
|
||||
|
||||
let sum = 0
|
||||
linkInfo.forEach((item) => {
|
||||
if (s.linkDirection === item.nextHop) {
|
||||
sum += item.bandwidth
|
||||
}
|
||||
})
|
||||
|
||||
// 上行使用情况计算
|
||||
const egressUsage = this.computeUsage(s.egressBytes, sum)
|
||||
// 下行使用情况计算
|
||||
const ingressUsage = this.computeUsage(s.ingressBytes, sum)
|
||||
s.egressUsage = egressUsage
|
||||
s.ingressUsage = ingressUsage
|
||||
})
|
||||
|
||||
this.nextHopData = nextHopSorted
|
||||
} else {
|
||||
this.isNoData = true
|
||||
}
|
||||
@@ -171,6 +269,16 @@ export default {
|
||||
}).finally(() => {
|
||||
this.toggleLoading(false)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 计算上下行使用占比
|
||||
*/
|
||||
computeUsage (e, bandwidth) {
|
||||
let usage = e / bandwidth
|
||||
if (usage >= 1) {
|
||||
usage = 1
|
||||
}
|
||||
return usage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,6 @@ export default {
|
||||
const linkData = res[0].data.result
|
||||
// 链路下一跳信息
|
||||
const nextLinkData = res[1].data.result
|
||||
console.log('接口的下一跳数据', nextLinkData)
|
||||
|
||||
// 链路流量数据
|
||||
const gridData = []
|
||||
@@ -77,7 +76,7 @@ export default {
|
||||
// 上行使用情况计算
|
||||
const egressUsage = this.computeUsage(d.egressBytes, egressLink.bandwidth)
|
||||
// 下行使用情况计算
|
||||
const ingressUsage = this.computeUsage(d.ingressBytes, egressLink.bandwidth)
|
||||
const ingressUsage = this.computeUsage(d.ingressBytes, ingressLink.bandwidth)
|
||||
// 宽带使用超过90%,赋红点
|
||||
d.usageMore90 = false
|
||||
if (egressUsage >= 0.9 || ingressUsage >= 0.9) {
|
||||
@@ -116,7 +115,7 @@ export default {
|
||||
}
|
||||
}
|
||||
})
|
||||
console.log('左侧出入链路数据', gridData)
|
||||
|
||||
this.gridData = gridData
|
||||
|
||||
nextLinkData.forEach(d => {
|
||||
@@ -182,7 +181,6 @@ export default {
|
||||
}
|
||||
}
|
||||
})
|
||||
console.log('右侧下一跳数据', gridData2)
|
||||
this.gridData2 = gridData2
|
||||
}
|
||||
})
|
||||
|
||||
@@ -55,14 +55,12 @@
|
||||
<svg class="icon item-popover-up" aria-hidden="true">
|
||||
<use xlink:href="#cn-icon-egress"></use>
|
||||
</svg>
|
||||
<!-- {{ row.egress[index2].egressUsage }}%-->
|
||||
{{ unitConvert(row.egress[index2].egressUsage, unitTypes.percent).join('') }}
|
||||
</div>
|
||||
<div>
|
||||
<svg class="icon item-popover-down" aria-hidden="true">
|
||||
<use xlink:href="#cn-icon-ingress"></use>
|
||||
</svg>
|
||||
<!-- {{ row.egress[index2].ingressUsage }}%-->
|
||||
{{ unitConvert(row.egress[index2].ingressUsage, unitTypes.percent).join('') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user