feat: traffic summary
This commit is contained in:
@@ -242,12 +242,9 @@ const pieWithTable = {
|
|||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
type: 'pie',
|
type: 'pie',
|
||||||
top: '10%',
|
radius: ['42%', '70%'],
|
||||||
left: '10%',
|
center: ['30%', '50%'],
|
||||||
width: 'auto',
|
data: [],
|
||||||
radius: ['50%', '80%'],
|
|
||||||
center: ['25%', '50%'],
|
|
||||||
data: pieData,
|
|
||||||
emphasis: {
|
emphasis: {
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
shadowBlur: 10,
|
shadowBlur: 10,
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
top: 20px;
|
top: 20px;
|
||||||
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cn-chart {
|
.cn-chart {
|
||||||
@@ -139,6 +140,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.cn-chart__title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 20px;
|
||||||
|
padding-left: 10px;
|
||||||
|
color: #333;
|
||||||
|
background-color: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
.cn-chart__table {
|
.cn-chart__table {
|
||||||
.cn-chart__header {
|
.cn-chart__header {
|
||||||
border-bottom: 1px solid $--content-right-background-color;
|
border-bottom: 1px solid $--content-right-background-color;
|
||||||
|
|||||||
@@ -385,3 +385,14 @@ export function replaceUrlPlaceholder (url, params) {
|
|||||||
})
|
})
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 下划线转换驼峰
|
||||||
|
export function lineToHump (name) {
|
||||||
|
return name.replace(/\_(\w)/g, function(all, letter){
|
||||||
|
return letter.toUpperCase()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 驼峰转换下划线
|
||||||
|
export function humpToLine (name) {
|
||||||
|
return name.replace(/([A-Z])/g,"_$1").toLowerCase()
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div
|
||||||
|
v-if="isTitle"
|
||||||
|
class="cn-chart cn-chart__title"
|
||||||
|
:style="computePosition">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</div>
|
||||||
<!-- 地图 -->
|
<!-- 地图 -->
|
||||||
<chart-map
|
<chart-map
|
||||||
v-if="isMap"
|
v-else-if="isMap"
|
||||||
:style="computePosition"
|
:style="computePosition"
|
||||||
>
|
>
|
||||||
<template #title>{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</template>
|
<template #title>{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</template>
|
||||||
@@ -105,6 +109,7 @@ import {
|
|||||||
isEcharts,
|
isEcharts,
|
||||||
isSingleValue,
|
isSingleValue,
|
||||||
isTable,
|
isTable,
|
||||||
|
isTitle,
|
||||||
isMap,
|
isMap,
|
||||||
getOption,
|
getOption,
|
||||||
getTypeCategory,
|
getTypeCategory,
|
||||||
@@ -123,9 +128,7 @@ import PieTable from '@/components/charts/PieTable'
|
|||||||
import ChartTablePagination from '@/components/charts/ChartTablePagination'
|
import ChartTablePagination from '@/components/charts/ChartTablePagination'
|
||||||
import { chartTableDefaultPageSize, chartTableTopOptions } from '@/utils/constants'
|
import { chartTableDefaultPageSize, chartTableTopOptions } from '@/utils/constants'
|
||||||
import { get } from '@/utils/http'
|
import { get } from '@/utils/http'
|
||||||
import { replaceUrlPlaceholder } from '@/utils/tools'
|
import { replaceUrlPlaceholder, lineToHump } from '@/utils/tools'
|
||||||
|
|
||||||
let myChart // echarts或amcharts实例
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Chart',
|
name: 'Chart',
|
||||||
@@ -156,73 +159,113 @@ export default {
|
|||||||
tableData: [], // table的所有数据
|
tableData: [], // table的所有数据
|
||||||
currentPageData: [] // table当前页的数据
|
currentPageData: [] // table当前页的数据
|
||||||
},
|
},
|
||||||
pieTableData: []
|
pieTableData: [],
|
||||||
|
myChart: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initChart () {
|
initChart () {
|
||||||
const self = this
|
|
||||||
const chartParams = this.chartInfo.params ? JSON.parse(this.chartInfo.params) : null // 图表参数
|
const chartParams = this.chartInfo.params ? JSON.parse(this.chartInfo.params) : null // 图表参数
|
||||||
if (this.isMap) {
|
if (this.isMap) {
|
||||||
myChart = this.initMap(`chart${this.chartInfo.id}`)
|
this.myChart = this.initMap(`chart${this.chartInfo.id}`)
|
||||||
/* const queryParams = { startTime: this.startTime, endTime: this.endTime } // 统计数据的查询参数
|
const queryParams = { startTime: 1593070343, endTime: this.endTime } // 统计数据的查询参数
|
||||||
if (chartParams) {
|
if (chartParams) {
|
||||||
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
|
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(mapResponse => {
|
||||||
console.info(response)
|
if (mapResponse.data.length > 100) {
|
||||||
})
|
mapResponse.data = mapResponse.data.slice(0, 100)
|
||||||
} */
|
|
||||||
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 }]
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
]
|
if (this.isMapLine) {
|
||||||
|
const lineSeries = this.myChart.series.push(new am4Maps.MapLineSeries())
|
||||||
|
lineSeries.mapLines.template.stroke = am4Core.color('#A258EC')
|
||||||
|
lineSeries.mapLines.template.line.nonScalingStroke = true
|
||||||
|
lineSeries.mapLines.template.line.strokeDasharray = '4 3'
|
||||||
|
lineSeries.data = [
|
||||||
|
{
|
||||||
|
multiGeoLine: mapResponse.data.map(d => {
|
||||||
|
return [{ latitude: parseFloat(d.server_latitude), longitude: parseFloat(d.server_longitude) }, { latitude: parseFloat(d.client_latitude), longitude: parseFloat(d.client_longitude) }]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const imageSeries = this.myChart.series.push(new am4Maps.MapImageSeries())
|
||||||
|
const imageSeriesTemplate = imageSeries.mapImages.template
|
||||||
|
const circle = imageSeriesTemplate.createChild(am4Core.Circle)
|
||||||
|
|
||||||
|
const gradient = new am4Core.RadialGradient()
|
||||||
|
gradient.addColor(am4Core.color('#A258EC'))
|
||||||
|
gradient.addColor(am4Core.color('#A258EC'))
|
||||||
|
gradient.addColor(am4Core.color('#A258EC'))
|
||||||
|
gradient.addColor(am4Core.color('#FFFFFF'))
|
||||||
|
gradient.addColor(am4Core.color('#FFFFFF'))
|
||||||
|
|
||||||
|
circle.radius = 4
|
||||||
|
circle.fill = gradient
|
||||||
|
circle.stroke = am4Core.color('#A258EC')
|
||||||
|
circle.strokeWidth = 1
|
||||||
|
circle.nonScaling = true
|
||||||
|
circle.tooltipText = '{title}'
|
||||||
|
|
||||||
|
imageSeriesTemplate.propertyFields.latitude = 'latitude'
|
||||||
|
imageSeriesTemplate.propertyFields.longitude = 'longitude'
|
||||||
|
|
||||||
|
const pointData = []
|
||||||
|
mapResponse.data.forEach(d => {
|
||||||
|
pointData.push({ latitude: parseFloat(d.server_latitude), longitude: parseFloat(d.server_longitude), title: d.server_region })
|
||||||
|
pointData.push({ latitude: parseFloat(d.client_latitude), longitude: parseFloat(d.client_longitude), title: d.client_region })
|
||||||
|
})
|
||||||
|
imageSeries.data = pointData
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
} else if (this.isEcharts) {
|
} else if (this.isEcharts) {
|
||||||
const dom = document.getElementById(`chart${this.chartInfo.id}`)
|
const dom = document.getElementById(`chart${this.chartInfo.id}`)
|
||||||
myChart = echarts.init(dom)
|
this.myChart = echarts.init(dom)
|
||||||
myChart.setOption(this.chartOption)
|
if (chartParams) {
|
||||||
if (this.isEchartsWithTable) {
|
if (this.isEchartsWithTable) {
|
||||||
this.chartOption.legend.formatter = (name) => { // 根据图表宽 显示legend的字数
|
const queryParams = { startTime: 1593070343, endTime: this.endTime } // 统计数据的查询参数
|
||||||
let str = name
|
const tableQueryParams = { startTime: 1593070343, endTime: this.endTime } // 统计数据的查询参数
|
||||||
const length = Math.floor(dom.offsetWidth / 75)
|
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
|
||||||
if (name.length > length) {
|
const data = response.data.map(d => {
|
||||||
str = name.substring(0, length - 3) + '...'
|
const trans = {}
|
||||||
}
|
Object.keys(d).forEach(k => {
|
||||||
return str
|
trans[lineToHump(k)] = d[k]
|
||||||
|
})
|
||||||
|
return trans
|
||||||
|
})
|
||||||
|
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
|
||||||
|
}
|
||||||
|
this.chartOption.series[0].data = data.map(d => {
|
||||||
|
return {
|
||||||
|
data: d,
|
||||||
|
name: d[chartParams.nameColumn],
|
||||||
|
value: parseInt(d[chartParams.valueColumn])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (this.chartOption.series[0].data && this.chartOption.series[0].data.length > 10) { // pieWithTable 图例超过10个改为滚动显示
|
||||||
|
this.chartOption.legend.type = 'scroll'
|
||||||
|
}
|
||||||
|
this.myChart.setOption(this.chartOption)
|
||||||
|
tableQueryParams[chartParams.nameColumn] = data[0][chartParams.nameColumn]
|
||||||
|
get(replaceUrlPlaceholder(chartParams.urlTable, tableQueryParams)).then(response2 => {
|
||||||
|
this.pieTableData = response2.data
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
this.myChart.on('click', function (echartParams) {
|
||||||
|
get(replaceUrlPlaceholder(chartParams.urlTable, tableQueryParams)).then(response => {
|
||||||
|
this.pieTableData = response.data
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.myChart.setOption(this.chartOption)
|
||||||
}
|
}
|
||||||
myChart.setOption(this.chartOption)
|
|
||||||
if (this.chartOption.series[0].data.length > 10) { // pieWithTable 图例超过10个改为滚动显示
|
|
||||||
this.chartOption.legend.type = 'scroll'
|
|
||||||
myChart.setOption(this.chartOption)
|
|
||||||
}
|
|
||||||
if (chartParams.url.split('?').length > 1) {
|
|
||||||
chartParams.url = chartParams.url.split('?')[0]
|
|
||||||
}
|
|
||||||
if (chartParams.urlTable.split('?').length > 1) {
|
|
||||||
chartParams.urlTable = chartParams.urlTable.split('?')[0]
|
|
||||||
}
|
|
||||||
/* get(chartParams.url, { startTime: now - 3600000, endTime: now, order: chartParams.order ? chartParams.order : null, limit: chartParams.limit ? chartParams.limit : '20' }).then(response => {
|
|
||||||
console.log(response)
|
|
||||||
}) */
|
|
||||||
// 获取pieTable的 table数据
|
|
||||||
/* get(chartParams.urlTable, { startTime: this.startTime, endTime: this.endTime, fqdnCategoryName: echartParams.name }).then(response => {
|
|
||||||
console.log(response)
|
|
||||||
}) */
|
|
||||||
self.pieTableData = pieTableDatas
|
|
||||||
myChart.on('click', function (echartParams) {
|
|
||||||
/* get(chartParams.urlTable, { startTime: this.startTime, endTime: this.endTime, fqdnCategoryName: echartParams.name }).then(response => {
|
|
||||||
console.log(response)
|
|
||||||
}) */
|
|
||||||
self.pieTableData = pieTableDatas
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
/*this.$nextTick(() => {
|
|
||||||
myChart.doLayout()
|
|
||||||
})*/
|
|
||||||
} else if (this.isTable) {
|
} else if (this.isTable) {
|
||||||
if (chartParams) {
|
if (chartParams) {
|
||||||
const tableColumns = new Set()
|
const tableColumns = new Set()
|
||||||
@@ -297,6 +340,7 @@ export default {
|
|||||||
isSingleValue: isSingleValue(props.chart.type),
|
isSingleValue: isSingleValue(props.chart.type),
|
||||||
isTable: isTable(props.chart.type),
|
isTable: isTable(props.chart.type),
|
||||||
isMap: isMap(props.chart.type),
|
isMap: isMap(props.chart.type),
|
||||||
|
isTitle: isTitle(props.chart.type),
|
||||||
isMapLine: isMapLine(props.chart.type),
|
isMapLine: isMapLine(props.chart.type),
|
||||||
layout: getLayout(props.chart.type)
|
layout: getLayout(props.chart.type)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
<div style="padding: 10px 0 20px 20px;">
|
<div style="padding: 10px 0 20px 20px;">
|
||||||
<div class="cn-panel">
|
<div class="cn-panel">
|
||||||
<div class="panel__time">
|
<div class="panel__time">
|
||||||
<TimeRefresh class="date-time-range" @change="timeRefreshChange" :end-time="endTime"/>
|
|
||||||
<DateTimeRange class="date-time-range" :start-time="startTime" :end-time="endTime" ref="dateTimeRange" @change="reload"/>
|
<DateTimeRange class="date-time-range" :start-time="startTime" :end-time="endTime" ref="dateTimeRange" @change="reload"/>
|
||||||
|
<TimeRefresh class="date-time-range" @change="timeRefreshChange" :end-time="endTime"/>
|
||||||
</div>
|
</div>
|
||||||
<chart v-for="(chart, index) in chartList" :key="index" :chart="chart" :start-time="startTime" :end-time="endTime"></chart>
|
<chart v-for="(chart, index) in chartList" :key="index" :chart="chart" :start-time="startTime" :end-time="endTime"></chart>
|
||||||
<!-- <grid-layout v-model:layout="chartList"
|
<!-- <grid-layout v-model:layout="chartList"
|
||||||
|
|||||||
Reference in New Issue
Block a user