CN-332 feat :Dashboard--dns 仪表盘图表开发

This commit is contained in:
zhangxiaolong
2022-03-02 16:13:55 +08:00
parent 80bcf559c1
commit 6e33638715
12 changed files with 249 additions and 59 deletions

View File

@@ -36,5 +36,8 @@
@import './views/charts/ipBasicInfo';
@import './views/charts/chartEchartIpHostedDomain';
@import './views/charts/chartEchartAppRelateDomain';
@import './views/charts/ChartOneSituationStatistics';
@import './views/charts/ChartTwoSituationStatistics';
//@import '../chart';

View File

@@ -0,0 +1,10 @@
.situation-statistics-main {
display: flex;
align-items: center;
margin-left: 50px;
margin-top: 20px;
.situation-statistics-main-right{
margin-left: 40px;
}
}

View File

@@ -0,0 +1,19 @@
.chart-two-situation-statistics{
.situation-statistics-top {
display: flex;
align-items: center;
.situation-statistics-main-right{
margin-left: 40px;
}
}
.situation-statistics-bottom {
display: flex;
align-items: center;
.situation-statistics-main-right{
margin-left: 40px;
}
}
}

View File

@@ -119,6 +119,7 @@ export default {
return {
panelTypeAndRouteMapping: panelTypeAndRouteMapping,
tableTitle: [ // 原table列
{
label: 'ID',
prop: 'id',

View File

@@ -3,7 +3,6 @@
<loading :loading="loading && !isTabs && !isBlock && !isGroup"></loading>
<chart-no-data v-if="isNoData"></chart-no-data>
<template v-else>
<chart-tabs
v-if="isTabs"
:chart-info="chartInfo"
@@ -181,6 +180,21 @@
:entity="entity"
></chart-echart-app-relate-domain>
<chart-one-Situation-Statistics
v-else-if="isSingleSupportStatistics"
:chart-info="chartInfo"
:chart-data="chartData"
@showLoading="showLoading"
:entity="entity"
></chart-one-Situation-Statistics>
<chart-two-Situation-Statistics
v-else-if="isTwoSupportStatistics"
:chart-info="chartInfo"
:chart-data="chartData"
@showLoading="showLoading"
:entity="entity"
></chart-two-Situation-Statistics>
</template>
</div>
</template>
@@ -210,6 +224,8 @@ import ChartDomainDnsRecord from '@/views/charts/charts/ChartDomainDnsRecord'
import ChartCryptocurrencyEventList from '@/views/charts/charts/ChartCryptocurrencyEventList'
import ChartRelationShip from '@/views/charts/charts/ChartRelationShip'
import ChartSanKey from '@/views/charts/charts/ChartSanKey'
import ChartOneSituationStatistics from '@/views/charts/charts/ChartOneSituationStatistics'
import ChartTwoSituationStatistics from '@/views/charts/charts/ChartTwoSituationStatistics'
import {
isEcharts,
isEchartsLine,
@@ -242,7 +258,9 @@ import {
isCryptocurrencyEventList,
isAppBasicInfo,
isAppRelatedDomain,
isBlock
isBlock,
isSingleSupportStatistics,
isTwoSupportStatistics
} from './charts/tools'
import _ from 'lodash'
@@ -272,7 +290,9 @@ export default {
ChartEchart,
ChartEchartWithTable,
ChartEchartIpHostedDomain,
ChartEchartAppRelateDomain
ChartEchartAppRelateDomain,
ChartOneSituationStatistics,
ChartTwoSituationStatistics
},
props: {
chartInfo: Object,
@@ -290,7 +310,18 @@ export default {
},
computed: {
isNoData () {
return !this.loading && (_.isEmpty(this.chartData) || this.isError) && !this.isSingleValue && !this.isTabs && !this.isDomainDnsRecord && !this.isCryptocurrencyEventList && !this.isActiveIpTable && !this.isMap
return (
!this.loading &&
(_.isEmpty(this.chartData) || this.isError) &&
!this.isSingleValue &&
!this.isTabs &&
!this.isDomainDnsRecord &&
!this.isCryptocurrencyEventList &&
!this.isActiveIpTable &&
!this.isMap &&
!this.isSingleSupportStatistics &&
!this.isTwoSupportStatistics
)
},
chartOption () {
if (this.customChartOption) {
@@ -302,21 +333,23 @@ export default {
},
methods: {
resize () {
this.$refs['chart' + this.chartInfo.id] && this.$refs['chart' + this.chartInfo.id].resize()
this.$refs['chart' + this.chartInfo.id] &&
this.$refs['chart' + this.chartInfo.id].resize()
},
showLoading (show) {
this.$emit('showLoading', show)
},
initEchartsWithTable () {
this.$refs['chart' + this.chartInfo.id] && this.$refs['chart' + this.chartInfo.id].initEchartsWithTable(`chart${this.chartInfo.id}`)
this.$refs['chart' + this.chartInfo.id] &&
this.$refs['chart' + this.chartInfo.id].initEchartsWithTable(
`chart${this.chartInfo.id}`
)
}
},
watch: {
chartData: {
deep: true,
handler (n) {
}
handler (n) {}
}
},
setup (props) {
@@ -331,7 +364,9 @@ export default {
isEchartsWithStatistics: isEchartsWithStatistics(props.chartInfo.type),
isSingleValue: isSingleValue(props.chartInfo.type),
isSingleValueWithEcharts: isSingleValueWithEcharts(props.chartInfo.type),
isSingleValueWithEchartsTemp: isSingleValueWithEchartsTemp(props.chartInfo.type),
isSingleValueWithEchartsTemp: isSingleValueWithEchartsTemp(
props.chartInfo.type
),
isRelationShip: isRelationShip(props.chartInfo.type),
isTable: isTable(props.chartInfo.type),
isCurrentTable: isCurrentTable(props.chartInfo.type),
@@ -349,9 +384,13 @@ export default {
isIpOpenPort: isIpOpenPort(props.chartInfo.type),
isDomainWhois: isDomainWhois(props.chartInfo.type),
isDomainDnsRecord: isDomainDnsRecord(props.chartInfo.type),
isCryptocurrencyEventList: isCryptocurrencyEventList(props.chartInfo.type),
isCryptocurrencyEventList: isCryptocurrencyEventList(
props.chartInfo.type
),
isAppBasicInfo: isAppBasicInfo(props.chartInfo.type),
isAppRelatedDomain: isAppRelatedDomain(props.chartInfo.type)
isAppRelatedDomain: isAppRelatedDomain(props.chartInfo.type),
isSingleSupportStatistics: isSingleSupportStatistics(props.chartInfo.type),
isTwoSupportStatistics: isTwoSupportStatistics(props.chartInfo.type)
}
}
}

View File

@@ -210,21 +210,20 @@ export default {
this.table.tableColumns = this.getTableTitle(response.data.result)
this.table.currentPageData = this.getTargetPageData(1, this.table.pageSize, this.table.tableData)
this.resultType = response.data.resultType
if(this.chartInfo.type === 12){
if (this.chartInfo.type === 12) {
const newArr = []
_.forEach(this.chartData,function(value,key){
_.forEach(value.values,function(value,key){
_.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){
console.log(_.head(value.values[0]));
if(_.head(value.values[0]) !== _.head(Arr)){
value.values.unshift([_.head(Arr),0])
_.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 ((_.last(value.values[0]) !== _.last(Arr))) {
value.values.push([_.last(Arr), 0])
}
})
}

View File

@@ -0,0 +1,56 @@
<template>
<div class="chart-one-situation-statistics">
<div class="situation-statistics-main" v-if="chartInfo.id === 686">
<div class="situation-statistics-main-left">
<el-progress type="circle" :color="chartInfo.params.color" width="100" :percentage="percentage" />
</div>
<div class="situation-statistics-main-right">
<div>{{ result.Dnssec.all }}</div>
<div>{{ $t(`dns.numberOfNodes`) }}</div>
</div>
</div>
<div class="situation-statistics-main" v-if="chartInfo.id === 687">
<div class="situation-statistics-main-left">
<el-progress type="circle" width="100" :color="chartInfo.params.color" :percentage="percentage" />
</div>
<div class="situation-statistics-main-right">
<div>{{ result.IPV6.all }}</div>
<div>{{ $t(`dns.numberOfNodes`) }}</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'ChartOneSituationStatistics',
props: {
chartInfo: Object,
chartData: [Array, Object]
},
data () {
return {
result: {
Dnssec: {
num: 5200,
all: 18000
},
IPV6: {
num: 2000,
all: 10000
}
}
}
},
computed: {
percentage () {
if (this.chartInfo.id === 686) {
return parseInt((this.result.Dnssec.num / this.result.Dnssec.all) * 100)
} else {
return parseInt((this.result.IPV6.num / this.result.IPV6.all) * 100)
}
}
}
}
</script>

View File

@@ -0,0 +1,55 @@
<template>
<div class="chart-two-situation-statistics">
<div
class="situation-statistics-main"
v-for="(value, index) in result"
:key="index"
>
<div v-if="value.type === 'doh'" class="situation-statistics-top">
<div class="situation-statistics-main-left">
<el-progress type="circle" :color="chartInfo.params.color[0]" width="100" :percentage="(parseInt((value.num/value.all)*100))" />
</div>
<div class="situation-statistics-main-right">
<div>{{ value.all }}</div>
<div>{{ $t(`dns.numberOfNodesSupportingDoHProtocol`) }}</div>
</div>
</div>
<div v-if="value.type === 'dot'" class="situation-statistics-bottom">
<div class="situation-statistics-main-left">
<el-progress type="circle" :color="chartInfo.params.color[1]" width="100" :percentage="(parseInt((value.num/value.all)*100))" />
</div>
<div class="situation-statistics-main-right">
<div>{{ value.all }}</div>
<div>{{ $t(`dns.numberOfNodesSupportingDoTProtocol`) }}</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'ChartTwoSituationStatistics',
props: {
chartInfo: Object,
chartData: [Array, Object]
},
data () {
return {
result: {
encryptedDns1: {
num: 1800,
all: 10000,
type: 'doh'
},
encryptedDns2: {
num: 13500,
all: 22000,
type: 'dot'
}
}
}
}
}
</script>

View File

@@ -113,7 +113,7 @@ export const lineWithStatistics = {
smooth: false,
symbol: 'none',
data: [],
connectNulls:true
connectNulls: true
}
]
}

View File

@@ -154,6 +154,14 @@ export function isDomainDnsRecord (type) {
export function isCryptocurrencyEventList (type) {
return type === 85
}
/* 单支持情况统计 */
export function isSingleSupportStatistics (type) {
return type === 86
}
/* 两个支持情况统计 */
export function isTwoSupportStatistics (type) {
return type === 87
}
/* 组 */
export function isGroup (type) {
return type === 94

View File

@@ -200,17 +200,17 @@ export default {
categoryPerData: [],
activeAttackOption: null,
activeAttackData: [],
isEventSeverityNoData:true,
isStatisticsSeverityNoData:true,
isStatisticsCategoryNoData:true,
isStatisticsActiveAttackNoData:true
isEventSeverityNoData: true,
isStatisticsSeverityNoData: true,
isStatisticsCategoryNoData: true,
isStatisticsActiveAttackNoData: true
}
},
methods: {
// 初始化顶部大柱状图
initEventSeverityTrendData (params) {
getData(api.detection[this.pageType].eventSeverityTrend, params).then(data => {
/*data = [
/* data = [
{
legend: 'critical',
values: [[1435781430781, '999'], [1435781431781, '222'], [1435781432781, '11'], [1435781433781, '3']]
@@ -228,7 +228,7 @@ export default {
legend: 'info',
values: [[1435781430781, '5'], [1435781431781, '7'], [1435781432781, '5'], [1435781433781, '8']]
}
]*/
] */
if (!this.$_.isEmpty(data)) {
const chartDom = document.getElementById(`eventSeverityTrendBar${this.pageType}`)
const detectionChart = echarts.init(chartDom)
@@ -249,7 +249,7 @@ export default {
// 初始化左侧事件严重等级和小饼图
initEventSeverityData (params) {
getData(api.detection[this.pageType].eventSeverity, params).then(data => {
/*data = [
/* data = [
{
eventSeverity: 'critical',
count: 1048
@@ -266,7 +266,7 @@ export default {
eventSeverity: 'info',
count: 300
}
]*/
] */
if (!this.$_.isEmpty(data)) {
this.filterData[this.pageType][0].data = data.map(r => ({ label: r.eventSeverity, value: r.eventSeverity, count: r.count }))
const eventSeverityOption = this.$_.cloneDeep(pieForSeverity)
@@ -284,7 +284,7 @@ export default {
},
initSecurityTypeData (params) {
getData(api.detection[this.pageType].securityType, params).then(data => {
/*data = [
/* data = [
{
attackType: 'command and control',
count: 1048
@@ -304,7 +304,7 @@ export default {
attackType: 'ddos',
count: 50
}
]*/
] */
if (!this.$_.isEmpty(data)) {
this.filterData[this.pageType][1].data = data.map(r => ({
label: r.attackType,
@@ -315,7 +315,7 @@ export default {
const detectionChart = echarts.init(chartDom)
const securityTypeOption = this.$_.cloneDeep(pieForSeverity)
securityTypeOption.series[0].data = data.map(d => {
return {value: d.count, name: d.attackType, itemStyle: {color: getAttackColor(d.attackType)}}
return { value: d.count, name: d.attackType, itemStyle: { color: getAttackColor(d.attackType) } }
})
detectionChart.setOption(securityTypeOption)
this.isStatisticsCategoryNoData = false
@@ -326,7 +326,7 @@ export default {
},
initOffenderIpData (params) {
getData(api.detection[this.pageType].offenderIp, params).then(data => {
/*data = [
/* data = [
{
offenderIp: '192.168.12.21',
count: 99999
@@ -375,22 +375,22 @@ export default {
offenderIp: '193.168.52.21',
count: 55355
}
]*/
] */
if (!this.$_.isEmpty(data)) {
this.filterData[this.pageType][4].data = data.map(r => ({
label: r.offenderIp,
value: r.offenderIp,
count: r.count
}))
const {showMore, showIndex} = this.computeFilterPage(this.filterData[this.pageType][4].data)
const { showMore, showIndex } = this.computeFilterPage(this.filterData[this.pageType][4].data)
this.filterData[this.pageType][4].showMore = showMore
this.filterData[this.pageType][4].showIndex = showIndex
const chartDom = document.getElementById(`detectionActiveAttacker${this.pageType}`)
const detectionChart = echarts.init(chartDom)
const offenderIpOption = this.$_.cloneDeep(activeAttackBar)
data.sort(this.sortBy('count'));
data = data.slice(0,5)
data.sort(this.sortBy('count'))
data = data.slice(0, 5)
offenderIpOption.series[0].data = data.map(d => {
return [d.count, d.offenderIp]
}).reverse()
@@ -401,14 +401,14 @@ export default {
})
},
sortBy(i) {
return function(a,b) {
sortBy (i) {
return function (a, b) {
return b[i] - a[i]
}
},
initVictimIpData (params) {
getData(api.detection[this.pageType].victimIp, params).then(data => {
/*data = [
/* data = [
{
victimIp: '1.2.6.8',
count: 50
@@ -493,7 +493,7 @@ export default {
victimIp: '1.2.6.88',
count: 50
}
]*/
] */
this.filterData[this.pageType][2].data = data.map(r => ({ label: r.victimIp, value: r.victimIp, count: r.count }))
const { showMore, showIndex } = this.computeFilterPage(this.filterData[this.pageType][2].data)
this.filterData[this.pageType][2].showMore = showMore
@@ -504,12 +504,12 @@ export default {
},
initVictimLocationData (params) {
getData(api.detection[this.pageType].victimLocation, params).then(data => {
/*data = [
/* data = [
{
victimLocationCountry: 'china',
count: 50
}
]*/
] */
this.filterData[this.pageType][3].data = data.map(r => ({ label: r.victimLocationCountry, value: r.victimLocationCountry, count: r.count }))
const { showMore, showIndex } = this.computeFilterPage(this.filterData[this.pageType][3].data)
this.filterData[this.pageType][3].showMore = showMore
@@ -520,12 +520,12 @@ export default {
},
initOffenderLocationData (params) {
getData(api.detection[this.pageType].offenderLocation, params).then(data => {
/*data = [
/* data = [
{
offenderLocationCountry: 'china',
count: 50
}
]*/
] */
this.filterData[this.pageType][5].data = data.map(r => ({ label: r.offenderLocationCountry, value: r.offenderLocationCountry, count: r.count }))
const { showMore, showIndex } = this.computeFilterPage(this.filterData[this.pageType][5].data)
this.filterData[this.pageType][5].showMore = showMore
@@ -536,7 +536,7 @@ export default {
},
initActiveEntity (params) {
getData(api.detection[this.pageType].activeEntity, params).then(data => {
/*data = [
/* data = [
{
name: 'csdn.net',
count: 250
@@ -549,7 +549,7 @@ export default {
name: '2.3.2.2',
count: 50
}
]*/
] */
const chartDom = document.getElementById(`detectionActiveAttacker${this.pageType}`)
const detectionChart = echarts.init(chartDom)
const option = this.$_.cloneDeep(activeAttackBar)
@@ -575,7 +575,7 @@ export default {
}
getData(api.detection[this.pageType].listBasic, params).then(data => {
if (this.pageType === detectionPageType.securityEvent) {
/*data = [
/* data = [
{
eventId: 1212,
securityType: 'ddos',
@@ -736,9 +736,9 @@ export default {
durationMs: 60000,
startTime: 1111111111
}
]*/
] */
} else if (this.pageType === detectionPageType.performanceEvent) {
/*data = [
/* data = [
{
entityType: 'ip',
eventType: 'Dns error',
@@ -867,7 +867,7 @@ export default {
durationMs: 60000,
startTime: 1111111111
}
]*/
] */
}
this.listData = data

View File

@@ -217,7 +217,7 @@ export default {
trafficUrlMap: api.entityDomainDetailTrafficMap,
relatedServerIpUrl: api.entityDomainRelatedServerIp,
relatedServerAppUrl: api.entityDomainRelatedServerApp,
basicProperties:api.entityDomainDetailBasic,
basicProperties: api.entityDomainDetailBasic,
chartData: null,
listMode: 'list',
singleValues: {
@@ -287,7 +287,7 @@ export default {
}
})
},
getBasicProperties(){
getBasicProperties () {
get(this.basicProperties, this.getQueryParams()).then(response => {
if (response.code === 200) {
this.entityData = response.data.result