@carto/ps-react-ui 4.7.1 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/category-DwaeYjpX.js +656 -0
- package/dist/category-DwaeYjpX.js.map +1 -0
- package/dist/change-column-Cidl_M-4.js +1110 -0
- package/dist/change-column-Cidl_M-4.js.map +1 -0
- package/dist/data-zoom-layout-BH0LPwSy.js +28 -0
- package/dist/data-zoom-layout-BH0LPwSy.js.map +1 -0
- package/dist/echart-CU0KmClP.js +176 -0
- package/dist/echart-CU0KmClP.js.map +1 -0
- package/dist/exports-Cx-f6m6U.js +63 -0
- package/dist/exports-Cx-f6m6U.js.map +1 -0
- package/dist/formula-DuC0NQLH.js +79 -0
- package/dist/formula-DuC0NQLH.js.map +1 -0
- package/dist/markdown-BD1jcknS.js +8326 -0
- package/dist/markdown-BD1jcknS.js.map +1 -0
- package/dist/merge-options-DCkkHZIf.js +34 -0
- package/dist/merge-options-DCkkHZIf.js.map +1 -0
- package/dist/{styles-BYTyKQFP.js → option-builders-F-c9ELi1.js} +25 -45
- package/dist/option-builders-F-c9ELi1.js.map +1 -0
- package/dist/png-item-CS4z1iSH.js +45 -0
- package/dist/png-item-CS4z1iSH.js.map +1 -0
- package/dist/range-DsqTjSpg.js +186 -0
- package/dist/range-DsqTjSpg.js.map +1 -0
- package/dist/spread-CTuIXZSM.js +67 -0
- package/dist/spread-CTuIXZSM.js.map +1 -0
- package/dist/style-DVnT6HC1.js +131 -0
- package/dist/style-DVnT6HC1.js.map +1 -0
- package/dist/styles-cohnxh9F.js +23 -0
- package/dist/styles-cohnxh9F.js.map +1 -0
- package/dist/table-HIpXuq4G.js +390 -0
- package/dist/table-HIpXuq4G.js.map +1 -0
- package/dist/transforms-Cdx4fkU5.js +106 -0
- package/dist/transforms-Cdx4fkU5.js.map +1 -0
- package/dist/types/widgets/echart/utils.test.d.ts +1 -0
- package/dist/types/widgets/formula/config.test.d.ts +1 -0
- package/dist/types/widgets/stores/widget-store-branches.test.d.ts +1 -0
- package/dist/types/widgets/table/config.test.d.ts +1 -0
- package/dist/types/widgets-v2/actions/brush-toggle/brush-toggle.d.ts +56 -0
- package/dist/types/widgets-v2/actions/brush-toggle/index.d.ts +3 -0
- package/dist/types/widgets-v2/actions/brush-toggle/labels.d.ts +5 -0
- package/dist/types/widgets-v2/actions/brush-toggle/style.d.ts +12 -0
- package/dist/types/widgets-v2/actions/brush-toggle/transforms.d.ts +11 -0
- package/dist/types/widgets-v2/actions/brush-toggle/transforms.test.d.ts +1 -0
- package/dist/types/widgets-v2/actions/change-column/change-column-icon.d.ts +2 -0
- package/dist/types/widgets-v2/actions/change-column/change-column.d.ts +29 -0
- package/dist/types/widgets-v2/actions/change-column/index.d.ts +3 -0
- package/dist/types/widgets-v2/actions/change-column/labels.d.ts +5 -0
- package/dist/types/widgets-v2/actions/change-column/sortable-column-item.d.ts +14 -0
- package/dist/types/widgets-v2/actions/change-column/style.d.ts +33 -0
- package/dist/types/widgets-v2/actions/change-column/types.d.ts +10 -0
- package/dist/types/widgets-v2/actions/download/download.d.ts +18 -0
- package/dist/types/widgets-v2/actions/download/exports.d.ts +37 -0
- package/dist/types/widgets-v2/actions/download/icons.d.ts +12 -0
- package/dist/types/widgets-v2/actions/download/index.d.ts +6 -0
- package/dist/types/widgets-v2/actions/download/labels.d.ts +11 -0
- package/dist/types/widgets-v2/actions/download/png-item.d.ts +24 -0
- package/dist/types/widgets-v2/actions/download/style.d.ts +1 -0
- package/dist/types/widgets-v2/actions/download/types.d.ts +35 -0
- package/dist/types/widgets-v2/actions/fullscreen/fullscreen.d.ts +59 -0
- package/dist/types/widgets-v2/actions/fullscreen/index.d.ts +3 -0
- package/dist/types/widgets-v2/actions/fullscreen/labels.d.ts +5 -0
- package/dist/types/widgets-v2/actions/fullscreen/style.d.ts +48 -0
- package/dist/types/widgets-v2/actions/fullscreen/types.d.ts +14 -0
- package/dist/types/widgets-v2/actions/index.d.ts +9 -0
- package/dist/types/widgets-v2/actions/lock-selection/index.d.ts +3 -0
- package/dist/types/widgets-v2/actions/lock-selection/labels.d.ts +6 -0
- package/dist/types/widgets-v2/actions/lock-selection/lock-selection.d.ts +36 -0
- package/dist/types/widgets-v2/actions/lock-selection/style.d.ts +12 -0
- package/dist/types/widgets-v2/actions/lock-selection/transforms.d.ts +6 -0
- package/dist/types/widgets-v2/actions/relative-data/index.d.ts +3 -0
- package/dist/types/widgets-v2/actions/relative-data/labels.d.ts +5 -0
- package/dist/types/widgets-v2/actions/relative-data/relative-data.d.ts +39 -0
- package/dist/types/widgets-v2/actions/relative-data/style.d.ts +12 -0
- package/dist/types/widgets-v2/actions/relative-data/transforms.d.ts +30 -0
- package/dist/types/widgets-v2/actions/relative-data/transforms.test.d.ts +1 -0
- package/dist/types/widgets-v2/actions/searcher/filter.d.ts +6 -0
- package/dist/types/widgets-v2/actions/searcher/index.d.ts +4 -0
- package/dist/types/widgets-v2/actions/searcher/labels.d.ts +7 -0
- package/dist/types/widgets-v2/actions/searcher/searcher-toggle.d.ts +23 -0
- package/dist/types/widgets-v2/actions/searcher/searcher.d.ts +11 -0
- package/dist/types/widgets-v2/actions/searcher/style.d.ts +16 -0
- package/dist/types/widgets-v2/actions/stack-toggle/index.d.ts +3 -0
- package/dist/types/widgets-v2/actions/stack-toggle/labels.d.ts +5 -0
- package/dist/types/widgets-v2/actions/stack-toggle/stack-toggle.d.ts +10 -0
- package/dist/types/widgets-v2/actions/stack-toggle/style.d.ts +12 -0
- package/dist/types/widgets-v2/actions/stack-toggle/transforms.d.ts +13 -0
- package/dist/types/widgets-v2/actions/stack-toggle/transforms.test.d.ts +1 -0
- package/dist/types/widgets-v2/actions/zoom-toggle/index.d.ts +3 -0
- package/dist/types/widgets-v2/actions/zoom-toggle/labels.d.ts +5 -0
- package/dist/types/widgets-v2/actions/zoom-toggle/style.d.ts +12 -0
- package/dist/types/widgets-v2/actions/zoom-toggle/transforms.d.ts +51 -0
- package/dist/types/widgets-v2/actions/zoom-toggle/transforms.test.d.ts +1 -0
- package/dist/types/widgets-v2/actions/zoom-toggle/zoom-toggle.d.ts +35 -0
- package/dist/types/widgets-v2/bar/download.d.ts +24 -0
- package/dist/types/widgets-v2/bar/index.d.ts +4 -0
- package/dist/types/widgets-v2/bar/options.d.ts +43 -0
- package/dist/types/widgets-v2/bar/options.test.d.ts +1 -0
- package/dist/types/widgets-v2/bar/skeleton.d.ts +6 -0
- package/dist/types/widgets-v2/bar/types.d.ts +41 -0
- package/dist/types/widgets-v2/category/category-ui.d.ts +81 -0
- package/dist/types/widgets-v2/category/category.d.ts +48 -0
- package/dist/types/widgets-v2/category/components/category-bar-stacked.d.ts +28 -0
- package/dist/types/widgets-v2/category/components/category-bar.d.ts +23 -0
- package/dist/types/widgets-v2/category/components/category-legend.d.ts +18 -0
- package/dist/types/widgets-v2/category/components/category-row-multi.d.ts +31 -0
- package/dist/types/widgets-v2/category/components/category-row-other.d.ts +13 -0
- package/dist/types/widgets-v2/category/components/category-row-single.d.ts +28 -0
- package/dist/types/widgets-v2/category/components/category-row-stacked.d.ts +38 -0
- package/dist/types/widgets-v2/category/download.d.ts +16 -0
- package/dist/types/widgets-v2/category/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/category/index.d.ts +10 -0
- package/dist/types/widgets-v2/category/skeleton.d.ts +11 -0
- package/dist/types/widgets-v2/category/style.d.ts +166 -0
- package/dist/types/widgets-v2/category/types.d.ts +49 -0
- package/dist/types/widgets-v2/echart/echart-ui.d.ts +44 -0
- package/dist/types/widgets-v2/echart/echart.d.ts +75 -0
- package/dist/types/widgets-v2/echart/index.d.ts +4 -0
- package/dist/types/widgets-v2/echart/shared-resize-observer.d.ts +5 -0
- package/dist/types/widgets-v2/echart/shared-resize-observer.test.d.ts +1 -0
- package/dist/types/widgets-v2/echart/style.d.ts +6 -0
- package/dist/types/widgets-v2/echart/use-chart-selection.d.ts +51 -0
- package/dist/types/widgets-v2/formula/delta.d.ts +22 -0
- package/dist/types/widgets-v2/formula/download.d.ts +20 -0
- package/dist/types/widgets-v2/formula/formula-ui.d.ts +20 -0
- package/dist/types/widgets-v2/formula/formula.d.ts +8 -0
- package/dist/types/widgets-v2/formula/index.d.ts +11 -0
- package/dist/types/widgets-v2/formula/note.d.ts +11 -0
- package/dist/types/widgets-v2/formula/prefix.d.ts +12 -0
- package/dist/types/widgets-v2/formula/series.d.ts +16 -0
- package/dist/types/widgets-v2/formula/skeleton.d.ts +4 -0
- package/dist/types/widgets-v2/formula/style.d.ts +29 -0
- package/dist/types/widgets-v2/formula/suffix.d.ts +12 -0
- package/dist/types/widgets-v2/formula/types.d.ts +40 -0
- package/dist/types/widgets-v2/formula/value.d.ts +14 -0
- package/dist/types/widgets-v2/histogram/download.d.ts +17 -0
- package/dist/types/widgets-v2/histogram/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/histogram/index.d.ts +5 -0
- package/dist/types/widgets-v2/histogram/options.d.ts +42 -0
- package/dist/types/widgets-v2/histogram/options.test.d.ts +1 -0
- package/dist/types/widgets-v2/histogram/skeleton.d.ts +9 -0
- package/dist/types/widgets-v2/histogram/transforms.d.ts +17 -0
- package/dist/types/widgets-v2/histogram/transforms.test.d.ts +1 -0
- package/dist/types/widgets-v2/histogram/types.d.ts +47 -0
- package/dist/types/widgets-v2/index.d.ts +107 -0
- package/dist/types/widgets-v2/markdown/download.d.ts +16 -0
- package/dist/types/widgets-v2/markdown/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/markdown/index.d.ts +6 -0
- package/dist/types/widgets-v2/markdown/markdown-content.d.ts +34 -0
- package/dist/types/widgets-v2/markdown/markdown-ui.d.ts +12 -0
- package/dist/types/widgets-v2/markdown/markdown.d.ts +6 -0
- package/dist/types/widgets-v2/markdown/skeleton.d.ts +4 -0
- package/dist/types/widgets-v2/markdown/style.d.ts +61 -0
- package/dist/types/widgets-v2/markdown/types.d.ts +4 -0
- package/dist/types/widgets-v2/note/labels.d.ts +5 -0
- package/dist/types/widgets-v2/note/style.d.ts +26 -0
- package/dist/types/widgets-v2/note/widget-note.d.ts +46 -0
- package/dist/types/widgets-v2/pie/download.d.ts +17 -0
- package/dist/types/widgets-v2/pie/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/pie/index.d.ts +4 -0
- package/dist/types/widgets-v2/pie/options.d.ts +35 -0
- package/dist/types/widgets-v2/pie/options.test.d.ts +1 -0
- package/dist/types/widgets-v2/pie/skeleton.d.ts +4 -0
- package/dist/types/widgets-v2/pie/types.d.ts +50 -0
- package/dist/types/widgets-v2/provider/widget-provider.d.ts +32 -0
- package/dist/types/widgets-v2/range/index.d.ts +4 -0
- package/dist/types/widgets-v2/range/range-ui.d.ts +19 -0
- package/dist/types/widgets-v2/range/range.d.ts +19 -0
- package/dist/types/widgets-v2/range/skeleton.d.ts +9 -0
- package/dist/types/widgets-v2/range/style.d.ts +40 -0
- package/dist/types/widgets-v2/range/types.d.ts +37 -0
- package/dist/types/widgets-v2/scatterplot/download.d.ts +16 -0
- package/dist/types/widgets-v2/scatterplot/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/scatterplot/index.d.ts +5 -0
- package/dist/types/widgets-v2/scatterplot/options.d.ts +42 -0
- package/dist/types/widgets-v2/scatterplot/options.test.d.ts +1 -0
- package/dist/types/widgets-v2/scatterplot/skeleton.d.ts +12 -0
- package/dist/types/widgets-v2/scatterplot/transforms.d.ts +17 -0
- package/dist/types/widgets-v2/scatterplot/transforms.test.d.ts +1 -0
- package/dist/types/widgets-v2/scatterplot/types.d.ts +50 -0
- package/dist/types/widgets-v2/selection-summary/labels.d.ts +6 -0
- package/dist/types/widgets-v2/selection-summary/selection-summary.d.ts +22 -0
- package/dist/types/widgets-v2/selection-summary/style.d.ts +23 -0
- package/dist/types/widgets-v2/spread/download.d.ts +15 -0
- package/dist/types/widgets-v2/spread/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/spread/index.d.ts +6 -0
- package/dist/types/widgets-v2/spread/separator.d.ts +7 -0
- package/dist/types/widgets-v2/spread/skeleton.d.ts +9 -0
- package/dist/types/widgets-v2/spread/spread-ui.d.ts +18 -0
- package/dist/types/widgets-v2/spread/spread.d.ts +5 -0
- package/dist/types/widgets-v2/spread/types.d.ts +25 -0
- package/dist/types/widgets-v2/state/labels.d.ts +7 -0
- package/dist/types/widgets-v2/state/labels.test.d.ts +1 -0
- package/dist/types/widgets-v2/state/style.d.ts +19 -0
- package/dist/types/widgets-v2/state/widget-state.d.ts +19 -0
- package/dist/types/widgets-v2/stores/index.d.ts +8 -0
- package/dist/types/widgets-v2/stores/pipeline-middleware.d.ts +5 -0
- package/dist/types/widgets-v2/stores/pipeline-middleware.test.d.ts +1 -0
- package/dist/types/widgets-v2/stores/transforms.d.ts +4 -0
- package/dist/types/widgets-v2/stores/transforms.test.d.ts +1 -0
- package/dist/types/widgets-v2/stores/types.d.ts +55 -0
- package/dist/types/widgets-v2/stores/use-echart-instance.d.ts +15 -0
- package/dist/types/widgets-v2/stores/use-transform-enabled.d.ts +17 -0
- package/dist/types/widgets-v2/stores/use-transform.d.ts +12 -0
- package/dist/types/widgets-v2/stores/widget-context.d.ts +2 -0
- package/dist/types/widgets-v2/stores/widget-store-registry.d.ts +74 -0
- package/dist/types/widgets-v2/stores/widget-store-registry.test.d.ts +1 -0
- package/dist/types/widgets-v2/subheader/style.d.ts +10 -0
- package/dist/types/widgets-v2/subheader/subheader.d.ts +11 -0
- package/dist/types/widgets-v2/table/download.d.ts +18 -0
- package/dist/types/widgets-v2/table/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/table/helpers.d.ts +32 -0
- package/dist/types/widgets-v2/table/helpers.test.d.ts +1 -0
- package/dist/types/widgets-v2/table/index.d.ts +7 -0
- package/dist/types/widgets-v2/table/labels.d.ts +22 -0
- package/dist/types/widgets-v2/table/skeleton.d.ts +22 -0
- package/dist/types/widgets-v2/table/style.d.ts +44 -0
- package/dist/types/widgets-v2/table/table-ui.d.ts +38 -0
- package/dist/types/widgets-v2/table/table.d.ts +50 -0
- package/dist/types/widgets-v2/table/types.d.ts +37 -0
- package/dist/types/widgets-v2/test-utils.d.ts +52 -0
- package/dist/types/widgets-v2/timeseries/download.d.ts +17 -0
- package/dist/types/widgets-v2/timeseries/download.test.d.ts +1 -0
- package/dist/types/widgets-v2/timeseries/index.d.ts +4 -0
- package/dist/types/widgets-v2/timeseries/options.d.ts +39 -0
- package/dist/types/widgets-v2/timeseries/options.test.d.ts +1 -0
- package/dist/types/widgets-v2/timeseries/skeleton.d.ts +8 -0
- package/dist/types/widgets-v2/timeseries/types.d.ts +56 -0
- package/dist/types/widgets-v2/toolbox/labels.d.ts +5 -0
- package/dist/types/widgets-v2/toolbox/style.d.ts +30 -0
- package/dist/types/widgets-v2/toolbox/toolbox.d.ts +49 -0
- package/dist/types/widgets-v2/utils/data-zoom-layout.d.ts +11 -0
- package/dist/types/widgets-v2/utils/index.d.ts +2 -0
- package/dist/types/widgets-v2/utils/merge-options.d.ts +12 -0
- package/dist/types/widgets-v2/utils/merge-options.test.d.ts +1 -0
- package/dist/types/widgets-v2/wrapper/index.d.ts +4 -0
- package/dist/types/widgets-v2/wrapper/labels.d.ts +6 -0
- package/dist/types/widgets-v2/wrapper/style.d.ts +111 -0
- package/dist/types/widgets-v2/wrapper/widget-actions.d.ts +22 -0
- package/dist/types/widgets-v2/wrapper/widget-content.d.ts +12 -0
- package/dist/types/widgets-v2/wrapper/widget-wrapper.d.ts +51 -0
- package/dist/use-transform-DXPN3nY7.js +110 -0
- package/dist/use-transform-DXPN3nY7.js.map +1 -0
- package/dist/widget-context-DTGO0Yta.js +13 -0
- package/dist/widget-context-DTGO0Yta.js.map +1 -0
- package/dist/widget-store-registry-_W4Z4xp-.js +178 -0
- package/dist/widget-store-registry-_W4Z4xp-.js.map +1 -0
- package/dist/widgets/bar.js +14 -13
- package/dist/widgets/bar.js.map +1 -1
- package/dist/widgets/histogram.js +8 -7
- package/dist/widgets/histogram.js.map +1 -1
- package/dist/widgets/pie.js +19 -18
- package/dist/widgets/pie.js.map +1 -1
- package/dist/widgets/scatterplot.js +8 -7
- package/dist/widgets/scatterplot.js.map +1 -1
- package/dist/widgets/timeseries.js +11 -10
- package/dist/widgets/timeseries.js.map +1 -1
- package/dist/widgets/utils.js +8 -7
- package/dist/widgets/utils.js.map +1 -1
- package/dist/widgets-v2/actions.js +43 -0
- package/dist/widgets-v2/actions.js.map +1 -0
- package/dist/widgets-v2/bar.js +327 -0
- package/dist/widgets-v2/bar.js.map +1 -0
- package/dist/widgets-v2/category.js +104 -0
- package/dist/widgets-v2/category.js.map +1 -0
- package/dist/widgets-v2/echart.js +57 -0
- package/dist/widgets-v2/echart.js.map +1 -0
- package/dist/widgets-v2/formula.js +74 -0
- package/dist/widgets-v2/formula.js.map +1 -0
- package/dist/widgets-v2/histogram.js +350 -0
- package/dist/widgets-v2/histogram.js.map +1 -0
- package/dist/widgets-v2/markdown.js +68 -0
- package/dist/widgets-v2/markdown.js.map +1 -0
- package/dist/widgets-v2/pie.js +381 -0
- package/dist/widgets-v2/pie.js.map +1 -0
- package/dist/widgets-v2/range.js +52 -0
- package/dist/widgets-v2/range.js.map +1 -0
- package/dist/widgets-v2/scatterplot.js +405 -0
- package/dist/widgets-v2/scatterplot.js.map +1 -0
- package/dist/widgets-v2/spread.js +72 -0
- package/dist/widgets-v2/spread.js.map +1 -0
- package/dist/widgets-v2/stores.js +42 -0
- package/dist/widgets-v2/stores.js.map +1 -0
- package/dist/widgets-v2/table.js +78 -0
- package/dist/widgets-v2/table.js.map +1 -0
- package/dist/widgets-v2/timeseries.js +352 -0
- package/dist/widgets-v2/timeseries.js.map +1 -0
- package/dist/widgets-v2/utils.js +7 -0
- package/dist/widgets-v2/utils.js.map +1 -0
- package/dist/widgets-v2.js +953 -0
- package/dist/widgets-v2.js.map +1 -0
- package/package.json +73 -5
- package/src/components/lasso-tool/chip.test.tsx +176 -0
- package/src/components/lasso-tool/lasso-tool-inline.test.tsx +171 -0
- package/src/components/lasso-tool/lasso-tool.test.tsx +198 -0
- package/src/components/list-data/list-data.test.tsx +73 -0
- package/src/components/no-data-alert/no-data-alert.test.tsx +38 -0
- package/src/components/responsive-drawer/responsive-drawer.test.tsx +68 -0
- package/src/widgets/actions/brush-toggle/brush-overlay.test.tsx +465 -0
- package/src/widgets/actions/brush-toggle/brush-toggle.test.tsx +208 -0
- package/src/widgets/actions/change-column/change-column-dnd.test.tsx +193 -0
- package/src/widgets/actions/change-column/sortable-column-item.test.tsx +124 -0
- package/src/widgets/actions/zoom-toggle/zoom-toggle.test.tsx +322 -0
- package/src/widgets/category/components/category-rows.test.tsx +213 -0
- package/src/widgets/echart/utils.test.ts +277 -0
- package/src/widgets/formula/config.test.ts +37 -0
- package/src/widgets/range/components/range-item.test.tsx +243 -0
- package/src/widgets/stores/widget-store-branches.test.ts +275 -0
- package/src/widgets/table/config.test.ts +65 -0
- package/src/widgets/utils/chart-config/option-builders.test.ts +188 -0
- package/src/widgets-v2/PERFORMANCE.md +189 -0
- package/src/widgets-v2/actions/brush-toggle/brush-toggle.test.tsx +180 -0
- package/src/widgets-v2/actions/brush-toggle/brush-toggle.tsx +154 -0
- package/src/widgets-v2/actions/brush-toggle/index.ts +3 -0
- package/src/widgets-v2/actions/brush-toggle/labels.ts +9 -0
- package/src/widgets-v2/actions/brush-toggle/style.ts +11 -0
- package/src/widgets-v2/actions/brush-toggle/transforms.test.ts +47 -0
- package/src/widgets-v2/actions/brush-toggle/transforms.ts +31 -0
- package/src/widgets-v2/actions/change-column/change-column-icon.tsx +14 -0
- package/src/widgets-v2/actions/change-column/change-column.test.tsx +59 -0
- package/src/widgets-v2/actions/change-column/change-column.tsx +180 -0
- package/src/widgets-v2/actions/change-column/index.ts +7 -0
- package/src/widgets-v2/actions/change-column/labels.ts +9 -0
- package/src/widgets-v2/actions/change-column/sortable-column-item.tsx +56 -0
- package/src/widgets-v2/actions/change-column/style.ts +32 -0
- package/src/widgets-v2/actions/change-column/types.ts +11 -0
- package/src/widgets-v2/actions/download/download.test.tsx +327 -0
- package/src/widgets-v2/actions/download/download.tsx +144 -0
- package/src/widgets-v2/actions/download/exports.test.tsx +198 -0
- package/src/widgets-v2/actions/download/exports.ts +115 -0
- package/src/widgets-v2/actions/download/icons.tsx +26 -0
- package/src/widgets-v2/actions/download/index.ts +13 -0
- package/src/widgets-v2/actions/download/labels.ts +16 -0
- package/src/widgets-v2/actions/download/png-item.test.tsx +72 -0
- package/src/widgets-v2/actions/download/png-item.tsx +52 -0
- package/src/widgets-v2/actions/download/style.ts +3 -0
- package/src/widgets-v2/actions/download/types.ts +32 -0
- package/src/widgets-v2/actions/fullscreen/fullscreen.test.tsx +150 -0
- package/src/widgets-v2/actions/fullscreen/fullscreen.tsx +230 -0
- package/src/widgets-v2/actions/fullscreen/index.ts +7 -0
- package/src/widgets-v2/actions/fullscreen/labels.ts +9 -0
- package/src/widgets-v2/actions/fullscreen/style.ts +59 -0
- package/src/widgets-v2/actions/fullscreen/types.ts +15 -0
- package/src/widgets-v2/actions/index.ts +82 -0
- package/src/widgets-v2/actions/lock-selection/index.ts +10 -0
- package/src/widgets-v2/actions/lock-selection/labels.ts +11 -0
- package/src/widgets-v2/actions/lock-selection/lock-selection.test.tsx +187 -0
- package/src/widgets-v2/actions/lock-selection/lock-selection.tsx +130 -0
- package/src/widgets-v2/actions/lock-selection/style.ts +11 -0
- package/src/widgets-v2/actions/lock-selection/transforms.ts +27 -0
- package/src/widgets-v2/actions/relative-data/index.ts +3 -0
- package/src/widgets-v2/actions/relative-data/labels.ts +9 -0
- package/src/widgets-v2/actions/relative-data/relative-data.test.tsx +71 -0
- package/src/widgets-v2/actions/relative-data/relative-data.tsx +107 -0
- package/src/widgets-v2/actions/relative-data/style.ts +11 -0
- package/src/widgets-v2/actions/relative-data/transforms.test.ts +151 -0
- package/src/widgets-v2/actions/relative-data/transforms.ts +70 -0
- package/src/widgets-v2/actions/searcher/filter.ts +28 -0
- package/src/widgets-v2/actions/searcher/index.ts +8 -0
- package/src/widgets-v2/actions/searcher/labels.ts +13 -0
- package/src/widgets-v2/actions/searcher/searcher-toggle.tsx +91 -0
- package/src/widgets-v2/actions/searcher/searcher.test.tsx +92 -0
- package/src/widgets-v2/actions/searcher/searcher.tsx +112 -0
- package/src/widgets-v2/actions/searcher/style.ts +15 -0
- package/src/widgets-v2/actions/stack-toggle/index.ts +3 -0
- package/src/widgets-v2/actions/stack-toggle/labels.ts +9 -0
- package/src/widgets-v2/actions/stack-toggle/stack-toggle.test.tsx +61 -0
- package/src/widgets-v2/actions/stack-toggle/stack-toggle.tsx +54 -0
- package/src/widgets-v2/actions/stack-toggle/style.ts +11 -0
- package/src/widgets-v2/actions/stack-toggle/transforms.test.ts +43 -0
- package/src/widgets-v2/actions/stack-toggle/transforms.ts +25 -0
- package/src/widgets-v2/actions/zoom-toggle/index.ts +9 -0
- package/src/widgets-v2/actions/zoom-toggle/labels.ts +9 -0
- package/src/widgets-v2/actions/zoom-toggle/style.ts +11 -0
- package/src/widgets-v2/actions/zoom-toggle/transforms.test.ts +148 -0
- package/src/widgets-v2/actions/zoom-toggle/transforms.ts +171 -0
- package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.test.tsx +107 -0
- package/src/widgets-v2/actions/zoom-toggle/zoom-toggle.tsx +106 -0
- package/src/widgets-v2/bar/download.test.tsx +91 -0
- package/src/widgets-v2/bar/download.tsx +66 -0
- package/src/widgets-v2/bar/index.ts +10 -0
- package/src/widgets-v2/bar/options.test.ts +317 -0
- package/src/widgets-v2/bar/options.ts +326 -0
- package/src/widgets-v2/bar/skeleton.test.tsx +19 -0
- package/src/widgets-v2/bar/skeleton.tsx +69 -0
- package/src/widgets-v2/bar/types.ts +46 -0
- package/src/widgets-v2/category/category-ui.test.tsx +746 -0
- package/src/widgets-v2/category/category-ui.tsx +389 -0
- package/src/widgets-v2/category/category.relative-data.test.tsx +107 -0
- package/src/widgets-v2/category/category.stack-toggle.test.tsx +85 -0
- package/src/widgets-v2/category/category.test.tsx +305 -0
- package/src/widgets-v2/category/category.tsx +121 -0
- package/src/widgets-v2/category/components/category-bar-stacked.test.tsx +121 -0
- package/src/widgets-v2/category/components/category-bar-stacked.tsx +73 -0
- package/src/widgets-v2/category/components/category-bar.test.tsx +64 -0
- package/src/widgets-v2/category/components/category-bar.tsx +49 -0
- package/src/widgets-v2/category/components/category-legend.test.tsx +51 -0
- package/src/widgets-v2/category/components/category-legend.tsx +39 -0
- package/src/widgets-v2/category/components/category-row-multi.tsx +86 -0
- package/src/widgets-v2/category/components/category-row-other.test.tsx +28 -0
- package/src/widgets-v2/category/components/category-row-other.tsx +33 -0
- package/src/widgets-v2/category/components/category-row-single.tsx +76 -0
- package/src/widgets-v2/category/components/category-row-stacked.test.tsx +244 -0
- package/src/widgets-v2/category/components/category-row-stacked.tsx +99 -0
- package/src/widgets-v2/category/download.test.ts +71 -0
- package/src/widgets-v2/category/download.ts +54 -0
- package/src/widgets-v2/category/index.ts +32 -0
- package/src/widgets-v2/category/skeleton.test.tsx +26 -0
- package/src/widgets-v2/category/skeleton.tsx +74 -0
- package/src/widgets-v2/category/style.ts +290 -0
- package/src/widgets-v2/category/types.ts +54 -0
- package/src/widgets-v2/echart/echart-ui.test.tsx +232 -0
- package/src/widgets-v2/echart/echart-ui.tsx +184 -0
- package/src/widgets-v2/echart/echart.test.tsx +229 -0
- package/src/widgets-v2/echart/echart.tsx +199 -0
- package/src/widgets-v2/echart/index.ts +22 -0
- package/src/widgets-v2/echart/shared-resize-observer.test.ts +91 -0
- package/src/widgets-v2/echart/shared-resize-observer.ts +56 -0
- package/src/widgets-v2/echart/style.ts +8 -0
- package/src/widgets-v2/echart/use-chart-selection.test.tsx +118 -0
- package/src/widgets-v2/echart/use-chart-selection.ts +115 -0
- package/src/widgets-v2/formula/delta.tsx +61 -0
- package/src/widgets-v2/formula/download.test.tsx +65 -0
- package/src/widgets-v2/formula/download.tsx +69 -0
- package/src/widgets-v2/formula/formula-ui.test.tsx +91 -0
- package/src/widgets-v2/formula/formula-ui.tsx +66 -0
- package/src/widgets-v2/formula/formula.test.tsx +50 -0
- package/src/widgets-v2/formula/formula.tsx +34 -0
- package/src/widgets-v2/formula/index.ts +17 -0
- package/src/widgets-v2/formula/note.tsx +25 -0
- package/src/widgets-v2/formula/prefix.tsx +25 -0
- package/src/widgets-v2/formula/series.tsx +67 -0
- package/src/widgets-v2/formula/skeleton.test.tsx +21 -0
- package/src/widgets-v2/formula/skeleton.tsx +27 -0
- package/src/widgets-v2/formula/style.ts +31 -0
- package/src/widgets-v2/formula/subcomponents.test.tsx +107 -0
- package/src/widgets-v2/formula/suffix.tsx +25 -0
- package/src/widgets-v2/formula/types.ts +44 -0
- package/src/widgets-v2/formula/value.tsx +31 -0
- package/src/widgets-v2/histogram/download.test.ts +94 -0
- package/src/widgets-v2/histogram/download.ts +60 -0
- package/src/widgets-v2/histogram/index.ts +10 -0
- package/src/widgets-v2/histogram/options.test.ts +304 -0
- package/src/widgets-v2/histogram/options.ts +337 -0
- package/src/widgets-v2/histogram/skeleton.test.tsx +16 -0
- package/src/widgets-v2/histogram/skeleton.tsx +70 -0
- package/src/widgets-v2/histogram/transforms.test.ts +46 -0
- package/src/widgets-v2/histogram/transforms.ts +30 -0
- package/src/widgets-v2/histogram/types.ts +51 -0
- package/src/widgets-v2/index.ts +201 -0
- package/src/widgets-v2/markdown/download.test.ts +66 -0
- package/src/widgets-v2/markdown/download.ts +53 -0
- package/src/widgets-v2/markdown/index.ts +6 -0
- package/src/widgets-v2/markdown/markdown-content.test.tsx +155 -0
- package/src/widgets-v2/markdown/markdown-content.tsx +72 -0
- package/src/widgets-v2/markdown/markdown-ui.test.tsx +75 -0
- package/src/widgets-v2/markdown/markdown-ui.tsx +55 -0
- package/src/widgets-v2/markdown/markdown.test.tsx +39 -0
- package/src/widgets-v2/markdown/markdown.tsx +17 -0
- package/src/widgets-v2/markdown/skeleton.test.tsx +15 -0
- package/src/widgets-v2/markdown/skeleton.tsx +32 -0
- package/src/widgets-v2/markdown/style.ts +53 -0
- package/src/widgets-v2/markdown/types.ts +4 -0
- package/src/widgets-v2/note/labels.ts +9 -0
- package/src/widgets-v2/note/style.ts +26 -0
- package/src/widgets-v2/note/widget-note.test.tsx +158 -0
- package/src/widgets-v2/note/widget-note.tsx +172 -0
- package/src/widgets-v2/pie/download.test.ts +78 -0
- package/src/widgets-v2/pie/download.ts +55 -0
- package/src/widgets-v2/pie/index.ts +10 -0
- package/src/widgets-v2/pie/options.test.ts +585 -0
- package/src/widgets-v2/pie/options.ts +509 -0
- package/src/widgets-v2/pie/skeleton.test.tsx +17 -0
- package/src/widgets-v2/pie/skeleton.tsx +32 -0
- package/src/widgets-v2/pie/types.ts +55 -0
- package/src/widgets-v2/provider/widget-provider.test.tsx +119 -0
- package/src/widgets-v2/provider/widget-provider.tsx +111 -0
- package/src/widgets-v2/range/index.ts +4 -0
- package/src/widgets-v2/range/range-ui.test.tsx +130 -0
- package/src/widgets-v2/range/range-ui.tsx +211 -0
- package/src/widgets-v2/range/range.test.tsx +68 -0
- package/src/widgets-v2/range/range.tsx +46 -0
- package/src/widgets-v2/range/skeleton.test.tsx +17 -0
- package/src/widgets-v2/range/skeleton.tsx +47 -0
- package/src/widgets-v2/range/style.ts +41 -0
- package/src/widgets-v2/range/types.ts +37 -0
- package/src/widgets-v2/scatterplot/download.test.ts +71 -0
- package/src/widgets-v2/scatterplot/download.ts +54 -0
- package/src/widgets-v2/scatterplot/index.ts +11 -0
- package/src/widgets-v2/scatterplot/options.test.ts +399 -0
- package/src/widgets-v2/scatterplot/options.ts +421 -0
- package/src/widgets-v2/scatterplot/skeleton.test.tsx +17 -0
- package/src/widgets-v2/scatterplot/skeleton.tsx +84 -0
- package/src/widgets-v2/scatterplot/transforms.test.ts +97 -0
- package/src/widgets-v2/scatterplot/transforms.ts +38 -0
- package/src/widgets-v2/scatterplot/types.ts +55 -0
- package/src/widgets-v2/selection-summary/labels.ts +11 -0
- package/src/widgets-v2/selection-summary/selection-summary.test.tsx +53 -0
- package/src/widgets-v2/selection-summary/selection-summary.tsx +62 -0
- package/src/widgets-v2/selection-summary/style.ts +23 -0
- package/src/widgets-v2/spread/download.test.ts +64 -0
- package/src/widgets-v2/spread/download.ts +59 -0
- package/src/widgets-v2/spread/index.ts +6 -0
- package/src/widgets-v2/spread/separator.tsx +11 -0
- package/src/widgets-v2/spread/skeleton.test.tsx +17 -0
- package/src/widgets-v2/spread/skeleton.tsx +38 -0
- package/src/widgets-v2/spread/spread-ui.test.tsx +108 -0
- package/src/widgets-v2/spread/spread-ui.tsx +52 -0
- package/src/widgets-v2/spread/spread.test.tsx +50 -0
- package/src/widgets-v2/spread/spread.tsx +31 -0
- package/src/widgets-v2/spread/types.ts +27 -0
- package/src/widgets-v2/state/labels.test.ts +33 -0
- package/src/widgets-v2/state/labels.ts +20 -0
- package/src/widgets-v2/state/style.ts +25 -0
- package/src/widgets-v2/state/widget-state.test.tsx +294 -0
- package/src/widgets-v2/state/widget-state.tsx +184 -0
- package/src/widgets-v2/stores/index.ts +49 -0
- package/src/widgets-v2/stores/pipeline-middleware.test.ts +187 -0
- package/src/widgets-v2/stores/pipeline-middleware.ts +91 -0
- package/src/widgets-v2/stores/transforms.test.ts +162 -0
- package/src/widgets-v2/stores/transforms.ts +70 -0
- package/src/widgets-v2/stores/types.ts +64 -0
- package/src/widgets-v2/stores/use-echart-instance.test.tsx +91 -0
- package/src/widgets-v2/stores/use-echart-instance.ts +29 -0
- package/src/widgets-v2/stores/use-transform-enabled.test.tsx +127 -0
- package/src/widgets-v2/stores/use-transform-enabled.ts +25 -0
- package/src/widgets-v2/stores/use-transform.test.tsx +262 -0
- package/src/widgets-v2/stores/use-transform.ts +158 -0
- package/src/widgets-v2/stores/widget-context.test.tsx +58 -0
- package/src/widgets-v2/stores/widget-context.ts +15 -0
- package/src/widgets-v2/stores/widget-store-registry.test.ts +292 -0
- package/src/widgets-v2/stores/widget-store-registry.ts +248 -0
- package/src/widgets-v2/subheader/style.ts +12 -0
- package/src/widgets-v2/subheader/subheader.test.tsx +30 -0
- package/src/widgets-v2/subheader/subheader.tsx +16 -0
- package/src/widgets-v2/table/download.test.ts +75 -0
- package/src/widgets-v2/table/download.ts +47 -0
- package/src/widgets-v2/table/helpers.test.ts +214 -0
- package/src/widgets-v2/table/helpers.ts +136 -0
- package/src/widgets-v2/table/index.ts +23 -0
- package/src/widgets-v2/table/labels.tsx +41 -0
- package/src/widgets-v2/table/skeleton.test.tsx +26 -0
- package/src/widgets-v2/table/skeleton.tsx +65 -0
- package/src/widgets-v2/table/style.ts +46 -0
- package/src/widgets-v2/table/table-ui.test.tsx +200 -0
- package/src/widgets-v2/table/table-ui.tsx +331 -0
- package/src/widgets-v2/table/table.test.tsx +119 -0
- package/src/widgets-v2/table/table.tsx +174 -0
- package/src/widgets-v2/table/types.ts +44 -0
- package/src/widgets-v2/test-utils.ts +107 -0
- package/src/widgets-v2/timeseries/download.test.ts +95 -0
- package/src/widgets-v2/timeseries/download.ts +86 -0
- package/src/widgets-v2/timeseries/index.ts +10 -0
- package/src/widgets-v2/timeseries/options.test.ts +379 -0
- package/src/widgets-v2/timeseries/options.ts +341 -0
- package/src/widgets-v2/timeseries/skeleton.test.tsx +13 -0
- package/src/widgets-v2/timeseries/skeleton.tsx +76 -0
- package/src/widgets-v2/timeseries/types.ts +61 -0
- package/src/widgets-v2/toolbox/labels.ts +9 -0
- package/src/widgets-v2/toolbox/style.ts +33 -0
- package/src/widgets-v2/toolbox/toolbox.test.tsx +200 -0
- package/src/widgets-v2/toolbox/toolbox.tsx +309 -0
- package/src/widgets-v2/utils/data-zoom-layout.ts +26 -0
- package/src/widgets-v2/utils/index.ts +2 -0
- package/src/widgets-v2/utils/merge-options.test.ts +52 -0
- package/src/widgets-v2/utils/merge-options.ts +50 -0
- package/src/widgets-v2/wrapper/index.ts +14 -0
- package/src/widgets-v2/wrapper/labels.ts +11 -0
- package/src/widgets-v2/wrapper/style.ts +134 -0
- package/src/widgets-v2/wrapper/widget-actions.test.tsx +52 -0
- package/src/widgets-v2/wrapper/widget-actions.tsx +43 -0
- package/src/widgets-v2/wrapper/widget-content.test.tsx +27 -0
- package/src/widgets-v2/wrapper/widget-content.tsx +29 -0
- package/src/widgets-v2/wrapper/widget-wrapper.test.tsx +159 -0
- package/src/widgets-v2/wrapper/widget-wrapper.tsx +178 -0
- package/dist/styles-BYTyKQFP.js.map +0 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** A single row in a Category widget. `name` is the category key. */
|
|
2
|
+
export interface CategoryDataItem {
|
|
3
|
+
name: string | number
|
|
4
|
+
value: number
|
|
5
|
+
/** Optional per-row color override (wins over series + palette). */
|
|
6
|
+
color?: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Category widget data — array of series, each a flat list of `{name, value}`.
|
|
11
|
+
*
|
|
12
|
+
* Single-series (`data.length === 1`) renders one bar per row.
|
|
13
|
+
* Multi-series (`data.length > 1`) groups items by `name` across series and
|
|
14
|
+
* renders N vertically-stacked bars per row, with a sticky legend at the
|
|
15
|
+
* bottom when `series` metadata is supplied.
|
|
16
|
+
*/
|
|
17
|
+
export type CategoryWidgetData = readonly (readonly CategoryDataItem[])[]
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The keyspace of selectable items. Per the destination-owned selection
|
|
21
|
+
* principle, the consumer keeps this in their own store.
|
|
22
|
+
*/
|
|
23
|
+
export type CategoryKey = string | number
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Per-series metadata. Supplied to enable the legend and override the
|
|
27
|
+
* auto-assigned palette color for a given series index. Length should
|
|
28
|
+
* mirror `data.length` for a full legend; shorter/longer arrays degrade
|
|
29
|
+
* gracefully (extra entries ignored; missing entries get palette
|
|
30
|
+
* defaults and are absent from the legend).
|
|
31
|
+
*/
|
|
32
|
+
export interface CategorySeriesConfig {
|
|
33
|
+
name: string
|
|
34
|
+
color?: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Labels for the "Other" overflow row (rendered when `data.length`
|
|
39
|
+
* exceeds `maxItems`). `{count}` in `otherCount` is replaced with the
|
|
40
|
+
* number of hidden categories.
|
|
41
|
+
*/
|
|
42
|
+
export interface CategoryLabels {
|
|
43
|
+
other?: string
|
|
44
|
+
otherCount?: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Visual density of the bar primitive. `'small'` (default) keeps the
|
|
49
|
+
* original 4px-tall, fully-rounded track. `'medium'` renders a 12px-tall
|
|
50
|
+
* track with a 2px corner radius (squarer affordance for denser layouts).
|
|
51
|
+
* Only the bar track + fill are affected — row layout, label typography,
|
|
52
|
+
* value column, legend, and hover affordance are unchanged.
|
|
53
|
+
*/
|
|
54
|
+
export type CategorySize = 'small' | 'medium'
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
|
2
|
+
import { act, render } from '@testing-library/react'
|
|
3
|
+
import type * as echarts from 'echarts'
|
|
4
|
+
|
|
5
|
+
// ─── Hoisted mocks ──────────────────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
// Capture the mock chart so each test can introspect setOption / dispose calls.
|
|
8
|
+
const mockChart = {
|
|
9
|
+
setOption: vi.fn(),
|
|
10
|
+
dispose: vi.fn(),
|
|
11
|
+
resize: vi.fn(),
|
|
12
|
+
on: vi.fn(),
|
|
13
|
+
off: vi.fn(),
|
|
14
|
+
}
|
|
15
|
+
const initSpy = vi.fn((...args: unknown[]): typeof mockChart => {
|
|
16
|
+
void args
|
|
17
|
+
return mockChart
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
vi.mock('echarts', () => ({
|
|
21
|
+
__esModule: true,
|
|
22
|
+
init: (...args: unknown[]) => initSpy(...args),
|
|
23
|
+
}))
|
|
24
|
+
|
|
25
|
+
// Resize observer mock — capture the callback so tests can trigger it.
|
|
26
|
+
let resizeCb: (() => void) | null = null
|
|
27
|
+
const observeResizeSpy = vi.fn((_node: HTMLElement, cb: () => void) => {
|
|
28
|
+
resizeCb = cb
|
|
29
|
+
return () => {
|
|
30
|
+
resizeCb = null
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
vi.mock('./shared-resize-observer', () => ({
|
|
34
|
+
observeResize: (node: HTMLElement, cb: () => void) =>
|
|
35
|
+
observeResizeSpy(node, cb),
|
|
36
|
+
}))
|
|
37
|
+
|
|
38
|
+
import { EchartUI } from './echart-ui'
|
|
39
|
+
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
mockChart.setOption.mockReset()
|
|
42
|
+
mockChart.dispose.mockReset()
|
|
43
|
+
mockChart.resize.mockReset()
|
|
44
|
+
mockChart.on.mockReset()
|
|
45
|
+
mockChart.off.mockReset()
|
|
46
|
+
initSpy.mockClear()
|
|
47
|
+
observeResizeSpy.mockClear()
|
|
48
|
+
resizeCb = null
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
describe('<EchartUI>', () => {
|
|
52
|
+
it('initialises echarts on mount with merged init opts and notifies onInstance', () => {
|
|
53
|
+
const onInstance = vi.fn()
|
|
54
|
+
render(
|
|
55
|
+
<EchartUI
|
|
56
|
+
option={{ xAxis: { type: 'category' } }}
|
|
57
|
+
init={{ renderer: 'canvas' }}
|
|
58
|
+
onInstance={onInstance}
|
|
59
|
+
/>,
|
|
60
|
+
)
|
|
61
|
+
expect(initSpy).toHaveBeenCalledTimes(1)
|
|
62
|
+
// 3rd arg merges the default `{ renderer: 'svg', height: 304 }` with the
|
|
63
|
+
// caller's init — canvas wins.
|
|
64
|
+
const initOpts = initSpy.mock.calls[0]![2] as Record<string, unknown>
|
|
65
|
+
expect(initOpts.renderer).toBe('canvas')
|
|
66
|
+
expect(initOpts.height).toBe(304)
|
|
67
|
+
expect(onInstance).toHaveBeenCalledWith(mockChart)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('applies setOption on mount and adds `series` to replaceMerge on first paint', () => {
|
|
71
|
+
render(<EchartUI option={{ series: [{ type: 'bar', data: [1, 2, 3] }] }} />)
|
|
72
|
+
expect(mockChart.setOption).toHaveBeenCalledTimes(1)
|
|
73
|
+
const args = mockChart.setOption.mock.calls[0]!
|
|
74
|
+
expect(
|
|
75
|
+
(args[1] as { replaceMerge?: readonly string[] }).replaceMerge,
|
|
76
|
+
).toContain('series')
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('merges caller-provided replaceMerge keys with structural fingerprints', () => {
|
|
80
|
+
render(
|
|
81
|
+
<EchartUI
|
|
82
|
+
option={{ series: [{ type: 'bar' }] }}
|
|
83
|
+
replaceMerge={['legend', 'grid']}
|
|
84
|
+
/>,
|
|
85
|
+
)
|
|
86
|
+
const augmented = (
|
|
87
|
+
mockChart.setOption.mock.calls[0]![1] as {
|
|
88
|
+
replaceMerge?: readonly string[]
|
|
89
|
+
}
|
|
90
|
+
).replaceMerge!
|
|
91
|
+
expect(augmented).toContain('legend')
|
|
92
|
+
expect(augmented).toContain('grid')
|
|
93
|
+
expect(augmented).toContain('series')
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('skips `series` in replaceMerge when only style fields change between renders', () => {
|
|
97
|
+
const onInstance = vi.fn()
|
|
98
|
+
const { rerender } = render(
|
|
99
|
+
<EchartUI
|
|
100
|
+
option={{
|
|
101
|
+
series: [{ type: 'bar', name: 'a', data: [1] }],
|
|
102
|
+
}}
|
|
103
|
+
onInstance={onInstance}
|
|
104
|
+
/>,
|
|
105
|
+
)
|
|
106
|
+
mockChart.setOption.mockClear()
|
|
107
|
+
rerender(
|
|
108
|
+
<EchartUI
|
|
109
|
+
option={{
|
|
110
|
+
// Same structural fields (type, name) — only itemStyle changed.
|
|
111
|
+
series: [
|
|
112
|
+
{
|
|
113
|
+
type: 'bar',
|
|
114
|
+
name: 'a',
|
|
115
|
+
data: [1],
|
|
116
|
+
itemStyle: { color: 'red' },
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
}}
|
|
120
|
+
onInstance={onInstance}
|
|
121
|
+
/>,
|
|
122
|
+
)
|
|
123
|
+
const replaceMerge = (
|
|
124
|
+
mockChart.setOption.mock.calls[0]![1] as {
|
|
125
|
+
replaceMerge?: readonly string[]
|
|
126
|
+
}
|
|
127
|
+
).replaceMerge
|
|
128
|
+
// No structural change → no `series` flag added; nothing else passed.
|
|
129
|
+
expect(replaceMerge).toBeUndefined()
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
it('adds `series` to replaceMerge when a series field changes structurally', () => {
|
|
133
|
+
const { rerender } = render(
|
|
134
|
+
<EchartUI option={{ series: [{ type: 'bar', name: 'a' }] }} />,
|
|
135
|
+
)
|
|
136
|
+
mockChart.setOption.mockClear()
|
|
137
|
+
rerender(<EchartUI option={{ series: [{ type: 'line', name: 'a' }] }} />)
|
|
138
|
+
const replaceMerge = (
|
|
139
|
+
mockChart.setOption.mock.calls[0]![1] as {
|
|
140
|
+
replaceMerge?: readonly string[]
|
|
141
|
+
}
|
|
142
|
+
).replaceMerge!
|
|
143
|
+
expect(replaceMerge).toContain('series')
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
it('adds `dataset` to replaceMerge when dataset length changes', () => {
|
|
147
|
+
const { rerender } = render(
|
|
148
|
+
<EchartUI option={{ dataset: [{ source: [] }] }} />,
|
|
149
|
+
)
|
|
150
|
+
mockChart.setOption.mockClear()
|
|
151
|
+
rerender(
|
|
152
|
+
<EchartUI option={{ dataset: [{ source: [] }, { source: [] }] }} />,
|
|
153
|
+
)
|
|
154
|
+
const replaceMerge = (
|
|
155
|
+
mockChart.setOption.mock.calls[0]![1] as {
|
|
156
|
+
replaceMerge?: readonly string[]
|
|
157
|
+
}
|
|
158
|
+
).replaceMerge!
|
|
159
|
+
expect(replaceMerge).toContain('dataset')
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
it('binds onEvents handlers and unbinds them on unmount', () => {
|
|
163
|
+
const handler = vi.fn()
|
|
164
|
+
const { unmount } = render(
|
|
165
|
+
<EchartUI option={{}} onEvents={{ click: handler }} />,
|
|
166
|
+
)
|
|
167
|
+
expect(mockChart.on).toHaveBeenCalledWith('click', handler)
|
|
168
|
+
unmount()
|
|
169
|
+
expect(mockChart.off).toHaveBeenCalledWith('click', handler)
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
it('observes the container for resize and calls chart.resize on resize', () => {
|
|
173
|
+
render(<EchartUI option={{}} />)
|
|
174
|
+
expect(observeResizeSpy).toHaveBeenCalled()
|
|
175
|
+
expect(resizeCb).not.toBeNull()
|
|
176
|
+
act(() => resizeCb?.())
|
|
177
|
+
expect(mockChart.resize).toHaveBeenCalledTimes(1)
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
it('disposes the chart and calls onInstance(null) on unmount', () => {
|
|
181
|
+
const onInstance = vi.fn()
|
|
182
|
+
const { unmount } = render(<EchartUI option={{}} onInstance={onInstance} />)
|
|
183
|
+
onInstance.mockClear()
|
|
184
|
+
unmount()
|
|
185
|
+
expect(onInstance).toHaveBeenCalledWith(null)
|
|
186
|
+
expect(mockChart.dispose).toHaveBeenCalledTimes(1)
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
it('treats a non-array series as a single-fingerprint signature', () => {
|
|
190
|
+
// The fingerprint helper handles both array AND object/single-series
|
|
191
|
+
// forms. Re-render with a *fresh* option object that has the same
|
|
192
|
+
// single-series shape — the apply effect re-runs (deps changed) but
|
|
193
|
+
// the fingerprint says nothing structural changed.
|
|
194
|
+
const { rerender } = render(
|
|
195
|
+
<EchartUI
|
|
196
|
+
option={{ series: { type: 'bar' } } as unknown as echarts.EChartsOption}
|
|
197
|
+
/>,
|
|
198
|
+
)
|
|
199
|
+
mockChart.setOption.mockClear()
|
|
200
|
+
rerender(
|
|
201
|
+
<EchartUI
|
|
202
|
+
option={{ series: { type: 'bar' } } as unknown as echarts.EChartsOption}
|
|
203
|
+
/>,
|
|
204
|
+
)
|
|
205
|
+
const replaceMerge = (
|
|
206
|
+
mockChart.setOption.mock.calls[0]![1] as {
|
|
207
|
+
replaceMerge?: readonly string[]
|
|
208
|
+
}
|
|
209
|
+
).replaceMerge
|
|
210
|
+
expect(replaceMerge).toBeUndefined()
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
it('treats a non-array dataset as a single-fingerprint signature', () => {
|
|
214
|
+
const { rerender } = render(
|
|
215
|
+
<EchartUI
|
|
216
|
+
option={{ dataset: { source: [] } } as unknown as echarts.EChartsOption}
|
|
217
|
+
/>,
|
|
218
|
+
)
|
|
219
|
+
mockChart.setOption.mockClear()
|
|
220
|
+
rerender(
|
|
221
|
+
<EchartUI
|
|
222
|
+
option={{ dataset: { source: [] } } as unknown as echarts.EChartsOption}
|
|
223
|
+
/>,
|
|
224
|
+
)
|
|
225
|
+
const replaceMerge = (
|
|
226
|
+
mockChart.setOption.mock.calls[0]![1] as {
|
|
227
|
+
replaceMerge?: readonly string[]
|
|
228
|
+
}
|
|
229
|
+
).replaceMerge
|
|
230
|
+
expect(replaceMerge).toBeUndefined()
|
|
231
|
+
})
|
|
232
|
+
})
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { useEffect, useEffectEvent, useRef } from 'react'
|
|
2
|
+
import { Box, type SxProps, type Theme } from '@mui/material'
|
|
3
|
+
import * as echarts from 'echarts'
|
|
4
|
+
import { observeResize } from './shared-resize-observer'
|
|
5
|
+
import { styles } from './style'
|
|
6
|
+
|
|
7
|
+
export const DEFAULT_INIT_OPTS = {
|
|
8
|
+
renderer: 'svg',
|
|
9
|
+
height: 304,
|
|
10
|
+
} satisfies echarts.EChartsInitOpts
|
|
11
|
+
|
|
12
|
+
export type EchartsEventHandler = (event: unknown) => void
|
|
13
|
+
|
|
14
|
+
export interface EchartUIProps {
|
|
15
|
+
option: echarts.EChartsOption
|
|
16
|
+
/**
|
|
17
|
+
* Keys to merge as arrays (replace by index) instead of by id. The middleware
|
|
18
|
+
* memoizes this content-stably, so identical sets don't re-trigger setOption.
|
|
19
|
+
*/
|
|
20
|
+
replaceMerge?: readonly string[]
|
|
21
|
+
/**
|
|
22
|
+
* Opaque ECharts event passthrough — handlers fire untransformed.
|
|
23
|
+
*
|
|
24
|
+
* **Must be referentially stable** (memoize it with `useMemo` /
|
|
25
|
+
* `useCallback`, or hoist to module scope). The binding effect depends on
|
|
26
|
+
* the `onEvents` object identity; an inline `{ click: handler }` literal
|
|
27
|
+
* recreates the object on every render and causes every listener to be
|
|
28
|
+
* detached and re-attached each commit.
|
|
29
|
+
*/
|
|
30
|
+
onEvents?: Record<string, EchartsEventHandler>
|
|
31
|
+
/**
|
|
32
|
+
* Init options forwarded to echarts.init. Captured at mount only — to change
|
|
33
|
+
* `renderer` or `height` after mount, unmount and remount the chart.
|
|
34
|
+
* Defaults: `{ renderer: 'svg', height: 304 }`.
|
|
35
|
+
*/
|
|
36
|
+
init?: echarts.EChartsInitOpts
|
|
37
|
+
/**
|
|
38
|
+
* Optional callback fired once after the ECharts instance is created
|
|
39
|
+
* (`onInstance(chart)`) and once when it's about to be disposed
|
|
40
|
+
* (`onInstance(null)`). Used by `Widget.Echart` to publish the live
|
|
41
|
+
* instance to the per-widget registry so other actions (e.g.
|
|
42
|
+
* `ZoomToggle`'s disable handler) can reach it without DOM lookups.
|
|
43
|
+
* No need to memoize — the bridge wraps it in `useEffectEvent` so an
|
|
44
|
+
* unstable reference does not re-init the chart.
|
|
45
|
+
*/
|
|
46
|
+
onInstance?: (chart: echarts.ECharts | null) => void
|
|
47
|
+
className?: string
|
|
48
|
+
sx?: SxProps<Theme>
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function EchartUI({
|
|
52
|
+
option,
|
|
53
|
+
replaceMerge,
|
|
54
|
+
onEvents,
|
|
55
|
+
init,
|
|
56
|
+
onInstance,
|
|
57
|
+
className,
|
|
58
|
+
sx,
|
|
59
|
+
}: EchartUIProps) {
|
|
60
|
+
const containerRef = useRef<HTMLDivElement>(null)
|
|
61
|
+
const chartRef = useRef<echarts.ECharts | null>(null)
|
|
62
|
+
|
|
63
|
+
// Structural fingerprint of the last applied series / dataset arrays.
|
|
64
|
+
// Used to decide whether the next `setOption` should *replace* those
|
|
65
|
+
// components (when their shape changed) or *merge* them (when only
|
|
66
|
+
// styling-level fields differ — e.g. a new `itemStyle.color` callback
|
|
67
|
+
// from a selection update). Replacing wipes ECharts' per-series runtime
|
|
68
|
+
// state (hover, animation cache, brush areas), so we want to do it only
|
|
69
|
+
// when the structure actually moved.
|
|
70
|
+
const seriesFingerprintRef = useRef<string | null>(null)
|
|
71
|
+
const datasetFingerprintRef = useRef<string | null>(null)
|
|
72
|
+
|
|
73
|
+
// Stable notify wrapper — always reads the latest `onInstance` prop
|
|
74
|
+
// without forcing the init effect below to re-run when the parent
|
|
75
|
+
// passes a fresh function reference. The init effect now only fires
|
|
76
|
+
// when `init` actually changes (documented as mount-only anyway).
|
|
77
|
+
const notifyInstance = useEffectEvent(
|
|
78
|
+
(chart: echarts.ECharts | null): void => {
|
|
79
|
+
onInstance?.(chart)
|
|
80
|
+
},
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
// Init / dispose. `init` is captured once at mount.
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
if (!containerRef.current) return undefined
|
|
86
|
+
const chart = echarts.init(containerRef.current, null, {
|
|
87
|
+
...DEFAULT_INIT_OPTS,
|
|
88
|
+
...init,
|
|
89
|
+
})
|
|
90
|
+
chartRef.current = chart
|
|
91
|
+
notifyInstance(chart)
|
|
92
|
+
return () => {
|
|
93
|
+
// Notify observers *before* disposal so any queued imperative
|
|
94
|
+
// dispatches (e.g. ZoomToggle's `setOption` cleanup) see the
|
|
95
|
+
// instance disappear before its DOM is torn down.
|
|
96
|
+
notifyInstance(null)
|
|
97
|
+
chart.dispose()
|
|
98
|
+
chartRef.current = null
|
|
99
|
+
}
|
|
100
|
+
}, [init])
|
|
101
|
+
|
|
102
|
+
// Apply option / replaceMerge changes via merge mode (no remount required).
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
const seriesFp = computeSeriesFingerprint(option)
|
|
105
|
+
const datasetFp = computeDatasetFingerprint(option)
|
|
106
|
+
const augmented = new Set<string>(replaceMerge ?? [])
|
|
107
|
+
if (seriesFp !== seriesFingerprintRef.current) augmented.add('series')
|
|
108
|
+
if (datasetFp !== datasetFingerprintRef.current) augmented.add('dataset')
|
|
109
|
+
seriesFingerprintRef.current = seriesFp
|
|
110
|
+
datasetFingerprintRef.current = datasetFp
|
|
111
|
+
chartRef.current?.setOption(option, {
|
|
112
|
+
notMerge: false,
|
|
113
|
+
lazyUpdate: true,
|
|
114
|
+
replaceMerge: augmented.size > 0 ? Array.from(augmented) : undefined,
|
|
115
|
+
})
|
|
116
|
+
}, [option, replaceMerge])
|
|
117
|
+
|
|
118
|
+
// Resize via shared singleton observer.
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
const node = containerRef.current
|
|
121
|
+
if (!node) return undefined
|
|
122
|
+
return observeResize(node, () => {
|
|
123
|
+
chartRef.current?.resize()
|
|
124
|
+
})
|
|
125
|
+
}, [])
|
|
126
|
+
|
|
127
|
+
// Bind / unbind opaque event handlers.
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
const chart = chartRef.current
|
|
130
|
+
if (!chart || !onEvents) return undefined
|
|
131
|
+
for (const [event, handler] of Object.entries(onEvents)) {
|
|
132
|
+
chart.on(event, handler)
|
|
133
|
+
}
|
|
134
|
+
return () => {
|
|
135
|
+
for (const [event, handler] of Object.entries(onEvents)) {
|
|
136
|
+
chart.off(event, handler)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}, [onEvents])
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<Box
|
|
143
|
+
ref={containerRef}
|
|
144
|
+
className={className}
|
|
145
|
+
sx={{ ...styles.root, ...sx }}
|
|
146
|
+
/>
|
|
147
|
+
)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Cheap structural digest of the option's `series` array — covers the fields
|
|
152
|
+
* that actually demand a `replaceMerge` (length, type, datasetIndex, name,
|
|
153
|
+
* stack, encode). Excludes runtime-style fields like `itemStyle` (callbacks
|
|
154
|
+
* have unstable identity but don't change structure).
|
|
155
|
+
*/
|
|
156
|
+
function computeSeriesFingerprint(option: echarts.EChartsOption): string {
|
|
157
|
+
const series = option.series
|
|
158
|
+
if (!Array.isArray(series)) return series ? '1' : ''
|
|
159
|
+
return series
|
|
160
|
+
.map((s) => {
|
|
161
|
+
if (s == null || typeof s !== 'object') return String(s)
|
|
162
|
+
const o = s as Record<string, unknown>
|
|
163
|
+
return [
|
|
164
|
+
o.type,
|
|
165
|
+
o.datasetIndex,
|
|
166
|
+
o.name,
|
|
167
|
+
o.stack,
|
|
168
|
+
// `encode` is small; stringify is cheap and stable for plain objects.
|
|
169
|
+
JSON.stringify(o.encode ?? null),
|
|
170
|
+
].join('|')
|
|
171
|
+
})
|
|
172
|
+
.join('||')
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Structural digest of the option's `dataset` array — count is the only
|
|
177
|
+
* thing that needs `replaceMerge` here. Row-level changes are picked up by
|
|
178
|
+
* ECharts' default merge.
|
|
179
|
+
*/
|
|
180
|
+
function computeDatasetFingerprint(option: echarts.EChartsOption): string {
|
|
181
|
+
const dataset = option.dataset
|
|
182
|
+
if (!Array.isArray(dataset)) return dataset ? '1' : ''
|
|
183
|
+
return String(dataset.length)
|
|
184
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { useEffect } from 'react'
|
|
2
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
|
|
3
|
+
import { act, render } from '@testing-library/react'
|
|
4
|
+
import type * as echarts from 'echarts'
|
|
5
|
+
import { Provider } from '../provider/widget-provider'
|
|
6
|
+
import { Echart } from './echart'
|
|
7
|
+
import type { OptionFactory } from './echart'
|
|
8
|
+
import {
|
|
9
|
+
clearAllWidgetStores,
|
|
10
|
+
getEchartInstance,
|
|
11
|
+
getWidgetStore,
|
|
12
|
+
} from '../stores'
|
|
13
|
+
|
|
14
|
+
// Capture the option that EchartUI receives, since we don't render real ECharts in tests.
|
|
15
|
+
const captured: {
|
|
16
|
+
option: echarts.EChartsOption | null
|
|
17
|
+
replaceMerge: readonly string[] | null
|
|
18
|
+
setOptions: number
|
|
19
|
+
} = {
|
|
20
|
+
option: null,
|
|
21
|
+
replaceMerge: null,
|
|
22
|
+
setOptions: 0,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
vi.mock('./echart-ui', () => ({
|
|
26
|
+
EchartUI: ({
|
|
27
|
+
option,
|
|
28
|
+
replaceMerge,
|
|
29
|
+
onInstance,
|
|
30
|
+
}: {
|
|
31
|
+
option: echarts.EChartsOption
|
|
32
|
+
replaceMerge: readonly string[]
|
|
33
|
+
onInstance?: (chart: echarts.ECharts | null) => void
|
|
34
|
+
}) => {
|
|
35
|
+
captured.option = option
|
|
36
|
+
captured.replaceMerge = replaceMerge
|
|
37
|
+
captured.setOptions++
|
|
38
|
+
// Mimic the real bridge: publish a fake instance on mount, clear on
|
|
39
|
+
// unmount. Cast through unknown so the test doesn't depend on the full
|
|
40
|
+
// ECharts surface.
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
const fake = { __mock: true } as unknown as echarts.ECharts
|
|
43
|
+
onInstance?.(fake)
|
|
44
|
+
return () => onInstance?.(null)
|
|
45
|
+
}, [onInstance])
|
|
46
|
+
return null
|
|
47
|
+
},
|
|
48
|
+
DEFAULT_INIT_OPTS: { renderer: 'svg', height: 304 },
|
|
49
|
+
}))
|
|
50
|
+
|
|
51
|
+
beforeEach(() => {
|
|
52
|
+
clearAllWidgetStores()
|
|
53
|
+
captured.option = null
|
|
54
|
+
captured.replaceMerge = null
|
|
55
|
+
captured.setOptions = 0
|
|
56
|
+
})
|
|
57
|
+
afterEach(() => clearAllWidgetStores())
|
|
58
|
+
|
|
59
|
+
// Helper: build an OptionFactory whose structural branch returns `structural`
|
|
60
|
+
// and whose merge branch passes the post-config-transforms option through
|
|
61
|
+
// `mergeData(option, data, ctx)`.
|
|
62
|
+
const makeFactory = (
|
|
63
|
+
structural: echarts.EChartsOption,
|
|
64
|
+
mergeData: (
|
|
65
|
+
option: echarts.EChartsOption,
|
|
66
|
+
data: unknown,
|
|
67
|
+
) => echarts.EChartsOption,
|
|
68
|
+
): OptionFactory => {
|
|
69
|
+
return (option, data) => {
|
|
70
|
+
if (option == null) return structural
|
|
71
|
+
return mergeData(option, data)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
describe('<Echart> bridge — owns the option factory directly', () => {
|
|
76
|
+
it('forwards the structural option to EchartUI synchronously on first render', () => {
|
|
77
|
+
const factory = makeFactory(
|
|
78
|
+
{ xAxis: { type: 'category' } } as echarts.EChartsOption,
|
|
79
|
+
// Merge branch: return the option as-is so the structural option
|
|
80
|
+
// flows through to ECharts unchanged.
|
|
81
|
+
(option) => option,
|
|
82
|
+
)
|
|
83
|
+
render(
|
|
84
|
+
<Provider id='e1' data={[]}>
|
|
85
|
+
<Echart optionFactory={factory} />
|
|
86
|
+
</Provider>,
|
|
87
|
+
)
|
|
88
|
+
expect(captured.option).toEqual({ xAxis: { type: 'category' } })
|
|
89
|
+
// No `rawOptions` on the store — the option pipeline is Echart-local now.
|
|
90
|
+
expect(
|
|
91
|
+
(getWidgetStore('e1').getState() as unknown as { rawOptions?: unknown })
|
|
92
|
+
.rawOptions,
|
|
93
|
+
).toBeUndefined()
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('fuses state.data into the option via the factory merge branch (dataset)', () => {
|
|
97
|
+
const factory = makeFactory(
|
|
98
|
+
{ xAxis: { type: 'category' } } as echarts.EChartsOption,
|
|
99
|
+
(option, data) =>
|
|
100
|
+
({
|
|
101
|
+
...option,
|
|
102
|
+
dataset: Array.isArray(data)
|
|
103
|
+
? (data as { name: string; value: number }[][]).map((source) => ({
|
|
104
|
+
source,
|
|
105
|
+
}))
|
|
106
|
+
: [],
|
|
107
|
+
}) as echarts.EChartsOption,
|
|
108
|
+
)
|
|
109
|
+
render(
|
|
110
|
+
<Provider id='e2' data={[[{ name: 'A', value: 1 }]]}>
|
|
111
|
+
<Echart optionFactory={factory} />
|
|
112
|
+
</Provider>,
|
|
113
|
+
)
|
|
114
|
+
const captured2 = captured.option as { dataset: { source: unknown }[] }
|
|
115
|
+
expect(captured2.dataset).toHaveLength(1)
|
|
116
|
+
expect(captured2.dataset[0]?.source).toEqual([{ name: 'A', value: 1 }])
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('updates the option when a data transform changes state.data (no re-init)', () => {
|
|
120
|
+
interface Row {
|
|
121
|
+
name: string
|
|
122
|
+
value: number
|
|
123
|
+
}
|
|
124
|
+
const factory = makeFactory(
|
|
125
|
+
{ xAxis: { type: 'category' } } as echarts.EChartsOption,
|
|
126
|
+
(option, data) =>
|
|
127
|
+
({
|
|
128
|
+
...option,
|
|
129
|
+
// Mark each dataset with the record count so changes are observable.
|
|
130
|
+
dataset: Array.isArray(data)
|
|
131
|
+
? (data as Row[][]).map((s) => ({
|
|
132
|
+
source: s,
|
|
133
|
+
id: `len:${s.length}`,
|
|
134
|
+
}))
|
|
135
|
+
: [],
|
|
136
|
+
}) as echarts.EChartsOption,
|
|
137
|
+
)
|
|
138
|
+
render(
|
|
139
|
+
<Provider
|
|
140
|
+
id='e3'
|
|
141
|
+
data={[
|
|
142
|
+
[
|
|
143
|
+
{ name: 'A', value: 1 },
|
|
144
|
+
{ name: 'B', value: 2 },
|
|
145
|
+
{ name: 'C', value: 3 },
|
|
146
|
+
],
|
|
147
|
+
]}
|
|
148
|
+
>
|
|
149
|
+
<Echart optionFactory={factory} />
|
|
150
|
+
</Provider>,
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
// Before transform: 3 records.
|
|
154
|
+
let dataset = (captured.option as { dataset: { id: string }[] }).dataset
|
|
155
|
+
expect(dataset[0]?.id).toBe('len:3')
|
|
156
|
+
|
|
157
|
+
// Register a data transform that filters out half the records.
|
|
158
|
+
act(() => {
|
|
159
|
+
getWidgetStore('e3').setState({
|
|
160
|
+
dataTransforms: [
|
|
161
|
+
{
|
|
162
|
+
id: 'cut',
|
|
163
|
+
type: 'data',
|
|
164
|
+
order: 1,
|
|
165
|
+
enabled: true,
|
|
166
|
+
fn: (input) => {
|
|
167
|
+
const arr = input as { name: string; value: number }[][]
|
|
168
|
+
return arr.map((s) => s.slice(0, 1))
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
})
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
// Bridge should have re-rendered with post-pipeline data: 1 record.
|
|
176
|
+
dataset = (captured.option as { dataset: { id: string }[] }).dataset
|
|
177
|
+
expect(dataset[0]?.id).toBe('len:1')
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
it('applies configTransforms to the rendered option and forwards replaceMerge', () => {
|
|
181
|
+
const factory = makeFactory(
|
|
182
|
+
{ xAxis: { type: 'category' } } as echarts.EChartsOption,
|
|
183
|
+
(option) => option,
|
|
184
|
+
)
|
|
185
|
+
render(
|
|
186
|
+
<Provider id='e-cfg' data={[]}>
|
|
187
|
+
<Echart optionFactory={factory} />
|
|
188
|
+
</Provider>,
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
// Before transform: untouched structural; replaceMerge is the default.
|
|
192
|
+
expect(captured.option).toEqual({ xAxis: { type: 'category' } })
|
|
193
|
+
expect(captured.replaceMerge).toEqual(['toolbox'])
|
|
194
|
+
|
|
195
|
+
// Register a config transform that stamps a field onto the option and
|
|
196
|
+
// contributes a `replaceMergeKeys` entry.
|
|
197
|
+
act(() => {
|
|
198
|
+
getWidgetStore('e-cfg').setState({
|
|
199
|
+
configTransforms: [
|
|
200
|
+
{
|
|
201
|
+
id: 'stamp',
|
|
202
|
+
type: 'config',
|
|
203
|
+
order: 1,
|
|
204
|
+
enabled: true,
|
|
205
|
+
replaceMergeKeys: ['stamp'],
|
|
206
|
+
fn: (o) => ({ ...(o as object), stamp: true }),
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
})
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
// After transform: option carries the mutation, replaceMerge is
|
|
213
|
+
// deduped+sorted with the default and the transform's keys.
|
|
214
|
+
expect((captured.option as { stamp?: boolean }).stamp).toBe(true)
|
|
215
|
+
expect(captured.replaceMerge).toEqual(['stamp', 'toolbox'])
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
it('publishes the live ECharts instance to the per-id registry on mount and clears on unmount', () => {
|
|
219
|
+
const factory = makeFactory({} as echarts.EChartsOption, (option) => option)
|
|
220
|
+
const { unmount } = render(
|
|
221
|
+
<Provider id='e-instance' data={[]}>
|
|
222
|
+
<Echart optionFactory={factory} />
|
|
223
|
+
</Provider>,
|
|
224
|
+
)
|
|
225
|
+
expect(getEchartInstance('e-instance')).not.toBeNull()
|
|
226
|
+
unmount()
|
|
227
|
+
expect(getEchartInstance('e-instance')).toBeNull()
|
|
228
|
+
})
|
|
229
|
+
})
|