feat:抽取图表公共参数 优化valuemapping display的逻辑

This commit is contained in:
zhangyu
2021-12-09 10:34:11 +08:00
parent 76332a0ce8
commit 2e7316272a
13 changed files with 1257 additions and 1081 deletions

View File

@@ -43,6 +43,12 @@
:chart-info="chartInfo" :chart-info="chartInfo"
:chart-option="chartOption" :chart-option="chartOption"
></chart-text> ></chart-text>
<chart-treemap
v-if="isTreemap(chartInfo.type)"
:chart-data="chartData"
:chart-info="chartInfo"
:chart-option="chartOption"
></chart-treemap>
</template> </template>
</div> </div>
</template> </template>
@@ -67,7 +73,7 @@ import chartTreemap from './chart/chartTreemap'
import chartUrl from './chart/chartUrl' import chartUrl from './chart/chartUrl'
import chartValue from './chart/chartValue' import chartValue from './chart/chartValue'
import chartHexagon from './chart/chartHexagon' import chartHexagon from './chart/chartHexagon'
import { getOption, isTimeSeries, isHexagonFigure, isUrl, isText, isChartPie, isChartBar } from './chart/tools' import { getOption, isTimeSeries, isHexagonFigure, isUrl, isText, isChartPie, isChartBar, isTreemap } from './chart/tools'
import lodash from 'lodash' import lodash from 'lodash'
export default { export default {
@@ -119,6 +125,7 @@ export default {
isChartBar, isChartBar,
isUrl, isUrl,
isText, isText,
isTreemap,
resize () { resize () {
this.$refs['chart' + this.chartInfo.id].resize() this.$refs['chart' + this.chartInfo.id].resize()
} }

View File

@@ -19,14 +19,12 @@
<script> <script>
import legend from '@/components/chart/chart/legend' import legend from '@/components/chart/chart/legend'
import chartMixin from '@/components/chart/chartMixin' import chartMixin from '@/components/chart/chartMixin'
import chartFormat from '@/components/chart/chartFormat'
import { chartLegendPlacement } from '@/components/common/js/constants' import { chartLegendPlacement } from '@/components/common/js/constants'
import * as echarts from 'echarts' import * as echarts from 'echarts'
import { getChart, setChart } from '@/components/common/js/common' import { getChart, setChart } from '@/components/common/js/common'
import moment from 'moment-timezone'
import bus from '@/libs/bus'
import { formatScientificNotation, getMetricTypeValue } from '@/components/common/js/tools' import { formatScientificNotation, getMetricTypeValue } from '@/components/common/js/tools'
import chartDataFormat from '@/components/charts/chartDataFormat' import chartDataFormat from '@/components/charts/chartDataFormat'
import { randomcolor } from '@/components/common/js/radomcolor/randomcolor'
import { initColor } from '@/components/chart/chart/tools' import { initColor } from '@/components/chart/chart/tools'
import lodash from 'lodash' import lodash from 'lodash'
@@ -35,7 +33,7 @@ export default {
components: { components: {
chartLegend: legend chartLegend: legend
}, },
mixins: [chartMixin], mixins: [chartMixin, chartFormat],
props: { props: {
chartInfo: Object, chartInfo: Object,
chartData: Array, chartData: Array,
@@ -108,44 +106,23 @@ export default {
this.isInit = false this.isInit = false
}, 200) }, 200)
}, },
getMinMaxFromData (originalDatas) { initBarData (chartInfo, seriesTemplate, originalDatas) {
let minTime = null
let maxTime = null
let minValue = null
let maxValue = null
// 将数据提为二维数组
let datas = []
originalDatas.forEach((originalData, expressionIndex) => {
originalData.forEach((data, dataIndex) => {
datas = [...datas, ...data.values]
})
})
const timeSorted = datas.sort((a, b) => {
return a[0] - b[0]
})
const valueSorted = datas.sort((a, b) => {
return a[1] - b[1]
})
minTime = timeSorted.length ? timeSorted[0][0] : ''
maxTime = timeSorted.length ? timeSorted[timeSorted.length - 1][0] : ''
minValue = valueSorted.length ? valueSorted[0][1] : ''
maxValue = valueSorted.length ? valueSorted[valueSorted.length - 1][1] : ''
return { minTime, maxTime, minValue, maxValue }
},
initPieData (chartInfo, seriesTemplate, originalDatas) {
let colorIndex = 0 let colorIndex = 0
const self = this
const s = lodash.cloneDeep(seriesTemplate) const s = lodash.cloneDeep(seriesTemplate)
s.data = [] s.data = []
originalDatas.forEach((originalData, expressionIndex) => { originalDatas.forEach((originalData, expressionIndex) => {
originalData.forEach((data, dataIndex) => { originalData.forEach((data, dataIndex) => {
if (s) { if (s) {
const value = getMetricTypeValue(data.values, chartInfo.param.statistics) const value = getMetricTypeValue(data.values, chartInfo.param.statistics)
const showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(value, null, -1, 2)
const mapping = this.selectMapping(value, chartInfo.param.valueMapping) const mapping = this.selectMapping(value, chartInfo.param.valueMapping)
// eslint-disable-next-line vue/no-mutating-props // eslint-disable-next-line vue/no-mutating-props
mapping && (this.chartOption.color[colorIndex] = mapping.color.bac) mapping && (this.chartOption.color[colorIndex] = mapping.color.bac)
s.data.push({ s.data.push({
value: chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(value, null, -1, 2), value: value,
realValue: value, realValue: value,
showValue: showValue,
name: this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex), name: this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex),
labels: data.metric, labels: data.metric,
seriesIndex: expressionIndex, seriesIndex: expressionIndex,
@@ -170,51 +147,22 @@ export default {
}) })
return s return s
}, },
pieFormatterLabel (params) {
let str = '{color|'
if (this.chartInfo.param.text === 'all') {
str += params.data.name
str += ' : '
str += params.data.mapping && params.data.mapping.display ? params.data.mapping.display : params.data.value
}
if (this.chartInfo.param.text === 'value') {
str += params.data.mapping && params.data.mapping.display ? params.data.mapping.display : params.data.value
}
if (this.chartInfo.param.text === 'legend') {
str += params.data.name
}
if (this.chartInfo.param.text === 'none') {
str += ''
}
str += '}'
return str
},
formatterFunc (params, ticket, callback) { formatterFunc (params, ticket, callback) {
const chartInfo = this.chartData const self = this
return ` return `
<div> <div>
<div style="white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis; min-width: 150px; max-width: 600px; line-height: 18px; font-size: 14px;"> <div style="white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis; min-width: 150px; max-width: 600px; line-height: 18px; font-size: 14px;">
<div style="max-width: 500px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom: 5px">${params.data.name}</div> <div style="max-width: 500px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom: 5px">${params.data.name}</div>
<div style="font-size:12px;display:flex;justify-content: space-between;"> <div style="font-size:12px;display:flex;justify-content: space-between;">
<div>value</div> <div>value</div>
<div style="display: ${params.data.mapping && params.data.mapping.display ? 'none' : 'inline-block'}">${chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(params.value, null, -1, 2)}</div> <div style="display: ${params.data.mapping && params.data.mapping.display ? 'none' : 'inline-block'}">${params.data.showValue}</div>
<div style="display: ${params.data.mapping && params.data.mapping.display ? 'inline-block' : 'none'}">${params.data.mapping.display}</div> <div style="display: ${params.data.mapping && params.data.mapping.display ? 'inline-block' : 'none'}">${self.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue })}</div>
</div> </div>
</div> </div>
</div> </div>
` `
} }
}, },
watch: {
chartData: {
deep: true,
handler (n) {
if (!this.isInit) {
this.initChart(this.chartOption)
}
}
}
},
mounted () { mounted () {
// eslint-disable-next-line vue/no-mutating-props // eslint-disable-next-line vue/no-mutating-props
this.chartOption.color || (this.chartOption.color = initColor(20)) this.chartOption.color || (this.chartOption.color = initColor(20))

View File

@@ -19,14 +19,12 @@
<script> <script>
import legend from '@/components/chart/chart/legend' import legend from '@/components/chart/chart/legend'
import chartMixin from '@/components/chart/chartMixin' import chartMixin from '@/components/chart/chartMixin'
import chartFormat from '@/components/chart/chartFormat'
import { chartLegendPlacement } from '@/components/common/js/constants' import { chartLegendPlacement } from '@/components/common/js/constants'
import * as echarts from 'echarts' import * as echarts from 'echarts'
import { getChart, setChart } from '@/components/common/js/common' import { getChart, setChart } from '@/components/common/js/common'
import moment from 'moment-timezone'
import bus from '@/libs/bus'
import { formatScientificNotation, getMetricTypeValue } from '@/components/common/js/tools' import { formatScientificNotation, getMetricTypeValue } from '@/components/common/js/tools'
import chartDataFormat from '@/components/charts/chartDataFormat' import chartDataFormat from '@/components/charts/chartDataFormat'
import { randomcolor } from '@/components/common/js/radomcolor/randomcolor'
import { initColor } from '@/components/chart/chart/tools' import { initColor } from '@/components/chart/chart/tools'
import lodash from 'lodash' import lodash from 'lodash'
@@ -35,7 +33,7 @@ export default {
components: { components: {
chartLegend: legend chartLegend: legend
}, },
mixins: [chartMixin], mixins: [chartMixin, chartFormat],
props: { props: {
chartInfo: Object, chartInfo: Object,
chartData: Array, chartData: Array,
@@ -92,30 +90,6 @@ export default {
this.isInit = false this.isInit = false
}, 200) }, 200)
}, },
getMinMaxFromData (originalDatas) {
let minTime = null
let maxTime = null
let minValue = null
let maxValue = null
// 将数据提为二维数组
let datas = []
originalDatas.forEach((originalData, expressionIndex) => {
originalData.forEach((data, dataIndex) => {
datas = [...datas, ...data.values]
})
})
const timeSorted = datas.sort((a, b) => {
return a[0] - b[0]
})
const valueSorted = datas.sort((a, b) => {
return a[1] - b[1]
})
minTime = timeSorted.length ? timeSorted[0][0] : ''
maxTime = timeSorted.length ? timeSorted[timeSorted.length - 1][0] : ''
minValue = valueSorted.length ? valueSorted[0][1] : ''
maxValue = valueSorted.length ? valueSorted[valueSorted.length - 1][1] : ''
return { minTime, maxTime, minValue, maxValue }
},
initPieData (chartInfo, seriesTemplate, originalDatas) { initPieData (chartInfo, seriesTemplate, originalDatas) {
let colorIndex = 0 let colorIndex = 0
const s = lodash.cloneDeep(seriesTemplate) const s = lodash.cloneDeep(seriesTemplate)
@@ -124,12 +98,14 @@ export default {
originalData.forEach((data, dataIndex) => { originalData.forEach((data, dataIndex) => {
if (s) { if (s) {
const value = getMetricTypeValue(data.values, chartInfo.param.statistics) const value = getMetricTypeValue(data.values, chartInfo.param.statistics)
const showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(value, null, -1, 2)
const mapping = this.selectMapping(value, chartInfo.param.valueMapping) const mapping = this.selectMapping(value, chartInfo.param.valueMapping)
// eslint-disable-next-line vue/no-mutating-props // eslint-disable-next-line vue/no-mutating-props
mapping && (this.chartOption.color[colorIndex] = mapping.color.bac) mapping && (this.chartOption.color[colorIndex] = mapping.color.bac)
s.data.push({ s.data.push({
value: chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(value, null, -1, 2), value: value,
realValue: value, realValue: value,
showValue: showValue,
name: this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex), name: this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex),
labels: data.metric, labels: data.metric,
seriesIndex: expressionIndex, seriesIndex: expressionIndex,
@@ -151,34 +127,15 @@ export default {
}) })
return s return s
}, },
pieFormatterLabel (params) {
let str = '{color|'
if (this.chartInfo.param.text === 'all') {
str += params.data.name
str += ' : '
str += params.data.mapping && params.data.mapping.display ? params.data.mapping.display : params.data.value
}
if (this.chartInfo.param.text === 'value') {
str += params.data.mapping && params.data.mapping.display ? params.data.mapping.display : params.data.value
}
if (this.chartInfo.param.text === 'legend') {
str += params.data.name
}
if (this.chartInfo.param.text === 'none') {
str += ''
}
str += '}'
return str
},
formatterFunc: function (params, ticket, callback) { formatterFunc: function (params, ticket, callback) {
const chartInfo = this.chartInfo const self = this
return `<div> return `<div>
<div style="white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis; min-width: 150px; max-width: 600px; line-height: 18px; font-size: 14px;"> <div style="white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis; min-width: 150px; max-width: 600px; line-height: 18px; font-size: 14px;">
<div style="max-width: 500px;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis;margin-bottom: 5px">${params.data.name}</div> <div style="max-width: 500px;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis;margin-bottom: 5px">${params.data.name}</div>
<div style="font-size:12px;display:flex;justify-content: space-between;"> <div style="font-size:12px;display:flex;justify-content: space-between;">
<div>value</div> <div>value</div>
<div style="display: ${params.data.mapping && params.data.mapping.display ? 'none' : 'inline-block'}">${chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(params.value, null, -1, 2)}</div> <div style="display: ${params.data.mapping && params.data.mapping.display ? 'none' : 'inline-block'}">${params.data.showValue}</div>
<div style="display: ${params.data.mapping && params.data.mapping.display ? 'inline-block' : 'none'}">${params.data.mapping.display}</div> <div style="display: ${params.data.mapping && params.data.mapping.display ? 'inline-block' : 'none'}">${self.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue })}</div>
</div> </div>
<div style="font-size:12px;display:flex;justify-content: space-between;"> <div style="font-size:12px;display:flex;justify-content: space-between;">
<div>percent</div> <div>percent</div>
@@ -189,16 +146,6 @@ export default {
` `
} }
}, },
watch: {
chartData: {
deep: true,
handler (n) {
if (!this.isInit) {
this.initChart(this.chartOption)
}
}
}
},
mounted () { mounted () {
// eslint-disable-next-line vue/no-mutating-props // eslint-disable-next-line vue/no-mutating-props
this.chartOption.color || (this.chartOption.color = initColor(20)) this.chartOption.color || (this.chartOption.color = initColor(20))

View File

@@ -246,16 +246,6 @@ export default {
} }
} }
}, },
watch: {
chartData: {
deep: true,
handler (n) {
if (!this.isInit) {
this.initChart(this.chartOption)
}
}
}
},
mounted () { mounted () {
this.chartOption.color || (this.chartOption.color = initColor(20)) this.chartOption.color || (this.chartOption.color = initColor(20))
this.colorList = this.chartOption.color this.colorList = this.chartOption.color

View File

@@ -1,10 +1,177 @@
<template> <template>
<div
:class="legendPlacement"
ref="pie-chart-box"
class="nz-chart__component nz-chart__component--time-series" @mouseenter="mouseEnterChart"
@mouseleave="mouseLeaveChart"
>
<div :id="`chart-canvas-${chartId}`" class="chart__canvas"></div>
<chart-legend
v-if="hasLegend"
:chart-data="chartData"
:chart-info="chartInfo"
:legends="legends"
:is-fullscreen="isFullscreen"
></chart-legend>
</div>
</template> </template>
<script> <script>
import legend from '@/components/chart/chart/legend'
import chartMixin from '@/components/chart/chartMixin'
import chartFormat from '@/components/chart/chartFormat'
import { chartLegendPlacement } from '@/components/common/js/constants'
import * as echarts from 'echarts'
import { getChart, setChart } from '@/components/common/js/common'
import { formatScientificNotation, getMetricTypeValue } from '@/components/common/js/tools'
import chartDataFormat from '@/components/charts/chartDataFormat'
import { initColor } from '@/components/chart/chart/tools'
import lodash from 'lodash'
export default { export default {
name: 'chart-treemap' // 矩形树 name: 'chart-treemap',
components: {
chartLegend: legend
},
mixins: [chartMixin, chartFormat],
props: {
chartInfo: Object,
chartData: Array,
chartOption: Object,
isFullscreen: Boolean
},
computed: {
hasLegend () {
try {
return [chartLegendPlacement.bottom, chartLegendPlacement.left, chartLegendPlacement.right].indexOf(this.chartInfo.param.legend.placement) > -1
} catch (e) {
return false
}
},
legendPlacement () {
try {
switch (this.chartInfo.param.legend.placement) {
case 'left':
case 'right':
case 'bottom': {
return `nz-chart__component--${this.chartInfo.param.legend.placement}`
}
default: return ''
}
} catch (e) {
return ''
}
}
},
data () {
return {
colorList: [],
chartDot: 2,
isInit: true, // 是否是初始化初始化时为true图表初始化结束后设为false
legends: [], // { name, alias, color, statistics: [{type: min, value: xxx}, ...] }
toolboxIconColor: {
active: '#53a3cb',
inactive: '#7e7e7e'
},
chartId: ''
}
},
methods: {
initChart (chartOption) {
const self = this
this.legends = []
chartOption.series = this.initTreeMapData(this.chartInfo, chartOption.series[0], this.chartData) // 生成series和legends
chartOption.xAxis.data = chartOption.series.data.map(item => item.name)
chartOption.axisLabel = {
margin: 8,
formatter (params) {
const dataLength = chartOption.series.data.length || 1
const chartWidth = (document.getElementById('chart-canvas-' + self.chartInfo.id).offsetWidth - 80) / dataLength// 容器宽 - padding - 空余
const length = Math.ceil((chartWidth) / 16)
let val = ''
if (params.length > length) {
val = params.substr(0, length) + '...'
return val
} else {
return params
}
}
}
chartOption.tooltip.formatter = this.formatterFunc
/* 使用setTimeout延迟渲染图表避免样式错乱 */
setTimeout(() => {
const myChart = this.isInit ? echarts.init(document.getElementById(`chart-canvas-${this.chartId}`)) : getChart(this.chartId)
myChart.setOption(chartOption)
this.isInit && setChart(this.chartId, myChart) // 缓存不使用vue的data是为避免整个chart被监听导致卡顿
this.isInit = false
}, 200)
},
initTreeMapData (chartInfo, seriesTemplate, originalDatas) {
let colorIndex = 0
const self = this
const s = lodash.cloneDeep(seriesTemplate)
s.data = []
originalDatas.forEach((originalData, expressionIndex) => {
originalData.forEach((data, dataIndex) => {
if (s) {
const value = getMetricTypeValue(data.values, chartInfo.param.statistics)
const showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(value, null, -1, 2)
const mapping = this.selectMapping(value, chartInfo.param.valueMapping)
// eslint-disable-next-line vue/no-mutating-props
mapping && (this.chartOption.color[colorIndex] = mapping.color.bac)
s.data.push({
value: value,
realValue: value,
showValue: showValue,
name: this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex),
labels: data.metric,
seriesIndex: expressionIndex,
dataIndex: dataIndex,
mapping: mapping,
label: {
...s.label,
formatter: this.pieFormatterLabel,
rich: {
color: {
color: mapping ? mapping.color.text : '#000000'
}
}
},
itemStyle: {
color: mapping ? mapping.color.bac : this.colorList[colorIndex]
}
})
colorIndex++
}
})
})
return s
},
formatterFunc (params, ticket, callback) {
const self = this
return `
<div>
<div style="white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis; min-width: 150px; max-width: 600px; line-height: 18px; font-size: 14px;">
<div style="max-width: 500px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-bottom: 5px">${params.data.name}</div>
<div style="font-size:12px;display:flex;justify-content: space-between;">
<div>value</div>
<div style="display: ${params.data.mapping && params.data.mapping.display ? 'none' : 'inline-block'}">${params.data.showValue}</div>
<div style="display: ${params.data.mapping && params.data.mapping.display ? 'inline-block' : 'none'}">${self.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue })}</div>
</div>
</div>
</div>
`
}
},
mounted () {
// eslint-disable-next-line vue/no-mutating-props
this.chartOption.color || (this.chartOption.color = initColor(20))
this.colorList = this.chartOption.color
try {
this.isStack = this.chartInfo.param.stack
} catch (e) {}
this.initChart(this.chartOption)
}
} }
</script> </script>

View File

@@ -1,4 +1,56 @@
import * as echarts from 'echarts'
const formatUtil = echarts.format
const chartTreemapOption = { const chartTreemapOption = {
tooltip: {
formatter: function (info) {
const value = info.value
const treePathInfo = info.treePathInfo
const treePath = []
for (let i = 1; i < treePathInfo.length; i++) {
treePath.push(treePathInfo[i].name)
}
return [
'<div class="tooltip-title">' +
formatUtil.encodeHTML(treePath.join('/')) +
'</div>',
'Disk Usage: ' + formatUtil.addCommas(value) + ' KB'
].join('')
}
},
series: [
{
name: 'Disk Usage',
type: 'treemap',
visibleMin: 10,
label: {
show: true,
formatter: '{b}'
},
itemStyle: {
borderColor: '#fff'
},
levels: [
{
itemStyle: {
borderWidth: 0,
gapWidth: 5
}
},
{
itemStyle: {
gapWidth: 1
}
},
{
colorSaturation: [0.35, 0.5],
itemStyle: {
gapWidth: 1,
borderColorSaturation: 0.6
}
}
],
data: []
}
]
} }
export default chartTreemapOption export default chartTreemapOption

View File

@@ -67,6 +67,9 @@ export function isUrl (type) {
export function isText (type) { export function isText (type) {
return type === chartType.text return type === chartType.text
} }
export function isTreemap (type) {
return type === chartType.treemap
}
export function initColor (colorNum = 20) { export function initColor (colorNum = 20) {
const colorList = [ const colorList = [

View File

@@ -0,0 +1,65 @@
export default {
methods: {
pieFormatterLabel (params) {
const self = this
let str = '{color|'
if (this.chartInfo.param.text === 'all') {
str += params.data.name
str += ' : '
str += params.data.mapping && params.data.mapping.display ? self.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.value }) : params.data.value
}
if (this.chartInfo.param.text === 'value') {
str += params.data.mapping && params.data.mapping.display ? self.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.value }) : params.data.value
}
if (this.chartInfo.param.text === 'legend') {
str += params.data.name
}
if (this.chartInfo.param.text === 'none') {
str += ''
}
str += '}'
return str
},
handleDisplay (display, params) {
console.log(params)
if (/\{\{.+\}\}/.test(display)) {
const labelValue = display.replace(/(\{\{.+?\}\})/g, function (i) {
const label = i.substr(i.indexOf('{{') + 2, i.indexOf('}}') - i.indexOf('{{') - 2)
console.log(label)
let value = null
if (params[label]) {
value = params[label]
}
return value || label
})
return labelValue
} else {
return display
}
},
getMinMaxFromData (originalDatas) {
let minTime = null
let maxTime = null
let minValue = null
let maxValue = null
// 将数据提为二维数组
let datas = []
originalDatas.forEach((originalData, expressionIndex) => {
originalData.forEach((data, dataIndex) => {
datas = [...datas, ...data.values]
})
})
const timeSorted = datas.sort((a, b) => {
return a[0] - b[0]
})
const valueSorted = datas.sort((a, b) => {
return a[1] - b[1]
})
minTime = timeSorted.length ? timeSorted[0][0] : ''
maxTime = timeSorted.length ? timeSorted[timeSorted.length - 1][0] : ''
minValue = valueSorted.length ? valueSorted[0][1] : ''
maxValue = valueSorted.length ? valueSorted[valueSorted.length - 1][1] : ''
return { minTime, maxTime, minValue, maxValue }
},
}
}

View File

@@ -113,22 +113,6 @@ export default {
return aliasExpression return aliasExpression
} }
}, },
handleDisplay (display, params) {
if (/\{\{.+\}\}/.test(display)) {
const labelValue = display.replace(/(\{\{.+?\}\})/g, function (i) {
const label = i.substr(i.indexOf('{{') + 2, i.indexOf('}}') - i.indexOf('{{') - 2)
console.log(label)
let value = null
if (params[label]) {
value = params[label]
}
return value || label
})
return labelValue
} else {
return display
}
},
selectMapping (value, valueMapping) { selectMapping (value, valueMapping) {
let mapping = '' let mapping = ''
if (valueMapping.show) { if (valueMapping.show) {
@@ -178,6 +162,16 @@ export default {
} }
} }
}, },
watch: {
chartData: {
deep: true,
handler (n) {
if (!this.isInit) {
this.initChart(this.chartOption)
}
}
}
},
mounted () { mounted () {
this.chartId = `${this.chartInfo.id}${this.isFullscreen ? '-fullscreen' : ''}` this.chartId = `${this.chartInfo.id}${this.isFullscreen ? '-fullscreen' : ''}`
}, },

View File

@@ -112,6 +112,8 @@ export default {
} }
}) })
this.chartData = chartData this.chartData = chartData
}).catch(res => {
console.log(res)
}).finally(() => { }).finally(() => {
this.loading = false this.loading = false
}) })

