diff --git a/nezha-fronted/package-lock.json b/nezha-fronted/package-lock.json index 7e16b4037..08a55bd17 100644 --- a/nezha-fronted/package-lock.json +++ b/nezha-fronted/package-lock.json @@ -10354,6 +10354,14 @@ "d3-zoom": "2" }, "dependencies": { + "d3-interpolate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "requires": { + "d3-color": "1 - 2" + } + }, "d3-zoom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-2.0.0.tgz", @@ -10391,6 +10399,16 @@ "d3-interpolate": "1 - 2", "d3-selection": "2", "d3-transition": "2" + }, + "dependencies": { + "d3-interpolate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "requires": { + "d3-color": "1 - 2" + } + } } }, "d3-chord": { @@ -10498,11 +10516,11 @@ "integrity": "sha512-SwIdqM3HxQX2214EG9GTjgmCc/mbSx4mQBn+DuEETubhOw6/U3fmnji4uCVrmzOydMHSO1nZle5gh6HB/wdOzw==" }, "d3-interpolate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", - "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", "requires": { - "d3-color": "1 - 2" + "d3-color": "1 - 3" } }, "d3-path": { @@ -10559,6 +10577,16 @@ "d3-interpolate": "1.2.0 - 2", "d3-time": "^2.1.1", "d3-time-format": "2 - 3" + }, + "dependencies": { + "d3-interpolate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "requires": { + "d3-color": "1 - 2" + } + } } }, "d3-scale-chromatic": { @@ -10568,6 +10596,16 @@ "requires": { "d3-color": "1 - 2", "d3-interpolate": "1 - 2" + }, + "dependencies": { + "d3-interpolate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "requires": { + "d3-color": "1 - 2" + } + } } }, "d3-selection": { @@ -10614,6 +10652,16 @@ "d3-ease": "1 - 2", "d3-interpolate": "1 - 2", "d3-timer": "1 - 2" + }, + "dependencies": { + "d3-interpolate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "requires": { + "d3-color": "1 - 2" + } + } } }, "d3-voronoi": { @@ -17732,7 +17780,7 @@ }, "node-sass": { "version": "4.14.1", - "resolved": "https://registry.npmmirror.com/node-sass/-/node-sass-4.14.1.tgz", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz", "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==", "dev": true, "requires": { @@ -24364,7 +24412,7 @@ }, "webpack-bundle-analyzer": { "version": "2.13.1", - "resolved": "https://registry.npmmirror.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.13.1.tgz", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.13.1.tgz", "integrity": "sha512-rwxyfecTAxoarCC9VlHlIpfQCmmJ/qWD5bpbjkof+7HrNhTNZIwZITxN6CdlYL2axGmwNUQ+tFgcSOiNXMf/sQ==", "dev": true, "requires": { diff --git a/nezha-fronted/package.json b/nezha-fronted/package.json index 75c0ed203..aeaf9d6f1 100644 --- a/nezha-fronted/package.json +++ b/nezha-fronted/package.json @@ -64,6 +64,7 @@ "cytoscape": "^3.15.2", "d3": "^6.7.0", "d3-hexbin": "^0.2.2", + "d3-interpolate": "^3.0.1", "d3-sankey": "^0.12.3", "d3-zoom": "^3.0.0", "echarts": "^5.2.2", diff --git a/nezha-fronted/src/assets/css/components/chart/chart.scss b/nezha-fronted/src/assets/css/components/chart/chart.scss index acac4906f..fc91211e8 100644 --- a/nezha-fronted/src/assets/css/components/chart/chart.scss +++ b/nezha-fronted/src/assets/css/components/chart/chart.scss @@ -401,7 +401,7 @@ cursor: pointer; display: inline-block; line-height: 20px; - color: $--color-text-regular; + color: $--color-text-primary; } .legend-item, .legend--table-row { &.legend-item--inactive, &.row--inactive { diff --git a/nezha-fronted/src/assets/css/components/common/rightBox/chartRightBox/chartRightBox.scss b/nezha-fronted/src/assets/css/components/common/rightBox/chartRightBox/chartRightBox.scss index 9ad3da3f4..780c282a5 100644 --- a/nezha-fronted/src/assets/css/components/common/rightBox/chartRightBox/chartRightBox.scss +++ b/nezha-fronted/src/assets/css/components/common/rightBox/chartRightBox/chartRightBox.scss @@ -390,3 +390,43 @@ overflow: unset; } } + +.colorScheme-form-item { + .el-form-item__content{ + display: flex; + align-items: center; + } +} + +.colorScheme-pop { + .el-select-dropdown__item{ + height: 50px; + padding: 8px 12px; + } + .colorScheme-item{ + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; + .colorScheme-name{ + font-size: 14px; + color: $--color-text-primary; + line-height: 100%; + font-weight: bold; + } + .colorScheme-msg{ + font-size: 12px; + color: $--color-text-secondary; + line-height: 100%; + font-weight: normal !important; + } + .colorScheme-line{ + width: 100%; + height: 8px; + margin: 2px 0; + border-radius: 3px; + display: flex; + justify-content: space-between; + } + } +} \ No newline at end of file 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 4b4a92b5b..6a4336395 100644 --- a/nezha-fronted/src/assets/css/components/page/dashboard/panel.scss +++ b/nezha-fronted/src/assets/css/components/page/dashboard/panel.scss @@ -95,7 +95,7 @@ flex: 1; background-color: $--background-color-empty; .legend--table-cell,.legend-item { - color: $--color-text-regular; + color: $--color-text-primary; } .legend-container { .legend--table-row.table-header { diff --git a/nezha-fronted/src/components/chart/chart/chartBar.vue b/nezha-fronted/src/components/chart/chart/chartBar.vue index 32965a067..3162fbea8 100644 --- a/nezha-fronted/src/components/chart/chart/chartBar.vue +++ b/nezha-fronted/src/components/chart/chart/chartBar.vue @@ -76,7 +76,7 @@ }" > - {{item.mapping ? handleDisplay(item.mapping.display, { ...item.label, value: item.showValue }) : item.showValue}} + {{item.mapping ? handleDisplay(item.mapping.display, { ...item.labels, value: item.showValue }) : item.showValue}}

@@ -140,7 +140,7 @@ }" > - {{item.mapping ? handleDisplay(item.mapping.display, { ...item.label, value: item.showValue }) : item.showValue}} + {{item.mapping ? handleDisplay(item.mapping.display, { ...item.labels, value: item.showValue }) : item.showValue}}

@@ -195,7 +195,7 @@ }" > - {{item.mapping ? handleDisplay(item.mapping.display, { ...item.label, value: item.showValue }) : item.showValue}} + {{item.mapping ? handleDisplay(item.mapping.display, { ...item.labels, value: item.showValue }) : item.showValue}}

@@ -224,7 +224,7 @@ }" > - {{item.mapping ? handleDisplay(item.mapping.display, { ...item.label, value: item.showValue }) : item.showValue}} + {{item.mapping ? handleDisplay(item.mapping.display, { ...item.labels, value: item.showValue }) : item.showValue}}

