diff --git a/common/changes/@visactor/vchart/008-fix-size-legend-handler-text_2026-03-23-03-45.json b/common/changes/@visactor/vchart/008-fix-size-legend-handler-text_2026-03-23-03-45.json new file mode 100644 index 0000000000..504b3f64f1 --- /dev/null +++ b/common/changes/@visactor/vchart/008-fix-size-legend-handler-text_2026-03-23-03-45.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "update changes for 008-fix-size-legend-handler-text: Allow size legend handlerText.style to accept function-based values in the same way other legend style hooks already do, and add regression coverage proving the style callback is preserved through continuous legend attribute transformation.", + "type": "none", + "packageName": "@visactor/vchart" + } + ], + "packageName": "@visactor/vchart", + "email": "lixuef1313@163.com" +} \ No newline at end of file diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index fd6a870992..e0efb19a63 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -37,11 +37,11 @@ importers: specifier: 1.2.4-alpha.5 version: 1.2.4-alpha.5 '@visactor/vrender': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vrender-kits': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vtable': specifier: 1.19.0-alpha.0 version: 1.19.0-alpha.0 @@ -203,11 +203,11 @@ importers: specifier: workspace:2.0.19 version: link:../vchart '@visactor/vrender-core': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vrender-kits': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vutils': specifier: ~1.0.23 version: 1.0.23 @@ -294,11 +294,11 @@ importers: specifier: workspace:2.0.19 version: link:../vchart-extension '@visactor/vrender-core': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vrender-kits': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vutils': specifier: ~1.0.23 version: 1.0.23 @@ -529,17 +529,17 @@ importers: specifier: ~1.0.23 version: 1.0.23 '@visactor/vrender-animate': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vrender-components': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vrender-core': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vrender-kits': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vscale': specifier: ~1.0.23 version: 1.0.23 @@ -692,17 +692,17 @@ importers: specifier: ~1.0.23 version: 1.0.23 '@visactor/vrender-animate': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vrender-components': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vrender-core': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vrender-kits': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vutils': specifier: ~1.0.23 version: 1.0.23 @@ -1098,7 +1098,7 @@ importers: version: 5.3.2 debug: specifier: 4.3.4 - version: 4.3.4(supports-color@6.1.0) + version: 4.3.4(supports-color@9.4.0) fs-extra: specifier: 10.1.0 version: 10.1.0 @@ -1260,14 +1260,14 @@ importers: specifier: workspace:2.0.19 version: link:../../packages/vchart '@visactor/vrender': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vrender-core': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vrender-kits': - specifier: ~1.0.41 - version: 1.0.41 + specifier: ~1.0.42 + version: 1.0.42 '@visactor/vutils': specifier: ~1.0.23 version: 1.0.23 @@ -3073,29 +3073,29 @@ packages: '@visactor/vrender-animate@1.0.0-alpha.18': resolution: {integrity: sha512-9kTtvp1ef+1t+AtUiza6A7qBQP7SmvOu3/ILGrqs/HGdZVj1XGjbYvD/X/zwKJ3LEb7gGV5fa8x95e4czTvRSA==} - '@visactor/vrender-animate@1.0.41': - resolution: {integrity: sha512-kdMoIh7OEo6z4rZfnJHX7d+izBhGVWq6MR22uppk0LPilfdBd/1hSNAEKO6C9JWAy5uROGFpEkh+kk+ar/zSZg==} + '@visactor/vrender-animate@1.0.42': + resolution: {integrity: sha512-SeTHzm6opLqrBNM6ueK92LNwPbpVt4Zw0PAMrnfeccMazYIMQ9ZTC9uAjo8ecWwJIG+NO6dhTaL97fe7mhCBKQ==} '@visactor/vrender-components@1.0.0-alpha.18': resolution: {integrity: sha512-7Euq+ZfswL74n2pgkaqZSsPxoSa5SPIGyXatN1eUrdzM2Z0kX6U0RcJg01fctvRs4op6WhcecRLqGvnHcBeb9Q==} - '@visactor/vrender-components@1.0.41': - resolution: {integrity: sha512-B7iXJE1TdkYapPZN6DNxoaErY4FzGf5AbcbG/z6Q0hnzO4Iw1hKdtlTGOIYA1+JXhehDWcyy+D0bnoNQNf+rgw==} + '@visactor/vrender-components@1.0.42': + resolution: {integrity: sha512-S6lbjABk3OOCNN2KMmvLRWS7RWLvw1Cklwb8MJNsb1IxpwTuivjUyz+HGhzj1ju9TkQf64ooA+gX1OgOlDJIaQ==} '@visactor/vrender-core@1.0.0-alpha.18': resolution: {integrity: sha512-0ihtNvCyNkOsWPFgRqowHzq0IcQgS2Wl/nPpKbVtxWKveenwlhA+ZKoQvam6VJyBY7jeNe1pROy0mJMDyVAJQw==} - '@visactor/vrender-core@1.0.41': - resolution: {integrity: sha512-P7YVUJ45vwqPA460W6JJjg201ThvxBrjEgTBJ4tHKaHZPP/nVyF8rPyUOCL8QesEFDB+R0e/sUJUVs+ckHhd2w==} + '@visactor/vrender-core@1.0.42': + resolution: {integrity: sha512-EcSH0SyFb6zlWYyt37NgOKCFXkv9At0HW91EreYunmQpr0Bj1oRNtKDm3GAmc7hMLp4PYMRR6q4mwuFYY9U4lg==} '@visactor/vrender-kits@1.0.0-alpha.18': resolution: {integrity: sha512-Tvolkq+4G8qiPFZo0Aj8M//Yr6jR2h8FNkFEyWM9gbQbEiTkjpmHAJOYnoSsaPtPrcMSlG4EhJSFDk6ymANHVg==} - '@visactor/vrender-kits@1.0.41': - resolution: {integrity: sha512-ffJlKkNseOsnRjvBmxKxQ9dsQXu+K288NFCtB0ZZ2N/mtcTsZUlH5SDCcsAvDhPGEvJ22Ye4MFKcXSEDctpGzA==} + '@visactor/vrender-kits@1.0.42': + resolution: {integrity: sha512-GgXRJlsm8A+dpq/htSbe1SmX5dyattveDvEAPfq458ws/7iGunWqKXa5UpGJb3RLAncGjmU7BXKIB0svF08+1w==} - '@visactor/vrender@1.0.41': - resolution: {integrity: sha512-FUpN89qavMUZBVobiF9OmvGgJv3t8mBy2FZyTaybgTl2msqjQzVF2CnlxjKzvv3daLusniok3T+bdo0AoQGzLw==} + '@visactor/vrender@1.0.42': + resolution: {integrity: sha512-3DAbCJMV/0MZ7DmnwQzgaopbBkYsxGQ6EAwVVOg1vbm/pssDqjLL0scqgyBB2eXlwwSbAe2okcIaHKM6YfyZkg==} '@visactor/vscale@0.18.18': resolution: {integrity: sha512-iRG4kv+5Fv4KX3AxEfV95XU3I6OmF0QizyAhqHxKa7L1MaT+MRvDDk5zHWf1E8gialLbL2xDe3GnT6g/4u5jhA==} @@ -12449,7 +12449,7 @@ snapshots: '@babel/traverse': 7.28.5 '@babel/types': 7.28.5 convert-source-map: 1.9.0 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -12516,7 +12516,7 @@ snapshots: '@babel/core': 7.20.12 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) lodash.debounce: 4.0.8 resolve: 1.22.11 semver: 6.3.1 @@ -13364,7 +13364,7 @@ snapshots: '@babel/parser': 7.28.5 '@babel/template': 7.27.2 '@babel/types': 7.28.5 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -13392,7 +13392,7 @@ snapshots: '@electron/get@1.14.1': dependencies: - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) env-paths: 2.2.1 fs-extra: 8.1.0 got: 9.6.0 @@ -13424,7 +13424,7 @@ snapshots: '@eslint/eslintrc@1.4.1': dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) espree: 9.6.1 globals: 13.24.0 ignore: 5.3.2 @@ -13494,7 +13494,7 @@ snapshots: '@humanwhocodes/config-array@0.9.5': dependencies: '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -13582,8 +13582,8 @@ snapshots: jest-regex-util: 26.0.0 jest-resolve: 26.6.2 jest-resolve-dependencies: 26.6.3 - jest-runner: 26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5)) - jest-runtime: 26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5)) + jest-runner: 26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@4.9.5)) + jest-runtime: 26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@4.9.5)) jest-snapshot: 26.6.2 jest-util: 26.6.2 jest-validate: 26.6.2 @@ -13716,20 +13716,6 @@ snapshots: - ts-node - utf-8-validate - '@jest/test-sequencer@26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5))': - dependencies: - '@jest/test-result': 26.6.2 - graceful-fs: 4.2.11 - jest-haste-map: 26.6.2 - jest-runner: 26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5)) - jest-runtime: 26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5)) - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - ts-node - - utf-8-validate - '@jest/transform@24.9.0': dependencies: '@babel/core': 7.20.12 @@ -14801,7 +14787,7 @@ snapshots: '@typescript-eslint/scope-manager': 5.30.0 '@typescript-eslint/type-utils': 5.30.0(eslint@8.18.0)(typescript@4.9.5) '@typescript-eslint/utils': 5.30.0(eslint@8.18.0)(typescript@4.9.5) - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) eslint: 8.18.0 functional-red-black-tree: 1.0.1 ignore: 5.3.2 @@ -14818,7 +14804,7 @@ snapshots: '@typescript-eslint/scope-manager': 4.33.0 '@typescript-eslint/types': 4.33.0 '@typescript-eslint/typescript-estree': 4.33.0(typescript@4.9.5) - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) eslint: 6.8.0 optionalDependencies: typescript: 4.9.5 @@ -14830,7 +14816,7 @@ snapshots: '@typescript-eslint/scope-manager': 4.33.0 '@typescript-eslint/types': 4.33.0 '@typescript-eslint/typescript-estree': 4.33.0(typescript@4.9.5) - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) eslint: 8.18.0 optionalDependencies: typescript: 4.9.5 @@ -14842,7 +14828,7 @@ snapshots: '@typescript-eslint/scope-manager': 5.30.0 '@typescript-eslint/types': 5.30.0 '@typescript-eslint/typescript-estree': 5.30.0(typescript@4.9.5) - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) eslint: 8.18.0 optionalDependencies: typescript: 4.9.5 @@ -14862,7 +14848,7 @@ snapshots: '@typescript-eslint/type-utils@5.30.0(eslint@8.18.0)(typescript@4.9.5)': dependencies: '@typescript-eslint/utils': 5.30.0(eslint@8.18.0)(typescript@4.9.5) - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) eslint: 8.18.0 tsutils: 3.21.0(typescript@4.9.5) optionalDependencies: @@ -14878,7 +14864,7 @@ snapshots: dependencies: '@typescript-eslint/types': 4.33.0 '@typescript-eslint/visitor-keys': 4.33.0 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) globby: 11.1.0 is-glob: 4.0.3 semver: 7.7.3 @@ -14892,7 +14878,7 @@ snapshots: dependencies: '@typescript-eslint/types': 5.30.0 '@typescript-eslint/visitor-keys': 5.30.0 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) globby: 11.1.0 is-glob: 4.0.3 semver: 7.7.3 @@ -15026,9 +15012,9 @@ snapshots: '@visactor/vrender-core': 1.0.0-alpha.18 '@visactor/vutils': 1.0.4 - '@visactor/vrender-animate@1.0.41': + '@visactor/vrender-animate@1.0.42': dependencies: - '@visactor/vrender-core': 1.0.41 + '@visactor/vrender-core': 1.0.42 '@visactor/vutils': 1.0.23 '@visactor/vrender-components@1.0.0-alpha.18': @@ -15039,11 +15025,11 @@ snapshots: '@visactor/vscale': 1.0.4 '@visactor/vutils': 1.0.4 - '@visactor/vrender-components@1.0.41': + '@visactor/vrender-components@1.0.42': dependencies: - '@visactor/vrender-animate': 1.0.41 - '@visactor/vrender-core': 1.0.41 - '@visactor/vrender-kits': 1.0.41 + '@visactor/vrender-animate': 1.0.42 + '@visactor/vrender-core': 1.0.42 + '@visactor/vrender-kits': 1.0.42 '@visactor/vscale': 1.0.23 '@visactor/vutils': 1.0.23 @@ -15052,7 +15038,7 @@ snapshots: '@visactor/vutils': 1.0.4 color-convert: 2.0.1 - '@visactor/vrender-core@1.0.41': + '@visactor/vrender-core@1.0.42': dependencies: '@visactor/vutils': 1.0.23 color-convert: 2.0.1 @@ -15066,21 +15052,21 @@ snapshots: lottie-web: 5.13.0 roughjs: 4.5.2 - '@visactor/vrender-kits@1.0.41': + '@visactor/vrender-kits@1.0.42': dependencies: '@resvg/resvg-js': 2.4.1 - '@visactor/vrender-core': 1.0.41 + '@visactor/vrender-core': 1.0.42 '@visactor/vutils': 1.0.23 gifuct-js: 2.1.2 lottie-web: 5.13.0 roughjs: 4.6.6 - '@visactor/vrender@1.0.41': + '@visactor/vrender@1.0.42': dependencies: - '@visactor/vrender-animate': 1.0.41 - '@visactor/vrender-components': 1.0.41 - '@visactor/vrender-core': 1.0.41 - '@visactor/vrender-kits': 1.0.41 + '@visactor/vrender-animate': 1.0.42 + '@visactor/vrender-components': 1.0.42 + '@visactor/vrender-core': 1.0.42 + '@visactor/vrender-kits': 1.0.42 '@visactor/vscale@0.18.18': dependencies: @@ -15495,7 +15481,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -18601,7 +18587,7 @@ snapshots: ajv: 6.12.6 chalk: 2.4.2 cross-spawn: 6.0.6 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) doctrine: 3.0.0 eslint-scope: 4.0.3 eslint-utils: 1.4.3 @@ -18642,7 +18628,7 @@ snapshots: ajv: 6.12.6 chalk: 2.4.2 cross-spawn: 6.0.6 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) doctrine: 3.0.0 eslint-scope: 5.1.1 eslint-utils: 1.4.3 @@ -18685,7 +18671,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -20136,7 +20122,7 @@ snapshots: dependencies: '@tootallnate/once': 1.1.2 agent-base: 6.0.2 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -20168,7 +20154,7 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -20762,7 +20748,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -20882,7 +20868,7 @@ snapshots: jest-environment-jsdom: 26.6.2(canvas@2.11.2(encoding@0.1.13)) jest-environment-node: 26.6.2 jest-get-type: 26.3.0 - jest-jasmine2: 26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@4.9.5)) + jest-jasmine2: 26.6.3 jest-regex-util: 26.0.0 jest-resolve: 26.6.2 jest-util: 26.6.2 @@ -20900,7 +20886,7 @@ snapshots: jest-config@26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5)): dependencies: '@babel/core': 7.20.12 - '@jest/test-sequencer': 26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5)) + '@jest/test-sequencer': 26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@4.9.5)) '@jest/types': 26.6.2 babel-jest: 26.6.3(@babel/core@7.20.12) chalk: 4.1.2 @@ -20910,7 +20896,7 @@ snapshots: jest-environment-jsdom: 26.6.2(canvas@2.11.2(encoding@0.1.13)) jest-environment-node: 26.6.2 jest-get-type: 26.3.0 - jest-jasmine2: 26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5)) + jest-jasmine2: 26.6.3 jest-regex-util: 26.0.0 jest-resolve: 26.6.2 jest-util: 26.6.2 @@ -21099,7 +21085,7 @@ snapshots: transitivePeerDependencies: - supports-color - jest-jasmine2@26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@4.9.5)): + jest-jasmine2@26.6.3: dependencies: '@babel/traverse': 7.28.5 '@jest/environment': 26.6.2 @@ -21120,38 +21106,7 @@ snapshots: pretty-format: 26.6.2 throat: 5.0.0 transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - ts-node - - utf-8-validate - - jest-jasmine2@26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5)): - dependencies: - '@babel/traverse': 7.28.5 - '@jest/environment': 26.6.2 - '@jest/source-map': 26.6.2 - '@jest/test-result': 26.6.2 - '@jest/types': 26.6.2 - '@types/node': 20.14.10 - chalk: 4.1.2 - co: 4.6.0 - expect: 26.6.2 - is-generator-fn: 2.1.0 - jest-each: 26.6.2 - jest-matcher-utils: 26.6.2 - jest-message-util: 26.6.2 - jest-runtime: 26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5)) - jest-snapshot: 26.6.2 - jest-util: 26.6.2 - pretty-format: 26.6.2 - throat: 5.0.0 - transitivePeerDependencies: - - bufferutil - - canvas - supports-color - - ts-node - - utf-8-validate jest-leak-detector@24.9.0: dependencies: @@ -21299,35 +21254,6 @@ snapshots: - ts-node - utf-8-validate - jest-runner@26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5)): - dependencies: - '@jest/console': 26.6.2 - '@jest/environment': 26.6.2 - '@jest/test-result': 26.6.2 - '@jest/types': 26.6.2 - '@types/node': 20.14.10 - chalk: 4.1.2 - emittery: 0.7.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-config: 26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5)) - jest-docblock: 26.0.0 - jest-haste-map: 26.6.2 - jest-leak-detector: 26.6.2 - jest-message-util: 26.6.2 - jest-resolve: 26.6.2 - jest-runtime: 26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5)) - jest-util: 26.6.2 - jest-worker: 26.6.2 - source-map-support: 0.5.21 - throat: 5.0.0 - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - ts-node - - utf-8-validate - jest-runtime@24.9.0: dependencies: '@jest/console': 24.9.0 @@ -21392,42 +21318,6 @@ snapshots: - ts-node - utf-8-validate - jest-runtime@26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5)): - dependencies: - '@jest/console': 26.6.2 - '@jest/environment': 26.6.2 - '@jest/fake-timers': 26.6.2 - '@jest/globals': 26.6.2 - '@jest/source-map': 26.6.2 - '@jest/test-result': 26.6.2 - '@jest/transform': 26.6.2 - '@jest/types': 26.6.2 - '@types/yargs': 15.0.20 - chalk: 4.1.2 - cjs-module-lexer: 0.6.0 - collect-v8-coverage: 1.0.3 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-config: 26.6.3(canvas@2.11.2(encoding@0.1.13))(ts-node@10.9.0(@types/node@20.14.10)(typescript@5.4.5)) - jest-haste-map: 26.6.2 - jest-message-util: 26.6.2 - jest-mock: 26.6.2 - jest-regex-util: 26.0.0 - jest-resolve: 26.6.2 - jest-snapshot: 26.6.2 - jest-util: 26.6.2 - jest-validate: 26.6.2 - slash: 3.0.0 - strip-bom: 4.0.0 - yargs: 15.4.1 - transitivePeerDependencies: - - bufferutil - - canvas - - supports-color - - ts-node - - utf-8-validate - jest-serializer@24.9.0: {} jest-serializer@26.6.2: @@ -22390,7 +22280,7 @@ snapshots: micromark@2.11.4: dependencies: - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) parse-entities: 2.0.0 transitivePeerDependencies: - supports-color @@ -25375,7 +25265,7 @@ snapshots: balanced-match: 1.0.2 chalk: 4.1.2 cosmiconfig: 6.0.0 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) execall: 2.0.0 file-entry-cache: 5.0.1 get-stdin: 8.0.0 @@ -25512,7 +25402,7 @@ snapshots: sumchecker@3.0.1: dependencies: - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -26483,7 +26373,7 @@ snapshots: vite-node@0.30.1(@types/node@20.14.10)(less@4.1.3)(sass@1.32.11)(stylus@0.54.8)(sugarss@2.0.0)(terser@5.17.1): dependencies: cac: 6.7.14 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) mlly: 1.8.0 pathe: 1.1.2 picocolors: 1.1.1 @@ -26527,7 +26417,7 @@ snapshots: cac: 6.7.14 chai: 4.5.0 concordance: 5.0.4 - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) local-pkg: 0.4.3 magic-string: 0.30.21 pathe: 1.1.2 @@ -26559,7 +26449,7 @@ snapshots: vue-eslint-parser@7.11.0(eslint@6.8.0): dependencies: - debug: 4.3.4(supports-color@6.1.0) + debug: 4.3.4(supports-color@9.4.0) eslint: 6.8.0 eslint-scope: 5.1.1 eslint-visitor-keys: 1.3.0 diff --git a/docs/package.json b/docs/package.json index 198055b2a9..b5f3f0fa87 100644 --- a/docs/package.json +++ b/docs/package.json @@ -19,8 +19,8 @@ "@visactor/vchart-theme": "~1.6.6", "@visactor/vmind": "1.2.4-alpha.5", "@visactor/vutils": "~1.0.23", - "@visactor/vrender": "~1.0.41", - "@visactor/vrender-kits": "~1.0.41", + "@visactor/vrender": "~1.0.42", + "@visactor/vrender-kits": "~1.0.42", "@visactor/vtable": "1.19.0-alpha.0", "@visactor/vtable-editors": "1.19.0-alpha.0", "@visactor/vtable-gantt": "1.19.0-alpha.0", diff --git a/packages/openinula-vchart/package.json b/packages/openinula-vchart/package.json index 1486242162..27a4cefb70 100644 --- a/packages/openinula-vchart/package.json +++ b/packages/openinula-vchart/package.json @@ -30,8 +30,8 @@ "dependencies": { "@visactor/vchart": "workspace:2.0.19", "@visactor/vutils": "~1.0.23", - "@visactor/vrender-core": "~1.0.41", - "@visactor/vrender-kits": "~1.0.41", + "@visactor/vrender-core": "~1.0.42", + "@visactor/vrender-kits": "~1.0.42", "react-is": "^18.2.0" }, "devDependencies": { diff --git a/packages/react-vchart/package.json b/packages/react-vchart/package.json index 96dc373865..b8fb0eaf90 100644 --- a/packages/react-vchart/package.json +++ b/packages/react-vchart/package.json @@ -31,8 +31,8 @@ "@visactor/vchart": "workspace:2.0.19", "@visactor/vchart-extension": "workspace:2.0.19", "@visactor/vutils": "~1.0.23", - "@visactor/vrender-core": "~1.0.41", - "@visactor/vrender-kits": "~1.0.41", + "@visactor/vrender-core": "~1.0.42", + "@visactor/vrender-kits": "~1.0.42", "react-is": "^18.2.0" }, "devDependencies": { @@ -83,4 +83,4 @@ "access": "public", "registry": "https://registry.npmjs.org/" } -} +} \ No newline at end of file diff --git a/packages/vchart-extension/package.json b/packages/vchart-extension/package.json index 34d8e8307c..bb5221459d 100644 --- a/packages/vchart-extension/package.json +++ b/packages/vchart-extension/package.json @@ -21,10 +21,10 @@ "start": "ts-node __tests__/runtime/browser/scripts/initVite.ts && vite serve __tests__/runtime/browser" }, "dependencies": { - "@visactor/vrender-core": "~1.0.41", - "@visactor/vrender-kits": "~1.0.41", - "@visactor/vrender-components": "~1.0.41", - "@visactor/vrender-animate": "~1.0.41", + "@visactor/vrender-core": "~1.0.42", + "@visactor/vrender-kits": "~1.0.42", + "@visactor/vrender-components": "~1.0.42", + "@visactor/vrender-animate": "~1.0.42", "@visactor/vchart": "workspace:2.0.19", "@visactor/vutils": "~1.0.23", "@visactor/vdataset": "~1.0.23", diff --git a/packages/vchart/__tests__/unit/component/legend/continuous-legend.test.ts b/packages/vchart/__tests__/unit/component/legend/continuous-legend.test.ts new file mode 100644 index 0000000000..bb1d168559 --- /dev/null +++ b/packages/vchart/__tests__/unit/component/legend/continuous-legend.test.ts @@ -0,0 +1,36 @@ +import { getContinuousLegendAttributes } from '../../../../src/component/legend/continuous/util'; + +describe('Continuous legend handlerText', () => { + test('should transform static handlerText style', () => { + const attrs = getContinuousLegendAttributes({ + type: 'size', + handlerText: { + style: { + angle: 90, + dx: 8 + } + } + } as any); + + expect(attrs.handlerText.style.dx).toBe(8); + expect(attrs.handlerText.style.angle).toBe(Math.PI / 2); + }); + + test('should preserve callback-based handlerText style', () => { + const attrs = getContinuousLegendAttributes({ + type: 'size', + handlerText: { + style: (value: number, position: 'start' | 'end') => ({ + angle: 180, + dx: value + (position === 'start' ? 1 : 2) + }) + } + } as any); + + const style = attrs.handlerText.style(2, 'start', {}); + + expect(typeof attrs.handlerText.style).toBe('function'); + expect(style.dx).toBe(3); + expect(style.angle).toBe(Math.PI); + }); +}); diff --git a/packages/vchart/package.json b/packages/vchart/package.json index 51bae70906..a3ad0cc7a0 100644 --- a/packages/vchart/package.json +++ b/packages/vchart/package.json @@ -122,14 +122,14 @@ "@visactor/vdataset": "~1.0.23", "@visactor/vscale": "~1.0.23", "@visactor/vlayouts": "~1.0.23", - "@visactor/vrender-core": "~1.0.41", - "@visactor/vrender-kits": "~1.0.41", - "@visactor/vrender-components": "~1.0.41", - "@visactor/vrender-animate": "~1.0.41", + "@visactor/vrender-core": "~1.0.42", + "@visactor/vrender-kits": "~1.0.42", + "@visactor/vrender-components": "~1.0.42", + "@visactor/vrender-animate": "~1.0.42", "@visactor/vutils-extension": "workspace:2.0.19" }, "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/" } -} +} \ No newline at end of file diff --git a/packages/vchart/src/component/legend/continuous/interface.ts b/packages/vchart/src/component/legend/continuous/interface.ts index a925a4916d..5159dc49b5 100644 --- a/packages/vchart/src/component/legend/continuous/interface.ts +++ b/packages/vchart/src/component/legend/continuous/interface.ts @@ -1,8 +1,15 @@ import type { IRectMarkSpec, ISymbolMarkSpec, ITextMarkSpec, StringOrNumber } from '../../../typings'; import type { ComponentThemeWithDirection } from '../../interface'; import type { ILegendCommonSpec, NoVisibleMarkStyle } from '../interface'; +import type { HandlerTextStyleContext } from '@visactor/vrender-components'; type Text = StringOrNumber; +type ContinuousLegendTextStyle = Omit, 'text'>; +type ContinuousLegendTextStyleCallback = ( + value: Text, + position: 'start' | 'end', + context: HandlerTextStyleContext +) => ContinuousLegendTextStyle | undefined; export type TextAttribute = { /** 是否展示 */ @@ -16,7 +23,7 @@ export type TextAttribute = { /** * 文本样式 */ - style?: Omit, 'text'>; + style?: ContinuousLegendTextStyle; }; export type HandlerTextAttribute = { @@ -35,7 +42,7 @@ export type HandlerTextAttribute = { /** * 文本样式 */ - style?: Omit, 'text'>; + style?: ContinuousLegendTextStyle | ContinuousLegendTextStyleCallback; }; // 连续图例通用配置 diff --git a/packages/vchart/src/component/legend/continuous/util.ts b/packages/vchart/src/component/legend/continuous/util.ts index 6182035c8a..5516a318a5 100644 --- a/packages/vchart/src/component/legend/continuous/util.ts +++ b/packages/vchart/src/component/legend/continuous/util.ts @@ -1,11 +1,32 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import type { IColorLegendSpec, ISizeLegendSpec } from './interface'; +import type { HandlerTextStyleContext } from '@visactor/vrender-components'; import { ColorContinuousLegend, SizeContinuousLegend } from '@visactor/vrender-components'; -import { isEmpty, isValid } from '@visactor/vutils'; +import { isEmpty, isFunction, isValid } from '@visactor/vutils'; import { mergeSpec } from '@visactor/vutils-extension'; import { transformComponentStyle, transformToGraphic } from '../../../util/style'; import { transformLegendTitleAttributes } from '../util'; +function transformHandlerText(handlerText: IColorLegendSpec['handlerText'] | ISizeLegendSpec['handlerText']) { + if (!handlerText) { + return handlerText; + } + + const nextHandlerText = { + ...handlerText + }; + const handlerTextStyle = handlerText.style; + + if (isFunction(handlerTextStyle)) { + nextHandlerText.style = (value: string | number, position: 'start' | 'end', context: HandlerTextStyleContext) => + transformToGraphic(handlerTextStyle(value, position, context)); + } else if (!isEmpty(handlerTextStyle)) { + nextHandlerText.style = transformToGraphic(handlerTextStyle); + } + + return nextHandlerText; +} + // 获取连续图例组件属性 export function getContinuousLegendAttributes(spec: IColorLegendSpec | ISizeLegendSpec) { const { @@ -68,7 +89,7 @@ export function getContinuousLegendAttributes(spec: IColorLegendSpec | ISizeLege attrs.startText = transformComponentStyle(startText); attrs.endText = transformComponentStyle(endText); - attrs.handlerText = transformComponentStyle(handlerText); + attrs.handlerText = transformHandlerText(handlerText); if (!isEmpty(sizeBackground)) { attrs.sizeBackground = transformToGraphic(sizeBackground); diff --git a/skills/vchart-development-assistant/references/type-details/ILegendSpec-Type-Definition.md b/skills/vchart-development-assistant/references/type-details/ILegendSpec-Type-Definition.md index e9caf08047..61f17a13fa 100644 --- a/skills/vchart-development-assistant/references/type-details/ILegendSpec-Type-Definition.md +++ b/skills/vchart-development-assistant/references/type-details/ILegendSpec-Type-Definition.md @@ -298,7 +298,14 @@ interface ILegendSpec { precision?: number; formatter?: (text: string | number) => string | number; space?: number; - style?: ITextMarkSpec; + style?: ITextMarkSpec | ((value: string | number, position: 'start' | 'end', context: { + layout?: 'horizontal' | 'vertical' | string; + align?: 'top' | 'bottom' | 'left' | 'right'; + railWidth: number; + railHeight: number; + handlerSize?: number; + slidable?: boolean; + }) => ITextMarkSpec | undefined); }; // Size legend specific @@ -404,7 +411,11 @@ const sizeLegend: ILegendSpec = { handlerText: { visible: true, precision: 0, - formatter: (value) => `${value}K` + formatter: (value) => `${value}K`, + style: (value, position) => ({ + dx: position === 'start' ? -6 : 6, + fill: Number(value) > 50 ? '#d03050' : '#666' + }) } }; ``` @@ -542,4 +553,4 @@ const multiLegendChart = { } ] }; -``` \ No newline at end of file +``` diff --git a/specs/008-fix-size-legend-handler-text/checklists/requirements.md b/specs/008-fix-size-legend-handler-text/checklists/requirements.md new file mode 100644 index 0000000000..8f75ef9e7b --- /dev/null +++ b/specs/008-fix-size-legend-handler-text/checklists/requirements.md @@ -0,0 +1,34 @@ +# Specification Quality Checklist: Size Legend Handler Text Layout + +**Purpose**: Validate specification completeness and quality before proceeding to planning +**Created**: 2026-03-20 +**Feature**: [/data00/home/lixuefei.1313/github/VChart/specs/008-fix-size-legend-handler-text/spec.md](/data00/home/lixuefei.1313/github/VChart/specs/008-fix-size-legend-handler-text/spec.md) + +## Content Quality + +- [x] No implementation details (languages, frameworks, APIs) +- [x] Focused on user value and business needs +- [x] Written for non-technical stakeholders +- [x] All mandatory sections completed + +## Requirement Completeness + +- [x] No [NEEDS CLARIFICATION] markers remain +- [x] Requirements are testable and unambiguous +- [x] Success criteria are measurable +- [x] Success criteria are technology-agnostic (no implementation details) +- [x] All acceptance scenarios are defined +- [x] Edge cases are identified +- [x] Scope is clearly bounded +- [x] Dependencies and assumptions identified + +## Feature Readiness + +- [x] All functional requirements have clear acceptance criteria +- [x] User scenarios cover primary flows +- [x] Feature meets measurable outcomes defined in Success Criteria +- [x] No implementation details leak into specification + +## Notes + +- Assumption: The issue scope is limited to the size legend `handlerText` behavior described in GitHub issue #4489 and does not change unrelated legend layout behavior. diff --git a/specs/008-fix-size-legend-handler-text/contracts/handler-text-style.md b/specs/008-fix-size-legend-handler-text/contracts/handler-text-style.md new file mode 100644 index 0000000000..735483e162 --- /dev/null +++ b/specs/008-fix-size-legend-handler-text/contracts/handler-text-style.md @@ -0,0 +1,14 @@ +# Contract: Continuous Legend Handler Text Style + +## Public Configuration Contract + +The `handlerText.style` field on continuous legends must accept: + +- A static text style object. +- A callback receiving continuous legend item context and returning a text style object. + +## Behavioral Guarantees + +- Static style values remain backward compatible. +- Callback return values are transformed with the same graphic conversion rules as static styles. +- Missing or partial callback return objects do not prevent handler text rendering. diff --git a/specs/008-fix-size-legend-handler-text/data-model.md b/specs/008-fix-size-legend-handler-text/data-model.md new file mode 100644 index 0000000000..2299be49e2 --- /dev/null +++ b/specs/008-fix-size-legend-handler-text/data-model.md @@ -0,0 +1,35 @@ +# Data Model: Size Legend Handler Text Layout + +## Entities + +### Continuous Legend Handler Text Config + +- Purpose: Represents the public `handlerText` configuration supplied in a continuous legend spec. +- Fields: + - `visible`: optional boolean toggle + - `precision`: optional numeric precision for displayed value + - `formatter`: optional text formatter + - `space`: optional spacing between handler and text + - `style`: either a static text style object or a callback returning a text style object +- Relationships: + - Belongs to `IContinuousLegendSpec` + - Is transformed into vrender continuous legend attributes by `getContinuousLegendAttributes` + +### Continuous Legend Render Attributes + +- Purpose: Runtime attributes passed from VChart to `@visactor/vrender-components`. +- Fields: + - `handlerText`: transformed handler text config + - `startText` / `endText`: sibling text configs using the same transformation helper + - `handlerStyle`, `railStyle`, `trackStyle`: other transformed style attributes +- Relationships: + - Derived from the legend spec + - Consumed by `SizeContinuousLegend` and `ColorContinuousLegend` + +## State Transitions + +1. User provides a continuous legend spec with `handlerText.style`. +2. VChart merges theme defaults and user spec. +3. `getContinuousLegendAttributes` transforms `handlerText` through `transformComponentStyle`. +4. The resulting static object or callback is passed to the continuous legend component. +5. During render or interaction updates, the component evaluates the style and applies it to the handler text. diff --git a/specs/008-fix-size-legend-handler-text/plan.md b/specs/008-fix-size-legend-handler-text/plan.md new file mode 100644 index 0000000000..5795facee4 --- /dev/null +++ b/specs/008-fix-size-legend-handler-text/plan.md @@ -0,0 +1,70 @@ +# Implementation Plan: Size Legend Handler Text Layout + +**Branch**: `008-fix-size-legend-handler-text` | **Date**: 2026-03-20 | **Spec**: [/data00/home/lixuefei.1313/github/VChart/specs/008-fix-size-legend-handler-text/spec.md](/data00/home/lixuefei.1313/github/VChart/specs/008-fix-size-legend-handler-text/spec.md) +**Input**: Feature specification from `/specs/008-fix-size-legend-handler-text/spec.md` + +## Summary + +Allow size legend `handlerText.style` to accept function-based values in the same way other legend style hooks already do, and add regression coverage proving the style callback is preserved through continuous legend attribute transformation. This gives chart authors a supported way to adjust handler text positioning dynamically and avoid overlap during handler movement. + +## Technical Context + +**Language/Version**: TypeScript 4.9.x +**Primary Dependencies**: `@visactor/vutils`, `@visactor/vutils-extension`, `@visactor/vrender-components` +**Storage**: N/A +**Testing**: Jest 26 unit tests under `packages/vchart/__tests__` +**Target Platform**: Cross-platform chart runtime for browser and mini-app wrappers +**Project Type**: Monorepo charting library package (`packages/vchart`) +**Performance Goals**: Preserve existing continuous legend interaction performance and stay within the constitution target for high-frequency interactions (<16ms budget) +**Constraints**: Keep backward compatibility for existing static `handlerText` config; avoid changing unrelated legend layout behavior; keep type/schema generation compatible with current public spec model +**Scale/Scope**: One public legend configuration path, one transformation utility, and focused unit regression coverage in `packages/vchart` + +## Constitution Check + +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* + +- Pass: Change is specification-driven and limited to the bug scope documented in the feature spec. +- Pass: Work stays inside `@visactor/vchart` package boundaries and does not introduce new cross-package coupling. +- Pass: The fix is a backward-compatible bug fix, aligned with patch-level behavior. +- Pass: A regression test will be added for the transformed continuous legend attributes, satisfying the constitution requirement for bug-fix coverage. +- Pass: No new runtime dependency or license review is required. + +## Project Structure + +### Documentation (this feature) + +```text +specs/008-fix-size-legend-handler-text/ +├── plan.md +├── research.md +├── data-model.md +├── quickstart.md +├── contracts/ +│ └── handler-text-style.md +└── tasks.md +``` + +### Source Code (repository root) + +```text +packages/vchart/ +├── src/ +│ ├── component/legend/continuous/ +│ │ ├── interface.ts +│ │ └── util.ts +│ └── util/ +│ └── style.ts +└── __tests__/ + └── unit/ + └── component/ + └── legend/ + └── continuous-legend.test.ts +``` + +**Structure Decision**: Implement the fix in `packages/vchart/src/component/legend/continuous/interface.ts` and verify behavior with a focused unit test under `packages/vchart/__tests__/unit/component/legend/`. Existing transformation logic in `packages/vchart/src/util/style.ts` is reused rather than duplicated. + +## Complexity Tracking + +| Violation | Why Needed | Simpler Alternative Rejected Because | +|-----------|------------|-------------------------------------| +| None | N/A | N/A | diff --git a/specs/008-fix-size-legend-handler-text/quickstart.md b/specs/008-fix-size-legend-handler-text/quickstart.md new file mode 100644 index 0000000000..62b70abe53 --- /dev/null +++ b/specs/008-fix-size-legend-handler-text/quickstart.md @@ -0,0 +1,14 @@ +# Quickstart: Verify Size Legend Handler Text Layout + +## Manual Verification + +1. Prepare a chart using the size legend demo referenced in issue #4489. +2. Configure `legend.size.handlerText.style` with a callback that changes text alignment or offset near the slider bounds. +3. Render the chart and drag the legend handler across the full range. +4. Confirm the handler text updates from the callback and remains readable near both ends of the slider. + +## Automated Verification + +1. Run the focused Jest test for the continuous legend regression. +2. Confirm that static `handlerText.style` still transforms as before. +3. Confirm that callback-based `handlerText.style` is preserved and its returned style is converted to graphic attributes. diff --git a/specs/008-fix-size-legend-handler-text/research.md b/specs/008-fix-size-legend-handler-text/research.md new file mode 100644 index 0000000000..70a2afdc38 --- /dev/null +++ b/specs/008-fix-size-legend-handler-text/research.md @@ -0,0 +1,25 @@ +# Research: Size Legend Handler Text Layout + +## Decision 1: Treat this as a VChart spec/type support gap, not a new layout engine feature + +- Decision: Extend the size legend `handlerText.style` contract so function-based style values are accepted and passed through the existing continuous legend transformation path. +- Rationale: `transformComponentStyle` already preserves `style` callbacks by wrapping them and converting returned values with `transformToGraphic`. The continuous legend path already calls `transformComponentStyle(handlerText)`, so the missing support is in the public type contract rather than the transform implementation itself. +- Alternatives considered: + - Modify continuous legend layout defaults to auto-avoid overlap in all cases. Rejected because the issue explicitly asks for function style support, and a generic layout rewrite is broader than the reported bug. + - Patch only documentation without changing the type contract. Rejected because TypeScript users would still be blocked from supplying the supported runtime shape. + +## Decision 2: Reuse the existing legend style callback signature pattern + +- Decision: Model the new `handlerText.style` callback after other legend callback-based style APIs that receive legend item context and return a style object. +- Rationale: Discrete legend already exposes callback-capable style values for legend item subparts, and `transformComponentStyle` is written against the `LegendItemDatum` callback shape expected by vrender components. +- Alternatives considered: + - Introduce a new callback signature specific to continuous legends. Rejected because it would add public API inconsistency and require additional transformation logic without evidence that vrender needs a different shape. + - Accept only full `handlerText` object callbacks. Rejected because the issue scope is narrower: `handlerText.style` should support function values. + +## Decision 3: Add a focused unit regression around attribute transformation + +- Decision: Add a unit test that verifies `getContinuousLegendAttributes` preserves function-based `handlerText.style` and transforms returned style values correctly. +- Rationale: This directly guards the bug path inside VChart without requiring browser-level screenshot infrastructure in this change. It also validates backward compatibility for static values in the same transformation layer. +- Alternatives considered: + - Add only end-to-end demo verification. Rejected because the constitution strongly prefers regression coverage for bug fixes. + - Test `transformComponentStyle` in isolation. Rejected because the user-facing contract is the continuous legend spec, and the regression should exercise the actual legend attribute assembly path. diff --git a/specs/008-fix-size-legend-handler-text/spec.md b/specs/008-fix-size-legend-handler-text/spec.md new file mode 100644 index 0000000000..cc16e69d49 --- /dev/null +++ b/specs/008-fix-size-legend-handler-text/spec.md @@ -0,0 +1,68 @@ +# Feature Specification: Size Legend Handler Text Layout + +**Feature Branch**: `008-fix-size-legend-handler-text` +**Created**: 2026-03-20 +**Status**: Draft +**Input**: User description: "Fix VChart issue #4489: size legend handlerText style should support function values and avoid overlapping text when sliding the handler" + +## User Scenarios & Testing *(mandatory)* + +### User Story 1 - Render Handler Text Without Overlap (Priority: P1) + +As a chart author using a size legend with a draggable handler, I want the handler text to stay readable while the handler moves so that the legend remains understandable during interaction. + +**Why this priority**: The reported bug is a visual regression in the primary interaction path for the size legend. Fixing readability during dragging is the direct user value of this issue. + +**Independent Test**: Open a chart with a size legend and drag the handler across its range. The handler text remains readable and does not overlap surrounding legend content throughout the interaction. + +**Acceptance Scenarios**: + +1. **Given** a size legend configured with handler text enabled, **When** the user drags the handler, **Then** the handler text remains visually separated from adjacent legend labels and marks. +2. **Given** a size legend with default handler text styling, **When** the handler is moved to either end of the slider range, **Then** the rendered text still stays readable and does not collide with neighboring content. + +--- + +### User Story 2 - Use Dynamic Handler Text Styling (Priority: P2) + +As a chart author, I want handler text style options to accept dynamic values so that I can tailor the text presentation to the active legend value and layout context. + +**Why this priority**: Supporting dynamic styling resolves the missing capability named in the bug report and enables authors to prevent layout problems in charts with varying content. + +**Independent Test**: Configure handler text style with value-dependent settings, render the chart, and verify that the handler text updates according to the current legend value while preserving legibility. + +**Acceptance Scenarios**: + +1. **Given** a size legend whose handler text style is configured with functions, **When** the legend renders or updates, **Then** the evaluated style is applied to the handler text for the current handler state. +2. **Given** a size legend whose handler text style mixes static values and functions, **When** the handler position changes, **Then** both static and dynamic style settings are honored without breaking rendering. + +### Edge Cases + +- What happens when the handler is dragged to the minimum or maximum extent of the size legend range? +- How does the system handle handler text style functions that return partial style objects or omit optional fields? +- What happens when the evaluated handler text content becomes longer than typical labels in the same legend? + +## Requirements *(mandatory)* + +### Functional Requirements + +- **FR-001**: The system MUST render size legend handler text in a way that remains readable while the handler is dragged across the legend range. +- **FR-002**: The system MUST prevent handler text from visually overlapping adjacent size legend content in normal dragging scenarios, including when the handler is at either range boundary. +- **FR-003**: Chart authors MUST be able to provide function-based values for size legend `handlerText` style settings. +- **FR-004**: The system MUST evaluate function-based `handlerText` style values against the current legend context whenever the handler text is rendered or updated. +- **FR-005**: The system MUST continue to support existing static `handlerText` style values without requiring configuration changes from current users. +- **FR-006**: The system MUST ignore unsupported or missing dynamic style fields gracefully and continue rendering the handler text. + +### Key Entities *(include if feature involves data)* + +- **Size Legend Handler**: The draggable control on a size legend that represents the active position within the legend range. +- **Handler Text Style**: The set of presentation properties applied to the size legend handler label, including both static and function-derived values. +- **Legend Render Context**: The runtime state used to resolve handler text appearance, such as current handler position or legend value. + +## Success Criteria *(mandatory)* + +### Measurable Outcomes + +- **SC-001**: In the reproduction for issue #4489, dragging the size legend handler no longer produces visible overlap between handler text and neighboring legend content. +- **SC-002**: Charts that already use static size legend `handlerText` styles continue to render without required option changes. +- **SC-003**: Charts configured with function-based size legend `handlerText` style values apply those values during initial render and after handler movement. +- **SC-004**: The bug fix can be verified with automated coverage or scripted examples that exercise both static and dynamic `handlerText` styling behavior. diff --git a/specs/008-fix-size-legend-handler-text/tasks.md b/specs/008-fix-size-legend-handler-text/tasks.md new file mode 100644 index 0000000000..7727625217 --- /dev/null +++ b/specs/008-fix-size-legend-handler-text/tasks.md @@ -0,0 +1,89 @@ +# Tasks: Size Legend Handler Text Layout + +**Input**: Design documents from `/specs/008-fix-size-legend-handler-text/` +**Prerequisites**: plan.md, spec.md, research.md, data-model.md, contracts/ + +**Tests**: Include focused unit regression coverage because this is a bug fix. + +**Organization**: Tasks are grouped by user story to enable independent implementation and testing. + +## Phase 1: Setup (Shared Infrastructure) + +**Purpose**: Confirm the feature scope and target files before code changes + +- [x] T001 Inspect continuous legend interfaces and existing style transformation flow in packages/vchart/src/component/legend/continuous/interface.ts and packages/vchart/src/component/legend/continuous/util.ts + +--- + +## Phase 2: Foundational (Blocking Prerequisites) + +**Purpose**: Establish the callback contract reused by the implementation and tests + +- [x] T002 Inspect existing callback-capable legend style types for reuse in packages/vchart/src/component/legend/discrete/interface.ts + +**Checkpoint**: Callback contract choice is settled and user story work can proceed + +--- + +## Phase 3: User Story 1 - Render Handler Text Without Overlap (Priority: P1) 🎯 MVP + +**Goal**: Preserve a supported path for dynamic handler text positioning so authors can keep size legend handler text readable during drag interactions + +**Independent Test**: Build continuous legend attributes from a size legend spec whose `handlerText.style` is a callback and confirm the callback survives transformation with returned offsets/styles converted correctly + +### Tests for User Story 1 + +- [x] T003 [P] [US1] Add continuous legend regression tests for static and callback `handlerText.style` in packages/vchart/__tests__/unit/component/legend/continuous-legend.test.ts + +### Implementation for User Story 1 + +- [x] T004 [US1] Extend continuous legend handler text style typings to accept callbacks in packages/vchart/src/component/legend/continuous/interface.ts +- [x] T005 [US1] Verify continuous legend attribute transformation preserves callback-based handler text styles in packages/vchart/src/component/legend/continuous/util.ts + +**Checkpoint**: Size legend handler text supports callback styling and the regression test proves the transform path + +--- + +## Phase 4: User Story 2 - Use Dynamic Handler Text Styling (Priority: P2) + +**Goal**: Keep the public configuration contract explicit and documented for function-based handler text styles + +**Independent Test**: Review the feature contract and ensure the public type now matches the supported runtime behavior + +### Implementation for User Story 2 + +- [x] T006 [US2] Update the feature contract notes to reflect callback-based `handlerText.style` support in specs/008-fix-size-legend-handler-text/contracts/handler-text-style.md + +**Checkpoint**: Public contract and implementation are aligned + +--- + +## Phase 5: Polish & Cross-Cutting Concerns + +**Purpose**: Validate the finished change and sync task tracking + +- [ ] T007 Run the focused Jest regression for continuous legend handler text support +- [x] T008 Mark completed tasks in specs/008-fix-size-legend-handler-text/tasks.md after implementation and verification + +--- + +## Dependencies & Execution Order + +- T001 -> T002 -> T003/T004/T005 +- T003 should be written before or alongside T004/T005 and must validate the user-facing behavior +- T006 depends on implementation decisions from T004/T005 +- T007 depends on T003-T006 +- T008 depends on all prior tasks completing + +## Parallel Opportunities + +- T003 can be prepared while T004 is being implemented, but both touch the same feature and should stay tightly coordinated + +## Implementation Strategy + +### MVP First + +1. Complete T001-T002 to lock the callback contract. +2. Complete T003-T005 to support callback-based `handlerText.style`. +3. Run T007 to verify the regression path. +4. Complete T006 and T008 to finish documentation and task tracking. diff --git a/tools/story-player/package.json b/tools/story-player/package.json index c632f49e03..5e687d15f2 100644 --- a/tools/story-player/package.json +++ b/tools/story-player/package.json @@ -56,10 +56,10 @@ "vite": "3.2.6" }, "dependencies": { - "@visactor/vrender-core": "~1.0.41", - "@visactor/vrender-kits": "~1.0.41", + "@visactor/vrender-core": "~1.0.42", + "@visactor/vrender-kits": "~1.0.42", "@visactor/vchart": "workspace:2.0.19", - "@visactor/vrender": "~1.0.41", + "@visactor/vrender": "~1.0.42", "@visactor/vutils": "~1.0.23" } } \ No newline at end of file