File diff suppressed because it is too large Load Diff

View File

@@ -66,7 +66,7 @@
<transition name="el-zoom-in-top"> <transition name="el-zoom-in-top">
<el-row v-show="expressionsShow[index-1].show" style="margin-bottom: 10px"> <el-row v-show="expressionsShow[index-1].show" style="margin-bottom: 10px">
<el-form-item :prop="'elements.' + (index -1) + '.expression'" <el-form-item :prop="'elements.' + (index -1) + '.expression'"
:rules="{ required: true, message: $t('validate.required'), trigger: 'change'}"> :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}">
<promql-input <promql-input
:from-father-data="true" :from-father-data="true"
:metricOptionsParent="metricOptions" :metricOptionsParent="metricOptions"
@@ -177,7 +177,7 @@
:label="$t('dashboard.panel.chartForm.limit')" :label="$t('dashboard.panel.chartForm.limit')"
class="form-item--half-width" class="form-item--half-width"
prop="param.limit"> prop="param.limit">
<el-input <el-input-number
size="small" size="small"
:placeholder="$t('placeholder.log.limit')" :placeholder="$t('placeholder.log.limit')"
v-model.number="chartConfig.param.limit" v-model.number="chartConfig.param.limit"
@@ -404,7 +404,7 @@
:key="index" :key="index"
class="thresholds-item" class="thresholds-item"
:prop="'param.thresholds.' + index + '.value'" :prop="'param.thresholds.' + index + '.value'"
:rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
> >
<nezhaColor <nezhaColor
:value-arr="[{name:'thresholds',value:item.color}]" :value-arr="[{name:'thresholds',value:item.color}]"
@@ -412,7 +412,7 @@
:color-val="item.color" :color-val="item.color"
@colorChange="(color,key)=>{colorChange(color,key,index)}" @colorChange="(color,key)=>{colorChange(color,key,index)}"
/> />
<el-input <el-input-number
size="small" size="small"
style="margin-top: 2px" style="margin-top: 2px"
:placeholder="$t('placeholder.chart.threshold')" :placeholder="$t('placeholder.chart.threshold')"
@@ -505,49 +505,49 @@
<el-form-item <el-form-item
v-if="item.type === 'value'" v-if="item.type === 'value'"
:prop="'param.valueMapping.mapping.' + index + '.value'" :prop="'param.valueMapping.mapping.' + index + '.value'"
:rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
class="thresholds-from-item" class="thresholds-from-item"
> >
<el-input <el-input-number
:controls="false" :controls="false"
size="small" size="small"
v-model.number="item.value" v-model.number="item.value"
placeholder="value" placeholder="value"
@change="change" @change="change"
></el-input> ></el-input-number>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
v-if="item.type === 'range'" v-if="item.type === 'range'"
:prop="'param.valueMapping.mapping.' + index + '.from'" :prop="'param.valueMapping.mapping.' + index + '.from'"
:rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
class="thresholds-from-item" class="thresholds-from-item"
> >
<el-input <el-input-number
:controls="false" :controls="false"
size="small" size="small"
v-model.number="item.from" v-model.number="item.from"
placeholder="from" placeholder="from"
@change="change" @change="change"
></el-input> ></el-input-number>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
v-if="item.type === 'range'" v-if="item.type === 'range'"
:prop="'param.valueMapping.mapping.' + index + '.to'" :prop="'param.valueMapping.mapping.' + index + '.to'"
:rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
class="thresholds-from-item" class="thresholds-from-item"
> >
<el-input <el-input-number
:controls="false" :controls="false"
size="small" size="small"
v-model.number="item.to" v-model.number="item.to"
@change="change" @change="change"
placeholder="to" placeholder="to"
></el-input> ></el-input-number>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
v-if="item.type === 'regx'" v-if="item.type === 'regx'"
:prop="'param.valueMapping.mapping.' + index + '.regx'" :prop="'param.valueMapping.mapping.' + index + '.regx'"
:rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
class="thresholds-from-item" class="thresholds-from-item"
> >
<el-input <el-input
@@ -562,7 +562,7 @@
<div> <div>
<div class='mapping-display'>Display</div> <div class='mapping-display'>Display</div>
</div> </div>
<el-form-item :prop="'param.valueMapping.mapping.' + index + '.display'" :rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" class="thresholds-from-item"> <el-form-item :prop="'param.valueMapping.mapping.' + index + '.display'" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}" class="thresholds-from-item">
<el-input v-model="item.display" style="margin-right: 10px" :placeholder="$t('placeholder.chart.display')" size="small" @change="change"/> <el-input v-model="item.display" style="margin-right: 10px" :placeholder="$t('placeholder.chart.display')" size="small" @change="change"/>
</el-form-item> </el-form-item>
<nezhaColor :color-val="item.color" :single="false" :value-arr="[{name:'bac',value:item.color.bac,key:'bac'},{name:'text',value:item.color.text,key:'text'}]" @colorChange="(val,key)=>{colorChange(val, key, index)}"/> <nezhaColor :color-val="item.color" :single="false" :value-arr="[{name:'bac',value:item.color.bac,key:'bac'},{name:'text',value:item.color.text,key:'text'}]" @colorChange="(val,key)=>{colorChange(val, key, index)}"/>
@@ -608,7 +608,7 @@
<div> <div>
<div class='mapping-display'>Title</div> <div class='mapping-display'>Title</div>
</div> </div>
<el-form-item :prop="'param.columns.' + index + '.title'" :rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" class="thresholds-from-item" style="flex: 1"> <el-form-item :prop="'param.columns.' + index + '.title'" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}" class="thresholds-from-item" style="flex: 1">
<el-input size="small" v-model="item.title" placeholder="regx" @change="change"></el-input> <el-input size="small" v-model="item.title" placeholder="regx" @change="change"></el-input>
</el-form-item> </el-form-item>
<div> <div>
@@ -627,7 +627,7 @@
<div> <div>
<div class='mapping-display'>Display</div> <div class='mapping-display'>Display</div>
</div> </div>
<el-form-item :prop="'param.columns.' + index + '.display'" :rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" class="thresholds-from-item"> <el-form-item :prop="'param.columns.' + index + '.display'" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}" class="thresholds-from-item">
<el-input v-model="item.display" style="margin-right: 10px" size="small" @change="change"/> <el-input v-model="item.display" style="margin-right: 10px" size="small" @change="change"/>
</el-form-item> </el-form-item>
</el-row> </el-row>

