feat:抽取图表公共参数 优化valuemapping display的逻辑
This commit is contained in:
@@ -43,6 +43,12 @@
|
||||
:chart-info="chartInfo"
|
||||
:chart-option="chartOption"
|
||||
></chart-text>
|
||||
<chart-treemap
|
||||
v-if="isTreemap(chartInfo.type)"
|
||||
:chart-data="chartData"
|
||||
:chart-info="chartInfo"
|
||||
:chart-option="chartOption"
|
||||
></chart-treemap>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
@@ -67,7 +73,7 @@ import chartTreemap from './chart/chartTreemap'
|
||||
import chartUrl from './chart/chartUrl'
|
||||
import chartValue from './chart/chartValue'
|
||||
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'
|
||||
|
||||
export default {
|
||||
@@ -119,6 +125,7 @@ export default {
|
||||
isChartBar,
|
||||
isUrl,
|
||||
isText,
|
||||
isTreemap,
|
||||
resize () {
|
||||
this.$refs['chart' + this.chartInfo.id].resize()
|
||||
}
|
||||
|
||||
@@ -19,14 +19,12 @@
|
||||
<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 moment from 'moment-timezone'
|
||||
import bus from '@/libs/bus'
|
||||
import { formatScientificNotation, getMetricTypeValue } from '@/components/common/js/tools'
|
||||
import chartDataFormat from '@/components/charts/chartDataFormat'
|
||||
import { randomcolor } from '@/components/common/js/radomcolor/randomcolor'
|
||||
import { initColor } from '@/components/chart/chart/tools'
|
||||
import lodash from 'lodash'
|
||||
|
||||
@@ -35,7 +33,7 @@ export default {
|
||||
components: {
|
||||
chartLegend: legend
|
||||
},
|
||||
mixins: [chartMixin],
|
||||
mixins: [chartMixin, chartFormat],
|
||||
props: {
|
||||
chartInfo: Object,
|
||||
chartData: Array,
|
||||
@@ -108,44 +106,23 @@ export default {
|
||||
this.isInit = false
|
||||
}, 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) {
|
||||
initBarData (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: chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(value, null, -1, 2),
|
||||
value: value,
|
||||
realValue: value,
|
||||
showValue: showValue,
|
||||
name: this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex),
|
||||
labels: data.metric,
|
||||
seriesIndex: expressionIndex,
|
||||
@@ -170,51 +147,22 @@ export default {
|
||||
})
|
||||
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) {
|
||||
const chartInfo = this.chartData
|
||||
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'}">${chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(params.value, null, -1, 2)}</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 ? '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>
|
||||
`
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
chartData: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
if (!this.isInit) {
|
||||
this.initChart(this.chartOption)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// eslint-disable-next-line vue/no-mutating-props
|
||||
this.chartOption.color || (this.chartOption.color = initColor(20))
|
||||
|
||||
@@ -19,14 +19,12 @@
|
||||
<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 moment from 'moment-timezone'
|
||||
import bus from '@/libs/bus'
|
||||
import { formatScientificNotation, getMetricTypeValue } from '@/components/common/js/tools'
|
||||
import chartDataFormat from '@/components/charts/chartDataFormat'
|
||||
import { randomcolor } from '@/components/common/js/radomcolor/randomcolor'
|
||||
import { initColor } from '@/components/chart/chart/tools'
|
||||
import lodash from 'lodash'
|
||||
|
||||
@@ -35,7 +33,7 @@ export default {
|
||||
components: {
|
||||
chartLegend: legend
|
||||
},
|
||||
mixins: [chartMixin],
|
||||
mixins: [chartMixin, chartFormat],
|
||||
props: {
|
||||
chartInfo: Object,
|
||||
chartData: Array,
|
||||
@@ -92,30 +90,6 @@ export default {
|
||||
this.isInit = false
|
||||
}, 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) {
|
||||
let colorIndex = 0
|
||||
const s = lodash.cloneDeep(seriesTemplate)
|
||||
@@ -124,12 +98,14 @@ export default {
|
||||
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: chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(value, null, -1, 2),
|
||||
value: value,
|
||||
realValue: value,
|
||||
showValue: showValue,
|
||||
name: this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex),
|
||||
labels: data.metric,
|
||||
seriesIndex: expressionIndex,
|
||||
@@ -151,34 +127,15 @@ export default {
|
||||
})
|
||||
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) {
|
||||
const chartInfo = this.chartInfo
|
||||
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-x: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'}">${chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(params.value, null, -1, 2)}</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 ? '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 style="font-size:12px;display:flex;justify-content: space-between;">
|
||||
<div>percent</div>
|
||||
@@ -189,16 +146,6 @@ export default {
|
||||
`
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
chartData: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
if (!this.isInit) {
|
||||
this.initChart(this.chartOption)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// eslint-disable-next-line vue/no-mutating-props
|
||||
this.chartOption.color || (this.chartOption.color = initColor(20))
|
||||
|
||||
@@ -246,16 +246,6 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
chartData: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
if (!this.isInit) {
|
||||
this.initChart(this.chartOption)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.chartOption.color || (this.chartOption.color = initColor(20))
|
||||
this.colorList = this.chartOption.color
|
||||
|
||||
@@ -1,10 +1,177 @@
|
||||
<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>
|
||||
|
||||
<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 {
|
||||
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>
|
||||
|
||||
|
||||
@@ -1,4 +1,56 @@
|
||||
import * as echarts from 'echarts'
|
||||
const formatUtil = echarts.format
|
||||
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
|
||||
|
||||
@@ -67,6 +67,9 @@ export function isUrl (type) {
|
||||
export function isText (type) {
|
||||
return type === chartType.text
|
||||
}
|
||||
export function isTreemap (type) {
|
||||
return type === chartType.treemap
|
||||
}
|
||||
|
||||
export function initColor (colorNum = 20) {
|
||||
const colorList = [
|
||||
|
||||
65
nezha-fronted/src/components/chart/chartFormat.js
Normal file
65
nezha-fronted/src/components/chart/chartFormat.js
Normal 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 }
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -113,22 +113,6 @@ export default {
|
||||
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) {
|
||||
let mapping = ''
|
||||
if (valueMapping.show) {
|
||||
@@ -178,6 +162,16 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
chartData: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
if (!this.isInit) {
|
||||
this.initChart(this.chartOption)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.chartId = `${this.chartInfo.id}${this.isFullscreen ? '-fullscreen' : ''}`
|
||||
},
|
||||
|
||||
@@ -112,6 +112,8 @@ export default {
|
||||
}
|
||||
})
|
||||
this.chartData = chartData
|
||||
}).catch(res => {
|
||||
console.log(res)
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -66,7 +66,7 @@
|
||||
<transition name="el-zoom-in-top">
|
||||
<el-row v-show="expressionsShow[index-1].show" style="margin-bottom: 10px">
|
||||
<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
|
||||
:from-father-data="true"
|
||||
:metricOptionsParent="metricOptions"
|
||||
@@ -177,7 +177,7 @@
|
||||
:label="$t('dashboard.panel.chartForm.limit')"
|
||||
class="form-item--half-width"
|
||||
prop="param.limit">
|
||||
<el-input
|
||||
<el-input-number
|
||||
size="small"
|
||||
:placeholder="$t('placeholder.log.limit')"
|
||||
v-model.number="chartConfig.param.limit"
|
||||
@@ -404,7 +404,7 @@
|
||||
:key="index"
|
||||
class="thresholds-item"
|
||||
:prop="'param.thresholds.' + index + '.value'"
|
||||
:rules="{ required: true, message: $t('validate.required'), trigger: 'change'}"
|
||||
:rules="{ required: true, message: $t('validate.required'), trigger: 'blur'}"
|
||||
>
|
||||
<nezhaColor
|
||||
:value-arr="[{name:'thresholds',value:item.color}]"
|
||||
@@ -412,7 +412,7 @@
|
||||
:color-val="item.color"
|
||||
@colorChange="(color,key)=>{colorChange(color,key,index)}"
|
||||
/>
|
||||
<el-input
|
||||
<el-input-number
|
||||
size="small"
|
||||
style="margin-top: 2px"
|
||||
:placeholder="$t('placeholder.chart.threshold')"
|
||||
@@ -505,49 +505,49 @@
|
||||
<el-form-item
|
||||
v-if="item.type === '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"
|
||||
>
|
||||
<el-input
|
||||
<el-input-number
|
||||
:controls="false"
|
||||
size="small"
|
||||
v-model.number="item.value"
|
||||
placeholder="value"
|
||||
@change="change"
|
||||
></el-input>
|
||||
></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="item.type === 'range'"
|
||||
: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"
|
||||
>
|
||||
<el-input
|
||||
<el-input-number
|
||||
:controls="false"
|
||||
size="small"
|
||||
v-model.number="item.from"
|
||||
placeholder="from"
|
||||
@change="change"
|
||||
></el-input>
|
||||
></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="item.type === 'range'"
|
||||
: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"
|
||||
>
|
||||
<el-input
|
||||
<el-input-number
|
||||
:controls="false"
|
||||
size="small"
|
||||
v-model.number="item.to"
|
||||
@change="change"
|
||||
placeholder="to"
|
||||
></el-input>
|
||||
></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="item.type === '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"
|
||||
>
|
||||
<el-input
|
||||
@@ -562,7 +562,7 @@
|
||||
<div>
|
||||
<div class='mapping-display'>Display</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-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)}"/>
|
||||
@@ -608,7 +608,7 @@
|
||||
<div>
|
||||
<div class='mapping-display'>Title</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-form-item>
|
||||
<div>
|
||||
@@ -627,7 +627,7 @@
|
||||
<div>
|
||||
<div class='mapping-display'>Display</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-form-item>
|
||||
</el-row>
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
class="form-item--half-width"
|
||||
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>
|
||||
</div>
|
||||
</div>
|
||||
@@ -250,49 +250,49 @@
|
||||
<el-form-item
|
||||
v-if="item.type === '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"
|
||||
>
|
||||
<el-input
|
||||
<el-input-number
|
||||
:controls="false"
|
||||
size="small"
|
||||
v-model.number="item.value"
|
||||
placeholder="value"
|
||||
@change="change"
|
||||
></el-input>
|
||||
></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="item.type === 'range'"
|
||||
: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"
|
||||
>
|
||||
<el-input
|
||||
<el-input-number
|
||||
:controls="false"
|
||||
size="small"
|
||||
v-model.number="item.from"
|
||||
placeholder="from"
|
||||
@change="change"
|
||||
></el-input>
|
||||
></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="item.type === 'range'"
|
||||
: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"
|
||||
>
|
||||
<el-input
|
||||
<el-input-number
|
||||
:controls="false"
|
||||
size="small"
|
||||
v-model.number="item.to"
|
||||
placeholder="to"
|
||||
@change="change"
|
||||
></el-input>
|
||||
></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="item.type === '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"
|
||||
>
|
||||
<el-input
|
||||
@@ -307,7 +307,7 @@
|
||||
<div>
|
||||
<div class='mapping-display'>Display</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-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)}"/>
|
||||
@@ -353,7 +353,7 @@
|
||||
<div>
|
||||
<div class='mapping-display'>Title</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-form-item>
|
||||
<div>
|
||||
@@ -372,7 +372,7 @@
|
||||
<div>
|
||||
<div class='mapping-display'>Display</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-form-item>
|
||||
</el-row>
|
||||
|
||||
Reference in New Issue
Block a user