@k2b/ui 0.50.0 → 0.52.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/base.css +35 -1
- package/dist/browser/actions/Button.js.map +1 -1
- package/dist/browser/actions/CommandList.js +861 -0
- package/dist/browser/actions/CommandList.js.map +1 -0
- package/dist/browser/actions/CommandMenu.js +237 -0
- package/dist/browser/actions/CommandMenu.js.map +1 -0
- package/dist/browser/actions/Dropdown.js +43 -10
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/Toolbar.js +8 -2
- package/dist/browser/actions/Toolbar.js.map +1 -1
- package/dist/browser/actions/command-dock.js +47 -0
- package/dist/browser/actions/command-dock.js.map +1 -0
- package/dist/browser/actions/command-items.js +84 -0
- package/dist/browser/actions/command-items.js.map +1 -0
- package/dist/browser/actions/command-messages.js +42 -0
- package/dist/browser/actions/command-messages.js.map +1 -0
- package/dist/browser/actions/index.js +1 -0
- package/dist/browser/actions/index.js.map +1 -1
- package/dist/browser/charts/core/area.js +3 -5
- package/dist/browser/charts/core/area.js.map +1 -1
- package/dist/browser/charts/core/bar-labels.js +5 -0
- package/dist/browser/charts/core/bar-labels.js.map +1 -0
- package/dist/browser/charts/core/bubble.js +166 -0
- package/dist/browser/charts/core/bubble.js.map +1 -0
- package/dist/browser/charts/core/calendar.js +1 -1
- package/dist/browser/charts/core/calendar.js.map +1 -1
- package/dist/browser/charts/core/chart-messages.js +17 -0
- package/dist/browser/charts/core/chart-messages.js.map +1 -0
- package/dist/browser/charts/core/default-styles.js +83 -0
- package/dist/browser/charts/core/default-styles.js.map +1 -0
- package/dist/browser/charts/core/funnel-layout.js +79 -0
- package/dist/browser/charts/core/funnel-layout.js.map +1 -0
- package/dist/browser/charts/core/funnel.js +27 -0
- package/dist/browser/charts/core/funnel.js.map +1 -0
- package/dist/browser/charts/core/hbar-layout.js +118 -0
- package/dist/browser/charts/core/hbar-layout.js.map +1 -0
- package/dist/browser/charts/core/hbar.js +39 -0
- package/dist/browser/charts/core/hbar.js.map +1 -0
- package/dist/browser/charts/core/index.js +12 -2
- package/dist/browser/charts/core/index.js.map +1 -1
- package/dist/browser/charts/core/map.js +116 -0
- package/dist/browser/charts/core/map.js.map +1 -0
- package/dist/browser/charts/core/pareto.js +120 -0
- package/dist/browser/charts/core/pareto.js.map +1 -0
- package/dist/browser/charts/core/radar.js +101 -0
- package/dist/browser/charts/core/radar.js.map +1 -0
- package/dist/browser/charts/core/registry.js +33 -16
- package/dist/browser/charts/core/registry.js.map +1 -1
- package/dist/browser/charts/core/render-size.js +15 -0
- package/dist/browser/charts/core/render-size.js.map +1 -0
- package/dist/browser/charts/core/render.js +39 -10
- package/dist/browser/charts/core/render.js.map +1 -1
- package/dist/browser/charts/core/snapshot.js +4 -4
- package/dist/browser/charts/core/snapshot.js.map +1 -1
- package/dist/browser/charts/core/svg-barGauge.js +67 -0
- package/dist/browser/charts/core/svg-barGauge.js.map +1 -0
- package/dist/browser/charts/core/svg-boxplot.js +127 -0
- package/dist/browser/charts/core/svg-boxplot.js.map +1 -0
- package/dist/browser/charts/core/svg-common.js +1065 -0
- package/dist/browser/charts/core/svg-common.js.map +1 -0
- package/dist/browser/charts/core/svg-gauge.js +185 -0
- package/dist/browser/charts/core/svg-gauge.js.map +1 -0
- package/dist/browser/charts/core/svg-heatmap.js +80 -0
- package/dist/browser/charts/core/svg-heatmap.js.map +1 -0
- package/dist/browser/charts/core/svg-histogram.js +73 -0
- package/dist/browser/charts/core/svg-histogram.js.map +1 -0
- package/dist/browser/charts/core/svg-renderers.js +638 -0
- package/dist/browser/charts/core/svg-renderers.js.map +1 -0
- package/dist/browser/charts/core/svg-scatter.js +114 -0
- package/dist/browser/charts/core/svg-scatter.js.map +1 -0
- package/dist/browser/charts/core/svg.js +4 -2525
- package/dist/browser/charts/core/svg.js.map +1 -1
- package/dist/browser/charts/core/treemap.js +138 -0
- package/dist/browser/charts/core/treemap.js.map +1 -0
- package/dist/browser/charts/core/types.js +0 -2
- package/dist/browser/charts/core/types.js.map +1 -1
- package/dist/browser/charts/core/waterfall.js +162 -0
- package/dist/browser/charts/core/waterfall.js.map +1 -0
- package/dist/browser/charts/description.js +2 -0
- package/dist/browser/charts/description.js.map +1 -0
- package/dist/browser/charts.js.map +1 -1
- package/dist/browser/content/Chart.js +14 -628
- package/dist/browser/content/Chart.js.map +1 -1
- package/dist/browser/content/ChartRoot.js +646 -0
- package/dist/browser/content/ChartRoot.js.map +1 -0
- package/dist/browser/content/ChartSnapshotView.js +4 -1
- package/dist/browser/content/ChartSnapshotView.js.map +1 -1
- package/dist/browser/content/ChartSparkline.js +24 -0
- package/dist/browser/content/ChartSparkline.js.map +1 -0
- package/dist/browser/content/DataTable.js +186 -193
- package/dist/browser/content/DataTable.js.map +1 -1
- package/dist/browser/content/FileView.js +111 -61
- package/dist/browser/content/FileView.js.map +1 -1
- package/dist/browser/content/Lightbox.js +62 -30
- package/dist/browser/content/Lightbox.js.map +1 -1
- package/dist/browser/content/MapView.js +30 -28
- package/dist/browser/content/MapView.js.map +1 -1
- package/dist/browser/content/PdfPreview.js +84 -52
- package/dist/browser/content/PdfPreview.js.map +1 -1
- package/dist/browser/content/PdfViewer.js +588 -0
- package/dist/browser/content/PdfViewer.js.map +1 -0
- package/dist/browser/content/ThumbnailStrip.js +174 -0
- package/dist/browser/content/ThumbnailStrip.js.map +1 -0
- package/dist/browser/content/chart-bar.js +344 -16
- package/dist/browser/content/chart-bar.js.map +1 -1
- package/dist/browser/content/chart-inspection-core.js +50 -29
- package/dist/browser/content/chart-inspection-core.js.map +1 -1
- package/dist/browser/content/chart-line-gaps.js +1 -1
- package/dist/browser/content/chart-line-gaps.js.map +1 -1
- package/dist/browser/content/chart-message-catalog.js +28 -0
- package/dist/browser/content/chart-message-catalog.js.map +1 -1
- package/dist/browser/content/chart-state-timeline.js +1 -1
- package/dist/browser/content/chart-state-timeline.js.map +1 -1
- package/dist/browser/content/chart-svg.js +2 -1
- package/dist/browser/content/chart-svg.js.map +1 -1
- package/dist/browser/content/index.js +2 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/content/pdf-document.js +29 -0
- package/dist/browser/content/pdf-document.js.map +1 -0
- package/dist/browser/content/pdf-limits.js +31 -0
- package/dist/browser/content/pdf-limits.js.map +1 -0
- package/dist/browser/content/pdf-messages.js +34 -2
- package/dist/browser/content/pdf-messages.js.map +1 -1
- package/dist/browser/content/pdf-viewer-engine.js +57 -0
- package/dist/browser/content/pdf-viewer-worker.js +28 -0
- package/dist/browser/content/thumbnail-strip-messages.js +24 -0
- package/dist/browser/content/thumbnail-strip-messages.js.map +1 -0
- package/dist/browser/inputs/ChoiceInputs.js +150 -76
- package/dist/browser/inputs/ChoiceInputs.js.map +1 -1
- package/dist/browser/inputs/ChoiceSlider.js +75 -58
- package/dist/browser/inputs/ChoiceSlider.js.map +1 -1
- package/dist/browser/inputs/DatePicker.js +113 -98
- package/dist/browser/inputs/DatePicker.js.map +1 -1
- package/dist/browser/inputs/PeriodPicker.js +874 -0
- package/dist/browser/inputs/PeriodPicker.js.map +1 -0
- package/dist/browser/inputs/index.js +5 -1
- package/dist/browser/inputs/index.js.map +1 -1
- package/dist/browser/inputs/input-messages.js +8 -2
- package/dist/browser/inputs/input-messages.js.map +1 -1
- package/dist/browser/inputs/markdown/MarkdownEditor.js +14 -10
- package/dist/browser/inputs/markdown/MarkdownEditor.js.map +1 -1
- package/dist/browser/inputs/markdown/MarkdownSelectionToolbar.js +330 -0
- package/dist/browser/inputs/markdown/MarkdownSelectionToolbar.js.map +1 -0
- package/dist/browser/inputs/markdown/SlashCommands.js +402 -0
- package/dist/browser/inputs/markdown/SlashCommands.js.map +1 -0
- package/dist/browser/inputs/period-picker-messages.js +71 -0
- package/dist/browser/inputs/period-picker-messages.js.map +1 -0
- package/dist/browser/inputs/period.js +263 -0
- package/dist/browser/inputs/period.js.map +1 -0
- package/dist/browser/internal/field.js +96 -77
- package/dist/browser/internal/field.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +7 -5
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/DetailPanel.js +147 -120
- package/dist/browser/layout/DetailPanel.js.map +1 -1
- package/dist/browser/layout/Discussion.js +101 -108
- package/dist/browser/layout/Discussion.js.map +1 -1
- package/dist/browser/layout/PanelDialog.js +92 -68
- package/dist/browser/layout/PanelDialog.js.map +1 -1
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/surfaces/DescriptionList.js +5 -2
- package/dist/browser/surfaces/DescriptionList.js.map +1 -1
- package/dist/browser/surfaces/StatCell.js +95 -78
- package/dist/browser/surfaces/StatCell.js.map +1 -1
- package/dist/browser/surfaces/delta-badge.js +16 -2
- package/dist/browser/surfaces/delta-badge.js.map +1 -1
- package/dist/browser/surfaces/stat-cell-messages.js +4 -2
- package/dist/browser/surfaces/stat-cell-messages.js.map +1 -1
- package/dist/browser/widgets/DashboardFrame.js +315 -0
- package/dist/browser/widgets/DashboardFrame.js.map +1 -0
- package/dist/browser/widgets/index.js +1 -0
- package/dist/browser/widgets/index.js.map +1 -1
- package/dist/licenses/pdfjs-dist.txt +177 -0
- package/dist/ssr/actions/Button.js.map +1 -1
- package/dist/ssr/actions/CommandList.js +638 -0
- package/dist/ssr/actions/CommandList.js.map +1 -0
- package/dist/ssr/actions/CommandMenu.js +197 -0
- package/dist/ssr/actions/CommandMenu.js.map +1 -0
- package/dist/ssr/actions/Dropdown.js +43 -10
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/Toolbar.js +8 -2
- package/dist/ssr/actions/Toolbar.js.map +1 -1
- package/dist/ssr/actions/command-dock.js +47 -0
- package/dist/ssr/actions/command-dock.js.map +1 -0
- package/dist/ssr/actions/command-items.js +84 -0
- package/dist/ssr/actions/command-items.js.map +1 -0
- package/dist/ssr/actions/command-messages.js +42 -0
- package/dist/ssr/actions/command-messages.js.map +1 -0
- package/dist/ssr/actions/index.js +1 -0
- package/dist/ssr/actions/index.js.map +1 -1
- package/dist/ssr/charts/core/area.js +3 -5
- package/dist/ssr/charts/core/area.js.map +1 -1
- package/dist/ssr/charts/core/bar-labels.js +5 -0
- package/dist/ssr/charts/core/bar-labels.js.map +1 -0
- package/dist/ssr/charts/core/bubble.js +166 -0
- package/dist/ssr/charts/core/bubble.js.map +1 -0
- package/dist/ssr/charts/core/calendar.js +1 -1
- package/dist/ssr/charts/core/calendar.js.map +1 -1
- package/dist/ssr/charts/core/chart-messages.js +17 -0
- package/dist/ssr/charts/core/chart-messages.js.map +1 -0
- package/dist/ssr/charts/core/default-styles.js +83 -0
- package/dist/ssr/charts/core/default-styles.js.map +1 -0
- package/dist/ssr/charts/core/funnel-layout.js +79 -0
- package/dist/ssr/charts/core/funnel-layout.js.map +1 -0
- package/dist/ssr/charts/core/funnel.js +27 -0
- package/dist/ssr/charts/core/funnel.js.map +1 -0
- package/dist/ssr/charts/core/hbar-layout.js +118 -0
- package/dist/ssr/charts/core/hbar-layout.js.map +1 -0
- package/dist/ssr/charts/core/hbar.js +39 -0
- package/dist/ssr/charts/core/hbar.js.map +1 -0
- package/dist/ssr/charts/core/index.js +12 -2
- package/dist/ssr/charts/core/index.js.map +1 -1
- package/dist/ssr/charts/core/map.js +116 -0
- package/dist/ssr/charts/core/map.js.map +1 -0
- package/dist/ssr/charts/core/pareto.js +120 -0
- package/dist/ssr/charts/core/pareto.js.map +1 -0
- package/dist/ssr/charts/core/radar.js +101 -0
- package/dist/ssr/charts/core/radar.js.map +1 -0
- package/dist/ssr/charts/core/registry.js +33 -16
- package/dist/ssr/charts/core/registry.js.map +1 -1
- package/dist/ssr/charts/core/render-size.js +15 -0
- package/dist/ssr/charts/core/render-size.js.map +1 -0
- package/dist/ssr/charts/core/render.js +39 -10
- package/dist/ssr/charts/core/render.js.map +1 -1
- package/dist/ssr/charts/core/snapshot.js +4 -4
- package/dist/ssr/charts/core/snapshot.js.map +1 -1
- package/dist/ssr/charts/core/svg-barGauge.js +67 -0
- package/dist/ssr/charts/core/svg-barGauge.js.map +1 -0
- package/dist/ssr/charts/core/svg-boxplot.js +127 -0
- package/dist/ssr/charts/core/svg-boxplot.js.map +1 -0
- package/dist/ssr/charts/core/svg-common.js +1065 -0
- package/dist/ssr/charts/core/svg-common.js.map +1 -0
- package/dist/ssr/charts/core/svg-gauge.js +185 -0
- package/dist/ssr/charts/core/svg-gauge.js.map +1 -0
- package/dist/ssr/charts/core/svg-heatmap.js +80 -0
- package/dist/ssr/charts/core/svg-heatmap.js.map +1 -0
- package/dist/ssr/charts/core/svg-histogram.js +73 -0
- package/dist/ssr/charts/core/svg-histogram.js.map +1 -0
- package/dist/ssr/charts/core/svg-renderers.js +638 -0
- package/dist/ssr/charts/core/svg-renderers.js.map +1 -0
- package/dist/ssr/charts/core/svg-scatter.js +114 -0
- package/dist/ssr/charts/core/svg-scatter.js.map +1 -0
- package/dist/ssr/charts/core/svg.js +4 -2525
- package/dist/ssr/charts/core/svg.js.map +1 -1
- package/dist/ssr/charts/core/treemap.js +138 -0
- package/dist/ssr/charts/core/treemap.js.map +1 -0
- package/dist/ssr/charts/core/types.js +0 -2
- package/dist/ssr/charts/core/types.js.map +1 -1
- package/dist/ssr/charts/core/waterfall.js +162 -0
- package/dist/ssr/charts/core/waterfall.js.map +1 -0
- package/dist/ssr/charts/description.js +2 -0
- package/dist/ssr/charts/description.js.map +1 -0
- package/dist/ssr/charts.js.map +1 -1
- package/dist/ssr/content/Chart.js +14 -471
- package/dist/ssr/content/Chart.js.map +1 -1
- package/dist/ssr/content/ChartRoot.js +489 -0
- package/dist/ssr/content/ChartRoot.js.map +1 -0
- package/dist/ssr/content/ChartSnapshotView.js +1 -0
- package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
- package/dist/ssr/content/ChartSparkline.js +24 -0
- package/dist/ssr/content/ChartSparkline.js.map +1 -0
- package/dist/ssr/content/DataTable.js +12 -16
- package/dist/ssr/content/DataTable.js.map +1 -1
- package/dist/ssr/content/FileView.js +56 -7
- package/dist/ssr/content/FileView.js.map +1 -1
- package/dist/ssr/content/Lightbox.js +39 -10
- package/dist/ssr/content/Lightbox.js.map +1 -1
- package/dist/ssr/content/MapView.js +9 -9
- package/dist/ssr/content/MapView.js.map +1 -1
- package/dist/ssr/content/PdfPreview.js +49 -20
- package/dist/ssr/content/PdfPreview.js.map +1 -1
- package/dist/ssr/content/PdfViewer.js +484 -0
- package/dist/ssr/content/PdfViewer.js.map +1 -0
- package/dist/ssr/content/ThumbnailStrip.js +103 -0
- package/dist/ssr/content/ThumbnailStrip.js.map +1 -0
- package/dist/ssr/content/chart-bar.js +344 -16
- package/dist/ssr/content/chart-bar.js.map +1 -1
- package/dist/ssr/content/chart-inspection-core.js +50 -29
- package/dist/ssr/content/chart-inspection-core.js.map +1 -1
- package/dist/ssr/content/chart-line-gaps.js +1 -1
- package/dist/ssr/content/chart-line-gaps.js.map +1 -1
- package/dist/ssr/content/chart-message-catalog.js +28 -0
- package/dist/ssr/content/chart-message-catalog.js.map +1 -1
- package/dist/ssr/content/chart-state-timeline.js +1 -1
- package/dist/ssr/content/chart-state-timeline.js.map +1 -1
- package/dist/ssr/content/chart-svg.js +2 -1
- package/dist/ssr/content/chart-svg.js.map +1 -1
- package/dist/ssr/content/index.js +2 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/content/pdf-document.js +29 -0
- package/dist/ssr/content/pdf-document.js.map +1 -0
- package/dist/ssr/content/pdf-limits.js +31 -0
- package/dist/ssr/content/pdf-limits.js.map +1 -0
- package/dist/ssr/content/pdf-messages.js +34 -2
- package/dist/ssr/content/pdf-messages.js.map +1 -1
- package/dist/ssr/content/thumbnail-strip-messages.js +24 -0
- package/dist/ssr/content/thumbnail-strip-messages.js.map +1 -0
- package/dist/ssr/inputs/ChoiceInputs.js +69 -17
- package/dist/ssr/inputs/ChoiceInputs.js.map +1 -1
- package/dist/ssr/inputs/ChoiceSlider.js +17 -12
- package/dist/ssr/inputs/ChoiceSlider.js.map +1 -1
- package/dist/ssr/inputs/DatePicker.js +14 -9
- package/dist/ssr/inputs/DatePicker.js.map +1 -1
- package/dist/ssr/inputs/PeriodPicker.js +598 -0
- package/dist/ssr/inputs/PeriodPicker.js.map +1 -0
- package/dist/ssr/inputs/index.js +5 -1
- package/dist/ssr/inputs/index.js.map +1 -1
- package/dist/ssr/inputs/input-messages.js +8 -2
- package/dist/ssr/inputs/input-messages.js.map +1 -1
- package/dist/ssr/inputs/markdown/MarkdownEditor.js +3 -2
- package/dist/ssr/inputs/markdown/MarkdownEditor.js.map +1 -1
- package/dist/ssr/inputs/markdown/MarkdownSelectionToolbar.js +293 -0
- package/dist/ssr/inputs/markdown/MarkdownSelectionToolbar.js.map +1 -0
- package/dist/ssr/inputs/markdown/SlashCommands.js +339 -0
- package/dist/ssr/inputs/markdown/SlashCommands.js.map +1 -0
- package/dist/ssr/inputs/period-picker-messages.js +71 -0
- package/dist/ssr/inputs/period-picker-messages.js.map +1 -0
- package/dist/ssr/inputs/period.js +263 -0
- package/dist/ssr/inputs/period.js.map +1 -0
- package/dist/ssr/internal/field.js +36 -24
- package/dist/ssr/internal/field.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +5 -1
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/DetailPanel.js +27 -4
- package/dist/ssr/layout/DetailPanel.js.map +1 -1
- package/dist/ssr/layout/Discussion.js +16 -2
- package/dist/ssr/layout/Discussion.js.map +1 -1
- package/dist/ssr/layout/PanelDialog.js +40 -26
- package/dist/ssr/layout/PanelDialog.js.map +1 -1
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/surfaces/DescriptionList.js +1 -1
- package/dist/ssr/surfaces/DescriptionList.js.map +1 -1
- package/dist/ssr/surfaces/StatCell.js +31 -21
- package/dist/ssr/surfaces/StatCell.js.map +1 -1
- package/dist/ssr/surfaces/delta-badge.js +16 -2
- package/dist/ssr/surfaces/delta-badge.js.map +1 -1
- package/dist/ssr/surfaces/stat-cell-messages.js +4 -2
- package/dist/ssr/surfaces/stat-cell-messages.js.map +1 -1
- package/dist/ssr/widgets/DashboardFrame.js +195 -0
- package/dist/ssr/widgets/DashboardFrame.js.map +1 -0
- package/dist/ssr/widgets/index.js +1 -0
- package/dist/ssr/widgets/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/Button.d.ts +1 -1
- package/dist/types/actions/CommandList.d.ts +120 -0
- package/dist/types/actions/CommandMenu.d.ts +39 -0
- package/dist/types/actions/Dropdown.d.ts +17 -0
- package/dist/types/actions/Toolbar.d.ts +2 -0
- package/dist/types/actions/command-dock.d.ts +8 -0
- package/dist/types/actions/command-items.d.ts +134 -0
- package/dist/types/actions/command-messages.d.ts +19 -0
- package/dist/types/actions/index.d.ts +3 -0
- package/dist/types/charts/core/bar-labels.d.ts +1 -0
- package/dist/types/charts/core/bubble.d.ts +66 -0
- package/dist/types/charts/core/calendar.d.ts +1 -1
- package/dist/types/charts/core/chart-messages.d.ts +5 -0
- package/dist/types/charts/core/default-styles.d.ts +1 -0
- package/dist/types/charts/core/funnel-layout.d.ts +43 -0
- package/dist/types/charts/core/funnel.d.ts +13 -0
- package/dist/types/charts/core/hbar-layout.d.ts +74 -0
- package/dist/types/charts/core/hbar.d.ts +13 -0
- package/dist/types/charts/core/index.d.ts +12 -2
- package/dist/types/charts/core/map.d.ts +3 -0
- package/dist/types/charts/core/pareto.d.ts +40 -0
- package/dist/types/charts/core/radar.d.ts +47 -0
- package/dist/types/charts/core/registry.d.ts +27 -11
- package/dist/types/charts/core/render-size.d.ts +7 -0
- package/dist/types/charts/core/render.d.ts +1 -4
- package/dist/types/charts/core/snapshot.d.ts +2 -2
- package/dist/types/charts/core/svg-barGauge.d.ts +3 -0
- package/dist/types/charts/core/svg-boxplot.d.ts +18 -0
- package/dist/types/charts/core/svg-common.d.ts +612 -0
- package/dist/types/charts/core/svg-gauge.d.ts +6 -0
- package/dist/types/charts/core/svg-heatmap.d.ts +6 -0
- package/dist/types/charts/core/svg-histogram.d.ts +16 -0
- package/dist/types/charts/core/svg-renderers.d.ts +118 -0
- package/dist/types/charts/core/svg-scatter.d.ts +23 -0
- package/dist/types/charts/core/svg.d.ts +4 -698
- package/dist/types/charts/core/treemap.d.ts +45 -0
- package/dist/types/charts/core/types.d.ts +1 -12
- package/dist/types/charts/core/waterfall.d.ts +68 -0
- package/dist/types/charts/description.d.ts +289 -0
- package/dist/types/charts.d.ts +1 -0
- package/dist/types/content/Chart.d.ts +3 -91
- package/dist/types/content/ChartRoot.d.ts +92 -0
- package/dist/types/content/ChartSparkline.d.ts +5 -0
- package/dist/types/content/Lightbox.d.ts +2 -0
- package/dist/types/content/PdfViewer.d.ts +32 -0
- package/dist/types/content/ThumbnailStrip.d.ts +29 -0
- package/dist/types/content/chart-bar.d.ts +131 -2
- package/dist/types/content/chart-inspection-core.d.ts +7 -0
- package/dist/types/content/chart-inspection.d.ts +1 -0
- package/dist/types/content/chart-message-catalog.d.ts +8 -0
- package/dist/types/content/index.d.ts +3 -0
- package/dist/types/content/pdf-document.d.ts +5 -0
- package/dist/types/content/pdf-engine.d.ts +9 -0
- package/dist/types/content/pdf-limits.d.ts +43 -0
- package/dist/types/content/pdf-messages.d.ts +16 -0
- package/dist/types/content/thumbnail-strip-messages.d.ts +10 -0
- package/dist/types/inputs/ChoiceInputs.d.ts +6 -0
- package/dist/types/inputs/ChoiceSlider.d.ts +12 -0
- package/dist/types/inputs/DatePicker.d.ts +22 -0
- package/dist/types/inputs/PeriodPicker.d.ts +24 -0
- package/dist/types/inputs/index.d.ts +10 -2
- package/dist/types/inputs/input-messages.d.ts +3 -0
- package/dist/types/inputs/markdown/MarkdownEditor.d.ts +5 -0
- package/dist/types/inputs/markdown/MarkdownSelectionToolbar.d.ts +19 -0
- package/dist/types/inputs/markdown/SlashCommands.d.ts +20 -0
- package/dist/types/inputs/period-picker-messages.d.ts +34 -0
- package/dist/types/inputs/period.d.ts +134 -0
- package/dist/types/internal/field.d.ts +2 -0
- package/dist/types/layout/DetailPanel.d.ts +12 -0
- package/dist/types/layout/PanelDialog.d.ts +5 -0
- package/dist/types/layout/index.d.ts +1 -1
- package/dist/types/surfaces/DescriptionList.d.ts +5 -0
- package/dist/types/surfaces/StatCell.d.ts +6 -1
- package/dist/types/surfaces/stat-cell-messages.d.ts +1 -0
- package/dist/types/widgets/DashboardFrame.d.ts +61 -0
- package/dist/types/widgets/index.d.ts +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { ssr as _$ssr } from "solid-js/web";
|
|
2
|
+
import { createComponent as _$createComponent } from "solid-js/web";
|
|
3
|
+
import { ssrAttribute as _$ssrAttribute } from "solid-js/web";
|
|
4
|
+
import { escape as _$escape } from "solid-js/web";
|
|
5
|
+
var _tmpl$ = ["<nav class=\"", "\"", "><ul data-scroll-fade-mode=\"both\" data-scroll-fade-axis=\"horizontal\">", "", "</ul></nav>"],
|
|
6
|
+
_tmpl$2 = "<span class=\"k2b-thumbnail-strip__dirty\" aria-hidden=\"true\"></span>",
|
|
7
|
+
_tmpl$3 = ["<li><button type=\"button\" class=\"k2b-thumbnail-strip__thumb\"", " aria-label=\"", "\"", ">", "", "</button></li>"],
|
|
8
|
+
_tmpl$4 = ["<img", " alt loading=\"lazy\" decoding=\"async\" draggable=\"false\">"],
|
|
9
|
+
_tmpl$5 = "<i class=\"ti ti-plus\" aria-hidden=\"true\"></i>",
|
|
10
|
+
_tmpl$6 = ["<li>", "</li>"];
|
|
11
|
+
import { createEffect, For, on, Show } from "solid-js";
|
|
12
|
+
import { IconButton } from "../actions/Button";
|
|
13
|
+
import { createScrollFade } from "../layout/scroll-fade";
|
|
14
|
+
import { useThumbnailStripMessages } from "./thumbnail-strip-messages";
|
|
15
|
+
|
|
16
|
+
/** One image in a `ThumbnailStrip`. */
|
|
17
|
+
|
|
18
|
+
/** Room an item keeps from a fading edge when keyboard focus scrolls it into view. */
|
|
19
|
+
const EDGE = 48;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* A row of image thumbnails, 44 px high, that scrolls sideways and fades softly only on the side where more images
|
|
23
|
+
* follow. The current image is ringed and is the strip's one tab stop; the arrow keys, Home, and End move focus between
|
|
24
|
+
* images, and Enter or a click shows one. A dot marks unsaved edits. The host decides where the strip sits, also on a
|
|
25
|
+
* phone, and whether it floats over a picture.
|
|
26
|
+
*/
|
|
27
|
+
export function ThumbnailStrip(props) {
|
|
28
|
+
const messages = useThumbnailStripMessages();
|
|
29
|
+
let list;
|
|
30
|
+
createScrollFade(() => list, () => true);
|
|
31
|
+
|
|
32
|
+
// The current image scrolls into the middle whenever it or the list changes.
|
|
33
|
+
createEffect(on(() => [props.currentItem, props.items.length], () => queueMicrotask(() => {
|
|
34
|
+
const current = list?.querySelector('[aria-current="true"]');
|
|
35
|
+
if (!list || !current) return;
|
|
36
|
+
list.style.scrollBehavior = "auto";
|
|
37
|
+
list.scrollLeft = current.offsetLeft - (list.clientWidth - current.offsetWidth) / 2;
|
|
38
|
+
list.style.scrollBehavior = "";
|
|
39
|
+
})));
|
|
40
|
+
|
|
41
|
+
// A native listener, so a host that handles arrow keys itself, such as a lightbox, does not also see them.
|
|
42
|
+
const keys = event => {
|
|
43
|
+
// The "+" tile takes part in the arrow keys, so the keyboard reaches it without a tab stop of its own.
|
|
44
|
+
const thumbs = [...(list?.querySelectorAll(".k2b-thumbnail-strip__thumb, .k2b-thumbnail-strip__add") ?? [])];
|
|
45
|
+
const at = thumbs.findIndex(thumb => thumb === document.activeElement);
|
|
46
|
+
if (at < 0 || !list) return;
|
|
47
|
+
const to = {
|
|
48
|
+
ArrowRight: Math.min(thumbs.length - 1, at + 1),
|
|
49
|
+
ArrowLeft: Math.max(0, at - 1),
|
|
50
|
+
Home: 0,
|
|
51
|
+
End: thumbs.length - 1
|
|
52
|
+
}[event.key];
|
|
53
|
+
if (to === undefined) return;
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
event.stopPropagation();
|
|
56
|
+
thumbs.forEach((thumb, index) => {
|
|
57
|
+
thumb.tabIndex = index === to ? 0 : -1;
|
|
58
|
+
});
|
|
59
|
+
const target = thumbs[to];
|
|
60
|
+
if (!target) return;
|
|
61
|
+
target.focus({
|
|
62
|
+
preventScroll: true
|
|
63
|
+
});
|
|
64
|
+
if (target.offsetLeft < list.scrollLeft + EDGE) list.scrollLeft = target.offsetLeft - EDGE;else if (target.offsetLeft + target.offsetWidth > list.scrollLeft + list.clientWidth - EDGE) list.scrollLeft = target.offsetLeft + target.offsetWidth - list.clientWidth + EDGE;
|
|
65
|
+
};
|
|
66
|
+
return _$ssr(_tmpl$, `k2b-thumbnail-strip ${_$escape(props.class ?? "", true)}`, _$ssrAttribute("aria-label", _$escape(props.label, true), false), _$escape(_$createComponent(For, {
|
|
67
|
+
get each() {
|
|
68
|
+
return props.items;
|
|
69
|
+
},
|
|
70
|
+
children: item => {
|
|
71
|
+
const current = () => item.id === props.currentItem;
|
|
72
|
+
return _$ssr(_tmpl$3, _$ssrAttribute("aria-current", _$escape(current(), true), false) + _$ssrAttribute("tabindex", current() ? 0 : -1, false), `${_$escape(item.name, true)}${current() ? `, ${_$escape(messages().thumbnailCurrent, true)}` : ""}${item.dirty ? `, ${_$escape(messages().thumbnailUnsaved, true)}` : ""}`, _$ssrAttribute("title", _$escape(item.name, true), false), (() => {
|
|
73
|
+
const thumbnail = item.thumbnail;
|
|
74
|
+
if (typeof thumbnail === "function") return thumbnail();
|
|
75
|
+
return thumbnail ? _$ssr(_tmpl$4, _$ssrAttribute("src", _$escape(thumbnail, true), false)) : _$escape(null);
|
|
76
|
+
})(), _$escape(_$createComponent(Show, {
|
|
77
|
+
get when() {
|
|
78
|
+
return item.dirty;
|
|
79
|
+
},
|
|
80
|
+
get children() {
|
|
81
|
+
return _$ssr(_tmpl$2);
|
|
82
|
+
}
|
|
83
|
+
})));
|
|
84
|
+
}
|
|
85
|
+
})), _$escape(_$createComponent(Show, {
|
|
86
|
+
get when() {
|
|
87
|
+
return props.onAddItems;
|
|
88
|
+
},
|
|
89
|
+
children: add => _$ssr(_tmpl$6, _$escape(_$createComponent(IconButton, {
|
|
90
|
+
"class": "k2b-thumbnail-strip__add",
|
|
91
|
+
size: "sm",
|
|
92
|
+
tabindex: "-1",
|
|
93
|
+
get label() {
|
|
94
|
+
return messages().thumbnailAdd;
|
|
95
|
+
},
|
|
96
|
+
onClick: () => add()(),
|
|
97
|
+
get children() {
|
|
98
|
+
return _$ssr(_tmpl$5);
|
|
99
|
+
}
|
|
100
|
+
})))
|
|
101
|
+
})));
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=ThumbnailStrip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["content/ThumbnailStrip.tsx"],"sourcesContent":["import { createEffect, For, type JSX, on, Show } from \"solid-js\";\nimport { IconButton } from \"../actions/Button\";\nimport { createScrollFade } from \"../layout/scroll-fade\";\nimport { useThumbnailStripMessages } from \"./thumbnail-strip-messages\";\n\n/** One image in a `ThumbnailStrip`. */\nexport type ThumbnailStripItem = {\n id: string;\n name: string;\n /** Small image URL, or a component that renders the caller's own thumbnail; a neutral tile shows until it loads. */\n thumbnail?: string | (() => JSX.Element);\n /** Marks an image with unsaved edits. */\n dirty?: boolean;\n};\n\nexport type ThumbnailStripProps = {\n items: readonly ThumbnailStripItem[];\n /** The `id` of the shown image; it is ringed, scrolled into view, and the strip's one tab stop. */\n currentItem?: string;\n onSelectItem: (id: string) => void;\n /** Adds a \"+\" tile at the end. */\n onAddItems?: () => void;\n /** Accessible name of the strip, such as \"Images\". */\n label: string;\n /** The host's layer class, such as `k2b-overlay-surface` where the strip floats over a picture. */\n class?: string;\n};\n\n/** Room an item keeps from a fading edge when keyboard focus scrolls it into view. */\nconst EDGE = 48;\n\n/**\n * A row of image thumbnails, 44 px high, that scrolls sideways and fades softly only on the side where more images\n * follow. The current image is ringed and is the strip's one tab stop; the arrow keys, Home, and End move focus between\n * images, and Enter or a click shows one. A dot marks unsaved edits. The host decides where the strip sits, also on a\n * phone, and whether it floats over a picture.\n */\nexport function ThumbnailStrip(props: ThumbnailStripProps): JSX.Element {\n const messages = useThumbnailStripMessages();\n let list: HTMLUListElement | undefined;\n createScrollFade(\n () => list,\n () => true,\n );\n\n // The current image scrolls into the middle whenever it or the list changes.\n createEffect(\n on(\n () => [props.currentItem, props.items.length] as const,\n () =>\n queueMicrotask(() => {\n const current = list?.querySelector<HTMLElement>('[aria-current=\"true\"]');\n if (!list || !current) return;\n list.style.scrollBehavior = \"auto\";\n list.scrollLeft = current.offsetLeft - (list.clientWidth - current.offsetWidth) / 2;\n list.style.scrollBehavior = \"\";\n }),\n ),\n );\n\n // A native listener, so a host that handles arrow keys itself, such as a lightbox, does not also see them.\n const keys = (event: KeyboardEvent) => {\n // The \"+\" tile takes part in the arrow keys, so the keyboard reaches it without a tab stop of its own.\n const thumbs = [...(list?.querySelectorAll<HTMLButtonElement>(\".k2b-thumbnail-strip__thumb, .k2b-thumbnail-strip__add\") ?? [])];\n const at = thumbs.findIndex((thumb) => thumb === document.activeElement);\n if (at < 0 || !list) return;\n const to = { ArrowRight: Math.min(thumbs.length - 1, at + 1), ArrowLeft: Math.max(0, at - 1), Home: 0, End: thumbs.length - 1 }[\n event.key\n ];\n if (to === undefined) return;\n event.preventDefault();\n event.stopPropagation();\n thumbs.forEach((thumb, index) => {\n thumb.tabIndex = index === to ? 0 : -1;\n });\n const target = thumbs[to];\n if (!target) return;\n target.focus({ preventScroll: true });\n if (target.offsetLeft < list.scrollLeft + EDGE) list.scrollLeft = target.offsetLeft - EDGE;\n else if (target.offsetLeft + target.offsetWidth > list.scrollLeft + list.clientWidth - EDGE)\n list.scrollLeft = target.offsetLeft + target.offsetWidth - list.clientWidth + EDGE;\n };\n\n return (\n <nav class={`k2b-thumbnail-strip ${props.class ?? \"\"}`} aria-label={props.label}>\n <ul ref={list} data-scroll-fade-mode=\"both\" data-scroll-fade-axis=\"horizontal\" on:keydown={keys}>\n <For each={props.items}>\n {(item) => {\n const current = () => item.id === props.currentItem;\n return (\n <li>\n <button\n type=\"button\"\n class=\"k2b-thumbnail-strip__thumb\"\n aria-current={current()}\n tabindex={current() ? 0 : -1}\n aria-label={`${item.name}${current() ? `, ${messages().thumbnailCurrent}` : \"\"}${item.dirty ? `, ${messages().thumbnailUnsaved}` : \"\"}`}\n title={item.name}\n onClick={() => {\n if (!current()) props.onSelectItem(item.id);\n }}\n >\n {(() => {\n const thumbnail = item.thumbnail;\n if (typeof thumbnail === \"function\") return thumbnail();\n return thumbnail ? <img src={thumbnail} alt=\"\" loading=\"lazy\" decoding=\"async\" draggable={false} /> : null;\n })()}\n <Show when={item.dirty}>\n <span class=\"k2b-thumbnail-strip__dirty\" aria-hidden=\"true\" />\n </Show>\n </button>\n </li>\n );\n }}\n </For>\n <Show when={props.onAddItems}>\n {(add) => (\n <li>\n <IconButton class=\"k2b-thumbnail-strip__add\" size=\"sm\" tabindex=\"-1\" label={messages().thumbnailAdd} onClick={() => add()()}>\n <i class=\"ti ti-plus\" aria-hidden=\"true\" />\n </IconButton>\n </li>\n )}\n </Show>\n </ul>\n </nav>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { barPercent } from "../charts/core/bar-labels";
|
|
2
|
+
import { chartDatumSvg, computeDomain, escapeXml, extendDomainToNice, MAX_AXIS_TICKS, mapLog, mapRange, niceLogTicks, niceStep, referenceLineAttributes, svgRoot } from "../charts/core/svg-renderers";
|
|
3
|
+
import { chartMessages } from "./chart-message-catalog";
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* Bar chart options: stdlib's `charts.bar` options plus a title for the category axis and a separate value format.
|
|
@@ -38,7 +40,7 @@ export const chartTextWidth = (text, size = FONT_PX) => {
|
|
|
38
40
|
};
|
|
39
41
|
|
|
40
42
|
/** Split a label into at most `lines` lines of `maxPx`; the last line ends with an ellipsis when the label is longer. */
|
|
41
|
-
const wrapLabel = (label, maxPx, lines) => {
|
|
43
|
+
export const wrapLabel = (label, maxPx, lines) => {
|
|
42
44
|
const words = label.trim().split(/\s+/);
|
|
43
45
|
const result = [];
|
|
44
46
|
let current = "";
|
|
@@ -128,7 +130,7 @@ const finiteItems = data => data.flatMap((item, index) => Number.isFinite(item.v
|
|
|
128
130
|
item,
|
|
129
131
|
index
|
|
130
132
|
}] : []);
|
|
131
|
-
const headerHeight = opts => opts.title || opts.subtitle ? (opts.title ? 14 : 0) + (opts.subtitle ? 6 : 0) + 16 : 0;
|
|
133
|
+
export const headerHeight = opts => opts.title || opts.subtitle ? (opts.title ? 14 : 0) + (opts.subtitle ? 6 : 0) + 16 : 0;
|
|
132
134
|
const valueFormat = opts => opts.valueFormat ?? opts.yAxis?.format ?? (value => String(value));
|
|
133
135
|
const tickFormat = opts => opts.yAxis?.format ?? (value => String(value));
|
|
134
136
|
|
|
@@ -146,7 +148,22 @@ const columnsFit = (opts, finite, width) => {
|
|
|
146
148
|
|
|
147
149
|
/** The renderer's plan for a chart: its layout and logical height at `width`, derived from the data alone. */
|
|
148
150
|
const barChartPlan = (opts, width = 480) => {
|
|
149
|
-
const finite = finiteItems(opts.data);
|
|
151
|
+
const finite = finiteItems(opts.data ?? []);
|
|
152
|
+
if (opts.layout === "rows" && !opts.series) return {
|
|
153
|
+
layout: "rows",
|
|
154
|
+
height: rankedBarLayout(opts, {
|
|
155
|
+
width,
|
|
156
|
+
height: 280
|
|
157
|
+
}).height,
|
|
158
|
+
finite,
|
|
159
|
+
header: headerHeight(opts)
|
|
160
|
+
};
|
|
161
|
+
if (opts.series) return {
|
|
162
|
+
layout: "columns",
|
|
163
|
+
height: 280,
|
|
164
|
+
finite,
|
|
165
|
+
header: headerHeight(opts)
|
|
166
|
+
};
|
|
150
167
|
const header = headerHeight(opts);
|
|
151
168
|
if (!finite.length) return {
|
|
152
169
|
layout: "columns",
|
|
@@ -154,7 +171,7 @@ const barChartPlan = (opts, width = 480) => {
|
|
|
154
171
|
finite,
|
|
155
172
|
header
|
|
156
173
|
};
|
|
157
|
-
if (opts.xAxis?.ordered || columnsFit(opts, finite, width)) return {
|
|
174
|
+
if (opts.layout === "columns" || opts.layout !== "rows" && (opts.xAxis?.ordered || columnsFit(opts, finite, width))) return {
|
|
158
175
|
layout: "columns",
|
|
159
176
|
height: 280,
|
|
160
177
|
finite,
|
|
@@ -296,7 +313,7 @@ const colorIndex = (item, fallback) => {
|
|
|
296
313
|
if (!Number.isInteger(index) || index < 0) throw new RangeError("Chart colorIndex must be a nonnegative integer");
|
|
297
314
|
return index % 8;
|
|
298
315
|
};
|
|
299
|
-
const renderHeader = (opts, width) => {
|
|
316
|
+
export const renderHeader = (opts, width) => {
|
|
300
317
|
const parts = [];
|
|
301
318
|
let y = 16;
|
|
302
319
|
if (opts.title) {
|
|
@@ -350,22 +367,15 @@ const renderColumns = (opts, plan, width, height, inspect) => {
|
|
|
350
367
|
const labelY = g.y1;
|
|
351
368
|
// Unordered columns fit every label (see columnsFit); ordered ones label every n-th column that leaves room, from
|
|
352
369
|
// the first column whose label stays inside the drawing.
|
|
353
|
-
const
|
|
370
|
+
const visibleLabels = visibleCategoryLabels(finite.map(({
|
|
354
371
|
item
|
|
355
|
-
}) =>
|
|
356
|
-
const labelStep = Math.max(1, Math.ceil(labelPx / (slot / units)));
|
|
357
|
-
const inside = position => {
|
|
358
|
-
const half = chartTextWidth(finite[position].item.label) / 2 * units;
|
|
359
|
-
const center = g.x0 + slot * (position + 0.5);
|
|
360
|
-
return center - half >= 0 && center + half <= width;
|
|
361
|
-
};
|
|
362
|
-
const firstLabel = Math.max(0, finite.findIndex((_, position) => inside(position)));
|
|
372
|
+
}) => item.label), g.x0, slot, width, units);
|
|
363
373
|
finite.forEach(({
|
|
364
374
|
item,
|
|
365
375
|
index
|
|
366
376
|
}, position) => {
|
|
367
377
|
const center = g.x0 + slot * (position + 0.5);
|
|
368
|
-
if (
|
|
378
|
+
if (visibleLabels.has(position)) parts.push(`<text class="stdlib-chart-tick-label stdlib-chart-category-label" x="${fmt(center)}" y="${fmt(labelY)}" dy="16" text-anchor="middle">${escapeXml(item.label)}</text>`);
|
|
369
379
|
if (g.scale.log && item.value <= 0) return;
|
|
370
380
|
const valueY = y(item.value);
|
|
371
381
|
const top = Math.min(valueY, baseline);
|
|
@@ -459,6 +469,8 @@ const renderRows = (opts, plan, width, inspect) => {
|
|
|
459
469
|
* drawing instead of dropping labels: use {@link barChartLayout} for its logical height.
|
|
460
470
|
*/
|
|
461
471
|
export const renderBarChartSvg = opts => {
|
|
472
|
+
if (opts.series) return renderSeriesBars(opts);
|
|
473
|
+
if (opts.layout === "rows") return renderRankedBars(opts);
|
|
462
474
|
const plan = barChartPlan(opts, opts.width);
|
|
463
475
|
// The empty drawing of stdlib's bar chart, written here so bundles leave out stdlib's whole bar renderer.
|
|
464
476
|
if (!plan.finite.length) return svgRoot({
|
|
@@ -473,4 +485,320 @@ export const renderBarChartSvg = opts => {
|
|
|
473
485
|
className: opts.className
|
|
474
486
|
}, body).replace("<svg ", `<svg data-bar-layout="${plan.layout}" `);
|
|
475
487
|
};
|
|
488
|
+
|
|
489
|
+
/** Stable wrapping legend slots reserve the widest total or category value before interaction. */
|
|
490
|
+
export function barSeriesLegend(entries, format, width = 480, displayWidth = 296, maxHeight = Infinity) {
|
|
491
|
+
const unit = width / displayWidth;
|
|
492
|
+
let x = 0,
|
|
493
|
+
row = 0;
|
|
494
|
+
const items = entries.map(entry => {
|
|
495
|
+
const finite = entry.data.filter(v => v !== null && Number.isFinite(v));
|
|
496
|
+
const total = finite.length ? finite.reduce((sum, v) => sum + v, 0) : null;
|
|
497
|
+
const valueWidth = Math.max(chartTextWidth(total === null ? "–" : format(total)), ...entry.data.filter(v => v !== null && Number.isFinite(v)).map(v => chartTextWidth(format(v))));
|
|
498
|
+
const labelWidth = Math.max(8, Math.min(96, displayWidth - valueWidth - 32, chartTextWidth(entry.label)));
|
|
499
|
+
const slot = Math.min(width, (14 + labelWidth + 6 + valueWidth + 16) * unit);
|
|
500
|
+
if (x && x + slot > width) {
|
|
501
|
+
x = 0;
|
|
502
|
+
row++;
|
|
503
|
+
}
|
|
504
|
+
const item = {
|
|
505
|
+
...entry,
|
|
506
|
+
total,
|
|
507
|
+
x,
|
|
508
|
+
y: row * 20 + 12,
|
|
509
|
+
labelWidth,
|
|
510
|
+
valueX: x + slot - 16 * unit
|
|
511
|
+
};
|
|
512
|
+
x += slot;
|
|
513
|
+
return item;
|
|
514
|
+
});
|
|
515
|
+
const rows = Math.max(1, Math.floor(maxHeight / 20));
|
|
516
|
+
const overflow = row + 1 > rows;
|
|
517
|
+
const visible = overflow ? items.filter(item => item.y <= (rows - 1) * 20) : items;
|
|
518
|
+
return {
|
|
519
|
+
items: visible,
|
|
520
|
+
hidden: items.length - visible.length,
|
|
521
|
+
height: entries.length ? Math.min(row + 1, rows) * 20 : 0
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/** Category geometry shared by SVG, server snapshots and browser inspection. */
|
|
526
|
+
export function seriesBarLayout(opts, size = {
|
|
527
|
+
width: 480,
|
|
528
|
+
height: 280
|
|
529
|
+
}) {
|
|
530
|
+
const categories = opts.x ?? [];
|
|
531
|
+
const series = opts.series ?? [];
|
|
532
|
+
if (series.some(s => s.data.length !== categories.length) || opts.compare && opts.compare.data.length !== categories.length) throw new RangeError("Bar series must have the same length as x");
|
|
533
|
+
if (opts.compare && series.length !== 1) throw new RangeError("Bar comparison needs exactly one current series");
|
|
534
|
+
if (opts.normalize && opts.layout !== "stacked") throw new RangeError("Normalized bars must be stacked");
|
|
535
|
+
if (opts.layout === "stacked" && opts.yAxis?.scale === "log") throw new RangeError("Stacked bars need a linear axis");
|
|
536
|
+
if (opts.layout === "stacked" && series.some(s => s.data.some(v => v !== null && v < 0))) throw new RangeError("Stacked bars require nonnegative values");
|
|
537
|
+
const totals = categories.map((_, i) => series.some(s => Number.isFinite(s.data[i])) ? series.reduce((sum, s) => sum + (Number.isFinite(s.data[i]) ? s.data[i] : 0), 0) : null);
|
|
538
|
+
const values = opts.layout === "stacked" ? totals.filter(v => v !== null) : series.flatMap(s => s.data.filter(v => v !== null));
|
|
539
|
+
const scale = valueScale(opts.normalize ? [0, 1] : [...values, ...(opts.compare?.data.filter(v => v !== null) ?? [])], opts.yAxis, true);
|
|
540
|
+
const format = valueFormat(opts);
|
|
541
|
+
const units = size.width / narrow(opts);
|
|
542
|
+
const legend = opts.legend !== false;
|
|
543
|
+
// Keep the legend within one quarter of the frame, leaving room for the plot.
|
|
544
|
+
const entries = [...series, ...(opts.compare ? [opts.compare] : [])];
|
|
545
|
+
const legendLayout = barSeriesLegend(entries, format, size.width, narrow(opts), size.height * 0.25);
|
|
546
|
+
const top = headerHeight(opts) + 8 + (legend ? legendLayout.height : 0) + (opts.yAxis?.label ? 16 : 0);
|
|
547
|
+
const left = Math.max(40, ...scale.ticks.map(v => (chartTextWidth(opts.normalize ? `${Math.round(v * 100)}%` : tickFormat(opts)(v)) + 8) * units));
|
|
548
|
+
const right = size.width - 4;
|
|
549
|
+
const bottom = size.height - 24 - (opts.xAxis?.label ? 18 : 0);
|
|
550
|
+
const slot = (right - left) / Math.max(1, categories.length);
|
|
551
|
+
const y = value => project(scale, value, [bottom, top]);
|
|
552
|
+
const columns = categories.map((label, index) => {
|
|
553
|
+
const center = left + slot * (index + 0.5);
|
|
554
|
+
let acc = 0;
|
|
555
|
+
const current = series.map((s, seriesIndex) => {
|
|
556
|
+
const raw = s.data[index];
|
|
557
|
+
const value = raw === null || !Number.isFinite(raw) || opts.normalize && totals[index] === 0 ? null : opts.normalize ? raw / totals[index] : raw;
|
|
558
|
+
const base = opts.layout === "stacked" ? acc : 0;
|
|
559
|
+
if (value !== null && opts.layout === "stacked") acc += value;
|
|
560
|
+
return {
|
|
561
|
+
seriesIndex,
|
|
562
|
+
raw,
|
|
563
|
+
value,
|
|
564
|
+
base
|
|
565
|
+
};
|
|
566
|
+
});
|
|
567
|
+
return {
|
|
568
|
+
label,
|
|
569
|
+
index,
|
|
570
|
+
center,
|
|
571
|
+
current,
|
|
572
|
+
total: totals[index],
|
|
573
|
+
previous: opts.compare?.data[index]
|
|
574
|
+
};
|
|
575
|
+
});
|
|
576
|
+
const barWidthPx = (opts.compare ? Math.min(slot * 0.32, 26) : Math.min(slot * (opts.layout === "stacked" ? 0.56 : 0.8 / Math.max(1, entries.length)), opts.layout === "stacked" ? 40 : 22)) / units;
|
|
577
|
+
return {
|
|
578
|
+
...size,
|
|
579
|
+
columns,
|
|
580
|
+
totals,
|
|
581
|
+
scale,
|
|
582
|
+
left,
|
|
583
|
+
right,
|
|
584
|
+
top,
|
|
585
|
+
bottom,
|
|
586
|
+
slot,
|
|
587
|
+
y,
|
|
588
|
+
format,
|
|
589
|
+
units,
|
|
590
|
+
entries,
|
|
591
|
+
legend,
|
|
592
|
+
legendLayout,
|
|
593
|
+
barWidthPx
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
const renderSeriesBars = opts => {
|
|
597
|
+
const g = seriesBarLayout(opts, opts);
|
|
598
|
+
const parts = [renderHeader(opts, opts.width)];
|
|
599
|
+
const labels = chartMessages.resolve([opts.locale ?? "en"]).t;
|
|
600
|
+
const change = new Intl.NumberFormat(opts.locale ?? "en", {
|
|
601
|
+
style: "percent",
|
|
602
|
+
maximumFractionDigits: 1,
|
|
603
|
+
signDisplay: "exceptZero"
|
|
604
|
+
});
|
|
605
|
+
const text = (x, y, value, cls = "stdlib-chart-tick-label", anchor = "start", extra = "") => `<text class="${cls}" x="${fmt(x)}" y="${fmt(y)}" text-anchor="${anchor}" ${extra}>${escapeXml(value)}</text>`;
|
|
606
|
+
if (g.legend) g.legendLayout.items.forEach((entry, i) => {
|
|
607
|
+
const y = headerHeight(opts) + entry.y;
|
|
608
|
+
const x = entry.x;
|
|
609
|
+
parts.push(`<rect class="stdlib-chart-series-${i < (opts.series?.length ?? 0) ? i % 8 : 0}" x="${x}" y="${y - 8}" width="${8 * g.units}" height="8" ${i >= (opts.series?.length ?? 0) ? 'style="fill:none;stroke:var(--stdlib-chart-c1);"' : ""}/>`);
|
|
610
|
+
if (i >= (opts.series?.length ?? 0)) parts.push(`<path d="M ${x} ${y - 4} l ${4 * g.units} -4 M ${x + 2 * g.units} ${y} l ${6 * g.units} -6 M ${x + 6 * g.units} ${y} l ${2 * g.units} -2" fill="none" stroke="var(--stdlib-chart-c1,#3b82f6)" stroke-width="1"/>`);
|
|
611
|
+
const label = wrapLabel(entry.label, Math.max(8, entry.labelWidth), 1).lines[0] ?? entry.label;
|
|
612
|
+
const value = escapeXml(entry.total === null ? "–" : g.format(entry.total));
|
|
613
|
+
// One text run keeps the value six CSS pixels after its label even when the SVG stretches.
|
|
614
|
+
parts.push(`<text x="${fmt(x + 14 * g.units)}" y="${fmt(y)}"><tspan class="stdlib-chart-tick-label">${escapeXml(label)}</tspan><tspan class="stdlib-chart-bar-value" dx="6" data-chart-legend-value data-field="${i < (opts.series?.length ?? 0) ? `series:${i}` : "previous"}" data-default="${value}">${value}</tspan></text>`);
|
|
615
|
+
});
|
|
616
|
+
if (g.legend && g.legendLayout.hidden) parts.push(text(0, headerHeight(opts) + g.legendLayout.height - 8, `+${g.legendLayout.hidden}`, "stdlib-chart-tick-label"));
|
|
617
|
+
if (opts.yAxis?.label) parts.push(text(0, g.top - 6, opts.yAxis.label, "stdlib-chart-axis-label"));
|
|
618
|
+
for (const tick of g.scale.ticks) {
|
|
619
|
+
parts.push(`<line class="stdlib-chart-grid" x1="${g.left}" x2="${g.right}" y1="${g.y(tick)}" y2="${g.y(tick)}"/>`);
|
|
620
|
+
parts.push(text(g.left - 6 * g.units, g.y(tick) + 4, opts.normalize ? `${Math.round(tick * 100)}%` : tickFormat(opts)(tick), undefined, "end"));
|
|
621
|
+
}
|
|
622
|
+
parts.push(`<line class="stdlib-chart-axis" x1="${g.left}" x2="${g.right}" y1="${g.bottom}" y2="${g.bottom}"/>`);
|
|
623
|
+
const visibleLabels = visibleCategoryLabels(g.columns.map(c => c.label), g.left, g.slot, opts.width, g.units);
|
|
624
|
+
for (const column of g.columns) {
|
|
625
|
+
const fields = column.current.map((v, i) => ({
|
|
626
|
+
key: `series:${i}`,
|
|
627
|
+
value: v.raw === null || !Number.isFinite(v.raw) ? "–" : v.raw,
|
|
628
|
+
formatted: v.raw === null || !Number.isFinite(v.raw) ? "–" : g.format(v.raw)
|
|
629
|
+
}));
|
|
630
|
+
if (opts.compare) {
|
|
631
|
+
const previous = column.previous;
|
|
632
|
+
fields.push({
|
|
633
|
+
key: "previous",
|
|
634
|
+
value: previous ?? "–",
|
|
635
|
+
formatted: previous === null || !Number.isFinite(previous) ? "–" : g.format(previous)
|
|
636
|
+
});
|
|
637
|
+
const current = column.current[0]?.raw;
|
|
638
|
+
const delta = current == null || previous == null || !Number.isFinite(current) || !Number.isFinite(previous) ? null : current - previous;
|
|
639
|
+
fields.push({
|
|
640
|
+
key: "delta",
|
|
641
|
+
value: delta ?? "–",
|
|
642
|
+
formatted: delta === null || previous === 0 ? "–" : change.format(delta / Math.abs(previous))
|
|
643
|
+
});
|
|
644
|
+
} else if (opts.layout === "stacked") {
|
|
645
|
+
fields.reverse();
|
|
646
|
+
fields.push({
|
|
647
|
+
key: "total",
|
|
648
|
+
value: column.total ?? "–",
|
|
649
|
+
formatted: column.total === null ? "–" : g.format(column.total)
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
let marks = `<rect class="k2b-chart-category-band" fill="none" pointer-events="all" x="${column.center - g.slot / 2}" y="${g.top}" width="${g.slot}" height="${Math.max(0, g.bottom - g.top)}" rx="6"/>`;
|
|
653
|
+
const bar = (value, base, x, width, color, previous = false) => {
|
|
654
|
+
const y0 = g.y(g.scale.log ? g.scale.domain[0] : base),
|
|
655
|
+
y1 = g.y(base + value);
|
|
656
|
+
const rect = `<rect class="stdlib-chart-bar stdlib-chart-series-${color % 8}" x="${fmt(x)}" y="${fmt(Math.min(y0, y1))}" width="${fmt(Math.max(0, width))}" height="${fmt(Math.abs(y0 - y1))}" rx="3"/>`;
|
|
657
|
+
if (!previous) return rect;
|
|
658
|
+
// Inline strokes avoid document-global SVG pattern IDs, including duplicate charts during SSR.
|
|
659
|
+
const lines = [];
|
|
660
|
+
for (let d = -Math.abs(y0 - y1); d < width; d += 6) {
|
|
661
|
+
const lo = Math.max(0, -d),
|
|
662
|
+
hi = Math.min(Math.abs(y0 - y1), width - d);
|
|
663
|
+
if (hi > lo) lines.push(`<line x1="${x + d + lo}" y1="${Math.max(y0, y1) - lo}" x2="${x + d + hi}" y2="${Math.max(y0, y1) - hi}" stroke="var(--stdlib-chart-c1,#3b82f6)" stroke-width="1.5"/>`);
|
|
664
|
+
}
|
|
665
|
+
return `<g class="k2b-chart-previous">${rect.replace("/>", ' style="fill:var(--stdlib-chart-c1,#3b82f6);fill-opacity:.14" stroke="var(--stdlib-chart-c1,#3b82f6)" stroke-width="1"/>')}${lines.join("")}</g>`;
|
|
666
|
+
};
|
|
667
|
+
if (opts.compare) {
|
|
668
|
+
const bw = Math.min(g.slot * 0.32, 26);
|
|
669
|
+
const gap = Math.min(1.5, g.slot * 0.08);
|
|
670
|
+
if (column.previous !== null && Number.isFinite(column.previous) && (!g.scale.log || column.previous > 0)) marks += bar(column.previous, 0, column.center - bw - gap, bw, 0, true);
|
|
671
|
+
const value = column.current[0]?.value;
|
|
672
|
+
if (value != null && (!g.scale.log || value > 0)) marks += bar(value, 0, column.center + gap, bw, 0);
|
|
673
|
+
} else column.current.forEach(v => {
|
|
674
|
+
if (v.value === null || g.scale.log && v.value <= 0) return;
|
|
675
|
+
const stacked = opts.layout === "stacked";
|
|
676
|
+
const bw = stacked ? Math.min(g.slot * 0.56, 40) : Math.min(g.slot * 0.8 / g.entries.length, 22);
|
|
677
|
+
const gap = bw / g.units > 4 ? 2 : 0;
|
|
678
|
+
const x = stacked ? column.center - bw / 2 : column.center - g.entries.length * bw / 2 + v.seriesIndex * bw + gap / 2;
|
|
679
|
+
const segment = bar(v.value, v.base, x, stacked ? bw : bw - gap, v.seriesIndex);
|
|
680
|
+
if (stacked && v.value > 0 && column.current.some(next => next.seriesIndex > v.seriesIndex && next.value !== null && next.value > 0)) {
|
|
681
|
+
const fullHeight = Math.abs(g.y(v.base) - g.y(v.base + v.value));
|
|
682
|
+
const gap = Math.min(1.5, fullHeight / 2);
|
|
683
|
+
marks += segment.replace(/y="[^"]*"/, `y="${g.y(v.base + v.value) + gap}"`).replace(/height="[^"]*"/, `height="${fullHeight - gap}"`);
|
|
684
|
+
} else marks += segment;
|
|
685
|
+
});
|
|
686
|
+
parts.push(chartDatumSvg(marks, {
|
|
687
|
+
role: "item",
|
|
688
|
+
index: column.index,
|
|
689
|
+
label: column.label,
|
|
690
|
+
anchor: [column.center, g.top],
|
|
691
|
+
values: fields
|
|
692
|
+
}, opts.inspect ?? false, [column.label, ...fields.map(field => `${field.key.startsWith("series:") ? opts.series[Number(field.key.slice(7))].label : field.key === "previous" ? opts.compare.label : field.key === "delta" ? labels.chartFields({
|
|
693
|
+
key: "delta"
|
|
694
|
+
}) : labels.chartFields({
|
|
695
|
+
key: "total"
|
|
696
|
+
})}: ${field.formatted}`)].join(" · ")));
|
|
697
|
+
if (visibleLabels.has(column.index)) parts.push(text(column.center, g.bottom, column.label, "stdlib-chart-tick-label stdlib-chart-category-label", "middle", 'dy="16"'));
|
|
698
|
+
}
|
|
699
|
+
for (const ref of opts.references ?? []) if ((ref.axis ?? "y") === "y" && Number.isFinite(ref.value) && ref.value >= g.scale.domain[0] && ref.value <= g.scale.domain[1]) {
|
|
700
|
+
parts.push(`<line class="stdlib-chart-reference" x1="${g.left}" x2="${g.right}" y1="${g.y(ref.value)}" y2="${g.y(ref.value)}"/>`);
|
|
701
|
+
if (ref.label) parts.push(text(g.right, g.y(ref.value) - 4, ref.label, "stdlib-chart-reference-label", "end"));
|
|
702
|
+
}
|
|
703
|
+
if (opts.xAxis?.label) parts.push(text((g.left + g.right) / 2, opts.height - 2, opts.xAxis.label, "stdlib-chart-axis-label", "middle"));
|
|
704
|
+
return svgRoot(opts, parts.join("")).replace("<svg ", '<svg data-bar-layout="columns" ');
|
|
705
|
+
};
|
|
706
|
+
const visibleCategoryLabels = (labels, left, slot, width, units) => {
|
|
707
|
+
const labelPx = Math.max(0, ...labels.map(label => chartTextWidth(label))) + GAP_PX;
|
|
708
|
+
const step = Math.max(1, Math.ceil(labelPx / (slot / units)));
|
|
709
|
+
const inside = i => {
|
|
710
|
+
const half = chartTextWidth(labels[i]) * units / 2,
|
|
711
|
+
center = left + slot * (i + 0.5);
|
|
712
|
+
return center - half >= 0 && center + half <= width;
|
|
713
|
+
};
|
|
714
|
+
const first = Math.max(0, labels.findIndex((_, i) => inside(i)));
|
|
715
|
+
return new Set(labels.flatMap((_, i) => i >= first && (i - first) % step === 0 && inside(i) ? [i] : []));
|
|
716
|
+
};
|
|
717
|
+
|
|
718
|
+
/** Ranked rows retain original indices. A limit changes the drawing, never the denominator or source data. */
|
|
719
|
+
export function rankedBarLayout(opts, size = {
|
|
720
|
+
width: 480,
|
|
721
|
+
height: 280
|
|
722
|
+
}) {
|
|
723
|
+
if (opts.limit !== undefined && (!Number.isInteger(opts.limit) || opts.limit < 1)) throw new RangeError("Bar list limit must be a positive integer");
|
|
724
|
+
if (opts.data?.some(d => Number.isFinite(d.value) && d.value < 0)) throw new RangeError("Ranked bar lists require nonnegative values");
|
|
725
|
+
const sorted = (opts.data ?? []).map((item, index) => ({
|
|
726
|
+
...item,
|
|
727
|
+
index
|
|
728
|
+
})).sort((a, b) => (Number.isFinite(b.value) ? b.value : -Infinity) - (Number.isFinite(a.value) ? a.value : -Infinity));
|
|
729
|
+
const total = sorted.reduce((sum, d) => sum + (Number.isFinite(d.value) ? d.value : 0), 0);
|
|
730
|
+
const shown = sorted.slice(0, opts.limit),
|
|
731
|
+
rest = sorted.slice(shown.length);
|
|
732
|
+
const top = headerHeight(opts),
|
|
733
|
+
unit = size.width / narrow(opts),
|
|
734
|
+
format = opts.valueFormat ?? opts.yAxis?.format ?? (v => new Intl.NumberFormat(opts.locale ?? "en").format(v)),
|
|
735
|
+
percent = barPercent(opts.locale);
|
|
736
|
+
const shareWidth = opts.share ? 48 * unit : 0;
|
|
737
|
+
const valueWidth = Math.max(20, ...shown.map(d => chartTextWidth(Number.isFinite(d.value) ? format(d.value) : "–"))) * unit;
|
|
738
|
+
const labelWidth = Math.max(8, (size.width - shareWidth - valueWidth - 36 * unit) / unit);
|
|
739
|
+
const max = Math.max(0, ...sorted.map(d => Number.isFinite(d.value) ? d.value : 0));
|
|
740
|
+
const rows = shown.map((d, rank) => ({
|
|
741
|
+
...d,
|
|
742
|
+
rank: rank + 1,
|
|
743
|
+
y: top + rank * 36,
|
|
744
|
+
width: Number.isFinite(d.value) && max > 0 ? d.value / max * size.width : 0,
|
|
745
|
+
share: Number.isFinite(d.value) && total > 0 ? d.value / total : null
|
|
746
|
+
}));
|
|
747
|
+
return {
|
|
748
|
+
...size,
|
|
749
|
+
height: Math.max(size.height, top + rows.length * 36 + (rest.length ? 24 : 0)),
|
|
750
|
+
rows,
|
|
751
|
+
total,
|
|
752
|
+
rest,
|
|
753
|
+
restValue: rest.some(d => Number.isFinite(d.value)) ? rest.reduce((sum, d) => sum + (Number.isFinite(d.value) ? d.value : 0), 0) : null,
|
|
754
|
+
top,
|
|
755
|
+
unit,
|
|
756
|
+
format,
|
|
757
|
+
percent,
|
|
758
|
+
shareWidth,
|
|
759
|
+
labelWidth
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
const renderRankedBars = opts => {
|
|
763
|
+
const g = rankedBarLayout(opts, opts),
|
|
764
|
+
labels = chartMessages.resolve([opts.locale ?? "en"]).t;
|
|
765
|
+
const parts = [renderHeader(opts, opts.width)];
|
|
766
|
+
const color = opts.tone ? `var(--k2b-flow-${opts.tone}-mark,var(--stdlib-chart-c1,#3b82f6))` : "var(--stdlib-chart-c1,#3b82f6)";
|
|
767
|
+
const text = (x, y, value, anchor = "start", cls = "stdlib-chart-tick-label") => `<text class="${cls}" x="${x}" y="${y}" text-anchor="${anchor}">${escapeXml(value)}</text>`;
|
|
768
|
+
for (const row of g.rows) {
|
|
769
|
+
const value = Number.isFinite(row.value) ? row.value : null,
|
|
770
|
+
written = value === null ? "–" : g.format(value);
|
|
771
|
+
const share = row.share === null ? "–" : g.percent.format(row.share);
|
|
772
|
+
const label = wrapLabel(row.label, g.labelWidth * 11 / 13, 1).lines[0] ?? row.label;
|
|
773
|
+
const marks = `<rect class="k2b-chart-category-band" fill="none" pointer-events="all" x="0" y="${row.y}" width="${g.width}" height="32" rx="6"/><rect x="0" y="${row.y}" width="${row.width}" height="32" rx="6" style="fill:${color};fill-opacity:.16;pointer-events:none"/>${text(10 * g.unit, row.y + 20, label)}${text(g.width - 10 * g.unit - g.shareWidth, row.y + 20, written, "end", "stdlib-chart-bar-value")}${opts.share ? text(g.width - 10 * g.unit, row.y + 20, share, "end") : ""}`;
|
|
774
|
+
parts.push(chartDatumSvg(marks, {
|
|
775
|
+
role: "item",
|
|
776
|
+
index: row.index,
|
|
777
|
+
label: row.label,
|
|
778
|
+
anchor: [g.width / 2, row.y],
|
|
779
|
+
values: [{
|
|
780
|
+
key: "value",
|
|
781
|
+
value: value ?? "–",
|
|
782
|
+
formatted: written
|
|
783
|
+
}, {
|
|
784
|
+
key: "percent",
|
|
785
|
+
value: row.share === null ? "–" : row.share * 100,
|
|
786
|
+
formatted: share
|
|
787
|
+
}, {
|
|
788
|
+
key: "rank",
|
|
789
|
+
value: row.rank
|
|
790
|
+
}]
|
|
791
|
+
}, opts.inspect ?? false, `${row.label} · ${written} · ${share} · ${labels.chartFields({
|
|
792
|
+
key: "rank"
|
|
793
|
+
})}: ${row.rank}`));
|
|
794
|
+
}
|
|
795
|
+
if (g.rest.length) parts.push(text(10 * g.unit, g.top + g.rows.length * 36 + 16, `${labels.chartBarMore({
|
|
796
|
+
n: g.rest.length
|
|
797
|
+
})} · ${g.restValue === null ? "–" : g.format(g.restValue)}`));
|
|
798
|
+
return svgRoot({
|
|
799
|
+
...opts,
|
|
800
|
+
height: g.height,
|
|
801
|
+
className: [opts.className, "k2b-chart-ranked"].filter(Boolean).join(" ")
|
|
802
|
+
}, parts.join("")).replace("</style>", ".k2b-chart-ranked :is(.stdlib-chart-tick-label,.stdlib-chart-bar-value){font-size:13px}</style>").replace("<svg ", '<svg data-bar-layout="rows" ');
|
|
803
|
+
};
|
|
476
804
|
//# sourceMappingURL=chart-bar.js.map
|