feat(图表): 线面图纵轴轴值自动挡的最小值,能够自动根据数据自动计算一个nice最小刻度值

This commit is contained in:
jianneng-fit2cloud
2025-07-23 17:20:02 +08:00
committed by jianneng-fit2cloud
parent 157f0ffcee
commit 780426205a
3 changed files with 106 additions and 2 deletions

View File

@@ -158,3 +158,26 @@ function transSeparatorAndSuffix(value, formatter) {
}
return str + formatter.suffix.replace(/(^\s*)|(\s*$)/g, '')
}
/**
* 根据最小值、最大值max和刻度数量tickCount
* 计算一个nice最小刻度值
* @param min
* @param max
* @param tickCount
*/
export const niceMin = (min, max, tickCount = 5) => {
// 数据的总跨度
const range = max - min
// 将范围均分为 tickCount-1 份, 得到每份的粗略步长
const roughStep = range / (tickCount - 1)
// 确定步长的数量级
// 取步长的 10 为底的对数,向下取整,得到步长的数量级
const exponent = Math.floor(Math.log10(roughStep))
// 将步长取整到nice的倍数如 1, 2, 5, 10, 20, 50...
const power = Math.pow(10, exponent)
// 从中找出第一个大于等于粗略步长的nice步长
const niceStep = [1, 2, 5, 10].map(mult => mult * power).find(step => step >= roughStep)
// 将 min 向下取整到 niceStep 的整数倍,得到一个更整齐的起始值
return Math.floor(min / niceStep) * niceStep
}

View File

@@ -19,7 +19,7 @@ import {
parseJson,
setUpStackSeriesColor
} from '@/views/chart/components/js/util'
import { valueFormatter } from '@/views/chart/components/js/formatter'
import { niceMin, valueFormatter } from '@/views/chart/components/js/formatter'
import {
LINE_AXIS_TYPE,
LINE_EDITOR_PROPERTY,
@@ -126,6 +126,30 @@ 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)
}
})
}
return newChart
}
@@ -270,6 +294,20 @@ 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 tmpOptions
}

View File

@@ -20,7 +20,7 @@ import {
setUpGroupSeriesColor
} from '@/views/chart/components/js/util'
import { cloneDeep, defaults, isEmpty } from 'lodash-es'
import { valueFormatter } from '@/views/chart/components/js/formatter'
import { niceMin, valueFormatter } from '@/views/chart/components/js/formatter'
import {
LINE_AXIS_TYPE,
LINE_EDITOR_PROPERTY,
@@ -34,6 +34,7 @@ import { Group } from '@antv/g-canvas'
const { t } = useI18n()
const DEFAULT_DATA = []
/**
* 折线图
*/
@@ -68,6 +69,7 @@ export class Line extends G2PlotChartView<LineOptions, G2Line> {
type: 'q'
}
}
async drawChart(drawOptions: G2PlotDrawOptions<G2Line>): Promise<G2Line> {
const { chart, action, container } = drawOptions
chart.container = container
@@ -128,6 +130,30 @@ 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)
}
})
}
return newChart
}
@@ -249,6 +275,20 @@ 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 tmpOptions
}
@@ -310,9 +350,11 @@ export class Line extends G2PlotChartView<LineOptions, G2Line> {
tooltip
}
}
public setupSeriesColor(chart: ChartObj, data?: any[]): ChartBasicStyle['seriesColor'] {
return setUpGroupSeriesColor(chart, data)
}
protected configLegend(chart: Chart, options: LineOptions): LineOptions {
const optionTmp = super.configLegend(chart, options)
if (!optionTmp.legend) {
@@ -420,6 +462,7 @@ export class Line extends G2PlotChartView<LineOptions, G2Line> {
}
return optionTmp
}
protected setupOptions(chart: Chart, options: LineOptions): LineOptions {
return flow(
this.configTheme,