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

sushuang pushed a commit to branch fix/matrix-label-api
in repository https://gitbox.apache.org/repos/asf/echarts.git

commit 1550ca23de290081be80976034fe43b153a5ac8f
Author: 100pah <[email protected]>
AuthorDate: Wed Jul 16 16:21:26 2025 +0800

    test(matrix): (1) Migrate (split) test case from `matrix2.html` to 
`matrix4.html`, as the previous is too long to visual test regression. (2) Fix 
test case for coordClamp.
---
 test/matrix.html                  |  12 +-
 test/matrix2.html                 | 592 +---------------------------------
 test/matrix3.html                 |   3 +-
 test/matrix4.html                 | 649 ++++++++++++++++++++++++++++++++++++++
 test/matrix_application.html      |   1 +
 test/runTest/actions/matrix2.json |   2 +-
 test/runTest/actions/matrix4.json |   1 +
 test/runTest/marks/matrix.json    |   8 +
 8 files changed, 677 insertions(+), 591 deletions(-)

diff --git a/test/matrix.html b/test/matrix.html
index c588c4d0c..66bd85322 100644
--- a/test/matrix.html
+++ b/test/matrix.html
@@ -69,12 +69,20 @@ under the License.
                         }],
                     },
                     y: {
-                        data: ['U', 'V']
+                        data: ['U', 'V', 'W']
                     },
                     body: {
                         itemStyle: {
                             // borderColor: '#333',
                         },
+                        data: [{
+                            coord: [['A2', 'A31', 'A32'], 'V'],
+                            mergeCells: true,
+                        }, {
+                            coord: [null, 'W'],
+                            clamp: true,
+                            mergeCells: true,
+                        }]
                     }
                 },
                 textStyle: {
@@ -98,7 +106,7 @@ under the License.
                     },
                     data: [
                         ['A1', 'U', 10], ['A1', 'V', 200], ['A2', 'U', 300],
-                        ['A2', 'V', 40], ['A31', 'U', 50], ['A3', 'V', 60]
+                        ['A2', 'V', 40], ['A31', 'U', 50], ['A3', 'V', 60], 
['A1', 'W', 80]
                     ],
                     label: {
                         show: true
diff --git a/test/matrix2.html b/test/matrix2.html
index dd3049f99..4172c3245 100644
--- a/test/matrix2.html
+++ b/test/matrix2.html
@@ -129,12 +129,14 @@ under the License.
                     },
                     {
                         coord: ['U', null],
+                        coordClamp: true,
                         itemStyle: {
                             color: 'rgb(220,230,170)',
                         },
                     },
                     {
                         coord: [NaN, 'F'],
+                        coordClamp: true,
                         mergeCells: true,
                     }
                 ];
