feat: traffic summary

This commit is contained in:
chenjinsong
2021-06-25 19:11:00 +08:00
parent c8103735b7
commit 08f3cb17a0
5 changed files with 128 additions and 65 deletions

View File

@@ -242,12 +242,9 @@ const pieWithTable = {
series: [
{
type: 'pie',
top: '10%',
left: '10%',
width: 'auto',
radius: ['50%', '80%'],
center: ['25%', '50%'],
data: pieData,
radius: ['42%', '70%'],
center: ['30%', '50%'],
data: [],
emphasis: {
itemStyle: {
shadowBlur: 10,

View File

@@ -14,6 +14,7 @@
position: absolute;
right: 20px;
top: 20px;
display: flex;
}
.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__header {
border-bottom: 1px solid $--content-right-background-color;

View File

@@ -385,3 +385,14 @@ export function replaceUrlPlaceholder (url, params) {
})
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()
}

View File

@@ -1,7 +1,11 @@
<template>
<div
v-if="isTitle"
class="cn-chart cn-chart__title"
:style="computePosition">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</div>
<!-- 地图 -->
<chart-map
v-if="isMap"
v-else-if="isMap"
:style="computePosition"
>
<template #title>{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</template>
@@ -105,6 +109,7 @@ import {
isEcharts,
isSingleValue,
isTable,
isTitle,
isMap,
getOption,
getTypeCategory,
@@ -123,9 +128,7 @@ import PieTable from '@/components/charts/PieTable'
import ChartTablePagination from '@/components/charts/ChartTablePagination'
import { chartTableDefaultPageSize, chartTableTopOptions } from '@/utils/constants'
import { get } from '@/utils/http'
import { replaceUrlPlaceholder } from '@/utils/tools'
let myChart // echarts或amcharts实例
import { replaceUrlPlaceholder, lineToHump } from '@/utils/tools'
export default {
name: 'Chart',
@@ -156,36 +159,79 @@ export default {
tableData: [], // table的所有数据
currentPageData: [] // table当前页的数据
},
pieTableData: []
pieTableData: [],
myChart: null
}
},
methods: {
initChart () {
const self = this
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 } // 统计数据的查询参数
this.myChart = this.initMap(`chart${this.chartInfo.id}`)
const queryParams = { startTime: 1593070343, endTime: this.endTime } // 统计数据的查询参数
if (chartParams) {
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
console.info(response)
})
} */
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(mapResponse => {
if (mapResponse.data.length > 100) {
mapResponse.data = mapResponse.data.slice(0, 100)
}
if (this.isMapLine) {
const lineSeries = myChart.series.push(new am4Maps.MapLineSeries())
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: d.server_latitude, longitude: d.server_longitude }, { latitude: d.client_latitude, longitude: d.client_longitude }]
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) {
const dom = document.getElementById(`chart${this.chartInfo.id}`)
myChart = echarts.init(dom)
myChart.setOption(this.chartOption)
this.myChart = echarts.init(dom)
if (chartParams) {
if (this.isEchartsWithTable) {
const queryParams = { startTime: 1593070343, endTime: this.endTime } // 统计数据的查询参数
const tableQueryParams = { startTime: 1593070343, endTime: this.endTime } // 统计数据的查询参数
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
const data = response.data.map(d => {
const trans = {}
Object.keys(d).forEach(k => {
trans[lineToHump(k)] = d[k]
})
return trans
})
this.chartOption.legend.formatter = (name) => { // 根据图表宽 显示legend的字数
let str = name
const length = Math.floor(dom.offsetWidth / 75)
@@ -194,35 +240,32 @@ export default {
}
return str
}
myChart.setOption(this.chartOption)
if (this.chartOption.series[0].data.length > 10) { // pieWithTable 图例超过10个改为滚动显示
this.chartOption.legend.type = 'scroll'
myChart.setOption(this.chartOption)
this.chartOption.series[0].data = data.map(d => {
return {
data: d,
name: d[chartParams.nameColumn],
value: parseInt(d[chartParams.valueColumn])
}
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
})
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)
}
}
/*this.$nextTick(() => {
myChart.doLayout()
})*/
} else if (this.isTable) {
if (chartParams) {
const tableColumns = new Set()
@@ -297,6 +340,7 @@ export default {
isSingleValue: isSingleValue(props.chart.type),
isTable: isTable(props.chart.type),
isMap: isMap(props.chart.type),
isTitle: isTitle(props.chart.type),
isMapLine: isMapLine(props.chart.type),
layout: getLayout(props.chart.type)
}

View File

@@ -2,8 +2,8 @@
<div style="padding: 10px 0 20px 20px;">
<div class="cn-panel">
<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"/>
<TimeRefresh class="date-time-range" @change="timeRefreshChange" :end-time="endTime"/>
</div>
<chart v-for="(chart, index) in chartList" :key="index" :chart="chart" :start-time="startTime" :end-time="endTime"></chart>
<!-- <grid-layout v-model:layout="chartList"