This is an automated email from the ASF dual-hosted git repository.

Justin-ZS pushed a commit to branch codex/fix-21613-piecewise-visual-meta
in repository https://gitbox.apache.org/repos/asf/echarts.git

commit 337a65d1c1721ad5dd17457c7148bdc6911d7731
Author: Justin-ZS <[email protected]>
AuthorDate: Tue Jun 2 16:32:22 2026 +0800

    fix(visualMap): preserve piecewise visual meta bounds. close #18066
---
 src/chart/line/LineView.ts                         |  8 +++-
 src/component/visualMap/PiecewiseModel.ts          | 10 ++---
 test/ut/spec/component/visualMap/setOption.test.ts | 49 +++++++++++++++++++++-
 3 files changed, 59 insertions(+), 8 deletions(-)

diff --git a/src/chart/line/LineView.ts b/src/chart/line/LineView.ts
index 847a87649..5a344e851 100644
--- a/src/chart/line/LineView.ts
+++ b/src/chart/line/LineView.ts
@@ -323,7 +323,10 @@ function getVisualGradient(
     const stopLen = colorStops.length;
     const outerColors = visualMeta.outerColors.slice();
 
-    if (stopLen && colorStops[0].coord > colorStops[stopLen - 1].coord) {
+    const coordExtent = axis.getExtent();
+    const isCoordReversed = axis.toGlobalCoord(coordExtent[0]) > 
axis.toGlobalCoord(coordExtent[1]);
+
+    if (stopLen && isCoordReversed) {
         colorStops.reverse();
         outerColors.reverse();
     }
@@ -337,6 +340,9 @@ function getVisualGradient(
             ? (outerColors[1] ? outerColors[1] : colorStops[stopLen - 1].color)
             : (outerColors[0] ? outerColors[0] : colorStops[0].color);
     }
+    if (!inRangeStopLen) {
+        return outerColors[0] || outerColors[1];
+    }
 
     const tinyExtent = 10; // Arbitrary value: 10px
     const minCoord = colorStopsInRange[0].coord - tinyExtent;
diff --git a/src/component/visualMap/PiecewiseModel.ts 
b/src/component/visualMap/PiecewiseModel.ts
index ef5913a62..36d151248 100644
--- a/src/component/visualMap/PiecewiseModel.ts
+++ b/src/component/visualMap/PiecewiseModel.ts
@@ -373,14 +373,14 @@ class PiecewiseModel extends 
VisualMapModel<PiecewiseVisualMapOption> {
             if (interval[0] === -Infinity) {
                 outerColors[0] = color;
             }
-            else if (interval[1] === Infinity) {
+            else {
+                stops.push({value: interval[0], color: color});
+            }
+            if (interval[1] === Infinity) {
                 outerColors[1] = color;
             }
             else {
-                stops.push(
-                    {value: interval[0], color: color},
-                    {value: interval[1], color: color}
-                );
+                stops.push({value: interval[1], color: color});
             }
         }
 
diff --git a/test/ut/spec/component/visualMap/setOption.test.ts 
b/test/ut/spec/component/visualMap/setOption.test.ts
index 05d9c58c8..b7a0aa63a 100755
--- a/test/ut/spec/component/visualMap/setOption.test.ts
+++ b/test/ut/spec/component/visualMap/setOption.test.ts
@@ -23,7 +23,7 @@ import { EChartsType } from '../../../../../src/echarts';
 import { EChartsOption } from '../../../../../src/export/option';
 import { ContinuousVisualMapOption } from 
'../../../../../src/component/visualMap/ContinuousModel';
 import { PiecewiseVisualMapOption } from 
'../../../../../src/component/visualMap/PiecewiseModel';
-import VisualMapModel from 
'../../../../../src/component/visualMap/VisualMapModel';
+import VisualMapModel, { VisualMeta } from 
'../../../../../src/component/visualMap/VisualMapModel';
 import globalDefault from '../../../../../src/model/globalDefault';
 
 
@@ -287,4 +287,49 @@ describe('vsiaulMap_setOption', function () {
         done();
     });
 
-});
\ No newline at end of file
+    it('piecewiseLineVisualMetaWithInfiniteBounds', function (done) {
+        expect(function () {
+            chart.setOption({
+                xAxis: {type: 'category', data: ['A', 'B', 'C', 'D']},
+                yAxis: {type: 'value'},
+                visualMap: {
+                    type: 'piecewise',
+                    dimension: 1,
+                    pieces: [{lte: null, color: 'red'}]
+                },
+                series: [{
+                    type: 'line',
+                    data: [['A', 4], ['B', 8], ['C', 18], ['D', 24]]
+                }]
+            });
+        }).not.toThrow();
+
+        let visualMeta = 
getECModel(chart).getSeriesByIndex(0).getData().getVisual('visualMeta') as 
VisualMeta[];
+        expect(visualMeta[0].stops).toEqual([]);
+        expect(visualMeta[0].outerColors).toEqual(['red', 'red']);
+
+        chart.clear();
+        chart.setOption({
+            xAxis: {type: 'category', data: ['A', 'B', 'C', 'D']},
+            yAxis: {type: 'value'},
+            visualMap: {
+                type: 'piecewise',
+                dimension: 1,
+                pieces: [{lte: 10, color: 'red'}],
+                outOfRange: {color: '#2563eb'}
+            },
+            series: [{
+                type: 'line',
+                data: [['A', 4], ['B', 8], ['C', 18], ['D', 24]]
+            }]
+        });
+
+        visualMeta = 
getECModel(chart).getSeriesByIndex(0).getData().getVisual('visualMeta') as 
VisualMeta[];
+        expect(visualMeta[0].stops.map(stop => stop.value)).toEqual([10, 10]);
+        expect(visualMeta[0].stops[0].color).toEqual('red');
+        expect(visualMeta[0].stops[1].color).toEqual('rgba(37,99,235,1)');
+        expect(visualMeta[0].outerColors).toEqual(['red', 
'rgba(37,99,235,1)']);
+        done();
+    });
+
+});


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to