CN-1519 fix: 链路配置更改;链路组件逻辑更改;
This commit is contained in:
@@ -88,7 +88,8 @@ $blue: #046ECA;
|
|||||||
.item-popover-header {
|
.item-popover-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
line-height: 32px;
|
padding: 10px 0;
|
||||||
|
line-height: 14px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|
||||||
|
|||||||
@@ -119,11 +119,21 @@ const user = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
axios.get(api.config, { params: { ckey: 'link_info' } }).then(response => {
|
axios.get(`${api.knowledgeBase}/13?pageSize=-1`).then(response => {
|
||||||
const res = response.data
|
const res = response.data
|
||||||
if (response.status === 200 && res.page.list && res.page.list.length > 0) {
|
if (response.status === 200 && res.data.itemList && res.data.itemList.length > 0) {
|
||||||
localStorage.setItem(storageKey.linkInfo, res.page.list[0].cvalue)
|
res.data.itemList.sort((a, b) => {
|
||||||
|
if (a.inLinkId !== b.inLinkId) {
|
||||||
|
return a.inLinkId - b.inLinkId
|
||||||
}
|
}
|
||||||
|
return a.outLinkId - b.outLinkId
|
||||||
|
})
|
||||||
|
localStorage.setItem(storageKey.linkInfo, JSON.stringify(res.data.itemList))
|
||||||
|
} else {
|
||||||
|
localStorage.setItem(storageKey.linkInfo, '')
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
localStorage.setItem(storageKey.linkInfo, '')
|
||||||
})
|
})
|
||||||
axios.get(api.config, { params: { ckey: 'schema_explore' } }).then(response => {
|
axios.get(api.config, { params: { ckey: 'schema_explore' } }).then(response => {
|
||||||
const res = response.data
|
const res = response.data
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export default {
|
|||||||
watch: {
|
watch: {
|
||||||
timeFilter: {
|
timeFilter: {
|
||||||
handler () {
|
handler () {
|
||||||
if (this.$route.path === '/panel/networkAppPerformance') {
|
if (this.$route.path === '/panel/networkAppPerformance' || this.$route.path === '/panel/linkMonitor') {
|
||||||
this.$store.commit('resetScoreBase')
|
this.$store.commit('resetScoreBase')
|
||||||
this.queryScoreBase()
|
this.queryScoreBase()
|
||||||
if (this.lineQueryCondition || this.networkOverviewBeforeTab) {
|
if (this.lineQueryCondition || this.networkOverviewBeforeTab) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #default>
|
<template #default>
|
||||||
<div class="popper-content">
|
<div class="popper-content">
|
||||||
<div class="popper-content__link-id">Link ID: {{ item.linkId }}</div>
|
<div class="popper-content__link-id">Link ID: {{ item.interfaceName }}</div>
|
||||||
<div class="popper-content__link-info">
|
<div class="popper-content__link-info">
|
||||||
<div class="info__label">{{ $t('linkMonitor.linkBlock.total') }}</div>
|
<div class="info__label">{{ $t('linkMonitor.linkBlock.total') }}</div>
|
||||||
<div class="info__value" :test-id="`linkBlockTotal${index}`" style="margin-left: 8px">
|
<div class="info__value" :test-id="`linkBlockTotal${index}`" style="margin-left: 8px">
|
||||||
@@ -122,6 +122,7 @@ import { drillDownPanelTypeMapping, storageKey, unitTypes } from '@/utils/consta
|
|||||||
import { getSecond } from '@/utils/date-util'
|
import { getSecond } from '@/utils/date-util'
|
||||||
import ChartError from '@/components/common/Error'
|
import ChartError from '@/components/common/Error'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import { analysis, analysisOneWay, nextHopAnalysis, nextHopAnalysisOneWay} from './test-data'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'LinkBlock',
|
name: 'LinkBlock',
|
||||||
@@ -166,13 +167,15 @@ export default {
|
|||||||
init () {
|
init () {
|
||||||
this.toggleLoading(true)
|
this.toggleLoading(true)
|
||||||
// 链路基本信息
|
// 链路基本信息
|
||||||
let linkInfo = null
|
let linkConfig = null
|
||||||
linkInfo = localStorage.getItem(storageKey.linkInfo)
|
linkConfig = localStorage.getItem(storageKey.linkInfo)
|
||||||
linkInfo = JSON.parse(linkInfo)
|
linkConfig = JSON.parse(linkConfig)
|
||||||
const params = {
|
const params = {
|
||||||
startTime: getSecond(this.timeFilter.startTime),
|
startTime: getSecond(this.timeFilter.startTime),
|
||||||
endTime: getSecond(this.timeFilter.endTime)
|
endTime: getSecond(this.timeFilter.endTime)
|
||||||
}
|
}
|
||||||
|
// 根据配置判断是否是单向还是双向,只要有一条数据的direction=0或1,就视为双向。
|
||||||
|
const isTwoWay = linkConfig.some(config => config.direction === 0 || config.direction === 1)
|
||||||
|
|
||||||
const dataRequest = axios.get(api.linkMonitor.analysis, { params: params }).catch(e => {
|
const dataRequest = axios.get(api.linkMonitor.analysis, { params: params }).catch(e => {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
@@ -191,37 +194,42 @@ export default {
|
|||||||
if (response[0] && response[1]) {
|
if (response[0] && response[1]) {
|
||||||
const res = []
|
const res = []
|
||||||
res[0] = response[0].data
|
res[0] = response[0].data
|
||||||
|
// res[0] = analysis.data
|
||||||
res[1] = response[1].data
|
res[1] = response[1].data
|
||||||
|
// res[1] = nextHopAnalysis.data
|
||||||
if (response[0].status === 200) {
|
if (response[0].status === 200) {
|
||||||
this.showError1 = false
|
this.showError1 = false
|
||||||
|
|
||||||
const linkData = res[0].data.result
|
const linkData = res[0].data.result
|
||||||
|
|
||||||
this.linkNoData = linkData.length === 0
|
this.linkNoData = linkData.length === 0
|
||||||
if (!this.linkNoData) {
|
if (!this.linkNoData) {
|
||||||
const data = []
|
const data = []
|
||||||
linkData.forEach(d => {
|
linkData.forEach(d => {
|
||||||
const info = linkInfo.find(i => i.originalLinkId === d.linkId)
|
const info = linkConfig.find(i => i.linkId === parseInt(d.linkId))
|
||||||
if (info) {
|
if (info) {
|
||||||
const hit = data.find(d => d.linkId === info.linkId)
|
const hit = data.find(d => d.interfaceName === info.interfaceName)
|
||||||
if (hit) {
|
if (hit) {
|
||||||
hit.outBitsRate += d.outBitsRate
|
hit.outBitsRate += d.outBitsRate
|
||||||
hit.inBitsRate += d.inBitsRate
|
hit.inBitsRate += d.inBitsRate
|
||||||
if (info.direction === 'out') {
|
if (info.direction === 0) {
|
||||||
hit.outBandwidth = info.bandwidth
|
hit.outBandwidth = info.bandwidth
|
||||||
} else if (info.direction === 'in') {
|
} else if (info.direction === 1) {
|
||||||
hit.inBandwidth = info.bandwidth
|
hit.inBandwidth = info.bandwidth
|
||||||
|
} else if (info.direction === 2) {
|
||||||
|
hit.bandwidth = info.bandwidth
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const hit = {
|
const hit = {
|
||||||
linkId: info.linkId,
|
interfaceName: info.interfaceName,
|
||||||
outBitsRate: d.outBitsRate,
|
outBitsRate: d.outBitsRate,
|
||||||
inBitsRate: d.inBitsRate
|
inBitsRate: d.inBitsRate
|
||||||
}
|
}
|
||||||
if (info.direction === 'out') {
|
if (info.direction === 0) {
|
||||||
hit.outBandwidth = info.bandwidth
|
hit.outBandwidth = info.bandwidth
|
||||||
} else if (info.direction === 'in') {
|
} else if (info.direction === 1) {
|
||||||
hit.inBandwidth = info.bandwidth
|
hit.inBandwidth = info.bandwidth
|
||||||
|
} else if (info.direction === 2) {
|
||||||
|
hit.bandwidth = info.bandwidth
|
||||||
}
|
}
|
||||||
data.push(hit)
|
data.push(hit)
|
||||||
}
|
}
|
||||||
@@ -230,11 +238,13 @@ export default {
|
|||||||
this.linkNoData = data.length === 0
|
this.linkNoData = data.length === 0
|
||||||
data.forEach(item => {
|
data.forEach(item => {
|
||||||
item.totalBitsRate = item.outBitsRate + item.inBitsRate
|
item.totalBitsRate = item.outBitsRate + item.inBitsRate
|
||||||
linkInfo.filter(info => info.linkId === item.linkId).forEach(info => {
|
linkConfig.filter(info => info.interfaceName === item.interfaceName).forEach(info => {
|
||||||
if (info.direction === 'out') {
|
if (info.direction === 0) {
|
||||||
item.outLinkId = info.originalLinkId
|
item.outLinkId = info.linkId
|
||||||
} else if (info.direction === 'in') {
|
} else if (info.direction === 1) {
|
||||||
item.inLinkId = info.originalLinkId
|
item.inLinkId = info.linkId
|
||||||
|
} else if (info.direction === 2) {
|
||||||
|
item.linkId = info.linkId
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -243,8 +253,8 @@ export default {
|
|||||||
const linkColors = colorGradientCalculation(this.gradientColor[0], this.gradientColor[1], sorted.map(s => s.totalBitsRate))
|
const linkColors = colorGradientCalculation(this.gradientColor[0], this.gradientColor[1], sorted.map(s => s.totalBitsRate))
|
||||||
sorted.forEach((s, i) => {
|
sorted.forEach((s, i) => {
|
||||||
s.color = linkColors[i]
|
s.color = linkColors[i]
|
||||||
s.outUsage = this.computeUsage(s.outBitsRate, s.outBandwidth)
|
s.outUsage = this.computeUsage(s.outBitsRate, isTwoWay ? s.outBandwidth : s.bandwidth)
|
||||||
s.inUsage = this.computeUsage(s.inBitsRate, s.inBandwidth)
|
s.inUsage = this.computeUsage(s.inBitsRate, isTwoWay ? s.inBandwidth : s.bandwidth)
|
||||||
s.popoverWidth = this.computePopoverWidth(s.outUsage, s.inUsage)
|
s.popoverWidth = this.computePopoverWidth(s.outUsage, s.inUsage)
|
||||||
})
|
})
|
||||||
this.linkData = sorted
|
this.linkData = sorted
|
||||||
@@ -293,17 +303,25 @@ export default {
|
|||||||
nextHopSorted.forEach((s, i) => {
|
nextHopSorted.forEach((s, i) => {
|
||||||
s.color = nextHopColors[i]
|
s.color = nextHopColors[i]
|
||||||
|
|
||||||
let sum = 0
|
let outTotalBandwidth = 0
|
||||||
linkInfo.forEach((item) => {
|
let inTotalBandwidth = 0
|
||||||
if (s.linkDirection === item.nextHop) {
|
let totalBandwidth = 0
|
||||||
sum += item.bandwidth
|
linkConfig.forEach((item) => {
|
||||||
|
if (s.linkDirection === item.peerCity) {
|
||||||
|
if (item.direction === 0) {
|
||||||
|
outTotalBandwidth += item.bandwidth
|
||||||
|
} else if (item.direction === 1) {
|
||||||
|
inTotalBandwidth += item.bandwidth
|
||||||
|
} else if (item.direction === 2) {
|
||||||
|
totalBandwidth += item.bandwidth
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 上行使用情况计算
|
// 上行使用情况计算
|
||||||
const outUsage = this.computeUsage(s.outBitsRate, sum)
|
const outUsage = this.computeUsage(s.outBitsRate, isTwoWay ? outTotalBandwidth : totalBandwidth)
|
||||||
// 下行使用情况计算
|
// 下行使用情况计算
|
||||||
const inUsage = this.computeUsage(s.inBitsRate, sum)
|
const inUsage = this.computeUsage(s.inBitsRate, isTwoWay ? inTotalBandwidth : totalBandwidth)
|
||||||
s.outUsage = outUsage
|
s.outUsage = outUsage
|
||||||
s.inUsage = inUsage
|
s.inUsage = inUsage
|
||||||
s.popoverWidth = this.computePopoverWidth(outUsage, inUsage)
|
s.popoverWidth = this.computePopoverWidth(outUsage, inUsage)
|
||||||
@@ -377,8 +395,8 @@ export default {
|
|||||||
query: {
|
query: {
|
||||||
...this.$route.query,
|
...this.$route.query,
|
||||||
thirdPanel: drillDownPanelTypeMapping.linkMonitor,
|
thirdPanel: drillDownPanelTypeMapping.linkMonitor,
|
||||||
thirdMenu: `Link ID: ${item.linkId}`,
|
thirdMenu: `Link ID: ${item.interfaceName}`,
|
||||||
panelName: `Link ID: ${item.linkId}`,
|
panelName: `Link ID: ${item.interfaceName}`,
|
||||||
queryCondition,
|
queryCondition,
|
||||||
t: +new Date()
|
t: +new Date()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,12 @@
|
|||||||
import chartMixin from '@/views/charts2/chart-mixin'
|
import chartMixin from '@/views/charts2/chart-mixin'
|
||||||
import { getSecond } from '@/utils/date-util'
|
import { getSecond } from '@/utils/date-util'
|
||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
import { storageKey, ZH } from '@/utils/constants'
|
import { storageKey } from '@/utils/constants'
|
||||||
import PopoverContent from './LinkDirectionGrid/PopoverContent'
|
import PopoverContent from './LinkDirectionGrid/PopoverContent'
|
||||||
import { computeScore } from '@/utils/tools'
|
import { computeScore } from '@/utils/tools'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import { bigramAnalysis, bigramAnalysisOneWay, bigramNextHopAnalysis, bigramNextHopAnalysisOneWay } from './test-data'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'LinkDirectionGrid',
|
name: 'LinkDirectionGrid',
|
||||||
@@ -67,23 +68,66 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
init () {
|
init () {
|
||||||
this.scoreDataState = false
|
this.scoreDataState = false
|
||||||
// 链路基本信息
|
// 获取缓存的链路配置
|
||||||
let linkInfo = localStorage.getItem(storageKey.linkInfo)
|
let linkConfig = localStorage.getItem(storageKey.linkInfo)
|
||||||
linkInfo = JSON.parse(linkInfo)
|
if (linkConfig) {
|
||||||
|
linkConfig = JSON.parse(linkConfig)
|
||||||
|
} else {
|
||||||
|
this.isLinkShowError = true
|
||||||
|
this.isNextShowError = true
|
||||||
|
this.isLinkNoData = false
|
||||||
|
this.isNextNoData = false
|
||||||
|
this.linkErrorMsg = this.$t('tip.noLinkKnowledgeBaseFound')
|
||||||
|
this.nextErrorMsg = this.$t('tip.noLinkKnowledgeBaseFound')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 根据配置判断是否是单向还是双向,只要有一条数据的direction=0或1,就视为双向。
|
||||||
|
const isTwoWay = linkConfig.some(config => config.direction === 0 || config.direction === 1)
|
||||||
|
/* 根据链路配置构造数据模型 */
|
||||||
|
// 1.链路数据模型,根据interfaceName属性构造n*n矩阵,根据行列键值进行填充
|
||||||
|
const linkGridData = []
|
||||||
|
const interfaceNames = this.getNames(linkConfig)
|
||||||
|
interfaceNames.forEach(name => {
|
||||||
|
linkGridData.push({
|
||||||
|
interfaceName: name,
|
||||||
|
outList: interfaceNames.map(name1 => {
|
||||||
|
return {
|
||||||
|
interfaceName: name1,
|
||||||
|
noData: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// 2.下一跳数据模型,根据peerCity属性构造n*n矩阵,根据行列键值进行填充
|
||||||
|
const nextGridData = []
|
||||||
|
const cities = this.getCities(linkConfig)
|
||||||
|
cities.forEach(city => {
|
||||||
|
nextGridData.push({
|
||||||
|
peerCity: city,
|
||||||
|
outList: cities.map(city1 => {
|
||||||
|
return {
|
||||||
|
peerCity: city1,
|
||||||
|
noData: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
/* 查数据 */
|
||||||
const params = {
|
const params = {
|
||||||
startTime: getSecond(this.timeFilter.startTime),
|
startTime: getSecond(this.timeFilter.startTime),
|
||||||
endTime: getSecond(this.timeFilter.endTime)
|
endTime: getSecond(this.timeFilter.endTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
const dataRequest = axios.get(api.linkMonitor.bigramAnalysis, { params: params }).catch(e => {
|
const dataRequest = axios.get(api.linkMonitor.bigramAnalysis, { params: params }).catch(e => {
|
||||||
this.isLinkShowError = true
|
this.isLinkShowError = true
|
||||||
this.isLinkNoData = false
|
this.isLinkNoData = false
|
||||||
|
console.error(e)
|
||||||
this.linkErrorMsg = this.errorMsgHandler(e)
|
this.linkErrorMsg = this.errorMsgHandler(e)
|
||||||
})
|
})
|
||||||
const nextHopRequest = axios.get(api.linkMonitor.bigramNextHopAnalysis, { params: params }).catch(e => {
|
const nextHopRequest = axios.get(api.linkMonitor.bigramNextHopAnalysis, { params: params }).catch(e => {
|
||||||
this.isNextShowError = true
|
this.isNextShowError = true
|
||||||
this.isNextNoData = false
|
this.isNextNoData = false
|
||||||
|
console.error(e)
|
||||||
this.nextErrorMsg = this.errorMsgHandler(e)
|
this.nextErrorMsg = this.errorMsgHandler(e)
|
||||||
})
|
})
|
||||||
this.toggleLoading(true)
|
this.toggleLoading(true)
|
||||||
@@ -92,76 +136,53 @@ export default {
|
|||||||
if (response[0].status === 200 && response[1].status === 200) {
|
if (response[0].status === 200 && response[1].status === 200) {
|
||||||
const res = []
|
const res = []
|
||||||
res[0] = response[0].data
|
res[0] = response[0].data
|
||||||
|
// res[0] = bigramAnalysis.data
|
||||||
res[1] = response[1].data
|
res[1] = response[1].data
|
||||||
|
// res[1] = bigramNextHopAnalysis.data
|
||||||
if (response[0].status === 200) {
|
if (response[0].status === 200) {
|
||||||
this.isLinkShowError = false
|
this.isLinkShowError = false
|
||||||
// 链路流量数据
|
// 链路流量数据
|
||||||
const linkData = res[0].data.result
|
const linkData = res[0].data.result
|
||||||
// 接口数据乱序,根据入链路id(inLinkId)大小排序之后,
|
|
||||||
// 再根据同inLinkId下的outLinkId进行排序
|
|
||||||
linkData.sort((a, b) => {
|
|
||||||
if (a.inLinkId !== b.inLinkId) {
|
|
||||||
return a.inLinkId - b.inLinkId
|
|
||||||
}
|
|
||||||
return a.outLinkId - b.outLinkId
|
|
||||||
})
|
|
||||||
|
|
||||||
this.isLinkNoData = linkData.length === 0
|
let isLinkNoData = linkData.length === 0
|
||||||
if (!this.isLinkNoData) {
|
|
||||||
// 链路流量数据
|
|
||||||
const linkGridData = []
|
|
||||||
// 默认构造10*10矩阵,根据行列键值进行填充,最后再删除空行空列
|
|
||||||
linkInfo.forEach(link => {
|
|
||||||
if (link.direction === 'in') {
|
|
||||||
const outList = []
|
|
||||||
linkInfo.forEach(link1 => {
|
|
||||||
if (link1.direction === 'out') {
|
|
||||||
outList.push({ linkId: link1.linkId, noData: true })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
linkGridData.push({ linkId: link.linkId, out: outList })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
if (!isLinkNoData) {
|
||||||
linkData.forEach(d => {
|
linkData.forEach(d => {
|
||||||
const inLink = linkInfo.find(l => l.originalLinkId === d.inLinkId)
|
const inLink = linkConfig.find(l => l.linkId === parseInt(d.inLinkId))
|
||||||
const outLink = linkInfo.find(l => l.originalLinkId === d.outLinkId)
|
const outLink = linkConfig.find(l => l.linkId === parseInt(d.outLinkId))
|
||||||
if (inLink && outLink) {
|
if (inLink && outLink) {
|
||||||
// 上行使用情况计算
|
const row = linkGridData.find(g => g.interfaceName === inLink.interfaceName)
|
||||||
|
if (row) {
|
||||||
|
const outIndex = row.outList.findIndex(o => o.interfaceName === outLink.interfaceName)
|
||||||
|
if (outIndex > -1) {
|
||||||
const outUsage = this.computeUsage(d.outBitsRate, outLink.bandwidth)
|
const outUsage = this.computeUsage(d.outBitsRate, outLink.bandwidth)
|
||||||
// 下行使用情况计算
|
|
||||||
const inUsage = this.computeUsage(d.inBitsRate, inLink.bandwidth)
|
const inUsage = this.computeUsage(d.inBitsRate, inLink.bandwidth)
|
||||||
// 宽带使用超过90%,赋红点
|
row.outList[outIndex] = {
|
||||||
|
|
||||||
d.usageMore90 = outUsage >= 0.9 || inUsage >= 0.9
|
|
||||||
// 计算npm分数
|
|
||||||
// 分数低于3分,赋红点
|
|
||||||
// d.score = this.localComputeScore(d)
|
|
||||||
|
|
||||||
// d.scoreLow3 = d.score < 3 || d.score === '-'
|
|
||||||
|
|
||||||
const xAxis = inLink.linkId.split('Hundredgige').pop() - 1
|
|
||||||
const yAxis = outLink.linkId.split('Hundredgige').pop() - 1
|
|
||||||
linkGridData[xAxis].out[yAxis] = {
|
|
||||||
noData: false,
|
noData: false,
|
||||||
linkId: outLink.linkId,
|
interfaceName: outLink.interfaceName,
|
||||||
outUsage: outUsage,
|
outUsage: outUsage,
|
||||||
inUsage: inUsage,
|
inUsage: inUsage,
|
||||||
|
usageMore90: outUsage >= 0.9 || inUsage >= 0.9,
|
||||||
popoverWidth: this.computeWidth(outUsage, inUsage, 'popover'),
|
popoverWidth: this.computeWidth(outUsage, inUsage, 'popover'),
|
||||||
valueWidth: this.computeWidth(outUsage, inUsage, 'value'),
|
valueWidth: this.computeWidth(outUsage, inUsage, 'value'),
|
||||||
totalBitsRate: d.totalBitsRate,
|
totalBitsRate: d.totalBitsRate,
|
||||||
...d
|
...d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
// 一行如果无数据,则删除该行,默认10*10矩阵
|
|
||||||
this.handleXRowNoData(linkGridData, 0)
|
|
||||||
// 一列如果无数据,则删除该列,默认10*10矩阵
|
|
||||||
this.handleYRowNoData(linkGridData, 0)
|
|
||||||
this.isLinkNoData = linkGridData.length === 0
|
|
||||||
this.linkGridData = linkGridData
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.linkGridData = linkGridData
|
||||||
|
let furtherNoData = true
|
||||||
|
linkGridData.forEach(lg => {
|
||||||
|
const hasData = lg.outList.some(o => o.noData === false)
|
||||||
|
if (hasData) {
|
||||||
|
furtherNoData = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
isLinkNoData = furtherNoData
|
||||||
|
}
|
||||||
|
this.isLinkNoData = isLinkNoData
|
||||||
} else {
|
} else {
|
||||||
this.isLinkNoData = true
|
this.isLinkNoData = true
|
||||||
this.isLinkShowError = true
|
this.isLinkShowError = true
|
||||||
@@ -173,95 +194,61 @@ export default {
|
|||||||
|
|
||||||
// 链路下一跳信息
|
// 链路下一跳信息
|
||||||
const nextLinkData = res[1].data.result
|
const nextLinkData = res[1].data.result
|
||||||
// 接口数据乱序,根据入方向排序,再根据同个入方向下的出方向进行排序
|
|
||||||
nextLinkData.sort((a, b) => {
|
|
||||||
if (a.inLinkDirection !== b.inLinkDirection) {
|
|
||||||
return a.inLinkDirection.localeCompare(b.inLinkDirection, ZH)
|
|
||||||
}
|
|
||||||
return a.outLinkDirection.localeCompare(b.outLinkDirection, ZH)
|
|
||||||
})
|
|
||||||
|
|
||||||
this.isNextNoData = nextLinkData.length === 0
|
let isNextNoData = nextLinkData.length === 0
|
||||||
if (!this.isNextNoData) {
|
if (!isNextNoData) {
|
||||||
// 链路下一跳数据
|
// 链路下一跳数据
|
||||||
let nextGridData = []
|
|
||||||
const nextGridTemplate = [
|
|
||||||
{ linkId: 'Hundredgige2', nextHop: '太原', out: [] },
|
|
||||||
{ linkId: 'Hundredgige1', nextHop: '西安', out: [] },
|
|
||||||
{ linkId: 'Hundredgige4', nextHop: '西宁', out: [] }
|
|
||||||
]
|
|
||||||
nextGridData = JSON.parse(JSON.stringify(nextGridTemplate))
|
|
||||||
nextGridData.forEach(link => {
|
|
||||||
link.out = JSON.parse(JSON.stringify(nextGridTemplate))
|
|
||||||
link.out.forEach(link1 => {
|
|
||||||
link1.noData = true
|
|
||||||
link1.coordinate = `${link.linkId}-${link1.linkId}`
|
|
||||||
delete link1.out
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
nextLinkData.forEach(d => {
|
nextLinkData.forEach(d => {
|
||||||
const inLink = linkInfo.find(l => l.nextHop === d.inLinkDirection && l.direction === 'in')
|
|
||||||
const outLink = linkInfo.find(l => l.nextHop === d.outLinkDirection && l.direction === 'out')
|
|
||||||
|
|
||||||
if (inLink && outLink) {
|
|
||||||
// const data = nextGridData.find(g => g.linkId === inLink.linkId)
|
|
||||||
|
|
||||||
let outBandwidth = 0
|
let outBandwidth = 0
|
||||||
let inBandwidth = 0
|
let inBandwidth = 0
|
||||||
linkInfo.forEach((item) => {
|
let bandwidth = 0
|
||||||
if (item.nextHop === d.outLinkDirection && item.direction === 'out') {
|
linkConfig.forEach((item) => {
|
||||||
|
if (!isTwoWay) {
|
||||||
|
if (item.peerCity === d.outLinkDirection || item.peerCity === d.inLinkDirection) {
|
||||||
|
bandwidth += item.bandwidth
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (item.peerCity === d.outLinkDirection && item.direction === 0) {
|
||||||
outBandwidth += item.bandwidth
|
outBandwidth += item.bandwidth
|
||||||
}
|
}
|
||||||
if (item.nextHop === d.inLinkDirection && item.direction === 'in') {
|
if (item.peerCity === d.inLinkDirection && item.direction === 1) {
|
||||||
inBandwidth += item.bandwidth
|
inBandwidth += item.bandwidth
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 上行使用情况计算
|
const row = nextGridData.find(g => g.peerCity === d.inLinkDirection)
|
||||||
const outUsage = this.computeUsage(d.outBitsRate, outBandwidth)
|
if (row) {
|
||||||
// 下行使用情况计算
|
const outIndex = row.outList.findIndex(o => o.peerCity === d.outLinkDirection)
|
||||||
const inUsage = this.computeUsage(d.inBitsRate, inBandwidth)
|
if (outIndex > -1) {
|
||||||
// 宽带使用超过90%,赋红点
|
// 上行带宽使用情况计算
|
||||||
|
const outUsage = this.computeUsage(d.outBitsRate, isTwoWay ? outBandwidth : bandwidth)
|
||||||
|
// 下行带宽使用情况计算
|
||||||
|
const inUsage = this.computeUsage(d.inBitsRate, isTwoWay ? inBandwidth : bandwidth)
|
||||||
|
|
||||||
d.usageMore90 = outUsage >= 0.9 || inUsage >= 0.9
|
row.outList[outIndex] = {
|
||||||
// 计算npm分数
|
|
||||||
// 分数低于3分,赋红点
|
|
||||||
// d.score = this.localComputeScore(d)
|
|
||||||
|
|
||||||
// d.scoreLow3 = d.score < 3 || d.score === '-'
|
|
||||||
|
|
||||||
const xAxis = inLink.linkId
|
|
||||||
const yAxis = outLink.linkId
|
|
||||||
nextGridData.forEach((link, index) => {
|
|
||||||
link.out.forEach((link1, index1) => {
|
|
||||||
if (link1.coordinate === (xAxis + '-' + yAxis)) {
|
|
||||||
nextGridData[index].out[index1] = {
|
|
||||||
coordinate: link1.coordinate,
|
|
||||||
noData: false,
|
noData: false,
|
||||||
linkId: outLink.linkId,
|
peerCity: d.outLinkDirection,
|
||||||
nextHop: outLink.nextHop,
|
|
||||||
outUsage: outUsage,
|
outUsage: outUsage,
|
||||||
inUsage: inUsage,
|
inUsage: inUsage,
|
||||||
|
usageMore90: outUsage >= 0.9 || inUsage >= 0.9, // 宽带使用超过90%,赋红点
|
||||||
popoverWidth: this.computeWidth(outUsage, inUsage, 'popover'),
|
popoverWidth: this.computeWidth(outUsage, inUsage, 'popover'),
|
||||||
valueWidth: this.computeWidth(outUsage, inUsage, 'value'),
|
valueWidth: this.computeWidth(outUsage, inUsage, 'value'),
|
||||||
totalBitsRate: d.totalBitsRate,
|
totalBitsRate: d.totalBitsRate,
|
||||||
...d
|
...d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 一行如果无数据,则删除该行,默认3*3矩阵
|
|
||||||
this.handleXRowNoData(nextGridData, 0)
|
|
||||||
// 一列如果无数据,则删除该列,默认3*3矩阵
|
|
||||||
this.handleYRowNoData(nextGridData, 0)
|
|
||||||
|
|
||||||
this.isNextNoData = nextGridData.length === 0
|
|
||||||
this.nextGridData = nextGridData
|
this.nextGridData = nextGridData
|
||||||
|
nextGridData.forEach(lg => {
|
||||||
|
const hasData = lg.outList.some(o => o.noData === false)
|
||||||
|
if (hasData) {
|
||||||
|
isNextNoData = false
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.isNextNoData = isNextNoData
|
||||||
} else {
|
} else {
|
||||||
this.isNextNoData = true
|
this.isNextNoData = true
|
||||||
this.isNextShowError = true
|
this.isNextShowError = true
|
||||||
@@ -300,8 +287,8 @@ export default {
|
|||||||
},
|
},
|
||||||
handleScoreData (data) {
|
handleScoreData (data) {
|
||||||
data.forEach(d => {
|
data.forEach(d => {
|
||||||
if (d.out) {
|
if (d.outList) {
|
||||||
d.out.forEach(t => {
|
d.outList.forEach(t => {
|
||||||
const data = {
|
const data = {
|
||||||
establishLatencyMs: t.establishLatencyMs,
|
establishLatencyMs: t.establishLatencyMs,
|
||||||
httpResponseLatency: t.httpResponseLatency,
|
httpResponseLatency: t.httpResponseLatency,
|
||||||
@@ -394,6 +381,22 @@ export default {
|
|||||||
this.handleYRowNoData(data, index + 1)
|
this.handleYRowNoData(data, index + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
// linkConfig去重获取name
|
||||||
|
getNames (linkConfig) {
|
||||||
|
const names = new Set()
|
||||||
|
linkConfig.forEach(c => {
|
||||||
|
names.add(c.interfaceName)
|
||||||
|
})
|
||||||
|
return Array.from(names)
|
||||||
|
},
|
||||||
|
// linkConfig去重获取city
|
||||||
|
getCities (linkConfig) {
|
||||||
|
const cities = new Set()
|
||||||
|
linkConfig.forEach(c => {
|
||||||
|
cities.add(c.peerCity)
|
||||||
|
})
|
||||||
|
return Array.from(cities)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,19 +8,19 @@
|
|||||||
|
|
||||||
<div class="data-grid" v-show="!isNoData && !showError">
|
<div class="data-grid" v-show="!isNoData && !showError">
|
||||||
<div class="egress-row" v-if="gridData[0]">
|
<div class="egress-row" v-if="gridData[0]">
|
||||||
<div class="egress-id" v-for="(item, index) in gridData[0].out" :key="index">
|
<div class="egress-id" v-for="(item, index) in gridData[0].outList" :key="index">
|
||||||
<!--兼容下一跳情况-->
|
<!--兼容下一跳情况-->
|
||||||
<span v-if="item.nextHop">{{ item.nextHop }}</span>
|
<span v-if="item.peerCity">{{ item.peerCity }}</span>
|
||||||
<span v-else>{{ item.linkId }}</span>
|
<span v-else>{{ item.interfaceName}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row" v-for="(row, index2) in gridData" :key="index2">
|
<div class="data-row" v-for="(row, index2) in gridData" :key="index2">
|
||||||
<div class="ingress-id">
|
<div class="ingress-id">
|
||||||
<!--兼容下一跳情况-->
|
<!--兼容下一跳情况-->
|
||||||
<span v-if="row.nextHop">{{ row.nextHop }}</span>
|
<span v-if="row.peerCity">{{ row.peerCity }}</span>
|
||||||
<span v-else>{{ row.linkId }}</span>
|
<span v-else>{{ row.interfaceName }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-for="(item, index3) in row.out" :key="index3">
|
<div v-for="(item, index3) in row.outList" :key="index3">
|
||||||
|
|
||||||
<el-popover v-if="!item.noData" :width="437" placement="right" trigger="hover">
|
<el-popover v-if="!item.noData" :width="437" placement="right" trigger="hover">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
@@ -34,13 +34,13 @@
|
|||||||
<template #default>
|
<template #default>
|
||||||
<div class="item-popover-header">
|
<div class="item-popover-header">
|
||||||
<!--兼容下一跳情况-->
|
<!--兼容下一跳情况-->
|
||||||
<span v-if="row.nextHop" :test-id="`toNextHop${index2+1}`">{{ row.nextHop }}</span>
|
<span v-if="row.peerCity" :test-id="`toNextHop${index2+1}`">{{ row.peerCity }}</span>
|
||||||
<span v-else :test-id="`fromLinkId${index2+1}`">{{ row.linkId }}</span>
|
<span v-else :test-id="`fromLinkId${index2+1}`">{{ row.interfaceName }}</span>
|
||||||
<svg class="icon item-popover-header-icon" aria-hidden="true">
|
<svg class="icon item-popover-header-icon" aria-hidden="true">
|
||||||
<use xlink:href="#cn-icon-arrow-right2"></use>
|
<use xlink:href="#cn-icon-arrow-right2"></use>
|
||||||
</svg>
|
</svg>
|
||||||
<span v-if="row.nextHop" :test-id="`toNextHop${index3+1}`">{{ item.outLinkDirection }}</span>
|
<span v-if="row.peerCity" :test-id="`toNextHop${index3+1}`">{{ item.peerCity }}</span>
|
||||||
<span v-else :test-id="`toLinkId${index3+1}`">{{ item.linkId }}</span>
|
<span v-else :test-id="`toLinkId${index3+1}`">{{ item.interfaceName }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="item-popover-block">
|
<div class="item-popover-block">
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import { valueToRangeValue } from '@/utils/unit-convert'
|
|||||||
import { storageKey, unitTypes } from '@/utils/constants'
|
import { storageKey, unitTypes } from '@/utils/constants'
|
||||||
import ChartError from '@/components/common/Error'
|
import ChartError from '@/components/common/Error'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import { quadrupleIngressAnalysis } from './test-data'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'LinksTrafficSankey',
|
name: 'LinksTrafficSankey',
|
||||||
@@ -116,6 +117,7 @@ export default {
|
|||||||
this.toggleLoading(true)
|
this.toggleLoading(true)
|
||||||
axios.get(url, { params }).then(response => {
|
axios.get(url, { params }).then(response => {
|
||||||
const res = response.data
|
const res = response.data
|
||||||
|
// const res = quadrupleIngressAnalysis.ingress.data
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
this.showError = false
|
this.showError = false
|
||||||
let noData
|
let noData
|
||||||
@@ -166,9 +168,9 @@ export default {
|
|||||||
if (tab === 0) {
|
if (tab === 0) {
|
||||||
result.forEach(t => {
|
result.forEach(t => {
|
||||||
this.cnLinkInfo.forEach(e => {
|
this.cnLinkInfo.forEach(e => {
|
||||||
if (t.commonInLinkId === e.originalLinkId) {
|
if (parseInt(t.commonInLinkId) === e.linkId) {
|
||||||
t.linkId = e.linkId
|
t.linkId = e.interfaceName
|
||||||
t.linkDirection = e.nextHop
|
t.linkDirection = e.peerCity
|
||||||
t.bandwidth = e.bandwidth
|
t.bandwidth = e.bandwidth
|
||||||
t.originalValue = _.round(Number(t.inBitsRate), 2)
|
t.originalValue = _.round(Number(t.inBitsRate), 2)
|
||||||
t.value = _.round(Number(t.drawInBitsRate), 2)
|
t.value = _.round(Number(t.drawInBitsRate), 2)
|
||||||
@@ -180,10 +182,10 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
result.forEach(t => {
|
result.forEach(t => {
|
||||||
this.cnLinkInfo.forEach(e => {
|
this.cnLinkInfo.forEach(e => {
|
||||||
if (t.commonOutLinkId === e.originalLinkId) {
|
if (parseInt(t.commonOutLinkId) === e.linkId) {
|
||||||
t.linkId = e.linkId
|
t.linkId = e.interfaceName
|
||||||
t.bandwidth = e.bandwidth
|
t.bandwidth = e.bandwidth
|
||||||
t.linkDirection = e.nextHop
|
t.linkDirection = e.peerCity
|
||||||
t.originalValue = _.round(Number(t.outBitsRate), 2)
|
t.originalValue = _.round(Number(t.outBitsRate), 2)
|
||||||
t.value = _.round(Number(t.drawOutBitsRate), 2)
|
t.value = _.round(Number(t.drawOutBitsRate), 2)
|
||||||
t.external = `e_${t.externalLocation}`
|
t.external = `e_${t.externalLocation}`
|
||||||
|
|||||||
Reference in New Issue
Block a user