diff --git a/nezha-fronted/src/components/chart/chart.vue b/nezha-fronted/src/components/chart/chart.vue index ab8cb5cda..26c75e0c2 100644 --- a/nezha-fronted/src/components/chart/chart.vue +++ b/nezha-fronted/src/components/chart/chart.vue @@ -17,6 +17,7 @@ :showAllData="showAllData" @chartIsNoData="chartIsNoData" :from="from" + :globalVariables="globalVariables" > @@ -256,7 +280,6 @@ import chartText from './chart/chartText' import chartTimeSeries from './chart/chartTimeSeries' import chartTreemap from './chart/chartTreemap' import chartUrl from './chart/chartUrl' -import chartValue from './chart/chartValue' import chartHexagonD3 from './chart/chartHexagonD3' import chartMap from './chart/chartMap' import chartTopology from './chart/chartTopology' @@ -290,7 +313,6 @@ export default { chartTimeSeries, chartTreemap, chartUrl, - chartValue, chartHexagonD3, chartMap, chartTopology, @@ -322,7 +344,8 @@ export default { isExportHtml: { type: Boolean, default: false - } + }, + globalVariables: {} }, data () { return { diff --git a/nezha-fronted/src/components/chart/chart/chartLog.vue b/nezha-fronted/src/components/chart/chart/chartLog.vue index 97e865cda..555226b9d 100644 --- a/nezha-fronted/src/components/chart/chart/chartLog.vue +++ b/nezha-fronted/src/components/chart/chart/chartLog.vue @@ -186,6 +186,7 @@ export default { aliasLegend (row) { let host = ''// up, let alias = '' + row.elements.legend = this.globalVariablesReplace(row.elements.legend) if (row.labels && Object.keys(row.labels).length > 0) { const metric = Object.keys(row.labels) if (metric.__name__) { @@ -292,7 +293,9 @@ export default { deep: true, handler (n) { // this.tableData = this.tableData.reverse() - this.$emit('refreshLogs', this.operations) + this.$nextTick(() => { + this.$emit('refreshLogs', this.operations) + }) } } } diff --git a/nezha-fronted/src/components/chart/chart/chartTable.vue b/nezha-fronted/src/components/chart/chart/chartTable.vue index 408215c42..adae168b8 100644 --- a/nezha-fronted/src/components/chart/chart/chartTable.vue +++ b/nezha-fronted/src/components/chart/chart/chartTable.vue @@ -12,7 +12,7 @@ - - - - diff --git a/nezha-fronted/src/components/chart/chartHeaderMixin.js b/nezha-fronted/src/components/chart/chartHeaderMixin.js index e9f7abe54..29d585fef 100644 --- a/nezha-fronted/src/components/chart/chartHeaderMixin.js +++ b/nezha-fronted/src/components/chart/chartHeaderMixin.js @@ -120,6 +120,7 @@ export default { str = str.replace(reg, item.checked.map(label => label.replace(/\\"/g, '"').replace(/\\'/g, "'")).join('+')) }) } + this.chartInfo.varName = str return str } }, diff --git a/nezha-fronted/src/components/chart/chartMixin.js b/nezha-fronted/src/components/chart/chartMixin.js index b50b15c3f..9d2fa3684 100644 --- a/nezha-fronted/src/components/chart/chartMixin.js +++ b/nezha-fronted/src/components/chart/chartMixin.js @@ -37,7 +37,8 @@ export default { dialogPadding: { type: Number, default: 0 - } + }, + globalVariables: {} }, computed: { filterTime () { @@ -239,6 +240,9 @@ export default { const myParams = JSON.parse(JSON.stringify(params)) myParams.$labels = JSON.parse(JSON.stringify(params)) myParams.$value = myParams.value + if (this.from !== 'meta2dTooltip') { + aliasExpression = this.globalVariablesReplace(aliasExpression) + } if (/\{\{.+\}\}/.test(aliasExpression)) { const labelValue = aliasExpression.replace(/(\{\{.+?\}\})/g, function (i) { const label = i.substr(i.indexOf('{{') + 2, i.indexOf('}}') - i.indexOf('{{') - 2) @@ -275,6 +279,18 @@ export default { return aliasExpression } }, + globalVariablesReplace (expression) { + let str = expression + if (str) { + this.globalVariables.forEach(item => { + const reg = new RegExp('{{\\' + item.name + '}}', 'g') + if (item.value != null) { + str = str.replace(reg, item.value) + } + }) + } + return str + }, selectMapping (value, valueMapping, show) { let mapping = '' if (show && valueMapping) { diff --git a/nezha-fronted/src/components/chart/panelChart.vue b/nezha-fronted/src/components/chart/panelChart.vue index f018927bd..11ffee26f 100644 --- a/nezha-fronted/src/components/chart/panelChart.vue +++ b/nezha-fronted/src/components/chart/panelChart.vue @@ -43,6 +43,7 @@ item.state)) // 处理不显示的表达式 + // eslint-disable-next-line vue/no-mutating-props + this.chartInfo.elements = this.chartInfo.elements.map((item, index) => { // 处理表达式的变量 + // 全局变量替换 + this.setGlobalVariablesValue(searchTime) + item.expression = this.globalVariablesReplace(item.expression, searchTime) + // group图表设置repeat的表达式替换 + if (this.chartInfo.repeatVariable) { + item.expression = this.variablesReplaceRepeat(item.expression) + } + const variables = this.variablesReplace((item.expression)) + this.myVariables.push(variables) + return { + ...item, + expression: variables + } + }) + }, dateChange (filter, multipleTime) { this.loading = true // TODO assetInfo、endpointInfo、echarts等进行不同的处理 @@ -152,6 +175,7 @@ export default { const step = bus.getStep(startTime, endTime) startTime = this.$stringTimeParseToUnix(startTime) endTime = this.$stringTimeParseToUnix(endTime) + this.variablesHandle([filter.start_time, filter.end_time]) const elements = this.chartInfo.elements || [] if (multipleTime.length) { const minusTime = (new Date(bus.formateTimeToTime(filter.start_time)).getTime() - new Date(bus.formateTimeToTime(multipleTime[0])).getTime()) @@ -169,7 +193,6 @@ export default { return } this.chartData = window.dataJson ? this.chartData : [] - this.myVariables = [] this.loading = true // TODO assetInfo、endpointInfo、echarts等进行不同的处理 let startTime = '' @@ -203,21 +226,7 @@ export default { if (!this.chartInfo.oldElements) { // 创建一个备份 用于判断变量替换 能拿到原本变量的位置 this.chartInfo.oldElements = this.chartInfo.elements ? JSON.parse(JSON.stringify(this.chartInfo.elements)) : [] } - // 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, - expression: variables - } - }) + this.variablesHandle() const elements = this.chartInfo.elements || [] if (this.isExportHtml) { this.chartInfo.loaded && this.queryData(elements, startTime, endTime, step, params) diff --git a/nezha-fronted/src/components/common/bottomBox/tabs/dashboardTab.vue b/nezha-fronted/src/components/common/bottomBox/tabs/dashboardTab.vue index eb10fab8c..f5cb81d9f 100644 --- a/nezha-fronted/src/components/common/bottomBox/tabs/dashboardTab.vue +++ b/nezha-fronted/src/components/common/bottomBox/tabs/dashboardTab.vue @@ -880,8 +880,10 @@ export default { }, showPanel: { handler () { - this.setDefaultTimeRange() - this.setDefaultRefresh() + if (this.from !== this.fromRoute.dashboardTemp) { + this.setDefaultTimeRange() + this.setDefaultRefresh() + } } }, // 监听图表联动配置 @@ -936,6 +938,10 @@ export default { document.querySelector('#tableList') && document.querySelector('#tableList').removeEventListener('mouseleave', this.tableListLeave) this.scrollbarWrap && this.scrollbarWrap.removeEventListener('scroll', bus.debounce) this.$store.dispatch('dispatchPanelLock', { flag: true }) + this.$store.dispatch('dispatchPanelTime', { + time: [], + nowTimeType: {} + }) // 页面销毁 清除图表联动 this.$store.commit('setCurrentMousemove', 0) diff --git a/nezha-fronted/src/components/common/mixin/globalVariables.js b/nezha-fronted/src/components/common/mixin/globalVariables.js new file mode 100644 index 000000000..e29be9b32 --- /dev/null +++ b/nezha-fronted/src/components/common/mixin/globalVariables.js @@ -0,0 +1,140 @@ +import bus from '@/libs/bus' +import { stringTimeParseToUnixMs } from '@/components/common/js/tools.js' +export default { + data () { + return { + globalVariables: [ + { name: '$G.dashboard.name', value: null }, // dashboard名称 + { name: '$G.from.ms', value: null }, // 选定时间开始时间,单位ms + { name: '$G.from.s', value: null }, // 选定时间开始时间,单位s + { name: '$G.to.ms', value: null }, // 选定时间结束时间,单位ms + { name: '$G.to.s', value: null }, // 选定时间结束时间,单位s + { name: '$G.from.date', value: null }, // 选定时间开始时间,根据系统设定时间格式显示 + { name: '$G.to.date', value: null }, // 选定时间结束时间,根据系统设定时间格式显示 + { name: '$G.range.ms', value: null }, // to - from ,单位ms + { name: '$G.range.s', value: null }, // to - from,单位s + { name: '$G.range.text', value: null }, // to - from ,文字显示,如:1h24min + { name: '$G.chart.name', value: null }, // chart 名称 + { name: '$G.interval.ms', value: null }, // 计算的step参数值,单位ms + { name: '$G.interval.s', value: null } // 计算的step参数值,单位s + ] + } + }, + mounted () { + this.setGlobalVariablesValue() + }, + methods: { + setGlobalVariablesValue (searchTime) { + const timeRange = searchTime || this.timeRange + if (!timeRange) { + return + } + this.globalVariables.forEach(item => { + switch (item.name) { + case '$G.dashboard.name': { + item.value = this.chartInfo.dashboard ? this.chartInfo.dashboard.name : '' + break + } + case '$G.from.ms': { + item.value = stringTimeParseToUnixMs(bus.formateTimeToTime(timeRange[0])) + break + } + case '$G.from.s': { + item.value = this.$stringTimeParseToUnix(bus.formateTimeToTime(timeRange[0])) + break + } + case '$G.to.ms': { + item.value = stringTimeParseToUnixMs(bus.formateTimeToTime(timeRange[1])) + break + } + case '$G.to.s': { + item.value = this.$stringTimeParseToUnix(bus.formateTimeToTime(timeRange[1])) + break + } + case '$G.from.date': { + item.value = bus.timeFormate(timeRange[0]) + break + } + case '$G.to.date': { + item.value = bus.timeFormate(timeRange[1]) + break + } + case '$G.range.ms': { + item.value = stringTimeParseToUnixMs(bus.formateTimeToTime(timeRange[1])) - stringTimeParseToUnixMs(bus.formateTimeToTime(timeRange[0])) + break + } + case '$G.range.s': { + item.value = this.$stringTimeParseToUnix(bus.formateTimeToTime(timeRange[1])) - this.$stringTimeParseToUnix(bus.formateTimeToTime(timeRange[0])) + break + } + case '$G.range.text': { + item.value = this.rangeText(bus.formateTimeToTime(timeRange[0]), bus.formateTimeToTime(timeRange[1])) + break + } + case '$G.chart.name': { + item.value = this.chartInfo.varName + break + } + case '$G.interval.ms': { + const step = bus.getStep(bus.formateTimeToTime(timeRange[0]), bus.formateTimeToTime(timeRange[1])) + const unit = step[step.length - 1] + let value + if (unit === 's') { + value = parseInt(step) * 1000 + } else if (unit === 'm') { + value = parseInt(step) * 1000 * 60 + } + item.value = value + break + } + case '$G.interval.s': { + const step = bus.getStep(bus.formateTimeToTime(timeRange[0]), bus.formateTimeToTime(timeRange[1])) + const unit = step[step.length - 1] + let value + if (unit === 's') { + value = parseInt(step) + } else if (unit === 'm') { + value = parseInt(step) * 60 + } + item.value = value + break + } + } + }) + }, + globalVariablesReplace (expression) { + let str = expression + if (str) { + this.globalVariables.forEach(item => { + const reg = new RegExp('{{\\' + item.name + '}}', 'g') + if (item.value != null) { + str = str.replace(reg, item.value) + } + }) + } + return str + }, + rangeText (startTime, endTime) { + const range = this.$stringTimeParseToUnix(endTime) - this.$stringTimeParseToUnix(startTime) + let time = parseInt(range) + 's' + if (parseInt(range) > 60) { + const second = parseInt(range) % 60 + let min = parseInt(range / 60) + time = min + 'min' + second + 's' + + if (min > 60) { + min = parseInt(range / 60) % 60 + let hour = parseInt(parseInt(range / 60) / 60) + time = hour + 'h' + min + 'min' + + if (hour > 24) { + hour = parseInt(parseInt(range / 60) / 60) % 24 + const day = parseInt(parseInt(parseInt(range / 60) / 60) / 24) + time = day + 'd' + hour + 'h' + } + } + } + return time + } + } +} diff --git a/nezha-fronted/src/components/common/project/meta2d/meta2dTooltip.vue b/nezha-fronted/src/components/common/project/meta2d/meta2dTooltip.vue index d2b1f41d6..01ad42809 100644 --- a/nezha-fronted/src/components/common/project/meta2d/meta2dTooltip.vue +++ b/nezha-fronted/src/components/common/project/meta2d/meta2dTooltip.vue @@ -13,6 +13,7 @@ ref="panelChart" :chart-info="chartInfo" :show-header="false" + from="meta2dTooltip" /> diff --git a/nezha-fronted/src/components/common/rightBox/chart/chartRightBox.vue b/nezha-fronted/src/components/common/rightBox/chart/chartRightBox.vue index 3429fac45..bef9ccc93 100644 --- a/nezha-fronted/src/components/common/rightBox/chart/chartRightBox.vue +++ b/nezha-fronted/src/components/common/rightBox/chart/chartRightBox.vue @@ -503,7 +503,11 @@ export default { setTimeout(() => { const start = new Date().setHours(new Date().getHours() - 1) const end = new Date() - this.timeRange = [bus.computeTimezoneTime(start), bus.computeTimezoneTime(end)] + if (this.from === 'dashboard') { + this.timeRange = this.$store.getters.getTimeRange + } else { + this.timeRange = [bus.computeTimezoneTime(start), bus.computeTimezoneTime(end)] + } this.prevChart = { ...lodash.cloneDeep(this.editChart), loaded: true diff --git a/nezha-fronted/src/components/page/dashboard/dashboard.vue b/nezha-fronted/src/components/page/dashboard/dashboard.vue index 9d3a333e1..01358ede4 100644 --- a/nezha-fronted/src/components/page/dashboard/dashboard.vue +++ b/nezha-fronted/src/components/page/dashboard/dashboard.vue @@ -1268,6 +1268,10 @@ export default { document.removeEventListener('keydown', this.escExit) bus.$off('refreshPanel') this.$store.dispatch('dispatchPanelLock', { flag: true }) + this.$store.dispatch('dispatchPanelTime', { + time: [], + nowTimeType: {} + }) if (document.querySelector('#tableList')) { document.querySelector('#tableList').removeEventListener('mouseenter', this.tableListEnter) document.querySelector('#tableList').removeEventListener('mouseleave', this.tableListLeave)