fix(图表): 修复线面图开启缩略轴时,纵轴最小值不立即自动计算的问题

This commit is contained in:
jianneng-fit2cloud
2025-07-24 09:34:41 +08:00
committed by jianneng-fit2cloud
parent 780426205a
commit 5f547c2201
3 changed files with 86 additions and 75 deletions

View File

@@ -1,6 +1,8 @@
import { find } from 'lodash-es'
import { useI18n } from '@/hooks/web/useI18n'
import { getLocale } from '@/utils/utils'
import { parseJson } from '@/views/chart/components/js/util'
const { t } = useI18n()
export const isEnLocal = !['zh', 'zh-cn', 'zh-CN', 'tw'].includes(getLocale())
@@ -166,7 +168,7 @@ function transSeparatorAndSuffix(value, formatter) {
* @param max
* @param tickCount
*/
export const niceMin = (min, max, tickCount = 5) => {
function niceMin(min, max, tickCount = 5) {
// 数据的总跨度
const range = max - min
// 将范围均分为 tickCount-1 份, 得到每份的粗略步长
@@ -181,3 +183,72 @@ export const niceMin = (min, max, tickCount = 5) => {
// 将 min 向下取整到 niceStep 的整数倍,得到一个更整齐的起始值
return Math.floor(min / niceStep) * niceStep
}
/**
* 监听图例、缩略轴事件计算y轴的nice最小刻度值
* @param chart
* @param newChart
*/
export const listenYAxisNiceMinEvents = (chart: Chart, newChart) => {
const yAxis = parseJson(chart.customStyle).yAxis
if (yAxis.axisValue?.auto) {
newChart.on('legend-item-group:click', e => {
if (e.view?.options?.scales) {
const values = e.view.filteredData
.map(d => d.value)
?.filter(v => v !== null && v !== undefined)
const min = Math.min(...values)
const max = Math.max(...values)
e.view.options.scales.value.min = niceMin(min, max)
e.view.render(true)
}
})
newChart.on('slider:valuechanged', ev => {
const values = ev.view.filteredData
.map(d => d.value)
?.filter(v => v !== null && v !== undefined)
const min = Math.min(...values)
const max = Math.max(...values)
if (max !== min) {
ev.view.options.scales.value.min = niceMin(min, max)
}
})
}
}
/**
* 计算数据min值的nice值
* @param chart
* @param options
* @param tmpOptions
*/
export const calcNiceMinValue = (chart, options, tmpOptions) => {
let filteredData
let cfg
const senior = parseJson(chart.senior)
if (senior.functionCfg && senior.functionCfg.sliderShow) {
cfg = {
start: senior.functionCfg.sliderRange[0] / 100,
end: senior.functionCfg.sliderRange[1] / 100
}
}
const data = options.data || []
filteredData = data
// 如果有缩略轴,则取缩略轴范围
if (cfg && cfg.start !== undefined && cfg.end !== undefined) {
const startIndex = Math.floor(cfg.start * data.length)
const endIndex = Math.ceil(cfg.end * data.length)
filteredData = data.slice(startIndex, endIndex)
}
const values = filteredData.map(d => d.value)?.filter(v => v !== null && v !== undefined)
const min = Math.min(...values)
const max = Math.max(...values)
const niceMinValue = niceMin(min, max)
const axis = {
yAxis: {
...tmpOptions.yAxis,
min: niceMinValue
}
}
return { ...tmpOptions, ...axis }
}

View File

@@ -19,7 +19,11 @@ import {
parseJson,
setUpStackSeriesColor
} from '@/views/chart/components/js/util'
import { niceMin, valueFormatter } from '@/views/chart/components/js/formatter'
import {
calcNiceMinValue,
listenYAxisNiceMinEvents,
valueFormatter
} from '@/views/chart/components/js/formatter'
import {
LINE_AXIS_TYPE,
LINE_EDITOR_PROPERTY,
@@ -126,30 +130,7 @@ export class Area extends G2PlotChartView<AreaOptions, G2Area> {
newChart.on('point:click', action)
extremumEvt(newChart, chart, options, container)
configPlotTooltipEvent(chart, newChart)
const yAxis = parseJson(chart.customStyle).yAxis
if (yAxis.axisValue?.auto) {
newChart.on('legend-item-group:click', e => {
if (e.view?.options?.scales) {
const values = e.view.filteredData
.map(d => d.value)
?.filter(v => v !== null && v !== undefined)
const min = Math.min(...values)
const max = Math.max(...values)
e.view.options.scales.value.min = niceMin(min, max)
e.view.render(true)
}
})
newChart.on('slider:valuechanged', ev => {
const values = ev.view.filteredData
.map(d => d.value)
?.filter(v => v !== null && v !== undefined)
const min = Math.min(...values)
const max = Math.max(...values)
if (max !== min) {
ev.view.options.scales.value.min = niceMin(min, max)
}
})
}
listenYAxisNiceMinEvents(chart, newChart)
return newChart
}
@@ -295,18 +276,7 @@ export class Area extends G2PlotChartView<AreaOptions, G2Area> {
return { ...tmpOptions, ...axis }
}
if (axisValue?.auto) {
const data = options.data || []
const values = data.map(d => d.value)?.filter(v => v !== null && v !== undefined)
const min = Math.min(...values)
const max = Math.max(...values)
const niceMinValue = niceMin(min, max)
const axis = {
yAxis: {
...tmpOptions.yAxis,
min: niceMinValue
}
}
return { ...tmpOptions, ...axis }
return calcNiceMinValue(chart, options, tmpOptions)
}
return tmpOptions
}

View File

@@ -20,7 +20,11 @@ import {
setUpGroupSeriesColor
} from '@/views/chart/components/js/util'
import { cloneDeep, defaults, isEmpty } from 'lodash-es'
import { niceMin, valueFormatter } from '@/views/chart/components/js/formatter'
import {
calcNiceMinValue,
listenYAxisNiceMinEvents,
valueFormatter
} from '@/views/chart/components/js/formatter'
import {
LINE_AXIS_TYPE,
LINE_EDITOR_PROPERTY,
@@ -130,30 +134,7 @@ export class Line extends G2PlotChartView<LineOptions, G2Line> {
newChart.on('point:click', action)
extremumEvt(newChart, chart, options, container)
configPlotTooltipEvent(chart, newChart)
const yAxis = parseJson(chart.customStyle).yAxis
if (yAxis.axisValue?.auto) {
newChart.on('legend-item-group:click', e => {
if (e.view?.options?.scales) {
const values = e.view.filteredData
.map(d => d.value)
?.filter(v => v !== null && v !== undefined)
const min = Math.min(...values)
const max = Math.max(...values)
e.view.options.scales.value.min = niceMin(min, max)
e.view.render(true)
}
})
newChart.on('slider:valuechanged', ev => {
const values = ev.view.filteredData
.map(d => d.value)
?.filter(v => v !== null && v !== undefined)
const min = Math.min(...values)
const max = Math.max(...values)
if (max !== min) {
ev.view.options.scales.value.min = niceMin(min, max)
}
})
}
listenYAxisNiceMinEvents(chart, newChart)
return newChart
}
@@ -276,18 +257,7 @@ export class Line extends G2PlotChartView<LineOptions, G2Line> {
return { ...tmpOptions, ...axis }
}
if (axisValue?.auto) {
const data = options.data || []
const values = data.map(d => d.value)?.filter(v => v !== null && v !== undefined)
const min = Math.min(...values)
const max = Math.max(...values)
const niceMinValue = niceMin(min, max)
const axis = {
yAxis: {
...tmpOptions.yAxis,
min: niceMinValue
}
}
return { ...tmpOptions, ...axis }
return calcNiceMinValue(chart, options, tmpOptions)
}
return tmpOptions
}