@@ -142,6 +144,7 @@ under the License.
                 var cornerData = [
                     {
                         coord: [null, -2],
+                        coordClamp: true,
                         value: 'some',
                         mergeCells: true,
                     }
@@ -695,6 +698,7 @@ under the License.
                     },
                     {
                         coord: ['O', ['B2', 'not_exist']],
+                        coordClamp: true,
                         mergeCells: true,
                         value: 'merged',
                         __expect: 'column O merged'
@@ -706,6 +710,7 @@ under the License.
                     },
                     {
                         coord: ['S', null],
+                        coordClamp: true,
                         mergeCells: true,
                         value: 'merged',
                         __expect: 'column S merged.'
@@ -1211,593 +1216,6 @@ under the License.
 
 
 
-
-
-
-
-        <script>
-
-            var option;
-
-            require([
-                'echarts'
-            ], function (echarts) {
-
-                const layoutList = [
-                    {
-                        layout: {
-                            left: 10,
-                            bottom: 10,
-                            width: 250,
-                            height: 50,
-                        },
-                        expect: 'left-bottom',
-                    },
-                    {
-                        layout: {
-                            right: 10,
-                            bottom: 10,
-                            width: 250,
-                            height: 50,
-                        },
-                        expect: 'right-bottom'
-                    },
-                    {
-                        layout: {
-                        },
-                        expect: 'default place'
-                    },
-                ];
-
-                option = {
-                    backgroundColor: '#eee',
-                    matrix: [
-
-                        // Layout test (r/l/t/b/w/h)
-                        ...layoutList.map(item => ({
-                            ...item.layout,
-                            backgroundStyle: {
-                                color: '#ddd'
-                            },
-                            x: {show: false, data: ['X1']},
-                            y: {show: false, data: ['Y1']},
-                            body: {
-                                label: {fontSize: 10},
-                                data: [{
-                                    coord: [0, 0],
-                                    value: `expect matrix on ${item.expect} 
due to\nl/r/t/b/w/h settings are:\n`
-                                        + JSON.stringify(item.layout)
-                                }]
-                            }
-                        })),
-
-                        // z-order test
-                        ...[{
-                            matrixLayout: {
-                                top: 10,
-                                left: 10,
-                                width: 300,
-                                height: 50,
-                            },
-                            borderZ2: undefined,
-                        }, {
-                            matrixLayout: {
-                                top: 'center',
-                                left: 10,
-                                width: 300,
-                                height: 50,
-                            },
-                            borderZ2: 500,
-                        }].map(({matrixLayout, borderZ2}) => ({
-                            ...matrixLayout,
-                            backgroundStyle: {
-                                color: 'yellow',
-                                borderColor: 'orange',
-                                borderWidth: 5,
-                                shadowColor: '#111',
-                                shadowBlur: 15,
-                            },
-                            borderZ2,
-                            x: {
-                                data: ['X1', 'X2', 'X3'],
-                                dividerLineStyle: {
-                                    color: 'rgb(0,200,200)',
-                                    width: 5,
-                                },
-                            },
-                            y: {
-                                data: ['Y1', 'Y2', 'Y3'],
-                                dividerLineStyle: {
-                                    color: 'rgb(100,150,150)',
-                                    width: 5,
-                                },
-                            },
-                            body: {
-                                label: {
-                                    fontSize: 10,
-                                },
-                                itemStyle: {
-                                    borderWidth: 1,
-                                    borderColor: 'blue'
-                                },
-                                data: [{
-                                    coord: [0, 0],
-                                    itemStyle: {
-                                        borderColor: 'red',
-                                        borderWidth: 3
-                                    },
-                                    value: 'red border',
-                                }, {
-                                    coord: [[1, 2], 0],
-                                    itemStyle: {
-                                        borderColor: 'green',
-                                        borderWidth: 3
-                                    },
-                                    mergeCells: true,
-                                    value: 'green border',
-                                }, {
-                                    coord: [[1, 2], 2],
-                                    mergeCells: true,
-                                    label: {
-                                        position: 'insideRight'
-                                    },
-                                    value: `borderZ2: ${borderZ2}`,
-                                }]
-                            },
-                            z: 10
-                        }))
-                    ]
-                };
-
-                var chart = testHelper.create(echarts, 'main_self_layout', {
-                    height: 200,
-                    title: [
-                        'matrix self layout test',
-                        'z-index test'
-                    ],
-                    option: option,
-                });
-            });
-
-        </script>
-
-
-
-
-
-        <script>
-            require([
-                'echarts',
-            ], function (echarts) {
-                const MatrixClampOption = {
-                    none: 0,
-                    all: 1,
-                    body: 2,
-                    corner: 3,
-                };
-
-                function makeMatrixOption({x, y, xLevels, yLevels}, {xShow, 
yShow}) {
-                    return {
-                        top: 90,
-                        bottom: 100,
-                        left: 160,
-                        x: {
-                            show: !!xShow,
-                            data: x,
-                            levels: xLevels ? xLevels : undefined,
-                            itemStyle: {color: '#111'},
-                            label: {color: '#eee'},
-                        },
-                        y: {
-                            show: !!yShow,
-                            data: y,
-                            levels: yLevels ? yLevels : undefined,
-                            itemStyle: {color: '#111'},
-                            label: {color: '#eee'},
-                        },
-                        corner: {
-                            itemStyle: {color: '#333'},
-                            label: {color: '#eee'},
-                        }
-                    };
-                }
-
-                function makeFailedOption(failed) {
-                    return {
-                        id: 'success_or_fail',
-                        type: 'text',
-                        ignore: failed == null,
-                        style: {
-                            text: failed ? 'Case Failed' : 'Case Succeeded',
-                            fontSize: 18,
-                            fill: failed ? 'red' : 'green',
-                        }
-                    }
-                }
-
-                const _matrixXYDataMap = {
-                    test_d: {
-                        desc: 'Different subtree have duplicated text, expect 
display the original text',
-                        data: {
-                            x: [{value: 'a', children: ['o', 'p', 'q']}, 
{value: 'b', children: ['o', 'p', 'q']}],
-                            y: [{value: 'M', children: [new Date(), /a/]}]
-                        },
-                        testList: [{
-                            testType: 'convertToLayout',
-                            cases: [{
-                                input: ['o', 'Y1'],
-                                expect: {matrixXYLocatorRange: [[0, 0], [1, 
1]]},
-                            }, {
-                                input: [3, 0],
-                                expect: {matrixXYLocatorRange: [[3, 3], [0, 
0]]},
-                            }, {
-                                input: [7, 0],
-                                expect: {matrixXYLocatorRange: [[3, 5], [0, 
0]]},
-                            }, {
-                                input: [7, 0],
-                                opt: {clamp: MatrixClampOption.body},
-                                expect: {matrixXYLocatorRange: [[3, 5], [0, 
0]]},
-                            }]
-                        }]
-                    },
-                    test_a: {
-                        desc: 'matrix.y.data is empty array, expect no error.',
-                        data: {
-                            x: ['a', 'X2', null, 'd'],
-                            y: [],
-                        },
-                        testList: [{
-                            testType: 'convertToLayout',
-                            cases: [{
-                                input: ['X2', null],
-                                expect: {matrixXYLocatorRange: [[1, 1], [NaN, 
NaN]]},
-                            }, {
-                                input: [null, 0],
-                                expect: {matrixXYLocatorRange: [[NaN, NaN], 
[NaN, NaN]]},
-                            }, {
-                                input: [null, null],
-                                opt: {clamp: MatrixClampOption.body},
-                                expect: {matrixXYLocatorRange: [[0, 3], [NaN, 
NaN]]},
-                            }]
-                        }]
-                    },
-                    test_a2: {
-                        desc: 'matrix.x.data is empty array, expect no error.',
-                        data: {
-                            x: [],
-                            y: ['a', 'X2', null, 'd'],
-                        },
-                    },
-                    test_b: {
-                        desc: '[null] is allowed; number is illegal in 
matrix.x/y.data and replaced by auto-gen text.',
-                        data: {
-                            x: [null, null],
-                            y: [1, 2, 3],
-                        },
-                        testList: [{
-                            testType: 'convertToLayout',
-                            cases: [{
-                                input: ['X1', 0],
-                                expect: {matrixXYLocatorRange: [[1, 1], [0, 
0]]},
-                            }, {
-                                input: [-1, -1],
-                                expect: {matrixXYLocatorRange: [[-1, -1], [-1, 
-1]]},
-                            }, {
-                                input: [null, null],
-                                opt: {clamp: MatrixClampOption.body},
-                                expect: {matrixXYLocatorRange: [[0, 1], [0, 
2]]},
-                            }, {
-                                input: [null, null],
-                                opt: {clamp: MatrixClampOption.corner},
-                                expect: {matrixXYLocatorRange: [[-1, -1], [-1, 
-1]]},
-                            }, {
-                                input: [0, 0],
-                                opt: {clamp: MatrixClampOption.corner},
-                                expect: {matrixXYLocatorRange: [[-1, -1], [-1, 
-1]]},
-                            }]
-                        }]
-                    },
-                    test_c: {
-                        desc: 'No matrix.x/y.data, expect no error',
-                        data: {
-                            x: [],
-                            y: [],
-                        },
-                        testList: [{
-                            testType: 'convertToLayout',
-                            cases: [{
-                                input: [0, 0],
-                                expect: {matrixXYLocatorRange: [[NaN, NaN], 
[NaN, NaN]]},
-                            }, {
-                                input: [null, null],
-                                opt: {clamp: MatrixClampOption.body},
-                                expect: {matrixXYLocatorRange: [[NaN, NaN], 
[NaN, NaN]]},
-                            }]
-                        }]
-                    },
-                    test_e: {
-                        desc: 'All col/row width specified but not touch or 
overflow the bounary',
-                        data: {
-                            x: [{value: 'a1', size: 30}, {value: 'a2', size: 
30}],
-                            y: [{value: 'b1', size: 300}, {value: 'b2', size: 
300}],
-                            yLevels: [{levelSize: 50}]
-                        },
-                    },
-                    test_f: {
-                        desc: 'collect all from series.data (has 
null/NaN/undefined/illegal, expect display)',
-                        data: {
-                            x: undefined,
-                            y: undefined,
-                            seriesData: [
-                                ['fruit', undefined, 1223],
-                                ['bread', 'good', 323],
-                                ['milk', 'good', 142],
-                                [null, 'medium', 63],
-                                ['bread', 'medium', 91],
-                                ['milk', 9999, 45],
-                                ['fruit', NaN, 55],
-                                ['bread', 'bad', 15],
-                                ['milk', 'bad', 53],
-                            ],
-                        },
-                    },
-                    test_g: {
-                        desc: 'no series.data and no matrix.x/y',
-                        data: {
-                            x: undefined,
-                            y: undefined,
-                            seriesData: [],
-                        },
-                    },
-                };
-
-                let _ctx = {
-                    xyData: 'test_d',
-                    testResult: null, // {result: unknown, failed: boolean}
-                    xShow: true,
-                    yShow: true,
-                    convertFromPixelOpt: null,
-                };
-
-                function updateView() {
-                    const option = {
-                        matrix: 
makeMatrixOption(_matrixXYDataMap[_ctx.xyData].data, _ctx),
-                        series: {
-                            data: _matrixXYDataMap[_ctx.xyData].data.seriesData
-                        },
-                    };
-                    chart.setOption(option, {replaceMerge: 'matrix'});
-
-                    chart.setOption({
-                        graphic: {
-                            elements: [{
-                                id: 'convert_result',
-                                style: {
-                                    text: _ctx.testResult ? 
_ctx.testResult.result : '',
-                                }
-                            }, {
-                                id: 'desc_text',
-                                style: {
-                                    text: '--- expect ---\n' + 
(_matrixXYDataMap[_ctx.xyData].desc || '')
-                                        + '\n--- current matrix data ---\n'
-                                        + testHelper.printObject(
-                                            {
-                                                x: {
-                                                    data: 
_matrixXYDataMap[_ctx.xyData].data.x,
-                                                    levels: 
_matrixXYDataMap[_ctx.xyData].data.xLevels,
-                                                },
-                                                y: {
-                                                    data: 
_matrixXYDataMap[_ctx.xyData].data.y,
-                                                    levels: 
_matrixXYDataMap[_ctx.xyData].data.yLevels,
-                                                },
-                                            },
-                                            {lineBreakMaxColumn: 150}
-                                        )
-                                        + '\n--- current series data ---\n' + (
-                                            
_matrixXYDataMap[_ctx.xyData].data.seriesData
-                                                ? testHelper.printObject(
-                                                    
_matrixXYDataMap[_ctx.xyData].data.seriesData,
-                                                    {lineBreakMaxColumn: 30}
-                                                )
-                                                : 'undefined'
-                                        )
-                                }
-                            },
-                            makeFailedOption(_ctx.testResult ? 
!!_ctx.testResult.failed : undefined)
-                            ]
-                        }
-                    });
-                }
-
-                const option = {
-                    tooltip: {},
-                    backgroundColor: '#aee',
-                    matrix: 
makeMatrixOption(_matrixXYDataMap[_ctx.xyData].data, _ctx),
-                    series: {
-                        type: 'scatter',
-                        coordinateSystem: 'matrix',
-                        symbolSize: 20,
-                        encode: {label: 2},
-                        label: {show: true},
-                        data: _matrixXYDataMap[_ctx.xyData].data.seriesData
-                    },
-                    graphic: {
-                        elements: [{
-                            bottom: 5,
-                            left: 'center',
-                            id: 'convert_result',
-                            type: 'text',
-                            style: {
-                                text: '',
-                                fill: 'blue',
-                                fontSize: 11,
-                            },
-                            silent: true
-                        }, {
-                            left: 5,
-                            top: 5,
-                            id: 'desc_text',
-                            type: 'text',
-                            style: {
-                                fontSize: 12,
-                                fill: '#333',
-                            },
-                            silent: true
-                        }, {
-                            right: 5,
-                            top: 5,
-                            id: 'success_or_fail',
-                            type: 'text',
-                            style: {
-                                fontSize: 20,
-                                fill: 'red',
-                            },
-                            silent: true
-                        }]
-                    }
-                };
-
-                var chart = testHelper.create(echarts, 
'main_dim_data_edge_cases', {
-                    title: [
-                        'edge case',
-                        '**click** on matrix inside and outside to test clamp.'
-                    ],
-                    option: option,
-                    height: 400,
-                    inputsStyle: 'compact',
-                    inputs: [{
-                        text: 'test cases:',
-                        type: 'select',
-                        options: Object.keys(_matrixXYDataMap).map(key => {
-                            let text = _matrixXYDataMap[key].desc;
-                            const MAX_STR = 100;
-                            if (text.length > MAX_STR) {
-                                text = text.slice(0, MAX_STR) + ' ...';
-                            }
-                            return {text: text, value: key};
-                        }),
-                        onchange() {
-                            const key = this.value;
-                            _ctx.xyData = key;
-                            _ctx.testResult = null;
-                            chart.__testHelper.switchGroup(key);
-                            updateView();
-                        }
-                    }, {
-                        type: 'br',
-                    }, {
-                        text: 'matrix.x show:',
-                        type: 'select',
-                        values: [true, false],
-                        onchange() {
-                            _ctx.xShow = this.value;
-                            updateView();
-                        }
-                    }, {
-                        text: 'matrix.y show:',
-                        type: 'select',
-                        values: [true, false],
-                        onchange() {
-                            _ctx.yShow = this.value;
-                            updateView();
-                        }
-                    }, {
-                        text: 'convertFromPixel opt:',
-                        type: 'select',
-                        options: [
-                            {value: undefined},
-                            {text: 'clamp body', value: {clamp: 
MatrixClampOption.body}},
-                            {text: 'clamp corner', value: {clamp: 
MatrixClampOption.corner}},
-                            {text: 'clamp all', value: {clamp: 
MatrixClampOption.all}},
-                            {text: 'clamp none', value: {clamp: 
MatrixClampOption.none}},
-                        ],
-                        onchange() {
-                            _ctx.convertFromPixelOpt = this.value;
-                        }
-                    }, {
-                        type: 'groupset',
-                        inputsStyle: 'compact',
-                        inputsHeight: 70,
-                        groups: Object.keys(_matrixXYDataMap).map(key => {
-                            const textList = _matrixXYDataMap[key].testList || 
[];
-                            const inputs = [];
-                            textList.forEach(testItem => {
-                                if (testItem.testType === 'convertToLayout') {
-                                    const cases = testItem.cases;
-                                    cases.forEach(caseItem => {
-                                        inputs.push({
-                                            text: 
`convertToLayout(${testHelper.printObject(caseItem.input)}, 
${testHelper.printObject(caseItem.opt)})`,
-                                            onclick() {
-                                                let expect = caseItem.expect;
-                                                let failed = false;
-                                                let actual;
-                                                try {
-                                                    actual = 
chart.convertToLayout({matrixIndex: 0}, caseItem.input, caseItem.opt);
-                                                    console.log(actual);
-                                                    if 
(!numEq(expect.matrixXYLocatorRange[0][0], actual.matrixXYLocatorRange[0][0])
-                                                        || 
!numEq(expect.matrixXYLocatorRange[0][1], actual.matrixXYLocatorRange[0][1])
-                                                        || 
!numEq(expect.matrixXYLocatorRange[1][0], actual.matrixXYLocatorRange[1][0])
-                                                        || 
!numEq(expect.matrixXYLocatorRange[1][1], actual.matrixXYLocatorRange[1][1])
-                                                    ) {
-                                                        failed = true;
-                                                    }
-                                                }
-                                                catch (err) {
-                                                    console.error(err);
-                                                    failed = true;
-                                                }
-                                                const result = 
'convertToLayout result: ' + testHelper.printObject(actual);
-                                                _ctx.testResult = {result, 
failed};
-                                                updateView();
-                                            }
-                                        });
-                                    });
-                                }
-                                else {
-                                    throw new Error('illegal');
-                                }
-                            });
-
-                            return {
-                                id: key,
-                                text: '[' + key + '] test cases:',
-                                inputs,
-                            };
-                        })
-                    }] // End of inputs
-                });
-
-                if (chart) {
-                    updateView();
-
-                    chart.getZr().on('click', function (event) {
-                        const point = [event.offsetX, event.offsetY];
-                        const data = chart.convertFromPixel({matrixIndex: 0}, 
point, _ctx.convertFromPixelOpt);
-                        const layout = chart.convertToLayout({matrixIndex: 0}, 
data);
-
-                        _ctx.testResult = {
-                            result: 'convertFromPixel result: ' + 
testHelper.printObject(data) + '\n'
-                                + 'Then use it convertToLayout result: ' + 
testHelper.printObject(layout),
-                            failed: false
-                        };
-                        updateView();
-                    });
-                }
-            });
-
-            function eqNaN(value) {
-                return value !== value;
-            }
-
-            function numEq(expect, actual) {
-                return eqNaN(expect)
-                    ? eqNaN(actual)
-                    : expect === actual;
-            }
-        </script>
-
-
-
     </body>
 </html>
 
