Merge branch 'dev' of https://git.mesalab.cn/cyber-narrator/cn-ui into dev
This commit is contained in:
@@ -119,7 +119,7 @@
|
|||||||
border: 1px solid #E7EAED;
|
border: 1px solid #E7EAED;
|
||||||
box-shadow: 0 2px 4px 0 rgba(51,51,51,0.02);
|
box-shadow: 0 2px 4px 0 rgba(51,51,51,0.02);
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
height: 100%;
|
height: calc(100% - 47px);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
.chart-drawing {
|
.chart-drawing {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
.chart-ip-open-port-bar {
|
.chart-ip-open-port-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
.el-table--border td{
|
.el-table--border td{
|
||||||
border: none !important;
|
border: none !important;
|
||||||
}
|
}
|
||||||
@@ -19,6 +20,9 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
.chart-drawing{
|
||||||
|
height: calc(100% - 36px) !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -199,7 +199,7 @@
|
|||||||
&>.cn-chart {
|
&>.cn-chart {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
height: 100%;
|
height: calc(100% - 47px);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
.chart-drawing {
|
.chart-drawing {
|
||||||
|
|||||||
@@ -123,6 +123,21 @@
|
|||||||
:query-params="queryParams"
|
:query-params="queryParams"
|
||||||
></chart-cryptocurrency-event-list>
|
></chart-cryptocurrency-event-list>
|
||||||
|
|
||||||
|
<chart-relation-ship
|
||||||
|
v-else-if="isRelationShip"
|
||||||
|
:chart-info="chartInfo"
|
||||||
|
:chart-data="chartData"
|
||||||
|
:query-params="queryParams"
|
||||||
|
></chart-relation-ship>
|
||||||
|
|
||||||
|
<chart-san-key
|
||||||
|
v-else-if="isSankey"
|
||||||
|
:chart-info="chartInfo"
|
||||||
|
:chart-data="chartData"
|
||||||
|
:query-params="queryParams"
|
||||||
|
:entity="entity"
|
||||||
|
></chart-san-key>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -145,6 +160,8 @@ import ChartAppBasicInfo from '@/views/charts/charts/ChartAppBasicInfo'
|
|||||||
import ChartDomainWhois from '@/views/charts/charts/ChartDomainWhois'
|
import ChartDomainWhois from '@/views/charts/charts/ChartDomainWhois'
|
||||||
import ChartDomainDnsRecord from '@/views/charts/charts/ChartDomainDnsRecord'
|
import ChartDomainDnsRecord from '@/views/charts/charts/ChartDomainDnsRecord'
|
||||||
import ChartCryptocurrencyEventList from '@/views/charts/charts/ChartCryptocurrencyEventList'
|
import ChartCryptocurrencyEventList from '@/views/charts/charts/ChartCryptocurrencyEventList'
|
||||||
|
import ChartRelationShip from '@/views/charts/charts/ChartRelationShip'
|
||||||
|
import ChartSanKey from '@/views/charts/charts/ChartSanKey'
|
||||||
import {
|
import {
|
||||||
isEcharts,
|
isEcharts,
|
||||||
isEchartsLine,
|
isEchartsLine,
|
||||||
@@ -183,6 +200,7 @@ import _ from 'lodash'
|
|||||||
export default {
|
export default {
|
||||||
name: 'chart',
|
name: 'chart',
|
||||||
components: {
|
components: {
|
||||||
|
ChartSanKey,
|
||||||
ChartCryptocurrencyEventList,
|
ChartCryptocurrencyEventList,
|
||||||
ChartDomainDnsRecord,
|
ChartDomainDnsRecord,
|
||||||
ChartDomainWhois,
|
ChartDomainWhois,
|
||||||
@@ -199,7 +217,8 @@ export default {
|
|||||||
ChartBlock,
|
ChartBlock,
|
||||||
ChartTimeBar,
|
ChartTimeBar,
|
||||||
ChartCategoryBar,
|
ChartCategoryBar,
|
||||||
ChartIpOpenPortBar
|
ChartIpOpenPortBar,
|
||||||
|
ChartRelationShip,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
chartInfo: Object,
|
chartInfo: Object,
|
||||||
|
|||||||
@@ -190,6 +190,10 @@ export default {
|
|||||||
response = testData.data2
|
response = testData.data2
|
||||||
} else if (this.chartInfo.type === 22 && testData) {
|
} else if (this.chartInfo.type === 22 && testData) {
|
||||||
response = testData.data3
|
response = testData.data3
|
||||||
|
} else if (this.chartInfo.type === 43 && testData) {
|
||||||
|
response = testData.data4
|
||||||
|
} else if (this.chartInfo.type === 42 && testData) {
|
||||||
|
response = testData.data5
|
||||||
}
|
}
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
this.chartData = response.data.result
|
this.chartData = response.data.result
|
||||||
|
|||||||
@@ -35,6 +35,9 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
|
import { ipOpenPortBar } from '@/views/charts/charts/options/bar'
|
||||||
|
import { getChartColor } from '@/components/charts/chart-options'
|
||||||
|
import * as echarts from 'echarts'
|
||||||
export default {
|
export default {
|
||||||
name: 'ChartIpOpenPortBar',
|
name: 'ChartIpOpenPortBar',
|
||||||
props: {
|
props: {
|
||||||
@@ -71,7 +74,22 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
init (id) {
|
init (id) {
|
||||||
|
const dom = document.getElementById(id)
|
||||||
|
!this.myChart && (this.myChart = echarts.init(dom))
|
||||||
this.tableData = lodash.cloneDeep(this.chartData)
|
this.tableData = lodash.cloneDeep(this.chartData)
|
||||||
|
this.chartOption = this.$_.cloneDeep(ipOpenPortBar)
|
||||||
|
const protocols = []
|
||||||
|
this.tableData.forEach((d, i) => {
|
||||||
|
const index = protocols.findIndex(p => p.name === d.protocol.toUpperCase())
|
||||||
|
if (index === -1) {
|
||||||
|
protocols.push({ name: d.protocol.toUpperCase(), value: 1, itemStyle: { color: getChartColor(i) } })
|
||||||
|
} else {
|
||||||
|
protocols[index].value++
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.chartOption.series[0].data = protocols
|
||||||
|
this.chartOption.xAxis.data = protocols.map(p => p.name)
|
||||||
|
this.myChart.setOption(this.chartOption)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|||||||
92
src/views/charts/charts/ChartRelationShip.vue
Normal file
92
src/views/charts/charts/ChartRelationShip.vue
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<template>
|
||||||
|
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as echarts from 'echarts'
|
||||||
|
import loadsh from 'lodash'
|
||||||
|
import { relationShip } from './options/sankey'
|
||||||
|
export default {
|
||||||
|
name: 'ChartRelationShip',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
myChart: null,
|
||||||
|
chartOption: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
chartInfo: Object,
|
||||||
|
chartData: [Array, Object],
|
||||||
|
resultType: Object,
|
||||||
|
queryParams: Object
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init (id) {
|
||||||
|
const chartParams = this.chartInfo.params
|
||||||
|
const dom = document.getElementById(id)
|
||||||
|
!this.myChart && (this.myChart = echarts.init(dom))
|
||||||
|
this.chartOption = this.$_.cloneDeep(relationShip)
|
||||||
|
const data = []
|
||||||
|
const links = []
|
||||||
|
handleData(data, links, this.chartData)
|
||||||
|
this.chartOption.series[0].data = data
|
||||||
|
this.chartOption.series[0].links = links
|
||||||
|
this.myChart.setOption(this.chartOption)
|
||||||
|
function handleData (data, links, item) {
|
||||||
|
if (!data.some(d => d.name === item.name)) {
|
||||||
|
data.push({ name: item.name, ...handleStyle(item) })
|
||||||
|
}
|
||||||
|
if (!loadsh.isEmpty(item.from) && !loadsh.isEmpty(item.to)) {
|
||||||
|
links.push({ target: item.to, source: item.from })
|
||||||
|
}
|
||||||
|
if (!loadsh.isEmpty(item.leaf)) {
|
||||||
|
item.leaf.forEach(i => {
|
||||||
|
handleData(data, links, i)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleStyle (item) {
|
||||||
|
const style = {}
|
||||||
|
switch (item.type) {
|
||||||
|
case 'app_id': {
|
||||||
|
style.itemStyle = { color: '#73DEB3' }
|
||||||
|
style.symbol = 'circle'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'domain': {
|
||||||
|
style.itemStyle = { color: '#73A0FA' }
|
||||||
|
style.symbol = 'circle'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'client_ip': {
|
||||||
|
style.itemStyle = { color: '#E8F6FF', borderColor: '#C9C9C9' }
|
||||||
|
style.symbol = 'roundRect'
|
||||||
|
style.symbolSize = [80, 25]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'server_ip': {
|
||||||
|
style.itemStyle = { color: '#E2FCEF', borderColor: '#C9C9C9' }
|
||||||
|
style.symbol = 'roundRect'
|
||||||
|
style.symbolSize = [80, 25]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
chartData: {
|
||||||
|
deep: true,
|
||||||
|
handler (n) {
|
||||||
|
this.init(`chart${this.chartInfo.id}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
122
src/views/charts/charts/ChartSanKey.vue
Normal file
122
src/views/charts/charts/ChartSanKey.vue
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
<template>
|
||||||
|
<div class="sankey-box">
|
||||||
|
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
|
||||||
|
<div class="sankey__label" style="left: 5%;">{{$t('entities.inboundLinkId')}}</div>
|
||||||
|
<div class="sankey__label" style="left: 50%;">{{entity.ip || entity.domain || entity.app}}</div>
|
||||||
|
<div class="sankey__label" style="right: 5%; transform: translateX(50%)">{{$t('entities.outboundLinkId')}}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import unitConvert, { valueToRangeValue } from '@/utils/unit-convert'
|
||||||
|
import { unitTypes } from '@/utils/constants'
|
||||||
|
import * as echarts from 'echarts'
|
||||||
|
import { sankey } from './options/sankey'
|
||||||
|
export default {
|
||||||
|
name: 'ChartSanKey',
|
||||||
|
props: {
|
||||||
|
chartInfo: Object,
|
||||||
|
chartData: [Array, Object],
|
||||||
|
resultType: Object,
|
||||||
|
queryParams: Object,
|
||||||
|
entity: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init (id) {
|
||||||
|
const vm = this
|
||||||
|
const chartParams = this.chartInfo.params
|
||||||
|
const entityName = this.entity.ip || this.entity.domain || this.entity.app
|
||||||
|
const dom = document.getElementById(id)
|
||||||
|
!this.myChart && (this.myChart = echarts.init(dom))
|
||||||
|
this.chartOption = this.$_.cloneDeep(sankey)
|
||||||
|
this.chartOption.series[0].tooltip = {
|
||||||
|
formatter: function (param) {
|
||||||
|
return `
|
||||||
|
<div class="sankey__tooltip">
|
||||||
|
<div class="sankey__tooltip-row">
|
||||||
|
<div class="sankey__row-label">Via:</div>
|
||||||
|
<div class="sankey__row-value">${param.data.name}</div>
|
||||||
|
</div>
|
||||||
|
<div class="sankey__tooltip-row">
|
||||||
|
<div style="margin: 6px 0; height: 1px; width: 100%; background-color: #E7EAED;"></div>
|
||||||
|
</div>
|
||||||
|
<div class="sankey__tooltip-row">
|
||||||
|
<div class="sankey__row-label">Traffic:</div>
|
||||||
|
<div class="sankey__row-value">${param.data.convert[0]}${param.data.convert[1]} (${param.data.percent[0]}%)</div>
|
||||||
|
</div>
|
||||||
|
<div class="sankey__tooltip-row">
|
||||||
|
<div class="sankey__row-label">Performance:</div>
|
||||||
|
</div>
|
||||||
|
<div class="sankey__tooltip-table">
|
||||||
|
<div class="sankey__table-row">
|
||||||
|
<div class="sankey__table-cell">${vm.$t('networkAppPerformance.tripTime')}:</div>
|
||||||
|
<div class="sankey__table-cell">${param.data.latency[0]} ${param.data.latency[1]}</div>
|
||||||
|
</div>
|
||||||
|
<div class="sankey__table-row">
|
||||||
|
<div class="sankey__table-cell">${vm.$t('overall.packetLoss')}:</div>
|
||||||
|
<div class="sankey__table-cell">${param.data.lossPercent[0]} %</div>
|
||||||
|
</div>
|
||||||
|
<div class="sankey__table-row">
|
||||||
|
<div class="sankey__table-cell">${vm.$t('overall.packetRetrans')}:</div>
|
||||||
|
<div class="sankey__table-cell">${param.data.retransPercent[0]} %</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let inTotalValue = 0
|
||||||
|
let outTotalValue = 0
|
||||||
|
this.chartData.forEach(item => {
|
||||||
|
if (item.direction === 'in') {
|
||||||
|
inTotalValue += parseInt(item.bytes)
|
||||||
|
} else if (item.direction === 'out') {
|
||||||
|
outTotalValue += parseInt(item.bytes)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const data = this.chartData.map(item => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
name: item.linkID,
|
||||||
|
percent: valueToRangeValue(parseInt(item.bytes) / (item.direction === 'in' ? inTotalValue : outTotalValue) * 100, unitTypes.percent),
|
||||||
|
convert: unitConvert(item.bytes, unitTypes.byte),
|
||||||
|
latency: valueToRangeValue(item.latency, unitTypes.time),
|
||||||
|
lossPercent: valueToRangeValue(item.lossPercent, unitTypes.percent),
|
||||||
|
retransPercent: valueToRangeValue(item.retransPercent, unitTypes.percent),
|
||||||
|
bytes: parseFloat(item.bytes)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
data.push({ name: entityName })
|
||||||
|
|
||||||
|
const link = data.map(item => {
|
||||||
|
const source = item.direction === 'in' ? item.linkID : entityName
|
||||||
|
const target = item.direction === 'in' ? entityName : item.linkID
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
source,
|
||||||
|
target,
|
||||||
|
value: item.bytes
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.chartOption.series[0].data = data
|
||||||
|
this.chartOption.series[0].links = link
|
||||||
|
this.myChart.setOption(this.chartOption)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
chartData: {
|
||||||
|
deep: true,
|
||||||
|
handler (n) {
|
||||||
|
this.init(`chart${this.chartInfo.id}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -4,7 +4,8 @@ import {
|
|||||||
categoryVerticalFormatter,
|
categoryVerticalFormatter,
|
||||||
chartColor,
|
chartColor,
|
||||||
getCharBartColor,
|
getCharBartColor,
|
||||||
timeVerticalFormatter, tooLongFormatter
|
timeVerticalFormatter,
|
||||||
|
tooLongFormatter
|
||||||
} from '@/views/charts/charts/tools'
|
} from '@/views/charts/charts/tools'
|
||||||
|
|
||||||
export const ipOpenPortBar = {
|
export const ipOpenPortBar = {
|
||||||
|
|||||||
@@ -41,3 +41,28 @@ export const sankey = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
export const relationShip = {
|
||||||
|
grid: {
|
||||||
|
left: 0,
|
||||||
|
bottom: 50,
|
||||||
|
top: 80,
|
||||||
|
right: 0
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'graph',
|
||||||
|
layout: 'force',
|
||||||
|
symbolSize: 40,
|
||||||
|
roam: true,
|
||||||
|
force: {
|
||||||
|
repulsion: 350
|
||||||
|
},
|
||||||
|
draggable: true,
|
||||||
|
label: { show: true },
|
||||||
|
edgeSymbol: ['none', 'arrow'],
|
||||||
|
edgeSymbolSize: 7,
|
||||||
|
data: [],
|
||||||
|
links: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user