diff --git a/nezha-fronted/package-lock.json b/nezha-fronted/package-lock.json index 034e95070..be7d108b9 100644 --- a/nezha-fronted/package-lock.json +++ b/nezha-fronted/package-lock.json @@ -22765,9 +22765,9 @@ "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" }, "tinycolor2": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", - "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==" + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" }, "tinyqueue": { "version": "2.0.3", diff --git a/nezha-fronted/package.json b/nezha-fronted/package.json index c43a287bd..e4cd21695 100644 --- a/nezha-fronted/package.json +++ b/nezha-fronted/package.json @@ -92,6 +92,7 @@ "showdown": "^2.1.0", "spark-md5": "^3.0.2", "speed-measure-webpack-plugin": "^1.5.0", + "tinycolor2": "^1.6.0", "uplot": "^1.6.26", "uplot-vue": "^1.1.5", "v-selectpage": "^2.1.4", diff --git a/nezha-fronted/src/assets/css/components/chart/chart.scss b/nezha-fronted/src/assets/css/components/chart/chart.scss index 2c900c840..70e505065 100644 --- a/nezha-fronted/src/assets/css/components/chart/chart.scss +++ b/nezha-fronted/src/assets/css/components/chart/chart.scss @@ -556,6 +556,10 @@ flex-grow: 1; position: relative; border: 1px solid $--background-color-empty; + .stat-text{ + text-align: center; + line-height: 1.2; + } .sparkline{ width: 100%; height: 40%; diff --git a/nezha-fronted/src/components/chart/chart/chartStat.vue b/nezha-fronted/src/components/chart/chart/chartStat.vue index a1b6fa02e..3f061271f 100644 --- a/nezha-fronted/src/components/chart/chart/chartStat.vue +++ b/nezha-fronted/src/components/chart/chart/chartStat.vue @@ -16,43 +16,52 @@ background:item.mapping ? item.mapping.color.bac : (statData.length===1 ? '' : colorList[index]), height:item.height+'px', width:item.width + 'px', - fontSize: item.fontSize + 'px', }" >
@@ -118,7 +127,7 @@
- + @@ -133,6 +142,7 @@ import { initColor } from '@/components/chart/chart/tools' import * as echarts from 'echarts' import chartSparklineOption from './options/chartSparkline' import lodash from 'lodash' +import tinycolor from 'tinycolor2' export default { name: 'chart-stat', mixins: [chartMixin, chartFormat], @@ -291,7 +301,6 @@ export default { }) }, renderStat (layout) { - let isDouble = false const width = this.boxWidth / layout.col const height = this.boxHeight / layout.row const integer = Math.floor(this.statData.length / layout.col) @@ -305,86 +314,62 @@ export default { } else { item.width = width } - let font = '' // 获取显示的字体 let display = '' if (item.mapping) { display = this.handleDisplay(item.mapping.display, { ...item.label, value: item.showValue }) } + let titleFont = '' + let valueFont = '' + let titleFontSize = '' + let valueFontSize = '' + const padding = 10 switch (this.chartInfo.param.text) { case 'all': + titleFont = item.legend if (item.mapping) { - isDouble = true - if (item.legend.length > item.showValue.length + 2) { - font = item.legend - } else { - font = display - if (item.mapping.icon) { - font += 'AA' - } + valueFont = display + if (item.mapping.icon) { + valueFont += 'AA' } } else { - isDouble = true - if (item.legend.length > item.showValue.length) { - font = item.legend - } else { - font = item.showValue - } + valueFont = item.showValue } + titleFontSize = this.calculateFontSize(titleFont, (item.width - padding * 2), (item.height - padding * 2) * 0.4, 30) + valueFontSize = this.calculateFontSize(valueFont, (item.width - padding * 2), (item.height - padding * 2) * 0.4) + titleFontSize = Math.min(valueFontSize * 0.7, titleFontSize) break case 'legend': + titleFont = item.legend if (item.mapping) { - isDouble = true - if (item.legend.length > item.showValue.length + 2) { - font = item.legend - } else { - font = display - if (item.mapping.icon) { - font += 'AA' - } + if (item.mapping.icon) { + titleFont += 'AA' } - } else { - font = item.legend } + valueFontSize = this.calculateFontSize(titleFont, (item.width - padding * 2), (item.height - padding * 2) * 0.4) break - case 'none': - font = '' + titleFontSize = '' + valueFontSize = '' break case 'value': default: if (item.mapping) { - font = display + valueFont = display if (item.mapping.icon) { - font += 'AA' + valueFont += 'AA' } } else { - font = item.showValue + valueFont = item.showValue } + valueFontSize = this.calculateFontSize(valueFont, (item.width - padding * 2), (item.height - padding * 2) * 0.4) break } - const el = this.$refs['temp-dom'] - el.innerText = font - const elWidth = el.offsetWidth - const elHeight = el.offsetHeight - const dimension = Math.min(item.width, item.height * 1.3) - const fontScale = parseInt('70%', 10) / 100 - let fontSize = Math.min(dimension / 5, 100) * fontScale - let scale = item.width / elWidth - if (scale * elHeight > item.height) { - scale = item.height / elHeight - } - if (isDouble) { - if (scale * elHeight * 2.5 > item.height) { - scale = item.height / elHeight * 2.5 - } - } - item.scale = scale < 1 ? 1 : parseFloat(scale) - fontSize = fontSize > 12 ? fontSize : this.minFontSzie - item.fontSize = fontSize + item.titleFontSize = titleFontSize + item.valueFontSize = valueFontSize - if (fontSize > 36) { + if (item.valueFontSize > 36) { item.comparisonFont = 16 - } else if (fontSize > 24) { + } else if (item.valueFontSize > 24) { item.comparisonFont = 14 } else { item.comparisonFont = 12 @@ -392,28 +377,43 @@ export default { }) this.isInit = false }, + + calculateFontSize (text, width, height, maxSize, lineHeight = 1.2) { + const el = this.$refs['temp-dom'] + el.innerText = text + const elWidth = el.offsetWidth + const fontSizeBasedOnWidth = (width / (elWidth + 2)) * 14 + const fontSizeBasedOnHeight = height / lineHeight + + const optimalSize = Math.min(fontSizeBasedOnHeight, fontSizeBasedOnWidth) + return Math.min(optimalSize, maxSize || optimalSize) + }, + // 绘制图表 drawChart () { this.statData.forEach((item, index) => { const chart = this.sparkline[index] ? this.sparkline[index] : echarts.init(document.getElementById(`chart-canvas-${this.chartId}-${index}`)) const chartOption = lodash.cloneDeep(chartSparklineOption) - // sparkline 颜色和 字体颜色 保持一致 - const theme = localStorage.getItem(`nz-user-${localStorage.getItem('nz-user-id')}-theme`) || 'light' - let color = theme === 'light' ? '#666666' : '#BEBEBE' - if (item.mapping) { - color = item.mapping.color.text + + // sparkline 颜色根据背景色计算 + const color = item.mapping ? item.mapping.color.bac : this.colorList[index] + const lineColor = tinycolor(color).brighten(40).toRgbString() + let areaColor = 'rgba(255,255,255,0.4)' + if (this.statData.length === 1 && !item.mapping) { + areaColor = tinycolor(color).setAlpha(0.2).toRgbString() } + chartOption.series = [{ ...chartOption.series[0], data: item.data, lineStyle: { - color + width: 1, + color: lineColor } }] if (this.chartInfo.param.sparklineMode === 'area') { chartOption.series[0].areaStyle = { - color: color, - opacity: 0.1 + color: areaColor } } chartOption.yAxis.max = this.maxValue