CN-738: 蜂窝图开发

This commit is contained in:
刘洪洪
2022-09-30 14:16:23 +08:00
parent 2e7720e19f
commit a1c26c9179
5 changed files with 207 additions and 68 deletions

View File

@@ -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
}
}
})
}

View File

@@ -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',

View File

@@ -1,55 +1,55 @@
<template>
<div class="link-blocks">
<!--<el-tabs v-model="tab">
<el-tab-pane :label="$t('linkMonitor.links')" :name="0"></el-tab-pane>
<el-tab-pane :label="$t('linkMonitor.nextHopInternet')" :name="1"></el-tab-pane>
</el-tabs>
<div class="block-list">
<el-popover
placement="bottom"
trigger="hover"
popper-class="link-block__popper"
v-for="(item, index) in linkData"
:width="220"
:key="index"
>
<template #reference>
<div class="link-block" :style="`background-color: ${item.color}`"></div>
</template>
<template #default>
<div class="popper-content">
<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>
<div class="popper-content__link-info">
<div class="info__label">{{$t('linkMonitor.linkBlock.bandwidthUsage')}}</div>
<div class="info__value">50%</div>
</div>
</div>
</template>
</el-popover>
</div>
<div class="block-heat-legend">
<div class="legend__box">
<div class="legend__value">
<span>0</span>
<span>90%</span>
<!--<el-tabs v-model="tab">
<el-tab-pane :label="$t('linkMonitor.links')" :name="0"></el-tab-pane>
<el-tab-pane :label="$t('linkMonitor.nextHopInternet')" :name="1"></el-tab-pane>
</el-tabs>
<div class="block-list">
<el-popover
placement="bottom"
trigger="hover"
popper-class="link-block__popper"
v-for="(item, index) in linkData"
:width="220"
:key="index"
>
<template #reference>
<div class="link-block" :style="`background-color: ${item.color}`"></div>
</template>
<template #default>
<div class="popper-content">
<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>
<div class="popper-content__link-info">
<div class="info__label">{{$t('linkMonitor.linkBlock.bandwidthUsage')}}</div>
<div class="info__value">50%</div>
</div>
</div>
</template>
</el-popover>
</div>
<div class="legend__color-piece"></div>
<div class="legend__desc">{{$t('linkMonitor.linkBlock.bandwidthUsage')}}</div>
</div>
</div> -->
<div class="block-heat-legend">
<div class="legend__box">
<div class="legend__value">
<span>0</span>
<span>90%</span>
</div>
<div class="legend__color-piece"></div>
<div class="legend__desc">{{$t('linkMonitor.linkBlock.bandwidthUsage')}}</div>
</div>
</div> -->
<div class="block-list">
<div class="block-list__title">{{$t('linkMonitor.links')}}</div>
<div class="block-list__title">{{ $t('linkMonitor.links') }}</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"
:width="285"
:key="index"
>
<template #reference>
@@ -61,29 +61,46 @@
</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.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__label">{{ $t('linkMonitor.linkBlock.total') }}</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__label">{{ $t('linkMonitor.linkBlock.bandwidthUsage') }}</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">
<div class="block-list__title">{{$t('linkMonitor.nextHopInternet')}}</div>
<!--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__label">{{ $t('linkMonitor.linkBlock.total') }}</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__label">{{ $t('linkMonitor.linkBlock.bandwidthUsage') }}</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
}
}
}

View File

@@ -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
}
})

View File

@@ -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>