From 53d57759f8530f3b993c69a94ef4964722027a68 Mon Sep 17 00:00:00 2001 From: zyh Date: Thu, 23 May 2024 16:36:29 +0800 Subject: [PATCH] =?UTF-8?q?NEZ-3478=20feat:=20dashboard=20=E5=9B=BE?= =?UTF-8?q?=E8=A1=A8=E5=A2=9E=E5=8A=A0=20legend=20=E5=85=A8=E9=80=89?= =?UTF-8?q?=EF=BC=8C=E5=8F=8D=E9=80=89=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nezha-fronted/src/assets/css/common.scss | 2 +- .../assets/css/components/chart/chart.scss | 58 ++- .../css/components/page/dashboard/panel.scss | 10 - .../src/components/chart/chart/legend.vue | 338 +++++++++--------- 4 files changed, 216 insertions(+), 192 deletions(-) diff --git a/nezha-fronted/src/assets/css/common.scss b/nezha-fronted/src/assets/css/common.scss index cbfd32554..d48ffa319 100644 --- a/nezha-fronted/src/assets/css/common.scss +++ b/nezha-fronted/src/assets/css/common.scss @@ -558,7 +558,7 @@ td .nz-icon-gear:before { pointer-events: none; } .yAxis-icon{ - margin-right: 4px; + margin-right: 5px; background: transparent !important; } diff --git a/nezha-fronted/src/assets/css/components/chart/chart.scss b/nezha-fronted/src/assets/css/components/chart/chart.scss index 2df857bb3..313d39d07 100644 --- a/nezha-fronted/src/assets/css/components/chart/chart.scss +++ b/nezha-fronted/src/assets/css/components/chart/chart.scss @@ -274,11 +274,6 @@ &.nz-chart__component--left { flex-direction: row-reverse; } - &.nz-chart__component--right, &.nz-chart__component--left { - .legend-container { - flex-direction: column; - } - } .legend-box{ width: 100%; display: flex; @@ -382,13 +377,20 @@ } } .legend-container { + flex: 1; display: flex; - overflow: auto; + flex-direction: column; + overflow: hidden; font-size: 12px; text-align: left; line-height: 18px; box-sizing: border-box; + .legend-list{ + display: flex; + overflow-y: auto; + } + .legend-item { box-sizing: border-box; padding: 0 8px; @@ -396,7 +398,7 @@ cursor: pointer; line-height: 20px; color: $--color-text-primary; - width: 100%; + max-width: 100%; display: flex; align-items: center; .legend-name{ @@ -404,9 +406,14 @@ text-overflow: ellipsis; } } + .legend--table-cell,.legend-item { + color: $--color-text-primary; + } .legend-item, .legend--table-row { &.legend-item--inactive, &.row--inactive { - color: $--color-text-secondary; + .legend--table-cell,.legend-item { + color: $--color-text-secondary !important; + } .legend-shape { background-color: $--background-color-1 !important; } @@ -425,7 +432,7 @@ vertical-align: middle; color: $--color-text-regular !important; } - .legend-item:hover { + .legend-item:not(.legendSelect):hover { background-color: $--background-color-1; cursor: pointer; .nz-icon-override{ @@ -433,6 +440,24 @@ } } + .legendSelect{ + width: 100%; + cursor: unset; + overflow: unset; + span{ + font-weight: bold; + cursor: pointer; + &:first-of-type{ + margin-right: 6px; + } + &.legendSelect-disabled{ + opacity: .6; + cursor: default; + color: $--color-text-secondary !important; + } + } + } + // 表格类型 .legend--table { width: 100%; @@ -461,11 +486,11 @@ position: sticky; top: 0; background-color: $--chart-background-color-base; - color:#33a2e5; - font-weight: bold; - font-size: 12px; .legend--table-cell:not(:first-of-type) { cursor: pointer; + color:#33a2e5; + font-size: 12px; + font-weight: bold; } .legend--table-cell{ white-space: nowrap; @@ -1183,6 +1208,9 @@ width: 100%; height: 2px; } + .legend-list{ + flex-wrap: wrap; + } } } .panel-chart--fullscreen{ @@ -1205,8 +1233,9 @@ width: 2px; height: 100%; } - .legend-container{ + .legend-list{ flex: 1; + flex-direction: column; } } } @@ -1222,8 +1251,9 @@ width: 2px; height: 100%; } - .legend-container{ + .legend-list{ flex: 1; + flex-direction: column; } } } diff --git a/nezha-fronted/src/assets/css/components/page/dashboard/panel.scss b/nezha-fronted/src/assets/css/components/page/dashboard/panel.scss index f29121684..1b0ca7d2d 100644 --- a/nezha-fronted/src/assets/css/components/page/dashboard/panel.scss +++ b/nezha-fronted/src/assets/css/components/page/dashboard/panel.scss @@ -94,16 +94,6 @@ height: calc(100% - 60px); flex: 1; background-color: $--background-color-empty; - .legend--table-cell,.legend-item { - color: $--color-text-primary; - } - .legend-container { - .legend--table-row.table-header { - .legend--table-cell { - color: #33a2e5; - } - } - } } .table-list-box { height: 100%; diff --git a/nezha-fronted/src/components/chart/chart/legend.vue b/nezha-fronted/src/components/chart/chart/legend.vue index f84712f81..bbb4d8d3e 100644 --- a/nezha-fronted/src/components/chart/chart/legend.vue +++ b/nezha-fronted/src/components/chart/chart/legend.vue @@ -6,7 +6,10 @@ @@ -144,6 +153,26 @@ export default { } }, methods: { + // 全选 + legendAll () { + if (this.isGrey.every(item => !item)) { + return + } + this.isGrey = this.isGrey.map(() => { + return false + }) + this.clickLegend(undefined, undefined, this.isGrey) + }, + // 反选 + legendInvert () { + if (this.isGrey.every(item => !item)) { + return + } + this.isGrey = this.isGrey.map((item) => { + return !item + }) + this.clickLegend(undefined, undefined, this.isGrey) + }, legendResize (e) { const placement = this.$lodash.get(this.chartInfo, 'param.legend.placement', 'bottom') if (placement === 'bottom') { @@ -152,6 +181,115 @@ export default { this.horizontalResize(e, placement) } }, + clickLegend (legendName, index, isGrey) { + /* 点击legend + * 1.当前如果是全高亮状态,则全部置灰,只留被点击的legend高亮 + * 2.如果点击的是唯一高亮的legend,则变为全高亮状态 + * 3.否则只改变被点击的legend状态 + * */ + let highlightNum = 0 // 高亮数量 + this.isGrey.forEach(g => { + if (!g) { + highlightNum++ + } + }) + const hasGrey = highlightNum < this.isGrey.length // 是否有置灰的 + const curIsGrey = this.isGrey[index] // 当前legend的状态 + const currentIsTheOnlyOneHighlight = !curIsGrey && highlightNum === 1 // 当前legend是否是目前唯一高亮的 + if (this.chartInfo.type === 'treemap') { + this.clickLegendTreemap(legendName, index, hasGrey, currentIsTheOnlyOneHighlight, isGrey) + return + } + if (this.chartInfo.type === 'pie' || this.chartInfo.type === 'doughnut' || this.chartInfo.type === 'rose') { + this.clickLegendD3(legendName, index, hasGrey, currentIsTheOnlyOneHighlight, isGrey) + return + } + if (this.isTimeSeries) { + this.clickcTimeSeries(legendName, index, hasGrey, currentIsTheOnlyOneHighlight, isGrey) + } + }, + clickcTimeSeries (legendName, index, hasGrey, currentIsTheOnlyOneHighlight, isGrey) { + const echarts = getChart(this.chartId) + if (echarts) { + if (isGrey) { + this.isGrey.forEach((item, index) => { + echarts.setSeries(index + 1, { show: !item, focus: false }) + }) + } else if (!hasGrey) { // 1.除当前legend外全置灰 + echarts.series.forEach((seriesItem, sindex) => { + if (sindex > 0) { + echarts.setSeries(sindex, { show: false, focus: false }) + } + }) + echarts.setSeries(index + 1, { show: true, focus: false }) + this.isGrey = this.isGrey.map((g, i) => i !== index) + } else if (currentIsTheOnlyOneHighlight) { // 2.全高亮 + echarts.series.forEach((seriesItem, sindex) => { + if (sindex > 0) { + echarts.setSeries(sindex, { show: true, focus: false }) + } + }) + this.isGrey = this.isGrey.map(() => false) + } else { + echarts.setSeries(index + 1, { show: this.isGrey[index], focus: false }) + this.$set(this.isGrey, index, !this.isGrey[index]) + } + this.$emit('legendChange', this.isGrey) + } + }, + clickLegendTreemap (legendName, index, hasGrey, currentIsTheOnlyOneHighlight, isGrey) { + const echarts = getChart(this.chartId) + if (echarts) { + let data = [] + data = lodash.cloneDeep(this.series) + if (isGrey) { + this.isGrey = isGrey + } else if (!hasGrey) { // 1.除当前legend外全置灰 + this.isGrey = this.isGrey.map((g, i) => i !== index) + } else if (currentIsTheOnlyOneHighlight) { // 2.全高亮 + this.isGrey = this.isGrey.map(() => false) + } else { // 对应高亮 + this.$set(this.isGrey, index, !this.isGrey[index]) + } + data[0].data = data[0].data.filter((item, i) => !this.isGrey[i]) + echarts.setOption({ + series: data + }) + } + }, + clickLegendD3 (legendName, index, hasGrey, currentIsTheOnlyOneHighlight, isGrey) { + if (isGrey) { + this.isGrey = isGrey + } else if (!hasGrey) { // 1.除当前legend外全置灰 + this.isGrey = this.isGrey.map((g, i) => i !== index) + } else if (currentIsTheOnlyOneHighlight) { // 2.全高亮 + this.isGrey = this.isGrey.map(() => false) + } else { // 对应高亮 + this.$set(this.isGrey, index, !this.isGrey[index]) + } + this.$emit('clickLegendD3', this.isGrey) + }, + hoverLegend (legendName, index, type) { + // legend 已经取消显示,鼠标悬浮,不开启 高亮效果 + if (this.isGrey[index]) { + return false + } + if (this.chartInfo.type === 'pie' || this.chartInfo.type === 'doughnut' || this.chartInfo.type === 'rose') { + this.$emit('hoverLegendD3', legendName, index, type) + } else if (this.isTimeSeries) { + const echarts = getChart(this.chartId) + if (type == 'highlight') { + echarts.setSeries(index + 1, { focus: true }) + } else { + echarts.setSeries(null, { focus: true }) + } + } else { + getChart(this.chartId) && getChart(this.chartId).dispatchAction({ + type: type, + name: legendName + }) + } + }, verticalResize (e) { const legendDom = this.$refs.legendDom // 得到点击时dom的初始高度 @@ -212,140 +350,6 @@ export default { document.onmousemove = null } }, - clickLegend (legendName, index) { - /* 点击legend - * 1.当前如果是全高亮状态,则全部置灰,只留被点击的legend高亮 - * 2.如果点击的是唯一高亮的legend,则变为全高亮状态 - * 3.否则只改变被点击的legend状态 - * */ - let highlightNum = 0 // 高亮数量 - this.isGrey.forEach(g => { - if (!g) { - highlightNum++ - } - }) - const hasGrey = highlightNum < this.isGrey.length // 是否有置灰的 - const curIsGrey = this.isGrey[index] // 当前legend的状态 - const currentIsTheOnlyOneHighlight = !curIsGrey && highlightNum === 1 // 当前legend是否是目前唯一高亮的 - const echarts = getChart(this.chartId) - if (this.chartInfo.type === 'bar') { - this.clickLegendBar(legendName, index, hasGrey, curIsGrey, currentIsTheOnlyOneHighlight) - return - } - if (this.chartInfo.type === 'treemap') { - this.clickLegendTreemap(legendName, index, hasGrey, curIsGrey, currentIsTheOnlyOneHighlight) - return - } - if (this.chartInfo.type === 'pie' || this.chartInfo.type === 'doughnut' || this.chartInfo.type === 'rose') { - this.clickLegendD3(legendName, index, hasGrey, curIsGrey, currentIsTheOnlyOneHighlight) - return - } - if (echarts) { - if (!hasGrey) { // 1.除当前legend外全置灰 - echarts.series.forEach((seriesItem, sindex) => { - if (sindex > 0) { - echarts.setSeries(sindex, { show: false, focus: false }) - } - }) - echarts.setSeries(index + 1, { show: true, focus: false }) - this.isGrey = this.isGrey.map((g, i) => i !== index) - } else if (currentIsTheOnlyOneHighlight) { // 2.全高亮 - echarts.series.forEach((seriesItem, sindex) => { - if (sindex > 0) { - echarts.setSeries(sindex, { show: true, focus: false }) - } - }) - this.isGrey = this.isGrey.map(() => false) - } else { - echarts.setSeries(index + 1, { show: this.isGrey[index], focus: false }) - this.$set(this.isGrey, index, !this.isGrey[index]) - } - this.$emit('legendChange', this.isGrey) - } - }, - clickLegendBar (legendName, index, hasGrey, curIsGrey, currentIsTheOnlyOneHighlight) { - const echarts = getChart(this.chartId) - if (echarts) { - let data = [] - const xAxis = { - data: [] - } - data = lodash.cloneDeep(this.series) - if (!hasGrey) { // 1.除当前legend外全置灰 - this.isGrey = this.isGrey.map((g, i) => i !== index) - } else if (currentIsTheOnlyOneHighlight) { // 2.全高亮 - this.isGrey = this.isGrey.map(() => false) - } else { // 对应高亮 - this.$set(this.isGrey, index, !this.isGrey[index]) - } - data[0].data = data[0].data.filter((item, i) => !this.isGrey[i]) - xAxis.data = data[0].data.map(item => { - if (this.chartInfo.param.text == 'all' || this.chartInfo.param.text == 'legend') { - return item.name - } else { - return '' - } - }) - echarts.setOption({ - series: data, - xAxis: { - data: xAxis.data - } - }) - } - }, - clickLegendTreemap (legendName, index, hasGrey, curIsGrey, currentIsTheOnlyOneHighlight) { - const echarts = getChart(this.chartId) - if (echarts) { - let data = [] - const xAxis = { - data: [] - } - data = lodash.cloneDeep(this.series) - if (!hasGrey) { // 1.除当前legend外全置灰 - this.isGrey = this.isGrey.map((g, i) => i !== index) - } else if (currentIsTheOnlyOneHighlight) { // 2.全高亮 - this.isGrey = this.isGrey.map(() => false) - } else { // 对应高亮 - this.$set(this.isGrey, index, !this.isGrey[index]) - } - data[0].data = data[0].data.filter((item, i) => !this.isGrey[i]) - echarts.setOption({ - series: data - }) - } - }, - clickLegendD3 (legendName, index, hasGrey, curIsGrey, currentIsTheOnlyOneHighlight) { - if (!hasGrey) { // 1.除当前legend外全置灰 - this.isGrey = this.isGrey.map((g, i) => i !== index) - } else if (currentIsTheOnlyOneHighlight) { // 2.全高亮 - this.isGrey = this.isGrey.map(() => false) - } else { // 对应高亮 - this.$set(this.isGrey, index, !this.isGrey[index]) - } - this.$emit('clickLegendD3', this.isGrey) - }, - hoverLegend (legendName, index, type) { - // legend 已经取消显示,鼠标悬浮,不开启 高亮效果 - if (this.isGrey[index]) { - return false - } - if (this.chartInfo.type === 'pie' || this.chartInfo.type === 'doughnut' || this.chartInfo.type === 'rose') { - this.$emit('hoverLegendD3', legendName, index, type) - } else if (this.isTimeSeries) { - const echarts = getChart(this.chartId) - if (type == 'highlight') { - echarts.setSeries(index + 1, { focus: true }) - } else { - echarts.setSeries(null, { focus: true }) - } - } else { - getChart(this.chartId) && getChart(this.chartId).dispatchAction({ - type: type, - name: legendName - }) - } - }, // 四舍五入保留2位小数(不够位数,则用0替补) keepTwoDecimalFull (num, type = 'left') { let chartUnit = this.chartInfo.unit