diff --git a/test/matrix3.html b/test/matrix3.html
index 0120a6e12..18f99ebe5 100644
--- a/test/matrix3.html
+++ b/test/matrix3.html
@@ -185,6 +185,7 @@ under the License.
                                 mergeCells: true,
                             }, {
                                 coord: [null, 'D'],
+                                coordClamp: true,
                                 mergeCells: true,
                             }, {
                                 coord: [['P', 'Q'], 'A1'],
@@ -973,7 +974,7 @@ under the License.
                     y: {data: ['r', 's', 't']},
                     body: {
                         data: [
-                            {coord: [null, 's'], mergeCells: true}
+                            {coord: [null, 's'], coordClamp: true, mergeCells: 
true}
                         ]
                     }
                 },
diff --git a/test/matrix4.html b/test/matrix4.html
new file mode 100644
index 000000000..110a9beeb
--- /dev/null
+++ b/test/matrix4.html
@@ -0,0 +1,649 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+
+
+<html>
+    <head>
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1" />
+        <script src="lib/simpleRequire.js"></script>
+        <script src="lib/config.js"></script>
+        <script src="lib/jquery.min.js"></script>
+        <script src="lib/facePrint.js"></script>
+        <script src="lib/testHelper.js"></script>
+        <script src="lib/draggable.js"></script>
+        <!-- <script src="ut/lib/canteen.js"></script> -->
+        <link rel="stylesheet" href="lib/reset.css" />
+    </head>
+    <body>
+        <style>
+        </style>
+
+
+        <div style="
+            height: 1207px;
+            margin: 0;
+            padding: 20px;
+            background: #eee;
+            overflow: hidden;
+            box-sizing: border-box;
+        "
+        >
+            This is a placeholder for y coord matching the visual test due to 
the visual test migration.
+            <br>
+            Scroll down to check the test case below.
+            <br>
+            ↓ ↓ ↓
+        </div>
+
+        <div id="main_self_layout"></div>
+        <div id="main_dim_data_edge_cases"></div>
+
+
+
+
+
+
+        <script>
+
+            var option;
+
+            require([
+                'echarts'
+            ], function (echarts) {
+
+                const layoutList = [
+                    {
+                        layout: {
+                            left: 10,
+                            bottom: 10,
+                            width: 250,
+                            height: 50,
+                        },
+                        expect: 'left-bottom',
+                    },
+                    {
+                        layout: {
+                            right: 10,
+                            bottom: 10,
+                            width: 250,
+                            height: 50,
+                        },
+                        expect: 'right-bottom'
+                    },
+                    {
+                        layout: {
+                        },
+                        expect: 'default place'
+                    },
+                ];
+
+                option = {
+                    backgroundColor: '#eee',
+                    matrix: [
+
+                        // Layout test (r/l/t/b/w/h)
+                        ...layoutList.map(item => ({
+                            ...item.layout,
+                            backgroundStyle: {
+                                color: '#ddd'
+                            },
+                            x: {show: false, data: ['X1']},
+                            y: {show: false, data: ['Y1']},
+                            body: {
+                                label: {fontSize: 10},
+                                data: [{
+                                    coord: [0, 0],
+                                    value: `expect matrix on ${item.expect} 
due to\nl/r/t/b/w/h settings are:\n`
+                                        + JSON.stringify(item.layout)
+                                }]
+                            }
+                        })),
+
+                        // z-order test
+                        ...[{
+                            matrixLayout: {
+                                top: 10,
+                                left: 10,
+                                width: 300,
+                                height: 50,
+                            },
+                            borderZ2: undefined,
+                        }, {
+                            matrixLayout: {
+                                top: 'center',
+                                left: 10,
+                                width: 300,
+                                height: 50,
+                            },
+                            borderZ2: 500,
+                        }].map(({matrixLayout, borderZ2}) => ({
+                            ...matrixLayout,
+                            backgroundStyle: {
+                                color: 'yellow',
+                                borderColor: 'orange',
+                                borderWidth: 5,
+                                shadowColor: '#111',
+                                shadowBlur: 15,
+                            },
+                            borderZ2,
+                            x: {
+                                data: ['X1', 'X2', 'X3'],
+                                dividerLineStyle: {
+                                    color: 'rgb(0,200,200)',
+                                    width: 5,
+                                },
+                            },
+                            y: {
+                                data: ['Y1', 'Y2', 'Y3'],
+                                dividerLineStyle: {
+                                    color: 'rgb(100,150,150)',
+                                    width: 5,
+                                },
+                            },
+                            body: {
+                                label: {
+                                    fontSize: 10,
+                                },
+                                itemStyle: {
+                                    borderWidth: 1,
+                                    borderColor: 'blue'
+                                },
+                                data: [{
+                                    coord: [0, 0],
+                                    itemStyle: {
+                                        borderColor: 'red',
+                                        borderWidth: 3
+                                    },
+                                    value: 'red border',
+                                }, {
+                                    coord: [[1, 2], 0],
+                                    itemStyle: {
+                                        borderColor: 'green',
+                                        borderWidth: 3
+                                    },
+                                    mergeCells: true,
+                                    value: 'green border',
+                                }, {
+                                    coord: [[1, 2], 2],
+                                    mergeCells: true,
+                                    label: {
+                                        position: 'insideRight'
+                                    },
+                                    value: `borderZ2: ${borderZ2}`,
+                                }]
+                            },
+                            z: 10
+                        }))
+                    ]
+                };
+
+                var chart = testHelper.create(echarts, 'main_self_layout', {
+                    height: 200,
+                    title: [
+                        'matrix self layout test',
+                        'z-index test'
+                    ],
+                    option: option,
+                });
+            });
+
+        </script>
+
+
+
+
+
+        <script>
+            require([
+                'echarts',
+            ], function (echarts) {
+                const MatrixClampOption = {
+                    none: 0,
+                    all: 1,
+                    body: 2,
+                    corner: 3,
+                };
+
+                function makeMatrixOption({x, y, xLevels, yLevels}, {xShow, 
yShow}) {
+                    return {
+                        top: 90,
+                        bottom: 100,
+                        left: 160,
+                        x: {
+                            show: !!xShow,
+                            data: x,
+                            levels: xLevels ? xLevels : undefined,
+                            itemStyle: {color: '#111'},
+                            label: {color: '#eee'},
+                        },
+                        y: {
+                            show: !!yShow,
+                            data: y,
+                            levels: yLevels ? yLevels : undefined,
+                            itemStyle: {color: '#111'},
+                            label: {color: '#eee'},
+                        },
+                        corner: {
+                            itemStyle: {color: '#333'},
+                            label: {color: '#eee'},
+                        }
+                    };
+                }
+
+                function makeFailedOption(failed) {
+                    return {
+                        id: 'success_or_fail',
+                        type: 'text',
+                        ignore: failed == null,
+                        style: {
+                            text: failed ? 'Case Failed' : 'Case Succeeded',
+                            fontSize: 18,
+                            fill: failed ? 'red' : 'green',
+                        }
+                    }
+                }
+
+                const _matrixXYDataMap = {
+                    test_d: {
+                        desc: 'Different subtree have duplicated text, expect 
display the original text',
+                        data: {
+                            x: [{value: 'a', children: ['o', 'p', 'q']}, 
{value: 'b', children: ['o', 'p', 'q']}],
+                            y: [{value: 'M', children: [new Date(), /a/]}]
+                        },
+                        testList: [{
+                            testType: 'convertToLayout',
+                            cases: [{
+                                input: ['o', 'Y1'],
+                                expect: {matrixXYLocatorRange: [[0, 0], [1, 
1]]},
+                            }, {
+                                input: [3, 0],
+                                expect: {matrixXYLocatorRange: [[3, 3], [0, 
0]]},
+                            }, {
+                                input: [7, 0],
+                                expect: {matrixXYLocatorRange: [[3, 5], [0, 
0]]},
+                            }, {
+                                input: [7, 0],
+                                opt: {clamp: MatrixClampOption.body},
+                                expect: {matrixXYLocatorRange: [[3, 5], [0, 
0]]},
+                            }]
+                        }]
+                    },
+                    test_a: {
+                        desc: 'matrix.y.data is empty array, expect no error.',
+                        data: {
+                            x: ['a', 'X2', null, 'd'],
+                            y: [],
+                        },
+                        testList: [{
+                            testType: 'convertToLayout',
+                            cases: [{
+                                input: ['X2', null],
+                                expect: {matrixXYLocatorRange: [[1, 1], [NaN, 
NaN]]},
+                            }, {
+                                input: [null, 0],
+                                expect: {matrixXYLocatorRange: [[NaN, NaN], 
[NaN, NaN]]},
+                            }, {
+                                input: [null, null],
+                                opt: {clamp: MatrixClampOption.body},
+                                expect: {matrixXYLocatorRange: [[0, 3], [NaN, 
NaN]]},
+                            }]
+                        }]
+                    },
+                    test_a2: {
+                        desc: 'matrix.x.data is empty array, expect no error.',
+                        data: {
+                            x: [],
+                            y: ['a', 'X2', null, 'd'],
+                        },
+                    },
+                    test_b: {
+                        desc: '[null] is allowed; number is illegal in 
matrix.x/y.data and replaced by auto-gen text.',
+                        data: {
+                            x: [null, null],
+                            y: [1, 2, 3],
+                        },
+                        testList: [{
+                            testType: 'convertToLayout',
+                            cases: [{
+                                input: ['X1', 0],
+                                expect: {matrixXYLocatorRange: [[1, 1], [0, 
0]]},
+                            }, {
+                                input: [-1, -1],
+                                expect: {matrixXYLocatorRange: [[-1, -1], [-1, 
-1]]},
+                            }, {
+                                input: [null, null],
+                                opt: {clamp: MatrixClampOption.body},
+                                expect: {matrixXYLocatorRange: [[0, 1], [0, 
2]]},
+                            }, {
+                                input: [null, null],
+                                opt: {clamp: MatrixClampOption.corner},
+                                expect: {matrixXYLocatorRange: [[-1, -1], [-1, 
-1]]},
+                            }, {
+                                input: [0, 0],
+                                opt: {clamp: MatrixClampOption.corner},
+                                expect: {matrixXYLocatorRange: [[-1, -1], [-1, 
-1]]},
+                            }]
+                        }]
+                    },
+                    test_c: {
+                        desc: 'No matrix.x/y.data, expect no error',
+                        data: {
+                            x: [],
+                            y: [],
+                        },
+                        testList: [{
+                            testType: 'convertToLayout',
+                            cases: [{
+                                input: [0, 0],
+                                expect: {matrixXYLocatorRange: [[NaN, NaN], 
[NaN, NaN]]},
+                            }, {
+                                input: [null, null],
+                                opt: {clamp: MatrixClampOption.body},
+                                expect: {matrixXYLocatorRange: [[NaN, NaN], 
[NaN, NaN]]},
+                            }]
+                        }]
+                    },
+                    test_e: {
+                        desc: 'All col/row width specified but not touch or 
overflow the bounary',
+                        data: {
+                            x: [{value: 'a1', size: 30}, {value: 'a2', size: 
30}],
+                            y: [{value: 'b1', size: 300}, {value: 'b2', size: 
300}],
+                            yLevels: [{levelSize: 50}]
+                        },
+                    },
+                    test_f: {
+                        desc: 'collect all from series.data (has 
null/NaN/undefined/illegal, expect display)',
+                        data: {
+                            x: undefined,
+                            y: undefined,
+                            seriesData: [
+                                ['fruit', undefined, 1223],
+                                ['bread', 'good', 323],
+                                ['milk', 'good', 142],
+                                [null, 'medium', 63],
+                                ['bread', 'medium', 91],
+                                ['milk', 9999, 45],
+                                ['fruit', NaN, 55],
+                                ['bread', 'bad', 15],
+                                ['milk', 'bad', 53],
+                            ],
+                        },
+                    },
+                    test_g: {
+                        desc: 'no series.data and no matrix.x/y',
+                        data: {
+                            x: undefined,
+                            y: undefined,
+                            seriesData: [],
+                        },
+                    },
+                };
+
+                let _ctx = {
+                    xyData: 'test_d',
+                    testResult: null, // {result: unknown, failed: boolean}
+                    xShow: true,
+                    yShow: true,
+                    convertFromPixelOpt: null,
+                };
+
+                function updateView() {
+                    const option = {
+                        matrix: 
makeMatrixOption(_matrixXYDataMap[_ctx.xyData].data, _ctx),
+                        series: {
+                            data: _matrixXYDataMap[_ctx.xyData].data.seriesData
+                        },
+                    };
+                    chart.setOption(option, {replaceMerge: 'matrix'});
+
+                    chart.setOption({
+                        graphic: {
+                            elements: [{
+                                id: 'convert_result',
+                                style: {
+                                    text: _ctx.testResult ? 
_ctx.testResult.result : '',
+                                }
+                            }, {
+                                id: 'desc_text',
+                                style: {
+                                    text: '--- expect ---\n' + 
(_matrixXYDataMap[_ctx.xyData].desc || '')
+                                        + '\n--- current matrix data ---\n'
+                                        + testHelper.printObject(
+                                            {
+                                                x: {
+                                                    data: 
_matrixXYDataMap[_ctx.xyData].data.x,
+                                                    levels: 
_matrixXYDataMap[_ctx.xyData].data.xLevels,
+                                                },
+                                                y: {
+                                                    data: 
_matrixXYDataMap[_ctx.xyData].data.y,
+                                                    levels: 
_matrixXYDataMap[_ctx.xyData].data.yLevels,
+                                                },
+                                            },
+                                            {lineBreakMaxColumn: 150}
+                                        )
+                                        + '\n--- current series data ---\n' + (
+                                            
_matrixXYDataMap[_ctx.xyData].data.seriesData
+                                                ? testHelper.printObject(
+                                                    
_matrixXYDataMap[_ctx.xyData].data.seriesData,
+                                                    {lineBreakMaxColumn: 30}
+                                                )
+                                                : 'undefined'
+                                        )
+                                }
+                            },
+                            makeFailedOption(_ctx.testResult ? 
!!_ctx.testResult.failed : undefined)
+                            ]
+                        }
+                    });
+                }
+
+                const option = {
+                    tooltip: {},
+                    backgroundColor: '#aee',
+                    matrix: 
makeMatrixOption(_matrixXYDataMap[_ctx.xyData].data, _ctx),
+                    series: {
+                        type: 'scatter',
+                        coordinateSystem: 'matrix',
+                        symbolSize: 20,
+                        encode: {label: 2},
+                        label: {show: true},
+                        data: _matrixXYDataMap[_ctx.xyData].data.seriesData
+                    },
+                    graphic: {
+                        elements: [{
+                            bottom: 5,
+                            left: 'center',
+                            id: 'convert_result',
+                            type: 'text',
+                            style: {
+                                text: '',
+                                fill: 'blue',
+                                fontSize: 11,
+                            },
+                            silent: true
+                        }, {
+                            left: 5,
+                            top: 5,
+                            id: 'desc_text',
+                            type: 'text',
+                            style: {
+                                fontSize: 12,
+                                fill: '#333',
+                            },
+                            silent: true
+                        }, {
+                            right: 5,
+                            top: 5,
+                            id: 'success_or_fail',
+                            type: 'text',
+                            style: {
+                                fontSize: 20,
+                                fill: 'red',
+                            },
+                            silent: true
+                        }]
+                    }
+                };
+
+                var chart = testHelper.create(echarts, 
'main_dim_data_edge_cases', {
+                    title: [
+                        'edge case',
+                        '**click** on matrix inside and outside to test clamp.'
+                    ],
+                    option: option,
+                    height: 400,
+                    inputsStyle: 'compact',
+                    inputs: [{
+                        text: 'test cases:',
+                        type: 'select',
+                        options: Object.keys(_matrixXYDataMap).map(key => {
+                            let text = _matrixXYDataMap[key].desc;
+                            const MAX_STR = 100;
+                            if (text.length > MAX_STR) {
+                                text = text.slice(0, MAX_STR) + ' ...';
+                            }
+                            return {text: text, value: key};
+                        }),
+                        onchange() {
+                            const key = this.value;
+                            _ctx.xyData = key;
+                            _ctx.testResult = null;
+                            chart.__testHelper.switchGroup(key);
+                            updateView();
+                        }
+                    }, {
+                        type: 'br',
+                    }, {
+                        text: 'matrix.x show:',
+                        type: 'select',
+                        values: [true, false],
+                        onchange() {
+                            _ctx.xShow = this.value;
+                            updateView();
+                        }
+                    }, {
+                        text: 'matrix.y show:',
+                        type: 'select',
+                        values: [true, false],
+                        onchange() {
+                            _ctx.yShow = this.value;
+                            updateView();
+                        }
+                    }, {
+                        text: 'convertFromPixel opt:',
+                        type: 'select',
+                        options: [
+                            {value: undefined},
+                            {text: 'clamp body', value: {clamp: 
MatrixClampOption.body}},
+                            {text: 'clamp corner', value: {clamp: 
MatrixClampOption.corner}},
+                            {text: 'clamp all', value: {clamp: 
MatrixClampOption.all}},
+                            {text: 'clamp none', value: {clamp: 
MatrixClampOption.none}},
+                        ],
+                        onchange() {
+                            _ctx.convertFromPixelOpt = this.value;
+                        }
+                    }, {
+                        type: 'groupset',
+                        inputsStyle: 'compact',
+                        inputsHeight: 70,
+                        groups: Object.keys(_matrixXYDataMap).map(key => {
+                            const textList = _matrixXYDataMap[key].testList || 
[];
+                            const inputs = [];
+                            textList.forEach(testItem => {
+                                if (testItem.testType === 'convertToLayout') {
+                                    const cases = testItem.cases;
+                                    cases.forEach(caseItem => {
+                                        inputs.push({
+                                            text: 
`convertToLayout(${testHelper.printObject(caseItem.input)}, 
${testHelper.printObject(caseItem.opt)})`,
+                                            onclick() {
+                                                let expect = caseItem.expect;
+                                                let failed = false;
+                                                let actual;
+                                                try {
+                                                    actual = 
chart.convertToLayout({matrixIndex: 0}, caseItem.input, caseItem.opt);
+                                                    console.log(actual);
+                                                    if 
(!numEq(expect.matrixXYLocatorRange[0][0], actual.matrixXYLocatorRange[0][0])
+                                                        || 
!numEq(expect.matrixXYLocatorRange[0][1], actual.matrixXYLocatorRange[0][1])
+                                                        || 
!numEq(expect.matrixXYLocatorRange[1][0], actual.matrixXYLocatorRange[1][0])
+                                                        || 
!numEq(expect.matrixXYLocatorRange[1][1], actual.matrixXYLocatorRange[1][1])
+                                                    ) {
+                                                        failed = true;
+                                                    }
+                                                }
+                                                catch (err) {
+                                                    console.error(err);
+                                                    failed = true;
+                                                }
+                                                const result = 
'convertToLayout result: ' + testHelper.printObject(actual);
+                                                _ctx.testResult = {result, 
failed};
+                                                updateView();
+                                            }
+                                        });
+                                    });
+                                }
+                                else {
+                                    throw new Error('illegal');
+                                }
+                            });
+
+                            return {
+                                id: key,
+                                text: '[' + key + '] test cases:',
+                                inputs,
+                            };
+                        })
+                    }] // End of inputs
+                });
+
+                if (chart) {
+                    updateView();
+
+                    chart.getZr().on('click', function (event) {
+                        const point = [event.offsetX, event.offsetY];
+                        const data = chart.convertFromPixel({matrixIndex: 0}, 
point, _ctx.convertFromPixelOpt);
+                        const layout = chart.convertToLayout({matrixIndex: 0}, 
data);
+
+                        _ctx.testResult = {
+                            result: 'convertFromPixel result: ' + 
testHelper.printObject(data) + '\n'
+                                + 'Then use it convertToLayout result: ' + 
testHelper.printObject(layout),
+                            failed: false
+                        };
+                        updateView();
+                    });
+                }
+            });
+
+            function eqNaN(value) {
+                return value !== value;
+            }
+
+            function numEq(expect, actual) {
+                return eqNaN(expect)
+                    ? eqNaN(actual)
+                    : expect === actual;
+            }
+        </script>
+
+
+
+    </body>
+</html>
+
diff --git a/test/matrix_application.html b/test/matrix_application.html
index 0f6ea81a5..56d3dbca7 100644
--- a/test/matrix_application.html
+++ b/test/matrix_application.html
@@ -958,6 +958,7 @@ under the License.
                         body: {
                             data: [{
                                 coord: [null, _yBreakTimeIndex],
+                                coordClamp: true,
                                 mergeCells: true,
                                 value: 'Break',
                                 label: {
diff --git a/test/runTest/actions/matrix2.json 
b/test/runTest/actions/matrix2.json
index b3eecf24b..ae97943d2 100644
--- a/test/runTest/actions/matrix2.json
+++ b/test/runTest/actions/matrix2.json
@@ -1 +1 @@
-[{"name":"Action 
1","ops":[{"type":"mousemove","time":543,"x":612,"y":165},{"type":"mousemove","time":743,"x":318,"y":198},{"type":"mousemove","time":950,"x":260,"y":218},{"type":"mousemove","time":1227,"x":259,"y":218},{"type":"mousemove","time":1427,"x":134,"y":108},{"type":"mousemove","time":1633,"x":121,"y":64},{"type":"mousemove","time":1849,"x":122,"y":54},{"type":"valuechange","selector":"#main_layout>div.test-chart-block-left>div.test-inputs.test-buttons.test-inputs-style-compact
 [...]
\ No newline at end of file
+[{"name":"Action 
1","ops":[{"type":"mousemove","time":543,"x":612,"y":165},{"type":"mousemove","time":743,"x":318,"y":198},{"type":"mousemove","time":950,"x":260,"y":218},{"type":"mousemove","time":1227,"x":259,"y":218},{"type":"mousemove","time":1427,"x":134,"y":108},{"type":"mousemove","time":1633,"x":121,"y":64},{"type":"mousemove","time":1849,"x":122,"y":54},{"type":"valuechange","selector":"#main_layout>div.test-chart-block-left>div.test-inputs.test-buttons.test-inputs-style-compact
 [...]
\ No newline at end of file
diff --git a/test/runTest/actions/matrix4.json 
b/test/runTest/actions/matrix4.json
new file mode 100644
index 000000000..6497dada8
--- /dev/null
+++ b/test/runTest/actions/matrix4.json
@@ -0,0 +1 @@
+[{"name":"Action 
1","ops":[{"type":"mousemove","time":704,"x":738,"y":219},{"type":"mousemove","time":917,"x":517,"y":196},{"type":"mousemove","time":1133,"x":407,"y":188},{"type":"mousemove","time":1236,"x":407,"y":188},{"type":"mousemove","time":1436,"x":263,"y":174},{"type":"mousemove","time":1647,"x":224,"y":162},{"type":"mousemove","time":1851,"x":216,"y":164},{"type":"mousemove","time":2320,"x":216,"y":164},{"type":"mousedown","time":2416,"x":216,"y":163},{"type":"mouseup","time":2
 [...]
\ No newline at end of file
diff --git a/test/runTest/marks/matrix.json b/test/runTest/marks/matrix.json
index 346fd04a1..c9a7cab6a 100644
--- a/test/runTest/marks/matrix.json
+++ b/test/runTest/marks/matrix.json
@@ -1,4 +1,12 @@
 [
+  {
+    "link": "",
+    "comment": "1. matrix.body/corner.data[i].coord disable 'clamp' by 
default.\n2. Support option.textStyle.",
+    "type": "New Feature",
+    "markedBy": "100pah",
+    "lastVersion": "6.0.0-beta.1",
+    "markTime": 1752590797892
+  },
   {
     "link": "https://github.com/apache/echarts/issues/19807";,
     "comment": "",


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

Reply via email to