This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
cyber-narrator-cn-ui/src/views/charts/PanelChart.vue

466 lines
17 KiB
Vue
Raw Normal View History

2022-01-16 23:16:00 +08:00
<template>
<!-- chart外层箱子 -->
<div
2022-02-08 12:01:47 +08:00
:class="{'panel-chart--fullscreen': isFullscreen, 'panel-chart--title-chart': isTitle, 'panel-chart-group': isGroup,'panel-chart-table': isTable}"
class="panel-chart"
:id="isFullscreen ? ('chart-screen-' + chartInfo.id ) : ('chart-local-' + chartInfo.id)"
>
2022-01-16 23:16:00 +08:00
<!-- title和工具栏支持浮动 -->
<chart-header
v-if="!isFullscreen && showHeader && !isSingleValue && !isTabs && !isDetectionSecurity && !isDetectionService"
2022-01-16 23:16:00 +08:00
:is-error="isError"
:error-info="errorInfo"
:chart-data="chartData"
:chart-info="chartInfo"
2022-01-19 15:54:27 +08:00
:table="table"
:order-pie-table="orderPieTable"
2022-01-16 23:16:00 +08:00
@loadMore="loadMore"
@refresh="refresh"
@tabHandleClick="tabHandleClick"
2022-01-21 15:35:09 +08:00
@groupShow="groupShow"
2022-01-16 23:16:00 +08:00
@showFullscreen="showFullscreen"
2022-01-19 15:54:27 +08:00
@tableChange="tableChange"
@orderPieTableChange="orderPieTableChange"
2022-01-16 23:16:00 +08:00
></chart-header>
<!-- chart -->
<!-- 数据查询后传入chart组件chart组件内不查询只根据接传递的数据来渲染 -->
<chart
ref="chart"
2022-03-27 13:04:47 +08:00
v-if="(!isGroup || !(chartInfo.params && chartInfo.params.collapse)) && !isTitle "
2022-01-16 23:16:00 +08:00
:chart-data="chartData"
:result-type="resultType"
2022-01-16 23:16:00 +08:00
:chart-info="chartInfo"
:query-params="queryParams"
:panel-lock="panelLock"
:is-error="isError"
:loading="loading"
:entity="entity"
2022-01-19 15:54:27 +08:00
:table="table"
2022-01-16 23:16:00 +08:00
:is-fullscreen="isFullscreen"
:order-pie-table="orderPieTable"
:need-timeout="needTimeout"
:time-filter="timeFilter"
@getChartData="getChartData"
2022-01-16 23:16:00 +08:00
@showLoading="showLoading"
:tabHandleClickType="tabHandleClickType"
2022-01-16 23:16:00 +08:00
></chart>
</div>
</template>
<script>
import ChartHeader from './ChartHeader'
2022-02-14 17:40:29 +08:00
import Chart from '@/views/charts/Chart'
import { dnsServerRole, chartPieTableTopOptions, chartTableDefaultPageSize, chartTableTopOptions } from '@/utils/constants'
2022-01-16 23:16:00 +08:00
import {
isEcharts,
isSingleValue,
isTable,
isBasicTable,
2022-01-16 23:16:00 +08:00
isActiveIpTable,
isTitle,
isMap,
isEchartsWithTable,
isEchartsWithStatistics,
isEchartsTimeBar,
isEchartsCategoryBar,
isMapLine,
isMapBlock,
isSingleValueWithEcharts,
2022-03-27 13:04:47 +08:00
isSingleValueWithPercent,
2022-01-16 23:16:00 +08:00
isRelationShip,
isTabs,
isGroup,
isSankey,
isIpBasicInfo,
2022-03-27 13:04:47 +08:00
isIpOpenPortBar,
2022-01-16 23:16:00 +08:00
isIpHostedDomain,
isDomainWhois,
isDomainDnsRecord,
isCryptocurrencyEventList,
isAppBasicInfo,
isAppRelatedDomain,
isBlock,
isAlarmInfo,
isDetectionSecurity,
isDetectionService
2022-01-16 23:16:00 +08:00
} from './charts/tools'
2022-02-14 17:40:29 +08:00
import { tableTitleMapping, legendMapping } from '@/views/charts/charts/chart-table-title'
2022-01-16 23:16:00 +08:00
import { replaceUrlPlaceholder } from '@/utils/tools'
import { getNowTime, getSecond } from '@/utils/date-util'
import axios from 'axios'
2022-01-16 23:16:00 +08:00
import { ref } from 'vue'
import _ from 'lodash'
2022-01-16 23:16:00 +08:00
export default {
name: 'PanelChart',
components: {
ChartHeader,
Chart
},
props: {
chartInfo: Object, // 其中的param json串已转化为对象
timeFilter: Object, // 时间范围
isFullscreen: Boolean,
panelLock: Boolean,
entity: Object,
needTimeout: Boolean
2022-01-16 23:16:00 +08:00
},
data () {
return {
chartData: null, // 图表要渲染的数据请求接口得到传入chart组件chart组件内除特别情况(多级)外不做查询
resultType: null, // 返回数据的类型
2022-01-16 23:16:00 +08:00
loading: false,
isError: false, // 接口响应是否报错
errorInfo: '', // 接口具体错误信息
queryTimeRange: { // 实际查询接口时使用的时间
startTime: '',
endTime: ''
},
queryParams: {},
standaloneTimeRange: { // 单个图表刷新时,重新获取时间范围,且不影响到其他图表
use: false,
startTime: '',
endTime: ''
},
orderPieTable: chartPieTableTopOptions[0].value,
// 挖矿右下角图
activeIpTable: {
orderBy: 'machine',
tableData: [
{
name: '192.168.20.21',
num: 111
}, {
name: '192.168.20.22',
num: 345
}, {
name: '192.168.20.23',
num: 111
}, {
name: '192.168.20.24',
num: 345
}, {
name: '192.168.20.25',
num: 111
}, {
name: '192.168.20.26',
num: 345
}
] // table的所有数据
},
tabHandleClickType: '',
firstRender: true
2022-01-16 23:16:00 +08:00
}
},
computed: {
headerH () {
return this.$store.getters.getHeaderH
},
headerHPadding () {
return this.$store.getters.getHeaderHPadding
2022-04-06 14:48:46 +08:00
},
showHeader () {
return this.chartInfo.params && this.chartInfo.params.showHeader
2022-01-16 23:16:00 +08:00
}
},
methods: {
reload () {
this.standaloneTimeRange.use = false
this.getChartData()
},
/* 参数 extraParams 额外请求参数 */
getChartData (url, extraParams = {}, chartTimeFilter, isRefresh) {
2022-01-16 23:16:00 +08:00
this.loading = true
try {
if (chartTimeFilter) {
// 图表自带timeFilter刷新时
this.queryTimeRange = { startTime: getSecond(chartTimeFilter.startTime), endTime: getSecond(chartTimeFilter.endTime), dateRangeValue: chartTimeFilter.dateRangeValue }
} else if (this.standaloneTimeRange.use) {
// 单个图表刷新时,使用单独的时间
this.queryTimeRange = { startTime: getSecond(this.standaloneTimeRange.startTime), endTime: getSecond(this.standaloneTimeRange.endTime), dateRangeValue: this.timeFilter.dateRangeValue }
2022-01-16 23:16:00 +08:00
} else if (this.timeFilter) {
this.queryTimeRange = { startTime: getSecond(this.timeFilter.startTime), endTime: getSecond(this.timeFilter.endTime), dateRangeValue: this.timeFilter.dateRangeValue }
2022-01-16 23:16:00 +08:00
} else {
this.queryTimeRange = { startTime: getSecond(this.chartTimeFilter.startTime), endTime: getSecond(this.chartTimeFilter.endTime), dateRangeValue: this.chartTimeFilter.dateRangeValue }
2022-01-16 23:16:00 +08:00
}
const chartParams = this.chartInfo.params
2022-03-31 14:49:32 +08:00
if (this.isAlarmInfo && JSON.stringify(extraParams) === '{}') {
extraParams = {
pageNo: 1,
pageSize: 9
}
}
if ((this.isDetectionService || this.isDetectionSecurity) && JSON.stringify(extraParams) === '{}') {
extraParams = {
pageNo: 1,
pageSize: 6
}
}
2022-01-16 23:16:00 +08:00
// 接口查询参数
this.queryParams = {
...this.handleQueryParams(),
...this.queryTimeRange,
...this.entity,
...extraParams
}
2022-01-17 16:00:12 +08:00
const requestUrl = url || (chartParams && chartParams.url)
// 默认参数特殊处理
2022-03-03 23:21:33 +08:00
if (requestUrl && requestUrl.indexOf('dnsServerRole') > -1) {
const currentMap = this.$store.getters.getCurrentMap
this.queryParams.dnsServerRole = extraParams.dnsServerRole || currentMap || dnsServerRole.RTDNSM
2022-03-03 23:21:33 +08:00
}
2022-01-16 23:16:00 +08:00
if (requestUrl) {
axios.get(replaceUrlPlaceholder(requestUrl, { params: this.queryParams })).then(response => {
if (response.status === 200) {
if (Array.isArray(response.data.data.result)) {
response.data.data.result.forEach(item => {
if (item.legend && legendMapping[`${this.entity && this.entity.ip ? 'ip_' : ''}${item.legend}`]) {
item.legend = this.$t(legendMapping[`${this.entity && this.entity.ip ? 'ip_' : ''}${item.legend}`])
}
})
}
this.chartData = response.data.data.result
this.resultType = response.data.data.resultType
2022-03-27 13:04:47 +08:00
if (isEchartsWithStatistics(this.chartInfo.type)) {
const newArr = []
_.forEach(this.chartData, function (value, key) {
_.forEach(value.values, function (value, key) {
newArr.push(value[0])
})
})
const Arr = newArr.sort()
_.forEach(this.chartData, function (value, key) {
if (_.head(value.values[0]) !== _.head(Arr)) {
value.values.unshift([_.head(Arr), 0])
}
if ((_.last(value.values[0]) !== _.last(Arr))) {
value.values.push([_.last(Arr), 0])
}
})
}
if (this.isTable) {
this.table.tableData = response.data.data.result
this.table.tableColumns = chartParams.columns
this.table.currentPageData = this.getTargetPageData(1, this.table.pageSize, this.table.tableData)
} else if (this.isSingleValue) {
if (chartParams && chartParams.dataKey) {
if (response.data.data.result && (response.data.data.result[chartParams.dataKey] || response.data.data.result[chartParams.dataKey] === 0)) {
this.chartData = response.data.data.result[chartParams.dataKey]
} else if (response.data.data.result && (response.data.data.result[chartParams.dataKey + 'Value'] || response.data.data.result[chartParams.dataKey + 'Value'] === 0)) {
2022-04-07 14:53:13 +08:00
this.chartData = {
value: response.data.data.result[chartParams.dataKey + 'Value'],
p50: response.data.data.result[chartParams.dataKey + 'P50'],
p90: response.data.data.result[chartParams.dataKey + 'P90']
2022-04-07 14:53:13 +08:00
}
} else {
this.chartData = null
}
}
}
2022-01-16 23:16:00 +08:00
this.isError = false
} else {
this.isError = true
this.noData = true
this.errorInfo = response.data.message || 'Unknown'
2022-01-16 23:16:00 +08:00
}
2022-01-17 16:00:12 +08:00
}).finally(() => {
if (this.needTimeout && this.firstRender) {
this.firstRender = false
setTimeout(() => {
this.loading = false
}, 5000)
} else {
this.loading = false
}
2022-01-16 23:16:00 +08:00
})
} else if (this.isGroup || this.isTabs) {
this.$refs.chart && this.$refs.chart.$refs.chart && this.$refs.chart.$refs.chart.reload()
} else if (this.isBlock) {
if (!this.chartInfo.firstShow) {
this.chartInfo.firstShow = true
} else {
if (this.$refs.chart && this.$refs.chart.$refs.chart) {
this.$refs.chart.$refs.chart.reload()
}
}
2022-01-16 23:16:00 +08:00
}
} catch (e) {
console.error(e)
setTimeout(() => {
this.loading = false
}, 200)
}
},
handleQueryParams () {
const params = {}
if (this.isEchartsWithTable) {
params.limit = 10
params.order = this.orderPieTable
} else if (this.isRelationShip) {
params.limit = 5
} else if (this.isActiveIpTable) {
params.order = this.activeIpTable.orderBy
} else if (this.isTable) {
params.limit = this.table.limit
params.order = this.table.orderBy
}
return params
},
resize () {
this.$refs.chart.resize()
},
refresh (chartTimeFilter) {
if (chartTimeFilter) {
this.timeFilter.startTime = chartTimeFilter.startTime
this.timeFilter.endTime = chartTimeFilter.endTime
this.timeFilter.dateRangeValue = chartTimeFilter.dateRangeValue
this.getChartData(null, {}, chartTimeFilter)
} else {
if (this.timeFilter.dateRangeValue && this.timeFilter.dateRangeValue > 0) {
const myEndTime = window.$dayJs.tz().valueOf()
const myStartTime = myEndTime - this.timeFilter.dateRangeValue * 60 * 1000
this.standaloneTimeRange.use = true
this.standaloneTimeRange.startTime = myStartTime
this.standaloneTimeRange.endTime = myEndTime
} else {
this.standaloneTimeRange.use = false
}
this.emitter.emit('chart-pageNo')
this.getChartData(null, {})
}
2022-01-16 23:16:00 +08:00
},
tabHandleClick (value) {
this.tabHandleClickType = value
},
2022-01-16 23:16:00 +08:00
showFullscreen (show) {
this.$emit('showFullscreen', show, this.chartInfo)
},
loadMore () {
this.$nextTick(() => {
this.$refs.chart && this.$refs.chart.$refs['chart' + this.chartInfo.id].initChart()
})
},
getDataKey (r) {
let key = ''
let labelText = ''
if (r.establishLatency || r.establishLatency === 0) {
key = 'establishLatency'
labelText = this.$t('networkAppPerformance.tripTime')
} else if (r.httpResponseLatency || r.httpResponseLatency === 0) {
key = 'httpResponseLatency'
labelText = this.$t('networkAppPerformance.httpResponse')
} else if (r.sslConLatency || r.sslConLatency === 0) {
key = 'sslConLatency'
labelText = this.$t('networkAppPerformance.sslResponse')
} else if (r.sequenceGapLossPercent || r.sequenceGapLossPercent === 0) {
key = 'sequenceGapLossPercent'
labelText = this.$t('networkAppPerformance.packetLossRate')
} else if (r.pktRetransPercent || r.pktRetransPercent === 0) {
key = 'pktRetransPercent'
labelText = this.$t('networkAppPerformance.retransmissionRate')
} else if (r.sessions || r.sessions === 0) {
key = 'sessions'
labelText = this.$t('overall.sessions')
}
return { key, labelText }
},
getTableTitle (data) {
if (data.length > 0) {
const dataColumns = Object.keys(data[0]) // 返回数据的字段
const columns = dataColumns.map(c => tableTitleMapping[c]) // 展示字段
const keys = ['clientIp', 'serverIp', 'ip', 'appId', 'app', 'appName', 'domain']
return columns.sort((a, b) => {
if (keys.indexOf(a.prop) > -1) {
return -1
} else if (keys.indexOf(b.prop) > -1) {
return 1
} else {
return 0
}
})
} else {
return []
}
},
showLoading (show) {
this.loading = show
2022-01-19 15:54:27 +08:00
},
tableChange () {
2022-01-19 16:18:11 +08:00
this.emitter.emit('chart-pageNo')
2022-01-19 15:54:27 +08:00
this.getChartData()
},
getTargetPageData (pageNum, pageSize, tableData) {
return this.$_.slice(tableData, (pageNum - 1) * pageSize, pageNum * pageSize)
2022-01-21 15:35:09 +08:00
},
groupShow (chartInfo) {
this.$emit('groupShow', chartInfo)
2022-01-21 15:35:09 +08:00
},
orderPieTableChange (orderPieTable) {
this.orderPieTable = orderPieTable
this.getChartData()
this.$refs.chart.initEchartsWithTable()
}
2022-01-16 23:16:00 +08:00
},
mounted () {
2022-01-17 17:06:14 +08:00
this.showLoading(true)
2022-02-21 16:54:13 +08:00
this.getChartData()
2022-03-14 18:30:26 +08:00
this.$store.commit('cleanChartList')
2022-01-16 23:16:00 +08:00
},
setup (props) {
const dateRangeValue = 60
const { startTime, endTime } = getNowTime(dateRangeValue)
const chartTimeFilter = ref({ startTime, endTime, dateRangeValue })
const table = ref({})
if (isBasicTable(props.chartInfo.type)) {
2022-04-28 10:51:54 +08:00
table.value = {
pageSize: chartTableDefaultPageSize,
limit: chartTableTopOptions[0], // top-n
orderBy: props.chartInfo.params.columns.order[0],
tableColumns: props.chartInfo.params.columns, // table字段
tableData: [], // table的所有数据
currentPageData: [] // table当前页的数据
}
}
2022-01-16 23:16:00 +08:00
return {
table,
2022-01-16 23:16:00 +08:00
chartTimeFilter,
isEcharts: isEcharts(props.chartInfo.type),
isEchartsTimeBar: isEchartsTimeBar(props.chartInfo.type),
isEchartsCategoryBar: isEchartsCategoryBar(props.chartInfo.type),
isEchartsWithTable: isEchartsWithTable(props.chartInfo.type),
isEchartsWithStatistics: isEchartsWithStatistics(props.chartInfo.type),
isSingleValue: isSingleValue(props.chartInfo.type),
isSingleValueWithEcharts: isSingleValueWithEcharts(props.chartInfo.type),
2022-03-27 13:04:47 +08:00
isSingleValueWithPercent: isSingleValueWithPercent(props.chartInfo.type),
2022-01-16 23:16:00 +08:00
isRelationShip: isRelationShip(props.chartInfo.type),
isTable: isTable(props.chartInfo.type),
isActiveIpTable: isActiveIpTable(props.chartInfo.type),
isMap: isMap(props.chartInfo.type),
isTitle: isTitle(props.chartInfo.type),
isMapLine: isMapLine(props.chartInfo.type),
isMapBlock: isMapBlock(props.chartInfo.type),
isTabs: isTabs(props.chartInfo.type),
isGroup: isGroup(props.chartInfo.type),
isBlock: isBlock(props.chartInfo.type),
isSankey: isSankey(props.chartInfo.type),
isIpBasicInfo: isIpBasicInfo(props.chartInfo.type),
isIpHostedDomain: isIpHostedDomain(props.chartInfo.type),
2022-03-27 13:04:47 +08:00
isIpOpenPortBar: isIpOpenPortBar(props.chartInfo.type),
2022-01-16 23:16:00 +08:00
isDomainWhois: isDomainWhois(props.chartInfo.type),
isDomainDnsRecord: isDomainDnsRecord(props.chartInfo.type),
isCryptocurrencyEventList: isCryptocurrencyEventList(props.chartInfo.type),
isAppBasicInfo: isAppBasicInfo(props.chartInfo.type),
isAppRelatedDomain: isAppRelatedDomain(props.chartInfo.type),
isAlarmInfo: isAlarmInfo(props.chartInfo.type),
isDetectionService: isDetectionService(props.chartInfo.type),
isDetectionSecurity: isDetectionSecurity(props.chartInfo.type)
2022-01-16 23:16:00 +08:00
}
}
}
</script>