@fusion.dev/helix-headless 0.0.0-dev
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/LICENSE +21 -0
- package/custom-elements.json +75202 -0
- package/dist/accordion/index.d.ts +2 -0
- package/dist/accordion/index.js +2 -0
- package/dist/accordion/item/accordion-item.d.ts +141 -0
- package/dist/accordion/item/accordion-item.js +214 -0
- package/dist/accordion/root/accordion-root.d.ts +57 -0
- package/dist/accordion/root/accordion-root.js +96 -0
- package/dist/announcement/index.d.ts +1 -0
- package/dist/announcement/index.js +1 -0
- package/dist/announcement/root/announcement-root.d.ts +106 -0
- package/dist/announcement/root/announcement-root.js +144 -0
- package/dist/app-header/index.d.ts +1 -0
- package/dist/app-header/index.js +1 -0
- package/dist/app-header/root/app-header-root.d.ts +113 -0
- package/dist/app-header/root/app-header-root.js +147 -0
- package/dist/avatar/group/avatar-group.d.ts +116 -0
- package/dist/avatar/group/avatar-group.js +136 -0
- package/dist/avatar/index.d.ts +2 -0
- package/dist/avatar/index.js +2 -0
- package/dist/avatar/root/avatar-root.d.ts +71 -0
- package/dist/avatar/root/avatar-root.js +147 -0
- package/dist/badge/index.d.ts +1 -0
- package/dist/badge/index.js +1 -0
- package/dist/badge/root/badge-root.d.ts +61 -0
- package/dist/badge/root/badge-root.js +121 -0
- package/dist/bar-chart/index.d.ts +1 -0
- package/dist/bar-chart/index.js +1 -0
- package/dist/bar-chart/root/bar-chart-root.d.ts +266 -0
- package/dist/bar-chart/root/bar-chart-root.js +515 -0
- package/dist/blockquote/index.d.ts +1 -0
- package/dist/blockquote/index.js +1 -0
- package/dist/blockquote/root/blockquote-root.d.ts +51 -0
- package/dist/blockquote/root/blockquote-root.js +84 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +104 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +137 -0
- package/dist/breadcrumbs/index.d.ts +2 -0
- package/dist/breadcrumbs/index.js +2 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +77 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.js +94 -0
- package/dist/button/index.d.ts +1 -0
- package/dist/button/index.js +1 -0
- package/dist/button/root/button-root.d.ts +251 -0
- package/dist/button/root/button-root.js +401 -0
- package/dist/button-group/index.d.ts +1 -0
- package/dist/button-group/index.js +1 -0
- package/dist/button-group/root/button-group-root.d.ts +62 -0
- package/dist/button-group/root/button-group-root.js +62 -0
- package/dist/callout/index.d.ts +1 -0
- package/dist/callout/index.js +1 -0
- package/dist/callout/root/callout-root.d.ts +72 -0
- package/dist/callout/root/callout-root.js +90 -0
- package/dist/card/index.d.ts +1 -0
- package/dist/card/index.js +1 -0
- package/dist/card/root/card-root.d.ts +54 -0
- package/dist/card/root/card-root.js +71 -0
- package/dist/carousel/index.d.ts +1 -0
- package/dist/carousel/index.js +1 -0
- package/dist/carousel/root/carousel-root.d.ts +399 -0
- package/dist/carousel/root/carousel-root.js +723 -0
- package/dist/chat/composer/chat-composer.d.ts +160 -0
- package/dist/chat/composer/chat-composer.js +273 -0
- package/dist/chat/index.d.ts +3 -0
- package/dist/chat/index.js +3 -0
- package/dist/chat/message/chat-message.d.ts +170 -0
- package/dist/chat/message/chat-message.js +271 -0
- package/dist/chat/root/chat-root.d.ts +216 -0
- package/dist/chat/root/chat-root.js +389 -0
- package/dist/checkbox/index.d.ts +1 -0
- package/dist/checkbox/index.js +1 -0
- package/dist/checkbox/root/checkbox-root.d.ts +108 -0
- package/dist/checkbox/root/checkbox-root.js +207 -0
- package/dist/checkbox-group/index.d.ts +1 -0
- package/dist/checkbox-group/index.js +1 -0
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +155 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +293 -0
- package/dist/code/index.d.ts +1 -0
- package/dist/code/index.js +1 -0
- package/dist/code/root/code-root.d.ts +36 -0
- package/dist/code/root/code-root.js +43 -0
- package/dist/code-block/index.d.ts +1 -0
- package/dist/code-block/index.js +1 -0
- package/dist/code-block/root/code-block-root.d.ts +112 -0
- package/dist/code-block/root/code-block-root.js +155 -0
- package/dist/color-input/index.d.ts +1 -0
- package/dist/color-input/index.js +1 -0
- package/dist/color-input/root/color-input-root.d.ts +227 -0
- package/dist/color-input/root/color-input-root.js +456 -0
- package/dist/color-picker/color.d.ts +74 -0
- package/dist/color-picker/color.js +238 -0
- package/dist/color-picker/index.d.ts +2 -0
- package/dist/color-picker/index.js +2 -0
- package/dist/color-picker/root/color-picker-root.d.ts +303 -0
- package/dist/color-picker/root/color-picker-root.js +576 -0
- package/dist/combobox/index.d.ts +1 -0
- package/dist/combobox/index.js +1 -0
- package/dist/combobox/root/combobox-root.d.ts +396 -0
- package/dist/combobox/root/combobox-root.js +808 -0
- package/dist/command/index.d.ts +1 -0
- package/dist/command/index.js +1 -0
- package/dist/command/root/command-root.d.ts +166 -0
- package/dist/command/root/command-root.js +353 -0
- package/dist/copy-button/index.d.ts +1 -0
- package/dist/copy-button/index.js +1 -0
- package/dist/copy-button/root/copy-button-root.d.ts +154 -0
- package/dist/copy-button/root/copy-button-root.js +225 -0
- package/dist/data-table/index.d.ts +2 -0
- package/dist/data-table/index.js +2 -0
- package/dist/data-table/root/data-table-root.d.ts +392 -0
- package/dist/data-table/root/data-table-root.js +729 -0
- package/dist/data-table/root/order.d.ts +116 -0
- package/dist/data-table/root/order.js +175 -0
- package/dist/date-input/index.d.ts +1 -0
- package/dist/date-input/index.js +1 -0
- package/dist/date-input/root/date-input-root.d.ts +361 -0
- package/dist/date-input/root/date-input-root.js +791 -0
- package/dist/date-picker/index.d.ts +1 -0
- package/dist/date-picker/index.js +1 -0
- package/dist/date-picker/root/date-picker-root.d.ts +361 -0
- package/dist/date-picker/root/date-picker-root.js +837 -0
- package/dist/dialog/index.d.ts +1 -0
- package/dist/dialog/index.js +1 -0
- package/dist/dialog/root/dialog-root.d.ts +185 -0
- package/dist/dialog/root/dialog-root.js +319 -0
- package/dist/divider/index.d.ts +1 -0
- package/dist/divider/index.js +1 -0
- package/dist/divider/root/divider-root.d.ts +68 -0
- package/dist/divider/root/divider-root.js +116 -0
- package/dist/donut-chart/index.d.ts +1 -0
- package/dist/donut-chart/index.js +1 -0
- package/dist/donut-chart/root/donut-chart-root.d.ts +209 -0
- package/dist/donut-chart/root/donut-chart-root.js +395 -0
- package/dist/drawer/index.d.ts +1 -0
- package/dist/drawer/index.js +1 -0
- package/dist/drawer/root/drawer-root.d.ts +144 -0
- package/dist/drawer/root/drawer-root.js +222 -0
- package/dist/drilldown/index.d.ts +2 -0
- package/dist/drilldown/index.js +2 -0
- package/dist/drilldown/item/drilldown-item.d.ts +87 -0
- package/dist/drilldown/item/drilldown-item.js +152 -0
- package/dist/drilldown/root/drilldown-root.d.ts +115 -0
- package/dist/drilldown/root/drilldown-root.js +263 -0
- package/dist/element-events.generated.d.ts +1 -0
- package/dist/element-events.generated.js +125 -0
- package/dist/empty/index.d.ts +1 -0
- package/dist/empty/index.js +1 -0
- package/dist/empty/root/empty-root.d.ts +47 -0
- package/dist/empty/root/empty-root.js +68 -0
- package/dist/file-input/index.d.ts +1 -0
- package/dist/file-input/index.js +1 -0
- package/dist/file-input/root/file-input-root.d.ts +196 -0
- package/dist/file-input/root/file-input-root.js +488 -0
- package/dist/format-date/index.d.ts +1 -0
- package/dist/format-date/index.js +1 -0
- package/dist/format-date/root/format-date-root.d.ts +151 -0
- package/dist/format-date/root/format-date-root.js +266 -0
- package/dist/heatmap/index.d.ts +2 -0
- package/dist/heatmap/index.js +2 -0
- package/dist/heatmap/root/buckets.d.ts +62 -0
- package/dist/heatmap/root/buckets.js +85 -0
- package/dist/heatmap/root/heatmap-root.d.ts +330 -0
- package/dist/heatmap/root/heatmap-root.js +526 -0
- package/dist/icon/index.d.ts +1 -0
- package/dist/icon/index.js +1 -0
- package/dist/icon/root/icon-root.d.ts +53 -0
- package/dist/icon/root/icon-root.js +93 -0
- package/dist/icon-button/index.d.ts +1 -0
- package/dist/icon-button/index.js +1 -0
- package/dist/icon-button/root/icon-button-root.d.ts +40 -0
- package/dist/icon-button/root/icon-button-root.js +46 -0
- package/dist/image/index.d.ts +1 -0
- package/dist/image/index.js +1 -0
- package/dist/image/root/image-root.d.ts +213 -0
- package/dist/image/root/image-root.js +335 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.js +99 -0
- package/dist/input/index.d.ts +1 -0
- package/dist/input/index.js +1 -0
- package/dist/input/root/input-root.d.ts +281 -0
- package/dist/input/root/input-root.js +472 -0
- package/dist/kbd/index.d.ts +1 -0
- package/dist/kbd/index.js +1 -0
- package/dist/kbd/root/kbd-root.d.ts +98 -0
- package/dist/kbd/root/kbd-root.js +230 -0
- package/dist/legend/index.d.ts +1 -0
- package/dist/legend/index.js +1 -0
- package/dist/legend/root/legend-root.d.ts +83 -0
- package/dist/legend/root/legend-root.js +125 -0
- package/dist/line-chart/index.d.ts +1 -0
- package/dist/line-chart/index.js +1 -0
- package/dist/line-chart/root/line-chart-root.d.ts +238 -0
- package/dist/line-chart/root/line-chart-root.js +365 -0
- package/dist/list/index.d.ts +2 -0
- package/dist/list/index.js +2 -0
- package/dist/list/item/list-item.d.ts +95 -0
- package/dist/list/item/list-item.js +148 -0
- package/dist/list/root/list-root.d.ts +72 -0
- package/dist/list/root/list-root.js +61 -0
- package/dist/listbox/index.d.ts +1 -0
- package/dist/listbox/index.js +1 -0
- package/dist/listbox/root/listbox-root.d.ts +357 -0
- package/dist/listbox/root/listbox-root.js +890 -0
- package/dist/loader/index.d.ts +1 -0
- package/dist/loader/index.js +1 -0
- package/dist/loader/root/loader-root.d.ts +52 -0
- package/dist/loader/root/loader-root.js +74 -0
- package/dist/megamenu/index.d.ts +1 -0
- package/dist/megamenu/index.js +1 -0
- package/dist/megamenu/root/megamenu-root.d.ts +254 -0
- package/dist/megamenu/root/megamenu-root.js +526 -0
- package/dist/menu/index.d.ts +2 -0
- package/dist/menu/index.js +2 -0
- package/dist/menu/item/menu-item.d.ts +231 -0
- package/dist/menu/item/menu-item.js +405 -0
- package/dist/menu/root/menu-root.d.ts +158 -0
- package/dist/menu/root/menu-root.js +422 -0
- package/dist/meter/index.d.ts +1 -0
- package/dist/meter/index.js +1 -0
- package/dist/meter/root/meter-root.d.ts +234 -0
- package/dist/meter/root/meter-root.js +316 -0
- package/dist/navigation/index.d.ts +1 -0
- package/dist/navigation/index.js +1 -0
- package/dist/navigation/root/navigation-root.d.ts +55 -0
- package/dist/navigation/root/navigation-root.js +130 -0
- package/dist/notifications/index.d.ts +2 -0
- package/dist/notifications/index.js +2 -0
- package/dist/notifications/notification/notification.d.ts +181 -0
- package/dist/notifications/notification/notification.js +305 -0
- package/dist/notifications/root/notifications-root.d.ts +168 -0
- package/dist/notifications/root/notifications-root.js +291 -0
- package/dist/number-input/index.d.ts +1 -0
- package/dist/number-input/index.js +1 -0
- package/dist/number-input/root/number-input-root.d.ts +282 -0
- package/dist/number-input/root/number-input-root.js +592 -0
- package/dist/option/group/option-group.d.ts +38 -0
- package/dist/option/group/option-group.js +58 -0
- package/dist/option/index.d.ts +2 -0
- package/dist/option/index.js +2 -0
- package/dist/option/root/option-root.d.ts +194 -0
- package/dist/option/root/option-root.js +247 -0
- package/dist/outline/index.d.ts +1 -0
- package/dist/outline/index.js +1 -0
- package/dist/outline/root/outline-root.d.ts +237 -0
- package/dist/outline/root/outline-root.js +519 -0
- package/dist/pagination/index.d.ts +3 -0
- package/dist/pagination/index.js +3 -0
- package/dist/pagination/root/pagination-root.d.ts +390 -0
- package/dist/pagination/root/pagination-root.js +695 -0
- package/dist/pagination/size/pagination-size.d.ts +127 -0
- package/dist/pagination/size/pagination-size.js +232 -0
- package/dist/pagination/summary/pagination-summary.d.ts +90 -0
- package/dist/pagination/summary/pagination-summary.js +145 -0
- package/dist/pin-input/index.d.ts +1 -0
- package/dist/pin-input/index.js +1 -0
- package/dist/pin-input/root/pin-input-root.d.ts +292 -0
- package/dist/pin-input/root/pin-input-root.js +553 -0
- package/dist/popover/index.d.ts +1 -0
- package/dist/popover/index.js +1 -0
- package/dist/popover/root/popover-root.d.ts +108 -0
- package/dist/popover/root/popover-root.js +231 -0
- package/dist/progress/index.d.ts +1 -0
- package/dist/progress/index.js +1 -0
- package/dist/progress/root/progress-root.d.ts +125 -0
- package/dist/progress/root/progress-root.js +212 -0
- package/dist/qr-code/index.d.ts +1 -0
- package/dist/qr-code/index.js +1 -0
- package/dist/qr-code/root/qr-code-root.d.ts +93 -0
- package/dist/qr-code/root/qr-code-root.js +233 -0
- package/dist/quote/index.d.ts +1 -0
- package/dist/quote/index.js +1 -0
- package/dist/quote/root/quote-root.d.ts +36 -0
- package/dist/quote/root/quote-root.js +50 -0
- package/dist/radio/group/radio-group.d.ts +84 -0
- package/dist/radio/group/radio-group.js +170 -0
- package/dist/radio/index.d.ts +2 -0
- package/dist/radio/index.js +2 -0
- package/dist/radio/root/radio-root.d.ts +102 -0
- package/dist/radio/root/radio-root.js +151 -0
- package/dist/rating/index.d.ts +1 -0
- package/dist/rating/index.js +1 -0
- package/dist/rating/root/rating-root.d.ts +242 -0
- package/dist/rating/root/rating-root.js +484 -0
- package/dist/scroll-area/index.d.ts +1 -0
- package/dist/scroll-area/index.js +1 -0
- package/dist/scroll-area/root/scroll-area-root.d.ts +96 -0
- package/dist/scroll-area/root/scroll-area-root.js +215 -0
- package/dist/select/index.d.ts +1 -0
- package/dist/select/index.js +1 -0
- package/dist/select/root/select-root.d.ts +170 -0
- package/dist/select/root/select-root.js +419 -0
- package/dist/skeleton/index.d.ts +1 -0
- package/dist/skeleton/index.js +1 -0
- package/dist/skeleton/root/skeleton-root.d.ts +31 -0
- package/dist/skeleton/root/skeleton-root.js +42 -0
- package/dist/slider/index.d.ts +1 -0
- package/dist/slider/index.js +1 -0
- package/dist/slider/root/slider-root.d.ts +235 -0
- package/dist/slider/root/slider-root.js +488 -0
- package/dist/sparkline/index.d.ts +1 -0
- package/dist/sparkline/index.js +1 -0
- package/dist/sparkline/root/sparkline-root.d.ts +147 -0
- package/dist/sparkline/root/sparkline-root.js +278 -0
- package/dist/speed-dial/index.d.ts +2 -0
- package/dist/speed-dial/index.js +2 -0
- package/dist/speed-dial/item/speed-dial-item.d.ts +71 -0
- package/dist/speed-dial/item/speed-dial-item.js +113 -0
- package/dist/speed-dial/root/speed-dial-root.d.ts +122 -0
- package/dist/speed-dial/root/speed-dial-root.js +251 -0
- package/dist/splitter/index.d.ts +1 -0
- package/dist/splitter/index.js +1 -0
- package/dist/splitter/root/splitter-root.d.ts +491 -0
- package/dist/splitter/root/splitter-root.js +1030 -0
- package/dist/stat/group/stat-group.d.ts +30 -0
- package/dist/stat/group/stat-group.js +47 -0
- package/dist/stat/index.d.ts +2 -0
- package/dist/stat/index.js +2 -0
- package/dist/stat/root/stat-root.d.ts +62 -0
- package/dist/stat/root/stat-root.js +51 -0
- package/dist/steps/index.d.ts +2 -0
- package/dist/steps/index.js +2 -0
- package/dist/steps/root/steps-root.d.ts +110 -0
- package/dist/steps/root/steps-root.js +130 -0
- package/dist/steps/step/step.d.ts +139 -0
- package/dist/steps/step/step.js +215 -0
- package/dist/switch/index.d.ts +1 -0
- package/dist/switch/index.js +1 -0
- package/dist/switch/root/switch-root.d.ts +74 -0
- package/dist/switch/root/switch-root.js +153 -0
- package/dist/table/cell/table-cell.d.ts +34 -0
- package/dist/table/cell/table-cell.js +52 -0
- package/dist/table/column/table-column.d.ts +165 -0
- package/dist/table/column/table-column.js +222 -0
- package/dist/table/index.d.ts +4 -0
- package/dist/table/index.js +4 -0
- package/dist/table/root/table-root.d.ts +98 -0
- package/dist/table/root/table-root.js +161 -0
- package/dist/table/row/table-row.d.ts +27 -0
- package/dist/table/row/table-row.js +42 -0
- package/dist/tabs/index.d.ts +3 -0
- package/dist/tabs/index.js +3 -0
- package/dist/tabs/panel/tab-panel.d.ts +67 -0
- package/dist/tabs/panel/tab-panel.js +98 -0
- package/dist/tabs/root/tabs-root.d.ts +123 -0
- package/dist/tabs/root/tabs-root.js +217 -0
- package/dist/tabs/tab/tab.d.ts +64 -0
- package/dist/tabs/tab/tab.js +116 -0
- package/dist/tag/index.d.ts +1 -0
- package/dist/tag/index.js +1 -0
- package/dist/tag/root/tag-root.d.ts +41 -0
- package/dist/tag/root/tag-root.js +67 -0
- package/dist/textarea/index.d.ts +1 -0
- package/dist/textarea/index.js +1 -0
- package/dist/textarea/root/textarea-root.d.ts +215 -0
- package/dist/textarea/root/textarea-root.js +380 -0
- package/dist/time-input/index.d.ts +1 -0
- package/dist/time-input/index.js +1 -0
- package/dist/time-input/root/time-input-root.d.ts +322 -0
- package/dist/time-input/root/time-input-root.js +661 -0
- package/dist/time-picker/index.d.ts +1 -0
- package/dist/time-picker/index.js +1 -0
- package/dist/time-picker/root/time-picker-root.d.ts +380 -0
- package/dist/time-picker/root/time-picker-root.js +669 -0
- package/dist/timeline/index.d.ts +2 -0
- package/dist/timeline/index.js +2 -0
- package/dist/timeline/item/timeline-item.d.ts +81 -0
- package/dist/timeline/item/timeline-item.js +128 -0
- package/dist/timeline/root/timeline-root.d.ts +52 -0
- package/dist/timeline/root/timeline-root.js +72 -0
- package/dist/toast/index.d.ts +2 -0
- package/dist/toast/index.js +2 -0
- package/dist/toast/item/toast-item.d.ts +183 -0
- package/dist/toast/item/toast-item.js +345 -0
- package/dist/toast/root/toast-root.d.ts +72 -0
- package/dist/toast/root/toast-root.js +87 -0
- package/dist/toggle/group/toggle-group.d.ts +140 -0
- package/dist/toggle/group/toggle-group.js +278 -0
- package/dist/toggle/index.d.ts +2 -0
- package/dist/toggle/index.js +2 -0
- package/dist/toggle/root/toggle-root.d.ts +99 -0
- package/dist/toggle/root/toggle-root.js +146 -0
- package/dist/toolbar/index.d.ts +1 -0
- package/dist/toolbar/index.js +1 -0
- package/dist/toolbar/root/toolbar-root.d.ts +105 -0
- package/dist/toolbar/root/toolbar-root.js +260 -0
- package/dist/tooltip/index.d.ts +1 -0
- package/dist/tooltip/index.js +1 -0
- package/dist/tooltip/root/tooltip-root.d.ts +388 -0
- package/dist/tooltip/root/tooltip-root.js +707 -0
- package/dist/tour/index.d.ts +2 -0
- package/dist/tour/index.js +2 -0
- package/dist/tour/root/tour-root.d.ts +161 -0
- package/dist/tour/root/tour-root.js +351 -0
- package/dist/tour/stop/tour-stop.d.ts +131 -0
- package/dist/tour/stop/tour-stop.js +249 -0
- package/dist/tree/index.d.ts +2 -0
- package/dist/tree/index.js +2 -0
- package/dist/tree/item/tree-item.d.ts +208 -0
- package/dist/tree/item/tree-item.js +381 -0
- package/dist/tree/root/tree-root.d.ts +88 -0
- package/dist/tree/root/tree-root.js +287 -0
- package/dist/trend/index.d.ts +1 -0
- package/dist/trend/index.js +1 -0
- package/dist/trend/root/trend-root.d.ts +67 -0
- package/dist/trend/root/trend-root.js +106 -0
- package/dist/video/index.d.ts +1 -0
- package/dist/video/index.js +1 -0
- package/dist/video/root/video-root.d.ts +711 -0
- package/dist/video/root/video-root.js +1821 -0
- package/dist/video-playlist/index.d.ts +3 -0
- package/dist/video-playlist/index.js +3 -0
- package/dist/video-playlist/item/video-playlist-item.d.ts +101 -0
- package/dist/video-playlist/item/video-playlist-item.js +162 -0
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +121 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +237 -0
- package/dist/video-playlist/root/video-playlist-root.d.ts +108 -0
- package/dist/video-playlist/root/video-playlist-root.js +218 -0
- package/dist/virtual-list/index.d.ts +1 -0
- package/dist/virtual-list/index.js +1 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +121 -0
- package/dist/virtual-list/root/virtual-list-root.js +221 -0
- package/jsx.d.ts +49767 -0
- package/package.json +77 -0
- package/svelte.d.ts +129 -0
- package/vue.d.ts +9242 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { type Curve, HelixElement, type Series } from '@fusion.dev/helix-core';
|
|
2
|
+
import { nothing, type TemplateResult } from 'lit';
|
|
3
|
+
import '../../tooltip/index.js';
|
|
4
|
+
declare const HelixHeadlessLineChart_base: typeof HelixElement & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinChartSourceInterface);
|
|
5
|
+
/**
|
|
6
|
+
* @summary A series over time as a line, read from a table.
|
|
7
|
+
*
|
|
8
|
+
* @description
|
|
9
|
+
* The chart for a shape rather than for a quantity, which is what decides the
|
|
10
|
+
* one thing a bar chart is not allowed to do.
|
|
11
|
+
*
|
|
12
|
+
* **It measures from its own range and not from zero, deliberately.** `BarChart`
|
|
13
|
+
* refuses that switch because a bar's length *is* its value, so a baseline
|
|
14
|
+
* anywhere else makes the lengths proportional to nothing. A line claims no
|
|
15
|
+
* such thing: it says where the readings went, and forcing zero into the range
|
|
16
|
+
* of a series that moves between 980 and 1020 flattens the entire shape into a
|
|
17
|
+
* rule across the top of the box. The two rules are opposite because the two
|
|
18
|
+
* charts answer opposite questions, and `zero` is here for the case where the
|
|
19
|
+
* distance from nothing is the point.
|
|
20
|
+
*
|
|
21
|
+
* **One scale across every series**, the same as the bar chart, because two
|
|
22
|
+
* series drawn to different scales are two charts sharing a picture.
|
|
23
|
+
*
|
|
24
|
+
* **The labels are HTML beside the drawing rather than `<text>` inside it**, for
|
|
25
|
+
* the reason `BarChart` records: an `<svg>` that fills its box scales its type
|
|
26
|
+
* with everything else, the same `font-size` arriving at 10px in a narrow chart
|
|
27
|
+
* and 43px in a wide one, and there is no non-scaling-font to answer it the way
|
|
28
|
+
* `vector-effect` answers strokes.
|
|
29
|
+
*
|
|
30
|
+
* The table is the accessible representation and this drawing is `aria-hidden`.
|
|
31
|
+
* A reader who wants the numbers gets the numbers, not a described picture.
|
|
32
|
+
*
|
|
33
|
+
* @since 0.1.0
|
|
34
|
+
* @status experimental
|
|
35
|
+
* @category charts
|
|
36
|
+
* @aliases Time Series, Trend Chart, Multi-line Chart
|
|
37
|
+
* @documentation https://helix.fusion.dev/components/line-chart
|
|
38
|
+
*
|
|
39
|
+
* @csspart area - The wash under one line, where `area` is set.
|
|
40
|
+
* @csspart band - The slot the pointer is resting in.
|
|
41
|
+
* @csspart baseline - The rule at zero, where zero is inside the range.
|
|
42
|
+
* @csspart gridline - One rule across the plot, under `gridlines`.
|
|
43
|
+
* @csspart guide - A rule down the reading a pointer is resting on.
|
|
44
|
+
* @csspart label - One reading's name.
|
|
45
|
+
* @csspart labels - The row of reading names.
|
|
46
|
+
* @csspart line - One series.
|
|
47
|
+
* @csspart mark - The invisible point the tooltip is anchored to.
|
|
48
|
+
* @csspart plot - The drawing.
|
|
49
|
+
* @csspart svg - The drawing surface the lines and areas sit on.
|
|
50
|
+
* @csspart terminus - The mark on one series' last reading.
|
|
51
|
+
* @csspart tooltip - The bubble, forwarded from `Tooltip`.
|
|
52
|
+
* @csspart tooltip-anchor - The `Tooltip` element itself.
|
|
53
|
+
* @csspart tooltip-cell - One column's name and value inside the tooltip.
|
|
54
|
+
* @csspart tooltip-label - The reading's own name inside the tooltip.
|
|
55
|
+
* @csspart tooltip-name - A column's name inside the tooltip.
|
|
56
|
+
* @csspart tooltip-value - A column's value inside the tooltip.
|
|
57
|
+
*/
|
|
58
|
+
export declare class HelixHeadlessLineChart extends HelixHeadlessLineChart_base {
|
|
59
|
+
/**
|
|
60
|
+
* Whether a wash is drawn under each line.
|
|
61
|
+
*
|
|
62
|
+
* Absent is lines alone, which is what suits more than one series: washes
|
|
63
|
+
* stack and the lower ones are read through the upper. One series over a
|
|
64
|
+
* ground it should feel like a quantity against is the case for this.
|
|
65
|
+
*/
|
|
66
|
+
area: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* How the line gets from one reading to the next.
|
|
69
|
+
*
|
|
70
|
+
* **`smooth` is the resting curve.** *Changed 21 Aug 2026, reversing the
|
|
71
|
+
* argument this comment used to make.* Joining the readings claims nothing in
|
|
72
|
+
* between, which is true and is why `straight` still exists: a straight
|
|
73
|
+
* segment asserts nothing about the values between two readings, and a curve
|
|
74
|
+
* invents them. What settles it the other way is that the invention is
|
|
75
|
+
* bounded. The interpolation is monotone cubic, so it never leaves the band
|
|
76
|
+
* the data sets and never introduces a peak or a trough the series does not
|
|
77
|
+
* have, and within that bound the smoothed line is the easier one to follow
|
|
78
|
+
* across a long series. `straight` becomes the deliberate claim.
|
|
79
|
+
*
|
|
80
|
+
* **Still absent rather than defaulted on the property**, because a
|
|
81
|
+
* reflecting property with a default writes its attribute onto every host
|
|
82
|
+
* anybody renders, including the ones nobody configured.
|
|
83
|
+
* `line-chart-root.ssr.spec.ts` asserts the host carries only what the
|
|
84
|
+
* consumer wrote, and caught that the first time. The default therefore lives
|
|
85
|
+
* where the path is built, as `curve ?? 'smooth'`.
|
|
86
|
+
*
|
|
87
|
+
* `step` claims the opposite of both, that a reading holds until the next.
|
|
88
|
+
*/
|
|
89
|
+
curve?: Curve;
|
|
90
|
+
/**
|
|
91
|
+
* Which rules are drawn across the plot, if any.
|
|
92
|
+
*
|
|
93
|
+
* Absent draws none, which is the honest default rather than a timid one: a
|
|
94
|
+
* chart in a card and a chart beside a figure are read as a shape, and a grid
|
|
95
|
+
* over one is furniture around a drawing nobody is measuring.
|
|
96
|
+
*
|
|
97
|
+
* `value` rules the axis the readings are *measured* on, at the levels
|
|
98
|
+
* `ticks` picks, which are round numbers anchored to the number line rather
|
|
99
|
+
* than to where the data starts, so two charts over different ranges rule at
|
|
100
|
+
* the same levels. `category` rules the axis they are *arranged* on, one
|
|
101
|
+
* through each reading, which is what lets a point be traced down to its
|
|
102
|
+
* label across a wide chart. `both` draws both.
|
|
103
|
+
*
|
|
104
|
+
* **A bare `gridlines` means `value`**, and so does anything unrecognised.
|
|
105
|
+
* Written out, the attribute a consumer reaches for first should be the grid
|
|
106
|
+
* they meant, and a typo should fall back to the useful half rather than to
|
|
107
|
+
* nothing at all: an unrecognised value that draws no rules is
|
|
108
|
+
* indistinguishable from the attribute being absent, which is the one thing
|
|
109
|
+
* a reader cannot debug.
|
|
110
|
+
*
|
|
111
|
+
* Furniture rather than data, so the rules are inside the `aria-hidden` plot
|
|
112
|
+
* and reach no reader through the table.
|
|
113
|
+
*/
|
|
114
|
+
gridlines?: 'both' | 'category' | 'value';
|
|
115
|
+
/** Whether the levels are ruled, which is every value but `category`. */
|
|
116
|
+
protected get rulesValue(): boolean;
|
|
117
|
+
/** Whether each reading is ruled, which only two values ask for. */
|
|
118
|
+
protected get rulesCategory(): boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Whether zero is forced into the range.
|
|
121
|
+
*
|
|
122
|
+
* Absent measures from the data's own extent, which is what a line is for.
|
|
123
|
+
* Set it where the distance from nothing is the point rather than the shape,
|
|
124
|
+
* and accept that a series which never approaches zero becomes a flat rule
|
|
125
|
+
* near the top of the box.
|
|
126
|
+
*/
|
|
127
|
+
zero: boolean;
|
|
128
|
+
/** The domain every series is drawn against, which the tooltip also needs. */
|
|
129
|
+
private range;
|
|
130
|
+
/**
|
|
131
|
+
* The shape of the mark on each series' last reading.
|
|
132
|
+
*
|
|
133
|
+
* Absent is a dot, and absent rather than defaulted because a reflecting
|
|
134
|
+
* property with a default writes its attribute onto a host the consumer
|
|
135
|
+
* rendered, which React reports as a hydration mismatch.
|
|
136
|
+
*
|
|
137
|
+
* **One per series, in a column at the right edge**, because every series here
|
|
138
|
+
* shares an x-axis and therefore ends at the same reading. That column is the
|
|
139
|
+
* useful thing: it is where a reader looks for "and what is it now", which is
|
|
140
|
+
* the question a sparkline's single mark answers too.
|
|
141
|
+
*
|
|
142
|
+
* `none` lets the lines stop on their own, which suits a chart read for its
|
|
143
|
+
* shape rather than for where it finished. The shapes come from
|
|
144
|
+
* `helix/styled/src/shared/chart/terminus.css`, the same sheet `Sparkline` takes, so
|
|
145
|
+
* the set is identical wherever one appears.
|
|
146
|
+
*
|
|
147
|
+
* `ring` is the one that asks something of the drawing. It leaves a hole and a
|
|
148
|
+
* line ends at the reading, which is the hole's center, so the `<svg>` is
|
|
149
|
+
* masked with one disc per series and every stroke stops at its own ring's
|
|
150
|
+
* inner edge. `mask-composite: intersect` is what makes N holes out of N
|
|
151
|
+
* layers; a single `mask-image` would only ever cut the last one.
|
|
152
|
+
*/
|
|
153
|
+
terminus?: 'none' | 'ring' | 'square' | 'triangle';
|
|
154
|
+
/**
|
|
155
|
+
* Where each series ends, as percentages of the drawing's own box.
|
|
156
|
+
*
|
|
157
|
+
* Percentages rather than user units, for the reason the mark is a `<span>`
|
|
158
|
+
* rather than a `<circle>`: `preserveAspectRatio="none"` stretches the
|
|
159
|
+
* coordinate space, so a length in there means two different things depending
|
|
160
|
+
* on how wide the consumer made the chart. The host's box stretches nothing.
|
|
161
|
+
*/
|
|
162
|
+
private ends;
|
|
163
|
+
protected render(): TemplateResult;
|
|
164
|
+
/**
|
|
165
|
+
* The lines themselves, behind a seam the styled tier can move.
|
|
166
|
+
*
|
|
167
|
+
* `aria-hidden`, because the table it was read from is the readable version
|
|
168
|
+
* and a screen reader hearing both hears the same numbers twice.
|
|
169
|
+
*/
|
|
170
|
+
protected renderPlot(series: Series[], x: (value: number) => number, y: (value: number) => number, domain: [number, number]): TemplateResult;
|
|
171
|
+
/**
|
|
172
|
+
* The grid, behind everything, or nothing at all.
|
|
173
|
+
*
|
|
174
|
+
* Drawn first so a series is never cut by a rule, and before the baseline so
|
|
175
|
+
* that where the two coincide the baseline wins: zero is a fact about the
|
|
176
|
+
* data and a gridline is a ruler, and the reader should see the fact.
|
|
177
|
+
*/
|
|
178
|
+
protected renderGridlines(x: (value: number) => number, y: (value: number) => number, domain: [number, number], count: number): TemplateResult | typeof nothing;
|
|
179
|
+
/**
|
|
180
|
+
* The slot the pointer is resting in, drawn behind the drawing.
|
|
181
|
+
*
|
|
182
|
+
* A band and not a second rule. The guide says exactly where the reading is
|
|
183
|
+
* and the band says which share of the width belongs to it, which is what a
|
|
184
|
+
* reader is actually pointing at: the catchment is a slot wide, so a pointer
|
|
185
|
+
* a few pixels off the line is still asking about that reading, and without
|
|
186
|
+
* the band nothing on screen says so.
|
|
187
|
+
*
|
|
188
|
+
* The same slot arithmetic the pointer controller resolves with, so the lit
|
|
189
|
+
* region and the region that answers are the same region by construction
|
|
190
|
+
* rather than by two files agreeing.
|
|
191
|
+
*/
|
|
192
|
+
protected renderBand(count: number): TemplateResult | typeof nothing;
|
|
193
|
+
/**
|
|
194
|
+
* A rule down the reading the tooltip is about.
|
|
195
|
+
*
|
|
196
|
+
* Without it the tooltip is a box of numbers floating over a drawing, and a
|
|
197
|
+
* reader has to match its heading against the row of names to find out which
|
|
198
|
+
* column it means. The rule is the whole of what connects the two, and it
|
|
199
|
+
* matters most on a line, where there is no marker under the pointer to
|
|
200
|
+
* stand in for one.
|
|
201
|
+
*
|
|
202
|
+
* Drawn before the series so a line is never cut by it.
|
|
203
|
+
*/
|
|
204
|
+
protected renderGuide(x: (value: number) => number): TemplateResult | typeof nothing;
|
|
205
|
+
/**
|
|
206
|
+
* The marks, as elements beside the drawing rather than shapes inside it.
|
|
207
|
+
*
|
|
208
|
+
* A seam of its own, so a tier or a consumer's subclass can draw them
|
|
209
|
+
* differently without reimplementing the plot.
|
|
210
|
+
*/
|
|
211
|
+
protected renderTermini(ends: Array<{
|
|
212
|
+
index: number;
|
|
213
|
+
x: number;
|
|
214
|
+
y: number;
|
|
215
|
+
}>): TemplateResult | typeof nothing;
|
|
216
|
+
/** One series, its wash first so the line is drawn over its own fill. */
|
|
217
|
+
protected renderSeries(one: Series, depth: number, x: (value: number) => number, y: (value: number) => number): TemplateResult;
|
|
218
|
+
/**
|
|
219
|
+
* The reading names, as HTML beside the drawing rather than inside it.
|
|
220
|
+
*
|
|
221
|
+
* Inside, they would scale with the box, for the reason the class doc gives.
|
|
222
|
+
*/
|
|
223
|
+
protected renderLabels(readings: string[]): TemplateResult;
|
|
224
|
+
/**
|
|
225
|
+
* What a pointer resting on a reading shows.
|
|
226
|
+
*
|
|
227
|
+
* A seam over `drawTooltip`, which holds the markup every chart shares. The
|
|
228
|
+
* usual reason to override is arrangement: every cell of the row is already
|
|
229
|
+
* there, including the columns nothing was plotted from.
|
|
230
|
+
*/
|
|
231
|
+
protected renderTooltip(): TemplateResult | typeof nothing;
|
|
232
|
+
}
|
|
233
|
+
declare global {
|
|
234
|
+
interface HTMLElementTagNameMap {
|
|
235
|
+
'helix-headless-line-chart': HelixHeadlessLineChart;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
export {};
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { customElement, drawTooltip, extent, HelixElement, linear, linePath, MixinChartSource, seriesIndex, ticks, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { html, nothing, svg } from 'lit';
|
|
9
|
+
import { property } from 'lit/decorators.js';
|
|
10
|
+
import '../../tooltip/index.js';
|
|
11
|
+
/** The drawing's own coordinates. */
|
|
12
|
+
const WIDTH = 100;
|
|
13
|
+
const HEIGHT = 100;
|
|
14
|
+
/**
|
|
15
|
+
* @summary A series over time as a line, read from a table.
|
|
16
|
+
*
|
|
17
|
+
* @description
|
|
18
|
+
* The chart for a shape rather than for a quantity, which is what decides the
|
|
19
|
+
* one thing a bar chart is not allowed to do.
|
|
20
|
+
*
|
|
21
|
+
* **It measures from its own range and not from zero, deliberately.** `BarChart`
|
|
22
|
+
* refuses that switch because a bar's length *is* its value, so a baseline
|
|
23
|
+
* anywhere else makes the lengths proportional to nothing. A line claims no
|
|
24
|
+
* such thing: it says where the readings went, and forcing zero into the range
|
|
25
|
+
* of a series that moves between 980 and 1020 flattens the entire shape into a
|
|
26
|
+
* rule across the top of the box. The two rules are opposite because the two
|
|
27
|
+
* charts answer opposite questions, and `zero` is here for the case where the
|
|
28
|
+
* distance from nothing is the point.
|
|
29
|
+
*
|
|
30
|
+
* **One scale across every series**, the same as the bar chart, because two
|
|
31
|
+
* series drawn to different scales are two charts sharing a picture.
|
|
32
|
+
*
|
|
33
|
+
* **The labels are HTML beside the drawing rather than `<text>` inside it**, for
|
|
34
|
+
* the reason `BarChart` records: an `<svg>` that fills its box scales its type
|
|
35
|
+
* with everything else, the same `font-size` arriving at 10px in a narrow chart
|
|
36
|
+
* and 43px in a wide one, and there is no non-scaling-font to answer it the way
|
|
37
|
+
* `vector-effect` answers strokes.
|
|
38
|
+
*
|
|
39
|
+
* The table is the accessible representation and this drawing is `aria-hidden`.
|
|
40
|
+
* A reader who wants the numbers gets the numbers, not a described picture.
|
|
41
|
+
*
|
|
42
|
+
* @since 0.1.0
|
|
43
|
+
* @status experimental
|
|
44
|
+
* @category charts
|
|
45
|
+
* @aliases Time Series, Trend Chart, Multi-line Chart
|
|
46
|
+
* @documentation https://helix.fusion.dev/components/line-chart
|
|
47
|
+
*
|
|
48
|
+
* @csspart area - The wash under one line, where `area` is set.
|
|
49
|
+
* @csspart band - The slot the pointer is resting in.
|
|
50
|
+
* @csspart baseline - The rule at zero, where zero is inside the range.
|
|
51
|
+
* @csspart gridline - One rule across the plot, under `gridlines`.
|
|
52
|
+
* @csspart guide - A rule down the reading a pointer is resting on.
|
|
53
|
+
* @csspart label - One reading's name.
|
|
54
|
+
* @csspart labels - The row of reading names.
|
|
55
|
+
* @csspart line - One series.
|
|
56
|
+
* @csspart mark - The invisible point the tooltip is anchored to.
|
|
57
|
+
* @csspart plot - The drawing.
|
|
58
|
+
* @csspart svg - The drawing surface the lines and areas sit on.
|
|
59
|
+
* @csspart terminus - The mark on one series' last reading.
|
|
60
|
+
* @csspart tooltip - The bubble, forwarded from `Tooltip`.
|
|
61
|
+
* @csspart tooltip-anchor - The `Tooltip` element itself.
|
|
62
|
+
* @csspart tooltip-cell - One column's name and value inside the tooltip.
|
|
63
|
+
* @csspart tooltip-label - The reading's own name inside the tooltip.
|
|
64
|
+
* @csspart tooltip-name - A column's name inside the tooltip.
|
|
65
|
+
* @csspart tooltip-value - A column's value inside the tooltip.
|
|
66
|
+
*/
|
|
67
|
+
let HelixHeadlessLineChart = class HelixHeadlessLineChart extends MixinChartSource(HelixElement) {
|
|
68
|
+
constructor() {
|
|
69
|
+
super(...arguments);
|
|
70
|
+
/**
|
|
71
|
+
* Whether a wash is drawn under each line.
|
|
72
|
+
*
|
|
73
|
+
* Absent is lines alone, which is what suits more than one series: washes
|
|
74
|
+
* stack and the lower ones are read through the upper. One series over a
|
|
75
|
+
* ground it should feel like a quantity against is the case for this.
|
|
76
|
+
*/
|
|
77
|
+
this.area = false;
|
|
78
|
+
/**
|
|
79
|
+
* Whether zero is forced into the range.
|
|
80
|
+
*
|
|
81
|
+
* Absent measures from the data's own extent, which is what a line is for.
|
|
82
|
+
* Set it where the distance from nothing is the point rather than the shape,
|
|
83
|
+
* and accept that a series which never approaches zero becomes a flat rule
|
|
84
|
+
* near the top of the box.
|
|
85
|
+
*/
|
|
86
|
+
this.zero = false;
|
|
87
|
+
}
|
|
88
|
+
/** Whether the levels are ruled, which is every value but `category`. */
|
|
89
|
+
get rulesValue() {
|
|
90
|
+
return this.gridlines !== undefined && this.gridlines !== 'category';
|
|
91
|
+
}
|
|
92
|
+
/** Whether each reading is ruled, which only two values ask for. */
|
|
93
|
+
get rulesCategory() {
|
|
94
|
+
return this.gridlines === 'both' || this.gridlines === 'category';
|
|
95
|
+
}
|
|
96
|
+
/** The domain every series is drawn against, which the tooltip also needs. */
|
|
97
|
+
range(series) {
|
|
98
|
+
const values = series.flatMap((one) => one.points.map((point) => point.value));
|
|
99
|
+
const [low, high] = extent(values.length > 0 ? values : [0]);
|
|
100
|
+
return this.zero ? [Math.min(0, low), Math.max(0, high)] : [low, high];
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Where each series ends, as percentages of the drawing's own box.
|
|
104
|
+
*
|
|
105
|
+
* Percentages rather than user units, for the reason the mark is a `<span>`
|
|
106
|
+
* rather than a `<circle>`: `preserveAspectRatio="none"` stretches the
|
|
107
|
+
* coordinate space, so a length in there means two different things depending
|
|
108
|
+
* on how wide the consumer made the chart. The host's box stretches nothing.
|
|
109
|
+
*/
|
|
110
|
+
ends(series, x, y) {
|
|
111
|
+
return series.flatMap((one, depth) => {
|
|
112
|
+
const last = one.points.at(-1);
|
|
113
|
+
/* A single reading is a point rather than a line, and a mark on the end of
|
|
114
|
+
something with no length is a mark on nothing. */
|
|
115
|
+
if (!last || one.points.length < 2) {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
return [
|
|
119
|
+
{
|
|
120
|
+
index: seriesIndex(depth),
|
|
121
|
+
x: (x(one.points.length - 1) / WIDTH) * 100,
|
|
122
|
+
y: (y(last.value) / HEIGHT) * 100,
|
|
123
|
+
},
|
|
124
|
+
];
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
render() {
|
|
128
|
+
const series = this.series;
|
|
129
|
+
const readings = series[0]?.points.map((point) => point.label) ?? [];
|
|
130
|
+
if (readings.length === 0) {
|
|
131
|
+
return html `<div id="helix-chart-plot" part="plot"></div>`;
|
|
132
|
+
}
|
|
133
|
+
const domain = this.range(series);
|
|
134
|
+
const y = linear(domain, [HEIGHT, 0]);
|
|
135
|
+
/* **A reading sits in the middle of its own slot, not at the edge of the
|
|
136
|
+
box**, which is what makes the names underneath line up with it.
|
|
137
|
+
*
|
|
138
|
+
* Spanning 0 to 100 is the obvious version and is what this did first. The
|
|
139
|
+
* labels are a grid of equal columns, the same row the bar chart uses, so
|
|
140
|
+
* each name is centered in its share of the width while the readings sat at
|
|
141
|
+
* the gridlines between those shares: measured, the first name centered at a
|
|
142
|
+
* twelfth of the width with its point at zero. Every label was off by half
|
|
143
|
+
* a slot and the error grew toward the middle.
|
|
144
|
+
*
|
|
145
|
+
* Insetting by half a slot also means a line chart and a bar chart drawn
|
|
146
|
+
* from the same table stack, which is the arrangement anybody comparing a
|
|
147
|
+
* total to its parts wants. The cost is that the line stops short of both
|
|
148
|
+
* edges, and that is the smaller thing to give up. */
|
|
149
|
+
const slot = WIDTH / readings.length;
|
|
150
|
+
const x = linear([0, Math.max(readings.length - 1, 1)], [slot / 2, WIDTH - slot / 2]);
|
|
151
|
+
return html `${this.renderPlot(series, x, y, domain)} ${this.renderLabels(readings)}`;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* The lines themselves, behind a seam the styled tier can move.
|
|
155
|
+
*
|
|
156
|
+
* `aria-hidden`, because the table it was read from is the readable version
|
|
157
|
+
* and a screen reader hearing both hears the same numbers twice.
|
|
158
|
+
*/
|
|
159
|
+
renderPlot(series, x, y, domain) {
|
|
160
|
+
/* Drawn only where zero is inside the range. A rule at the foot of a chart
|
|
161
|
+
whose lowest reading is 980 is not the zero line, it is the bottom of the
|
|
162
|
+
box wearing the zero line's clothes, and a reader takes it for one. */
|
|
163
|
+
const floor = domain[0] <= 0 && domain[1] >= 0 ? y(0) : undefined;
|
|
164
|
+
const ends = this.terminus === 'none' ? [] : this.ends(series, x, y);
|
|
165
|
+
/* Built here rather than in the sheet, because a stylesheet cannot count
|
|
166
|
+
series and a mask needs one layer per hole. Each layer is transparent
|
|
167
|
+
inside its own ring and opaque everywhere else, so intersecting them
|
|
168
|
+
removes the union of the holes and nothing besides. */
|
|
169
|
+
const holes = this.terminus === 'ring' && ends.length > 0
|
|
170
|
+
? ends
|
|
171
|
+
.map((end) => `radial-gradient(circle at ${end.x}% ${end.y}%, #0000 calc(var(--_chart-terminus-inner) - 0.5px), #000 var(--_chart-terminus-inner))`)
|
|
172
|
+
.join(', ')
|
|
173
|
+
: undefined;
|
|
174
|
+
return html `<div
|
|
175
|
+
aria-hidden="true"
|
|
176
|
+
id="helix-chart-plot"
|
|
177
|
+
part="plot"
|
|
178
|
+
style=${holes ? `--_line-chart-holes: ${holes}` : nothing}
|
|
179
|
+
>
|
|
180
|
+
<svg part="svg"
|
|
181
|
+
preserveAspectRatio="none"
|
|
182
|
+
viewBox="0 0 ${WIDTH} ${HEIGHT}"
|
|
183
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
184
|
+
>
|
|
185
|
+
${this.renderGridlines(x, y, domain, series[0]?.points.length ?? 0)}
|
|
186
|
+
${floor === undefined
|
|
187
|
+
? nothing
|
|
188
|
+
: svg `<line part="baseline" x1="0" x2=${WIDTH} y1=${floor} y2=${floor} />`}
|
|
189
|
+
${this.renderBand(series[0]?.points.length ?? 0)}
|
|
190
|
+
${this.renderGuide(x)}
|
|
191
|
+
${series.map((one, depth) => this.renderSeries(one, depth, x, y))}
|
|
192
|
+
</svg>
|
|
193
|
+
${this.renderTermini(ends)}
|
|
194
|
+
${this.renderTooltip()}
|
|
195
|
+
</div>`;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* The grid, behind everything, or nothing at all.
|
|
199
|
+
*
|
|
200
|
+
* Drawn first so a series is never cut by a rule, and before the baseline so
|
|
201
|
+
* that where the two coincide the baseline wins: zero is a fact about the
|
|
202
|
+
* data and a gridline is a ruler, and the reader should see the fact.
|
|
203
|
+
*/
|
|
204
|
+
renderGridlines(x, y, domain, count) {
|
|
205
|
+
if (this.gridlines === undefined) {
|
|
206
|
+
return nothing;
|
|
207
|
+
}
|
|
208
|
+
/* Through each reading rather than between them. A rule on the boundary
|
|
209
|
+
divides two catchments, which is a fact about the pointer; a rule on the
|
|
210
|
+
reading is the line a reader traces down to the label, which is what a
|
|
211
|
+
category grid is for. The readings sit at slot centres, so the two are
|
|
212
|
+
half a slot apart and only one of them lands under a point. */
|
|
213
|
+
const down = this.rulesCategory
|
|
214
|
+
? Array.from({ length: count }, (_, index) => svg `<line part="gridline" x1=${x(index)} x2=${x(index)} y1="0" y2=${HEIGHT} />`)
|
|
215
|
+
: [];
|
|
216
|
+
const across = this.rulesValue
|
|
217
|
+
? ticks(domain).map((level) => svg `<line part="gridline" x1="0" x2=${WIDTH} y1=${y(level)} y2=${y(level)} />`)
|
|
218
|
+
: [];
|
|
219
|
+
return svg `${down}${across}`;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* The slot the pointer is resting in, drawn behind the drawing.
|
|
223
|
+
*
|
|
224
|
+
* A band and not a second rule. The guide says exactly where the reading is
|
|
225
|
+
* and the band says which share of the width belongs to it, which is what a
|
|
226
|
+
* reader is actually pointing at: the catchment is a slot wide, so a pointer
|
|
227
|
+
* a few pixels off the line is still asking about that reading, and without
|
|
228
|
+
* the band nothing on screen says so.
|
|
229
|
+
*
|
|
230
|
+
* The same slot arithmetic the pointer controller resolves with, so the lit
|
|
231
|
+
* region and the region that answers are the same region by construction
|
|
232
|
+
* rather than by two files agreeing.
|
|
233
|
+
*/
|
|
234
|
+
renderBand(count) {
|
|
235
|
+
const at = this.pointer.at;
|
|
236
|
+
if (at < 0 || count === 0) {
|
|
237
|
+
return nothing;
|
|
238
|
+
}
|
|
239
|
+
const slot = WIDTH / count;
|
|
240
|
+
return svg `<rect height=${HEIGHT} part="band" width=${slot} x=${at * slot} y="0" />`;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* A rule down the reading the tooltip is about.
|
|
244
|
+
*
|
|
245
|
+
* Without it the tooltip is a box of numbers floating over a drawing, and a
|
|
246
|
+
* reader has to match its heading against the row of names to find out which
|
|
247
|
+
* column it means. The rule is the whole of what connects the two, and it
|
|
248
|
+
* matters most on a line, where there is no marker under the pointer to
|
|
249
|
+
* stand in for one.
|
|
250
|
+
*
|
|
251
|
+
* Drawn before the series so a line is never cut by it.
|
|
252
|
+
*/
|
|
253
|
+
renderGuide(x) {
|
|
254
|
+
const at = this.pointer.at;
|
|
255
|
+
if (at < 0) {
|
|
256
|
+
return nothing;
|
|
257
|
+
}
|
|
258
|
+
return svg `<line part="guide" x1=${x(at)} x2=${x(at)} y1="0" y2=${HEIGHT} />`;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* The marks, as elements beside the drawing rather than shapes inside it.
|
|
262
|
+
*
|
|
263
|
+
* A seam of its own, so a tier or a consumer's subclass can draw them
|
|
264
|
+
* differently without reimplementing the plot.
|
|
265
|
+
*/
|
|
266
|
+
renderTermini(ends) {
|
|
267
|
+
if (ends.length === 0) {
|
|
268
|
+
return nothing;
|
|
269
|
+
}
|
|
270
|
+
return html `${ends.map((end) => html `<span
|
|
271
|
+
aria-hidden="true"
|
|
272
|
+
part="terminus"
|
|
273
|
+
style=${`--chart-series: var(--chart-series-${end.index}); --chart-terminus-x: ${end.x}%; --chart-terminus-y: ${end.y}%`}
|
|
274
|
+
></span>`)}`;
|
|
275
|
+
}
|
|
276
|
+
/** One series, its wash first so the line is drawn over its own fill. */
|
|
277
|
+
renderSeries(one, depth, x, y) {
|
|
278
|
+
const points = one.points.map((point, index) => [x(index), y(point.value)]);
|
|
279
|
+
const path = linePath(points, this.curve ?? 'smooth');
|
|
280
|
+
if (path === '') {
|
|
281
|
+
return html `${nothing}`;
|
|
282
|
+
}
|
|
283
|
+
const index = seriesIndex(depth);
|
|
284
|
+
/* Closed along the floor of the box and back, which is what makes it
|
|
285
|
+
fillable: a `<path>` is filled between its own ends, so an open line
|
|
286
|
+
fills the region between the stroke and the straight line joining its
|
|
287
|
+
first point to its last. */
|
|
288
|
+
const first = points[0];
|
|
289
|
+
const last = points.at(-1);
|
|
290
|
+
const wash = `${path}L${last[0]},${HEIGHT}L${first[0]},${HEIGHT}Z`;
|
|
291
|
+
return svg `${this.area
|
|
292
|
+
? svg `<path
|
|
293
|
+
d=${wash}
|
|
294
|
+
data-series=${index}
|
|
295
|
+
part="area"
|
|
296
|
+
style="--chart-series: var(--chart-series-${index})"
|
|
297
|
+
/>`
|
|
298
|
+
: nothing}<path
|
|
299
|
+
d=${path}
|
|
300
|
+
data-series=${index}
|
|
301
|
+
fill="none"
|
|
302
|
+
part="line"
|
|
303
|
+
style="--chart-series: var(--chart-series-${index})"
|
|
304
|
+
/>`;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* The reading names, as HTML beside the drawing rather than inside it.
|
|
308
|
+
*
|
|
309
|
+
* Inside, they would scale with the box, for the reason the class doc gives.
|
|
310
|
+
*/
|
|
311
|
+
renderLabels(readings) {
|
|
312
|
+
return html `<div aria-hidden="true" part="labels">
|
|
313
|
+
${readings.map((one) => html `<span part="label">${one}</span>`)}
|
|
314
|
+
</div>`;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* What a pointer resting on a reading shows.
|
|
318
|
+
*
|
|
319
|
+
* A seam over `drawTooltip`, which holds the markup every chart shares. The
|
|
320
|
+
* usual reason to override is arrangement: every cell of the row is already
|
|
321
|
+
* there, including the columns nothing was plotted from.
|
|
322
|
+
*/
|
|
323
|
+
renderTooltip() {
|
|
324
|
+
const at = this.pointer.at;
|
|
325
|
+
const series = this.series;
|
|
326
|
+
if (at < 0 || series.length === 0) {
|
|
327
|
+
return drawTooltip(this.sourceRows, at, this.tag('tooltip'));
|
|
328
|
+
}
|
|
329
|
+
/* Above the topmost series at that reading, so the box never covers the
|
|
330
|
+
line it is describing. `y` counts down in the drawing, so the smallest is
|
|
331
|
+
the highest, and no readings at all would make `Math.min` return
|
|
332
|
+
Infinity. */
|
|
333
|
+
const domain = this.range(series);
|
|
334
|
+
const scale = linear(domain, [HEIGHT, 0]);
|
|
335
|
+
const tops = series
|
|
336
|
+
.map((one) => one.points[at]?.value)
|
|
337
|
+
.filter((one) => one !== undefined)
|
|
338
|
+
.map((one) => scale(one));
|
|
339
|
+
const slot = 100 / this.readings;
|
|
340
|
+
return drawTooltip(this.sourceRows, at, this.tag('tooltip'), {
|
|
341
|
+
placement: 'top',
|
|
342
|
+
x: `${at * slot + slot / 2}%`,
|
|
343
|
+
y: `${tops.length > 0 ? Math.min(...tops) : 0}%`,
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
__decorate([
|
|
348
|
+
property({ reflect: true, type: Boolean })
|
|
349
|
+
], HelixHeadlessLineChart.prototype, "area", void 0);
|
|
350
|
+
__decorate([
|
|
351
|
+
property({ reflect: true })
|
|
352
|
+
], HelixHeadlessLineChart.prototype, "curve", void 0);
|
|
353
|
+
__decorate([
|
|
354
|
+
property()
|
|
355
|
+
], HelixHeadlessLineChart.prototype, "gridlines", void 0);
|
|
356
|
+
__decorate([
|
|
357
|
+
property({ reflect: true, type: Boolean })
|
|
358
|
+
], HelixHeadlessLineChart.prototype, "zero", void 0);
|
|
359
|
+
__decorate([
|
|
360
|
+
property({ reflect: true })
|
|
361
|
+
], HelixHeadlessLineChart.prototype, "terminus", void 0);
|
|
362
|
+
HelixHeadlessLineChart = __decorate([
|
|
363
|
+
customElement('helix-headless-line-chart')
|
|
364
|
+
], HelixHeadlessLineChart);
|
|
365
|
+
export { HelixHeadlessLineChart };
|