{ - return Math.max(maxValue, obj.value) - }, 0) - - if (maxNum <= 1) { - return 1 - } - - let bite = 1 - while (maxNum >= 10) { - maxNum /= 10 - if (maxNum > 1) { - bite += 1 - } - } - - return Math.pow(10, bite) - }, initBarData (chartInfo, originalDatas) { this.barData = [] let colorIndex = 0 @@ -602,7 +578,7 @@ export default { mapping && this.chartOption.color && (this.chartOption.color[colorIndex] = mapping.color.bac) const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex) this.barData.push({ - value: Number(value), + value: parseFloat(value), realValue: value, showValue: showValue, name: legend.name, @@ -614,11 +590,15 @@ export default { expressionIndex: expressionIndex, dataIndex: dataIndex, mapping: mapping, - background: mapping ? mapping.color.bac : this.colorList[colorIndex] + background: '' }) colorIndex++ }) }) + this.setColorList(this.barData) + this.barData.forEach((item, index) => { + item.background = item.mapping ? item.mapping.color.bac : this.colorList[index] + }) this.$emit('chartIsNoData', this.isNoData) }, formatterFunc (params, ticket, callback) { @@ -718,9 +698,6 @@ export default { } }, mounted () { - // eslint-disable-next-line vue/no-mutating-props - this.chartOption.color || (this.chartOption.color = initColor(20)) - this.colorList = this.chartOption.color this.chartInfo.loaded && this.initChart(this.chartOption) } } diff --git a/nezha-fronted/src/components/chart/chart/chartBubble.vue b/nezha-fronted/src/components/chart/chart/chartBubble.vue index b10227f36..7638713e4 100644 --- a/nezha-fronted/src/components/chart/chart/chartBubble.vue +++ b/nezha-fronted/src/components/chart/chart/chartBubble.vue @@ -58,9 +58,7 @@ import chartFormat from '@/components/chart/chartFormat' import * as d3 from 'd3' import { getMetricTypeValue } from '@/components/common/js/tools' import chartDataFormat from '@/components/chart/chartDataFormat' -import { initColor } from '@/components/chart/chart/tools' import lodash from 'lodash' - export default { name: 'chart-bubble', components: { @@ -122,11 +120,15 @@ export default { expressionIndex: expressionIndex, dataIndex: dataIndex, mapping: mapping, - background: mapping ? mapping.color.bac : this.colorList[colorIndex] // 气泡颜色 + background: '' }) colorIndex++ }) }) + this.setColorList(this.bubbleData) + this.bubbleData.forEach((item, index) => { + item.background = item.mapping ? item.mapping.color.bac : this.colorList[index] + }) this.$emit('chartIsNoData', this.isNoData) }, drawBubbleChart () { @@ -356,7 +358,6 @@ export default { } }, mounted () { - this.colorList = initColor(20) this.chartInfo.loaded && this.initChart() }, beforeDestroy () { diff --git a/nezha-fronted/src/components/chart/chart/chartDoughnut.vue b/nezha-fronted/src/components/chart/chart/chartDoughnut.vue index 93ab038e1..d66b562a5 100644 --- a/nezha-fronted/src/components/chart/chart/chartDoughnut.vue +++ b/nezha-fronted/src/components/chart/chart/chartDoughnut.vue @@ -153,7 +153,7 @@ export default { const mapping = this.selectMapping(value, chartInfo.param.valueMapping, chartInfo.param.enable && this.chartInfo.param.enable.valueMapping) const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex) this.doughnutData.push({ - value: Number(value), + value: parseFloat(value), realValue: value, showValue: showValue, name: legend.name, @@ -165,12 +165,17 @@ export default { expressionIndex: expressionIndex, dataIndex: dataIndex, mapping: mapping, - background: mapping ? mapping.color.bac : this.colorList[colorIndex] + background: '' }) colorIndex++ }) }) + this.setColorList(this.doughnutData) + this.doughnutData.forEach((item, index) => { + item.background = item.mapping ? item.mapping.color.bac : this.colorList[index] + this.legends[index].color = item.mapping ? item.mapping.color.bac : this.colorList[index] + }) this.$emit('chartIsNoData', this.isNoData) }, drawDoughnutChart (animate) { @@ -465,7 +470,6 @@ export default { } }, mounted () { - this.colorList = initColor(20) this.chartInfo.loaded && this.initChart(true) }, beforeDestroy () { diff --git a/nezha-fronted/src/components/chart/chart/chartFunnel.vue b/nezha-fronted/src/components/chart/chart/chartFunnel.vue index c5e939210..85c2428d2 100644 --- a/nezha-fronted/src/components/chart/chart/chartFunnel.vue +++ b/nezha-fronted/src/components/chart/chart/chartFunnel.vue @@ -60,7 +60,7 @@ import { getMetricTypeValue } from '@/components/common/js/tools' import chartDataFormat from '@/components/chart/chartDataFormat' import { initColor } from '@/components/chart/chart/tools' import lodash from 'lodash' - +import tinycolor from 'tinycolor2' export default { name: 'chart-funnel', components: { @@ -109,7 +109,7 @@ export default { const mapping = this.selectMapping(value, chartInfo.param.valueMapping, chartInfo.param.enable && this.chartInfo.param.enable.valueMapping) const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex) this.funnelData.push({ - value: Number(value), + value: parseFloat(value), realValue: value, showValue: showValue, name: legend.name, @@ -121,12 +121,15 @@ export default { expressionIndex: expressionIndex, dataIndex: dataIndex, mapping: mapping, - background: mapping ? mapping.color.bac.substr(0, 7) : this.colorList[colorIndex], // 仅限十六进制 - label: legend.alias + background: '' }) colorIndex++ }) }) + this.setColorList(this.funnelData) + this.funnelData.forEach((item, index) => { + item.background = item.mapping ? item.mapping.color.bac.substr(0, 7) : tinycolor(this.colorList[index]).toHexString() // 仅限十六进制 + }) this.funnelData.sort((a, b) => b.value - a.value) this.$emit('chartIsNoData', this.isNoData) }, @@ -349,24 +352,6 @@ export default { } }) }, - /** - * Convert a hex color to an RGB object. - * - * @param {string} color - * - * @returns {{R: Number, G: number, B: number}} - */ - hexToRgb (color) { - let hex = color.slice(1) - if (hex.length === 3) { - hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] - } - const f = parseInt(hex, 16) - const R = f >> 16 - const G = (f >> 8) & 0x00FF - const B = f & 0x0000FF - return { R, G, B } - }, /** * Shade a color to the given percentage. * @@ -376,14 +361,14 @@ export default { * @return {string} */ shade (color, shade) { - const { R, G, B } = this.hexToRgb(color) + const { r, g, b } = tinycolor(color).toRgb() const t = shade < 0 ? 0 : 255 const p = shade < 0 ? shade * -1 : shade const converted = 0x1000000 + - ((Math.round((t - R) * p) + R) * 0x10000) + - ((Math.round((t - G) * p) + G) * 0x100) + - (Math.round((t - B) * p) + B) + ((Math.round((t - r) * p) + r) * 0x10000) + + ((Math.round((t - g) * p) + g) * 0x100) + + (Math.round((t - b) * p) + b) return `#${converted.toString(16).slice(1)}` }, diff --git a/nezha-fronted/src/components/chart/chart/chartGauge.vue b/nezha-fronted/src/components/chart/chart/chartGauge.vue index efcd68b10..f3c23d771 100644 --- a/nezha-fronted/src/components/chart/chart/chartGauge.vue +++ b/nezha-fronted/src/components/chart/chart/chartGauge.vue @@ -100,7 +100,7 @@ export default { const gauge = { value: '', showValue: '', - label: {}, + labels: {}, width: '', height: '', legend: '', @@ -109,9 +109,9 @@ export default { } const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex) gauge.value = getMetricTypeValue(data.values, chartInfo.param.statistics || 'last') - gauge.label = data.metric + gauge.labels = data.metric gauge.legend = legend.alias - gauge.label.legend = gauge.legend + gauge.labels.legend = gauge.legend gauge.expressionIndex = expressionIndex gauge.name = legend.name gauge.alias = legend.alias @@ -123,29 +123,11 @@ export default { }) }) this.maxValue = this.calcMax(this.gaugeData) + this.setColorList(this.gaugeData) this.$emit('chartIsNoData', this.isNoData) resolve() }) }, - calcMax (arr) { - let maxNum = arr.reduce((maxValue, obj) => { - return Math.max(maxValue, obj.value) - }, 0) - - if (maxNum <= 1) { - return 1 - } - - let bite = 1 - while (maxNum >= 10) { - maxNum /= 10 - if (maxNum > 1) { - bite += 1 - } - } - - return Math.pow(10, bite) - }, calculateGridDimensions (parentWidth, parentHeight, numberOfChildren) { const vertical = this.calculateSizeOfChild(parentWidth, parentHeight, numberOfChildren) const horizontal = this.calculateSizeOfChild(parentHeight, parentWidth, numberOfChildren) @@ -224,7 +206,7 @@ export default { const gaugeWidth = Math.min(dimension / 5.5, 30) let showValue = data.showValue if (data.mapping) { - showValue = this.handleDisplay(data.mapping.display, { ...data.label, value: showValue }) + showValue = this.handleDisplay(data.mapping.display, { ...data.labels, value: showValue }) } const textWidth = dimension - (gaugeWidth * 4) const valueFontSize = this.calculateFontSize(showValue, textWidth, textWidth / 2, 1, gaugeWidth * 2) @@ -264,7 +246,7 @@ export default { if (this.chartInfo.param.text === 'all' || this.chartInfo.param.text === 'value' || !this.chartInfo.param.text) { let showValue = chartDataFormat.getUnit(self.chartInfo.unit ? self.chartInfo.unit : 2).compute(params, null, -1, 2).trim() if (item.mapping) { - showValue = self.handleDisplay(item.mapping.display, { ...item.label, value: showValue }) + showValue = self.handleDisplay(item.mapping.display, { ...item.labels, value: showValue }) } str += showValue } @@ -276,14 +258,8 @@ export default { }, color: lodash.get(item, 'mapping.color.text', 'auto') } - if (index < 20) { - option.series[0].itemStyle = { - color: lodash.get(item, 'mapping.color.bac', this.colorList[index]) - } - } else { - option.series[0].itemStyle = { - color: lodash.get(item, 'mapping.color.bac', randomcolor()) - } + option.series[0].itemStyle = { + color: lodash.get(item, 'mapping.color.bac', this.colorList[index]) } option.tooltip.formatter = this.formatterFunc option.tooltip.position = this.tooltipPosition @@ -371,7 +347,7 @@ export default { this.toolbox.value = params.data.mapping && params.data.mapping.display ? this.handleDisplay(params.data.mapping.display, { ...params.data.labels, value: params.data.showValue }) : params.data.showValue this.toolbox.mapping = params.data.mapping this.toolbox.show = true - this.toolbox.metric.labels = params.data.label + this.toolbox.metric.labels = params.data.labels this.toolbox.metric.expressionIndex = params.data.expressionIndex const e = params.event.event this.toolboxPosition(e) @@ -383,8 +359,6 @@ export default { } }, mounted () { - this.chartOption.color || (this.chartOption.color = initColor(20)) - this.colorList = this.chartOption.color this.chartInfo.loaded && this.initChart() }, beforeDestroy () { diff --git a/nezha-fronted/src/components/chart/chart/chartHexagonD3.vue b/nezha-fronted/src/components/chart/chart/chartHexagonD3.vue index e5b40405d..aec29b330 100644 --- a/nezha-fronted/src/components/chart/chart/chartHexagonD3.vue +++ b/nezha-fronted/src/components/chart/chart/chartHexagonD3.vue @@ -100,37 +100,31 @@ export default { originalData.forEach((data, dataIndex) => { this.isNoData = false const Hexagon = { - value: '', - showValue: '', - label: {}, width: '', height: '', - legend: '', - oldValue: '', - mapping: { - - } + value: '', + showValue: '', + name: '', + alias: '', + labels: {}, + mapping: {} } - const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex) Hexagon.value = getMetricTypeValue(data.values, chartInfo.param.statistics || 'last') - Hexagon.max = chartInfo.param.max || 100 - Hexagon.min = chartInfo.param.min || 0 - if (Hexagon.min === Hexagon.max) { - Hexagon.min = Hexagon.max / 2 - } - Hexagon.label = data.metric - Hexagon.legend = legend.alias - Hexagon.label.legend = Hexagon.legend - Hexagon.expressionIndex = expressionIndex + Hexagon.showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(Hexagon.value, null, -1, decimals) + const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex) Hexagon.name = legend.name Hexagon.alias = legend.alias - Hexagon.showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(Hexagon.value, null, -1, decimals) - // Hexagon.value = Hexagon.showValue + Hexagon.labels = { + ...data.metric, + legend: legend.alias + } + Hexagon.expressionIndex = expressionIndex Hexagon.mapping = this.selectMapping(Hexagon.value, chartInfo.param.valueMapping, chartInfo.param.enable && this.chartInfo.param.enable.valueMapping) this.HexagonData.push(Hexagon) colorIndex++ }) }) + this.setColorList(this.HexagonData) this.$emit('chartIsNoData', this.isNoData) resolve() }) @@ -149,8 +143,7 @@ export default { ...item, x: colIndex, y: rowIndex, - metrics: item.label, - label: item.legend + labels: item.labels } }) const dom = document.getElementById(`chart-canvas-${this.chartId}`) @@ -213,7 +206,7 @@ export default { }, hexagonOver (that, e) { // 移入六边形 this.tooltip.title = that.alias - this.tooltip.value = that.mapping && that.mapping.display ? this.handleDisplay(that.mapping.display, { ...that.metrics, legend: that.alias, value: that.showValue }) : that.showValue + this.tooltip.value = that.mapping && that.mapping.display ? this.handleDisplay(that.mapping.display, { ...that.labels, value: that.showValue }) : that.showValue this.tooltip.mapping = that.mapping this.tooltip.show = true this.setPosition(e) @@ -276,10 +269,10 @@ export default { const textColor = point.mapping ? point.mapping.color.text : this.invertColor(color) if (this.chartInfo.param.text === 'all') { str += point.alias - valueStr = point.mapping && point.mapping.display ? self.handleDisplay(point.mapping.display, { ...point.metrics, legend: point.alias, value: point.showValue }) : point.showValue + valueStr = point.mapping && point.mapping.display ? self.handleDisplay(point.mapping.display, { ...point.labels, value: point.showValue }) : point.showValue } if (this.chartInfo.param.text === 'value' || !this.chartInfo.param.text) { - valueStr = point.mapping && point.mapping.display ? self.handleDisplay(point.mapping.display, { ...point.metrics, legend: point.alias, value: point.showValue }) : point.showValue + valueStr = point.mapping && point.mapping.display ? self.handleDisplay(point.mapping.display, { ...point.labels, value: point.showValue }) : point.showValue } if (this.chartInfo.param.text === 'legend') { str += point.alias @@ -492,10 +485,10 @@ export default { this.tooltip.show = false this.toolbox.title = data.alias - this.toolbox.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.metrics, legend: data.alias, value: data.showValue }) : data.showValue + this.toolbox.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.labels, value: data.showValue }) : data.showValue this.toolbox.mapping = data.mapping this.toolbox.show = true - this.toolbox.metric.labels = data.metrics + this.toolbox.metric.labels = data.labels this.toolbox.metric.expressionIndex = data.expressionIndex this.toolboxPosition(e) } @@ -507,9 +500,6 @@ export default { } }, mounted () { - // eslint-disable-next-line vue/no-mutating-props - this.chartOption.color || (this.chartOption.color = initColor(20)) - this.colorList = this.chartOption.color this.chartInfo.loaded && this.initChart(this.chartOption) }, beforeDestroy () { diff --git a/nezha-fronted/src/components/chart/chart/chartRank.vue b/nezha-fronted/src/components/chart/chart/chartRank.vue index 1088ff58c..588cdacc0 100644 --- a/nezha-fronted/src/components/chart/chart/chartRank.vue +++ b/nezha-fronted/src/components/chart/chart/chartRank.vue @@ -66,7 +66,6 @@ import chartFormat from '@/components/chart/chartFormat' import * as d3 from 'd3' import { getMetricTypeValue } from '@/components/common/js/tools' import chartDataFormat from '@/components/chart/chartDataFormat' -import { initColor } from '@/components/chart/chart/tools' import lodash from 'lodash' export default { @@ -136,6 +135,7 @@ export default { colorIndex++ }) }) + this.setColorList(this.rankData) }, drawRankChart () { @@ -371,7 +371,6 @@ export default { } }, mounted () { - this.colorList = initColor(20) this.chartInfo.loaded && this.initChart() }, beforeDestroy () { diff --git a/nezha-fronted/src/components/chart/chart/chartRose.vue b/nezha-fronted/src/components/chart/chart/chartRose.vue index f5541b4e7..68dc83792 100644 --- a/nezha-fronted/src/components/chart/chart/chartRose.vue +++ b/nezha-fronted/src/components/chart/chart/chartRose.vue @@ -154,7 +154,7 @@ export default { const mapping = this.selectMapping(value, chartInfo.param.valueMapping, chartInfo.param.enable && this.chartInfo.param.enable.valueMapping) const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex) this.roseData.push({ - value: Number(value), + value: parseFloat(value), realValue: value, showValue: showValue, name: legend.name, @@ -166,12 +166,16 @@ export default { expressionIndex: expressionIndex, dataIndex: dataIndex, mapping: mapping, - background: mapping ? mapping.color.bac : this.colorList[colorIndex] - + background: '' }) colorIndex++ }) }) + this.setColorList(this.roseData) + this.roseData.forEach((item, index) => { + item.background = item.mapping ? item.mapping.color.bac : this.colorList[index] + this.legends[index].color = item.mapping ? item.mapping.color.bac : this.colorList[index] + }) this.$emit('chartIsNoData', this.isNoData) }, drawRoseChart (animate) { diff --git a/nezha-fronted/src/components/chart/chart/chartSankey.vue b/nezha-fronted/src/components/chart/chart/chartSankey.vue index d46d77527..f0a8f57c3 100644 --- a/nezha-fronted/src/components/chart/chart/chartSankey.vue +++ b/nezha-fronted/src/components/chart/chart/chartSankey.vue @@ -199,17 +199,16 @@ export default { links: linksData }) + this.setColorList(nodes) + // 设置节点颜色 nodes.forEach((item, index) => { - if (index >= 20) { - const colorRandom = randomcolor() - this.colorList.push(colorRandom) - } - const mapping = this.selectMapping(item.value, this.chartInfo.param.valueMapping, this.chartInfo.param.enable && this.chartInfo.param.enable.valueMapping) + const value = !allZero ? item.value : 0 + const mapping = this.selectMapping(value, this.chartInfo.param.valueMapping, this.chartInfo.param.enable && this.chartInfo.param.enable.valueMapping) item.mapping = mapping item.background = mapping ? mapping.color.bac : this.colorList[index] const decimals = this.chartInfo.param.decimals || 2 - item.showValue = chartDataFormat.getUnit(this.chartInfo.unit ? this.chartInfo.unit : 2).compute(!allZero ? item.value : 0, null, -1, decimals) + item.showValue = chartDataFormat.getUnit(this.chartInfo.unit ? this.chartInfo.unit : 2).compute(value, null, -1, decimals) }) // 创建一个连线绘制组,绑定连线数据(links) @@ -471,7 +470,6 @@ export default { } }, mounted () { - this.colorList = initColor(20) this.chartInfo.loaded && this.initChart() }, beforeDestroy () { diff --git a/nezha-fronted/src/components/chart/chart/chartStat.vue b/nezha-fronted/src/components/chart/chart/chartStat.vue index ba7d85f15..4a931d35c 100644 --- a/nezha-fronted/src/components/chart/chart/chartStat.vue +++ b/nezha-fronted/src/components/chart/chart/chartStat.vue @@ -22,16 +22,16 @@ @@ -42,11 +42,11 @@ - {{item.legend}} + {{item.alias}}

-

{{item.legend}}

+

{{item.alias}}

@@ -56,7 +56,7 @@ - {{handleDisplay(item.mapping.display, { ...item.label, value: item.showValue })}} + {{handleDisplay(item.mapping.display, { ...item.labels, value: item.showValue })}}

@@ -137,7 +137,6 @@ import chartFormat from '@/components/chart/chartFormat' import { getMetricTypeValue } from '@/components/common/js/tools' import chartDataFormat from '@/components/chart/chartDataFormat' import { randomcolor } from '@/components/common/js/radomcolor/randomcolor' -import { initColor } from '@/components/chart/chart/tools' // import fontWidth from '@/components/chart/chart/options/fontWidth' import * as echarts from 'echarts' import chartSparklineOption from './options/chartSparkline' @@ -159,7 +158,7 @@ export default { minFontSzie: 12, defaultUnit: 60, // 根据stat的长宽取 需要的字体 = (取最短的边 / defaultUnit) * fontSize 因为 需要的字体/fontSize = 实际宽 / defaultUnit sparkline: {}, - maxValue: 0 + maxYAxis: 0 } }, methods: { @@ -189,23 +188,26 @@ export default { originalData.forEach((data, dataIndex) => { this.isNoData = false const stat = { - value: '', - showValue: '', - label: {}, width: '', height: '', - legend: '', + value: '', + showValue: '', name: '', + alias: '', + labels: {}, mapping: {}, data: {} } stat.value = getMetricTypeValue(data.values, chartInfo.param.statistics) - stat.label = data.metric - stat.legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex).alias - stat.label.legend = stat.legend - stat.expressionIndex = expressionIndex - stat.name = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex).name stat.showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(stat.value, null, -1, decimals) + const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex) + stat.name = legend.name + stat.alias = legend.alias + stat.labels = { + ...data.metric, + legend: legend.alias + } + stat.expressionIndex = expressionIndex stat.mapping = this.selectMapping(stat.value, chartInfo.param.valueMapping, chartInfo.param.enable && this.chartInfo.param.enable.valueMapping) stat.data = data.values // 判断是否是对比的数据 @@ -217,19 +219,19 @@ export default { colorIndex++ }) }) - // 计算最大值 - let maxValue = 0 + // 计算sparkline最大值 + let maxYAxis = 0 if (this.statData.length > 0) { - maxValue = 0 + maxYAxis = 0 for (let j = 0; j < this.statData.length; j++) { for (let i = 0; i < this.statData[j].data.length; i++) { if (!isNaN(this.statData[j].data[i][1])) { - maxValue = (maxValue < Number(this.statData[j].data[i][1]) ? Number(this.statData[j].data[i][1]) : maxValue) + maxYAxis = (maxYAxis < Number(this.statData[j].data[i][1]) ? Number(this.statData[j].data[i][1]) : maxYAxis) } } } } - this.maxValue = maxValue + this.maxYAxis = maxYAxis // 计算同比变化量 if (this.chartInfo.param.comparison && this.chartInfo.param.comparison !== 'none') { @@ -259,11 +261,12 @@ export default { item.comparison = comparison }) } - + this.setColorList(this.statData) this.$emit('chartIsNoData', this.isNoData) resolve() }) }, + calculateGridDimensions (parentWidth, parentHeight, numberOfChildren) { const vertical = this.calculateSizeOfChild(parentWidth, parentHeight, numberOfChildren) const horizontal = this.calculateSizeOfChild(parentHeight, parentWidth, numberOfChildren) @@ -314,7 +317,7 @@ export default { let display = '' if (item.mapping) { - display = this.handleDisplay(item.mapping.display, { ...item.label, value: item.showValue }) + display = this.handleDisplay(item.mapping.display, { ...item.labels, value: item.showValue }) } let titleFont = '' let valueFont = '' @@ -323,7 +326,7 @@ export default { const padding = 10 switch (this.chartInfo.param.text) { case 'all': - titleFont = item.legend + titleFont = item.alias if (item.mapping) { valueFont = display if (item.mapping.icon) { @@ -337,7 +340,7 @@ export default { titleFontSize = Math.min(valueFontSize * 0.7, titleFontSize) break case 'legend': - titleFont = item.legend + titleFont = item.alias if (item.mapping) { if (item.mapping.icon) { titleFont += 'AA' @@ -432,7 +435,7 @@ export default { color: areaColor } } - chartOption.yAxis.max = this.maxValue + chartOption.yAxis.max = this.maxYAxis chart.setOption(chartOption) this.sparkline[index] = chart }) @@ -452,8 +455,8 @@ export default { }, 100) }, statMouseEnter (data, e) { - this.tooltip.title = data.legend - this.tooltip.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.label, value: data.showValue }) : data.showValue + this.tooltip.title = data.alias + this.tooltip.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.labels, value: data.showValue }) : data.showValue this.tooltip.mapping = data.mapping this.tooltip.show = true this.setPosition(e) @@ -555,11 +558,11 @@ export default { if (this.dataLink.length || this.chartInfo.datasource === 'metrics' || this.chartInfo.datasource === 'logs') { this.tooltip.show = false - this.toolbox.title = data.legend - this.toolbox.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.label, value: data.showValue }) : data.showValue + this.toolbox.title = data.alias + this.toolbox.value = data.mapping && data.mapping.display ? this.handleDisplay(data.mapping.display, { ...data.labels, value: data.showValue }) : data.showValue this.toolbox.mapping = data.mapping this.toolbox.show = true - this.toolbox.metric.labels = data.label + this.toolbox.metric.labels = data.labels this.toolbox.metric.expressionIndex = data.expressionIndex this.toolboxPosition(e) } @@ -571,7 +574,6 @@ export default { } }, mounted () { - this.colorList = initColor(20) this.chartInfo.loaded && this.initChart() }, beforeDestroy () { diff --git a/nezha-fronted/src/components/chart/chart/chartTimeSeries.vue b/nezha-fronted/src/components/chart/chart/chartTimeSeries.vue index bf7b7efd8..68ab547c2 100644 --- a/nezha-fronted/src/components/chart/chart/chartTimeSeries.vue +++ b/nezha-fronted/src/components/chart/chart/chartTimeSeries.vue @@ -248,7 +248,7 @@ export default { setTimeout(() => { const dom = document.getElementById(`chart-canvas-${this.chartId}`) if (!dom) { - return; + return } const myChart = this.isInit ? echarts.init(dom) : getChart(this.chartId) if (!myChart) { diff --git a/nezha-fronted/src/components/chart/chart/chartTreemap.vue b/nezha-fronted/src/components/chart/chart/chartTreemap.vue index aabf345e1..6777fb30d 100644 --- a/nezha-fronted/src/components/chart/chart/chartTreemap.vue +++ b/nezha-fronted/src/components/chart/chart/chartTreemap.vue @@ -108,6 +108,13 @@ export default { this.setDataLink() this.legends = [] this.series = chartOption.series = this.initTreeMapData(this.chartInfo, chartOption.series[0], this.chartData) // 生成series和legends + this.setColorList(this.series[0].data) + this.series[0].data.forEach((item, index) => { + item.itemStyle = { + color: item.mapping ? item.mapping.color.bac : this.colorList[index] + } + this.legends[index].color = item.mapping ? item.mapping.color.bac : this.colorList[index] + }) chartOption.tooltip.formatter = this.formatterFunc chartOption.tooltip.position = this.tooltipPosition if (navigator.userAgent.match(/Mobi/i) || @@ -149,11 +156,9 @@ export default { const value = getMetricTypeValue(data.values, chartInfo.param.statistics) const showValue = chartDataFormat.getUnit(chartInfo.unit ? chartInfo.unit : 2).compute(value, null, -1, decimals) const mapping = this.selectMapping(value, chartInfo.param.valueMapping, chartInfo.param.enable && this.chartInfo.param.enable.valueMapping) - // eslint-disable-next-line vue/no-mutating-props - this.chartOption.color && mapping && (this.chartOption.color[colorIndex] = mapping.color.bac) const legend = this.handleLegend(chartInfo, data, expressionIndex, dataIndex, colorIndex) s.data.push({ - value: value, + value: parseFloat(value), realValue: value, showValue: showValue, name: legend.name, @@ -170,7 +175,6 @@ export default { color: mapping ? mapping.color.text : '#000000' }, itemStyle: { - color: mapping ? mapping.color.bac : this.colorList[colorIndex] } }) colorIndex++ @@ -244,8 +248,6 @@ export default { }, mounted () { // eslint-disable-next-line vue/no-mutating-props - this.chartOption.color || (this.chartOption.color = initColor(20)) - this.colorList = this.chartOption.color this.chartInfo.loaded && this.initChart(this.chartOption) } } diff --git a/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeries.vue b/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeries.vue index a20608753..5cc56e161 100644 --- a/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeries.vue +++ b/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeries.vue @@ -57,7 +57,6 @@ import chartMixin from '@/components/chart/chartMixin' import renderChart from '@/components/chart/renderChart' import { chartLegendPlacement } from '@/components/common/js/constants' import { getChart, setChart, chartCache } from '@/components/common/js/common' -import { initColor } from '@/components/chart/chart/tools' import UPlot from 'uplot' import chartTimeSeriesMixin from '@/components/chart/chart/uplot/chartTimeSeriesMixin' import chartDataFormat from '@/components/chart/chartDataFormat' @@ -608,8 +607,6 @@ export default { } }, mounted () { - this.chartOption.color || (this.chartOption.color = initColor(20)) - this.colorList = this.chartOption.color try { this.isStack = !!this.chartInfo.param.stack } catch (e) {} diff --git a/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeriesMixin.js b/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeriesMixin.js index 14f294891..c5cf5018a 100644 --- a/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeriesMixin.js +++ b/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeriesMixin.js @@ -7,10 +7,12 @@ import bus from '@/libs/bus' import moment from 'moment-timezone' import { getChart } from '@/components/common/js/common' import uplot from 'uplot' +import { interpolateRgbBasis } from 'd3-interpolate' +import tinycolor from 'tinycolor2' export default { data () { return { - seriesColor: initColor(), + colorList: [], incrs: Incrs, dataIdx: null, seriesIdx: null, @@ -95,19 +97,80 @@ export default { }) this.chartIndex = chartIndex seriesData.unshift(time) + this.setColorList(seriesAll, seriesData) this.series = seriesAll return { seriesData, seriesAll } }, + setColorList (seriesAll, seriesData) { + let dataArr = lodash.cloneDeep(seriesData) + dataArr.shift() + // 取最后一个非空值 + dataArr = dataArr.map(item => { + let value = 0 + for (let i = item.length - 1; i >= 0; i--) { + if (item[i]) { + value = item[i] + break + } + } + return { + value + } + }) + this.colorList = [] + const initColorArr = initColor(20) + const mode = lodash.get(this.chartInfo, 'param.color.mode', 'palette') + seriesAll.forEach((item, index) => { + let color = '' + if (mode === 'palette') { + color = initColorArr[index] || randomcolor() + } else if (mode === 'fixed') { + color = lodash.get(this.chartInfo, 'param.color.fixedColor') + } else if (mode === 'continuous') { + const continuousType = lodash.get(this.chartInfo, 'param.color.continuousType') + let min = lodash.get(this.chartInfo, 'param.min') || 0 + let max = lodash.get(this.chartInfo, 'param.max') || this.calcMax(dataArr) + if (item.yAxisIndex == 1) { + min = lodash.get(this.chartInfo, 'param.rightYAxis.min') || 0 + max = lodash.get(this.chartInfo, 'param.rightYAxis.max') || this.calcMax(dataArr) + } + // 获取颜色数组 + const colorArr = this.$CONSTANTS.colorScheme.find(item => item.value == continuousType).color + const value = parseFloat(dataArr[index].value) + const valuePercent = this.getValuePercent(value, min, max) + // 创建插值函数 + const interpolateColor = interpolateRgbBasis(colorArr) + color = interpolateColor(valuePercent) + } + // 设置图表颜色 + const chartType = item.yAxisIndex == 1 ? lodash.get(this.chartInfo, 'param.rightYAxis.style', 'line') : this.chartInfo.type + item.stroke = color + if (chartType === 'area') { + // 使用 tinycolor 转换为十六进制 + const hexColor = tinycolor(color).toHexString() + item.fill = hexColor + '20' // 面积图使用 + } + if (chartType === 'point') { + item.points = { + show: true, + size: 6, + width: 3, + fill: color, + stroke: color + } + item.width = 0 + } + this.colorList.push(color) + this.legends[index].color = color + }) + }, renderSeries (series, expressionIndex, dataIndex, chartIndex) { const leftUnit = this.chartInfo.unit const leftUnitCompute = chartDataFormat.getUnit(leftUnit) const decimals = this.chartInfo.param.decimals || 2 - if (chartIndex > 19) { - this.seriesColor.push(randomcolor()) - } const legend = this.handleLegend(this.chartInfo, series, expressionIndex, dataIndex, chartIndex) let isRight if (this.chartInfo.param.enable.rightYAxis) { @@ -117,7 +180,6 @@ export default { const name = legend.name const alias = legend.alias const statistics = series.statistics - const chartType = this.chartInfo.type const obj = { name: name, @@ -125,7 +187,6 @@ export default { scale: isRight ? 'right' : 'left', // right yAxisIndex: isRight, // right // values: (u, v) => series.elements.name + JSON.stringify(series.metric), - stroke: this.seriesColor[chartIndex], width: 1 / devicePixelRatio, expressionIndex: series.expressionIndex, paths (taht, seriesIdx, idx0, idx1, filtIdxs) { @@ -133,20 +194,7 @@ export default { }, spanGaps: true } - if (chartType === 'area') { - obj.fill = this.seriesColor[chartIndex] + '20' // 面积图使用 - } - if (chartType === 'point') { - obj.points = { - show: true, - size: 6, - width: 3, - fill: this.seriesColor[chartIndex], - stroke: this.seriesColor[chartIndex] - } - obj.width = 0 - } - this.legends.push({ name, alias, statistics, color: this.seriesColor[chartIndex] }) + this.legends.push({ name, alias, statistics, color: this.colorList[chartIndex] }) return obj }, tooltipPlugin ({ onclick, shiftX = 10, shiftY = 10 }) { diff --git a/nezha-fronted/src/components/chart/chartMixin.js b/nezha-fronted/src/components/chart/chartMixin.js index 7a60ba7bd..2bb356307 100644 --- a/nezha-fronted/src/components/chart/chartMixin.js +++ b/nezha-fronted/src/components/chart/chartMixin.js @@ -10,6 +10,8 @@ import { chartTimeSeriesScatterOption } from './chart/options/chartTimeSeries' import * as CSV from 'csv-string' +import { initColor } from '@/components/chart/chart/tools' +import { interpolateRgbBasis } from 'd3-interpolate' export default { data () { return { @@ -92,7 +94,6 @@ export default { originalDatas.forEach((originalData, expressionIndex) => { originalData.forEach((data, dataIndex) => { if (colorIndex >= 20 && !this.showAllData) { - colorIndex++ return } this.isNoData = false @@ -246,10 +247,6 @@ export default { return { type, value: getMetricTypeValue(data.values, type) } }) } - if (colorIndex >= 20) { - const colorRandom = randomcolor() - this.colorList.push(colorRandom) - } if (this.chartInfo.type !== 'line' && this.chartInfo.type !== 'area' && this.chartInfo.type !== 'point') { this.legends.push({ name, alias, statistics, color: this.colorList[colorIndex] }) } @@ -648,16 +645,63 @@ export default { csv += '\n' }) return csv + }, + // 计算最大值向上取整 + calcMax (arr) { + let maxNum = arr.reduce((maxValue, obj) => { + return Math.max(maxValue, obj.value) + }, 0) + + if (maxNum <= 1) { + return 1 + } + + let bite = 1 + while (maxNum >= 10) { + maxNum /= 10 + if (maxNum > 1) { + bite += 1 + } + } + + return Math.pow(10, bite) + }, + // 获取值百分比 + getValuePercent (value, minValue, maxValue) { + // Need special logic for when minValue === maxValue === value to prevent returning NaN + const valueRatio = Math.min((value - minValue) / (maxValue - minValue), 1) + return isNaN(valueRatio) ? 0 : valueRatio + }, + setColorList (arr) { + this.colorList = [] + const initColorArr = initColor(20) + const mode = lodash.get(this.chartInfo, 'param.color.mode', 'palette') + arr.forEach((item, index) => { + let color = '' + if (mode === 'palette') { + color = initColorArr[index] || randomcolor() + } else if (mode === 'fixed') { + color = lodash.get(this.chartInfo, 'param.color.fixedColor') + } else if (mode === 'continuous') { + const continuousType = lodash.get(this.chartInfo, 'param.color.continuousType') + const min = lodash.get(this.chartInfo, 'param.min') || 0 + const max = lodash.get(this.chartInfo, 'param.max') || this.calcMax(arr) + // 获取颜色数组 + const colorArr = this.$CONSTANTS.colorScheme.find(item => item.value == continuousType).color + const value = parseFloat(item.value) + const valuePercent = this.getValuePercent(value, min, max) + // 创建插值函数 + const interpolateColor = interpolateRgbBasis(colorArr) + color = interpolateColor(valuePercent) + } + this.colorList.push(color) + }) } }, watch: { chartData: { deep: true, handler (n) { - if (!this.isInit && this.chartOption.color) { - this.colorList = this.colorList.slice(0, 20) - this.chartOption.color = this.chartOption.color.slice(0, 20) - } if (!this.isInit) { this.initChart(this.chartOption) if (this.resize) { diff --git a/nezha-fronted/src/components/common/bottomBox/tabs/dashboardTab.vue b/nezha-fronted/src/components/common/bottomBox/tabs/dashboardTab.vue index e8eda2217..fc3c1c165 100644 --- a/nezha-fronted/src/components/common/bottomBox/tabs/dashboardTab.vue +++ b/nezha-fronted/src/components/common/bottomBox/tabs/dashboardTab.vue @@ -156,7 +156,7 @@ import htmlToPdfMixin from '@/components/common/mixin/htmlToPdfMixin' import exportHtmlMixin from '@/components/common/mixin/exportHtml' import panelVariables from '@/components/common/panel/panelVariables' import snapshotProgress from '@/components/common/snapshotProgress/snapshotProgress.vue' - +import { initColor } from '@/components/chart/chart/tools' export default { name: 'dashboardTab', mixins: [subDataListMixin, detailViewRightMixin, htmlToPdfMixin, exportHtmlMixin], @@ -223,6 +223,15 @@ export default { height: 2, unit: 2, param: { + min: undefined, + max: undefined, + color: { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + }, stack: 0, nullType: 'null', legend: { placement: 'bottom', values: [], show: true }, @@ -255,7 +264,7 @@ export default { tooltip: { mode: 'all', sort: 'none' - }, + } }, elements: [{ expression: '', legend: '', type: 'expert', id: '', name: 'A', state: 1, orderNum: 0 }], panel: '', @@ -330,7 +339,7 @@ export default { { value: 60, label: '1m' }, { value: 300, label: '5m' }, { value: 900, label: '15m' }, - { value: 1800, label: '30m' }, + { value: 1800, label: '30m' } ] } }, diff --git a/nezha-fronted/src/components/common/bottomBox/tabs/notebookTab.vue b/nezha-fronted/src/components/common/bottomBox/tabs/notebookTab.vue index 2d1df892c..74079b4f2 100644 --- a/nezha-fronted/src/components/common/bottomBox/tabs/notebookTab.vue +++ b/nezha-fronted/src/components/common/bottomBox/tabs/notebookTab.vue @@ -105,6 +105,7 @@ import { fromRoute } from '@/components/common/js/constants' import { randomcolor } from '@/components/common/js/radomcolor/randomcolor' import snapshotProgress from '@/components/common/snapshotProgress/snapshotProgress.vue' import notebookList from '@/components/page/notebook/notebookList.vue' +import { initColor } from '@/components/chart/chart/tools' export default { name: 'notebookTab', mixins: [subDataListMixin, detailViewRightMixin], @@ -326,6 +327,15 @@ export default { case 'area': case 'point': param = { + min: undefined, + max: undefined, + color: { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + }, stack: 0, link: '', nullType: 'null', @@ -370,13 +380,20 @@ export default { case 'rank': case 'funnel': param = { + min: undefined, + max: undefined, + color: { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + }, link: '', nullType: 'null', statistics: 'last', text: 'value', valueMapping: [], - min: 0, - max: 100, enable: { legend: true, valueMapping: false, @@ -399,6 +416,15 @@ export default { case 'doughnut': case 'rose': param = { + min: undefined, + max: undefined, + color: { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + }, link: '', nullType: 'null', statistics: 'last', diff --git a/nezha-fronted/src/components/common/js/constants.js b/nezha-fronted/src/components/common/js/constants.js index d8d4a76ad..7af4f7e0d 100644 --- a/nezha-fronted/src/components/common/js/constants.js +++ b/nezha-fronted/src/components/common/js/constants.js @@ -369,7 +369,7 @@ export const intervalList = [ { value: 60, label: '1m' }, { value: 300, label: '5m' }, { value: 900, label: '15m' }, - { value: 1800, label: '30m' }, + { value: 1800, label: '30m' } // { value: 3600, label: '1h' }, // { value: 7200, label: '2h' } ] @@ -523,3 +523,16 @@ export const systemIcon = { } export const stackIconSvg = 'path://M538.112 998.4a25.6 25.6 0 0 1-11.776-2.88L39.424 743.232a25.6 25.6 0 1 1 23.552-45.44l474.368 245.824 422.592-245.248a25.6 25.6 0 0 1 25.728 44.288l-434.688 252.288a25.728 25.728 0 0 1-12.864 3.456z,M538.112 789.888a25.6 25.6 0 0 1-11.776-2.88L39.424 534.72a25.6 25.6 0 1 1 23.552-45.44l474.368 245.824 422.592-245.248a25.6 25.6 0 1 1 25.728 44.288l-434.688 252.288a25.728 25.728 0 0 1-12.864 3.456z,M538.112 581.312a25.6 25.6 0 0 1-11.776-2.88L39.424 326.144a25.6 25.6 0 0 1-1.088-44.928L473.088 28.928a25.344 25.344 0 0 1 24.64-0.576l486.848 252.288a25.6 25.6 0 0 1 1.088 44.928L550.976 577.856a25.728 25.728 0 0 1-12.864 3.456zM104.384 302.208l432.96 224.384 382.208-221.824-432.96-224.384-382.208 221.824z' + +export const colorScheme = [ + { name: i18n.t('dashboard.dashboard.chartForm.singleColor'), value: 'fixed', background: '' }, + { name: i18n.t('dashboard.dashboard.chartForm.classicPalette'), value: 'palette', background: 'linear-gradient(90deg, #3685FF 0%, #3685FF 5%, #00DCA2 5%, #00DCA2 10%, #00BFD0 10%, #00BFD0 15%, #954Eff 15%, #954Eff 20%, #FFCB01 20%, #FFCB01 25%, #f65A96 25%, #f65A96 30%, #FF9094 30%, #FF9094 35%, #00CCF5 35%, #00CCF5 40%, #FF8BEA 40%, #FF8BEA 45%, #4D7693 45%, #4D7693 50%, #72577C 50%, #72577C 55%, #99D750 55%, #99D750 60%, #DD8270 60%, #DD8270 65%, #C475EE 65%, #C475EE 70%, #7E83FB 70%, #7E83FB 75%, #7EB090 75%, #7EB090 80%, #CF6684 80%, #CF6684 85%, #4E55FF 85%, #4E55FF 90%, #FF8D00 90%, #FF8D00 95%, #FF5200 95%, #FF5200 100%)' }, + { name: i18n.t('dashboard.dashboard.chartForm.greenYellowRed'), value: 'GrYlRd', color: ['rgb(86, 166, 75)', 'rgb(242, 204, 12)', 'rgb(224, 47, 68)'], background: 'linear-gradient(90deg, rgb(86, 166, 75), rgb(242, 204, 12), rgb(224, 47, 68))' }, + { name: i18n.t('dashboard.dashboard.chartForm.redYellowGreen'), value: 'RdYlGr', color: ['rgb(224, 47, 68)', 'rgb(242, 204, 12)', 'rgb(86, 166, 75)'], background: 'linear-gradient(90deg, rgb(224, 47, 68), rgb(242, 204, 12), rgb(86, 166, 75))' }, + { name: i18n.t('dashboard.dashboard.chartForm.blueYellowRed'), value: 'BlYlRd', color: ['rgb(18, 80, 176)', 'rgb(255, 238, 82)', 'rgb(173, 3, 23)'], background: 'linear-gradient(90deg, rgb(18, 80, 176), rgb(255, 238, 82), rgb(173, 3, 23))' }, + { name: i18n.t('dashboard.dashboard.chartForm.yellowRed'), value: 'YlRd', color: ['rgb(255, 238, 82)', 'rgb(173, 3, 23)'], background: 'linear-gradient(90deg, rgb(255, 238, 82), rgb(173, 3, 23))' }, + { name: i18n.t('dashboard.dashboard.chartForm.yellowBlue'), value: 'YlBl', color: ['rgb(255, 238, 82)', 'rgb(18, 80, 176)'], background: 'linear-gradient(90deg, rgb(255, 238, 82), rgb(18, 80, 176))' }, + { name: i18n.t('dashboard.dashboard.chartForm.blues'), value: 'blues', color: ['rgb(255, 255, 255)', 'rgb(18, 80, 176)'], background: 'linear-gradient(90deg, rgb(255, 255, 255), rgb(18, 80, 176))' }, + { name: i18n.t('dashboard.dashboard.chartForm.greens'), value: 'reds', color: ['rgb(255, 255, 255)', 'rgb(25, 115, 14)'], background: 'linear-gradient(90deg, rgb(255, 255, 255), rgb(25, 115, 14))' }, + { name: i18n.t('dashboard.dashboard.chartForm.reds'), value: 'greens', color: ['rgb(255, 255, 255)', 'rgb(173, 3, 23)'], background: 'linear-gradient(90deg, rgb(255, 255, 255), rgb(173, 3, 23))' } +] diff --git a/nezha-fronted/src/components/common/nezhaColor.vue b/nezha-fronted/src/components/common/nezhaColor.vue index a571e0d77..92ee3e743 100644 --- a/nezha-fronted/src/components/common/nezhaColor.vue +++ b/nezha-fronted/src/components/common/nezhaColor.vue @@ -10,10 +10,8 @@
-
- - T - +
+ T
@@ -130,7 +128,7 @@ export default { this.showColorPicker = !this.showColorPicker if (this.showColorPicker) { window.addEventListener('mousewheel', this.mousewheel) - setTimeout(() => { + this.$nextTick(() => { const position = this.$refs.colorShow.getBoundingClientRect() const colorBox = this.$refs.colorBox.getBoundingClientRect() const w = window.innerWidth diff --git a/nezha-fronted/src/components/common/rightBox/chart/chartConfig.vue b/nezha-fronted/src/components/common/rightBox/chart/chartConfig.vue index fb663b64e..8e1f6e118 100644 --- a/nezha-fronted/src/components/common/rightBox/chart/chartConfig.vue +++ b/nezha-fronted/src/components/common/rightBox/chart/chartConfig.vue @@ -207,6 +207,69 @@ + + + + + + + + + + + + + + + + +
+

{{$t(item.name)}}

+
+ +

{{$t('dashboard.dashboard.chartForm.singleColorMsg')}}

+
+
+
+ +
+ - + + -
-
- - - - - - - - -
- -
- - - - - - - - -
- -
- - - - + +
+
+ + + + + + + + +
+
@@ -579,7 +608,7 @@ :controls="false" @change="change" show-word-limit - :placeholder="chartConfig.param.rightYAxis.min?'':'Auto'" + placeholder="Auto" v-model="chartConfig.param.rightYAxis.min"/> @@ -594,7 +623,7 @@ :controls="false" @change="change" show-word-limit - :placeholder="chartConfig.param.rightYAxis.max?'':'Auto'" + placeholder="Auto" v-model="chartConfig.param.rightYAxis.max"/>
@@ -1367,7 +1396,7 @@ import VueTagsInput from '@johmun/vue-tags-input' import draggable from 'vuedraggable' import { s8 } from '@/components/common/js/common' import { randomcolor, ColorReverse } from '@/components/common/js/radomcolor/randomcolor' -import { isSankey } from '@/components/chart/chart/tools' +import { isSankey, initColor } from '@/components/chart/chart/tools' export default { name: 'chartConfig', @@ -1462,6 +1491,15 @@ export default { break } this.chartConfig.param = { + min: undefined, + max: undefined, + color: { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + }, stack: 0, link: this.chartConfig.param.link, nullType: this.chartConfig.param.nullType, @@ -1512,13 +1550,20 @@ export default { break } this.chartConfig.param = { + min: undefined, + max: undefined, + color: { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + }, nullType: this.chartConfig.param.nullType, link: this.chartConfig.param.link, statistics: 'last', text: 'value', valueMapping: [], - min: 0, - max: 100, enable: { legend: true, valueMapping: false, @@ -1547,14 +1592,21 @@ export default { break } this.chartConfig.param = { + min: undefined, + max: undefined, + color: { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + }, nullType: this.chartConfig.param.nullType, link: this.chartConfig.param.link, statistics: 'last', text: 'value', valueMapping: [], legend: { placement: 'bottom', values: [], show: true }, - min: 0, - max: 100, enable: { legend: true, valueMapping: false, diff --git a/nezha-fronted/src/components/common/rightBox/chart/chartRightBox.vue b/nezha-fronted/src/components/common/rightBox/chart/chartRightBox.vue index 5713b33c9..451feec83 100644 --- a/nezha-fronted/src/components/common/rightBox/chart/chartRightBox.vue +++ b/nezha-fronted/src/components/common/rightBox/chart/chartRightBox.vue @@ -145,7 +145,7 @@ import panelChart from '@/components/chart/panelChart' import lodash from 'lodash' import bus from '@/libs/bus' import chartTypeShow from '@/components/common/rightBox/chart/chartTypeShow' - +import { initColor } from '@/components/chart/chart/tools' const rz = { methods: { rz (e) { @@ -264,6 +264,27 @@ export default { delete params.param.orientation delete params.param.displayMode } + if (this.isShowColorScheme(params.type)) { + if (params.param.color) { + const mode = params.param.color.mode + if (mode === 'palette') { + params.param.color = { + mode: mode, + paletteColors: params.param.color.paletteColors + } + } else if (mode === 'fixed') { + params.param.color = { + mode: mode, + fixedColor: params.param.color.fixedColor + } + } else { + params.param.color = { + mode: mode, + continuousType: params.param.color.continuousType + } + } + } + } if (!params.x && !params.y && this.from === 'endpointQuery') { // endpointQuery 新增 放在最后 params.x = 0 params.y = 999 @@ -391,6 +412,15 @@ export default { type: 'line', elements: [{ expression: '', legend: '', type: 'expert', id: '', name: 'A', state: 1, step: undefined, queryType: 1 }], param: { + min: undefined, + max: undefined, + color: { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + }, stack: 0, nullType: 'null', legend: { placement: 'bottom', values: [] }, @@ -435,6 +465,15 @@ export default { type: 'line', elements: [{ expression: '', legend: '', type: 'expert', id: '', name: 'A', state: 1, step: undefined, queryType: 1 }], param: { + min: undefined, + max: undefined, + color: { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + }, stack: 0, nullType: 'null', legend: { placement: 'bottom', values: [] }, @@ -503,6 +542,15 @@ export default { unit: 2, type: 'stat', param: { + min: undefined, + max: undefined, + color: { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + }, refer: 0, nullType: 'null', statistics: 'last', @@ -748,6 +796,26 @@ export default { if (!obj.param.orientation) { obj.param.orientation = 'vertical' } if (!obj.param.displayMode) { obj.param.displayMode = 'basic' } } + if (this.isShowColorScheme(obj.type)) { + if (!obj.param.color) { + obj.param.color = { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + } + } else { + const mode = obj.param.color.mode + if (mode === 'palette') { + obj.param.color.schemeType = 'palette' + } else if (mode === 'fixed') { + obj.param.color.schemeType = 'fixed' + } else { + obj.param.color.schemeType = obj.param.color.continuousType + } + } + } } if (obj.elements && obj.elements.length) { obj.elements.forEach((item, index) => { diff --git a/nezha-fronted/src/components/common/rightBox/chart/chartTypeShow.js b/nezha-fronted/src/components/common/rightBox/chart/chartTypeShow.js index af5900c15..dd8da285b 100644 --- a/nezha-fronted/src/components/common/rightBox/chart/chartTypeShow.js +++ b/nezha-fronted/src/components/common/rightBox/chart/chartTypeShow.js @@ -231,12 +231,10 @@ export default { }, isShowMinMax (type) { switch (type) { - case 'line': - case 'area': - case 'point': - case 'gauge': - return true - default: return false + case 'log' : + case 'table' : + return false + default: return true } }, isTimeSeries (type) { @@ -254,6 +252,14 @@ export default { return true default: return false } + }, + isShowColorScheme (type) { + switch (type) { + case 'log' : + case 'table' : + return false + default: return true + } } } } diff --git a/nezha-fronted/src/components/common/rightBox/chart/publicConfig.js b/nezha-fronted/src/components/common/rightBox/chart/publicConfig.js index f14e68ef9..8a8e87ff2 100644 --- a/nezha-fronted/src/components/common/rightBox/chart/publicConfig.js +++ b/nezha-fronted/src/components/common/rightBox/chart/publicConfig.js @@ -1,9 +1,10 @@ import chartDataFormat from '@/components/chart/chartDataFormat' import { getUUID, resetZIndex } from '@/components/common/js/common' import { randomcolor, ColorReverse } from '@/components/common/js/radomcolor/randomcolor' -import { isStat } from '@/components/chart/chart/tools' +import { isStat, initColor } from '@/components/chart/chart/tools' import lodash from 'lodash' import iconList from '@/components/common/js/iconList' +import { colorScheme } from '@/components/common/js/constants' const rz = { methods: { rz (e) { @@ -299,11 +300,30 @@ export default { id: 'month', name: this.$t('dashboard.chartForm.comparison.month') } - ] + ], + colorScheme } }, mixins: [rz], methods: { + schemeTypeChange (val) { + const obj = this.$lodash.cloneDeep(this.chartConfig.param.color) + if (val === 'palette') { + obj.schemeType = 'palette' + obj.mode = 'palette' + obj.paletteColors = initColor(20) + } else if (val === 'fixed') { + obj.schemeType = 'fixed' + obj.mode = 'fixed' + obj.fixedColor = obj.fixedColor || randomcolor() + } else { + obj.schemeType = val + obj.mode = 'continuous' + obj.continuousType = val + } + this.$set(this.chartConfig.param, 'color', obj) + this.change() + }, isStat, // icon点击 iconActive (item, subItem, index) { @@ -330,7 +350,7 @@ export default { state: this.expressionsShow[i].state, orderNum: i, step: this.expressionsShow[i].step, - queryType: this.expressionsShow[i].queryType, + queryType: this.expressionsShow[i].queryType }) } }) @@ -559,6 +579,9 @@ export default { this.chartConfig.param.valueMapping[index].color.icon = val this.$set(this.chartConfig.param.valueMapping, index, this.chartConfig.param.valueMapping[index]) } + if (key === 'colorScheme') { + this.chartConfig.param.color.fixedColor = val + } this.change() }, change (key, index) { diff --git a/nezha-fronted/src/components/common/rightBox/chart/systemChartConfig.vue b/nezha-fronted/src/components/common/rightBox/chart/systemChartConfig.vue index 3e185abfb..b63ea91fc 100644 --- a/nezha-fronted/src/components/common/rightBox/chart/systemChartConfig.vue +++ b/nezha-fronted/src/components/common/rightBox/chart/systemChartConfig.vue @@ -157,28 +157,92 @@ - + + + + + + + + + + + + + + + + + + +
+

{{$t(item.name)}}

+
+ +

{{$t('dashboard.dashboard.chartForm.singleColorMsg')}}

+
+
+ - - - - - -
-
- - - - - - - - -
-
+ - - - - +
+
@@ -1010,7 +1023,7 @@ import chartTypeShow from '@/components/common/rightBox/chart/chartTypeShow' import nezhaColor from '@/components/common/nezhaColor' import filterSearch from '@/components/common/filterSearch/filterSearch.vue' import VueTagsInput from '@johmun/vue-tags-input' -import { isGauge } from '@/components/chart/chart/tools' +import { isGauge, initColor } from '@/components/chart/chart/tools' import draggable from 'vuedraggable' export default { name: 'systemChartConfig', @@ -1146,13 +1159,20 @@ export default { break } this.chartConfig.param = { + min: undefined, + max: undefined, + color: { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + }, nullType: this.chartConfig.param.nullType, link: this.chartConfig.param.link, statistics: 'last', text: 'value', valueMapping: [], - min: 0, - max: 100, enable: { legend: true, valueMapping: false, @@ -1180,14 +1200,21 @@ export default { break } this.chartConfig.param = { + min: undefined, + max: undefined, + color: { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + }, nullType: this.chartConfig.param.nullType, link: this.chartConfig.param.link, statistics: 'last', text: 'value', valueMapping: [], legend: { placement: 'bottom', values: [], show: true }, - min: 0, - max: 100, enable: { legend: true, valueMapping: false, diff --git a/nezha-fronted/src/components/page/dashboard/dashboard.vue b/nezha-fronted/src/components/page/dashboard/dashboard.vue index 9ac2eea88..490b5632e 100644 --- a/nezha-fronted/src/components/page/dashboard/dashboard.vue +++ b/nezha-fronted/src/components/page/dashboard/dashboard.vue @@ -174,7 +174,7 @@ import panelVariables from '@/components/common/panel/panelVariables' import snapshotProgress from '@/components/common/snapshotProgress/snapshotProgress.vue' import dashboardTempBox from '@/components/common/rightBox/dashboardTempBox' import playlist from '@/components/common/playlist' - +import { initColor } from '@/components/chart/chart/tools' // import FileSaver from 'file-saver' // import chartData from './testData' export default { @@ -236,6 +236,15 @@ export default { height: 2, unit: 2, param: { + min: undefined, + max: undefined, + color: { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + }, stack: 0, nullType: 'null', legend: { placement: 'bottom', values: [], show: true }, @@ -268,7 +277,7 @@ export default { tooltip: { mode: 'all', sort: 'none' - }, + } }, elements: [{ expression: '', legend: '', type: 'expert', id: '', name: 'A', state: 1, orderNum: 0, step: undefined, queryType: 1 }], panel: '', @@ -359,7 +368,7 @@ export default { { value: 60, label: '1m' }, { value: 300, label: '5m' }, { value: 900, label: '15m' }, - { value: 1800, label: '30m' }, + { value: 1800, label: '30m' } ], playListControls: false, // 显示隐藏轮播按钮 playlistObj: {} // 轮播仪表盘配置 diff --git a/nezha-fronted/src/components/page/dashboard/explore/exploreItem.vue b/nezha-fronted/src/components/page/dashboard/explore/exploreItem.vue index bc5ec5790..c55d7fc7e 100644 --- a/nezha-fronted/src/components/page/dashboard/explore/exploreItem.vue +++ b/nezha-fronted/src/components/page/dashboard/explore/exploreItem.vue @@ -3675,7 +3675,7 @@ import './promqlparser/wasm_exec.js' import draggable from 'vuedraggable' import lineData from '@/components/chart/defaultLineData' import logData from '@/components/chart/defaultLogData' - +import { initColor } from '@/components/chart/chart/tools' export default { name: 'exploreItem', components: { @@ -4644,6 +4644,15 @@ export default { height: 2, unit: 2, param: { + min: undefined, + max: undefined, + color: { + schemeType: 'palette', + mode: 'palette', + paletteColors: initColor(20), + fixedColor: '', + continuousType: '' + }, stack: 0, nullType: 'null', legend: {