CN-65 perf: 数据的单位的展示逻辑完善
This commit is contained in:
@@ -28,8 +28,11 @@
|
||||
>
|
||||
<template #header>{{c.label}}</template>
|
||||
<template #default="{ row }">{{}}
|
||||
<span v-if="c.prop === 'bytes' || c.prop === 'packets' || c.prop === 'sessions'" >
|
||||
{{shortFormatter(row[c.prop])}}
|
||||
<span v-if="c.prop === 'bytes'">
|
||||
{{unitConvert(row[c.prop], unitTypes.byte).join(' ')}}
|
||||
</span>
|
||||
<span v-else-if="c.prop === 'packets' || c.prop === 'sessions'">
|
||||
{{unitConvert(row[c.prop], unitTypes.number).join(' ')}}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{row[c.prop]}}
|
||||
@@ -45,15 +48,19 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { shortFormatter } from '@/components/charts/chart-formatter'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
export default {
|
||||
name: 'ChartTable',
|
||||
props: {
|
||||
tableColumns: Array,
|
||||
tableData: Array
|
||||
},
|
||||
methods: {
|
||||
shortFormatter: shortFormatter
|
||||
setup () {
|
||||
return {
|
||||
unitTypes,
|
||||
unitConvert
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -36,8 +36,11 @@
|
||||
<span v-if="item.prop === 'nameColumn'">
|
||||
{{ nameColumn === 'fqdnCategoryName' ? row['fqdnCategoryName'] : row['reputationLevel'] }}
|
||||
</span>
|
||||
<span v-else-if="item.prop === 'bytes' || item.prop === 'packets' || item.prop === 'sessions'">
|
||||
{{ shortFormatter(row[item.prop]) }}
|
||||
<span v-else-if="item.prop === 'bytes'">
|
||||
{{unitConvert(row[item.prop], unitTypes.byte).join(' ')}}
|
||||
</span>
|
||||
<span v-else-if="item.prop === 'packets' || item.prop === 'sessions'">
|
||||
{{unitConvert(row[item.prop], unitTypes.number).join(' ')}}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ row[item.prop] }}
|
||||
@@ -57,8 +60,11 @@
|
||||
<span v-if="item.prop === 'nameColumn'">
|
||||
{{ nameColumn === 'fqdnCategoryName' ? row['categoryName'] : row['reputationLevel'] }}
|
||||
</span>
|
||||
<span v-else-if="item.prop === 'bytes' || item.prop === 'packets' || item.prop === 'sessions'">
|
||||
{{ shortFormatter(row[item.prop]) }}
|
||||
<span v-else-if="item.prop === 'bytes'">
|
||||
{{unitConvert(row[item.prop], unitTypes.byte).join(' ')}}
|
||||
</span>
|
||||
<span v-else-if="item.prop === 'packets' || item.prop === 'sessions'">
|
||||
{{unitConvert(row[item.prop], unitTypes.number).join(' ')}}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ row[item.prop] }}
|
||||
@@ -68,9 +74,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { shortFormatter } from '@/components/charts/chart-formatter'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import { get } from '@/utils/http'
|
||||
import { replaceUrlPlaceholder } from '@/utils/tools'
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
|
||||
export default {
|
||||
name: 'PieTable',
|
||||
@@ -78,12 +85,7 @@ export default {
|
||||
tableData: Array,
|
||||
chartInfo: Object,
|
||||
order: String,
|
||||
startTime: {
|
||||
type: Number
|
||||
},
|
||||
endTime: {
|
||||
type: Number
|
||||
}
|
||||
timeFilter: Object
|
||||
},
|
||||
watch: {
|
||||
tableData: {
|
||||
@@ -170,7 +172,6 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
shortFormatter: shortFormatter,
|
||||
// rowChange (echartParams) {
|
||||
// const nameColumnKey = this.nameColumn === 'fqdnCategoryName' ? 'categoryName' : 'reputationLevel'
|
||||
// const row = this.pieTableData.find(item => echartParams.name === item[nameColumnKey])
|
||||
@@ -185,8 +186,8 @@ export default {
|
||||
// this.$refs.table.toggleRowExpansion(row)
|
||||
const url = this.chartInfo.params.urlChildrenTable
|
||||
const queryParams = {
|
||||
startTime: parseInt(this.startTime / 1000),
|
||||
endTime: parseInt(this.endTime / 1000),
|
||||
startTime: parseInt(this.timeFilter.startTime / 1000),
|
||||
endTime: parseInt(this.timeFilter.endTime / 1000),
|
||||
order: this.order,
|
||||
domain: row.domain,
|
||||
limit: 10
|
||||
@@ -205,6 +206,12 @@ export default {
|
||||
getRowKey (row) {
|
||||
return row.domain
|
||||
}
|
||||
},
|
||||
setup () {
|
||||
return {
|
||||
unitTypes,
|
||||
unitConvert
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
<div v-for="(item,index) in data" :key="index" class="table-below-box">
|
||||
<div class="table__below-color"><div :style="{backgroundColor: getChartColor(index)}"></div></div>
|
||||
<div class="table__below-title" :title="item.legend">{{item.legend}}</div>
|
||||
<div class="table__below-statistics" :title="item.aggregation.max">{{shortFormatter(item.aggregation.max)}}</div>
|
||||
<div class="table__below-statistics" :title="item.aggregation.avg">{{shortFormatter(item.aggregation.avg)}}</div>
|
||||
<div class="table__below-statistics" :title="item.aggregation.avg">{{unitConvert(item.aggregation.avg)}}</div>
|
||||
<div class="table__below-statistics" :title="item.aggregation.max">{{unitConvert(item.aggregation.max)}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -18,24 +18,16 @@
|
||||
|
||||
<script>
|
||||
import { getChartColor } from '@/components/charts/chart-options'
|
||||
import { shortFormatter } from '@/components/charts/chart-formatter'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
export default {
|
||||
name: 'StatisticsLegend',
|
||||
props: {
|
||||
data: Array
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
handler (n) {
|
||||
}
|
||||
}
|
||||
},
|
||||
setup () {
|
||||
return {
|
||||
getChartColor,
|
||||
shortFormatter
|
||||
unitConvert
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
const shortList = [' ', 'K', 'M', 'G', 'T', 'Quadrillion', 'Quintillion']
|
||||
function asciiCompute (num, ascii, units, dot = 2) {
|
||||
if (!num && num !== 0 && num !== '0') {
|
||||
return ''
|
||||
}
|
||||
num = Number(num)
|
||||
let carry = 0
|
||||
if (num > 1) {
|
||||
const log = Math.log(num) / Math.log(ascii)
|
||||
carry = parseInt(log)
|
||||
num = num / Math.pow(ascii, carry)
|
||||
}
|
||||
if (Number.isInteger(num)) {
|
||||
return num + ' ' + units[carry]
|
||||
} else {
|
||||
return num.toFixed(dot) + ' ' + units[carry]
|
||||
}
|
||||
}
|
||||
export function shortFormatter (value, index, dot = 2) {
|
||||
return asciiCompute(value, 1000, shortList, dot)
|
||||
}
|
||||
/* 时间单位转换,例如将ms转为h */
|
||||
const timeStep = [ // 步进倍数,以ms为基数
|
||||
{ unit: 'ms', step: 1 },
|
||||
{ unit: 's', step: 1000 },
|
||||
{ unit: 'm', step: 60 },
|
||||
{ unit: 'h', step: 60 },
|
||||
{ unit: 'd', step: 24 }
|
||||
]
|
||||
export function timeUnitFormatter (time, sourceUnit = 'ms', targetUnit, dot = 2) {
|
||||
let sourceIndex = -1
|
||||
let targetIndex = -1
|
||||
timeStep.forEach((t, i) => {
|
||||
sourceUnit === t.unit && (sourceIndex = i)
|
||||
targetUnit && targetUnit === t.unit && (targetIndex = i)
|
||||
})
|
||||
let multi = 1
|
||||
let result = parseFloat(time)
|
||||
if (targetIndex < 0) {
|
||||
while (sourceIndex < timeStep.length - 1 && result > timeStep[sourceIndex + 1].step) {
|
||||
sourceIndex++
|
||||
multi = timeStep[sourceIndex].step
|
||||
result /= multi
|
||||
}
|
||||
return [multi === 1 ? result : result.toFixed(dot), timeStep[sourceIndex].unit]
|
||||
} else {
|
||||
timeStep.forEach((s, i) => {
|
||||
if (i <= targetIndex) {
|
||||
multi *= s.step
|
||||
}
|
||||
})
|
||||
result /= multi
|
||||
return [result.toFixed(dot), targetUnit]
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,8 @@
|
||||
* @description chart option和一些工具
|
||||
*/
|
||||
import { format } from 'echarts'
|
||||
import { shortFormatter, timeUnitFormatter } from './chart-formatter'
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import _ from 'lodash'
|
||||
export const chartColor = ['#5370C6', '#90CC74', '#FAC858', '#EE6666',
|
||||
'#73BFDE', '#3BA172', '#FC8452', '#9960B4',
|
||||
@@ -32,9 +33,12 @@ const line = {
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
formatter: shortFormatter
|
||||
formatter: function (value, index, a, b) {
|
||||
return unitConvert(value, unitTypes.number).join(' ')
|
||||
}
|
||||
},
|
||||
minInterval: 1
|
||||
},
|
||||
animation: false,
|
||||
grid: {
|
||||
left: 55,
|
||||
@@ -93,9 +97,11 @@ const lineWithStatistics = {
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
formatter: shortFormatter
|
||||
formatter: function (value, index) {
|
||||
return unitConvert(value, unitTypes.number).join(' ')
|
||||
}
|
||||
|
||||
},
|
||||
minInterval: 1
|
||||
},
|
||||
color: chartColor,
|
||||
grid: {
|
||||
@@ -139,9 +145,11 @@ const lineStack = {
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
formatter: shortFormatter
|
||||
formatter: function (value, index) {
|
||||
return unitConvert(value, unitTypes.number).join(' ')
|
||||
}
|
||||
|
||||
},
|
||||
minInterval: 1
|
||||
},
|
||||
grid: {
|
||||
left: 55,
|
||||
@@ -209,7 +217,7 @@ const pieWithTable = {
|
||||
},
|
||||
tooltip: {
|
||||
formatter: function (param, index, callback) {
|
||||
return `${param.name}: ${shortFormatter(param.value)}`
|
||||
return `${param.name}: ${unitConvert(param.value, param.data.unitType).join(' ')}`
|
||||
}
|
||||
},
|
||||
emphasis: {
|
||||
@@ -332,7 +340,7 @@ function axiosFormatter (params) {
|
||||
${item.seriesName}
|
||||
</span>`
|
||||
str += `<span class="cn-chart-tooltip-value">
|
||||
${shortFormatter(item.data[1])}
|
||||
${unitConvert(item.data[1], item.data[2]).join(' ')}
|
||||
</span>`
|
||||
str += '</div>'
|
||||
})
|
||||
|
||||
@@ -54,6 +54,12 @@ export const entityTypeMappingKey = {
|
||||
ip: ['country', 'region']
|
||||
}
|
||||
|
||||
export const unitTypes = {
|
||||
time: 'time',
|
||||
number: 'number',
|
||||
byte: 'byte'
|
||||
}
|
||||
|
||||
export const chartTableDefaultPageSize = 10 // table类型图表默认每页数据量
|
||||
export const chartTableTopOptions = [10, 100] // table类型图表的TOP-N选项
|
||||
export const chartPieTableTopOptions = [{ name: 'Sessions', value: 'sessions' }, { name: 'Packets', value: 'packets' }, { name: 'Bytes', value: 'bytes' }] // table类型图表的TOP-N选项
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// 获取初始化时间,默认最近一周
|
||||
import moment from 'moment-timezone'
|
||||
|
||||
Date.prototype.setStart = function () {
|
||||
this.setHours(0)
|
||||
this.setMinutes(0)
|
||||
|
||||
101
src/utils/unit-convert.js
Normal file
101
src/utils/unit-convert.js
Normal file
@@ -0,0 +1,101 @@
|
||||
import { unitTypes } from '@/utils/constants'
|
||||
|
||||
const numberUnit = ['', 'K', 'M', 'G', 'T', 'P', 'E']
|
||||
const byteUnit = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB']
|
||||
const timeUnit = [ // 时间单位步进倍数,以ms为基数
|
||||
{ unit: 'ms', step: 1 },
|
||||
{ unit: 's', step: 1000 },
|
||||
{ unit: 'm', step: 60 },
|
||||
{ unit: 'h', step: 60 },
|
||||
{ unit: 'd', step: 24 }
|
||||
]
|
||||
function asciiCompute (num, ascii = 1000, units, dot = 2) {
|
||||
if (!num && num !== 0 && num !== '0') {
|
||||
return ['', '']
|
||||
}
|
||||
num = Number(num)
|
||||
let carry = 0
|
||||
if (num > 1) {
|
||||
const log = Math.log(num) / Math.log(ascii)
|
||||
carry = parseInt(log)
|
||||
num = num / Math.pow(ascii, carry)
|
||||
}
|
||||
if (Number.isInteger(num)) {
|
||||
return [num, units[carry]]
|
||||
} else {
|
||||
return [num.toFixed(dot), units[carry]]
|
||||
}
|
||||
}
|
||||
|
||||
export function numberUnitConvert (value, sourceUnit, targetUnit, dot = 2) {
|
||||
return asciiCompute(value, 1000, numberUnit, dot)
|
||||
}
|
||||
export function byteUnitConvert (value, sourceUnit = 'B', targetUnit, dot = 2) {
|
||||
return asciiCompute(value, 1024, byteUnit, dot)
|
||||
}
|
||||
/* 时间单位转换,例如将ms转为h */
|
||||
export function timeUnitFormatter (time, sourceUnit = 'ms', targetUnit, dot = 2) {
|
||||
let sourceIndex = -1
|
||||
let targetIndex = -1
|
||||
timeUnit.forEach((t, i) => {
|
||||
sourceUnit === t.unit && (sourceIndex = i)
|
||||
targetUnit && targetUnit === t.unit && (targetIndex = i)
|
||||
})
|
||||
let multi = 1
|
||||
let result = parseFloat(time)
|
||||
if (targetIndex < 0) {
|
||||
while (sourceIndex < timeUnit.length - 1 && result > timeUnit[sourceIndex + 1].step) {
|
||||
sourceIndex++
|
||||
multi = timeUnit[sourceIndex].step
|
||||
result /= multi
|
||||
}
|
||||
return [multi === 1 ? result : result.toFixed(dot), timeUnit[sourceIndex].unit]
|
||||
} else {
|
||||
timeUnit.forEach((s, i) => {
|
||||
if (i <= targetIndex) {
|
||||
multi *= s.step
|
||||
}
|
||||
})
|
||||
result /= multi
|
||||
return [result.toFixed(dot), targetUnit]
|
||||
}
|
||||
}
|
||||
|
||||
/* 单位转换,返回转换后的[value, unit] */
|
||||
// unitType = time / number / byte
|
||||
export default function unitConvert (value, unitType, sourceUnit, targetUnit, dot = 2) {
|
||||
if (!Number(value) && Number(value) !== 0) {
|
||||
return ['-', '']
|
||||
} else {
|
||||
switch (unitType) {
|
||||
case unitTypes.time: {
|
||||
return timeUnitFormatter(value, sourceUnit, targetUnit, dot)
|
||||
}
|
||||
case unitTypes.number: {
|
||||
return numberUnitConvert(value, sourceUnit, targetUnit, dot)
|
||||
}
|
||||
case unitTypes.byte: {
|
||||
return byteUnitConvert(value, sourceUnit, targetUnit, dot)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getUnitType (column) {
|
||||
if (column) {
|
||||
switch (column.toLowerCase()) {
|
||||
case 'time': {
|
||||
return unitTypes.time
|
||||
}
|
||||
case 'bytes': {
|
||||
return unitTypes.byte
|
||||
}
|
||||
case 'sessions':
|
||||
default: {
|
||||
return unitTypes.number
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return unitTypes.number
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,8 @@
|
||||
:style="computePosition">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</div>
|
||||
<!-- Tabs -->
|
||||
<el-tabs
|
||||
v-else-if="isTabs"
|
||||
class="cn-chart cn-chart__tabs"
|
||||
v-else-if="isTabs"
|
||||
v-model="activeTab"
|
||||
@tab-click="changeTab"
|
||||
:style="computePosition"
|
||||
@@ -17,8 +17,8 @@
|
||||
:label="tab.i18n ? $t(tab.i18n) : tab.name" :name="`${tab.id}`"
|
||||
:key="tab.id"
|
||||
>
|
||||
<template v-for="(chart, index) in tab.children">
|
||||
<chart v-if="activeTab == tab.id" :key="index" :chart="chart" :start-time="startTime" :end-time="endTime"></chart>
|
||||
<template v-for="chart in tab.children">
|
||||
<chart v-if="activeTab == tab.id" :key="chart.id" :chart="chart" :time-filter="timeFilter" :ref="`chart-${chart.id}`"></chart>
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
@@ -64,10 +64,10 @@
|
||||
<template #default>
|
||||
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
|
||||
</template>
|
||||
<template #footer v-if="layout.indexOf(layoutConstant.FOOTER) > -1" :class="{}">
|
||||
<template #footer v-if="layout.indexOf(layoutConstant.FOOTER) > -1">
|
||||
<!-- 带Table的饼图,展示Table -->
|
||||
<template v-if="isEchartsWithTable">
|
||||
<pie-table :tableData="pieTableData" ref="pieTable" :chartInfo="chartInfo" :start-time="startTime" :end-time="endTime" :order="orderPieTable"/>
|
||||
<pie-table :tableData="pieTableData" ref="pieTable" :chartInfo="chartInfo" :time-filter="timeFilter" :order="orderPieTable"/>
|
||||
</template>
|
||||
<template v-else-if="isEchartsWithStatistics">
|
||||
<statistics-legend :data="statisticsData"></statistics-legend>
|
||||
@@ -84,7 +84,7 @@
|
||||
<template #title><span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span></template>
|
||||
<template #data>
|
||||
<span>{{handleSingleValue[0]}}</span>
|
||||
<span v-if="chartInfo.params && chartInfo.params.unit" class="single-value__unit">{{handleSingleValue[1]}}</span>
|
||||
<span class="single-value__unit">{{handleSingleValue[1]}}</span>
|
||||
</template>
|
||||
</single-value>
|
||||
<!-- 表格 -->
|
||||
@@ -174,8 +174,8 @@ import ChartMap from '@/components/charts/ChartMap'
|
||||
import PieTable from '@/components/charts/PieTable'
|
||||
import StatisticsLegend from '@/components/charts/StatisticsLegend'
|
||||
import ChartTablePagination from '@/components/charts/ChartTablePagination'
|
||||
import { shortFormatter, timeUnitFormatter } from '@/components/charts/chart-formatter'
|
||||
import { chartTableDefaultPageSize, chartTableTopOptions, storageKey, chartPieTableTopOptions } from '@/utils/constants'
|
||||
import unitConvert, { getUnitType } from '@/utils/unit-convert'
|
||||
import { chartTableDefaultPageSize, chartTableTopOptions, storageKey, chartPieTableTopOptions, unitTypes } from '@/utils/constants'
|
||||
import { get } from '@/utils/http'
|
||||
import { replaceUrlPlaceholder, getCapitalGeo, getGeoData, lineToSpace } from '@/utils/tools'
|
||||
|
||||
@@ -183,12 +183,7 @@ export default {
|
||||
name: 'Chart',
|
||||
props: {
|
||||
chart: Object, // 图表对象,包括id、name、type等数据
|
||||
startTime: {
|
||||
type: Number
|
||||
},
|
||||
endTime: {
|
||||
type: Number
|
||||
}
|
||||
timeFilter: Object
|
||||
},
|
||||
components: {
|
||||
EchartsFrame,
|
||||
@@ -248,7 +243,7 @@ export default {
|
||||
} else if (this.isSingleValue) {
|
||||
if (chartParams) {
|
||||
this.singleValue.icon = chartParams.icon
|
||||
const queryParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000) }
|
||||
const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000) }
|
||||
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.singleValue.value = response.data.result
|
||||
@@ -261,19 +256,29 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
reloadChart () {
|
||||
this.initChart()
|
||||
this.$nextTick(() => {
|
||||
this.$_.forIn(this.$refs, (ref, key) => {
|
||||
if (this.$_.startsWith(key, 'chart-')) {
|
||||
ref.reloadChart()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
getTitle (r) {
|
||||
let title = ''
|
||||
if (r.establishLatency || r.httpResponseLatency || r.sslConLatency) {
|
||||
title = `${title}: ${timeUnitFormatter(r.establishLatency || r.httpResponseLatency || r.sslConLatency).join(' ')}`
|
||||
title = `${title}: ${unitConvert(r.establishLatency || r.httpResponseLatency || r.sslConLatency, unitTypes.time).join(' ')}`
|
||||
}
|
||||
if (r.sequenceGapLossPercent || r.pktRetransPercent) {
|
||||
title = `${title}: ${shortFormatter(r.sequenceGapLossPercent || r.pktRetransPercent)} %`
|
||||
title = `${title}: ${unitConvert(r.sequenceGapLossPercent || r.pktRetransPercent, unitTypes.number).join(' ')} %`
|
||||
}
|
||||
if (r.sessions) {
|
||||
title = `${title}\nSessions: ${shortFormatter(r.sessions)}`
|
||||
title = `${title}\nSessions: ${unitConvert(r.sessions, unitTypes.number).join(' ')}`
|
||||
}
|
||||
if (r.bytes) {
|
||||
title = `${title}\nBytes: ${shortFormatter(r.bytes)}`
|
||||
title = `${title}\nBytes: ${unitConvert(r.bytes, unitTypes.byte).join(' ')}`
|
||||
}
|
||||
return title
|
||||
},
|
||||
@@ -300,7 +305,7 @@ export default {
|
||||
},
|
||||
loadMap (polygonSeries) {
|
||||
const chartParams = this.chartInfo.params
|
||||
const queryParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000), country: '', region: '' } // 统计数据的查询参数
|
||||
const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000), country: '', region: '' } // 统计数据的查询参数
|
||||
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
|
||||
if (response.code === 200) {
|
||||
const data = response.data.result
|
||||
@@ -415,7 +420,7 @@ export default {
|
||||
}
|
||||
},
|
||||
initECharts (chartParams) {
|
||||
const queryParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000) }
|
||||
const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000) }
|
||||
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
|
||||
if (response.code === 200) {
|
||||
const seriesTemplate = this.chartOption.series[0]
|
||||
@@ -423,9 +428,15 @@ export default {
|
||||
return {
|
||||
...seriesTemplate,
|
||||
name: legendMapping[r.legend] ? legendMapping[r.legend] : lineToSpace(r.legend),
|
||||
data: r.values.map(v => [Number(v[0]) * 1000, Number(v[1])])
|
||||
data: r.values.map(v => [Number(v[0]) * 1000, Number(v[1]), chartParams.unitType])
|
||||
}
|
||||
})
|
||||
if (chartParams.unitType === unitTypes.byte) {
|
||||
this.chartOption.yAxis.axisLabel.formatter = function (value, index, a, b) {
|
||||
return unitConvert(value, unitTypes.byte).join(' ')
|
||||
}
|
||||
this.chartOption.grid.left = 75
|
||||
}
|
||||
}
|
||||
this.myChart.setOption(this.chartOption)
|
||||
this.$nextTick(() => {
|
||||
@@ -434,7 +445,7 @@ export default {
|
||||
})
|
||||
},
|
||||
initEchartsWithStatistics (chartParams) {
|
||||
const queryParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000) }
|
||||
const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000) }
|
||||
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.statisticsData = response.data.result
|
||||
@@ -443,7 +454,7 @@ export default {
|
||||
return {
|
||||
...seriesTemplate,
|
||||
name: r.legend,
|
||||
data: r.values.map(v => [Number(v[0]) * 1000, Number(v[1])]),
|
||||
data: r.values.map(v => [Number(v[0]) * 1000, Number(v[1]), chartParams.unitType]),
|
||||
lineStyle: {
|
||||
color: getChartColor[i]
|
||||
}
|
||||
@@ -459,8 +470,9 @@ export default {
|
||||
initEchartsWithPieTable (chartParams) {
|
||||
const self = this
|
||||
chartParams.valueColumn = this.orderPieTable
|
||||
const queryParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000), limit: 10, order: this.orderPieTable } // 统计数据的查询参数
|
||||
const tableQueryParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000), limit: 10, order: this.orderPieTable } // 统计数据的查询参数
|
||||
const unitType = getUnitType(chartParams.valueColumn)
|
||||
const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000), limit: 10, order: this.orderPieTable } // 统计数据的查询参数
|
||||
const tableQueryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000), limit: 10, order: this.orderPieTable } // 统计数据的查询参数
|
||||
tableQueryParams[chartParams.nameColumn] = [] // 处理两个图表不一样的地方
|
||||
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
|
||||
if (response.code === 200) {
|
||||
@@ -469,7 +481,8 @@ export default {
|
||||
return {
|
||||
data: d,
|
||||
name: d[chartParams.nameColumn],
|
||||
value: parseInt(d[chartParams.valueColumn])
|
||||
value: parseInt(d[chartParams.valueColumn]),
|
||||
unitType: unitType
|
||||
}
|
||||
})
|
||||
this.chartOption.series[0].data = data
|
||||
@@ -493,6 +506,9 @@ export default {
|
||||
legend: { selected: { [params.name]: true } }
|
||||
})
|
||||
self.chartOption.series[0].data.forEach((d, i) => {
|
||||
// 遍历到当前点击的legend时
|
||||
if (d.name === params.name) {
|
||||
// 如果这个legend是已激活状态,则取消激活,并且查询全部
|
||||
if (self.selectPieChartName === d.name) {
|
||||
self.myChart.dispatchAction({
|
||||
type: 'unselect',
|
||||
@@ -501,8 +517,7 @@ export default {
|
||||
})
|
||||
self.selectPieChartName = ''
|
||||
self.loadPieTableData()
|
||||
} else {
|
||||
if (d.name === params.name) {
|
||||
} else { // 否则激活,并且查询当前name的数据
|
||||
self.selectPieChartName = d.name
|
||||
self.myChart.dispatchAction({
|
||||
type: 'select',
|
||||
@@ -510,6 +525,7 @@ export default {
|
||||
dataIndex: i
|
||||
})
|
||||
self.loadPieTableData(params.name)
|
||||
}
|
||||
} else {
|
||||
self.myChart.dispatchAction({
|
||||
type: 'unselect',
|
||||
@@ -517,16 +533,22 @@ export default {
|
||||
dataIndex: i
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
// 饼图色块点击事件
|
||||
this.myChart.on('click', function (echartParams) {
|
||||
// 若是已选,则点击后取消选择,并查询全部数据
|
||||
if (echartParams.name === self.selectPieChartName) {
|
||||
self.selectPieChartName = ''
|
||||
self.loadPieTableData()
|
||||
} else { // 否则查询当前name数据
|
||||
self.selectPieChartName = echartParams.name
|
||||
self.loadPieTableData(echartParams.name)
|
||||
}
|
||||
})
|
||||
},
|
||||
loadPieTableData (name = '') {
|
||||
const childrenParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000), limit: 10, order: this.orderPieTable }
|
||||
const childrenParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000), limit: 10, order: this.orderPieTable }
|
||||
childrenParams[this.chartInfo.params.nameColumn] = name
|
||||
get(replaceUrlPlaceholder(this.chartInfo.params.urlTable, childrenParams)).then(response => {
|
||||
if (response.code === 200) {
|
||||
@@ -539,7 +561,7 @@ export default {
|
||||
this.initChartTable(chartParams)
|
||||
},
|
||||
initChartTable (chartParams) {
|
||||
const queryParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000), limit: this.table.limit, order: this.table.orderBy }
|
||||
const queryParams = { startTime: parseInt(this.timeFilter.startTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000), limit: this.table.limit, order: this.table.orderBy }
|
||||
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
|
||||
if (response.code === 200) {
|
||||
this.table.tableColumns = allTableTitle['tableTitles' + this.chart.id]
|
||||
@@ -560,16 +582,21 @@ export default {
|
||||
},
|
||||
handleSingleValue () {
|
||||
const value = this.singleValue.value
|
||||
const unit = this.chartInfo.params.unit
|
||||
if (!Number(value) && Number(value) !== 0) {
|
||||
return '-'
|
||||
} else {
|
||||
if (unit && unit === 'ms') {
|
||||
return Number(value) < 1 ? ['< 1', 'ms'] : timeUnitFormatter(value, null, 0)
|
||||
} else {
|
||||
return Number(value) < 0.01 ? ['< 0.01', ''] : [shortFormatter(value), '']
|
||||
const unitType = this.chartInfo.params.unitType
|
||||
const result = unitConvert(value, unitType)
|
||||
switch (unitType) {
|
||||
case unitTypes.number: {
|
||||
result[0] = result[0] < 0.01 ? '< 0.01' : result[0]
|
||||
break
|
||||
}
|
||||
case unitTypes.time: {
|
||||
result[0] = result[0] < 1 ? '< 1' : result[0]
|
||||
break
|
||||
}
|
||||
default: break
|
||||
}
|
||||
console.info(result)
|
||||
return result
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<div style="padding: 10px 0 20px 20px;">
|
||||
<div class="cn-panel" id="cn-panel">
|
||||
<div class="panel__time">
|
||||
<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"/>
|
||||
<DateTimeRange class="date-time-range" :start-time="timeFilter.startTime" :end-time="timeFilter.endTime" ref="dateTimeRange" @change="reload"/>
|
||||
<TimeRefresh class="date-time-range" @change="timeRefreshChange" :end-time="timeFilter.endTime"/>
|
||||
</div>
|
||||
<chart v-for="(chart, index) in chartList" :key="index" :chart="chart" :start-time="startTime" :end-time="endTime"></chart>
|
||||
<chart v-for="chart in chartList" :key="chart.id" :chart="chart" :time-filter="timeFilter" :ref="`chart-${chart.id}`"></chart>
|
||||
<!-- <grid-layout v-model:layout="chartList"
|
||||
:col-num="12"
|
||||
:row-height="30"
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
<script>
|
||||
import { useRoute } from 'vue-router'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import { panelTypeAndRouteMapping } from '@/utils/constants'
|
||||
import { api, getPanelList, getChartList } from '@/utils/api'
|
||||
import { getNowTime } from '@/utils/date-util'
|
||||
@@ -47,7 +47,7 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
||||
chartList: []
|
||||
}
|
||||
},
|
||||
async mounted () {
|
||||
@@ -55,39 +55,18 @@ export default {
|
||||
},
|
||||
setup (props, ctx) {
|
||||
// data
|
||||
const chartList = ref([])
|
||||
const dateRangeValue = ref(60)
|
||||
const now = getNowTime(dateRangeValue.value)
|
||||
const startTime = ref(now.startTime)
|
||||
const endTime = ref(now.endTime)
|
||||
const dateRangeValue = 60
|
||||
const { startTime, endTime } = getNowTime(dateRangeValue)
|
||||
const timeFilter = { startTime, endTime, dateRangeValue }
|
||||
const panel = ref({})
|
||||
let panelType = 1 // 取得panel的type
|
||||
const { params } = useRoute()
|
||||
// refs
|
||||
const dateTimeRange = ref(null)
|
||||
|
||||
panelTypeAndRouteMapping[params.typeName] && (panelType = panelTypeAndRouteMapping[params.typeName])
|
||||
// onMounted
|
||||
onMounted(() => {
|
||||
dateTimeRange.value.isCustom = false
|
||||
dateTimeRange.value.dateRangeValue = dateRangeValue
|
||||
})
|
||||
// methods
|
||||
const dateTimeRangeChange = (s, e, v) => {
|
||||
startTime.value = s
|
||||
endTime.value = e
|
||||
dateRangeValue.value = v
|
||||
}
|
||||
return {
|
||||
panelType,
|
||||
chartList,
|
||||
panel,
|
||||
startTime,
|
||||
endTime,
|
||||
dateRangeValue,
|
||||
dateTimeRange,
|
||||
api,
|
||||
dateTimeRangeChange
|
||||
timeFilter,
|
||||
api
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -103,21 +82,30 @@ export default {
|
||||
})
|
||||
}
|
||||
},
|
||||
async timeRefreshChange () {
|
||||
timeRefreshChange () {
|
||||
if (!this.$refs.dateTimeRange) {
|
||||
await this.init()
|
||||
this.reloadCharts()
|
||||
return
|
||||
}
|
||||
if (this.$refs.dateTimeRange.isCustom) {
|
||||
await this.init()
|
||||
this.reloadCharts()
|
||||
} else {
|
||||
const value = this.dateRangeValue.value || this.dateRangeValue
|
||||
const value = this.timeFilter.dateRangeValue
|
||||
this.$refs.dateTimeRange.quickChange(value)
|
||||
}
|
||||
},
|
||||
async reload (s, e, v) {
|
||||
reload (s, e, v) {
|
||||
this.dateTimeRangeChange(s, e, v)
|
||||
await this.init()
|
||||
this.reloadCharts()
|
||||
},
|
||||
// methods
|
||||
dateTimeRangeChange (s, e, v) {
|
||||
this.timeFilter = { startTime: s, endTime: e, dateRangeValue: v }
|
||||
},
|
||||
reloadCharts () {
|
||||
this.chartList.forEach(chart => {
|
||||
this.$refs[`chart-${chart.id}`] && this.$refs[`chart-${chart.id}`].reloadChart()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +232,6 @@ export default {
|
||||
filterType: this.filterType,
|
||||
loadFilter
|
||||
})
|
||||
console.info(this.filterData)
|
||||
},
|
||||
setup () {
|
||||
const filterType = ref(Object.keys(entityType)[0])
|
||||
|
||||
Reference in New Issue
Block a user