diff --git a/nezha-fronted/src/components/chart/ChartScreenHeader.vue b/nezha-fronted/src/components/chart/ChartScreenHeader.vue index 7317b9eee..1d4c78ed8 100644 --- a/nezha-fronted/src/components/chart/ChartScreenHeader.vue +++ b/nezha-fronted/src/components/chart/ChartScreenHeader.vue @@ -27,9 +27,9 @@ -
+
- {{chartInfo.name}} + {{nameFormate()}}
diff --git a/nezha-fronted/src/components/chart/chartHeader.vue b/nezha-fronted/src/components/chart/chartHeader.vue index 6f21283d7..2b3eaa6e2 100644 --- a/nezha-fronted/src/components/chart/chartHeader.vue +++ b/nezha-fronted/src/components/chart/chartHeader.vue @@ -40,10 +40,10 @@ -
{{chartInfo.name}}
+
{{nameFormate()}}
- {{chartInfo.name}} + {{nameFormate()}} ({{chartData ? chartData.length : 0}} charts)
@@ -56,7 +56,7 @@ - + @@ -71,7 +71,7 @@
- + diff --git a/nezha-fronted/src/components/chart/chartHeaderMixin.js b/nezha-fronted/src/components/chart/chartHeaderMixin.js index 214b4d6af..cde2737f0 100644 --- a/nezha-fronted/src/components/chart/chartHeaderMixin.js +++ b/nezha-fronted/src/components/chart/chartHeaderMixin.js @@ -84,6 +84,39 @@ export default { }, unitChange (val) { this.$emit('unitChange', val) + }, + // 所有类型 chart name 支持变量替换 + nameFormate () { + let str = this.chartInfo.name + // group图表设置repeat的name替换 + if (this.chartInfo.repeatVariable) { + const variable = this.chartInfo.repeatVariable + const reg = new RegExp('\\$' + variable, 'g') + str = str.replace(reg, this.chartInfo.repeatValue.replace(/\"/g, '\\"').replace(/\'/g, "\\'")) + } + let confirmReg = [] + this.variablesArr.forEach(item => { + const reg = '$' + item.name // 后续需要考虑 item,name 使用特殊字符的问题 + const index = this.chartInfo.name.indexOf(reg) + if (index !== -1) { + confirmReg.push(item) + } + }) + confirmReg = this.$loadsh.orderBy(confirmReg, function (item) { // 根据 匹配的name的长度排序 避免匹配的 $a 没匹配 $asset的问题 + return item.name.length + }, 'desc') + if (confirmReg.length) { + confirmReg.forEach(item => { + const reg = new RegExp('\\$' + item.name, 'g') // 后续需要考虑 item,name 使用特殊字符的问题 + str = str.replace(reg, item.checked.map(label => label.replace(/\"/g, '\\"').replace(/\'/g, "\\'")).join('+')) + }) + } + return str + } + }, + computed: { + variablesArr () { + return this.$store.getters.getVariablesArr } }, watch: { @@ -94,6 +127,14 @@ export default { this.errorText = this.chartData.filter(item => item.error).map(item => item.error).join('\n') } } + }, + 'chartInfo.repeatVariable': { + immediate: true, + handler (n) { + if (n) { + this.nameFormate() + } + } } } } diff --git a/nezha-fronted/src/components/chart/chartList.vue b/nezha-fronted/src/components/chart/chartList.vue index a38c848ff..8e8a06182 100644 --- a/nezha-fronted/src/components/chart/chartList.vue +++ b/nezha-fronted/src/components/chart/chartList.vue @@ -243,7 +243,7 @@ export default { }, movedEvent (i, newX, newY) { if (!this.isGroup) { - this.moveChart() + this.moveChart(i, newX, newY) this.onScroll(this.scrollTop) } else { bus.$emit('groupChildMove') @@ -280,9 +280,22 @@ export default { this.$set(this.copyDataList, index, chart) this.onScroll(this.scrollTop) }, - moveChart () { + moveChart (id, newX, newY) { + if (!this.groupInfo) { + const moveItem = this.copyDataList.find(item => item.id == id) + const moveIndex = this.copyDataList.findIndex(item => item.id == id) + let num = 1 + this.copyDataList.forEach((item, index) => { + const moveId = String(id).split('-repeat-')[0] + const repeatId = String(item.id).split('-repeat-')[0] + if (moveId == repeatId && moveIndex != index) { + item.y = moveItem.y + (num * 0.1) + num++ + } + }) + } this.onScroll(this.scrollTop) - const arr = this.copyDataList.filter(item => !item.staic) + const arr = this.copyDataList.filter(item => !item.staic && !item.repeatIndex) const charts = [] let weight = 0 arr.forEach(item => { @@ -393,7 +406,7 @@ export default { bus.$emit('refreshPanel') }, createChartSuccess (params) { - const arr = this.copyDataList.filter(item => !item.staic) + const arr = this.copyDataList.filter(item => !item.staic && !item.repeatIndex) const charts = [] let weight = 0 arr.forEach(item => { @@ -453,6 +466,10 @@ export default { }, // 比较变量 图表是否显示/隐藏 compareVariables () { + // 防止group中的chartList执行 + if (this.groupInfo) { + return + } const isRegExp = (v) => { let isReg try { @@ -539,7 +556,75 @@ export default { } }) this.onScroll(this.scrollTop) + }, + + // group设置repeat 便利变量重复渲染图表 + repeatVariableFn () { + // 防止group中的chartList执行 + if (this.groupInfo) { + return + } + // 先删除掉复制的数据 + for (let index = 0; index < this.copyDataList.length; index++) { + const item = this.copyDataList[index] + if (item.repeatIndex > 0) { + this.copyDataList.splice(index, 1) + index-- + } + } + this.$nextTick(() => { + for (let index = 0; index < this.copyDataList.length; index++) { + const item = this.copyDataList[index] + if (this.$loadsh.get(this.showHidden[item.id], 'visibility') !== 'hidden' && this.$loadsh.get(item.param.enable, 'repeat')) { + this.variablesArr.forEach((variables) => { + const repeatVariable = this.$loadsh.get(item.param.repeat, 'variable') + if (item.type === 'group' && variables.name === repeatVariable) { + if (!variables.checked.length) { + item.children.forEach(children => { + delete children.repeatIndex + delete children.repeatVariable + delete children.repeatValue + }) + return + } + variables.checked.forEach((subItem, subIndex) => { + if (subIndex > 0) { + // 复制数据 重新设置id + const repeatItem = this.$loadsh.cloneDeep(item) + repeatItem.id = item.id + '-' + 'repeat-' + subIndex + repeatItem.i = repeatItem.id + repeatItem.repeatIndex = subIndex + repeatItem.repeatVariable = repeatVariable + repeatItem.repeatValue = subItem + repeatItem.children.forEach(children => { + children.id = children.id + '-' + 'repeat-' + subIndex + children.repeatIndex = subIndex + children.repeatVariable = repeatVariable + children.repeatValue = subItem + }) + index += 1 + // 复制数据 + this.copyDataList.splice(index, 0, repeatItem) + } else { + item.repeatIndex = 0 + item.repeatVariable = repeatVariable + item.repeatValue = subItem + item.children.forEach(children => { + children.repeatIndex = 0 + children.repeatVariable = repeatVariable + children.repeatValue = subItem + }) + this.$refs['chart' + item.id] && this.$refs['chart' + item.id][0] && this.$refs['chart' + item.id][0].getChartData() + } + }) + } + }) + } + } + this.onScroll(this.scrollTop) + }) } + }, created () { this.firstInit = true @@ -572,9 +657,11 @@ export default { }, // 监听变量数组 variablesArr: { - handler () { + handler (newVal, oldVal) { // 比较变量 图表是否显示/隐藏 this.compareVariables() + + this.repeatVariableFn() } }, panelLock: { @@ -673,6 +760,8 @@ export default { this.copyDataList = JSON.parse(JSON.stringify(tempList)) // 比较变量 图表是否显示/隐藏 this.compareVariables() + + this.repeatVariableFn() tempList = null setTimeout(() => { this.gridLayoutShow = true diff --git a/nezha-fronted/src/components/chart/panelChart.vue b/nezha-fronted/src/components/chart/panelChart.vue index cc1d737ae..97ab29128 100644 --- a/nezha-fronted/src/components/chart/panelChart.vue +++ b/nezha-fronted/src/components/chart/panelChart.vue @@ -187,9 +187,15 @@ export default { if (!this.chartInfo.oldElements) { // 创建一个备份 用于判断变量替换 能拿到原本变量的位置 this.chartInfo.oldElements = this.chartInfo.elements ? JSON.parse(JSON.stringify(this.chartInfo.elements)) : [] } - this.chartInfo.elements = this.chartInfo.oldElements.filter(item => item.state) // 处理不显示的表达式 - this.chartInfo.elements = this.chartInfo.elements.map(item => { // 处理表达式的变量 - const variables = this.variablesReplace(item.expression) + // eslint-disable-next-line vue/no-mutating-props + this.chartInfo.elements = this.$loadsh.cloneDeep(this.chartInfo.oldElements.filter(item => item.state)) // 处理不显示的表达式 + // eslint-disable-next-line vue/no-mutating-props + this.chartInfo.elements = this.chartInfo.elements.map((item, index) => { // 处理表达式的变量 + // group图表设置repeat的表达式替换 + if (this.chartInfo.repeatVariable) { + item.expression = this.variablesReplaceRepeat(item.expression) + } + const variables = this.variablesReplace((item.expression)) this.myVariables.push(variables) return { ...item, @@ -574,6 +580,14 @@ export default { } return str }, + // group图表repeat 表达式替换 + variablesReplaceRepeat (expression) { + let str = expression + const variable = this.chartInfo.repeatVariable + const reg = new RegExp('\\$' + variable, 'g') + str = str.replace(reg, this.chartInfo.repeatValue.replace(/\"/g, '\\"').replace(/\'/g, "\\'")) + return str + }, getHexagonFigureData () { return new Promise(resolve => { this.$get('stat/alertMessage/topN', { size: 48, dimension: 'module' }).then(response => { @@ -766,7 +780,7 @@ export default { }, variablesArr: { handler (n) { - const elements = this.chartInfo.oldElements || [] + const elements = this.$loadsh.cloneDeep(this.chartInfo.oldElements) || [] const variables = elements.map((element) => { return this.variablesReplace(element.expression) }) diff --git a/nezha-fronted/src/components/common/panel/panelVariables.vue b/nezha-fronted/src/components/common/panel/panelVariables.vue index 4ebc43eac..c0823ff5a 100644 --- a/nezha-fronted/src/components/common/panel/panelVariables.vue +++ b/nezha-fronted/src/components/common/panel/panelVariables.vue @@ -389,13 +389,22 @@ export default { }) }, close () { + let flag = false this.labelArr.forEach((item) => { if (item.visible && item.multi) { - this.$store.dispatch('dispatchVariablesArr', [...this.labelArr]) + flag = true } item.visible = false }) + if (flag) { + const oldVariables = this.$store.state.panel.variablesArr + // 如果新旧值相等 则不执行 + if (JSON.stringify(oldVariables) !== JSON.stringify(this.labelArr)) { + this.$store.dispatch('dispatchVariablesArr', [...this.labelArr]) + } + } } + }, beforeDestroy () { this.$store.dispatch('dispatchVariablesArr', []) diff --git a/nezha-fronted/src/store/panel.js b/nezha-fronted/src/store/panel.js index 5c5615346..07041cb13 100644 --- a/nezha-fronted/src/store/panel.js +++ b/nezha-fronted/src/store/panel.js @@ -94,7 +94,7 @@ const panel = { state.currentMousemove = value }, setVariablesArr (state, value) { - state.variablesArr = value + state.variablesArr = JSON.parse(JSON.stringify(value)) }, setTimeBoxClass (state, value) { state.timeBoxClass = value