View File

@@ -67,7 +67,7 @@
class="form-item--half-width" class="form-item--half-width"
prop="param.limit" prop="param.limit"
> >
<el-input :controls="false" v-model.number="chartConfig.param.limit" :placeholder="$t('placeholder.system.limit')" size="small" @change="change"/> <el-input-number :controls="false" v-model.number="chartConfig.param.limit" :placeholder="$t('placeholder.system.limit')" size="small" @change="change"/>
</el-form-item> </el-form-item>
</div> </div>
</div> </div>
@@ -250,49 +250,49 @@
<el-form-item <el-form-item
v-if="item.type === 'value'" v-if="item.type === 'value'"
:prop="'param.valueMapping.mapping.' + index + '.value'" :prop="'param.valueMapping.mapping.' + index + '.value'"
:rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
class="thresholds-from-item" class="thresholds-from-item"
> >
<el-input <el-input-number
:controls="false" :controls="false"
size="small" size="small"
v-model.number="item.value" v-model.number="item.value"
placeholder="value" placeholder="value"
@change="change" @change="change"
></el-input> ></el-input-number>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
v-if="item.type === 'range'" v-if="item.type === 'range'"
:prop="'param.valueMapping.mapping.' + index + '.from'" :prop="'param.valueMapping.mapping.' + index + '.from'"
:rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
class="thresholds-from-item" class="thresholds-from-item"
> >
<el-input <el-input-number
:controls="false" :controls="false"
size="small" size="small"
v-model.number="item.from" v-model.number="item.from"
placeholder="from" placeholder="from"
@change="change" @change="change"
></el-input> ></el-input-number>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
v-if="item.type === 'range'" v-if="item.type === 'range'"
:prop="'param.valueMapping.mapping.' + index + '.to'" :prop="'param.valueMapping.mapping.' + index + '.to'"
:rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
class="thresholds-from-item" class="thresholds-from-item"
> >
<el-input <el-input-number
:controls="false" :controls="false"
size="small" size="small"
v-model.number="item.to" v-model.number="item.to"
placeholder="to" placeholder="to"
@change="change" @change="change"
></el-input> ></el-input-number>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
v-if="item.type === 'regx'" v-if="item.type === 'regx'"
:prop="'param.valueMapping.mapping.' + index + '.regx'" :prop="'param.valueMapping.mapping.' + index + '.regx'"
:rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
class="thresholds-from-item" class="thresholds-from-item"
> >
<el-input <el-input
@@ -307,7 +307,7 @@
<div> <div>
<div class='mapping-display'>Display</div> <div class='mapping-display'>Display</div>
</div> </div>
<el-form-item :prop="'param.valueMapping.mapping.' + index + '.display'" :rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" class="thresholds-from-item"> <el-form-item :prop="'param.valueMapping.mapping.' + index + '.display'" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}" class="thresholds-from-item">
<el-input v-model="item.display" style="margin-right: 10px" size="small" @change="change"/> <el-input v-model="item.display" style="margin-right: 10px" size="small" @change="change"/>
</el-form-item> </el-form-item>
<nezhaColor :color-val="item.color" :single="false" :value-arr="[{name:'bac',value:item.color.bac,key:'bac'},{name:'text',value:item.color.text,key:'text'}]" @colorChange="(val,key)=>{colorChange(val, key, index)}"/> <nezhaColor :color-val="item.color" :single="false" :value-arr="[{name:'bac',value:item.color.bac,key:'bac'},{name:'text',value:item.color.text,key:'text'}]" @colorChange="(val,key)=>{colorChange(val, key, index)}"/>
@@ -353,7 +353,7 @@
<div> <div>
<div class='mapping-display'>Title</div> <div class='mapping-display'>Title</div>
</div> </div>
<el-form-item :prop="'param.columns.' + index + 'title'" :rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" class="thresholds-from-item" style="flex: 1"> <el-form-item :prop="'param.columns.' + index + 'title'" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}" class="thresholds-from-item" style="flex: 1">
<el-input size="small" v-model="item.title" placeholder="regx" @change="change"></el-input> <el-input size="small" v-model="item.title" placeholder="regx" @change="change"></el-input>
</el-form-item> </el-form-item>
<div> <div>
@@ -372,7 +372,7 @@
<div> <div>
<div class='mapping-display'>Display</div> <div class='mapping-display'>Display</div>
</div> </div>
<el-form-item :prop="'param.columns.' + index + 'display'" :rules="{ required: true, message: $t('validate.required'), trigger: 'change'}" class="thresholds-from-item"> <el-form-item :prop="'param.columns.' + index + 'display'" :rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}" class="thresholds-from-item">
<el-input v-model="item.display" style="margin-right: 10px" size="small" @change="change"/> <el-input v-model="item.display" style="margin-right: 10px" size="small" @change="change"/>
</el-form-item> </el-form-item>
</el-row> </el-row>