CN-284 echarts图表优化;tabs 切换时数据无法正确显示;

This commit is contained in:
hyx
2022-02-10 17:06:15 +08:00
parent bcd107aa81
commit 7efa110f3b
11 changed files with 212 additions and 418 deletions

View File

@@ -139,13 +139,13 @@
:entity="entity"
></chart-san-key>
<chart-echart-line
v-else-if="isEchartsLine"
<chart-echart
v-else-if="isEchartsLine || isEchartsPie"
:chart-info="chartInfo"
:chart-data="chartData"
:result-type="resultType"
@showLoading="showLoading"
></chart-echart-line>
></chart-echart>
<chart-echart-with-statistics
v-else-if="isEchartsWithStatistics"
@@ -155,14 +155,6 @@
@showLoading="showLoading"
></chart-echart-with-statistics>
<chart-echart-pie
v-else-if="isEchartsPie"
:chart-info="chartInfo"
:chart-data="chartData"
:result-type="resultType"
@showLoading="showLoading"
></chart-echart-pie>
<chart-echart-with-table
v-else-if="isEchartsWithTable"
:chart-info="chartInfo"
@@ -202,9 +194,8 @@ import ChartSingleValue from '@/views/charts/charts/ChartSingleValue'
import ChartBlock from '@/views/charts/charts/ChartBlock'
import ChartGroup from '@/views/charts/charts/ChartGroup'
import IpBasicInfo from '@/views/charts/charts/IpBasicInfo'
import ChartEchartLine from '@/views/charts/charts/ChartEchartLine'
import ChartEchart from '@/views/charts/charts/ChartEchart'
import ChartEchartWithStatistics from '@/views/charts/charts/ChartEchartWithStatistics'
import ChartEchartPie from '@/views/charts/charts/ChartEchartPie'
import ChartEchartWithTable from '@/views/charts/charts/ChartEchartWithTable'
import ChartEchartIpHostedDomain from '@/views/charts/charts/ChartEchartIpHostedDomain'
import ChartEchartAppRelateDomain from '@/views/charts/charts/ChartEchartAppRelateDomain'
@@ -277,9 +268,8 @@ export default {
ChartIpOpenPortBar,
ChartRelationShip,
ChartGroup,
ChartEchartLine,
ChartEchartWithStatistics,
ChartEchartPie,
ChartEchart,
ChartEchartWithTable,
ChartEchartIpHostedDomain,
ChartEchartAppRelateDomain

View File

@@ -0,0 +1,78 @@
<template>
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
</template>
<script>
import unitConvert from '@/utils/unit-convert'
import * as echarts from 'echarts'
import { lineToSpace } from '@/utils/tools'
import { unitTypes } from '@/utils/constants'
import chartEchartMixin from './chart-echart-mixin'
import { getOption, isEchartsPie } from './tools'
import { legendMapping } from '@/components/charts/chart-table-title'
export default {
name: 'ChartEchart',
mixins: [chartEchartMixin],
data () {
return {
}
},
props: {
resultType: Object
},
setup (props) {
return {
isEchartsPie: isEchartsPie(props.chartInfo.type)
}
},
methods: {
initEcharts (id) {
this.initDom(id)
const chartParams = this.chartInfo.params
if (chartParams.showLegend === false) {
this.chartOption.legend.show = false
}
this.handleYaxis()
if (this.isEchartsPie) {
this.chartOption.series[0].data = this.chartData.map(d => {
return {
name: lineToSpace(d.name),
data: d,
value: parseInt(d.num),
unitType: chartParams.unitType ? chartParams.unitType : 'number'
}
})
} else {
const seriesTemplate = this.chartOption.series[0]
this.chartOption.series = this.chartData.map(r => {
return {
...seriesTemplate,
name: legendMapping[`${this.entity && this.entity.ip ? 'ip_' : ''}${r.legend}`] ? legendMapping[`${this.entity && this.entity.ip ? 'ip_' : ''}${r.legend}`] : lineToSpace(r.legend),
data: r.values.map(v => [Number(v[0]) * 1000, Number(v[1]), chartParams.unitType])
}
})
}
const rows = (this.chartData.length - 1) / 4 + 1 // 根据legend个数动态预留legend空间
const gridTop = 10 + 27 * rows
if (chartParams.unitType === unitTypes.byte) {
this.chartOption.yAxis.axisLabel.formatter = function (value, index, a, b) {
return unitConvert(value, unitTypes.byte).join(' ')
}
this.chartOption.grid = {
top: gridTop,
left: 75
}
} else {
this.chartOption.grid = {
top: gridTop
}
}
this.loadEchart()
}
}
}
</script>

View File

@@ -24,31 +24,20 @@ import * as echarts from 'echarts'
import {
ipHostedDomain
} from '@/views/charts/charts/options/pie'
import { replaceUrlPlaceholder, lineToSpace } from '@/utils/tools'
import { get } from '@/utils/http'
import chartEchartMixin from './chart-echart-mixin'
export default {
name: 'ChartEchartAppRelateDomain',
mixins: [chartEchartMixin],
data () {
return {
myChart: null,
myChart2: null,
chartOption: null
}
},
props: {
chartInfo: Object,
chartData: [Array, Object],
entity: Object
},
methods: {
initAppRelatedDomain (id) {
const chartParams = this.chartInfo.params
const dom = document.getElementById(`chart${this.chartInfo.id}-0`)
const dom2 = document.getElementById(`chart${this.chartInfo.id}-1`)
!this.myChart && (this.myChart = echarts.init(dom))
!this.myChart2 && (this.myChart2 = echarts.init(dom2))
this.chartOption = this.$_.cloneDeep(ipHostedDomain)
initEcharts (id) {
this.initDom(id, 2)
this.$emit('showLoading', true)
this.chartOption.series[0].data = [
{
@@ -68,43 +57,7 @@ export default {
value: 7
}
]
this.loadEchartPie()
/*
get(replaceUrlPlaceholder(chartParams.url, { appName: this.entity.appName })).then(response => {
if (response.code === 200) {
if (this.$_.isEmpty(response.data.result)) {
this.noData = true
} else {
this.detailData = response.data.result
this.noData = false
}
}
}).finally(() => {
setTimeout(() => {
this.$emit('showLoading', false)
}, 250)
})
*/
},
loadEchartPie () {
this.$emit('showLoading', true)
try {
this.myChart.setOption(this.chartOption)
this.myChart2.setOption(this.chartOption)
} finally {
setTimeout(() => {
this.$emit('showLoading', false)
}, 200)
}
}
},
watch: {
chartData: {
deep: true,
handler (n) {
this.initAppRelatedDomain(`chart${this.chartInfo.id}`)
}
this.loadEchart(2)
}
}
}

View File

@@ -27,29 +27,22 @@ import {
} from '@/views/charts/charts/options/pie'
import { replaceUrlPlaceholder } from '@/utils/tools'
import { get } from '@/utils/http'
import chartEchartMixin from './chart-echart-mixin'
export default {
name: 'ChartEchartIpHostedDomain',
mixins: [chartEchartMixin],
data () {
return {
myChart: null,
myChart2: null,
chartOption: null
}
},
props: {
chartInfo: Object,
chartData: [Array, Object],
entity: Object
},
methods: {
initIpHostedDomain (id) {
initEcharts (id) {
this.initDom(id, 2)
const chartParams = this.chartInfo.params
const dom = document.getElementById(id + '-0')
const dom2 = document.getElementById(id + '-1')
!this.myChart && (this.myChart = echarts.init(dom))
!this.myChart2 && (this.myChart2 = echarts.init(dom2))
this.chartOption = this.$_.cloneDeep(ipHostedDomain)
this.$emit('showLoading', true)
const byType = new Promise(resolve => {
get(replaceUrlPlaceholder(chartParams.byTypeUrl, { ip: this.entity.ip })).then(response => {
@@ -103,14 +96,6 @@ export default {
}, 1000)
})
}
},
watch: {
chartData: {
deep: true,
handler (n) {
this.initIpHostedDomain(`chart${this.chartInfo.id}`)
}
}
}
}
</script>

View File

@@ -1,106 +0,0 @@
<template>
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
</template>
<script>
import unitConvert from '@/utils/unit-convert'
import * as echarts from 'echarts'
import { lineToSpace } from '@/utils/tools'
import { unitTypes } from '@/utils/constants'
import { legendMapping } from '@/components/charts/chart-table-title'
import {
line
} from '@/views/charts/charts/options/line'
export default {
name: 'ChartEchartLine',
setup () {
const myChart = null
return {
myChart
}
},
data () {
return {
chartOption: null
}
},
props: {
chartInfo: Object,
chartData: [Array, Object],
resultType: Object
},
methods: {
initLine (id) {
const chartParams = this.chartInfo.params
const dom = document.getElementById(id)
!this.myChart && (this.myChart = echarts.init(dom))
this.chartOption = this.$_.cloneDeep(line)
if (chartParams.showLegend === false) {
this.chartOption.legend.show = false
}
const seriesTemplate = this.chartOption.series[0]
const allZero = this.timeLineIsAllZero(this.chartData)
if (allZero) {
this.chartOption.yAxis = {
...this.chartOption.yAxis,
min: 0,
max: 5,
interval: 1
}
}
this.chartOption.series = this.chartData.map(r => {
return {
...seriesTemplate,
name: legendMapping[`${this.entity && this.entity.ip ? 'ip_' : ''}${r.legend}`] ? legendMapping[`${this.entity && this.entity.ip ? 'ip_' : ''}${r.legend}`] : lineToSpace(r.legend),
data: r.values.map(v => [Number(v[0]) * 1000, Number(v[1]), chartParams.unitType])
}
})
const rows = (this.chartData.length - 1) / 4 + 1 // 根据legend个数动态预留legend空间
const gridTop = 10 + 27 * rows
this.chartOption.grid.top = gridTop
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.loadEchartLine()
},
loadEchartLine () {
this.$emit('showLoading', true)
try {
this.myChart.setOption(this.chartOption)
} finally {
setTimeout(() => {
this.$emit('showLoading', false)
}, 200)
}
},
timeLineIsAllZero (data) {
if (this.resultType === 'matrix') {
let allZero = true
try {
data.forEach(d => {
d.values.forEach(r => {
if (r[1] && r[1] !== '0') {
allZero = false
throw new Error('break')
}
})
})
} catch (e) {}
return allZero
}
}
},
watch: {
chartData: {
deep: true,
handler (n) {
this.initLine(`chart${this.chartInfo.id}`)
}
}
}
}
</script>

View File

@@ -1,107 +0,0 @@
<template>
<div class="chart-drawing" :id="`chart${chartInfo.id}`"></div>
</template>
<script>
import unitConvert from '@/utils/unit-convert'
import * as echarts from 'echarts'
import { lineToSpace } from '@/utils/tools'
import { unitTypes } from '@/utils/constants'
import {
pieWithTable
} from '@/views/charts/charts/options/pie'
export default {
name: 'ChartEchartPie',
data () {
return {
myChart: null,
chartOption: null
}
},
props: {
chartInfo: Object,
chartData: [Array, Object],
resultType: Object
},
methods: {
initPie (id) {
const chartParams = this.chartInfo.params
const dom = document.getElementById(id)
!this.myChart && (this.myChart = echarts.init(dom))
this.chartOption = this.$_.cloneDeep(pieWithTable)
if (chartParams.showLegend === false) {
this.chartOption.legend.show = false
}
const allZero = this.timeLineIsAllZero(this.chartData)
if (allZero) {
this.chartOption.yAxis = {
...this.chartOption.yAxis,
min: 0,
max: 5,
interval: 1
}
}
this.chartOption.series[0].data = this.chartData.map(d => {
return {
data: d,
name: lineToSpace(d.name),
value: parseInt(d.num),
unitType: chartParams.unitType
}
})
const rows = (this.chartData.length - 1) / 4 + 1 // 根据legend个数动态预留legend空间
const gridTop = 10 + 27 * rows
if (chartParams.unitType === unitTypes.byte) {
this.chartOption.yAxis.axisLabel.formatter = function (value, index, a, b) {
return unitConvert(value, unitTypes.byte).join(' ')
}
this.chartOption.grid = {
top: gridTop,
left: 75
}
} else {
this.chartOption.grid = {
top: gridTop
}
}
this.loadEchartPie()
},
loadEchartPie () {
this.$emit('showLoading', true)
try {
this.myChart.setOption(this.chartOption)
} finally {
setTimeout(() => {
this.$emit('showLoading', false)
}, 200)
}
},
timeLineIsAllZero (data) {
if (this.resultType === 'matrix') {
let allZero = true
try {
data.forEach(d => {
d.values.forEach(r => {
if (r[1] && r[1] !== '0') {
allZero = false
throw new Error('break')
}
})
})
} catch (e) {}
return allZero
}
}
},
watch: {
chartData: {
deep: true,
handler (n) {
this.initPie(`chart${this.chartInfo.id}`)
}
}
}
}
</script>

View File

@@ -14,25 +14,18 @@ import {
import {
getChartColor
} from '@/views/charts/charts/chart-options'
import chartEchartMixin from './chart-echart-mixin'
export default {
name: 'ChartEchartWithStatistics',
setup () {
const myChart = null
return {
myChart
}
},
mixins: [chartEchartMixin],
data () {
return {
chartOption: null,
statisticsData: [],
statisticsHeight: 280
}
},
props: {
chartInfo: Object,
chartData: [Array, Object],
resultType: Object
},
components: {
@@ -46,20 +39,10 @@ export default {
}
},
methods: {
initEchartsWithStatistics (id) {
initEcharts (id) {
this.initDom(id)
const chartParams = this.chartInfo.params
const dom = document.getElementById(id)
!this.myChart && (this.myChart = echarts.init(dom))
this.chartOption = this.$_.cloneDeep(lineWithStatistics)
const allZero = this.timeLineIsAllZero(this.chartData)
if (allZero) {
this.chartOption.yAxis = {
...this.chartOption.yAxis,
min: 0,
max: 5,
interval: 1
}
}
this.handleYaxis()
this.statisticsData = this.chartData.map(d => {
return {
...d,
@@ -77,34 +60,7 @@ export default {
}
}
})
this.loadEchartWithStatistics()
},
loadEchartWithStatistics () {
this.$emit('showLoading', true)
try {
this.myChart.setOption(this.chartOption)
} finally {
setTimeout(() => {
this.$emit('showLoading', false)
}, 200)
}
},
timeLineIsAllZero (data) {
if (this.resultType === 'matrix') {
let allZero = true
try {
data.forEach(d => {
d.values.forEach(r => {
if (r[1] && r[1] !== '0') {
allZero = false
throw new Error('break')
}
})
})
} catch (e) {}
return allZero
}
this.loadEchart()
},
toggleStatisticsLegend (index) {
this.statisticsData[index].active = !this.statisticsData[index].active
@@ -124,12 +80,6 @@ export default {
}
},
watch: {
chartData: {
deep: true,
handler (n) {
this.initEchartsWithStatistics(`chart${this.chartInfo.id}`)
}
},
statisticsHeight (val) {
const dom = document.getElementById(`chart${this.chartInfo.id}`)
dom.style.cssText += `height: calc(100% - ${val}px)`

View File

@@ -18,21 +18,19 @@ import {
import { getUnitType } from '@/utils/unit-convert'
import { replaceUrlPlaceholder } from '@/utils/tools'
import { get } from '@/utils/http'
import chartEchartMixin from './chart-echart-mixin'
export default {
name: 'ChartEchartWithTable',
mixins: [chartEchartMixin],
data () {
return {
myChart: null,
chartOption: null,
pieTableData: [],
selectPieChartName: '',
allSelectPieChartName: []
}
},
props: {
chartInfo: Object,
chartData: [Array, Object],
resultType: Object,
queryParams: Object,
orderPieTable: Object
@@ -43,33 +41,20 @@ export default {
mounted () {
},
methods: {
handleQueryParams(queryParams) {
handleQueryParams (queryParams) {
return this.timeFilter = {
startTime:Number(queryParams.startTime)*1000,
endTime:Number(queryParams.endTime)*1000
startTime: Number(queryParams.startTime) * 1000,
endTime: Number(queryParams.endTime) * 1000
}
},
initEchartsWithTable (id) {
initEcharts (id) {
this.initDom(id)
const chartParams = this.chartInfo.params
const dom = document.getElementById(id)
!this.myChart && (this.myChart = echarts.init(dom))
this.chartOption = this.$_.cloneDeep(pieWithTable)
chartParams.valueColumn = this.orderPieTable
const unitType = getUnitType(chartParams.valueColumn)
const tableQueryParams = this.$_.cloneDeep(this.queryParams)
tableQueryParams[chartParams.nameColumn] = [] // 处理两个图表不一样的地方)
const allZero = this.timeLineIsAllZero(this.chartData)
if (allZero) {
this.chartOption.yAxis = {
...this.chartOption.yAxis,
min: 0,
max: 5,
interval: 1
}
}
this.handleYaxis()
const data = this.chartData.map(d => {
if (d[chartParams.nameColumn]) {
this.allSelectPieChartName.push(d[chartParams.nameColumn])
@@ -87,7 +72,7 @@ export default {
if (this.chartOption.series[0].data && this.chartOption.series[0].data.length > 10) { // pieWithTable 图例超过10个改为滚动显示
this.chartOption.legend.type = 'scroll'
}
this.loadEchartWithTable()
this.loadEchart()
if (!this.$_.isEmpty(data)) {
get(replaceUrlPlaceholder(chartParams.urlTable, tableQueryParams)).then(response => {
@@ -130,11 +115,8 @@ export default {
// 饼图色块点击事件
this.myChart.off('click')
this.myChart.on('click', function (echartParams) {
console.log(echartParams)
console.log(self.selectPieChartName)
// 若是已选,则点击后取消选择,并查询全部数据
if (echartParams.name === self.selectPieChartName) {
console.log(1)
self.selectPieChartName = ''
self.loadPieTableData(this.allSelectPieChartName)
} else { // 否则查询当前name数据
@@ -152,41 +134,6 @@ export default {
this.pieTableData = response.data.result
}
})
},
loadEchartWithTable () {
this.$emit('showLoading', true)
try {
this.myChart.setOption(this.chartOption)
} finally {
setTimeout(() => {
this.$emit('showLoading', false)
}, 200)
}
},
timeLineIsAllZero (data) {
if (this.resultType === 'matrix') {
let allZero = true
try {
data.forEach(d => {
d.values.forEach(r => {
if (r[1] && r[1] !== '0') {
allZero = false
throw new Error('break')
}
})
})
} catch (e) {}
return allZero
}
}
},
watch: {
chartData: {
deep: true,
handler (n) {
this.initEchartsWithTable(`chart${this.chartInfo.id}`)
}
}
}
}

View File

@@ -12,6 +12,7 @@
:ref="`chart-${chartInfo.id}`"
>
<panel-chart-list
v-if="activeTab == tab.id"
:time-filter="timeFilter"
:data-list="tab.children"
:panel-lock="true"

View File

@@ -0,0 +1,102 @@
import { shallowRef } from 'vue'
import * as echarts from 'echarts'
import {
isEchartsLine,
isEchartsPie,
isEchartsWithTable,
isEchartsWithStatistics,
isIpHostedDomain,
isAppRelatedDomain,
getOption
} from './tools'
export default {
props: {
chartInfo: Object,
chartData: [Object, Array, String] // 数据在父组件查询后传入,本组件内不查询,只根据接传递的数据来渲染
},
setup (props) {
return {
myChart: shallowRef(null),
myChart2: shallowRef(null), // 个别有两个图表的chart
isEchartsLine: isEchartsLine(props.chartInfo.type),
isEchartsPie: isEchartsPie(props.chartInfo.type),
isEchartsWithTable: isEchartsWithTable(props.chartInfo.type),
isEchartsWithStatistics: isEchartsWithStatistics(props.chartInfo.type),
isAppRelatedDomain: isAppRelatedDomain(props.chartInfo.type),
isIpHostedDomain: isIpHostedDomain(props.chartInfo.type)
}
},
data () {
return {
chartOption: null
}
},
methods: {
initDom (id, chartNum) {
if (chartNum && chartNum == 2) {
const dom = document.getElementById(id + '-0')
const dom2 = document.getElementById(id + '-1')
!this.myChart && (this.myChart = echarts.init(dom))
!this.myChart2 && (this.myChart2 = echarts.init(dom2))
} else {
const dom = document.getElementById(id)
!this.myChart && (this.myChart = echarts.init(dom))
}
this.chartOption = this.$_.cloneDeep(getOption(this.chartInfo.type))
},
// 出来y轴相关配置
handleYaxis () {
const allZero = this.timeLineIsAllZero(this.chartData)
if (allZero) {
this.chartOption.yAxis = {
...this.chartOption.yAxis,
min: 0,
max: 5,
interval: 1
}
}
},
timeLineIsAllZero (data) {
if (this.resultType === 'matrix') {
let allZero = true
try {
data.forEach(d => {
d.values.forEach(r => {
if (r[1] && r[1] !== '0') {
allZero = false
throw new Error('break')
}
})
})
} catch (e) {}
return allZero
}
},
loadEchart (chartNum) {
this.$emit('showLoading', true)
try {
this.myChart.setOption(this.chartOption)
if (chartNum && chartNum == 2) {
this.myChart2.setOption(this.chartOption)
}
} finally {
setTimeout(() => {
this.$emit('showLoading', false)
}, 200)
}
}
},
watch: {
chartData: {
deep: true,
handler (n) {
if (this.chartData && this.chartData.length > 0) {
this.initEcharts(`chart${this.chartInfo.id}`)
}
}
}
}
}

View File

@@ -26,7 +26,8 @@ const typeOptionMappings = [
{ value: 22, option: ipOpenPortBar }, // ip详情--开放端口的柱状图
{ value: 23, option: timeBar }, // 矿机所属单位
{ value: 24, option: categoryBar }, // 挖矿事件统计
{ value: 31, option: pieWithTable }, // 常规折线
{ value: 31, option: pieWithTable }, // 常规
{ value: 32, option: pieWithTable }, // 带表格饼图
{ value: 33, option: ipHostedDomain }, // ip详情--托管域名
{ value: 34, option: ipHostedDomain }, // app详情--相关域名
{ value: 42, option: relationShip }, // 关系图