From 46fb6bb07fa6db716e374be395f409dac55c2355 Mon Sep 17 00:00:00 2001 From: water <672684719@qq.com> Date: Tue, 11 Aug 2026 08:36:29 +0800 Subject: [PATCH] fix(candlestick/boxplot): resolve base axis correctly when series uses xAxisId/yAxisId fix #21725 --- src/chart/helper/whiskerBoxCommon.ts | 11 +- test/ut/spec/series/whiskerBoxCommon.test.ts | 105 +++++++++++++++++++ 2 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 test/ut/spec/series/whiskerBoxCommon.test.ts diff --git a/src/chart/helper/whiskerBoxCommon.ts b/src/chart/helper/whiskerBoxCommon.ts index faa15d6b7c..baa112f8d4 100644 --- a/src/chart/helper/whiskerBoxCommon.ts +++ b/src/chart/helper/whiskerBoxCommon.ts @@ -29,6 +29,7 @@ import type SeriesData from '../../data/SeriesData'; import type Axis2D from '../../coord/cartesian/Axis2D'; import { CoordDimensionDefinition } from '../../data/helper/createDimensions'; import { CoordinateSystemClipArea } from '../../coord/CoordinateSystem'; +import { SINGLE_REFERRING } from '../../util/model'; import { SHAPE_CLIP_KIND_FULLY_CLIPPED, SHAPE_CLIP_KIND_NOT_CLIPPED, SHAPE_CLIP_KIND_PARTIALLY_CLIPPED, ShapeClipKind @@ -79,8 +80,8 @@ export class WhiskerBoxCommonMixin { let ordinalMeta; - const xAxisModel = ecModel.getComponent('xAxis', this.get('xAxisIndex')) as CartesianAxisModel; - const yAxisModel = ecModel.getComponent('yAxis', this.get('yAxisIndex')) as CartesianAxisModel; + const xAxisModel = this.getReferringComponents('xAxis', SINGLE_REFERRING).models[0] as CartesianAxisModel; + const yAxisModel = this.getReferringComponents('yAxis', SINGLE_REFERRING).models[0] as CartesianAxisModel; const xAxisType = xAxisModel.get('type'); const yAxisType = yAxisModel.get('type'); let addOrdinal; @@ -178,9 +179,9 @@ export class WhiskerBoxCommonMixin { */ getBaseAxis(): Axis2D { const dim = this._baseAxisDim; - return (this.ecModel.getComponent( - dim + 'Axis', this.get(dim + 'AxisIndex' as 'xAxisIndex' | 'yAxisIndex') - ) as CartesianAxisModel).axis; + return (this.getReferringComponents( + dim + 'Axis', SINGLE_REFERRING + ).models[0] as CartesianAxisModel).axis; } getWhiskerBoxesLayout() { diff --git a/test/ut/spec/series/whiskerBoxCommon.test.ts b/test/ut/spec/series/whiskerBoxCommon.test.ts new file mode 100644 index 0000000000..99d8803d97 --- /dev/null +++ b/test/ut/spec/series/whiskerBoxCommon.test.ts @@ -0,0 +1,105 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +import { createChart } from '../../core/utHelper'; + +describe('whiskerBoxCommon (candlestick/boxplot)', function () { + + it('should resolve the correct base axis when series refers axis by id', function () { + const chart = createChart({width: 400, height: 300}); + + try { + const data = [ + [0, 317.3413, 327.2178, 317.0466, 328.4467], + [1, 327.7224, 332.9728, 326.5084, 334.3916], + [2, 331.6939, 333.4524, 328.7171, 334.7013] + ]; + + chart.setOption({ + animation: false, + xAxis: [ + { id: 'main-x', type: 'value', gridIndex: 0 }, + { id: 'second-x', type: 'value', gridIndex: 1 } + ], + yAxis: [ + { type: 'value', id: 'main-y', gridIndex: 0, min: 300, max: 340 }, + { type: 'value', id: 'second-y', gridIndex: 1, min: 300, max: 340 } + ], + grid: [ + { id: 'main-grid', top: '5%', height: '35%' }, + { id: 'second-grid', top: '50%', height: '35%' } + ], + series: [ + { id: 's1', xAxisId: 'main-x', yAxisId: 'main-y', type: 'candlestick', data: data }, + { id: 's2', xAxisId: 'second-x', yAxisId: 'second-y', type: 'candlestick', data: data } + ] + }); + + const model = (chart as any).getModel(); + const series0 = model.getSeriesByIndex(0); + const series1 = model.getSeriesByIndex(1); + + // The base axis of series 0 should be the axis with id 'main-x' + const baseAxis0 = (series0 as any).getBaseAxis(); + expect(baseAxis0.model.option.id).toBe('main-x'); + + // The base axis of series 1 should be the axis with id 'second-x' + // (previously this incorrectly resolved to the first xAxis) + const baseAxis1 = (series1 as any).getBaseAxis(); + expect(baseAxis1.model.option.id).toBe('second-x'); + + // The base axis dims should differ (different axes), not both resolve to axis 0 + expect(baseAxis0.model.componentIndex).toBe(0); + expect(baseAxis1.model.componentIndex).toBe(1); + } + finally { + chart.dispose(); + } + }); + + it('should still fall back to the first axis when no index/id is specified', function () { + const chart = createChart({width: 400, height: 300}); + + try { + const data = [ + [317.3413, 327.2178, 317.0466, 328.4467], + [327.7224, 332.9728, 326.5084, 334.3916] + ]; + + chart.setOption({ + animation: false, + xAxis: { type: 'value' }, + yAxis: { type: 'value' }, + series: [ + { type: 'candlestick', data: data } + ] + }); + + const model = (chart as any).getModel(); + const series0 = model.getSeriesByIndex(0); + const baseAxis0 = (series0 as any).getBaseAxis(); + expect(baseAxis0.model.option.id).toBe(undefined); + expect(baseAxis0.model.componentIndex).toBe(0); + } + finally { + chart.dispose(); + } + }); + +}); \ No newline at end of file