CN-65 perf: 数据的单位的展示逻辑完善

This commit is contained in:
chenjinsong
2021-07-21 22:46:08 +08:00
parent 1f28cb7148
commit 3ae20a4a85
11 changed files with 275 additions and 197 deletions

View File

@@ -28,8 +28,11 @@
> >
<template #header>{{c.label}}</template> <template #header>{{c.label}}</template>
<template #default="{ row }">{{}} <template #default="{ row }">{{}}
<span v-if="c.prop === 'bytes' || c.prop === 'packets' || c.prop === 'sessions'" > <span v-if="c.prop === 'bytes'">
{{shortFormatter(row[c.prop])}} {{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>
<span v-else> <span v-else>
{{row[c.prop]}} {{row[c.prop]}}
@@ -45,15 +48,19 @@
</template> </template>
<script> <script>
import { shortFormatter } from '@/components/charts/chart-formatter' import unitConvert from '@/utils/unit-convert'
import { unitTypes } from '@/utils/constants'
export default { export default {
name: 'ChartTable', name: 'ChartTable',
props: { props: {
tableColumns: Array, tableColumns: Array,
tableData: Array tableData: Array
}, },
methods: { setup () {
shortFormatter: shortFormatter return {
unitTypes,
unitConvert
}
} }
} }
</script> </script>

View File

@@ -36,8 +36,11 @@
<span v-if="item.prop === 'nameColumn'"> <span v-if="item.prop === 'nameColumn'">
{{ nameColumn === 'fqdnCategoryName' ? row['fqdnCategoryName'] : row['reputationLevel'] }} {{ nameColumn === 'fqdnCategoryName' ? row['fqdnCategoryName'] : row['reputationLevel'] }}
</span> </span>
<span v-else-if="item.prop === 'bytes' || item.prop === 'packets' || item.prop === 'sessions'"> <span v-else-if="item.prop === 'bytes'">
{{ shortFormatter(row[item.prop]) }} {{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>
<span v-else> <span v-else>
{{ row[item.prop] }} {{ row[item.prop] }}
@@ -54,23 +57,27 @@
:label="item.label" :label="item.label"
:prop="item.prop" :prop="item.prop"
#default="{row}"> #default="{row}">
<span v-if="item.prop === 'nameColumn'"> <span v-if="item.prop === 'nameColumn'">
{{ nameColumn === 'fqdnCategoryName' ? row['categoryName'] : row['reputationLevel'] }} {{ nameColumn === 'fqdnCategoryName' ? row['categoryName'] : row['reputationLevel'] }}
</span> </span>
<span v-else-if="item.prop === 'bytes' || item.prop === 'packets' || item.prop === 'sessions'"> <span v-else-if="item.prop === 'bytes'">
{{ shortFormatter(row[item.prop]) }} {{unitConvert(row[item.prop], unitTypes.byte).join(' ')}}
</span> </span>
<span v-else-if="item.prop === 'packets' || item.prop === 'sessions'">
{{unitConvert(row[item.prop], unitTypes.number).join(' ')}}
</span>
<span v-else> <span v-else>
{{ row[item.prop] }} {{ row[item.prop] }}
</span> </span>
</el-table-column> </el-table-column>
</el-table> </el-table>
</template> </template>
<script> <script>
import { shortFormatter } from '@/components/charts/chart-formatter' import unitConvert from '@/utils/unit-convert'
import { get } from '@/utils/http' import { get } from '@/utils/http'
import { replaceUrlPlaceholder } from '@/utils/tools' import { replaceUrlPlaceholder } from '@/utils/tools'
import { unitTypes } from '@/utils/constants'
export default { export default {
name: 'PieTable', name: 'PieTable',
@@ -78,12 +85,7 @@ export default {
tableData: Array, tableData: Array,
chartInfo: Object, chartInfo: Object,
order: String, order: String,
startTime: { timeFilter: Object
type: Number
},
endTime: {
type: Number
}
}, },
watch: { watch: {
tableData: { tableData: {
@@ -170,7 +172,6 @@ export default {
} }
}, },
methods: { methods: {
shortFormatter: shortFormatter,
// rowChange (echartParams) { // rowChange (echartParams) {
// const nameColumnKey = this.nameColumn === 'fqdnCategoryName' ? 'categoryName' : 'reputationLevel' // const nameColumnKey = this.nameColumn === 'fqdnCategoryName' ? 'categoryName' : 'reputationLevel'
// const row = this.pieTableData.find(item => echartParams.name === item[nameColumnKey]) // const row = this.pieTableData.find(item => echartParams.name === item[nameColumnKey])
@@ -185,8 +186,8 @@ export default {
// this.$refs.table.toggleRowExpansion(row) // this.$refs.table.toggleRowExpansion(row)
const url = this.chartInfo.params.urlChildrenTable const url = this.chartInfo.params.urlChildrenTable
const queryParams = { const queryParams = {
startTime: parseInt(this.startTime / 1000), startTime: parseInt(this.timeFilter.startTime / 1000),
endTime: parseInt(this.endTime / 1000), endTime: parseInt(this.timeFilter.endTime / 1000),
order: this.order, order: this.order,
domain: row.domain, domain: row.domain,
limit: 10 limit: 10
@@ -205,6 +206,12 @@ export default {
getRowKey (row) { getRowKey (row) {
return row.domain return row.domain
} }
},
setup () {
return {
unitTypes,
unitConvert
}
} }
} }
</script> </script>

View File

@@ -8,8 +8,8 @@
<div v-for="(item,index) in data" :key="index" class="table-below-box"> <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-color"><div :style="{backgroundColor: getChartColor(index)}"></div></div>
<div class="table__below-title" :title="item.legend">{{item.legend}}</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">{{unitConvert(item.aggregation.avg)}}</div>
<div class="table__below-statistics" :title="item.aggregation.avg">{{shortFormatter(item.aggregation.avg)}}</div> <div class="table__below-statistics" :title="item.aggregation.max">{{unitConvert(item.aggregation.max)}}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -18,24 +18,16 @@
<script> <script>
import { getChartColor } from '@/components/charts/chart-options' import { getChartColor } from '@/components/charts/chart-options'
import { shortFormatter } from '@/components/charts/chart-formatter' import unitConvert from '@/utils/unit-convert'
export default { export default {
name: 'StatisticsLegend', name: 'StatisticsLegend',
props: { props: {
data: Array data: Array
}, },
watch: {
data: {
immediate: true,
deep: true,
handler (n) {
}
}
},
setup () { setup () {
return { return {
getChartColor, getChartColor,
shortFormatter unitConvert
} }
} }
} }

View File

@@ -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]
}
}

View File

@@ -4,7 +4,8 @@
* @description chart option和一些工具 * @description chart option和一些工具
*/ */
import { format } from 'echarts' import { format } from 'echarts'
import { shortFormatter, timeUnitFormatter } from './chart-formatter' import { unitTypes } from '@/utils/constants'
import unitConvert from '@/utils/unit-convert'
import _ from 'lodash' import _ from 'lodash'
export const chartColor = ['#5370C6', '#90CC74', '#FAC858', '#EE6666', export const chartColor = ['#5370C6', '#90CC74', '#FAC858', '#EE6666',
'#73BFDE', '#3BA172', '#FC8452', '#9960B4', '#73BFDE', '#3BA172', '#FC8452', '#9960B4',
@@ -32,8 +33,11 @@ const line = {
yAxis: { yAxis: {
type: 'value', type: 'value',
axisLabel: { axisLabel: {
formatter: shortFormatter formatter: function (value, index, a, b) {
} return unitConvert(value, unitTypes.number).join(' ')
}
},
minInterval: 1
}, },
animation: false, animation: false,
grid: { grid: {
@@ -93,9 +97,11 @@ const lineWithStatistics = {
yAxis: { yAxis: {
type: 'value', type: 'value',
axisLabel: { axisLabel: {
formatter: shortFormatter formatter: function (value, index) {
} return unitConvert(value, unitTypes.number).join(' ')
}
},
minInterval: 1
}, },
color: chartColor, color: chartColor,
grid: { grid: {
@@ -139,9 +145,11 @@ const lineStack = {
yAxis: { yAxis: {
type: 'value', type: 'value',
axisLabel: { axisLabel: {
formatter: shortFormatter formatter: function (value, index) {
} return unitConvert(value, unitTypes.number).join(' ')
}
},
minInterval: 1
}, },
grid: { grid: {
left: 55, left: 55,
@@ -209,7 +217,7 @@ const pieWithTable = {
}, },
tooltip: { tooltip: {
formatter: function (param, index, callback) { formatter: function (param, index, callback) {
return `${param.name}: ${shortFormatter(param.value)}` return `${param.name}: ${unitConvert(param.value, param.data.unitType).join(' ')}`
} }
}, },
emphasis: { emphasis: {
@@ -332,7 +340,7 @@ function axiosFormatter (params) {
${item.seriesName} ${item.seriesName}
</span>` </span>`
str += `<span class="cn-chart-tooltip-value"> str += `<span class="cn-chart-tooltip-value">
${shortFormatter(item.data[1])} ${unitConvert(item.data[1], item.data[2]).join(' ')}
</span>` </span>`
str += '</div>' str += '</div>'
}) })

View File

@@ -54,6 +54,12 @@ export const entityTypeMappingKey = {
ip: ['country', 'region'] ip: ['country', 'region']
} }
export const unitTypes = {
time: 'time',
number: 'number',
byte: 'byte'
}
export const chartTableDefaultPageSize = 10 // table类型图表默认每页数据量 export const chartTableDefaultPageSize = 10 // table类型图表默认每页数据量
export const chartTableTopOptions = [10, 100] // table类型图表的TOP-N选项 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选项 export const chartPieTableTopOptions = [{ name: 'Sessions', value: 'sessions' }, { name: 'Packets', value: 'packets' }, { name: 'Bytes', value: 'bytes' }] // table类型图表的TOP-N选项

View File

@@ -1,6 +1,4 @@
// 获取初始化时间,默认最近一周 // 获取初始化时间,默认最近一周
import moment from 'moment-timezone'
Date.prototype.setStart = function () { Date.prototype.setStart = function () {
this.setHours(0) this.setHours(0)
this.setMinutes(0) this.setMinutes(0)

101
src/utils/unit-convert.js Normal file
View 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
}
}

View File

@@ -6,8 +6,8 @@
:style="computePosition">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</div> :style="computePosition">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</div>
<!-- Tabs --> <!-- Tabs -->
<el-tabs <el-tabs
v-else-if="isTabs"
class="cn-chart cn-chart__tabs" class="cn-chart cn-chart__tabs"
v-else-if="isTabs"
v-model="activeTab" v-model="activeTab"
@tab-click="changeTab" @tab-click="changeTab"
:style="computePosition" :style="computePosition"
@@ -17,8 +17,8 @@
:label="tab.i18n ? $t(tab.i18n) : tab.name" :name="`${tab.id}`" :label="tab.i18n ? $t(tab.i18n) : tab.name" :name="`${tab.id}`"
:key="tab.id" :key="tab.id"
> >
<template v-for="(chart, index) in tab.children"> <template v-for="chart in tab.children">
<chart v-if="activeTab == tab.id" :key="index" :chart="chart" :start-time="startTime" :end-time="endTime"></chart> <chart v-if="activeTab == tab.id" :key="chart.id" :chart="chart" :time-filter="timeFilter" :ref="`chart-${chart.id}`"></chart>
</template> </template>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
@@ -64,10 +64,10 @@
<template #default> <template #default>
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div> <div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
</template> </template>
<template #footer v-if="layout.indexOf(layoutConstant.FOOTER) > -1" :class="{}"> <template #footer v-if="layout.indexOf(layoutConstant.FOOTER) > -1">
<!-- 带Table的饼图展示Table --> <!-- 带Table的饼图展示Table -->
<template v-if="isEchartsWithTable"> <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>
<template v-else-if="isEchartsWithStatistics"> <template v-else-if="isEchartsWithStatistics">
<statistics-legend :data="statisticsData"></statistics-legend> <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 #title><span :title="chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name">{{chartInfo.i18n ? $t(chartInfo.i18n) : chartInfo.name}}</span></template>
<template #data> <template #data>
<span>{{handleSingleValue[0]}}</span> <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> </template>
</single-value> </single-value>
<!-- 表格 --> <!-- 表格 -->
@@ -174,8 +174,8 @@ import ChartMap from '@/components/charts/ChartMap'
import PieTable from '@/components/charts/PieTable' import PieTable from '@/components/charts/PieTable'
import StatisticsLegend from '@/components/charts/StatisticsLegend' import StatisticsLegend from '@/components/charts/StatisticsLegend'
import ChartTablePagination from '@/components/charts/ChartTablePagination' import ChartTablePagination from '@/components/charts/ChartTablePagination'
import { shortFormatter, timeUnitFormatter } from '@/components/charts/chart-formatter' import unitConvert, { getUnitType } from '@/utils/unit-convert'
import { chartTableDefaultPageSize, chartTableTopOptions, storageKey, chartPieTableTopOptions } from '@/utils/constants' import { chartTableDefaultPageSize, chartTableTopOptions, storageKey, chartPieTableTopOptions, unitTypes } from '@/utils/constants'
import { get } from '@/utils/http' import { get } from '@/utils/http'
import { replaceUrlPlaceholder, getCapitalGeo, getGeoData, lineToSpace } from '@/utils/tools' import { replaceUrlPlaceholder, getCapitalGeo, getGeoData, lineToSpace } from '@/utils/tools'
@@ -183,12 +183,7 @@ export default {
name: 'Chart', name: 'Chart',
props: { props: {
chart: Object, // 图表对象包括id、name、type等数据 chart: Object, // 图表对象包括id、name、type等数据
startTime: { timeFilter: Object
type: Number
},
endTime: {
type: Number
}
}, },
components: { components: {
EchartsFrame, EchartsFrame,
@@ -248,7 +243,7 @@ export default {
} else if (this.isSingleValue) { } else if (this.isSingleValue) {
if (chartParams) { if (chartParams) {
this.singleValue.icon = chartParams.icon 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 => { get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
if (response.code === 200) { if (response.code === 200) {
this.singleValue.value = response.data.result 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) { getTitle (r) {
let title = '' let title = ''
if (r.establishLatency || r.httpResponseLatency || r.sslConLatency) { 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) { 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) { if (r.sessions) {
title = `${title}\nSessions: ${shortFormatter(r.sessions)}` title = `${title}\nSessions: ${unitConvert(r.sessions, unitTypes.number).join(' ')}`
} }
if (r.bytes) { if (r.bytes) {
title = `${title}\nBytes: ${shortFormatter(r.bytes)}` title = `${title}\nBytes: ${unitConvert(r.bytes, unitTypes.byte).join(' ')}`
} }
return title return title
}, },
@@ -300,7 +305,7 @@ export default {
}, },
loadMap (polygonSeries) { loadMap (polygonSeries) {
const chartParams = this.chartInfo.params 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 => { get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
if (response.code === 200) { if (response.code === 200) {
const data = response.data.result const data = response.data.result
@@ -415,7 +420,7 @@ export default {
} }
}, },
initECharts (chartParams) { 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 => { get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
if (response.code === 200) { if (response.code === 200) {
const seriesTemplate = this.chartOption.series[0] const seriesTemplate = this.chartOption.series[0]
@@ -423,9 +428,15 @@ export default {
return { return {
...seriesTemplate, ...seriesTemplate,
name: legendMapping[r.legend] ? legendMapping[r.legend] : lineToSpace(r.legend), 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.myChart.setOption(this.chartOption)
this.$nextTick(() => { this.$nextTick(() => {
@@ -434,7 +445,7 @@ export default {
}) })
}, },
initEchartsWithStatistics (chartParams) { 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 => { get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
if (response.code === 200) { if (response.code === 200) {
this.statisticsData = response.data.result this.statisticsData = response.data.result
@@ -443,7 +454,7 @@ export default {
return { return {
...seriesTemplate, ...seriesTemplate,
name: r.legend, 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: { lineStyle: {
color: getChartColor[i] color: getChartColor[i]
} }
@@ -459,8 +470,9 @@ export default {
initEchartsWithPieTable (chartParams) { initEchartsWithPieTable (chartParams) {
const self = this const self = this
chartParams.valueColumn = this.orderPieTable chartParams.valueColumn = this.orderPieTable
const queryParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000), limit: 10, order: this.orderPieTable } // 统计数据的查询参数 const unitType = getUnitType(chartParams.valueColumn)
const tableQueryParams = { startTime: parseInt(this.startTime / 1000), endTime: parseInt(this.endTime / 1000), limit: 10, order: this.orderPieTable } // 统计数据的查询参数 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] = [] // 处理两个图表不一样的地方 tableQueryParams[chartParams.nameColumn] = [] // 处理两个图表不一样的地方
get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => { get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
if (response.code === 200) { if (response.code === 200) {
@@ -469,7 +481,8 @@ export default {
return { return {
data: d, data: d,
name: d[chartParams.nameColumn], name: d[chartParams.nameColumn],
value: parseInt(d[chartParams.valueColumn]) value: parseInt(d[chartParams.valueColumn]),
unitType: unitType
} }
}) })
this.chartOption.series[0].data = data this.chartOption.series[0].data = data
@@ -493,16 +506,18 @@ export default {
legend: { selected: { [params.name]: true } } legend: { selected: { [params.name]: true } }
}) })
self.chartOption.series[0].data.forEach((d, i) => { self.chartOption.series[0].data.forEach((d, i) => {
if (self.selectPieChartName === d.name) { // 遍历到当前点击的legend时
self.myChart.dispatchAction({ if (d.name === params.name) {
type: 'unselect', // 如果这个legend是已激活状态则取消激活并且查询全部
seriesIndex: 0, if (self.selectPieChartName === d.name) {
dataIndex: i self.myChart.dispatchAction({
}) type: 'unselect',
self.selectPieChartName = '' seriesIndex: 0,
self.loadPieTableData() dataIndex: i
} else { })
if (d.name === params.name) { self.selectPieChartName = ''
self.loadPieTableData()
} else { // 否则激活并且查询当前name的数据
self.selectPieChartName = d.name self.selectPieChartName = d.name
self.myChart.dispatchAction({ self.myChart.dispatchAction({
type: 'select', type: 'select',
@@ -510,23 +525,30 @@ export default {
dataIndex: i dataIndex: i
}) })
self.loadPieTableData(params.name) self.loadPieTableData(params.name)
} else {
self.myChart.dispatchAction({
type: 'unselect',
seriesIndex: 0,
dataIndex: i
})
} }
} else {
self.myChart.dispatchAction({
type: 'unselect',
seriesIndex: 0,
dataIndex: i
})
} }
}) })
}) })
// 饼图色块点击事件 // 饼图色块点击事件
this.myChart.on('click', function (echartParams) { this.myChart.on('click', function (echartParams) {
self.loadPieTableData(echartParams.name) // 若是已选,则点击后取消选择,并查询全部数据
if (echartParams.name === self.selectPieChartName) {
self.selectPieChartName = ''
self.loadPieTableData()
} else { // 否则查询当前name数据
self.selectPieChartName = echartParams.name
self.loadPieTableData(echartParams.name)
}
}) })
}, },
loadPieTableData (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 childrenParams[this.chartInfo.params.nameColumn] = name
get(replaceUrlPlaceholder(this.chartInfo.params.urlTable, childrenParams)).then(response => { get(replaceUrlPlaceholder(this.chartInfo.params.urlTable, childrenParams)).then(response => {
if (response.code === 200) { if (response.code === 200) {
@@ -539,7 +561,7 @@ export default {
this.initChartTable(chartParams) this.initChartTable(chartParams)
}, },
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 => { get(replaceUrlPlaceholder(chartParams.url, queryParams)).then(response => {
if (response.code === 200) { if (response.code === 200) {
this.table.tableColumns = allTableTitle['tableTitles' + this.chart.id] this.table.tableColumns = allTableTitle['tableTitles' + this.chart.id]
@@ -560,16 +582,21 @@ export default {
}, },
handleSingleValue () { handleSingleValue () {
const value = this.singleValue.value const value = this.singleValue.value
const unit = this.chartInfo.params.unit const unitType = this.chartInfo.params.unitType
if (!Number(value) && Number(value) !== 0) { const result = unitConvert(value, unitType)
return '-' switch (unitType) {
} else { case unitTypes.number: {
if (unit && unit === 'ms') { result[0] = result[0] < 0.01 ? '< 0.01' : result[0]
return Number(value) < 1 ? ['< 1', 'ms'] : timeUnitFormatter(value, null, 0) break
} else {
return Number(value) < 0.01 ? ['< 0.01', ''] : [shortFormatter(value), '']
} }
case unitTypes.time: {
result[0] = result[0] < 1 ? '< 1' : result[0]
break
}
default: break
} }
console.info(result)
return result
} }
}, },
mounted () { mounted () {

View File

@@ -2,10 +2,10 @@
<div style="padding: 10px 0 20px 20px;"> <div style="padding: 10px 0 20px 20px;">
<div class="cn-panel" id="cn-panel"> <div class="cn-panel" id="cn-panel">
<div class="panel__time"> <div class="panel__time">
<DateTimeRange class="date-time-range" :start-time="startTime" :end-time="endTime" ref="dateTimeRange" @change="reload"/> <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="endTime"/> <TimeRefresh class="date-time-range" @change="timeRefreshChange" :end-time="timeFilter.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 in chartList" :key="chart.id" :chart="chart" :time-filter="timeFilter" :ref="`chart-${chart.id}`"></chart>
<!-- <grid-layout v-model:layout="chartList" <!-- <grid-layout v-model:layout="chartList"
:col-num="12" :col-num="12"
:row-height="30" :row-height="30"
@@ -30,7 +30,7 @@
<script> <script>
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { ref, onMounted } from 'vue' import { ref } from 'vue'
import { panelTypeAndRouteMapping } from '@/utils/constants' import { panelTypeAndRouteMapping } from '@/utils/constants'
import { api, getPanelList, getChartList } from '@/utils/api' import { api, getPanelList, getChartList } from '@/utils/api'
import { getNowTime } from '@/utils/date-util' import { getNowTime } from '@/utils/date-util'
@@ -47,7 +47,7 @@ export default {
}, },
data () { data () {
return { return {
chartList: []
} }
}, },
async mounted () { async mounted () {
@@ -55,39 +55,18 @@ export default {
}, },
setup (props, ctx) { setup (props, ctx) {
// data // data
const chartList = ref([]) const dateRangeValue = 60
const dateRangeValue = ref(60) const { startTime, endTime } = getNowTime(dateRangeValue)
const now = getNowTime(dateRangeValue.value) const timeFilter = { startTime, endTime, dateRangeValue }
const startTime = ref(now.startTime)
const endTime = ref(now.endTime)
const panel = ref({}) const panel = ref({})
let panelType = 1 // 取得panel的type let panelType = 1 // 取得panel的type
const { params } = useRoute() const { params } = useRoute()
// refs
const dateTimeRange = ref(null)
panelTypeAndRouteMapping[params.typeName] && (panelType = panelTypeAndRouteMapping[params.typeName]) 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 { return {
panelType, panelType,
chartList,
panel, panel,
startTime, timeFilter,
endTime, api
dateRangeValue,
dateTimeRange,
api,
dateTimeRangeChange
} }
}, },
methods: { methods: {
@@ -103,21 +82,30 @@ export default {
}) })
} }
}, },
async timeRefreshChange () { timeRefreshChange () {
if (!this.$refs.dateTimeRange) { if (!this.$refs.dateTimeRange) {
await this.init() this.reloadCharts()
return return
} }
if (this.$refs.dateTimeRange.isCustom) { if (this.$refs.dateTimeRange.isCustom) {
await this.init() this.reloadCharts()
} else { } else {
const value = this.dateRangeValue.value || this.dateRangeValue const value = this.timeFilter.dateRangeValue
this.$refs.dateTimeRange.quickChange(value) this.$refs.dateTimeRange.quickChange(value)
} }
}, },
async reload (s, e, v) { reload (s, e, v) {
this.dateTimeRangeChange(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()
})
} }
} }
} }

View File

@@ -232,7 +232,6 @@ export default {
filterType: this.filterType, filterType: this.filterType,
loadFilter loadFilter
}) })
console.info(this.filterData)
}, },
setup () { setup () {
const filterType = ref(Object.keys(entityType)[0]) const filterType = ref(Object.keys(entityType)[0])