@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,10 @@
|
|
|
1
|
+
export { barOptions, createBarOptionFactory } from './options'
|
|
2
|
+
export { BarSkeleton } from './skeleton'
|
|
3
|
+
export { createBarDownloadConfig } from './download'
|
|
4
|
+
export type {
|
|
5
|
+
BarDatum,
|
|
6
|
+
BarWidgetData,
|
|
7
|
+
BarOptionsInput,
|
|
8
|
+
BarOptionFactoryInput,
|
|
9
|
+
BarEChartsOption,
|
|
10
|
+
} from './types'
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { createTheme, type Theme } from '@mui/material'
|
|
3
|
+
import { barOptions, createBarOptionFactory } from './options'
|
|
4
|
+
|
|
5
|
+
const theme = createTheme() as unknown as Theme
|
|
6
|
+
|
|
7
|
+
describe('barOptions (structural)', () => {
|
|
8
|
+
it('returns a category x-axis without baked data', () => {
|
|
9
|
+
const out = barOptions({ theme })
|
|
10
|
+
const xAxis = out.xAxis as { type: string; data?: unknown }
|
|
11
|
+
expect(xAxis.type).toBe('category')
|
|
12
|
+
expect(xAxis.data).toBeUndefined()
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('returns no series and no dataset (data is fused at render time)', () => {
|
|
16
|
+
const out = barOptions({ theme })
|
|
17
|
+
expect(out.series).toBeUndefined()
|
|
18
|
+
expect(out.dataset).toBeUndefined()
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('hides x and y axis lines and ticks for the v1 minimal look', () => {
|
|
22
|
+
const out = barOptions({ theme })
|
|
23
|
+
const xAxis = out.xAxis as {
|
|
24
|
+
axisLine?: { show?: boolean }
|
|
25
|
+
axisTick?: { show?: boolean }
|
|
26
|
+
}
|
|
27
|
+
const yAxis = out.yAxis as {
|
|
28
|
+
axisLine?: { show?: boolean }
|
|
29
|
+
axisTick?: { show?: boolean }
|
|
30
|
+
splitLine?: { show?: boolean }
|
|
31
|
+
}
|
|
32
|
+
expect(xAxis.axisLine?.show).toBe(false)
|
|
33
|
+
expect(xAxis.axisTick?.show).toBe(false)
|
|
34
|
+
expect(yAxis.axisLine?.show).toBe(false)
|
|
35
|
+
expect(yAxis.axisTick?.show).toBe(false)
|
|
36
|
+
expect(yAxis.splitLine?.show).toBe(true)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('y-axis label formatter only renders min/max via the user formatter', () => {
|
|
40
|
+
const fmt = (n: number): string => `$${n}`
|
|
41
|
+
const out = barOptions({ theme, formatter: fmt })
|
|
42
|
+
const yAxis = out.yAxis as {
|
|
43
|
+
axisLabel?: { formatter?: (v: number) => string }
|
|
44
|
+
}
|
|
45
|
+
// niceMin / niceMax default to 0 and 1 until min/max callbacks run.
|
|
46
|
+
expect(yAxis.axisLabel?.formatter?.(1)).toBe('$1')
|
|
47
|
+
// 0 is suppressed (matches v1) and intermediate values are blanked.
|
|
48
|
+
expect(yAxis.axisLabel?.formatter?.(0)).toBe('')
|
|
49
|
+
expect(yAxis.axisLabel?.formatter?.(0.5)).toBe('')
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('renders y-axis labels inside the plot, anchored to the bottom', () => {
|
|
53
|
+
const out = barOptions({ theme })
|
|
54
|
+
const yAxis = out.yAxis as {
|
|
55
|
+
axisLabel?: { inside?: boolean; verticalAlign?: string }
|
|
56
|
+
}
|
|
57
|
+
expect(yAxis.axisLabel?.inside).toBe(true)
|
|
58
|
+
expect(yAxis.axisLabel?.verticalAlign).toBe('bottom')
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('wires labelFormatter into the x-axis label', () => {
|
|
62
|
+
const lf = (v: string | number) => `[${v}]`
|
|
63
|
+
const out = barOptions({ theme, labelFormatter: lf })
|
|
64
|
+
const xAxis = out.xAxis as {
|
|
65
|
+
axisLabel?: { formatter?: (v: string | number) => string }
|
|
66
|
+
}
|
|
67
|
+
expect(xAxis.axisLabel?.formatter?.('A')).toBe('[A]')
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
describe('createBarOptionFactory', () => {
|
|
72
|
+
it('builds one dataset per series with the data array as source', () => {
|
|
73
|
+
const merge = createBarOptionFactory({ theme })
|
|
74
|
+
const data = [
|
|
75
|
+
[
|
|
76
|
+
{ name: 'A', value: 1 },
|
|
77
|
+
{ name: 'B', value: 2 },
|
|
78
|
+
],
|
|
79
|
+
[
|
|
80
|
+
{ name: 'A', value: 3 },
|
|
81
|
+
{ name: 'B', value: 4 },
|
|
82
|
+
],
|
|
83
|
+
]
|
|
84
|
+
const out = merge({}, data) as { dataset: { source: object[] }[] }
|
|
85
|
+
expect(out.dataset).toHaveLength(2)
|
|
86
|
+
expect(out.dataset[0]?.source).toBe(data[0])
|
|
87
|
+
expect(out.dataset[1]?.source).toBe(data[1])
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('encodes name → x and value → y, with each series referencing its dataset by index', () => {
|
|
91
|
+
const merge = createBarOptionFactory({ theme })
|
|
92
|
+
const out = merge({}, [
|
|
93
|
+
[{ name: 'A', value: 1 }],
|
|
94
|
+
[{ name: 'A', value: 2 }],
|
|
95
|
+
]) as {
|
|
96
|
+
series: {
|
|
97
|
+
type: string
|
|
98
|
+
datasetIndex: number
|
|
99
|
+
encode: { x: string; y: string }
|
|
100
|
+
barMaxWidth: number
|
|
101
|
+
emphasis: { focus: string }
|
|
102
|
+
}[]
|
|
103
|
+
}
|
|
104
|
+
expect(out.series[0]).toMatchObject({
|
|
105
|
+
type: 'bar',
|
|
106
|
+
datasetIndex: 0,
|
|
107
|
+
encode: { x: 'name', y: 'value' },
|
|
108
|
+
barMaxWidth: 100,
|
|
109
|
+
emphasis: { focus: 'series' },
|
|
110
|
+
})
|
|
111
|
+
expect(out.series[1]).toMatchObject({
|
|
112
|
+
type: 'bar',
|
|
113
|
+
datasetIndex: 1,
|
|
114
|
+
encode: { x: 'name', y: 'value' },
|
|
115
|
+
barMaxWidth: 100,
|
|
116
|
+
emphasis: { focus: 'series' },
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it('uses seriesNames for legend names when provided', () => {
|
|
121
|
+
const merge = createBarOptionFactory({
|
|
122
|
+
theme,
|
|
123
|
+
seriesNames: ['2024', '2025'],
|
|
124
|
+
})
|
|
125
|
+
const out = merge({}, [
|
|
126
|
+
[{ name: 'A', value: 1 }],
|
|
127
|
+
[{ name: 'A', value: 2 }],
|
|
128
|
+
]) as { series: { name: string }[] }
|
|
129
|
+
expect(out.series[0]?.name).toBe('2024')
|
|
130
|
+
expect(out.series[1]?.name).toBe('2025')
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it('toggles legend visibility based on series count, preserving styling', () => {
|
|
134
|
+
const merge = createBarOptionFactory({ theme })
|
|
135
|
+
const baseLegend = { icon: 'circle', type: 'scroll' }
|
|
136
|
+
const single = merge({ legend: baseLegend }, [
|
|
137
|
+
[{ name: 'A', value: 1 }],
|
|
138
|
+
]) as { legend: { show: boolean; icon?: string } }
|
|
139
|
+
const multi = merge({ legend: baseLegend }, [
|
|
140
|
+
[{ name: 'A', value: 1 }],
|
|
141
|
+
[{ name: 'A', value: 2 }],
|
|
142
|
+
]) as { legend: { show: boolean; icon?: string } }
|
|
143
|
+
expect(single.legend.show).toBe(false)
|
|
144
|
+
expect(single.legend.icon).toBe('circle')
|
|
145
|
+
expect(multi.legend.show).toBe(true)
|
|
146
|
+
expect(multi.legend.icon).toBe('circle')
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it('reserves extra grid bottom space when a legend is shown', () => {
|
|
150
|
+
const merge = createBarOptionFactory({ theme })
|
|
151
|
+
const baseGrid = { bottom: 24 }
|
|
152
|
+
const single = merge({ grid: baseGrid }, [[{ name: 'A', value: 1 }]]) as {
|
|
153
|
+
grid: { bottom: number }
|
|
154
|
+
}
|
|
155
|
+
const multi = merge({ grid: baseGrid }, [
|
|
156
|
+
[{ name: 'A', value: 1 }],
|
|
157
|
+
[{ name: 'A', value: 2 }],
|
|
158
|
+
]) as { grid: { bottom: number } }
|
|
159
|
+
expect(single.grid.bottom).toBe(24)
|
|
160
|
+
expect(multi.grid.bottom).toBe(56)
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
it('returns empty dataset/series for empty data', () => {
|
|
164
|
+
const merge = createBarOptionFactory({ theme })
|
|
165
|
+
const out = merge({ xAxis: { type: 'category' } }, []) as {
|
|
166
|
+
dataset: unknown[]
|
|
167
|
+
series: unknown[]
|
|
168
|
+
}
|
|
169
|
+
expect(out.dataset).toEqual([])
|
|
170
|
+
expect(out.series).toEqual([])
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
it('merges incoming series template into every series (Stack survives)', () => {
|
|
174
|
+
// Simulates `addStack` having run as a config transform: the option
|
|
175
|
+
// arrives with a single broadcast template carrying { stack: 'total' }.
|
|
176
|
+
const merge = createBarOptionFactory({ theme })
|
|
177
|
+
const out = merge({ series: [{ stack: 'total' }] }, [
|
|
178
|
+
[{ name: 'A', value: 1 }],
|
|
179
|
+
[{ name: 'A', value: 2 }],
|
|
180
|
+
]) as { series: { stack?: string; type: string; datasetIndex: number }[] }
|
|
181
|
+
expect(out.series).toHaveLength(2)
|
|
182
|
+
expect(out.series[0]?.stack).toBe('total')
|
|
183
|
+
expect(out.series[1]?.stack).toBe('total')
|
|
184
|
+
// Authoritative properties still win over the template.
|
|
185
|
+
expect(out.series[0]?.type).toBe('bar')
|
|
186
|
+
expect(out.series[0]?.datasetIndex).toBe(0)
|
|
187
|
+
expect(out.series[1]?.datasetIndex).toBe(1)
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
it('uses ctx.formatter for the y-axis min/max label (RelativeData support)', () => {
|
|
191
|
+
const merge = createBarOptionFactory({ theme })
|
|
192
|
+
const fmt = (n: number) => `${n}%`
|
|
193
|
+
const out = merge(
|
|
194
|
+
{ yAxis: { type: 'value' } },
|
|
195
|
+
[
|
|
196
|
+
[
|
|
197
|
+
{ name: 'A', value: 0 },
|
|
198
|
+
{ name: 'B', value: 100 },
|
|
199
|
+
],
|
|
200
|
+
],
|
|
201
|
+
{ formatter: fmt },
|
|
202
|
+
) as {
|
|
203
|
+
yAxis: {
|
|
204
|
+
min: number
|
|
205
|
+
max: number
|
|
206
|
+
axisLabel: { formatter: (v: number) => string }
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
expect(out.yAxis.min).toBe(0)
|
|
210
|
+
expect(out.yAxis.max).toBe(100)
|
|
211
|
+
expect(out.yAxis.axisLabel.formatter(100)).toBe('100%')
|
|
212
|
+
// Intermediate values are still suppressed.
|
|
213
|
+
expect(out.yAxis.axisLabel.formatter(50)).toBe('')
|
|
214
|
+
expect(out.yAxis.axisLabel.formatter(0)).toBe('')
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
it('reserves grid bottom space for the zoom slider when dataZoom is present', () => {
|
|
218
|
+
const merge = createBarOptionFactory({ theme })
|
|
219
|
+
// Single series, no legend.
|
|
220
|
+
const single = merge(
|
|
221
|
+
{
|
|
222
|
+
grid: { bottom: 24 },
|
|
223
|
+
dataZoom: [{ type: 'inside' }, { type: 'slider', bottom: 0 }],
|
|
224
|
+
},
|
|
225
|
+
[[{ name: 'A', value: 1 }]],
|
|
226
|
+
) as { grid: { bottom: number } }
|
|
227
|
+
// 24 (base) + 32 (slider height) + 8 (gap) = 64.
|
|
228
|
+
expect(single.grid.bottom).toBe(64)
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
it('lifts the zoom slider above the legend when both are present', () => {
|
|
232
|
+
const merge = createBarOptionFactory({ theme })
|
|
233
|
+
const out = merge(
|
|
234
|
+
{
|
|
235
|
+
dataZoom: [{ type: 'inside' }, { type: 'slider', bottom: 0 }],
|
|
236
|
+
},
|
|
237
|
+
[[{ name: 'A', value: 1 }], [{ name: 'A', value: 2 }]],
|
|
238
|
+
) as {
|
|
239
|
+
dataZoom: { type: string; bottom?: number }[]
|
|
240
|
+
grid: { bottom: number }
|
|
241
|
+
}
|
|
242
|
+
const slider = out.dataZoom.find((d) => d.type === 'slider')
|
|
243
|
+
expect(slider?.bottom).toBe(28)
|
|
244
|
+
// Legend space (56) + slider height (32) + gap (8) = 96.
|
|
245
|
+
expect(out.grid.bottom).toBe(96)
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
describe('itemStyle.color (dim non-selected)', () => {
|
|
249
|
+
it('passes through the params color when no selection is set', () => {
|
|
250
|
+
const merge = createBarOptionFactory({ theme })
|
|
251
|
+
const out = merge({}, [[{ name: 'A', value: 1 }]]) as {
|
|
252
|
+
series: { itemStyle: { color: (p: unknown) => string } }[]
|
|
253
|
+
}
|
|
254
|
+
const colorFn = out.series[0]!.itemStyle.color
|
|
255
|
+
expect(colorFn({ value: { name: 'A' }, color: '#abc', name: 'A' })).toBe(
|
|
256
|
+
'#abc',
|
|
257
|
+
)
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
it('keeps the base colour for bars matching the selection', () => {
|
|
261
|
+
const merge = createBarOptionFactory({ theme, selection: ['A'] })
|
|
262
|
+
const out = merge({}, [[{ name: 'A', value: 1 }]]) as {
|
|
263
|
+
series: { itemStyle: { color: (p: unknown) => string } }[]
|
|
264
|
+
}
|
|
265
|
+
const colorFn = out.series[0]!.itemStyle.color
|
|
266
|
+
expect(colorFn({ value: { name: 'A' }, color: '#abc', name: 'A' })).toBe(
|
|
267
|
+
'#abc',
|
|
268
|
+
)
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
it('dims bars outside the selection via 15% alpha', () => {
|
|
272
|
+
const merge = createBarOptionFactory({ theme, selection: ['B'] })
|
|
273
|
+
const out = merge({}, [[{ name: 'A', value: 1 }]]) as {
|
|
274
|
+
series: { itemStyle: { color: (p: unknown) => string } }[]
|
|
275
|
+
}
|
|
276
|
+
const colorFn = out.series[0]!.itemStyle.color
|
|
277
|
+
const dimmed = colorFn({
|
|
278
|
+
value: { name: 'A' },
|
|
279
|
+
color: '#FF0000',
|
|
280
|
+
name: 'A',
|
|
281
|
+
})
|
|
282
|
+
expect(dimmed).not.toBe('#FF0000')
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
it('falls back to params.name when datum has no name', () => {
|
|
286
|
+
const merge = createBarOptionFactory({ theme, selection: ['A'] })
|
|
287
|
+
const out = merge({}, [[{ name: 'A', value: 1 }]]) as {
|
|
288
|
+
series: { itemStyle: { color: (p: unknown) => string } }[]
|
|
289
|
+
}
|
|
290
|
+
const colorFn = out.series[0]!.itemStyle.color
|
|
291
|
+
expect(colorFn({ value: undefined, color: '#abc', name: 'A' })).toBe(
|
|
292
|
+
'#abc',
|
|
293
|
+
)
|
|
294
|
+
})
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
it('uses ctx formatters for the tooltip (RelativeData support)', () => {
|
|
298
|
+
const merge = createBarOptionFactory({ theme })
|
|
299
|
+
const fmt = (n: number) => `${n}%`
|
|
300
|
+
const lf = (v: string | number) => `[ITEM:${v}]`
|
|
301
|
+
const out = merge({}, [[{ name: 'A', value: 50 }]], {
|
|
302
|
+
formatter: fmt,
|
|
303
|
+
labelFormatter: lf,
|
|
304
|
+
}) as { tooltip: { formatter: (params: unknown) => string } }
|
|
305
|
+
const html = out.tooltip.formatter([
|
|
306
|
+
{
|
|
307
|
+
value: { name: 'A', value: 50 },
|
|
308
|
+
name: 'A',
|
|
309
|
+
seriesName: '',
|
|
310
|
+
marker: '',
|
|
311
|
+
},
|
|
312
|
+
])
|
|
313
|
+
// The percent formatter and label formatter both ran.
|
|
314
|
+
expect(html).toContain('50%')
|
|
315
|
+
expect(html).toContain('[ITEM:A]')
|
|
316
|
+
})
|
|
317
|
+
})
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import type { EChartsOption } from 'echarts'
|
|
2
|
+
import * as echarts from 'echarts'
|
|
3
|
+
import type { CallbackDataParams } from 'echarts/types/dist/shared'
|
|
4
|
+
import {
|
|
5
|
+
buildGridConfig,
|
|
6
|
+
buildLegendConfig,
|
|
7
|
+
createTooltipFormatter,
|
|
8
|
+
createTooltipPositioner,
|
|
9
|
+
niceNum,
|
|
10
|
+
} from '../../widgets/utils/chart-config'
|
|
11
|
+
import { ZOOM_LAYOUT } from '../actions/zoom-toggle'
|
|
12
|
+
import type { OptionFactory } from '../echart'
|
|
13
|
+
import { mergeOptions } from '../utils'
|
|
14
|
+
import { positionDataZoomForLegend } from '../utils/data-zoom-layout'
|
|
15
|
+
import type {
|
|
16
|
+
BarEChartsOption,
|
|
17
|
+
BarOptionFactoryInput,
|
|
18
|
+
BarOptionsInput,
|
|
19
|
+
BarWidgetData,
|
|
20
|
+
} from './types'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Builds the **structural** ECharts option for a bar widget — axes, grid,
|
|
24
|
+
* tooltip styling, themed legend. Intentionally data-agnostic: no series,
|
|
25
|
+
* no dataset, no `legend.show` (those depend on data and are added by the
|
|
26
|
+
* option factory's merge phase). This separation is what lets data-side
|
|
27
|
+
* pipeline transforms (Searcher, RelativeData) drive the rendered chart —
|
|
28
|
+
* the merge happens at render time inside the Echart bridge.
|
|
29
|
+
*
|
|
30
|
+
* Styling matches the v1 `barConfig` look-and-feel: minimal axes (only
|
|
31
|
+
* min/max y-labels rendered inside the plot via `niceNum`), themed tooltip,
|
|
32
|
+
* scroll legend, and CARTO color palette. The y-axis min/max + label
|
|
33
|
+
* formatter and the tooltip formatter are wired here for the no-data case;
|
|
34
|
+
* {@link createBarOptionFactory} re-derives them at fusion time so reactive
|
|
35
|
+
* formatter changes (RelativeData) and stack templates (StackToggle) flow
|
|
36
|
+
* through to the chart.
|
|
37
|
+
*/
|
|
38
|
+
export function barOptions({
|
|
39
|
+
theme,
|
|
40
|
+
formatter,
|
|
41
|
+
labelFormatter,
|
|
42
|
+
}: BarOptionsInput): BarEChartsOption {
|
|
43
|
+
// Closure shared between yAxis min/max callbacks and the label formatter,
|
|
44
|
+
// so only the rounded extents are labelled (matches v1).
|
|
45
|
+
let niceMin = 0
|
|
46
|
+
let niceMax = 1
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
grid: {
|
|
50
|
+
left: parseInt(theme.spacing(1)),
|
|
51
|
+
top: parseInt(theme.spacing(3)),
|
|
52
|
+
right: parseInt(theme.spacing(1)),
|
|
53
|
+
// Default: no legend. Merger bumps this when there are >1 series.
|
|
54
|
+
...buildGridConfig(false, theme),
|
|
55
|
+
containLabel: true,
|
|
56
|
+
},
|
|
57
|
+
tooltip: {
|
|
58
|
+
trigger: 'axis',
|
|
59
|
+
backgroundColor: theme.palette.grey[900],
|
|
60
|
+
borderWidth: 0,
|
|
61
|
+
padding: [parseInt(theme.spacing(1)), parseInt(theme.spacing(1))],
|
|
62
|
+
textStyle: {
|
|
63
|
+
color: theme.palette.common.white,
|
|
64
|
+
fontSize: 11,
|
|
65
|
+
fontFamily: theme.typography.caption.fontFamily,
|
|
66
|
+
},
|
|
67
|
+
axisPointer: { type: 'line' },
|
|
68
|
+
position: createTooltipPositioner(theme),
|
|
69
|
+
formatter: buildBarTooltipFormatter(formatter, labelFormatter),
|
|
70
|
+
},
|
|
71
|
+
// Legend styling baked here; `show` is toggled by the merger based on
|
|
72
|
+
// series count.
|
|
73
|
+
legend: {
|
|
74
|
+
...buildLegendConfig({ hasLegend: false, labelFormatter }),
|
|
75
|
+
},
|
|
76
|
+
axisPointer: { lineStyle: { color: theme.palette.grey[400] } },
|
|
77
|
+
color: [
|
|
78
|
+
theme.palette.secondary.main,
|
|
79
|
+
...Object.values(
|
|
80
|
+
(theme.palette as { qualitative?: { bold?: Record<string, string> } })
|
|
81
|
+
.qualitative?.bold ?? {},
|
|
82
|
+
),
|
|
83
|
+
],
|
|
84
|
+
xAxis: {
|
|
85
|
+
type: 'category',
|
|
86
|
+
axisLine: { show: false },
|
|
87
|
+
axisTick: { show: false },
|
|
88
|
+
axisLabel: {
|
|
89
|
+
padding: [parseInt(theme.spacing(0.5)), 0, 0, 0],
|
|
90
|
+
margin: 0,
|
|
91
|
+
hideOverlap: true,
|
|
92
|
+
...(labelFormatter && {
|
|
93
|
+
formatter: (v: string | number) => String(labelFormatter(v)),
|
|
94
|
+
}),
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
yAxis: {
|
|
98
|
+
type: 'value',
|
|
99
|
+
min: (extent: { min: number }) => {
|
|
100
|
+
niceMin = extent.min < 0 ? niceNum(extent.min) : 0
|
|
101
|
+
return niceMin
|
|
102
|
+
},
|
|
103
|
+
max: (extent: { min: number; max: number }) => {
|
|
104
|
+
niceMax = extent.max <= 0 ? 1 : niceNum(extent.max)
|
|
105
|
+
return niceMax
|
|
106
|
+
},
|
|
107
|
+
axisLine: { show: false },
|
|
108
|
+
axisTick: { show: false },
|
|
109
|
+
splitLine: {
|
|
110
|
+
show: true,
|
|
111
|
+
lineStyle: { color: theme.palette.black?.[4] ?? theme.palette.divider },
|
|
112
|
+
},
|
|
113
|
+
axisLabel: {
|
|
114
|
+
fontSize: theme.typography.overlineDelicate?.fontSize,
|
|
115
|
+
fontFamily: theme.typography.overlineDelicate?.fontFamily,
|
|
116
|
+
margin: parseInt(theme.spacing(1)),
|
|
117
|
+
show: true,
|
|
118
|
+
showMaxLabel: true,
|
|
119
|
+
showMinLabel: true,
|
|
120
|
+
verticalAlign: 'bottom',
|
|
121
|
+
inside: true,
|
|
122
|
+
formatter: (value: number) => {
|
|
123
|
+
if (value !== niceMax && value !== niceMin) return ''
|
|
124
|
+
if (value === 0) return ''
|
|
125
|
+
return formatter ? formatter(value) : String(value)
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
} as BarEChartsOption
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Returns the bar widget's {@link OptionFactory} — a single closure that
|
|
134
|
+
* handles BOTH option-construction phases:
|
|
135
|
+
*
|
|
136
|
+
* - **Structural phase** (`option == null`) — builds the theme-aware
|
|
137
|
+
* structural option via {@link barOptions}, optionally merging the
|
|
138
|
+
* consumer-supplied `optionsOverride` on top. Called once by Provider
|
|
139
|
+
* to seed `rawOptions` in the store; configTransforms (StackToggle /
|
|
140
|
+
* ZoomToggle / BrushToggle) then mutate it via the pipeline middleware.
|
|
141
|
+
* - **Merge phase** (`option != null`) — fuses post-pipeline `state.data`
|
|
142
|
+
* (`BarWidgetData`) into the option via the dataset API: one dataset
|
|
143
|
+
* per series, each series referencing its dataset by index, encoded
|
|
144
|
+
* by `name` (x) and `value` (y). Spreads any series-template fields
|
|
145
|
+
* already on the incoming option (e.g. `{ stack: 'total' }` from
|
|
146
|
+
* `addStack`) into every emitted series so configTransforms compose
|
|
147
|
+
* end-to-end. Reactive `ctx.formatter` / `ctx.labelFormatter` drive
|
|
148
|
+
* the y-axis min/max-only label and the tooltip formatter at fusion
|
|
149
|
+
* time so RelativeData's percent formatter flows through without a
|
|
150
|
+
* structural rebuild.
|
|
151
|
+
*
|
|
152
|
+
* Stable identity when the inputs don't change (consumers should wrap the
|
|
153
|
+
* call in `useMemo` keyed on the same inputs).
|
|
154
|
+
*/
|
|
155
|
+
export function createBarOptionFactory(
|
|
156
|
+
options: BarOptionFactoryInput,
|
|
157
|
+
): OptionFactory {
|
|
158
|
+
const { theme, formatter, labelFormatter, optionsOverride } = options
|
|
159
|
+
const seriesNames = options.seriesNames
|
|
160
|
+
const selection = options.selection
|
|
161
|
+
const selectionSet =
|
|
162
|
+
selection && selection.length > 0
|
|
163
|
+
? new Set<string | number>(selection)
|
|
164
|
+
: null
|
|
165
|
+
return (option, data, ctx) => {
|
|
166
|
+
// Structural phase: Provider seeds rawOptions with this branch. No data
|
|
167
|
+
// is read; we just emit the theme-aware base (optionally with override).
|
|
168
|
+
if (option == null) {
|
|
169
|
+
const structural = barOptions({ theme, formatter, labelFormatter })
|
|
170
|
+
return optionsOverride
|
|
171
|
+
? (mergeOptions(
|
|
172
|
+
structural as unknown as Record<string, unknown>,
|
|
173
|
+
optionsOverride as Partial<Record<string, unknown>>,
|
|
174
|
+
) as EChartsOption)
|
|
175
|
+
: structural
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const seriesArr = Array.isArray(data) ? (data as BarWidgetData) : []
|
|
179
|
+
if (seriesArr.length === 0) {
|
|
180
|
+
return { ...option, dataset: [], series: [] }
|
|
181
|
+
}
|
|
182
|
+
const hasLegend = seriesArr.length > 1
|
|
183
|
+
const baseLegend =
|
|
184
|
+
typeof option.legend === 'object' && !Array.isArray(option.legend)
|
|
185
|
+
? option.legend
|
|
186
|
+
: {}
|
|
187
|
+
const baseGrid =
|
|
188
|
+
typeof option.grid === 'object' && !Array.isArray(option.grid)
|
|
189
|
+
? option.grid
|
|
190
|
+
: {}
|
|
191
|
+
const baseTooltip =
|
|
192
|
+
typeof option.tooltip === 'object' && !Array.isArray(option.tooltip)
|
|
193
|
+
? option.tooltip
|
|
194
|
+
: {}
|
|
195
|
+
const baseYAxis =
|
|
196
|
+
typeof option.yAxis === 'object' && !Array.isArray(option.yAxis)
|
|
197
|
+
? option.yAxis
|
|
198
|
+
: {}
|
|
199
|
+
|
|
200
|
+
const seriesTemplates = Array.isArray(option.series) ? option.series : []
|
|
201
|
+
const broadcastTemplate = seriesTemplates[0] ?? {}
|
|
202
|
+
|
|
203
|
+
// Reactive (live store) formatters from ctx — distinct from the
|
|
204
|
+
// closure-time `formatter` / `labelFormatter` captured for the
|
|
205
|
+
// structural-build branch above. RelativeData can install a percent
|
|
206
|
+
// formatter on the store after the factory was constructed; the merge
|
|
207
|
+
// phase reads `ctx` to pick that up.
|
|
208
|
+
const liveFormatter = ctx?.formatter
|
|
209
|
+
const liveLabelFormatter = ctx?.labelFormatter
|
|
210
|
+
|
|
211
|
+
const { niceMinVal, niceMaxVal } = computeNiceBounds(seriesArr)
|
|
212
|
+
|
|
213
|
+
// Zoom slider layout: when ZoomToggle has installed `dataZoom`, push the
|
|
214
|
+
// slider above the legend (if any) and reserve room in the grid below.
|
|
215
|
+
const dataZoomLayout = positionDataZoomForLegend(option.dataZoom, hasLegend)
|
|
216
|
+
const fallbackBottom =
|
|
217
|
+
typeof baseGrid.bottom === 'number' ? baseGrid.bottom : 24
|
|
218
|
+
const baseBottom = hasLegend ? 56 : fallbackBottom
|
|
219
|
+
const gridBottom = dataZoomLayout
|
|
220
|
+
? baseBottom + ZOOM_LAYOUT.sliderHeight + ZOOM_LAYOUT.sliderGap
|
|
221
|
+
: baseBottom
|
|
222
|
+
|
|
223
|
+
// When a selection is active, dim non-selected bars by routing the
|
|
224
|
+
// resolved palette color through `modifyAlpha`. Per-row `itemStyle` on
|
|
225
|
+
// dataset object-rows is silently ignored when `series.encode` is in
|
|
226
|
+
// play — the callback approach is the standard ECharts pattern for
|
|
227
|
+
// per-data styling derived from a dataset.
|
|
228
|
+
//
|
|
229
|
+
// We *always* emit `itemStyle.color` (a passthrough when nothing is
|
|
230
|
+
// selected), not conditionally — dropping the key between renders
|
|
231
|
+
// would let ECharts' default merge keep the previous callback alive
|
|
232
|
+
// and bars would stay dimmed forever after an external clear. Always
|
|
233
|
+
// emitting lets normal merge swap the callback in place, no
|
|
234
|
+
// `replaceMerge` and no entry-animation flash on selection on/off.
|
|
235
|
+
const dimItemStyle = {
|
|
236
|
+
color: (params: CallbackDataParams) => {
|
|
237
|
+
const base = params.color as string
|
|
238
|
+
if (!selectionSet) return base
|
|
239
|
+
const datum = params.value as { name?: string | number } | undefined
|
|
240
|
+
const name = datum?.name ?? params.name
|
|
241
|
+
return name != null && selectionSet.has(name)
|
|
242
|
+
? base
|
|
243
|
+
: echarts.color.modifyAlpha(base, 0.15)
|
|
244
|
+
},
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return {
|
|
248
|
+
...option,
|
|
249
|
+
dataset: seriesArr.map((s) => ({ source: s as readonly object[] })),
|
|
250
|
+
series: seriesArr.map((_, i) => {
|
|
251
|
+
const template =
|
|
252
|
+
(seriesTemplates[i] as object | undefined) ??
|
|
253
|
+
(broadcastTemplate as object)
|
|
254
|
+
return {
|
|
255
|
+
...(typeof template === 'object' ? template : {}),
|
|
256
|
+
type: 'bar' as const,
|
|
257
|
+
datasetIndex: i,
|
|
258
|
+
name: seriesNames?.[i] ?? `Series ${i + 1}`,
|
|
259
|
+
encode: { x: 'name', y: 'value' },
|
|
260
|
+
barMaxWidth: 100,
|
|
261
|
+
emphasis: { focus: 'series' },
|
|
262
|
+
itemStyle: dimItemStyle,
|
|
263
|
+
}
|
|
264
|
+
}),
|
|
265
|
+
legend: { ...baseLegend, show: hasLegend },
|
|
266
|
+
grid: {
|
|
267
|
+
...baseGrid,
|
|
268
|
+
bottom: gridBottom,
|
|
269
|
+
},
|
|
270
|
+
...(dataZoomLayout ? { dataZoom: dataZoomLayout } : {}),
|
|
271
|
+
yAxis: {
|
|
272
|
+
...baseYAxis,
|
|
273
|
+
min: niceMinVal,
|
|
274
|
+
max: niceMaxVal,
|
|
275
|
+
axisLabel: {
|
|
276
|
+
...((baseYAxis as { axisLabel?: object }).axisLabel ?? {}),
|
|
277
|
+
formatter: (value: number) => {
|
|
278
|
+
if (value !== niceMaxVal && value !== niceMinVal) return ''
|
|
279
|
+
if (value === 0) return ''
|
|
280
|
+
return liveFormatter ? liveFormatter(value) : String(value)
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
} as EChartsOption['yAxis'],
|
|
284
|
+
tooltip: {
|
|
285
|
+
...baseTooltip,
|
|
286
|
+
formatter: buildBarTooltipFormatter(liveFormatter, liveLabelFormatter),
|
|
287
|
+
},
|
|
288
|
+
} as EChartsOption
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function buildBarTooltipFormatter(
|
|
293
|
+
formatter: ((value: number) => string) | undefined,
|
|
294
|
+
labelFormatter: ((value: string | number) => string | number) | undefined,
|
|
295
|
+
) {
|
|
296
|
+
return createTooltipFormatter((item) => {
|
|
297
|
+
const row = item.value as { name?: string | number; value?: number }
|
|
298
|
+
const raw = row?.value
|
|
299
|
+
const formattedValue =
|
|
300
|
+
typeof raw === 'number' && formatter ? formatter(raw) : (raw ?? '')
|
|
301
|
+
const marker = typeof item.marker === 'string' ? item.marker : ''
|
|
302
|
+
const seriesName = item.seriesName ? `${item.seriesName}: ` : ''
|
|
303
|
+
const name = labelFormatter
|
|
304
|
+
? String(labelFormatter(item.name ?? ''))
|
|
305
|
+
: (item.name ?? '')
|
|
306
|
+
return { name: String(name), seriesName, marker, value: formattedValue }
|
|
307
|
+
})
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function computeNiceBounds(seriesArr: BarWidgetData): {
|
|
311
|
+
niceMinVal: number
|
|
312
|
+
niceMaxVal: number
|
|
313
|
+
} {
|
|
314
|
+
let min = 0
|
|
315
|
+
let max = -Infinity
|
|
316
|
+
for (const series of seriesArr) {
|
|
317
|
+
for (const d of series) {
|
|
318
|
+
if (typeof d?.value !== 'number' || !Number.isFinite(d.value)) continue
|
|
319
|
+
if (d.value < min) min = d.value
|
|
320
|
+
if (d.value > max) max = d.value
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
const niceMinVal = min < 0 ? niceNum(min) : 0
|
|
324
|
+
const niceMaxVal = max <= 0 ? 1 : niceNum(max)
|
|
325
|
+
return { niceMinVal, niceMaxVal }
|
|
326
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { render } from '@testing-library/react'
|
|
3
|
+
import { BarSkeleton } from './skeleton'
|
|
4
|
+
|
|
5
|
+
describe('<BarSkeleton>', () => {
|
|
6
|
+
it('renders without crashing', () => {
|
|
7
|
+
const { container } = render(<BarSkeleton />)
|
|
8
|
+
expect(container.firstChild).not.toBeNull()
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('renders MUI Skeleton placeholders for the bars + axis', () => {
|
|
12
|
+
const { container } = render(<BarSkeleton />)
|
|
13
|
+
// MuiSkeleton applies the .MuiSkeleton-root class — count > 1 confirms
|
|
14
|
+
// both the bar grid AND the axis row are emitted.
|
|
15
|
+
expect(
|
|
16
|
+
container.querySelectorAll('.MuiSkeleton-root').length,
|
|
17
|
+
).toBeGreaterThan(1)
|
|
18
|
+
})
|
|
19
|
+
})
|