From b0a5fb2efcc9cb51235633ce7ffdf010cce24f00 Mon Sep 17 00:00:00 2001 From: aloktomarr Date: Fri, 17 Jul 2026 18:21:20 +0530 Subject: [PATCH] fix(marker): skip invalid markLine data items instead of crashing the render. close #21683 --- src/component/marker/MarkLineView.ts | 7 ++ .../ut/spec/component/marker/MarkLine.test.ts | 67 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 test/ut/spec/component/marker/MarkLine.test.ts diff --git a/src/component/marker/MarkLineView.ts b/src/component/marker/MarkLineView.ts index 9ee9aa43d0..2a1092e48b 100644 --- a/src/component/marker/MarkLineView.ts +++ b/src/component/marker/MarkLineView.ts @@ -175,6 +175,13 @@ function markLineFilter( coordSys: CoordinateSystem, item: MarkLine2DDataItemOption ) { + // An invalid entry in `markLine.data` (e.g. an empty object `{}`) is + // normalized to undefined endpoints. Such a markLine cannot be drawn, so + // drop it here instead of dereferencing `undefined.coord` and throwing, + // which would abort rendering of all the other markLines. See #21683. + if (!item[0] || !item[1]) { + return false; + } if (coordSys.type === 'cartesian2d') { const fromCoord = item[0].coord; const toCoord = item[1].coord; diff --git a/test/ut/spec/component/marker/MarkLine.test.ts b/test/ut/spec/component/marker/MarkLine.test.ts new file mode 100644 index 0000000000..479d5e38b9 --- /dev/null +++ b/test/ut/spec/component/marker/MarkLine.test.ts @@ -0,0 +1,67 @@ +/* +* 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, getECModel } from '../../../core/utHelper'; +import { EChartsType } from '../../../../../src/echarts'; +import MarkerModel from '../../../../../src/component/marker/MarkerModel'; + +describe('component/markLine', function () { + + let chart: EChartsType; + beforeEach(function () { + chart = createChart(); + }); + + afterEach(function () { + chart.dispose(); + }); + + // Regression test for #21683: an empty/invalid entry (e.g. `{}`) inside + // `markLine.data` used to throw "Cannot read properties of undefined + // (reading 'coord')" in markLineFilter, which aborted rendering of ALL + // markLines. It should instead be ignored while the valid markLines render. + it('ignores an empty markLine data item and still renders the valid ones (#21683)', function () { + function setInvalidMarkLine() { + chart.setOption({ + xAxis: { type: 'category', data: ['A', 'B', 'C', 'D', 'E'] }, + yAxis: { type: 'value' }, + series: [{ + type: 'bar', + data: [1, 2, 3, 4, 5], + markLine: { + data: [ + { yAxis: 1 }, + {}, // invalid / empty entry + { yAxis: 3 } + ] + } + }] + }); + } + + expect(setInvalidMarkLine).not.toThrow(); + + // The two valid markLines should still be rendered; the empty one dropped. + const seriesModel = getECModel(chart).getSeriesByIndex(0); + const markLineModel = MarkerModel.getMarkerModelFromSeries(seriesModel, 'markLine'); + expect(markLineModel).toBeTruthy(); + expect(markLineModel.getData().count()).toBe(2); + }); + +});