@aceshooting/lyra-ui 1.2.0 → 2.0.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/README.md +11 -0
- package/custom-elements.json +23341 -11202
- package/dist/components/app-rail/app-rail.d.ts +171 -0
- package/dist/components/app-rail/app-rail.js +483 -0
- package/dist/components/app-rail/app-rail.styles.d.ts +1 -0
- package/dist/components/app-rail/app-rail.styles.js +125 -0
- package/dist/components/attachment-chip/attachment-chip.d.ts +114 -0
- package/dist/components/attachment-chip/attachment-chip.js +312 -0
- package/dist/components/attachment-chip/attachment-chip.styles.d.ts +1 -0
- package/dist/components/attachment-chip/attachment-chip.styles.js +184 -0
- package/dist/components/attachment-trigger/attachment-trigger.d.ts +83 -0
- package/dist/components/attachment-trigger/attachment-trigger.js +258 -0
- package/dist/components/attachment-trigger/attachment-trigger.styles.d.ts +1 -0
- package/dist/components/attachment-trigger/attachment-trigger.styles.js +68 -0
- package/dist/components/chart/box-plot.js +11 -1
- package/dist/components/chart/chart-loader.d.ts +44 -13
- package/dist/components/chart/chart-loader.js +65 -18
- package/dist/components/chart/chart.d.ts +1 -2
- package/dist/components/chart/chart.js +67 -12
- package/dist/components/chart/histogram-bin.d.ts +4 -1
- package/dist/components/chart/histogram-bin.js +24 -14
- package/dist/components/chart/lite-chart.d.ts +54 -0
- package/dist/components/chart/lite-chart.js +140 -22
- package/dist/components/chart/lite-chart.styles.js +9 -0
- package/dist/components/chat-composer/chat-composer.d.ts +92 -0
- package/dist/components/chat-composer/chat-composer.js +285 -0
- package/dist/components/chat-composer/chat-composer.styles.d.ts +1 -0
- package/dist/components/chat-composer/chat-composer.styles.js +135 -0
- package/dist/components/chat-message/chat-message.d.ts +113 -0
- package/dist/components/chat-message/chat-message.js +291 -0
- package/dist/components/chat-message/chat-message.styles.d.ts +1 -0
- package/dist/components/chat-message/chat-message.styles.js +203 -0
- package/dist/components/checkbox/checkbox.d.ts +59 -0
- package/dist/components/checkbox/checkbox.js +230 -0
- package/dist/components/checkbox/checkbox.styles.d.ts +1 -0
- package/dist/components/checkbox/checkbox.styles.js +70 -0
- package/dist/components/chip/chip-group.d.ts +56 -0
- package/dist/components/chip/chip-group.js +124 -0
- package/dist/components/chip/chip-group.styles.d.ts +1 -0
- package/dist/components/chip/chip-group.styles.js +57 -0
- package/dist/components/chip/chip.d.ts +64 -0
- package/dist/components/chip/chip.js +115 -0
- package/dist/components/chip/chip.styles.d.ts +1 -0
- package/dist/components/chip/chip.styles.js +115 -0
- package/dist/components/citation-badge/citation-badge.d.ts +113 -0
- package/dist/components/citation-badge/citation-badge.js +300 -0
- package/dist/components/citation-badge/citation-badge.styles.d.ts +1 -0
- package/dist/components/citation-badge/citation-badge.styles.js +96 -0
- package/dist/components/code-block/code-block.d.ts +89 -0
- package/dist/components/code-block/code-block.js +317 -0
- package/dist/components/code-block/code-block.styles.d.ts +1 -0
- package/dist/components/code-block/code-block.styles.js +187 -0
- package/dist/components/code-block/code-loader.d.ts +44 -0
- package/dist/components/code-block/code-loader.js +79 -0
- package/dist/components/combobox/combobox.d.ts +19 -1
- package/dist/components/combobox/combobox.js +84 -14
- package/dist/components/combobox/option.d.ts +5 -1
- package/dist/components/combobox/option.js +35 -0
- package/dist/components/context-meter/context-meter.d.ts +53 -0
- package/dist/components/context-meter/context-meter.js +150 -0
- package/dist/components/context-meter/context-meter.styles.d.ts +1 -0
- package/dist/components/context-meter/context-meter.styles.js +120 -0
- package/dist/components/conversation-item/conversation-item.d.ts +128 -0
- package/dist/components/conversation-item/conversation-item.js +322 -0
- package/dist/components/conversation-item/conversation-item.styles.d.ts +1 -0
- package/dist/components/conversation-item/conversation-item.styles.js +155 -0
- package/dist/components/date-picker/date-input.d.ts +24 -0
- package/dist/components/date-picker/date-input.js +134 -22
- package/dist/components/date-picker/date-picker.d.ts +7 -0
- package/dist/components/date-picker/date-picker.js +85 -16
- package/dist/components/dialog/confirm.d.ts +40 -0
- package/dist/components/dialog/confirm.js +79 -0
- package/dist/components/dialog/dialog.d.ts +85 -0
- package/dist/components/dialog/dialog.js +272 -0
- package/dist/components/dialog/dialog.styles.d.ts +1 -0
- package/dist/components/dialog/dialog.styles.js +52 -0
- package/dist/components/dock-panel/dock-panel.d.ts +134 -0
- package/dist/components/dock-panel/dock-panel.js +345 -0
- package/dist/components/dock-panel/dock-panel.styles.d.ts +1 -0
- package/dist/components/dock-panel/dock-panel.styles.js +145 -0
- package/dist/components/document-preview/document-preview.d.ts +135 -0
- package/dist/components/document-preview/document-preview.js +372 -0
- package/dist/components/document-preview/document-preview.styles.d.ts +1 -0
- package/dist/components/document-preview/document-preview.styles.js +191 -0
- package/dist/components/export-button/csv.js +1 -1
- package/dist/components/export-button/export-button.js +2 -0
- package/dist/components/flag/flag.d.ts +29 -13
- package/dist/components/flag/flag.js +39 -13
- package/dist/components/gauge/gauge.js +19 -10
- package/dist/components/generation-status/generation-status.d.ts +109 -0
- package/dist/components/generation-status/generation-status.js +273 -0
- package/dist/components/generation-status/generation-status.styles.d.ts +1 -0
- package/dist/components/generation-status/generation-status.styles.js +84 -0
- package/dist/components/heatmap/calendar-grid.d.ts +4 -1
- package/dist/components/heatmap/calendar-grid.js +25 -12
- package/dist/components/heatmap/heatmap-scale.d.ts +6 -0
- package/dist/components/heatmap/heatmap-scale.js +7 -1
- package/dist/components/heatmap/heatmap.d.ts +74 -0
- package/dist/components/heatmap/heatmap.js +135 -23
- package/dist/components/json-viewer/json-viewer.d.ts +53 -0
- package/dist/components/json-viewer/json-viewer.js +283 -0
- package/dist/components/json-viewer/json-viewer.styles.d.ts +1 -0
- package/dist/components/json-viewer/json-viewer.styles.js +176 -0
- package/dist/components/kbd/kbd.d.ts +77 -0
- package/dist/components/kbd/kbd.js +214 -0
- package/dist/components/kbd/kbd.styles.d.ts +1 -0
- package/dist/components/kbd/kbd.styles.js +52 -0
- package/dist/components/live-region/live-region.d.ts +81 -0
- package/dist/components/live-region/live-region.js +153 -0
- package/dist/components/live-region/live-region.styles.d.ts +1 -0
- package/dist/components/live-region/live-region.styles.js +10 -0
- package/dist/components/map/map.d.ts +8 -6
- package/dist/components/map/map.js +44 -8
- package/dist/components/markdown/markdown-loader.d.ts +34 -0
- package/dist/components/markdown/markdown-loader.js +43 -0
- package/dist/components/markdown/markdown.d.ts +81 -0
- package/dist/components/markdown/markdown.js +284 -0
- package/dist/components/markdown/markdown.styles.d.ts +1 -0
- package/dist/components/markdown/markdown.styles.js +82 -0
- package/dist/components/media-card/media-card.d.ts +122 -0
- package/dist/components/media-card/media-card.js +295 -0
- package/dist/components/media-card/media-card.styles.d.ts +1 -0
- package/dist/components/media-card/media-card.styles.js +132 -0
- package/dist/components/mention-popover/mention-popover.d.ts +200 -0
- package/dist/components/mention-popover/mention-popover.js +475 -0
- package/dist/components/mention-popover/mention-popover.styles.d.ts +1 -0
- package/dist/components/mention-popover/mention-popover.styles.js +101 -0
- package/dist/components/menu/menu-item.d.ts +62 -0
- package/dist/components/menu/menu-item.js +119 -0
- package/dist/components/menu/menu-item.styles.d.ts +1 -0
- package/dist/components/menu/menu-item.styles.js +67 -0
- package/dist/components/menu/menu.d.ts +143 -0
- package/dist/components/menu/menu.js +365 -0
- package/dist/components/menu/menu.styles.d.ts +1 -0
- package/dist/components/menu/menu.styles.js +66 -0
- package/dist/components/model-select/model-select.d.ts +125 -0
- package/dist/components/model-select/model-select.js +490 -0
- package/dist/components/model-select/model-select.styles.d.ts +1 -0
- package/dist/components/model-select/model-select.styles.js +189 -0
- package/dist/components/model-settings-panel/model-settings-panel.d.ts +69 -0
- package/dist/components/model-settings-panel/model-settings-panel.js +145 -0
- package/dist/components/model-settings-panel/model-settings-panel.styles.d.ts +1 -0
- package/dist/components/model-settings-panel/model-settings-panel.styles.js +82 -0
- package/dist/components/playback/playback.d.ts +13 -1
- package/dist/components/playback/playback.js +47 -14
- package/dist/components/responsive-panel/responsive-panel.d.ts +150 -0
- package/dist/components/responsive-panel/responsive-panel.js +365 -0
- package/dist/components/responsive-panel/responsive-panel.styles.d.ts +1 -0
- package/dist/components/responsive-panel/responsive-panel.styles.js +103 -0
- package/dist/components/result-card/result-card.d.ts +44 -0
- package/dist/components/result-card/result-card.js +83 -0
- package/dist/components/result-card/result-card.styles.d.ts +1 -0
- package/dist/components/result-card/result-card.styles.js +50 -0
- package/dist/components/result-card/result-field.d.ts +36 -0
- package/dist/components/result-card/result-field.js +87 -0
- package/dist/components/result-card/result-field.styles.d.ts +1 -0
- package/dist/components/result-card/result-field.styles.js +32 -0
- package/dist/components/select/select.d.ts +43 -2
- package/dist/components/select/select.js +150 -17
- package/dist/components/slider/slider.d.ts +89 -0
- package/dist/components/slider/slider.js +352 -0
- package/dist/components/slider/slider.styles.d.ts +1 -0
- package/dist/components/slider/slider.styles.js +87 -0
- package/dist/components/source-card/source-card.d.ts +92 -0
- package/dist/components/source-card/source-card.js +148 -0
- package/dist/components/source-card/source-card.styles.d.ts +1 -0
- package/dist/components/source-card/source-card.styles.js +69 -0
- package/dist/components/source-list/source-list.d.ts +63 -0
- package/dist/components/source-list/source-list.js +122 -0
- package/dist/components/source-list/source-list.styles.d.ts +1 -0
- package/dist/components/source-list/source-list.styles.js +59 -0
- package/dist/components/sparkline/sparkline.js +27 -13
- package/dist/components/split/split.d.ts +93 -1
- package/dist/components/split/split.js +284 -15
- package/dist/components/split/split.styles.js +30 -0
- package/dist/components/stat/stat.d.ts +6 -1
- package/dist/components/stat/stat.js +8 -2
- package/dist/components/stream-status/stream-status.d.ts +110 -0
- package/dist/components/stream-status/stream-status.js +210 -0
- package/dist/components/stream-status/stream-status.styles.d.ts +1 -0
- package/dist/components/stream-status/stream-status.styles.js +103 -0
- package/dist/components/streaming-text/streaming-text.d.ts +98 -0
- package/dist/components/streaming-text/streaming-text.js +209 -0
- package/dist/components/streaming-text/streaming-text.styles.d.ts +1 -0
- package/dist/components/streaming-text/streaming-text.styles.js +62 -0
- package/dist/components/switch/switch.d.ts +58 -0
- package/dist/components/switch/switch.js +179 -0
- package/dist/components/switch/switch.styles.d.ts +1 -0
- package/dist/components/switch/switch.styles.js +75 -0
- package/dist/components/table/table.d.ts +73 -4
- package/dist/components/table/table.js +169 -20
- package/dist/components/table/table.styles.js +6 -1
- package/dist/components/tabs/tabs.d.ts +51 -0
- package/dist/components/tabs/tabs.js +190 -0
- package/dist/components/tabs/tabs.styles.d.ts +1 -0
- package/dist/components/tabs/tabs.styles.js +63 -0
- package/dist/components/thinking-panel/thinking-panel.d.ts +121 -0
- package/dist/components/thinking-panel/thinking-panel.js +235 -0
- package/dist/components/thinking-panel/thinking-panel.styles.d.ts +1 -0
- package/dist/components/thinking-panel/thinking-panel.styles.js +117 -0
- package/dist/components/toast/toast-item.d.ts +1 -0
- package/dist/components/toast/toast-item.js +31 -6
- package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +130 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.js +403 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.d.ts +1 -0
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +160 -0
- package/dist/components/tool-call-chip/tool-call-chip.d.ts +89 -0
- package/dist/components/tool-call-chip/tool-call-chip.js +288 -0
- package/dist/components/tool-call-chip/tool-call-chip.styles.d.ts +1 -0
- package/dist/components/tool-call-chip/tool-call-chip.styles.js +203 -0
- package/dist/components/tool-param-form/tool-param-form.d.ts +145 -0
- package/dist/components/tool-param-form/tool-param-form.js +366 -0
- package/dist/components/tool-param-form/tool-param-form.styles.d.ts +1 -0
- package/dist/components/tool-param-form/tool-param-form.styles.js +75 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +102 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.js +393 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.d.ts +1 -0
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +176 -0
- package/dist/components/tool-result-view/registry.d.ts +81 -0
- package/dist/components/tool-result-view/registry.js +84 -0
- package/dist/components/tool-result-view/tool-result-view.d.ts +55 -0
- package/dist/components/tool-result-view/tool-result-view.js +138 -0
- package/dist/components/tool-result-view/tool-result-view.styles.d.ts +1 -0
- package/dist/components/tool-result-view/tool-result-view.styles.js +13 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +151 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.js +439 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.d.ts +1 -0
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +182 -0
- package/dist/components/tree/tree-node.d.ts +11 -2
- package/dist/components/tree/tree-node.js +16 -6
- package/dist/components/tree/tree.d.ts +8 -2
- package/dist/components/tree/tree.js +18 -11
- package/dist/components/typing-indicator/typing-indicator.d.ts +60 -0
- package/dist/components/typing-indicator/typing-indicator.js +96 -0
- package/dist/components/typing-indicator/typing-indicator.styles.d.ts +1 -0
- package/dist/components/typing-indicator/typing-indicator.styles.js +132 -0
- package/dist/components/virtual-list/virtual-list.d.ts +173 -0
- package/dist/components/virtual-list/virtual-list.js +461 -0
- package/dist/components/virtual-list/virtual-list.styles.d.ts +1 -0
- package/dist/components/virtual-list/virtual-list.styles.js +44 -0
- package/dist/components/word-cloud/word-cloud-layout.js +14 -1
- package/dist/components/word-cloud/word-cloud.d.ts +6 -0
- package/dist/components/word-cloud/word-cloud.js +25 -14
- package/dist/components/word-cloud/word-cloud.styles.js +3 -2
- package/dist/internal/announcer.d.ts +57 -0
- package/dist/internal/announcer.js +71 -0
- package/dist/internal/form-associated.d.ts +1 -0
- package/dist/internal/form-associated.js +55 -11
- package/dist/internal/group-by-recency.d.ts +50 -0
- package/dist/internal/group-by-recency.js +80 -0
- package/dist/internal/rtl.d.ts +23 -0
- package/dist/internal/rtl.js +28 -0
- package/dist/internal/scroll-lock.d.ts +10 -5
- package/dist/internal/scroll-lock.js +30 -14
- package/dist/internal/tokens.styles.js +6 -0
- package/dist/lyra.d.ts +130 -31
- package/dist/lyra.js +94 -26
- package/llms-full.txt +3836 -17
- package/llms.txt +16 -1
- package/package.json +23 -5
- package/dist/components/chart/bar-chart.stories.d.ts +0 -5
- package/dist/components/chart/bar-chart.stories.js +0 -20
- package/dist/components/chart/box-plot.stories.d.ts +0 -5
- package/dist/components/chart/box-plot.stories.js +0 -29
- package/dist/components/chart/bubble-chart.stories.d.ts +0 -5
- package/dist/components/chart/bubble-chart.stories.js +0 -26
- package/dist/components/chart/chart.stories.d.ts +0 -32
- package/dist/components/chart/chart.stories.js +0 -141
- package/dist/components/chart/doughnut-chart.stories.d.ts +0 -5
- package/dist/components/chart/doughnut-chart.stories.js +0 -26
- package/dist/components/chart/histogram.stories.d.ts +0 -5
- package/dist/components/chart/histogram.stories.js +0 -17
- package/dist/components/chart/line-chart.stories.d.ts +0 -22
- package/dist/components/chart/line-chart.stories.js +0 -99
- package/dist/components/chart/lite-chart.stories.d.ts +0 -14
- package/dist/components/chart/lite-chart.stories.js +0 -114
- package/dist/components/chart/pie-chart.stories.d.ts +0 -5
- package/dist/components/chart/pie-chart.stories.js +0 -26
- package/dist/components/chart/polar-area-chart.stories.d.ts +0 -5
- package/dist/components/chart/polar-area-chart.stories.js +0 -20
- package/dist/components/chart/radar-chart.stories.d.ts +0 -5
- package/dist/components/chart/radar-chart.stories.js +0 -20
- package/dist/components/chart/scatter-chart.stories.d.ts +0 -5
- package/dist/components/chart/scatter-chart.stories.js +0 -31
- package/dist/components/combobox/combobox.stories.d.ts +0 -24
- package/dist/components/combobox/combobox.stories.js +0 -102
- package/dist/components/date-picker/date-input.stories.d.ts +0 -10
- package/dist/components/date-picker/date-input.stories.js +0 -48
- package/dist/components/date-picker/date-picker.stories.d.ts +0 -10
- package/dist/components/date-picker/date-picker.stories.js +0 -25
- package/dist/components/empty/empty.stories.d.ts +0 -7
- package/dist/components/empty/empty.stories.js +0 -34
- package/dist/components/export-button/export-button.stories.d.ts +0 -7
- package/dist/components/export-button/export-button.stories.js +0 -37
- package/dist/components/file-input/file-input.stories.d.ts +0 -7
- package/dist/components/file-input/file-input.stories.js +0 -19
- package/dist/components/flag/flag.stories.d.ts +0 -6
- package/dist/components/flag/flag.stories.js +0 -31
- package/dist/components/gauge/gauge.stories.d.ts +0 -8
- package/dist/components/gauge/gauge.stories.js +0 -19
- package/dist/components/graph/graph.stories.d.ts +0 -8
- package/dist/components/graph/graph.stories.js +0 -68
- package/dist/components/heatmap/heatmap.stories.d.ts +0 -27
- package/dist/components/heatmap/heatmap.stories.js +0 -179
- package/dist/components/map/map.stories.d.ts +0 -15
- package/dist/components/map/map.stories.js +0 -135
- package/dist/components/playback/playback.stories.d.ts +0 -7
- package/dist/components/playback/playback.stories.js +0 -16
- package/dist/components/select/select.stories.d.ts +0 -21
- package/dist/components/select/select.stories.js +0 -91
- package/dist/components/skeleton/skeleton.stories.d.ts +0 -5
- package/dist/components/skeleton/skeleton.stories.js +0 -16
- package/dist/components/sparkline/sparkline.stories.d.ts +0 -11
- package/dist/components/sparkline/sparkline.stories.js +0 -39
- package/dist/components/split/split.stories.d.ts +0 -7
- package/dist/components/split/split.stories.js +0 -36
- package/dist/components/stat/stat.stories.d.ts +0 -9
- package/dist/components/stat/stat.stories.js +0 -81
- package/dist/components/table/table.stories.d.ts +0 -12
- package/dist/components/table/table.stories.js +0 -67
- package/dist/components/time-range/time-range.stories.d.ts +0 -8
- package/dist/components/time-range/time-range.stories.js +0 -26
- package/dist/components/toast/toast.stories.d.ts +0 -8
- package/dist/components/toast/toast.stories.js +0 -72
- package/dist/components/tree/tree.stories.d.ts +0 -9
- package/dist/components/tree/tree.stories.js +0 -52
- package/dist/components/widget/widget.stories.d.ts +0 -9
- package/dist/components/widget/widget.stories.js +0 -74
- package/dist/components/word-cloud/word-cloud.stories.d.ts +0 -10
- package/dist/components/word-cloud/word-cloud.stories.js +0 -55
|
@@ -1,25 +1,56 @@
|
|
|
1
1
|
import type * as ChartJsModule from 'chart.js';
|
|
2
2
|
import type ZoomPlugin from 'chartjs-plugin-zoom';
|
|
3
3
|
/**
|
|
4
|
-
* Independently loads the mandatory `chart.js` peer dependency and
|
|
5
|
-
* opt-in `chartjs-plugin-zoom` peer dependency
|
|
6
|
-
* (`chart.js` only, which `peerDependenciesMeta`
|
|
7
|
-
* combination) degrades to "charts render, zoom is inert"
|
|
8
|
-
* chart breaking.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
4
|
+
* Independently loads the mandatory `chart.js` peer dependency and, only
|
|
5
|
+
* when `needsZoom` is true, the opt-in `chartjs-plugin-zoom` peer dependency
|
|
6
|
+
* — so a partial install (`chart.js` only, which `peerDependenciesMeta`
|
|
7
|
+
* marks as a valid combination) degrades to "charts render, zoom is inert"
|
|
8
|
+
* instead of every chart breaking. `needsZoom` defaults to `false` because
|
|
9
|
+
* most charts never set `zoom`, and `chartjs-plugin-zoom` has a hard
|
|
10
|
+
* dependency on `hammerjs` — no point paying that import cost for every
|
|
11
|
+
* chart on the page. Exported (in addition to `loadChartJs()`/
|
|
12
|
+
* `loadChartJsWithZoom()` below) so both failure paths — and the real caught
|
|
13
|
+
* error each one logs — are directly testable without needing to actually
|
|
14
|
+
* uninstall either package.
|
|
11
15
|
*/
|
|
12
16
|
export declare function loadChartAndZoom(importChart?: () => Promise<typeof ChartJsModule>, importZoom?: () => Promise<{
|
|
13
17
|
default: typeof ZoomPlugin;
|
|
14
|
-
}
|
|
18
|
+
}>, needsZoom?: boolean): Promise<{
|
|
15
19
|
mod: typeof ChartJsModule;
|
|
16
20
|
zoomPlugin: typeof ZoomPlugin | undefined;
|
|
17
21
|
} | null>;
|
|
18
22
|
/**
|
|
19
|
-
* Lazily loads the optional peer dependency `chart.js`
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
23
|
+
* Lazily loads the optional peer dependency `chart.js` once per page,
|
|
24
|
+
* registering only the tree-shaken subset this library uses.
|
|
25
|
+
* `chartjs-plugin-zoom` is *not* loaded here — see `loadChartJsWithZoom()`
|
|
26
|
+
* below, which any chart that actually sets `zoom` should call instead.
|
|
27
|
+
* Resolves to `null` if chart.js isn't installed.
|
|
24
28
|
*/
|
|
25
29
|
export declare function loadChartJs(): Promise<typeof ChartJsModule | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Loads `chart.js` (reusing the cached load above) plus `chartjs-plugin-zoom`,
|
|
32
|
+
* on first actual demand — most charts never set `zoom`, and the plugin has
|
|
33
|
+
* a hard dependency on `hammerjs`. Registers the plugin at most once across
|
|
34
|
+
* the page. Call this instead of `loadChartJs()` from any chart that has
|
|
35
|
+
* `zoom` set (at connect time, or later once `zoom` turns on).
|
|
36
|
+
*
|
|
37
|
+
* The whole operation (chart.js core + the zoom plugin import + its
|
|
38
|
+
* registration) is memoized behind a single `zoomLoad` promise, assigned
|
|
39
|
+
* synchronously before any `await` — mirroring `loadChartJs()`'s own
|
|
40
|
+
* `chartJs` memoization above. A plain boolean "already registered" guard
|
|
41
|
+
* checked before an `await` and only set after would leave a check-then-act
|
|
42
|
+
* race across that `await` boundary: two callers racing to turn `zoom` on
|
|
43
|
+
* close together (e.g. two `<lyra-chart zoom>` elements connecting around
|
|
44
|
+
* the same time) could both pass the check before either sets the flag,
|
|
45
|
+
* each independently re-importing the plugin and calling
|
|
46
|
+
* `mod.Chart.register()`. A single promise assigned up front closes that
|
|
47
|
+
* window — the second caller synchronously observes `zoomLoad` already set
|
|
48
|
+
* and awaits the same in-flight load instead of starting its own.
|
|
49
|
+
*
|
|
50
|
+
* `importZoom` defaults to the real dynamic import; it's a parameter purely
|
|
51
|
+
* so tests can instrument/count the underlying import without needing to
|
|
52
|
+
* actually uninstall the package.
|
|
53
|
+
*/
|
|
54
|
+
export declare function loadChartJsWithZoom(importZoom?: () => Promise<{
|
|
55
|
+
default: typeof ZoomPlugin;
|
|
56
|
+
}>): Promise<typeof ChartJsModule | null>;
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
let chartJs;
|
|
2
|
+
let zoomLoad;
|
|
2
3
|
let registered = false;
|
|
3
4
|
/**
|
|
4
|
-
* Independently loads the mandatory `chart.js` peer dependency and
|
|
5
|
-
* opt-in `chartjs-plugin-zoom` peer dependency
|
|
6
|
-
* (`chart.js` only, which `peerDependenciesMeta`
|
|
7
|
-
* combination) degrades to "charts render, zoom is inert"
|
|
8
|
-
* chart breaking.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
5
|
+
* Independently loads the mandatory `chart.js` peer dependency and, only
|
|
6
|
+
* when `needsZoom` is true, the opt-in `chartjs-plugin-zoom` peer dependency
|
|
7
|
+
* — so a partial install (`chart.js` only, which `peerDependenciesMeta`
|
|
8
|
+
* marks as a valid combination) degrades to "charts render, zoom is inert"
|
|
9
|
+
* instead of every chart breaking. `needsZoom` defaults to `false` because
|
|
10
|
+
* most charts never set `zoom`, and `chartjs-plugin-zoom` has a hard
|
|
11
|
+
* dependency on `hammerjs` — no point paying that import cost for every
|
|
12
|
+
* chart on the page. Exported (in addition to `loadChartJs()`/
|
|
13
|
+
* `loadChartJsWithZoom()` below) so both failure paths — and the real caught
|
|
14
|
+
* error each one logs — are directly testable without needing to actually
|
|
15
|
+
* uninstall either package.
|
|
11
16
|
*/
|
|
12
|
-
export async function loadChartAndZoom(importChart = () => import('chart.js'), importZoom = () => import('chartjs-plugin-zoom')) {
|
|
17
|
+
export async function loadChartAndZoom(importChart = () => import('chart.js'), importZoom = () => import('chartjs-plugin-zoom'), needsZoom = false) {
|
|
13
18
|
let mod;
|
|
14
19
|
try {
|
|
15
20
|
mod = await importChart();
|
|
@@ -18,6 +23,8 @@ export async function loadChartAndZoom(importChart = () => import('chart.js'), i
|
|
|
18
23
|
console.warn('<lyra-chart> needs the optional peer dependency `chart.js` — install it with `pnpm add chart.js`:', err);
|
|
19
24
|
return null;
|
|
20
25
|
}
|
|
26
|
+
if (!needsZoom)
|
|
27
|
+
return { mod, zoomPlugin: undefined };
|
|
21
28
|
let zoomPlugin;
|
|
22
29
|
try {
|
|
23
30
|
zoomPlugin = (await importZoom()).default;
|
|
@@ -29,25 +36,65 @@ export async function loadChartAndZoom(importChart = () => import('chart.js'), i
|
|
|
29
36
|
}
|
|
30
37
|
return { mod, zoomPlugin };
|
|
31
38
|
}
|
|
39
|
+
function registerCore(mod) {
|
|
40
|
+
if (registered)
|
|
41
|
+
return;
|
|
42
|
+
mod.Chart.register(mod.LineController, mod.BarController, mod.ScatterController, mod.DoughnutController, mod.PieController, mod.RadarController, mod.PolarAreaController, mod.BubbleController, mod.LineElement, mod.PointElement, mod.BarElement, mod.ArcElement, mod.LinearScale, mod.CategoryScale, mod.RadialLinearScale, mod.Filler, mod.Tooltip, mod.Legend);
|
|
43
|
+
registered = true;
|
|
44
|
+
}
|
|
32
45
|
/**
|
|
33
|
-
* Lazily loads the optional peer dependency `chart.js`
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
46
|
+
* Lazily loads the optional peer dependency `chart.js` once per page,
|
|
47
|
+
* registering only the tree-shaken subset this library uses.
|
|
48
|
+
* `chartjs-plugin-zoom` is *not* loaded here — see `loadChartJsWithZoom()`
|
|
49
|
+
* below, which any chart that actually sets `zoom` should call instead.
|
|
50
|
+
* Resolves to `null` if chart.js isn't installed.
|
|
38
51
|
*/
|
|
39
52
|
export function loadChartJs() {
|
|
40
53
|
if (!chartJs) {
|
|
41
54
|
chartJs = loadChartAndZoom().then((result) => {
|
|
42
55
|
if (!result)
|
|
43
56
|
return null;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
registerCore(result.mod);
|
|
58
|
+
return result.mod;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return chartJs;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Loads `chart.js` (reusing the cached load above) plus `chartjs-plugin-zoom`,
|
|
65
|
+
* on first actual demand — most charts never set `zoom`, and the plugin has
|
|
66
|
+
* a hard dependency on `hammerjs`. Registers the plugin at most once across
|
|
67
|
+
* the page. Call this instead of `loadChartJs()` from any chart that has
|
|
68
|
+
* `zoom` set (at connect time, or later once `zoom` turns on).
|
|
69
|
+
*
|
|
70
|
+
* The whole operation (chart.js core + the zoom plugin import + its
|
|
71
|
+
* registration) is memoized behind a single `zoomLoad` promise, assigned
|
|
72
|
+
* synchronously before any `await` — mirroring `loadChartJs()`'s own
|
|
73
|
+
* `chartJs` memoization above. A plain boolean "already registered" guard
|
|
74
|
+
* checked before an `await` and only set after would leave a check-then-act
|
|
75
|
+
* race across that `await` boundary: two callers racing to turn `zoom` on
|
|
76
|
+
* close together (e.g. two `<lyra-chart zoom>` elements connecting around
|
|
77
|
+
* the same time) could both pass the check before either sets the flag,
|
|
78
|
+
* each independently re-importing the plugin and calling
|
|
79
|
+
* `mod.Chart.register()`. A single promise assigned up front closes that
|
|
80
|
+
* window — the second caller synchronously observes `zoomLoad` already set
|
|
81
|
+
* and awaits the same in-flight load instead of starting its own.
|
|
82
|
+
*
|
|
83
|
+
* `importZoom` defaults to the real dynamic import; it's a parameter purely
|
|
84
|
+
* so tests can instrument/count the underlying import without needing to
|
|
85
|
+
* actually uninstall the package.
|
|
86
|
+
*/
|
|
87
|
+
export function loadChartJsWithZoom(importZoom = () => import('chartjs-plugin-zoom')) {
|
|
88
|
+
if (!zoomLoad) {
|
|
89
|
+
zoomLoad = loadChartJs().then(async (mod) => {
|
|
90
|
+
if (!mod)
|
|
91
|
+
return null;
|
|
92
|
+
const result = await loadChartAndZoom(() => Promise.resolve(mod), importZoom, true);
|
|
93
|
+
if (result?.zoomPlugin) {
|
|
94
|
+
mod.Chart.register(result.zoomPlugin);
|
|
48
95
|
}
|
|
49
96
|
return mod;
|
|
50
97
|
});
|
|
51
98
|
}
|
|
52
|
-
return
|
|
99
|
+
return zoomLoad;
|
|
53
100
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type TemplateResult, type PropertyValues } from 'lit';
|
|
2
|
-
import type { ChartConfiguration } from 'chart.js';
|
|
3
2
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
4
3
|
import '../skeleton/skeleton.js';
|
|
5
4
|
export interface Series {
|
|
@@ -73,7 +72,7 @@ export declare class LyraChart extends LyraElement {
|
|
|
73
72
|
* without discarding sibling keys the generated config set), for consumers
|
|
74
73
|
* who need full Chart.js control beyond the simplified `Series` shape.
|
|
75
74
|
*/
|
|
76
|
-
config?: Partial<ChartConfiguration>;
|
|
75
|
+
config?: Partial<import('chart.js').ChartConfiguration>;
|
|
77
76
|
/** True until the lazy-loaded `chart.js` peer dependency has settled (success or failure). */
|
|
78
77
|
private loading;
|
|
79
78
|
private zoomed;
|
|
@@ -8,7 +8,7 @@ import { html, nothing } from 'lit';
|
|
|
8
8
|
import { property, query, state } from 'lit/decorators.js';
|
|
9
9
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
10
10
|
import { defineElement } from '../../internal/prefix.js';
|
|
11
|
-
import { loadChartJs } from './chart-loader.js';
|
|
11
|
+
import { loadChartJs, loadChartJsWithZoom } from './chart-loader.js';
|
|
12
12
|
import { styles } from './chart.styles.js';
|
|
13
13
|
import '../skeleton/skeleton.js';
|
|
14
14
|
/**
|
|
@@ -111,7 +111,10 @@ export class LyraChart extends LyraElement {
|
|
|
111
111
|
static { this.styles = [LyraElement.styles, styles]; }
|
|
112
112
|
connectedCallback() {
|
|
113
113
|
super.connectedCallback();
|
|
114
|
-
|
|
114
|
+
const load = this.zoom ? loadChartJsWithZoom() : loadChartJs();
|
|
115
|
+
void load.then((mod) => {
|
|
116
|
+
if (!this.isConnected)
|
|
117
|
+
return;
|
|
115
118
|
this.loading = false;
|
|
116
119
|
if (!mod)
|
|
117
120
|
return;
|
|
@@ -135,6 +138,19 @@ export class LyraChart extends LyraElement {
|
|
|
135
138
|
this.intersectionObserver?.disconnect();
|
|
136
139
|
}
|
|
137
140
|
updated(changed) {
|
|
141
|
+
// Disconnected between the property change that scheduled this update
|
|
142
|
+
// and Lit's (microtask-deferred) processing of it — e.g. a property
|
|
143
|
+
// changes and the element is removed in the same synchronous tick, so
|
|
144
|
+
// `disconnectedCallback()` (which already destroyed `this.chart`) runs
|
|
145
|
+
// *before* this method does. Nothing below should run in that case:
|
|
146
|
+
// this method's own unconditional `draw()` call further down would
|
|
147
|
+
// otherwise construct a brand-new `Chart` bound to the now-detached
|
|
148
|
+
// canvas — `draw()`'s own guard (`!chartJsModule || !canvasEl`) doesn't
|
|
149
|
+
// catch this, since both persist on a disconnected-but-intact element.
|
|
150
|
+
// If the component is reconnected later, `connectedCallback()` re-kicks
|
|
151
|
+
// its own load/draw sequence, so nothing is lost by bailing out here.
|
|
152
|
+
if (!this.isConnected)
|
|
153
|
+
return;
|
|
138
154
|
if (this.loading)
|
|
139
155
|
this.setAttribute('aria-busy', 'true');
|
|
140
156
|
else
|
|
@@ -154,6 +170,22 @@ export class LyraChart extends LyraElement {
|
|
|
154
170
|
// other property having changed in the meantime.
|
|
155
171
|
if (this.loading)
|
|
156
172
|
return;
|
|
173
|
+
// `zoom` can also turn on after connect (it was false at
|
|
174
|
+
// `connectedCallback()` time, so only the core `loadChartJs()` load was
|
|
175
|
+
// kicked off) — load the zoom plugin on demand now and redraw once it's
|
|
176
|
+
// registered. Mirrors the same `isConnected` guard `connectedCallback()`
|
|
177
|
+
// uses: this method already bailed out above if *already* disconnected,
|
|
178
|
+
// but the element can *also* disconnect during the gap while this
|
|
179
|
+
// dynamic import is in flight — without this guard, `draw()` would
|
|
180
|
+
// construct a new, leaked `Chart` bound to the now-detached canvas once
|
|
181
|
+
// the import resolves.
|
|
182
|
+
if (changed.has('zoom') && this.zoom) {
|
|
183
|
+
void loadChartJsWithZoom().then(() => {
|
|
184
|
+
if (!this.isConnected)
|
|
185
|
+
return;
|
|
186
|
+
this.draw();
|
|
187
|
+
});
|
|
188
|
+
}
|
|
157
189
|
const onlyZoomChanged = changed.size === 1 && changed.has('zoomed');
|
|
158
190
|
if (onlyZoomChanged)
|
|
159
191
|
return;
|
|
@@ -170,7 +202,20 @@ export class LyraChart extends LyraElement {
|
|
|
170
202
|
return {
|
|
171
203
|
label: s.label,
|
|
172
204
|
data: s.points ?? s.data ?? [],
|
|
173
|
-
|
|
205
|
+
// Leave unset rather than defaulting to `this.type`: Chart.js already
|
|
206
|
+
// falls back to the chart-level (effective) type for any dataset that
|
|
207
|
+
// doesn't set its own `type`, and forcing `this.type` here unconditionally
|
|
208
|
+
// used to be harmless (it normally matched the effective type anyway) —
|
|
209
|
+
// but it actively breaks a `config.type` override to a different chart
|
|
210
|
+
// family (e.g. attribute `type="line"` + `config.type: 'radar'`): every
|
|
211
|
+
// dataset would carry an explicit `type: 'line'` under a chart whose
|
|
212
|
+
// scales are built for `radar` (a single radial `r` scale, no `x`/`y`),
|
|
213
|
+
// which Chart.js can't reconcile — it hangs the page trying to lay out
|
|
214
|
+
// a cartesian-scale controller against a radial-only scale set. Only
|
|
215
|
+
// `s.type` (an explicit per-series mixed-type override, e.g. a line
|
|
216
|
+
// series over a bar chart of the *same* effective family) is passed
|
|
217
|
+
// through.
|
|
218
|
+
type: s.type,
|
|
174
219
|
fill: s.fill ?? this.area,
|
|
175
220
|
borderWidth: s.width ?? 2,
|
|
176
221
|
borderDash: s.dash ? [4, 4] : undefined,
|
|
@@ -179,7 +224,6 @@ export class LyraChart extends LyraElement {
|
|
|
179
224
|
pointBackgroundColor: s.pointColors,
|
|
180
225
|
pointRadius: s.pointRadius,
|
|
181
226
|
yAxisID: s.axis === 'y2' ? 'y2' : 'y',
|
|
182
|
-
tooltip: s.noTooltip ? { enabled: false } : undefined,
|
|
183
227
|
};
|
|
184
228
|
}
|
|
185
229
|
/**
|
|
@@ -235,10 +279,10 @@ export class LyraChart extends LyraElement {
|
|
|
235
279
|
* scale's `ticks.color`/`grid.color`/axis `title.color` so grid lines and
|
|
236
280
|
* labels retheme instead of sitting at Chart.js's own hardcoded defaults.
|
|
237
281
|
*/
|
|
238
|
-
buildScales(theme) {
|
|
239
|
-
if (
|
|
282
|
+
buildScales(effectiveType, theme) {
|
|
283
|
+
if (effectiveType === 'pie' || effectiveType === 'doughnut')
|
|
240
284
|
return {};
|
|
241
|
-
if (
|
|
285
|
+
if (effectiveType === 'radar' || effectiveType === 'polarArea') {
|
|
242
286
|
return {
|
|
243
287
|
r: {
|
|
244
288
|
beginAtZero: this.beginAtZero,
|
|
@@ -253,10 +297,10 @@ export class LyraChart extends LyraElement {
|
|
|
253
297
|
// `stacked` only applies to bar/line-family charts sharing a categorical
|
|
254
298
|
// axis, per the design spec — scatter/bubble's linear x scale and the
|
|
255
299
|
// radial r scale above are out of scope.
|
|
256
|
-
const stacked = this.stacked && (
|
|
300
|
+
const stacked = this.stacked && (effectiveType === 'bar' || effectiveType === 'line');
|
|
257
301
|
return {
|
|
258
302
|
x: {
|
|
259
|
-
type:
|
|
303
|
+
type: effectiveType === 'scatter' || effectiveType === 'bubble' ? 'linear' : 'category',
|
|
260
304
|
title: { display: !!this.xLabel, text: this.xLabel, color: theme.tick },
|
|
261
305
|
ticks: { color: theme.tick },
|
|
262
306
|
grid: { color: theme.grid },
|
|
@@ -310,8 +354,15 @@ export class LyraChart extends LyraElement {
|
|
|
310
354
|
}
|
|
311
355
|
buildConfig() {
|
|
312
356
|
const theme = this.themeColors();
|
|
357
|
+
// Resolve the effective type up front: `config.type` (if set) overrides
|
|
358
|
+
// the attribute `type` post-merge, so scales/interaction must be built
|
|
359
|
+
// for *that* type, not `this.type` — otherwise a config.type override
|
|
360
|
+
// (e.g. line -> radar) ships with the wrong axis shape (categorical x/y
|
|
361
|
+
// instead of a radial r scale).
|
|
362
|
+
const effectiveType = this.config?.type ??
|
|
363
|
+
this.type;
|
|
313
364
|
const generated = {
|
|
314
|
-
type:
|
|
365
|
+
type: effectiveType,
|
|
315
366
|
data: {
|
|
316
367
|
labels: this.labels,
|
|
317
368
|
datasets: this.datasets.map((s) => this.seriesToDataset(s)),
|
|
@@ -329,7 +380,7 @@ export class LyraChart extends LyraElement {
|
|
|
329
380
|
// canvas-internal animation loop, so `prefersReducedMotion()` is
|
|
330
381
|
// checked here instead and fed into `options.animation`.
|
|
331
382
|
animation: prefersReducedMotion() ? false : undefined,
|
|
332
|
-
interaction: { intersect: false, mode:
|
|
383
|
+
interaction: { intersect: false, mode: effectiveType === 'scatter' ? 'nearest' : 'index' },
|
|
333
384
|
onClick: (event, _elements, chart) => this.handlePointClick(event, chart),
|
|
334
385
|
plugins: {
|
|
335
386
|
legend: { display: this.legend, labels: { color: theme.legend } },
|
|
@@ -337,6 +388,10 @@ export class LyraChart extends LyraElement {
|
|
|
337
388
|
backgroundColor: theme.tooltipBg,
|
|
338
389
|
titleColor: theme.tooltipText,
|
|
339
390
|
bodyColor: theme.tooltipText,
|
|
391
|
+
// Chart.js's tooltip plugin has no per-dataset `tooltip.enabled`
|
|
392
|
+
// — `Series.noTooltip` is implemented here instead, via the one
|
|
393
|
+
// mechanism the core tooltip plugin actually reads.
|
|
394
|
+
filter: (item) => !this.datasets[item.datasetIndex]?.noTooltip,
|
|
340
395
|
},
|
|
341
396
|
zoom: this.zoom
|
|
342
397
|
? {
|
|
@@ -357,7 +412,7 @@ export class LyraChart extends LyraElement {
|
|
|
357
412
|
}
|
|
358
413
|
: undefined,
|
|
359
414
|
},
|
|
360
|
-
scales: this.buildScales(theme),
|
|
415
|
+
scales: this.buildScales(effectiveType, theme),
|
|
361
416
|
},
|
|
362
417
|
};
|
|
363
418
|
if (!this.config)
|
|
@@ -2,5 +2,8 @@ export interface HistogramBucket {
|
|
|
2
2
|
label: string;
|
|
3
3
|
count: number;
|
|
4
4
|
}
|
|
5
|
-
/** Splits `values` into `binCount` equal-width buckets and counts membership.
|
|
5
|
+
/** Splits `values` into `binCount` equal-width buckets and counts membership.
|
|
6
|
+
* Non-finite `binCount` (or <= 0) yields no buckets; a fractional `binCount`
|
|
7
|
+
* is floored; non-finite samples in `values` are dropped rather than
|
|
8
|
+
* corrupting bucket-index math. */
|
|
6
9
|
export declare function binValues(values: number[], binCount: number): HistogramBucket[];
|
|
@@ -1,29 +1,39 @@
|
|
|
1
|
-
/** Splits `values` into `binCount` equal-width buckets and counts membership.
|
|
1
|
+
/** Splits `values` into `binCount` equal-width buckets and counts membership.
|
|
2
|
+
* Non-finite `binCount` (or <= 0) yields no buckets; a fractional `binCount`
|
|
3
|
+
* is floored; non-finite samples in `values` are dropped rather than
|
|
4
|
+
* corrupting bucket-index math. */
|
|
2
5
|
export function binValues(values, binCount) {
|
|
3
|
-
|
|
6
|
+
const finite = values.filter((v) => Number.isFinite(v));
|
|
7
|
+
if (finite.length === 0 || !Number.isFinite(binCount))
|
|
4
8
|
return [];
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
let
|
|
10
|
-
|
|
11
|
-
for (const v of values) {
|
|
9
|
+
const bins = Math.floor(binCount);
|
|
10
|
+
if (bins <= 0)
|
|
11
|
+
return [];
|
|
12
|
+
let lo = finite[0];
|
|
13
|
+
let hi = finite[0];
|
|
14
|
+
for (const v of finite) {
|
|
12
15
|
if (v < lo)
|
|
13
16
|
lo = v;
|
|
14
17
|
if (v > hi)
|
|
15
18
|
hi = v;
|
|
16
19
|
}
|
|
20
|
+
// Constant data (lo === hi) previously fell into the `v === hi` branch
|
|
21
|
+
// below, which places every value in the *last* bucket alone — misleading,
|
|
22
|
+
// since every other bucket reads 0 and the label implies a spread that
|
|
23
|
+
// isn't real. Spread it into the *first* bucket instead so a single-value
|
|
24
|
+
// dataset reads as "N items, one bucket populated" starting from the data's
|
|
25
|
+
// own value, not its synthetic +1 upper edge.
|
|
26
|
+
const constant = hi === lo;
|
|
17
27
|
const span = hi - lo || 1;
|
|
18
|
-
const width = span /
|
|
19
|
-
const buckets = Array.from({ length:
|
|
28
|
+
const width = span / bins;
|
|
29
|
+
const buckets = Array.from({ length: bins }, (_, i) => {
|
|
20
30
|
const bLo = lo + i * width;
|
|
21
31
|
const bHi = lo + (i + 1) * width;
|
|
22
32
|
return { label: `${bLo.toFixed(1)}–${bHi.toFixed(1)}`, count: 0 };
|
|
23
33
|
});
|
|
24
|
-
for (const v of
|
|
25
|
-
const index = v === hi ?
|
|
26
|
-
buckets[Math.min(
|
|
34
|
+
for (const v of finite) {
|
|
35
|
+
const index = constant ? 0 : v === hi ? bins - 1 : Math.floor((v - lo) / width);
|
|
36
|
+
buckets[Math.min(bins - 1, Math.max(0, index))].count++;
|
|
27
37
|
}
|
|
28
38
|
return buckets;
|
|
29
39
|
}
|
|
@@ -7,6 +7,13 @@ export interface LiteSeries {
|
|
|
7
7
|
color?: string;
|
|
8
8
|
}
|
|
9
9
|
export type LyraLiteChartType = 'bar' | 'line';
|
|
10
|
+
/**
|
|
11
|
+
* `'fit'` (default) squeezes the whole plot into the measured host width,
|
|
12
|
+
* exactly as this component always behaved. `'scroll'` gives every bar a
|
|
13
|
+
* fixed `barWidth` instead and lets the plot's content width exceed the
|
|
14
|
+
* host's, making the host horizontally scrollable.
|
|
15
|
+
*/
|
|
16
|
+
export type LyraLiteChartLayout = 'fit' | 'scroll';
|
|
10
17
|
/**
|
|
11
18
|
* `<lyra-lite-chart>` — a dependency-free bar/line chart, plain SVG/DOM
|
|
12
19
|
* rendering with zero peer dependencies (unlike `lyra-chart`, which wraps
|
|
@@ -22,6 +29,17 @@ export type LyraLiteChartType = 'bar' | 'line';
|
|
|
22
29
|
* `getComputedStyle()`-based re-theming step is needed the way `chart.ts`
|
|
23
30
|
* needs one for its canvas.
|
|
24
31
|
*
|
|
32
|
+
* By default (`layout="fit"`) the plot always squeezes to the measured host
|
|
33
|
+
* width. Three independent, opt-in escape hatches for dense/aligned data:
|
|
34
|
+
* `layout="scroll"` (+ `barWidth`) gives every bar a fixed pixel width and
|
|
35
|
+
* lets the plot overflow the host horizontally (scrollable) instead of
|
|
36
|
+
* squeezing; `maxLabels` decimates which x-axis text labels render (bars
|
|
37
|
+
* always still render) once there are more categories than that; and
|
|
38
|
+
* `barX` lets a consumer hand in its own per-category x-coordinate function
|
|
39
|
+
* — e.g. to pixel-align this chart's bars with a sibling `lyra-heatmap`'s
|
|
40
|
+
* calendar columns — overriding the internal slot math for both bars and
|
|
41
|
+
* their labels. All three are additive and no-ops when left unset.
|
|
42
|
+
*
|
|
25
43
|
* @customElement lyra-lite-chart
|
|
26
44
|
* @event lyra-point-click - Fired when a bar/point is activated (click, or
|
|
27
45
|
* Enter/Space while focused). `detail: { datasetIndex: number, index:
|
|
@@ -53,6 +71,27 @@ export declare class LyraLiteChart extends LyraElement {
|
|
|
53
71
|
/** Formats a y-axis tick value for display (e.g. `(v) => \`$${v.toFixed(2)}\``). Falls back to the
|
|
54
72
|
* built-in nice-number formatter when unset. */
|
|
55
73
|
tickFormat?: (value: number) => string;
|
|
74
|
+
/** `'fit'` (default) squeezes the plot into the measured host width, unchanged from before this
|
|
75
|
+
* property existed. `'scroll'` gives every bar a fixed `barWidth` instead, letting the plot's
|
|
76
|
+
* content width exceed the host's — the host becomes horizontally scrollable
|
|
77
|
+
* (`overflow-x: auto`) so every bar stays exactly `barWidth` wide regardless of category count.
|
|
78
|
+
* Reflects to the `layout` attribute (e.g. for `:host([layout='scroll'])` host styling). */
|
|
79
|
+
layout: LyraLiteChartLayout;
|
|
80
|
+
/** Fixed per-category bar width in px, used only when `layout="scroll"`. Ignored (as before this
|
|
81
|
+
* property existed) in `layout="fit"`, the default. */
|
|
82
|
+
barWidth: number;
|
|
83
|
+
/** Caps how many x-axis category labels render text once `this.labels.length` exceeds it,
|
|
84
|
+
* decimating roughly evenly while always keeping the first and last label. Bars themselves
|
|
85
|
+
* always render regardless — only the axis text is decimated. Unset (the default) renders every
|
|
86
|
+
* label, unchanged from before this property existed. Works in either `layout` mode. */
|
|
87
|
+
maxLabels?: number;
|
|
88
|
+
/** Overrides the x-origin `renderBars()`/the category labels would otherwise compute internally
|
|
89
|
+
* for a given category index, for `type="bar"` only (bars and their axis labels stay
|
|
90
|
+
* consistent with each other either way). Lets a consumer pixel-align this chart's bars with,
|
|
91
|
+
* e.g., a sibling `lyra-heatmap`'s calendar columns by handing both components the same
|
|
92
|
+
* coordinate function. Unset (the default) uses the existing internal per-category slot math,
|
|
93
|
+
* unchanged from before this property existed. */
|
|
94
|
+
barX?: (index: number) => number;
|
|
56
95
|
private plotWidth;
|
|
57
96
|
private plotHeight;
|
|
58
97
|
private visible;
|
|
@@ -71,9 +110,24 @@ export declare class LyraLiteChart extends LyraElement {
|
|
|
71
110
|
private emitPoint;
|
|
72
111
|
private onPointKeyDown;
|
|
73
112
|
private renderGrid;
|
|
113
|
+
/**
|
|
114
|
+
* `slot` is the per-category width to lay bars out against — either the
|
|
115
|
+
* measured-width-derived `plotW / n` (`layout="fit"`) or the fixed
|
|
116
|
+
* `barWidth` (`layout="scroll"`), computed once by the caller
|
|
117
|
+
* (`renderChart()`) and handed to both this method and the category-label
|
|
118
|
+
* x-position calc so the two can never drift apart from each other.
|
|
119
|
+
*/
|
|
74
120
|
private renderBars;
|
|
75
121
|
private renderLines;
|
|
76
122
|
render(): TemplateResult;
|
|
123
|
+
/**
|
|
124
|
+
* Step size for `maxLabels` decimation: 1 (show every label, today's
|
|
125
|
+
* unchanged default) when `maxLabels` is unset or already >= the label
|
|
126
|
+
* count, otherwise the ceil-divide spacing that lands close to
|
|
127
|
+
* `maxLabels` shown labels while always keeping index 0 and the last
|
|
128
|
+
* index (enforced by the caller, not here).
|
|
129
|
+
*/
|
|
130
|
+
private labelStep;
|
|
77
131
|
private renderChart;
|
|
78
132
|
}
|
|
79
133
|
declare global {
|