NEZ-2528 feat:dashboard时序图表支持双Y轴 页面开发
This commit is contained in:
@@ -458,6 +458,12 @@ td .nz-icon-gear:before {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.yAxis-icon{
|
||||
margin-right: 4px;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.loading-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -378,6 +378,10 @@
|
||||
.legend-shape {
|
||||
background-color: $--background-color-1 !important;
|
||||
}
|
||||
|
||||
.nz-icon{
|
||||
color: $--background-color-1 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,6 +429,7 @@
|
||||
text-overflow: ellipsis;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
min-width: 150px;
|
||||
max-width: 600px;
|
||||
line-height: 18px;
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -5,6 +5,34 @@
|
||||
"css_prefix_text": "nz-icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "33998082",
|
||||
"name": "右纵轴",
|
||||
"font_class": "youzongzhou",
|
||||
"unicode": "e7ce",
|
||||
"unicode_decimal": 59342
|
||||
},
|
||||
{
|
||||
"icon_id": "33998083",
|
||||
"name": "左纵轴",
|
||||
"font_class": "zuozongzhou",
|
||||
"unicode": "e7cf",
|
||||
"unicode_decimal": 59343
|
||||
},
|
||||
{
|
||||
"icon_id": "33991102",
|
||||
"name": "全部收起",
|
||||
"font_class": "quanbushouqi",
|
||||
"unicode": "e7cc",
|
||||
"unicode_decimal": 59340
|
||||
},
|
||||
{
|
||||
"icon_id": "33991103",
|
||||
"name": "全部展开",
|
||||
"font_class": "quanbuzhankai",
|
||||
"unicode": "e7cd",
|
||||
"unicode_decimal": 59341
|
||||
},
|
||||
{
|
||||
"icon_id": "33693407",
|
||||
"name": "普通文件",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -4,7 +4,13 @@
|
||||
class="nz-chart__component nz-chart__component--time-series" @mouseenter="mouseEnterChart"
|
||||
@mouseleave="mouseLeaveChart"
|
||||
>
|
||||
<div :id="`chart-canvas-${chartId}`" class="chart__canvas"></div>
|
||||
<div class="chart__canvas" style="position:relative">
|
||||
<div :id="`chart-canvas-${chartId}`"></div>
|
||||
<!-- 右y轴name -->
|
||||
<p class="rightYAxis-name" v-if="hasRightYAxis">
|
||||
<span>{{chartInfo.param.rightYAxis.label}}</span>
|
||||
</p>
|
||||
</div>
|
||||
<chart-legend
|
||||
v-if="hasLegend"
|
||||
:chart-data="chartData"
|
||||
@@ -43,7 +49,9 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
stackTotalColor: null,
|
||||
isStack: false
|
||||
stackTotalColorRight: null,
|
||||
isStack: false,
|
||||
hasRightYAxis: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -136,21 +144,25 @@ export default {
|
||||
chartOption.tooltip.appendToBody = false
|
||||
delete chartOption.tooltip.position
|
||||
}
|
||||
chartOption.yAxis.axisLabel.formatter = this.yAxisLabelFormatter(minValue, maxValue, copies, unit, decimals)
|
||||
// 左y轴
|
||||
chartOption.yAxis[0].axisLabel.formatter = this.yAxisLabelFormatter(minValue, maxValue, copies, unit, decimals)
|
||||
|
||||
if (!this.chartInfo.param.min && !this.chartInfo.param.max) {
|
||||
chartOption.yAxis.minInterval = chartDataFormat.Interval(maxValue, copies, unit.type, 'min')
|
||||
chartOption.yAxis.maxInterval = chartDataFormat.Interval(maxValue, copies, unit.type, 'max') * Math.ceil(chartOption.series.length / 5)
|
||||
if (this.chartInfo.param.stack) {
|
||||
chartOption.yAxis.maxInterval = chartOption.yAxis.maxInterval * (Math.ceil(chartOption.series.length / 5) + 1)
|
||||
}
|
||||
if (unit.type === 'Time' || unit.type === 'Date & Time') {
|
||||
delete chartOption.yAxis.minInterval
|
||||
delete chartOption.yAxis.maxInterval
|
||||
}
|
||||
} else {
|
||||
chartOption.yAxis.min = this.chartInfo.param.min ? this.chartInfo.param.min : undefined
|
||||
chartOption.yAxis.max = this.chartInfo.param.max ? this.chartInfo.param.max : undefined
|
||||
chartOption.yAxis[0].min = this.chartInfo.param.min ? this.chartInfo.param.min : undefined
|
||||
chartOption.yAxis[0].max = this.chartInfo.param.max ? this.chartInfo.param.max : undefined
|
||||
|
||||
// 右y轴
|
||||
if (this.chartInfo.param.enable.rightYAxis) {
|
||||
// 如果全都为右y轴数据 则右y轴显示网格
|
||||
const allRight = this.series.every(item => item.yAxisIndex == 1)
|
||||
chartOption.yAxis[1].splitLine.show = allRight
|
||||
|
||||
const unit = chartDataFormat.getUnit(lodash.get(this, 'chartInfo.param.rightYAxis.unit', 2))
|
||||
chartOption.yAxis[1].axisLabel.formatter = this.yAxisLabelFormatter(undefined, undefined, undefined, unit, decimals)
|
||||
chartOption.yAxis[1].min = this.chartInfo.param.rightYAxis.min ? this.chartInfo.param.rightYAxis.min : undefined
|
||||
chartOption.yAxis[1].max = this.chartInfo.param.rightYAxis.max ? this.chartInfo.param.rightYAxis.max : undefined
|
||||
|
||||
// 有右y轴数据则显示name
|
||||
this.hasRightYAxis = this.series.some(item => item.yAxisIndex == 1)
|
||||
}
|
||||
|
||||
if (chartOption.toolbox.feature) {
|
||||
@@ -166,7 +178,6 @@ export default {
|
||||
myChart.clear()
|
||||
myChart.setOption(chartOption)
|
||||
this.isInit && setChart(this.chartId, myChart) // 缓存;不使用vue的data是为避免整个chart被监听导致卡顿
|
||||
|
||||
this.$store.commit('setCurrentMousemove', 0)
|
||||
if (this.isInit && !this.isFullscreen) {
|
||||
// timeSeries类型图表设置group 用于多表联动
|
||||
@@ -181,72 +192,6 @@ export default {
|
||||
}
|
||||
})
|
||||
}
|
||||
const self = this
|
||||
getChart(this.chartId).off('dataZoom')
|
||||
getChart(this.chartId).on('dataZoom', function (params) {
|
||||
if (this.chartInfo.param.min || this.chartInfo.param.max) {
|
||||
return
|
||||
}
|
||||
if (params.batch[0].startValue) {
|
||||
const chartInfo = self.chartInfo
|
||||
const dataArg = self.$loadsh.cloneDeep(self.series)
|
||||
dataArg.forEach(item => {
|
||||
item.data = item.data.filter(value => value[0] > params.batch[0].startValue && value[0] < params.batch[0].endValue)
|
||||
})
|
||||
const maxValueCopies = self.getMaxValue(dataArg, chartInfo)
|
||||
const maxValue = maxValueCopies.maxValue
|
||||
const copies = maxValueCopies.copies
|
||||
const unit = maxValueCopies.unit
|
||||
const option = {
|
||||
yAxis: {
|
||||
minInterval: chartDataFormat.Interval(maxValue, copies, unit.type, 'min'),
|
||||
maxInterval: chartDataFormat.Interval(maxValue, copies, unit.type, 'max') * Math.ceil(dataArg.length / 5)
|
||||
}
|
||||
}
|
||||
if (!maxValueCopies.copies) {
|
||||
option.yAxis.min = 0
|
||||
option.yAxis.max = 1
|
||||
} else {
|
||||
option.yAxis.max = undefined
|
||||
}
|
||||
if (unit.type == 'Time' || option.yAxis.maxInterval === 1) {
|
||||
delete option.yAxis.maxInterval
|
||||
}
|
||||
getChart(self.chartId) && getChart(self.chartId).setOption({
|
||||
yAxis: {
|
||||
...option.yAxis
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 处理点击后的 Y轴
|
||||
const chartInfo = self.chartInfo
|
||||
const dataArg = self.series
|
||||
const maxValueCopies = self.getMaxValue(dataArg, chartInfo)
|
||||
const maxValue = maxValueCopies.maxValue
|
||||
const copies = maxValueCopies.copies
|
||||
const unit = maxValueCopies.unit
|
||||
const option = {
|
||||
yAxis: {
|
||||
minInterval: chartDataFormat.Interval(maxValue, copies, unit.type, 'min'),
|
||||
maxInterval: chartDataFormat.Interval(maxValue, copies, unit.type, 'max') * Math.ceil(dataArg.length / 5)
|
||||
}
|
||||
}
|
||||
if (!maxValueCopies.copies) {
|
||||
option.yAxis.min = 0
|
||||
option.yAxis.max = 1
|
||||
} else {
|
||||
option.yAxis.max = undefined
|
||||
}
|
||||
if (unit.type == 'Time' || option.yAxis.maxInterval === 1) {
|
||||
delete option.yAxis.maxInterval
|
||||
}
|
||||
getChart(self.chartId) && getChart(self.chartId).setOption({
|
||||
yAxis: {
|
||||
...option.yAxis
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
this.isInit = false
|
||||
}, 200)
|
||||
},
|
||||
@@ -369,32 +314,74 @@ export default {
|
||||
return function (params) {
|
||||
const decimals = self.chartInfo.param.decimals || 2
|
||||
let str = '<div class="nz-chart__tooltip">'
|
||||
// 区分左y轴右y轴
|
||||
params.forEach(item => {
|
||||
item.yAxisIndex = self.series[item.seriesIndex].yAxisIndex
|
||||
})
|
||||
// 排序先展示左y轴
|
||||
params.sort((a, b) => a.yAxisIndex - b.yAxisIndex)
|
||||
// 分割
|
||||
const rightYAxisIndex = params.findIndex(item => item.yAxisIndex == 1)
|
||||
let leftYAxis = []
|
||||
let rightYAxis = []
|
||||
if (rightYAxisIndex != -1) {
|
||||
leftYAxis = params.slice(0, rightYAxisIndex)
|
||||
rightYAxis = params.slice(rightYAxisIndex)
|
||||
} else {
|
||||
leftYAxis = params
|
||||
}
|
||||
handler(leftYAxis, 'left')
|
||||
handler(rightYAxis, 'right')
|
||||
function handler (arr, type) {
|
||||
if (!arr.length) {
|
||||
return
|
||||
}
|
||||
let sum = 0
|
||||
let flag = true
|
||||
params.forEach((item, i) => {
|
||||
arr.forEach((item, i) => {
|
||||
let unit = self.chartInfo.unit ? self.chartInfo.unit : 2
|
||||
if (type == 'right') {
|
||||
unit = lodash.get(self, 'chartInfo.param.rightYAxis.unit', 2)
|
||||
}
|
||||
const nameArr = item.seriesName.split('-')
|
||||
if (nameArr.length > 1) {
|
||||
nameArr.splice(nameArr.length - 1, 1)
|
||||
}
|
||||
const seriesName = nameArr.join('-')
|
||||
if (i === 0 && item.seriesName.indexOf('Previous') === -1) {
|
||||
if (i === 0 && item.seriesName.indexOf('Previous') === -1 && type == 'left') {
|
||||
const value = bus.computeTimezone(item.data[0] * 1000)
|
||||
const tData = new Date(value)
|
||||
str += '<div class="tooltip-title" style="margin-bottom: 5px">'
|
||||
str += bus.timeFormate(tData)
|
||||
str += '</div>'
|
||||
}
|
||||
// 两条y轴数据分割线
|
||||
if (i == 0 && rightYAxisIndex != 0 && type == 'right') {
|
||||
str += '<div style="border: 1px solid #EEEEEE;margin-top: 5px;margin-bottom: 5px"></div>'
|
||||
}
|
||||
if (item.seriesName.indexOf('Previous') === -1 && type == 'right') {
|
||||
if (i == 0 && (rightYAxisIndex == 0 || (arr.some(item => item.seriesName.indexOf('Previous') !== -1)))) {
|
||||
const value = bus.computeTimezone(item.data[0] * 1000)
|
||||
const tData = new Date(value)
|
||||
str += '<div class="tooltip-title" style="margin-bottom: 5px">'
|
||||
str += bus.timeFormate(tData)
|
||||
str += '</div>'
|
||||
}
|
||||
}
|
||||
// Previous分割线
|
||||
if (i !== 0 && flag && item.seriesName.indexOf('Previous') !== -1) {
|
||||
str += '<div style="border: 1px solid #EEEEEE;margin-top: 5px;margin-bottom: 5px"></div>'
|
||||
}
|
||||
if (flag && item.seriesName.indexOf('Previous') !== -1) {
|
||||
flag = false
|
||||
const value = bus.computeTimezone(item.data[0] * 1000 - self.minusTime)
|
||||
const tData = new Date(value)
|
||||
str += '<div style="border: 1px solid #EEEEEE"></div>'
|
||||
str += '<div class="tooltip-title" style="margin-top: 5px;margin-bottom: 5px">'
|
||||
str += '<div class="tooltip-title" style="margin-bottom: 5px">'
|
||||
str += bus.timeFormate(tData)
|
||||
str += '</div>'
|
||||
}
|
||||
const color = self.colorList[item.seriesIndex]
|
||||
const previousItem = params.find((series) => ('Previous ' + item.seriesName) === series.seriesName)
|
||||
const previousItem = arr.find((series) => ('Previous ' + item.seriesName) === series.seriesName)
|
||||
let paramsDot = bus.countDecimals(item.data[1])
|
||||
if (paramsDot < self.chartDot) {
|
||||
paramsDot = self.chartDot
|
||||
@@ -416,40 +403,67 @@ export default {
|
||||
operator = '-'
|
||||
}
|
||||
previousDom = `
|
||||
<span>${operator}${chartDataFormat.getUnit(self.chartInfo.unit ? self.chartInfo.unit : 2).compute(minusVal, null, -1, decimals)}</span>
|
||||
<span>${operator}${chartDataFormat.getUnit(unit).compute(minusVal, null, -1, decimals)}</span>
|
||||
`
|
||||
}
|
||||
|
||||
let className = 'row__color-block'
|
||||
if (item.yAxisIndex == 0) {
|
||||
className = 'yAxis-icon nz-icon nz-icon-zuozongzhou'
|
||||
} else if (item.yAxisIndex == 1) {
|
||||
className = 'yAxis-icon nz-icon nz-icon-youzongzhou'
|
||||
}
|
||||
|
||||
str += `
|
||||
<div class="tooltip__row">
|
||||
<div class="row__label">
|
||||
<span class="row__color-block" style="background-color: ${color}"></span>
|
||||
<span class="${className}" style="background-color: ${color};color: ${color}"></span>
|
||||
<span>${seriesName}</span>
|
||||
</div>
|
||||
<div class="row__value">
|
||||
<span>${chartDataFormat.getUnit(self.chartInfo.unit ? self.chartInfo.unit : 2).compute(val, null, -1, decimals)}</span>
|
||||
<span>${chartDataFormat.getUnit(unit).compute(val, null, -1, decimals)}</span>
|
||||
${previousDom}
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
// 显示total
|
||||
if (hasTotal) {
|
||||
sum = parseFloat(Number(sum).toFixed(2))
|
||||
let unit = self.chartInfo.unit ? self.chartInfo.unit : 2
|
||||
let className = 'row__color-block'
|
||||
let color = ''
|
||||
if (type == 'left') {
|
||||
// 判断是否开启rightYAxis 否则显示普通图标
|
||||
if (self.series.some(item => item.yAxisIndex == 0)) {
|
||||
className = 'yAxis-icon nz-icon nz-icon-zuozongzhou'
|
||||
}
|
||||
if (!self.stackTotalColor) {
|
||||
self.stackTotalColor = randomcolor()
|
||||
}
|
||||
sum = parseFloat(Number(sum).toFixed(2))
|
||||
color = self.stackTotalColor
|
||||
} else {
|
||||
unit = lodash.get(self, 'chartInfo.param.rightYAxis.unit', 2)
|
||||
className = 'yAxis-icon nz-icon nz-icon-youzongzhou'
|
||||
if (!self.stackTotalColorRight) {
|
||||
self.stackTotalColorRight = randomcolor()
|
||||
}
|
||||
color = self.stackTotalColorRight
|
||||
}
|
||||
|
||||
str += `
|
||||
<div class="tooltip__row">
|
||||
<div class="row__label">
|
||||
<span class="row__color-block" style="background-color: ${self.stackTotalColor}"></span>
|
||||
<span class="${className}" style="background-color: ${color};color: ${color}"></span>
|
||||
<span>${self.$t('dashboard.panel.chartTotal')}</span>
|
||||
</div>
|
||||
<div class="row__value">
|
||||
<span>${chartDataFormat.getUnit(self.chartInfo.unit ? self.chartInfo.unit : 2).compute(sum, null, decimals)}</span>
|
||||
<span>${chartDataFormat.getUnit(unit).compute(sum, null, decimals)}</span>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
str += '</div>'
|
||||
return str
|
||||
@@ -473,18 +487,11 @@ export default {
|
||||
option.toolbox[0].feature.myStack.iconStyle.borderColor = self.isStack ? self.toolboxIconColor.inactive : self.toolboxIconColor.active
|
||||
// 切换stack状态
|
||||
option.series.forEach((s, i) => {
|
||||
self.isStack ? (s.stack = i) : (s.stack = 'Total')
|
||||
self.isStack ? (s.stack = i) : (s.stack = 'Total' + s.yAxisIndex)
|
||||
})
|
||||
self.isStack = !self.isStack
|
||||
// 改变tooltip
|
||||
option.tooltip[0].formatter = self.tooltipFormatter(self.isStack)
|
||||
if (!self.chartInfo.param.min && !self.chartInfo.param.max) {
|
||||
if (!self.chartInfo.param.stack) {
|
||||
option.yAxis.maxInterval = option.yAxis.maxInterval / (Math.ceil(option.series.length / 5) + 1)
|
||||
} else {
|
||||
option.yAxis.maxInterval = option.yAxis.maxInterval * (Math.ceil(option.series.length / 5) + 1)
|
||||
}
|
||||
}
|
||||
myChart.setOption(option)
|
||||
}
|
||||
},
|
||||
@@ -492,6 +499,22 @@ export default {
|
||||
setTimeout(() => {
|
||||
getChart(this.chartId) && getChart(this.chartId).resize()
|
||||
}, 100)
|
||||
},
|
||||
legendChange (isGrey) {
|
||||
let flag = false
|
||||
// 点击legend 如果右y轴数据有一个不是灰色 则显示右y轴name
|
||||
isGrey.forEach((item, index) => {
|
||||
if (this.series[index].yAxisIndex == 1 && item == false) {
|
||||
flag = true
|
||||
}
|
||||
})
|
||||
this.hasRightYAxis = flag
|
||||
|
||||
const myChart = getChart(this.chartId)
|
||||
const option = myChart.getOption()
|
||||
if (option.yAxis[1].min && option.yAxis[1].max) {
|
||||
this.hasRightYAxis = true
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
@@ -504,3 +527,25 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.rightYAxis-name{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
line-height: 100%;
|
||||
margin-left: calc(50% - 18px);
|
||||
font-size: 12px;
|
||||
color:#666666;
|
||||
pointer-events:none;
|
||||
span{
|
||||
transform: rotate(90deg);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,30 +10,110 @@
|
||||
<span v-else>--</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="(item, index) in legends"
|
||||
<!-- 左y轴legend -->
|
||||
<div
|
||||
v-for="(item, index) in legends"
|
||||
:key="index"
|
||||
v-show="series[index].yAxisIndex!=1"
|
||||
:class="{'row--inactive': isGrey[index]}"
|
||||
class="legend--table-row"
|
||||
@click="clickLegend(item.name, index)"
|
||||
>
|
||||
<div :title="item.alias ? item.alias : item.name" class="legend--table-cell">
|
||||
<span :style="{background: item.color}" class="legend-shape"></span>{{item.alias ? item.alias : item.name}}
|
||||
<i v-if="series[index].yAxisIndex==0" :style="{color: item.color}" class="yAxis-icon nz-icon nz-icon-zuozongzhou"></i>
|
||||
<span v-else :style="{background: item.color}" class="legend-shape"></span>
|
||||
<span>{{item.alias ? item.alias : item.name}}</span>
|
||||
</div>
|
||||
<div v-for="(statistics, index) in item.statistics" :key="index" :class="{'legend-item--inactive': isGrey[index]}" class="legend--table-cell">{{(keepTwoDecimalFull(statistics.value))}}</div>
|
||||
</div>
|
||||
<!-- 右y轴legend -->
|
||||
<div
|
||||
v-for="(item, index) in legends"
|
||||
:key="index+'right'"
|
||||
v-show="series[index].yAxisIndex==1"
|
||||
:class="{'row--inactive': isGrey[index]}"
|
||||
class="legend--table-row"
|
||||
@click="clickLegend(item.name, index)"
|
||||
>
|
||||
<div :title="item.alias ? item.alias : item.name" class="legend--table-cell">
|
||||
<i v-if="series[index].yAxisIndex==1" :style="{color: item.color}" class="yAxis-icon nz-icon nz-icon-youzongzhou"></i>
|
||||
<span v-else :style="{background: item.color}" class="legend-shape"></span>
|
||||
<span>{{item.alias ? item.alias : item.name}}</span>
|
||||
</div>
|
||||
<div v-for="(statistics, index) in item.statistics" :key="index" :class="{'legend-item--inactive': isGrey[index]}" class="legend--table-cell">{{(keepTwoDecimalFull(statistics.value))}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 否则是普通形式 -->
|
||||
<template v-else>
|
||||
<div
|
||||
<!-- placement=bottom -->
|
||||
<template v-else-if="chartInfo.param.legend.placement=='bottom'">
|
||||
<div class="legend-box">
|
||||
<div style="display:flex">
|
||||
<!-- 左y轴legend -->
|
||||
<ul>
|
||||
<li
|
||||
v-for="(item, index) in legends"
|
||||
:key="index"
|
||||
v-show="series[index].yAxisIndex!=1"
|
||||
:class="{'legend-item--inactive': isGrey[index]}"
|
||||
:title="item.alias ? item.alias : item.name"
|
||||
class="legend-item"
|
||||
@click="clickLegend(item.name, index)"
|
||||
>
|
||||
<span :style="{background: item.color}" class="legend-shape"></span>{{item.alias ? item.alias : item.name.split('-')[0]}}
|
||||
<i v-if="series[index].yAxisIndex==0" :style="{color: item.color}" class="yAxis-icon nz-icon nz-icon-zuozongzhou"></i>
|
||||
<span v-else :style="{background: item.color}" class="legend-shape"></span>
|
||||
<span>{{item.alias ? item.alias : item.name.split('-')[0]}}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- 右y轴legend -->
|
||||
<div class="rightYAxis">
|
||||
<ul>
|
||||
<li
|
||||
v-for="(item, index) in legends"
|
||||
:key="index+'right'"
|
||||
v-show="series[index].yAxisIndex==1"
|
||||
:class="{'legend-item--inactive': isGrey[index]}"
|
||||
:title="item.alias ? item.alias : item.name"
|
||||
class="legend-item"
|
||||
@click="clickLegend(item.name, index)"
|
||||
>
|
||||
<i v-if="series[index].yAxisIndex==1" :style="{color: item.color}" class="yAxis-icon nz-icon nz-icon-youzongzhou"></i>
|
||||
<span v-else :style="{background: item.color}" class="legend-shape"></span>
|
||||
<span>{{item.alias ? item.alias : item.name.split('-')[0]}}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 否则是普通形式 -->
|
||||
<template v-else>
|
||||
<!-- 左y轴legend -->
|
||||
<div
|
||||
v-for="(item, index) in legends"
|
||||
:key="index"
|
||||
v-show="series[index].yAxisIndex!=1"
|
||||
:class="{'legend-item--inactive': isGrey[index]}"
|
||||
:title="item.alias ? item.alias : item.name"
|
||||
class="legend-item"
|
||||
@click="clickLegend(item.name, index)"
|
||||
>
|
||||
<i v-if="series[index].yAxisIndex==0" :style="{color: item.color}" class="yAxis-icon nz-icon nz-icon-zuozongzhou"></i>
|
||||
<span v-else :style="{background: item.color}" class="legend-shape"></span>
|
||||
<span>{{item.alias ? item.alias : item.name.split('-')[0]}}</span>
|
||||
</div>
|
||||
<!-- 右y轴legend -->
|
||||
<div
|
||||
v-for="(item, index) in legends"
|
||||
:key="index+'right'"
|
||||
v-show="series[index].yAxisIndex==1"
|
||||
:class="{'legend-item--inactive': isGrey[index]}"
|
||||
:title="item.alias ? item.alias : item.name"
|
||||
class="legend-item"
|
||||
@click="clickLegend(item.name, index)"
|
||||
>
|
||||
<i v-if="series[index].yAxisIndex==1" :style="{color: item.color}" class="yAxis-icon nz-icon nz-icon-youzongzhou"></i>
|
||||
<span v-else :style="{background: item.color}" class="legend-shape"></span>
|
||||
<span>{{item.alias ? item.alias : item.name.split('-')[0]}}</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@@ -126,43 +206,13 @@ export default {
|
||||
})
|
||||
this.$set(this.isGrey, index, !this.isGrey[index])
|
||||
}
|
||||
if (isTimeSeries(this.chartInfo.type)) {
|
||||
this.$parent.legendChange(this.isGrey)
|
||||
}
|
||||
// 判断timeSeries类型图表 建立多表联动
|
||||
if (isTimeSeries(this.chartInfo.type) && (this.isConnect && this.isConnect !== 'none')) {
|
||||
chart.connect('timeSeriesGroup')
|
||||
}
|
||||
|
||||
if (this.chartInfo.type == 'line' || this.chartInfo.type == 'area' || this.chartInfo.type == 'point') {
|
||||
if (this.chartInfo.param.min || this.chartInfo.param.max) {
|
||||
return
|
||||
}
|
||||
// 处理点击后的 Y轴
|
||||
const chartInfo = this.chartInfo
|
||||
const dataArg = this.series.filter((seriesItem, seriesIndex) => !this.isGrey[seriesIndex])
|
||||
const maxValueCopies = this.getMaxValue(dataArg, chartInfo)
|
||||
const maxValue = maxValueCopies.maxValue
|
||||
const copies = maxValueCopies.copies
|
||||
const unit = maxValueCopies.unit
|
||||
const option = {
|
||||
yAxis: {
|
||||
minInterval: chartDataFormat.Interval(maxValue, copies, unit.type, 'min'),
|
||||
maxInterval: chartDataFormat.Interval(maxValue, copies, unit.type, 'max') * Math.ceil(dataArg.length / 5)
|
||||
}
|
||||
}
|
||||
if (!maxValueCopies.copies) {
|
||||
option.yAxis.min = 0
|
||||
option.yAxis.max = 1
|
||||
} else {
|
||||
option.yAxis.max = undefined
|
||||
}
|
||||
if (unit.type == 'Time' || option.yAxis.maxInterval === 1) {
|
||||
delete option.yAxis.maxInterval
|
||||
}
|
||||
getChart(this.chartId) && getChart(this.chartId).setOption({
|
||||
yAxis: {
|
||||
...option.yAxis
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
clickLegendBar (legendName, index, hasGrey, curIsGrey, currentIsTheOnlyOneHighlight) {
|
||||
@@ -302,5 +352,15 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.legend-box{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.rightYAxis{
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
flex-grow: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -85,7 +85,9 @@ export const chartTimeSeriesLineOption = {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
yAxis: [
|
||||
{
|
||||
name: '',
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: true,
|
||||
@@ -108,6 +110,31 @@ export const chartTimeSeriesLineOption = {
|
||||
// formatter: 动态生成
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false,
|
||||
lineStyle: {
|
||||
color: '#d9d9d9',
|
||||
opacity: 0.8,
|
||||
width: 1
|
||||
}
|
||||
},
|
||||
// 去掉y轴
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
fontSize: 10
|
||||
// formatter: 动态生成
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [{
|
||||
name: '',
|
||||
type: 'line',
|
||||
|
||||
@@ -72,6 +72,17 @@ export default {
|
||||
}
|
||||
this.isNoData = false
|
||||
const s = lodash.cloneDeep(seriesTemplate)
|
||||
|
||||
// 设置右y轴
|
||||
if (chartInfo.param.enable.rightYAxis) {
|
||||
s.yAxisIndex = 0
|
||||
chartInfo.param.rightYAxis && chartInfo.param.rightYAxis.elementNames.forEach(item => {
|
||||
if (data.elements.name == item) {
|
||||
s.yAxisIndex = 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (s.param && s.param.nullType) {
|
||||
s.connectNulls = s.param.nullType !== 'null'
|
||||
} else {
|
||||
@@ -81,13 +92,15 @@ export default {
|
||||
s.data = data.values
|
||||
s.name = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex).name
|
||||
if (chartInfo.param.stack) { // 堆叠
|
||||
s.stack = 'Total'
|
||||
s.stack = 'Total' + s.yAxisIndex
|
||||
}
|
||||
if (chartInfo.param.enable && chartInfo.param.enable.thresholds && !lodash.isEmpty(chartInfo.param.thresholds) && chartInfo.param.thresholds.length) { // 阈值
|
||||
s.markLine = {
|
||||
symbol: 'circle',
|
||||
symbolSize: 5
|
||||
}
|
||||
// Thresholds 只对左Y轴有效
|
||||
if (s.yAxisIndex != 1) {
|
||||
s.markLine.data = chartInfo.param.thresholds.map(threshold => {
|
||||
return {
|
||||
yAxis: threshold.value || 0,
|
||||
@@ -99,6 +112,7 @@ export default {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// 判断如果是面积图 颜色设为渐变色
|
||||
if (s.areaStyle && this.colorList.length) {
|
||||
s.areaStyle = {
|
||||
|
||||
@@ -306,6 +306,7 @@ export default {
|
||||
} else {
|
||||
if (r.status === 'success') {
|
||||
r.data.result.forEach(item => {
|
||||
item.elements = elements[rIndex - elements.length]
|
||||
this.allDataLength++
|
||||
item.values.forEach(values => {
|
||||
values[0] = values[0] + this.minusTime / 1000
|
||||
|
||||
@@ -42,11 +42,12 @@
|
||||
}">
|
||||
<i class="nz-icon nz-icon-arrow-down" :class="expressionsShow[index-1].show?'':'is-active'" @click.stop="showExpression(index)"></i>
|
||||
<el-input
|
||||
style="width: 120px"
|
||||
@mousedown.stop
|
||||
v-model="expressionName[index-1]"
|
||||
size="small"
|
||||
@input="(val)=>{expressionNameInput(val,index-1)}"
|
||||
@change="expressionNameChange(index-1)" style="width: 120px"
|
||||
@change="expressionNameChange(index-1)"
|
||||
@focus.stop="showInput(index-1,false)"
|
||||
@blur="showInput(index-1,true)"
|
||||
/>
|
||||
@@ -136,8 +137,7 @@
|
||||
<el-option
|
||||
v-for="item in chartTypeList"
|
||||
:key="item.id"
|
||||
:disabled="
|
||||
item.id==='group' && chartConfig.isGroup"
|
||||
:disabled="item.id==='group' && chartConfig.isGroup"
|
||||
:label="item.name"
|
||||
:value="item.id">
|
||||
<span class="panel-dropdown-label-txt" >{{item.name}}</span>
|
||||
@@ -411,6 +411,133 @@
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<!-- Right Y Axis -->
|
||||
<div v-if="isShowRightYAxis(chartConfig.type)">
|
||||
<div class="form__sub-title">
|
||||
<span>{{$t('dashboard.panel.chartForm.rightYAxis')}}</span>
|
||||
<el-switch
|
||||
v-model="chartConfig.param.enable.rightYAxis"
|
||||
size="small"
|
||||
@change="change"
|
||||
></el-switch>
|
||||
</div>
|
||||
<transition name="el-zoom-in-top">
|
||||
<div
|
||||
v-if="chartConfig.param.enable.rightYAxis"
|
||||
class="form-items--half-width-group"
|
||||
>
|
||||
<!-- Data Source -->
|
||||
<el-form-item
|
||||
:label="$t('dashboard.panel.chartForm.datasource')"
|
||||
class="form-item--half-width"
|
||||
prop="param.rightYAxis.elementNames"
|
||||
:rules="{ required: true, message: $t('validate.required'), trigger: 'change'}"
|
||||
>
|
||||
<el-select
|
||||
v-model="chartConfig.param.rightYAxis.elementNames"
|
||||
multiple
|
||||
collapse-tags
|
||||
placeholder=""
|
||||
popper-class="right-box-select-top prevent-clickoutside"
|
||||
size="small"
|
||||
@change="change"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in chartConfig.elements"
|
||||
:key="item.name"
|
||||
:label="item.name"
|
||||
:value="item.name"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- type -->
|
||||
<el-form-item
|
||||
:label="$t('overall.type')"
|
||||
class="form-item--half-width"
|
||||
prop="param.rightYAxis.style"
|
||||
>
|
||||
<el-select
|
||||
v-model="chartConfig.param.rightYAxis.style"
|
||||
placeholder=""
|
||||
popper-class="right-box-select-top prevent-clickoutside"
|
||||
size="small"
|
||||
@change="change"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in timeSeriesTypeList"
|
||||
:key="item.value"
|
||||
:label="$t(item.name)"
|
||||
:value="item.id"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- unit -->
|
||||
<el-form-item
|
||||
:label="$t('dashboard.panel.chartForm.unit')"
|
||||
class="form-item--half-width"
|
||||
prop="param.rightYAxis.unit"
|
||||
>
|
||||
<el-cascader
|
||||
v-model="chartConfig.param.rightYAxis.unit"
|
||||
:options="unitOptions"
|
||||
:props="{ expandTrigger: 'hover',emitPath:false }"
|
||||
:show-all-levels="false"
|
||||
filterable
|
||||
popper-class="dc-dropdown right-box-select-top right-public-box-dropdown-top prevent-clickoutside chart-box-unit"
|
||||
size="small"
|
||||
style="width: 100%"
|
||||
@change="unitSelected"
|
||||
>
|
||||
</el-cascader>
|
||||
</el-form-item>
|
||||
<!-- label -->
|
||||
<el-form-item
|
||||
:label="$t('alert.list.labels')"
|
||||
class="form-item--half-width"
|
||||
prop="param.rightYAxis.label"
|
||||
>
|
||||
<el-input
|
||||
size="small"
|
||||
v-model="chartConfig.param.rightYAxis.label"
|
||||
placeholder=""
|
||||
@change="change"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<!--min-->
|
||||
<el-form-item
|
||||
:label="$t('dashboard.panel.chartForm.min')"
|
||||
class="form-item--half-width"
|
||||
prop="param.rightYAxis.min"
|
||||
>
|
||||
<el-input-number
|
||||
size="small"
|
||||
style="margin-top: 2px"
|
||||
:controls="false"
|
||||
@change="change"
|
||||
show-word-limit
|
||||
:placeholder="chartConfig.param.rightYAxis.min?'':'Auto'"
|
||||
v-model="chartConfig.param.rightYAxis.min"/>
|
||||
</el-form-item>
|
||||
<!--max-->
|
||||
<el-form-item
|
||||
:label="$t('dashboard.panel.chartForm.max')"
|
||||
class="form-item--half-width"
|
||||
prop="param.rightYAxis.max"
|
||||
>
|
||||
<el-input-number
|
||||
size="small"
|
||||
style="margin-top: 2px"
|
||||
:controls="false"
|
||||
@change="change"
|
||||
show-word-limit
|
||||
:placeholder="chartConfig.param.rightYAxis.max?'':'Auto'"
|
||||
v-model="chartConfig.param.rightYAxis.max"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
|
||||
<div v-if="isShowLegend(chartConfig.type)">
|
||||
<!--legendConfig-->
|
||||
<div class="form__sub-title">
|
||||
@@ -1041,7 +1168,8 @@ export default {
|
||||
legend: true,
|
||||
valueMapping: false,
|
||||
thresholds: false,
|
||||
visibility: false
|
||||
visibility: false,
|
||||
rightYAxis: false
|
||||
},
|
||||
showHeader: this.chartConfig.param.showHeader,
|
||||
visibility: {
|
||||
@@ -1049,6 +1177,14 @@ export default {
|
||||
operator: 'equal',
|
||||
varValue: '',
|
||||
result: 'show'
|
||||
},
|
||||
rightYAxis: {
|
||||
elementNames: [],
|
||||
style: 'line',
|
||||
unit: 2,
|
||||
label: '',
|
||||
min: undefined,
|
||||
max: undefined
|
||||
}
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
|
||||
@@ -222,6 +222,15 @@ export default {
|
||||
return true
|
||||
default: return false
|
||||
}
|
||||
},
|
||||
isShowRightYAxis (type) {
|
||||
switch (type) {
|
||||
case 'line':
|
||||
case 'area':
|
||||
case 'point':
|
||||
return true
|
||||
default: return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,7 +338,6 @@ export default {
|
||||
id: 'table',
|
||||
name: this.$t('dashboard.panel.chartForm.typeVal.table.label')
|
||||
}
|
||||
|
||||
],
|
||||
textList: [
|
||||
{
|
||||
@@ -365,6 +364,20 @@ export default {
|
||||
label: this.$t('dashboard.panel.chartForm.typeVal.server')
|
||||
}
|
||||
],
|
||||
timeSeriesTypeList: [
|
||||
{
|
||||
id: 'line',
|
||||
name: this.$t('dashboard.panel.chartForm.typeVal.line.label')
|
||||
},
|
||||
{
|
||||
id: 'area',
|
||||
name: this.$t('dashboard.panel.chartForm.typeVal.stackArea.label')
|
||||
},
|
||||
{
|
||||
id: 'point',
|
||||
name: this.$t('dashboard.panel.chartForm.typeVal.point.label')
|
||||
}
|
||||
],
|
||||
isChoose: []
|
||||
}
|
||||
},
|
||||
@@ -424,6 +437,11 @@ export default {
|
||||
} else if (!this.expressionName[index]) {
|
||||
this.expressionName[index] = this.expressionsShow[index].oldName
|
||||
} else {
|
||||
this.chartConfig.param.rightYAxis && this.chartConfig.param.rightYAxis.elementNames.forEach((item, index) => {
|
||||
if (item == this.expressionsShow[index].oldName) {
|
||||
this.chartConfig.param.rightYAxis.elementNames[index] = this.expressionName[index]
|
||||
}
|
||||
})
|
||||
this.expressionsShow[index].oldName = this.expressionName[index]
|
||||
}
|
||||
this.$refs.chartForm.clearValidate('elements.' + (index - 1) + '.expression')
|
||||
@@ -481,8 +499,7 @@ export default {
|
||||
} else {
|
||||
this.expressions.push(item.expression)
|
||||
this.expressionName.push(item.name)
|
||||
this.expressionsShow.push(
|
||||
{
|
||||
this.expressionsShow.push({
|
||||
show: true,
|
||||
hideInput: true,
|
||||
oldName: item.name,
|
||||
@@ -490,8 +507,7 @@ export default {
|
||||
elementId: item.id,
|
||||
legend: item.legend,
|
||||
state: item.state
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
},
|
||||
copyExpression (index) {
|
||||
@@ -510,16 +526,20 @@ export default {
|
||||
)
|
||||
this.$nextTick(() => {
|
||||
this.expressions.forEach((ex, index) => {
|
||||
if (ex) {
|
||||
this.$refs[`promql-${index}`][0].metricChange(ex)
|
||||
this.$refs[`promql-${index}`][0].promqlInputChange(ex)
|
||||
}
|
||||
})
|
||||
})
|
||||
this.expressionChange()
|
||||
},
|
||||
removeExpression (index) {
|
||||
if (this.expressionsShow.length > 1) {
|
||||
this.chartConfig.param.rightYAxis && this.chartConfig.param.rightYAxis.elementNames.forEach((elementName, subIndex) => {
|
||||
if (elementName == this.expressionName[index]) {
|
||||
this.chartConfig.param.rightYAxis.elementNames.splice(subIndex, 1)
|
||||
}
|
||||
})
|
||||
|
||||
this.expressions.splice(index, 1)
|
||||
this.expressionName.splice(index, 1)
|
||||
this.expressionsShow.splice(index, 1)
|
||||
@@ -528,10 +548,8 @@ export default {
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
this.expressions.forEach((ex, index) => {
|
||||
if (ex) {
|
||||
this.$refs[`promql-${index}`][0].metricChange(ex)
|
||||
this.$refs[`promql-${index}`][0].promqlInputChange(ex)
|
||||
}
|
||||
})
|
||||
})
|
||||
this.expressionChange()
|
||||
|
||||
@@ -248,7 +248,8 @@ export default {
|
||||
legend: true,
|
||||
valueMapping: false,
|
||||
thresholds: false,
|
||||
visibility: false
|
||||
visibility: false,
|
||||
rightYAxis: false
|
||||
},
|
||||
thresholdShow: true,
|
||||
thresholds: [{ value: undefined, color: randomcolor() }],
|
||||
@@ -258,6 +259,14 @@ export default {
|
||||
operator: 'equal',
|
||||
varValue: '',
|
||||
result: 'show'
|
||||
},
|
||||
rightYAxis: {
|
||||
elementNames: [],
|
||||
style: 'line',
|
||||
unit: 2,
|
||||
label: '',
|
||||
min: undefined,
|
||||
max: undefined
|
||||
}
|
||||
},
|
||||
elements: [{ expression: '', legend: '', type: 'expert', id: '', name: 'A', state: 1, orderNum: 0 }],
|
||||
@@ -269,7 +278,7 @@ export default {
|
||||
},
|
||||
pageObj: {
|
||||
pageNo: 1,
|
||||
pageSize: -1, // 此处获取所有数据,所以设置一个较大的值
|
||||
pageSize: -1, // 此处获取所有数据
|
||||
total: 0
|
||||
},
|
||||
blankChartTemp: {
|
||||
@@ -602,7 +611,16 @@ export default {
|
||||
} else {
|
||||
this.chart.param = {}
|
||||
}
|
||||
|
||||
if (!this.chart.param.rightYAxis) {
|
||||
this.chart.param.rightYAxis = {
|
||||
elementNames: [],
|
||||
style: 'line',
|
||||
unit: 2,
|
||||
label: '',
|
||||
min: undefined,
|
||||
max: undefined
|
||||
}
|
||||
}
|
||||
if (!this.chart.groupId || this.chart.groupId == -1) {
|
||||
this.chart.groupId = ''
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user