diff --git a/nezha-fronted/src/components/chart/chart/legend.vue b/nezha-fronted/src/components/chart/chart/legend.vue index 0157b04c6..719ab46d7 100644 --- a/nezha-fronted/src/components/chart/chart/legend.vue +++ b/nezha-fronted/src/components/chart/chart/legend.vue @@ -157,51 +157,27 @@ export default { this.clickLegendD3(legendName, index, hasGrey, curIsGrey, currentIsTheOnlyOneHighlight) return } - if (echarts) { - // 判断timeSeries类型图表 先取消多表联动 - if (this.isTimeSeries && (this.isConnect && this.isConnect !== 'none')) { - chart.disconnect('timeSeriesGroup') - } if (!hasGrey) { // 1.除当前legend外全置灰 - echarts.dispatchAction({ - type: 'legendInverseSelect' - }) - echarts.dispatchAction({ - type: 'legendSelect', - name: legendName + echarts.series.forEach((seriesItem, sindex) => { + if (sindex > 0) { + seriesItem.show = false + } }) + echarts.series[index + 1].show = !echarts.series[index + 1].show this.isGrey = this.isGrey.map((g, i) => i !== index) } else if (currentIsTheOnlyOneHighlight) { // 2.全高亮 - echarts.dispatchAction({ - type: 'legendAllSelect' + echarts.series.forEach((seriesItem, sindex) => { + if (sindex > 0) { + echarts.series[sindex].show = true + } }) this.isGrey = this.isGrey.map(() => false) } else { - const type = curIsGrey ? 'legendSelect' : 'legendUnSelect' - echarts.dispatchAction({ - type: type, - name: legendName - }) + echarts.series[index + 1].show = !echarts.series[index + 1].show this.$set(this.isGrey, index, !this.isGrey[index]) } - if (this.isTimeSeries) { - this.$parent.legendChange(this.isGrey) - } - // 点击后 处理Y轴的刻度边的 - const chartInfo = this.chartInfo - const series = this.$lodash.cloneDeep(this.series) - const dataArg = series.filter((seriesItem, seriesIndex) => !this.isGrey[seriesIndex]) - const option = this.renderYAxis(dataArg, chartInfo, 'legend') - getChart(this.chartId) && getChart(this.chartId).setOption({ - yAxis: [ - ...option.yAxis - ] - }) - // 判断timeSeries类型图表 建立多表联动 - if (this.isTimeSeries && (this.isConnect && this.isConnect !== 'none')) { - chart.connect('timeSeriesGroup') - } + echarts.redraw() } }, clickLegendBar (legendName, index, hasGrey, curIsGrey, currentIsTheOnlyOneHighlight) { @@ -271,6 +247,7 @@ export default { if (this.isGrey[index]) { return false } + return if (this.chartInfo.type === 'pie' || this.chartInfo.type === 'doughnut' || this.chartInfo.type === 'rose') { this.$emit('hoverLegendD3', legendName, index, type) } else if (this.isTimeSeries) { diff --git a/nezha-fronted/src/components/chart/chart/tools.js b/nezha-fronted/src/components/chart/chart/tools.js index 7771bd72e..c642dfece 100644 --- a/nezha-fronted/src/components/chart/chart/tools.js +++ b/nezha-fronted/src/components/chart/chart/tools.js @@ -203,3 +203,11 @@ export function initColor (colorNum = 20) { } return colorList } +export function initIncrs () { + const arr = [] + for (let i = 0; i < 53; i++) { + arr.push(Math.pow(2, i)) + } + return arr +} +export const Incrs = initIncrs() diff --git a/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeries.vue b/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeries.vue index 44649d41a..17150cd98 100644 --- a/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeries.vue +++ b/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeries.vue @@ -15,6 +15,7 @@ v == null ? null : v.toFixed(2) + ' MB', - stroke: 'green', - width: 1 / devicePixelRatio - } + } ], axes: [ {}, { - scale: 'mb', - values: (u, vals, space) => vals.map(v => +v.toFixed(2) + ' MB') + scale: 'left', + values: (u, vals, space) => vals.map(v => leftUnitCompute.compute(v, null, -1, decimals)), + formatValue: (v, d) => { + console.log(v, d, 'vd') + return v + }, + incrs: incrs, + size (self, values, axisIdx, cycleNum) { + const axis = self.axes[axisIdx] + + // bail out, force convergence + if (cycleNum > 1) { return axis._size } + + let axisSize = axis.ticks.size + axis.gap + + // find longest value + const longestVal = (values ?? []).reduce((acc, val) => ( + val.length > acc.length ? val : acc + ), '') + + if (longestVal != '') { + self.ctx.font = axis.font[0] + axisSize += self.ctx.measureText(longestVal).width / devicePixelRatio + } + + return Math.ceil(axisSize) + } } ] } - const seriesData = this.initSeriesData(this.chartData) - const data = [ - this.chartData[0][0].values.map(item => item[0]), - this.chartData[0][0].values.map(item => Number(item[1]) / 1000000).splice(0, 20) - ] - console.log(data) - this.chart = new UPlot(opts, data, document.getElementById(`chart-canvas-${this.chartId}`)) + const { seriesData, seriesAll } = this.initSeriesData(this.chartData) + console.log(seriesData, seriesAll) + const data = seriesData + opts.series.push(...seriesAll) + this.series = seriesAll + setTimeout(() => { // 延迟加载 保证legend的高度正常 + const dom = document.getElementById(`chart-canvas-${this.chartId}`) + const width = dom.offsetWidth + const height = dom.offsetHeight + console.log(width, height) + opts.width = width + opts.height = height + this.chart = new UPlot(opts, data, document.getElementById(`chart-canvas-${this.chartId}`)) + setChart(this.chartId, this.chart) + }, 100) + }, + size (self, values, axisIdx, cycleNum) { + const axis = self.axes[axisIdx] + + // bail out, force convergence + if (cycleNum > 1) { return axis._size } + + let axisSize = axis.ticks.size + axis.gap + + // find longest value + const longestVal = (values ?? []).reduce((acc, val) => ( + val.length > acc.length ? val : acc + ), '') + + if (longestVal != '') { + self.ctx.font = axis.font[0] + axisSize += self.ctx.measureText(longestVal).width / devicePixelRatio + } + + return Math.ceil(axisSize) + }, + autoPadRight (self, side, sidesWithAxes, cycleNum) { + const xAxis = self.axes[0] + + const xVals = xAxis._values + + if (xVals != null) { + // bail out, force convergence + if (cycleNum > 2) { return self._padding[1] } + + const xSplits = xAxis._splits + const rightSplit = xSplits[xSplits.length - 1] + const rightSplitCoord = self.valToPos(rightSplit, 'x') + const leftPlotEdge = (self.bbox.left / devicePixelRatio) + const rightPlotEdge = leftPlotEdge + (self.bbox.width / devicePixelRatio) + const rightChartEdge = rightPlotEdge + self._padding[1] + + const pxPerChar = 8 + const rightVal = xVals[xVals.length - 1] + '' + const valHalfWidth = pxPerChar * (rightVal.length / 2) + + const rightValEdge = leftPlotEdge + rightSplitCoord + valHalfWidth + + if (rightValEdge >= rightChartEdge) { + return rightValEdge - rightPlotEdge + } + } + + // default size + return 8 }, clickout () { if (this.toolbox.show) { diff --git a/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeriesMixin.js b/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeriesMixin.js index 07fbe174a..1cdf7b8f9 100644 --- a/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeriesMixin.js +++ b/nezha-fronted/src/components/chart/chart/uplot/chartTimeSeriesMixin.js @@ -1,12 +1,78 @@ +import { initColor, Incrs } from '@/components/chart/chart/tools' +import { randomcolor } from '@/components/common/js/radomcolor/randomcolor' +import chartDataFormat from '@/components/chart/chartDataFormat' export default { + data () { + return { + seriesColor: initColor(), + incrs: Incrs + } + }, methods: { - initSeriesData (chartData) { - const time = [] - const seriesData = [] + initSeriesData (chartData) { // 处理数据 以及 series + let time = [] + const seriesData = [] // 返回的数据 + const seriesAll = [ // 返回的 series + + ] + let chartIndex = 0 chartData.forEach(series => { // 首先处理时间 对应点没有值(不包括null 则添加undefind) - console.log(series); + series.forEach(item => { + time.push(...item.values.map(value => value[0])) + }) }) - return seriesData + const timeSet = new Set(time) + time = [...timeSet] + time = this.$lodash.sortBy(time, function (o) { return o }) + const ObjTime = {} + time.forEach(item => { + ObjTime[item] = undefined + }) + chartData.forEach(series => { // 首先处理时间 对应点没有值(不包括null 则添加undefind) + series.forEach(item => { + let seriesObjTime = {} + item.values.forEach(value => { + seriesObjTime[value[0]] = value[1] + }) + // 处理统计数据 statistics + seriesObjTime = { + ...ObjTime, + ...seriesObjTime + } + console.log(seriesObjTime, seriesObjTime) + seriesData.push(Object.keys(seriesObjTime).map(time => seriesObjTime[time])) + seriesAll.push(this.renderSeries(item, chartIndex)) + chartIndex++ + }) + }) + seriesData.unshift(time) + return { + seriesData, + seriesAll + } + }, + renderSeries (series, 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 obj = { + name: series.elements.name + JSON.stringify(series.metric), + label: series.elements.name + JSON.stringify(series.metric), + class: series.elements.name + JSON.stringify(series.metric), + scale: 'left', // right + // value: (u, v) => v == null ? null : (!v ? v : leftUnitCompute.compute(v, null, -1, decimals)), + values: (u, v) => series.elements.name + JSON.stringify(series.metric), + stroke: this.seriesColor[chartIndex], + width: 1 / devicePixelRatio + } + const name = series.elements.name + JSON.stringify(series.metric) + const alias = series.elements.name + JSON.stringify(series.metric) + const statistics = series.statistics + this.legends.push({ name, alias, statistics, color: this.seriesColor[chartIndex] }) + return obj } } } diff --git a/nezha-fronted/src/components/chart/chartMixin.js b/nezha-fronted/src/components/chart/chartMixin.js index ef546147f..d143d23bf 100644 --- a/nezha-fronted/src/components/chart/chartMixin.js +++ b/nezha-fronted/src/components/chart/chartMixin.js @@ -326,15 +326,6 @@ export default { }, mouseEnterChart () { const myChart = getChart(this.chartId) - if (myChart) { - setTimeout(() => { - myChart.setOption({ - toolbox: { - show: true - } - }) - }, 300) - } }, tooltipPosition (point, params, dom, rect, size) { if (this.isConnect === 'tooltip' && this.$store.state.panel.currentMousemove != this.chartId) { @@ -370,15 +361,6 @@ export default { }, mouseLeaveChart () { const myChart = getChart(this.chartId) - if (myChart) { - setTimeout(() => { - myChart.setOption({ - toolbox: { - show: false - } - }) - }, 300) - } }, getMaxValue (dataArg, chartInfo) { let maxValue = 0