diff --git a/nezha-fronted/src/assets/css/components/chart/chart.scss b/nezha-fronted/src/assets/css/components/chart/chart.scss index ff02f21a2..e82b5aca5 100644 --- a/nezha-fronted/src/assets/css/components/chart/chart.scss +++ b/nezha-fronted/src/assets/css/components/chart/chart.scss @@ -653,6 +653,65 @@ justify-content: space-between; align-items: center; } + +.chart-dataLink-tooltip{ + position: fixed; + min-width: 150px; + max-width: 600px; + display: block; + white-space: nowrap; + will-change: transform; + transition: opacity 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s, visibility 0.2s cubic-bezier(0.23, 1, 0.32, 1) 0s, transform 0.4s cubic-bezier(0.23, 1, 0.32, 1) 0s; + border-radius: 4px; + font: 14 px/ 21px "Microsoft YaHei"; + padding-top: 10px; + z-index: 9999999999; + overflow: hidden; + background-color: $--tooltip-background-color !important; + border: 2px solid $--tooltip-border-color !important; + border-color: $--tooltip-border-color !important; + color: $--color-text-regular !important; + box-shadow: none !important; + .chart-dataLink-title{ + margin-bottom: 5px; + padding: 0 10px; + box-sizing: border-box; + max-width: 500px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + font-size: 14px; + color: $--color-text-primary !important; + font-weight: 600; + } + .chart-dataLink-content{ + padding: 0 10px; + box-sizing: border-box; + font-size: 12px; + display: flex; + justify-content: space-between; + align-items: center; + } + .chart-dataLink-list{ + margin-top: 10px; + border-top: 1px solid $--border-color-light; + .chart-dataLink-item{ + padding: 0 10px; + height: 32px; + line-height: 32px; + font-size: 14px; + cursor: pointer; + &:hover{ + background: $--background-color-base; + color: $--color-primary !important; + } + .nz-icon{ + margin-right: 2px; + } + } + } +} + .graph-icon-info-box{ position: absolute; top: 50%; diff --git a/nezha-fronted/src/components/chart/chart/chartBubble.vue b/nezha-fronted/src/components/chart/chart/chartBubble.vue index 764d45e83..89e3edc27 100644 --- a/nezha-fronted/src/components/chart/chart/chartBubble.vue +++ b/nezha-fronted/src/components/chart/chart/chartBubble.vue @@ -175,7 +175,7 @@ export default { }) .style('font-size', function (d) { let fontSize - fontSize = d.r / 4 > 10 ? d.r / 4 : 0 + fontSize = d.r / 3 > 10 ? d.r / 3 : 0 fontSize = fontSize > 30 ? 30 : fontSize return fontSize }) diff --git a/nezha-fronted/src/components/chart/chart/chartDoughnut.vue b/nezha-fronted/src/components/chart/chart/chartDoughnut.vue index 235369429..fa154c030 100644 --- a/nezha-fronted/src/components/chart/chart/chartDoughnut.vue +++ b/nezha-fronted/src/components/chart/chart/chartDoughnut.vue @@ -26,6 +26,10 @@
{{tooltip.value}}
+
+
percent
+
{{tooltip.percent}}%
+
@@ -87,6 +91,7 @@ export default { y: 0, title: 0, value: 0, + percent: 0, mapping: {}, show: false }, @@ -181,6 +186,12 @@ export default { .value(d => d.value) const arcs = pie(doughnutData) + // 计算百分比 + arcs.forEach(function (d) { + const percentage = (d.data.value / d3.sum(doughnutData, function (d) { return d.value })) * 100 + d.percent = percentage.toFixed(2) + }) + function doughnutOver (e, d) { chart.select('.path-' + d.index) .transition() @@ -297,6 +308,7 @@ export default { doughnutEnter (e, node) { // 移入气泡 this.tooltip.title = node.data.alias this.tooltip.value = node.data.showValue + this.tooltip.percent = node.percent this.tooltip.mapping = node.data.mapping this.tooltip.show = true this.setPosition(e) diff --git a/nezha-fronted/src/components/chart/chart/chartRose.vue b/nezha-fronted/src/components/chart/chart/chartRose.vue index a47f8f978..3da00da97 100644 --- a/nezha-fronted/src/components/chart/chart/chartRose.vue +++ b/nezha-fronted/src/components/chart/chart/chartRose.vue @@ -26,6 +26,10 @@
{{tooltip.value}}
+
+
percent
+
{{tooltip.percent}}%
+
@@ -87,6 +91,7 @@ export default { y: 0, title: 0, value: 0, + percent: 0, mapping: {}, show: false }, @@ -193,6 +198,12 @@ export default { const arcs = pie(roseData) + // 计算百分比 + arcs.forEach(function (d) { + const percentage = (d.data.value / d3.sum(roseData, function (d) { return d.value })) * 100 + d.percent = percentage.toFixed(2) + }) + function roseOver (e, d) { chart.select('.path-' + d.index) .transition() @@ -312,6 +323,7 @@ export default { roseEnter (e, node) { // 移入气泡 this.tooltip.title = node.data.alias this.tooltip.value = node.data.showValue + this.tooltip.percent = node.percent this.tooltip.mapping = node.data.mapping this.tooltip.show = true this.setPosition(e) diff --git a/nezha-fronted/src/components/chart/chart/chartTimeSeries.vue b/nezha-fronted/src/components/chart/chart/chartTimeSeries.vue index d19ebe1ba..3c015e7c5 100644 --- a/nezha-fronted/src/components/chart/chart/chartTimeSeries.vue +++ b/nezha-fronted/src/components/chart/chart/chartTimeSeries.vue @@ -537,6 +537,9 @@ export default { this.isStack = this.chartInfo.param.stack } catch (e) {} this.chartInfo.loaded && this.initChart(this.chartOption) + }, + beforeDestroy () { + getChart(this.chartId) && getChart(this.chartId).getZr().off('mousemove') } } diff --git a/nezha-fronted/src/components/chart/chartList.vue b/nezha-fronted/src/components/chart/chartList.vue index 7b2885fd3..5c4c33464 100644 --- a/nezha-fronted/src/components/chart/chartList.vue +++ b/nezha-fronted/src/components/chart/chartList.vue @@ -715,6 +715,7 @@ export default { bus.$off('creat-chart-success', this.createChartSuccess) bus.$off('groupChildMove', this.moveChart) window.removeEventListener('resize', this.resize) + document.onmousemove = null }, watch: { isShrink: { diff --git a/nezha-fronted/src/components/chart/chartMixin.js b/nezha-fronted/src/components/chart/chartMixin.js index 9d2fa3684..98b86e4cf 100644 --- a/nezha-fronted/src/components/chart/chartMixin.js +++ b/nezha-fronted/src/components/chart/chartMixin.js @@ -115,6 +115,7 @@ export default { } if (chartInfo.param.enable && chartInfo.param.enable.thresholds && !lodash.isEmpty(chartInfo.param.thresholds) && chartInfo.param.thresholds.length) { // 阈值 s.markLine = { + silent: true, symbol: 'circle', symbolSize: 5 } @@ -481,9 +482,6 @@ export default { this.chartId = `${this.chartInfo.id}${this.isFullscreen ? '-fullscreen' : ''}` }, beforeDestroy () { - try { - getChart(this.chartId) && getChart(this.chartId).getZr().off('mousemove') - } catch (error) {} getChart(this.chartId) && setChart(this.chartId, null) } } diff --git a/nezha-fronted/src/components/common/bottomBox/tabs/dashboardTab.vue b/nezha-fronted/src/components/common/bottomBox/tabs/dashboardTab.vue index f5cb81d9f..cac8c6987 100644 --- a/nezha-fronted/src/components/common/bottomBox/tabs/dashboardTab.vue +++ b/nezha-fronted/src/components/common/bottomBox/tabs/dashboardTab.vue @@ -240,7 +240,8 @@ export default { label: '', min: undefined, max: undefined - } + }, + dataLink: [] }, elements: [{ expression: '', legend: '', type: 'expert', id: '', name: 'A', state: 1, orderNum: 0 }], panel: '', @@ -274,12 +275,7 @@ export default { type: this.from, id: null }, - blankChartTemp: { - varType: 1, - pid: '', - dashboardId: null, - varIds: [] - }, + // removeModal: false, // 删除弹出 // deleteObj: {}, // 删除对象 // ---图表相关参数--end @@ -368,17 +364,7 @@ export default { this.$refs.addChartModal.isStable = 'stable' }) }, - addChartByTemp () { - this.chart = JSON.parse(JSON.stringify(this.blankChartTemp)) - this.chart.dashboardId = this.showPanel.id - if (this.from === fromRoute.endpoint) { - this.chart.varType = 2 - } - if (this.from === fromRoute.asset || this.from === fromRoute.endpoint) { - this.chart.varIds.push(this.obj.id) - } - this.rightBox.chartTemp.show = true - }, + newChart () { return JSON.parse(JSON.stringify(this.blankChart)) }, @@ -435,6 +421,23 @@ export default { if (!this.chart.groupId || this.chart.groupId == -1) { this.chart.groupId = '' } + if ((this.chart.type === 'line' || this.chart.type === 'area' || this.chart.type === 'point') && !this.chart.param.rightYAxis) { + this.chart.param.rightYAxis = { + elementNames: [], + style: 'line', + unit: 2, + label: '', + min: undefined, + max: undefined + } + } + if (this.chart.type === 'stat') { + if (!this.chart.param.sparklineMode) { this.chart.param.sparklineMode = 'none' } + if (!this.chart.param.comparison) { this.chart.param.comparison = 'none' } + } + if (!this.chart.param.dataLink) { + this.chart.param.dataLink = [] + } } else { this.rightBox.loading = true this.$get('visual/dashboard/chart/' + data.id).then(res => { @@ -449,7 +452,10 @@ export default { } else { this.chart.param = {} } - if (!this.chart.param.rightYAxis) { + if (!this.chart.groupId || this.chart.groupId == -1) { + this.chart.groupId = '' + } + if ((this.chart.type === 'line' || this.chart.type === 'area' || this.chart.type === 'point') && !this.chart.param.rightYAxis) { this.chart.param.rightYAxis = { elementNames: [], style: 'line', @@ -459,13 +465,13 @@ export default { max: undefined } } - if (!this.chart.groupId || this.chart.groupId == -1) { - this.chart.groupId = '' - } if (this.chart.type === 'stat') { if (!this.chart.param.sparklineMode) { this.chart.param.sparklineMode = 'none' } if (!this.chart.param.comparison) { this.chart.param.comparison = 'none' } } + if (!this.chart.param.dataLink) { + this.chart.param.dataLink = [] + } if (this.chart.type == 'table') { const arr = this.chart.param.indexs ? this.chart.param.indexs.split(',') : [] this.chart.param.tags = arr.map((item) => { diff --git a/nezha-fronted/src/components/common/rightBox/chart/chartConfig.vue b/nezha-fronted/src/components/common/rightBox/chart/chartConfig.vue index 8a996c765..b46a5f743 100644 --- a/nezha-fronted/src/components/common/rightBox/chart/chartConfig.vue +++ b/nezha-fronted/src/components/common/rightBox/chart/chartConfig.vue @@ -1092,6 +1092,91 @@ + +
+ {{$t('dashboard.dashboard.chartForm.dataLink')}} +
+ +
+
+ + + + + {{item.title}} + + + + + + + + + + + + + + + + + +
+ + +
+
{{$t("dashboard.dashboard.chartForm.title")}}
+
+ + + + +
+
{{$t('dashboard.dashboard.chartForm.openIn')}}
+
+ + + + + + + +
+ +
+
{{$t('dashboard.dashboard.chartForm.dataLinkUrl')}}
+
+ + + + +
+
+
+
+
+ {{$t('overall.addDataLink')}} +
+ @@ -1224,7 +1309,8 @@ export default { label: '', min: undefined, max: undefined - } + }, + dataLink: this.chartConfig.param.dataLink } this.$nextTick(() => { this.chartConfig.param.thresholds.push({ value: undefined, color: randomcolor() }) @@ -1266,7 +1352,8 @@ export default { result: 'show' }, sparklineMode: 'line', - comparison: 'none' + comparison: 'none', + dataLink: this.chartConfig.param.dataLink } break case 'bar': @@ -1298,7 +1385,8 @@ export default { operator: 'equal', varValue: '', result: 'show' - } + }, + dataLink: this.chartConfig.param.dataLink } break case 'table': @@ -1325,7 +1413,8 @@ export default { operator: 'equal', varValue: '', result: 'show' - } + }, + dataLink: this.chartConfig.param.dataLink } break case 'log': @@ -1347,7 +1436,8 @@ export default { operator: 'equal', varValue: '', result: 'show' - } + }, + dataLink: this.chartConfig.param.dataLink } break } diff --git a/nezha-fronted/src/components/common/rightBox/chart/chartRightBox.vue b/nezha-fronted/src/components/common/rightBox/chart/chartRightBox.vue index bef9ccc93..a1068e047 100644 --- a/nezha-fronted/src/components/common/rightBox/chart/chartRightBox.vue +++ b/nezha-fronted/src/components/common/rightBox/chart/chartRightBox.vue @@ -233,8 +233,14 @@ export default { delete item.uid }) } + if (params.param.dataLink) { + params.param.dataLink.forEach(item => { + delete item.error + }) + } if (params.type === 'group') { params.height = 1 + delete params.param.dataLink } if (!params.groupId) { params.groupId = 0 @@ -389,7 +395,8 @@ export default { operator: 'equal', varValue: '', result: 'show' - } + }, + dataLink: this.editChart.param.dataLink } } } @@ -415,7 +422,8 @@ export default { operator: 'equal', varValue: '', result: 'show' - } + }, + dataLink: this.editChart.param.dataLink } } } @@ -456,7 +464,8 @@ export default { operator: 'equal', varValue: '', result: 'show' - } + }, + dataLink: this.editChart.param.dataLink } } delete this.editChart.elements @@ -481,7 +490,8 @@ export default { operator: 'equal', varValue: '', result: 'show' - } + }, + dataLink: this.editChart.param.dataLink } } delete this.editChart.elements diff --git a/nezha-fronted/src/components/common/rightBox/chart/otherChartConfig.vue b/nezha-fronted/src/components/common/rightBox/chart/otherChartConfig.vue index 693956b8e..7f152afda 100644 --- a/nezha-fronted/src/components/common/rightBox/chart/otherChartConfig.vue +++ b/nezha-fronted/src/components/common/rightBox/chart/otherChartConfig.vue @@ -289,6 +289,93 @@ + + + @@ -298,12 +385,14 @@ import publicConfig from '@/components/common/rightBox/chart/publicConfig' import chartTypeShow from '@/components/common/rightBox/chart/chartTypeShow' import diagram from '@/components/common/ChartDiagram/diagram' import richTextEditor from '@/components/chart/richTextEditor' +import draggable from 'vuedraggable' export default { name: 'otherChartConfig', mixins: [publicConfig, chartTypeShow], components: { diagram, - richTextEditor + richTextEditor, + draggable }, watch: { // 'chartConfig.param.text': { @@ -373,7 +462,8 @@ export default { }, repeat: { variable: '' - } + }, + dataLink: this.chartConfig.param.dataLink } break case 'text': @@ -389,7 +479,8 @@ export default { operator: 'equal', varValue: '', result: 'show' - } + }, + dataLink: this.chartConfig.param.dataLink } break case 'diagram': @@ -405,7 +496,8 @@ export default { operator: 'equal', varValue: '', result: 'show' - } + }, + dataLink: this.chartConfig.param.dataLink } break case 'url': @@ -421,7 +513,8 @@ export default { operator: 'equal', varValue: '', result: 'show' - } + }, + dataLink: this.chartConfig.param.dataLink } break case 'clock': @@ -437,7 +530,8 @@ export default { operator: 'equal', varValue: '', result: 'show' - } + }, + dataLink: this.chartConfig.param.dataLink } break } @@ -455,6 +549,13 @@ export default { this.chartConfig.param.text = html this.$refs.chartForm.validateField('param.text') this.change() + }, + start () { + document.body.classList.add('isDrag') + }, + onEnd () { + this.change() + document.body.classList.remove('isDrag') } }, created () { diff --git a/nezha-fronted/src/components/common/rightBox/chart/publicConfig.js b/nezha-fronted/src/components/common/rightBox/chart/publicConfig.js index 70c00e494..7d0420c97 100644 --- a/nezha-fronted/src/components/common/rightBox/chart/publicConfig.js +++ b/nezha-fronted/src/components/common/rightBox/chart/publicConfig.js @@ -685,6 +685,11 @@ export default { this.$emit('change', this.chartConfig) }) }, + tagsChange (newTags) { + this.chartConfig.param.tags = newTags + this.chartConfig.param.indexs = newTags.map(item => item.text).join(',') + this.change() + }, addColumns () { this.chartConfig.param.columns.push({ title: '', @@ -706,9 +711,25 @@ export default { this.chartConfig.param.columns[index].show = !this.chartConfig.param.columns[index].show this.change() }, - tagsChange (newTags) { - this.chartConfig.param.tags = newTags - this.chartConfig.param.indexs = newTags.map(item => item.text).join(',') + addDataLink () { + this.chartConfig.param.dataLink.push({ + show: true, + title: '', + url: '', + openIn: 'newTab' + }) + this.change() + }, + copyDataLink (index) { + this.chartConfig.param.dataLink.push({ ...this.chartConfig.param.dataLink[index] }) + this.change() + }, + removeDataLink (index) { + this.chartConfig.param.dataLink.splice(index, 1) + this.change() + }, + showDataLink (index) { + this.chartConfig.param.dataLink[index].show = !this.chartConfig.param.dataLink[index].show this.change() }, enableChange (type) { diff --git a/nezha-fronted/src/components/common/rightBox/chart/systemChartConfig.vue b/nezha-fronted/src/components/common/rightBox/chart/systemChartConfig.vue index 92019ed3f..bda8bf650 100644 --- a/nezha-fronted/src/components/common/rightBox/chart/systemChartConfig.vue +++ b/nezha-fronted/src/components/common/rightBox/chart/systemChartConfig.vue @@ -440,7 +440,7 @@ + {{$t('dashboard.dashboard.chartForm.dataLink')}} + + +
+
+ + + + + {{item.title}} + + + + + + + + + + + + + + + + + +
+ + +
+
{{$t("dashboard.dashboard.chartForm.title")}}
+
+ + + + +
+
{{$t('dashboard.dashboard.chartForm.openIn')}}
+
+ + + + + + + +
+ +
+
{{$t('dashboard.dashboard.chartForm.dataLinkUrl')}}
+
+ + + + +
+
+
+
+
+ {{$t('overall.addDataLink')}} +
+ @@ -1005,7 +1090,8 @@ export default { operator: 'equal', varValue: '', result: 'show' - } + }, + dataLink: this.chartConfig.param.dataLink } break case 'bar': @@ -1038,7 +1124,8 @@ export default { operator: 'equal', varValue: '', result: 'show' - } + }, + dataLink: this.chartConfig.param.dataLink } break case 'table': @@ -1065,7 +1152,8 @@ export default { operator: 'equal', varValue: '', result: 'show' - } + }, + dataLink: this.chartConfig.param.dataLink } break } @@ -1127,7 +1215,7 @@ export default { start () { document.body.classList.add('isDrag') }, - end () { + onEnd () { this.change() document.body.classList.remove('isDrag') } diff --git a/nezha-fronted/src/components/page/dashboard/dashboard.vue b/nezha-fronted/src/components/page/dashboard/dashboard.vue index 01358ede4..7832b03dd 100644 --- a/nezha-fronted/src/components/page/dashboard/dashboard.vue +++ b/nezha-fronted/src/components/page/dashboard/dashboard.vue @@ -261,7 +261,8 @@ export default { label: '', min: undefined, max: undefined - } + }, + dataLink: [] }, elements: [{ expression: '', legend: '', type: 'expert', id: '', name: 'A', state: 1, orderNum: 0 }], panel: '', @@ -275,12 +276,6 @@ export default { pageSize: -1, // 此处获取所有数据 total: 0 }, - blankChartTemp: { - varType: 1, - pid: '', - dashboardId: '', - varIds: [] - }, panelData: [], panelDataDragTmp: [], searchMsg: { // 给搜索框子组件传递的信息 @@ -566,11 +561,6 @@ export default { this.$refs.addChartModal.isStable = 'stable' }) }, - addChartByTemp () { - this.chart = JSON.parse(JSON.stringify(this.blankChartTemp)) - this.chart.dashboardId = this.showPanel.id - this.rightBox.chartTemp.show = true - }, addGroupItem (groupId) { this.chart = this.newChart() this.chart.groupId = groupId @@ -604,6 +594,23 @@ export default { if (!this.chart.groupId || this.chart.groupId == -1) { this.chart.groupId = '' } + if ((this.chart.type === 'line' || this.chart.type === 'area' || this.chart.type === 'point') && !this.chart.param.rightYAxis) { + this.chart.param.rightYAxis = { + elementNames: [], + style: 'line', + unit: 2, + label: '', + min: undefined, + max: undefined + } + } + if (this.chart.type === 'stat') { + if (!this.chart.param.sparklineMode) { this.chart.param.sparklineMode = 'none' } + if (!this.chart.param.comparison) { this.chart.param.comparison = 'none' } + } + if (!this.chart.param.dataLink) { + this.chart.param.dataLink = [] + } } else { this.rightBox.loading = true this.$get('visual/dashboard/chart/' + data.id).then(res => { @@ -618,7 +625,10 @@ export default { } else { this.chart.param = {} } - if (!this.chart.param.rightYAxis) { + if (!this.chart.groupId || this.chart.groupId == -1) { + this.chart.groupId = '' + } + if ((this.chart.type === 'line' || this.chart.type === 'area' || this.chart.type === 'point') && !this.chart.param.rightYAxis) { this.chart.param.rightYAxis = { elementNames: [], style: 'line', @@ -628,13 +638,13 @@ export default { max: undefined } } - if (!this.chart.groupId || this.chart.groupId == -1) { - this.chart.groupId = '' - } if (this.chart.type === 'stat') { if (!this.chart.param.sparklineMode) { this.chart.param.sparklineMode = 'none' } if (!this.chart.param.comparison) { this.chart.param.comparison = 'none' } } + if (!this.chart.param.dataLink) { + this.chart.param.dataLink = [] + } if (this.chart.type == 'table') { const arr = this.chart.param.indexs ? this.chart.param.indexs.split(',') : [] this.chart.param.tags = arr.map((item) => {