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/Chart.vue

422 lines
14 KiB
Vue
Raw Normal View History

<template>
2021-06-24 17:59:51 +08:00
<!-- 地图 -->
<chart-map
v-if="isMap"
:style="computePosition"
>
<template #title>{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</template>
<template #operations>
<i class="cn-icon cn-icon-more-light"></i>
</template>
<template #default>
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
</template>
</chart-map>
<!-- echarts类的图如饼图柱状图折线图等 -->
<echarts-frame
2021-06-24 17:59:51 +08:00
v-else-if="isEcharts"
:layout="layout"
:style="computePosition"
2021-06-23 15:57:34 +08:00
:chartInfo="chartInfo"
>
<template #title v-if="layout.indexOf(layoutConstant.HEADER) > -1">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</template>
<template #operations v-if="layout.indexOf(layoutConstant.HEADER) > -1">
<i class="cn-icon cn-icon-more-light"></i>
</template>
<template #default>
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
</template>
2021-06-23 15:57:34 +08:00
<template #footer v-if="layout.indexOf(layoutConstant.FOOTER) > -1" :class="{}">
<!-- 带Table的饼图展示Table -->
<template v-if="isEchartsWithTable">
2021-06-24 17:59:51 +08:00
<div style="height: 100%">
<PieTable :tableData="pieTableData" ref="pieTable"/>
</div>
</template>
</template>
</echarts-frame>
<!-- 单值图 -->
<single-value
v-else-if="isSingleValue"
:type="chartInfo.type"
:style="computePosition"
>
</single-value>
<!-- 表格 -->
<chart-table
v-else-if="isTable"
2021-06-21 20:33:39 +08:00
:table-columns="table.tableColumns"
:table-data="table.currentPageData"
:style="computePosition"
>
<template #title>{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</template>
<template #operations>
<!-- <div class="header__operation header__operation&#45;&#45;table">
<span class="option__button"><i class="cn-icon cn-icon-download"></i></span>
</div>-->
2021-06-21 20:33:39 +08:00
<div class="header__operation header__operation--table">
<el-select
size="mini"
v-model="table.limit"
class="option__select select-topn"
2021-06-21 20:33:39 +08:00
placeholder=""
popper-class="option-popper"
2021-06-21 20:33:39 +08:00
>
<el-option v-for="item in chartTableTopOptions" :key="item" :value="item">TOP&nbsp;{{item}}</el-option>
<template #prefix>TOP&nbsp;</template>
</el-select>
</div>
<div class="header__operation header__operation--table">
<el-select
size="mini"
v-model="table.orderBy"
class="option__select select-column"
2021-06-21 20:33:39 +08:00
placeholder=""
popper-class="option-popper"
2021-06-21 20:33:39 +08:00
>
<el-option v-for="item in table.tableColumns" :key="item" :value="item">{{item}}</el-option>
</el-select>
</div>
<!-- <div class="header__operation header__operation&#45;&#45;table">
<span class="option__button"><i class="cn-icon cn-icon-style"></i></span>
<div class="icon-group-divide"></div>
<span class="option__button"><i class="cn-icon cn-icon-dropdown"></i></span>
</div>-->
<div class="header__operation header__operation--table">
<span class="option__button"><i class="cn-icon cn-icon-full-screen"></i></span>
</div>
</template>
2021-06-21 20:33:39 +08:00
<template #footer>
<chart-table-pagination
:total="table.tableData.length"
@pageJump="pageJump"
></chart-table-pagination>
</template>
</chart-table>
</template>
<script>
import * as echarts from 'echarts'
2021-06-24 17:59:51 +08:00
import * as am4Core from '@amcharts/amcharts4/core'
import * as am4Maps from '@amcharts/amcharts4/maps'
import am4GeoDataWorldLow from '@amcharts/amcharts4-geodata/worldChinaLow'
import {
isEcharts,
isSingleValue,
isTable,
isMap,
getOption,
getTypeCategory,
getLayout,
layoutConstant,
heightUnit,
isEchartsWithTable,
pieTableDatas,
isMapLine
} from '@/components/charts/chart-options'
import EchartsFrame from '@/components/charts/EchartsFrame'
import SingleValue from '@/components/charts/ChartSingleValue'
2021-06-24 17:59:51 +08:00
import ChartTable from '@/components/charts/ChartTable'
import ChartMap from '@/components/charts/ChartMap'
2021-06-23 15:57:34 +08:00
import PieTable from '@/components/charts/PieTable'
2021-06-21 20:33:39 +08:00
import ChartTablePagination from '@/components/charts/ChartTablePagination'
import { chartTableDefaultPageSize, chartTableTopOptions } from '@/utils/constants'
import { get } from '@/utils/http'
2021-06-24 17:59:51 +08:00
import { replaceUrlPlaceholder } from '@/utils/tools'
2021-06-24 17:59:51 +08:00
let myChart // echarts或amcharts实例
export default {
name: 'Chart',
props: {
2021-06-23 15:57:34 +08:00
chart: Object, // 图表对象包括id、name、type等数据
startTime: {
type: Number
},
endTime: {
type: Number
}
},
components: {
EchartsFrame,
SingleValue,
2021-06-21 20:33:39 +08:00
ChartTablePagination,
2021-06-24 17:59:51 +08:00
ChartTable,
PieTable,
ChartMap
},
data () {
return {
2021-06-21 20:33:39 +08:00
table: {
pageSize: chartTableDefaultPageSize,
limit: chartTableTopOptions[0], // top-n
orderBy: '',
tableColumns: [], // table字段
tableData: [], // table的所有数据
currentPageData: [] // table当前页的数据
2021-06-23 15:57:34 +08:00
},
pieTableData: []
}
},
methods: {
initChart () {
2021-06-23 15:57:34 +08:00
const self = this
2021-06-24 17:59:51 +08:00
const chartParams = this.chartInfo.params ? JSON.parse(this.chartInfo.params) : null // 图表参数
if (this.isMap) {
myChart = this.initMap(`chart${this.chartInfo.id}`)
/* const queryParams = { startTime: this.startTime, endTime: this.endTime } // 统计数据的查询参数
if (chartParams) {
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
console.info(response)
})
} */
if (this.isMapLine) {
const lineSeries = myChart.series.push(new am4Maps.MapLineSeries())
lineSeries.data = [
{
multiGeoLine: mapResponse.data.map(d => {
return [{ latitude: d.server_latitude, longitude: d.server_longitude }, { latitude: d.client_latitude, longitude: d.client_longitude }]
})
}
]
}
} else if (this.isEcharts) {
2021-06-25 10:10:35 +08:00
const dom = document.getElementById(`chart${this.chartInfo.id}`)
myChart = echarts.init(dom)
myChart.setOption(this.chartOption)
2021-06-23 15:57:34 +08:00
if (this.isEchartsWithTable) {
2021-06-25 10:10:35 +08:00
this.chartOption.legend.formatter = (name) => { // 根据图表宽 显示legend的字数
let str = name
const length = Math.floor(dom.offsetWidth / 75)
if (name.length > length) {
str = name.substring(0, length - 3) + '...'
}
return str
}
myChart.setOption(this.chartOption)
2021-06-23 15:57:34 +08:00
if (this.chartOption.series[0].data.length > 10) { // pieWithTable 图例超过10个改为滚动显示
this.chartOption.legend.type = 'scroll'
myChart.setOption(this.chartOption)
}
2021-06-24 17:59:51 +08:00
if (chartParams.url.split('?').length > 1) {
chartParams.url = chartParams.url.split('?')[0]
2021-06-23 15:57:34 +08:00
}
2021-06-24 17:59:51 +08:00
if (chartParams.urlTable.split('?').length > 1) {
chartParams.urlTable = chartParams.urlTable.split('?')[0]
2021-06-23 15:57:34 +08:00
}
2021-06-24 17:59:51 +08:00
/* get(chartParams.url, { startTime: now - 3600000, endTime: now, order: chartParams.order ? chartParams.order : null, limit: chartParams.limit ? chartParams.limit : '20' }).then(response => {
2021-06-23 15:57:34 +08:00
console.log(response)
}) */
// 获取pieTable的 table数据
2021-06-24 17:59:51 +08:00
/* get(chartParams.urlTable, { startTime: this.startTime, endTime: this.endTime, fqdnCategoryName: echartParams.name }).then(response => {
2021-06-23 15:57:34 +08:00
console.log(response)
}) */
self.pieTableData = pieTableDatas
myChart.on('click', function (echartParams) {
2021-06-24 17:59:51 +08:00
/* get(chartParams.urlTable, { startTime: this.startTime, endTime: this.endTime, fqdnCategoryName: echartParams.name }).then(response => {
2021-06-23 15:57:34 +08:00
console.log(response)
}) */
self.pieTableData = pieTableDatas
})
}
2021-06-24 17:59:51 +08:00
/*this.$nextTick(() => {
myChart.doLayout()
})*/
} else if (this.isTable) {
2021-06-24 17:59:51 +08:00
if (chartParams) {
const tableColumns = new Set()
tableResponse.data.forEach(d => {
Object.keys(d).forEach(k => {
tableColumns.add(k)
})
})
2021-06-21 20:33:39 +08:00
this.table.tableColumns = Array.from(tableColumns)
this.table.orderBy = this.table.tableColumns[0]
this.table.tableData = tableResponse.data
this.table.currentPageData = this.getTargetPageData(1, this.table.pageSize, this.table.tableData)
2021-06-24 17:59:51 +08:00
/* get(chartParams.url, { startTime: now - 3600000, endTime: now, order: chartParams.order ? chartParams.order : null, limit: chartParams.limit ? chartParams.limit : null }).then(response => {
if (response.code === 200) {
const tableColumns = new Set()
response.data.forEach(d => {
Object.keys(d).forEach(k => {
tableColumns.add(k)
})
})
2021-06-21 20:33:39 +08:00
this.table.tableColumns = tableColumns
this.table.tableData = response.data
}
}) */
}
}
2021-06-21 20:33:39 +08:00
},
2021-06-24 17:59:51 +08:00
initMap (id) {
const myChart = am4Core.create(id, am4Maps.MapChart)
myChart.geodata = am4GeoDataWorldLow
myChart.projection = new am4Maps.projections.Miller()
const polygonSeries = myChart.series.push(new am4Maps.MapPolygonSeries())
polygonSeries.useGeodata = true
polygonSeries.exclude = ['AQ'] // 移除南极洲
const polygonTemplate = polygonSeries.mapPolygons.template
polygonTemplate.tooltipText = '{name}'
polygonTemplate.fill = am4Core.color('#E7EDF6')
/* const hs = polygonTemplate.states.create('hover') // 添加hover事件
hs.properties.fill = am4Core.color('#B7BDC6') */
return myChart
},
2021-06-21 20:33:39 +08:00
pageJump (val) {
this.table.currentPageData = this.getTargetPageData(val, this.table.pageSize, this.table.tableData)
},
getTargetPageData (pageNum, pageSize, tableData) {
return this.$_.slice(tableData, (pageNum - 1) * pageSize, pageNum * pageSize)
}
},
computed: {
computePosition () {
const gridColumn = `${this.chartInfo.x} / ${this.chartInfo.x + this.chartInfo.w}`
const gridRow = `${this.chartInfo.y} / ${this.chartInfo.y + this.chartInfo.h}`
return {
gridColumn,
gridRow
}
}
},
mounted () {
this.initChart()
},
setup (props) {
const chartInfo = JSON.parse(JSON.stringify(props.chart))
chartInfo.category = getTypeCategory(props.chart.type)
return {
chartInfo,
layoutConstant,
2021-06-21 20:33:39 +08:00
chartTableTopOptions,
chartOption: getOption(props.chart.type),
isEcharts: isEcharts(props.chart.type),
isEchartsWithTable: isEchartsWithTable(props.chart.type),
isSingleValue: isSingleValue(props.chart.type),
isTable: isTable(props.chart.type),
2021-06-24 17:59:51 +08:00
isMap: isMap(props.chart.type),
isMapLine: isMapLine(props.chart.type),
layout: getLayout(props.chart.type)
}
}
}
2021-06-24 17:59:51 +08:00
const mapResponse = JSON.parse(`{
"code": "200666",
"data": [{
"server_longitude": "110.290534",
"server_latitude": "30.816222",
"server_country": "America",
"server_region": "Washington",
"client_longitude": "116.352963",
"client_latitude": "40.409079",
"client_country": "China",
"client_region": "Beijing",
"bytes": 27010,
"sessions": 40
}, {
"server_longitude": "2.352222",
"server_latitude": "48.856614",
"server_country": "America",
"server_region": "Washington",
"client_longitude": "-74.005973",
"client_latitude": "40.712775",
"client_country": "China",
"client_region": "Beijing",
"bytes": 67010,
"sessions": 30
}],
"status": 200,
"statistics": {
"result_rows": 0,
"elapsed": 0,
"rows_read": 0,
"result_size": 0
}
}`)
const tableResponse = JSON.parse(`{
"status": 200,
"success": true,
"message": "OK",
"statistics": {
"elapsed": 2111,
"rows_read": 1750155,
"result_size": 872,
"result_rows": 10
},
"data": [{
"ip": "192.168.32.107",
"sessions": "229112",
"packets": "245823",
"bytes": "17974141"
},{
"ip": "192.168.32.108",
"sessions": "229112",
"packets": "245823",
"bytes": "17974141"
},{
"ip": "192.168.32.109",
"sessions": "229112",
"packets": "245823",
"bytes": "17974141"
},{
"ip": "192.168.32.110",
"sessions": "229112",
"packets": "245823",
"bytes": "17974141"
},{
"ip": "192.168.32.111",
"sessions": "229112",
"packets": "245823",
"bytes": "17974141"
},{
"ip": "192.168.32.112",
"sessions": "229112",
"packets": "245823",
"bytes": "17974141"
},{
"ip": "192.168.32.113",
"sessions": "229112",
"packets": "245823",
"bytes": "17974141"
},{
"ip": "192.168.32.114",
"sessions": "229112",
"packets": "245823",
"bytes": "17974141"
},{
"ip": "192.168.32.115",
"sessions": "229112",
"packets": "245823",
"bytes": "17974141"
},{
"ip": "192.168.32.116",
"sessions": "229112",
"packets": "245823",
"bytes": "17974141"
},{
"ip": "192.168.32.117",
"sessions": "229112",
"packets": "245823",
"bytes": "17974141"
},{
"ip": "192.168.32.118",
"sessions": "229112",
"packets": "245823",
"bytes": "17974141"
},{
"ip": "192.168.32.119",
"sessions": "229112",
"packets": "245823",
"bytes": "17974141"
}
]
}`)
</script>
<style>
</style>