ngwr 15.0.1 → 15.2.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.
Files changed (420) hide show
  1. package/anchor/styles/_index.scss +13 -2
  2. package/bits/aurora/styles/_rules.scss +11 -0
  3. package/bits/dot-grid/dot-grid.scss +1 -0
  4. package/bits/dot-grid/styles/_index.scss +8 -0
  5. package/bits/dot-grid/styles/_rules.scss +54 -0
  6. package/bits/iridescence/iridescence.scss +1 -0
  7. package/bits/iridescence/styles/_index.scss +8 -0
  8. package/bits/iridescence/styles/_rules.scss +72 -0
  9. package/bits/marquee/styles/_rules.scss +7 -3
  10. package/bits/ripple-grid/ripple-grid.scss +1 -0
  11. package/bits/ripple-grid/styles/_index.scss +8 -0
  12. package/bits/ripple-grid/styles/_rules.scss +63 -0
  13. package/bits/spotlight-card/styles/_rules.scss +7 -4
  14. package/bits/star-border/styles/_rules.scss +5 -2
  15. package/bits/threads/styles/_index.scss +8 -0
  16. package/bits/threads/styles/_rules.scss +76 -0
  17. package/bits/threads/threads.scss +1 -0
  18. package/bits/waves/styles/_rules.scss +8 -1
  19. package/charts/bar-chart/styles/_index.scss +607 -7
  20. package/charts/boxplot-chart/styles/_index.scss +297 -0
  21. package/charts/bullet-chart/styles/_index.scss +268 -0
  22. package/charts/calendar-heatmap/styles/_index.scss +25 -3
  23. package/charts/candlestick-chart/styles/_index.scss +307 -0
  24. package/charts/chart-legend/styles/_index.scss +143 -0
  25. package/charts/core/styles/_index.scss +30 -0
  26. package/charts/donut-chart/styles/_index.scss +39 -3
  27. package/charts/funnel-chart/styles/_index.scss +237 -0
  28. package/charts/gauge/styles/_index.scss +4 -2
  29. package/charts/heatmap-chart/styles/_index.scss +329 -0
  30. package/charts/line-chart/styles/_index.scss +141 -8
  31. package/charts/meter-group/styles/_index.scss +44 -13
  32. package/charts/radar-chart/styles/_index.scss +206 -0
  33. package/charts/scatter-chart/styles/_index.scss +245 -0
  34. package/charts/sparkline/styles/_index.scss +10 -1
  35. package/charts/treemap-chart/styles/_index.scss +215 -0
  36. package/charts/waterfall-chart/styles/_index.scss +321 -0
  37. package/collapse/styles/_index.scss +6 -1
  38. package/fesm2022/ngwr-affix.mjs +3 -3
  39. package/fesm2022/ngwr-alert.mjs +3 -3
  40. package/fesm2022/ngwr-anchor.mjs +3 -3
  41. package/fesm2022/ngwr-avatar.mjs +3 -3
  42. package/fesm2022/ngwr-back-top.mjs +3 -3
  43. package/fesm2022/ngwr-badge.mjs +6 -6
  44. package/fesm2022/ngwr-bits-aurora.mjs +30 -38
  45. package/fesm2022/ngwr-bits-aurora.mjs.map +1 -1
  46. package/fesm2022/ngwr-bits-blur-text.mjs +3 -3
  47. package/fesm2022/ngwr-bits-border-glow-testing.mjs.map +1 -1
  48. package/fesm2022/ngwr-bits-border-glow.mjs +11 -5
  49. package/fesm2022/ngwr-bits-border-glow.mjs.map +1 -1
  50. package/fesm2022/ngwr-bits-circular-text.mjs +3 -3
  51. package/fesm2022/ngwr-bits-click-spark.mjs +3 -3
  52. package/fesm2022/ngwr-bits-confetti.mjs +3 -3
  53. package/fesm2022/ngwr-bits-decrypt-text.mjs +3 -3
  54. package/fesm2022/ngwr-bits-dot-grid-testing.mjs +40 -0
  55. package/fesm2022/ngwr-bits-dot-grid-testing.mjs.map +1 -0
  56. package/fesm2022/ngwr-bits-dot-grid.mjs +482 -0
  57. package/fesm2022/ngwr-bits-dot-grid.mjs.map +1 -0
  58. package/fesm2022/ngwr-bits-falling-text.mjs +3 -3
  59. package/fesm2022/ngwr-bits-fuzzy-text.mjs +3 -3
  60. package/fesm2022/ngwr-bits-glitch-text.mjs +3 -3
  61. package/fesm2022/ngwr-bits-gradient-text.mjs +3 -3
  62. package/fesm2022/ngwr-bits-iridescence-testing.mjs +31 -0
  63. package/fesm2022/ngwr-bits-iridescence-testing.mjs.map +1 -0
  64. package/fesm2022/ngwr-bits-iridescence.mjs +591 -0
  65. package/fesm2022/ngwr-bits-iridescence.mjs.map +1 -0
  66. package/fesm2022/ngwr-bits-marquee-testing.mjs +1 -1
  67. package/fesm2022/ngwr-bits-marquee-testing.mjs.map +1 -1
  68. package/fesm2022/ngwr-bits-marquee.mjs +7 -7
  69. package/fesm2022/ngwr-bits-marquee.mjs.map +1 -1
  70. package/fesm2022/ngwr-bits-ripple-grid-testing.mjs +40 -0
  71. package/fesm2022/ngwr-bits-ripple-grid-testing.mjs.map +1 -0
  72. package/fesm2022/ngwr-bits-ripple-grid.mjs +805 -0
  73. package/fesm2022/ngwr-bits-ripple-grid.mjs.map +1 -0
  74. package/fesm2022/ngwr-bits-rotating-text.mjs +3 -3
  75. package/fesm2022/ngwr-bits-shiny-text.mjs +6 -6
  76. package/fesm2022/ngwr-bits-splash-cursor.mjs +3 -3
  77. package/fesm2022/ngwr-bits-split-text.mjs +3 -3
  78. package/fesm2022/ngwr-bits-spotlight-card-testing.mjs +1 -1
  79. package/fesm2022/ngwr-bits-spotlight-card-testing.mjs.map +1 -1
  80. package/fesm2022/ngwr-bits-spotlight-card.mjs +10 -10
  81. package/fesm2022/ngwr-bits-spotlight-card.mjs.map +1 -1
  82. package/fesm2022/ngwr-bits-star-border-testing.mjs +1 -1
  83. package/fesm2022/ngwr-bits-star-border-testing.mjs.map +1 -1
  84. package/fesm2022/ngwr-bits-star-border.mjs +7 -7
  85. package/fesm2022/ngwr-bits-star-border.mjs.map +1 -1
  86. package/fesm2022/ngwr-bits-threads-testing.mjs +41 -0
  87. package/fesm2022/ngwr-bits-threads-testing.mjs.map +1 -0
  88. package/fesm2022/ngwr-bits-threads.mjs +482 -0
  89. package/fesm2022/ngwr-bits-threads.mjs.map +1 -0
  90. package/fesm2022/ngwr-bits-tilt-card.mjs +6 -6
  91. package/fesm2022/ngwr-bits-typewriter.mjs +3 -3
  92. package/fesm2022/ngwr-bits-waves-testing.mjs.map +1 -1
  93. package/fesm2022/ngwr-bits-waves.mjs +60 -41
  94. package/fesm2022/ngwr-bits-waves.mjs.map +1 -1
  95. package/fesm2022/ngwr-breadcrumbs.mjs +8 -8
  96. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  97. package/fesm2022/ngwr-burger.mjs +3 -3
  98. package/fesm2022/ngwr-button.mjs +6 -6
  99. package/fesm2022/ngwr-calendar.mjs +3 -3
  100. package/fesm2022/ngwr-card.mjs +9 -9
  101. package/fesm2022/ngwr-carousel.mjs +6 -6
  102. package/fesm2022/ngwr-cascader.mjs +5 -5
  103. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  104. package/fesm2022/ngwr-charts-bar-chart-testing.mjs +127 -3
  105. package/fesm2022/ngwr-charts-bar-chart-testing.mjs.map +1 -1
  106. package/fesm2022/ngwr-charts-bar-chart.mjs +683 -49
  107. package/fesm2022/ngwr-charts-bar-chart.mjs.map +1 -1
  108. package/fesm2022/ngwr-charts-boxplot-chart-testing.mjs +161 -0
  109. package/fesm2022/ngwr-charts-boxplot-chart-testing.mjs.map +1 -0
  110. package/fesm2022/ngwr-charts-boxplot-chart.mjs +517 -0
  111. package/fesm2022/ngwr-charts-boxplot-chart.mjs.map +1 -0
  112. package/fesm2022/ngwr-charts-bullet-chart-testing.mjs +68 -0
  113. package/fesm2022/ngwr-charts-bullet-chart-testing.mjs.map +1 -0
  114. package/fesm2022/ngwr-charts-bullet-chart.mjs +459 -0
  115. package/fesm2022/ngwr-charts-bullet-chart.mjs.map +1 -0
  116. package/fesm2022/ngwr-charts-calendar-heatmap-testing.mjs +27 -0
  117. package/fesm2022/ngwr-charts-calendar-heatmap-testing.mjs.map +1 -1
  118. package/fesm2022/ngwr-charts-calendar-heatmap.mjs +96 -17
  119. package/fesm2022/ngwr-charts-calendar-heatmap.mjs.map +1 -1
  120. package/fesm2022/ngwr-charts-candlestick-chart-testing.mjs +107 -0
  121. package/fesm2022/ngwr-charts-candlestick-chart-testing.mjs.map +1 -0
  122. package/fesm2022/ngwr-charts-candlestick-chart.mjs +508 -0
  123. package/fesm2022/ngwr-charts-candlestick-chart.mjs.map +1 -0
  124. package/fesm2022/ngwr-charts-chart-legend-testing.mjs +126 -0
  125. package/fesm2022/ngwr-charts-chart-legend-testing.mjs.map +1 -0
  126. package/fesm2022/ngwr-charts-chart-legend.mjs +251 -0
  127. package/fesm2022/ngwr-charts-chart-legend.mjs.map +1 -0
  128. package/fesm2022/ngwr-charts-core.mjs +383 -0
  129. package/fesm2022/ngwr-charts-core.mjs.map +1 -0
  130. package/fesm2022/ngwr-charts-donut-chart-testing.mjs +10 -1
  131. package/fesm2022/ngwr-charts-donut-chart-testing.mjs.map +1 -1
  132. package/fesm2022/ngwr-charts-donut-chart.mjs +187 -31
  133. package/fesm2022/ngwr-charts-donut-chart.mjs.map +1 -1
  134. package/fesm2022/ngwr-charts-funnel-chart-testing.mjs +100 -0
  135. package/fesm2022/ngwr-charts-funnel-chart-testing.mjs.map +1 -0
  136. package/fesm2022/ngwr-charts-funnel-chart.mjs +415 -0
  137. package/fesm2022/ngwr-charts-funnel-chart.mjs.map +1 -0
  138. package/fesm2022/ngwr-charts-gauge-testing.mjs +9 -3
  139. package/fesm2022/ngwr-charts-gauge-testing.mjs.map +1 -1
  140. package/fesm2022/ngwr-charts-gauge.mjs +9 -15
  141. package/fesm2022/ngwr-charts-gauge.mjs.map +1 -1
  142. package/fesm2022/ngwr-charts-heatmap-chart-testing.mjs +120 -0
  143. package/fesm2022/ngwr-charts-heatmap-chart-testing.mjs.map +1 -0
  144. package/fesm2022/ngwr-charts-heatmap-chart.mjs +519 -0
  145. package/fesm2022/ngwr-charts-heatmap-chart.mjs.map +1 -0
  146. package/fesm2022/ngwr-charts-line-chart-testing.mjs +43 -1
  147. package/fesm2022/ngwr-charts-line-chart-testing.mjs.map +1 -1
  148. package/fesm2022/ngwr-charts-line-chart.mjs +436 -122
  149. package/fesm2022/ngwr-charts-line-chart.mjs.map +1 -1
  150. package/fesm2022/ngwr-charts-meter-group-testing.mjs +14 -2
  151. package/fesm2022/ngwr-charts-meter-group-testing.mjs.map +1 -1
  152. package/fesm2022/ngwr-charts-meter-group.mjs +101 -32
  153. package/fesm2022/ngwr-charts-meter-group.mjs.map +1 -1
  154. package/fesm2022/ngwr-charts-radar-chart-testing.mjs +98 -0
  155. package/fesm2022/ngwr-charts-radar-chart-testing.mjs.map +1 -0
  156. package/fesm2022/ngwr-charts-radar-chart.mjs +720 -0
  157. package/fesm2022/ngwr-charts-radar-chart.mjs.map +1 -0
  158. package/fesm2022/ngwr-charts-scatter-chart-testing.mjs +132 -0
  159. package/fesm2022/ngwr-charts-scatter-chart-testing.mjs.map +1 -0
  160. package/fesm2022/ngwr-charts-scatter-chart.mjs +545 -0
  161. package/fesm2022/ngwr-charts-scatter-chart.mjs.map +1 -0
  162. package/fesm2022/ngwr-charts-sparkline-testing.mjs.map +1 -1
  163. package/fesm2022/ngwr-charts-sparkline.mjs +14 -16
  164. package/fesm2022/ngwr-charts-sparkline.mjs.map +1 -1
  165. package/fesm2022/ngwr-charts-treemap-chart-testing.mjs +103 -0
  166. package/fesm2022/ngwr-charts-treemap-chart-testing.mjs.map +1 -0
  167. package/fesm2022/ngwr-charts-treemap-chart.mjs +535 -0
  168. package/fesm2022/ngwr-charts-treemap-chart.mjs.map +1 -0
  169. package/fesm2022/ngwr-charts-waterfall-chart-testing.mjs +131 -0
  170. package/fesm2022/ngwr-charts-waterfall-chart-testing.mjs.map +1 -0
  171. package/fesm2022/ngwr-charts-waterfall-chart.mjs +462 -0
  172. package/fesm2022/ngwr-charts-waterfall-chart.mjs.map +1 -0
  173. package/fesm2022/ngwr-checkbox.mjs +6 -6
  174. package/fesm2022/ngwr-clipboard.mjs +3 -3
  175. package/fesm2022/ngwr-collapse.mjs +9 -9
  176. package/fesm2022/ngwr-color-picker.mjs +6 -6
  177. package/fesm2022/ngwr-command-palette.mjs +3 -3
  178. package/fesm2022/ngwr-compare.mjs +3 -3
  179. package/fesm2022/ngwr-context-menu.mjs +12 -12
  180. package/fesm2022/ngwr-cookie.mjs +3 -3
  181. package/fesm2022/ngwr-counter.mjs +6 -6
  182. package/fesm2022/ngwr-date-picker.mjs +21 -21
  183. package/fesm2022/ngwr-date.mjs +6 -6
  184. package/fesm2022/ngwr-density.mjs +6 -6
  185. package/fesm2022/ngwr-descriptions.mjs +6 -6
  186. package/fesm2022/ngwr-dialog.mjs +15 -15
  187. package/fesm2022/ngwr-directives.mjs +12 -12
  188. package/fesm2022/ngwr-divider.mjs +3 -3
  189. package/fesm2022/ngwr-drawer.mjs +18 -18
  190. package/fesm2022/ngwr-dropdown.mjs +9 -9
  191. package/fesm2022/ngwr-editor.mjs +3 -3
  192. package/fesm2022/ngwr-empty.mjs +3 -3
  193. package/fesm2022/ngwr-event-calendar.mjs +6 -6
  194. package/fesm2022/ngwr-file-upload.mjs +3 -3
  195. package/fesm2022/ngwr-form.mjs +9 -9
  196. package/fesm2022/ngwr-graph.mjs +6 -6
  197. package/fesm2022/ngwr-hotkey.mjs +6 -6
  198. package/fesm2022/ngwr-i18n-ar.mjs +90 -4
  199. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
  200. package/fesm2022/ngwr-i18n-cs.mjs +90 -4
  201. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
  202. package/fesm2022/ngwr-i18n-de.mjs +90 -4
  203. package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
  204. package/fesm2022/ngwr-i18n-en.mjs +90 -4
  205. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  206. package/fesm2022/ngwr-i18n-es.mjs +90 -4
  207. package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
  208. package/fesm2022/ngwr-i18n-fr.mjs +90 -4
  209. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
  210. package/fesm2022/ngwr-i18n-he.mjs +90 -4
  211. package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
  212. package/fesm2022/ngwr-i18n-hi.mjs +90 -4
  213. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
  214. package/fesm2022/ngwr-i18n-id.mjs +90 -4
  215. package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
  216. package/fesm2022/ngwr-i18n-it.mjs +90 -4
  217. package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
  218. package/fesm2022/ngwr-i18n-ja.mjs +90 -4
  219. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
  220. package/fesm2022/ngwr-i18n-ko.mjs +90 -4
  221. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
  222. package/fesm2022/ngwr-i18n-nl.mjs +90 -4
  223. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
  224. package/fesm2022/ngwr-i18n-pl.mjs +90 -4
  225. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
  226. package/fesm2022/ngwr-i18n-pt.mjs +90 -4
  227. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
  228. package/fesm2022/ngwr-i18n-ru.mjs +90 -4
  229. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  230. package/fesm2022/ngwr-i18n-sv.mjs +90 -4
  231. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
  232. package/fesm2022/ngwr-i18n-tr.mjs +90 -4
  233. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
  234. package/fesm2022/ngwr-i18n-uk.mjs +90 -4
  235. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
  236. package/fesm2022/ngwr-i18n-vi.mjs +90 -4
  237. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
  238. package/fesm2022/ngwr-i18n-zh-tw.mjs +90 -4
  239. package/fesm2022/ngwr-i18n-zh-tw.mjs.map +1 -1
  240. package/fesm2022/ngwr-i18n-zh.mjs +90 -4
  241. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
  242. package/fesm2022/ngwr-i18n.mjs +9 -9
  243. package/fesm2022/ngwr-icon.mjs +6 -6
  244. package/fesm2022/ngwr-image-cropper.mjs +3 -3
  245. package/fesm2022/ngwr-input-number.mjs +3 -3
  246. package/fesm2022/ngwr-input-otp.mjs +3 -3
  247. package/fesm2022/ngwr-input.mjs +15 -15
  248. package/fesm2022/ngwr-keyboard.mjs +3 -3
  249. package/fesm2022/ngwr-knob.mjs +3 -3
  250. package/fesm2022/ngwr-layout.mjs +15 -15
  251. package/fesm2022/ngwr-lightbox.mjs +5 -5
  252. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  253. package/fesm2022/ngwr-list.mjs +8 -8
  254. package/fesm2022/ngwr-list.mjs.map +1 -1
  255. package/fesm2022/ngwr-loading-bar.mjs +6 -6
  256. package/fesm2022/ngwr-mention.mjs +6 -6
  257. package/fesm2022/ngwr-meta.mjs +6 -6
  258. package/fesm2022/ngwr-overlay.mjs +6 -6
  259. package/fesm2022/ngwr-page-header.mjs +3 -3
  260. package/fesm2022/ngwr-pagination.mjs +3 -3
  261. package/fesm2022/ngwr-pipes.mjs +21 -21
  262. package/fesm2022/ngwr-platform.mjs +6 -6
  263. package/fesm2022/ngwr-popconfirm.mjs +6 -6
  264. package/fesm2022/ngwr-popover.mjs +43 -20
  265. package/fesm2022/ngwr-popover.mjs.map +1 -1
  266. package/fesm2022/ngwr-progress.mjs +3 -3
  267. package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
  268. package/fesm2022/ngwr-qr.mjs +4 -3
  269. package/fesm2022/ngwr-qr.mjs.map +1 -1
  270. package/fesm2022/ngwr-radio.mjs +6 -6
  271. package/fesm2022/ngwr-rating.mjs +3 -3
  272. package/fesm2022/ngwr-result.mjs +12 -12
  273. package/fesm2022/ngwr-schema-form.mjs +3 -3
  274. package/fesm2022/ngwr-scroll.mjs +3 -3
  275. package/fesm2022/ngwr-segmented.mjs +3 -3
  276. package/fesm2022/ngwr-select.mjs +12 -12
  277. package/fesm2022/ngwr-sidebar.mjs +3 -3
  278. package/fesm2022/ngwr-skeleton.mjs +3 -3
  279. package/fesm2022/ngwr-slider.mjs +3 -3
  280. package/fesm2022/ngwr-sortable-list.mjs +11 -11
  281. package/fesm2022/ngwr-sortable-list.mjs.map +1 -1
  282. package/fesm2022/ngwr-speed-dial.mjs +3 -3
  283. package/fesm2022/ngwr-spinner.mjs +3 -3
  284. package/fesm2022/ngwr-splitter.mjs +3 -3
  285. package/fesm2022/ngwr-statistic.mjs +9 -9
  286. package/fesm2022/ngwr-stepper.mjs +6 -6
  287. package/fesm2022/ngwr-storage.mjs +3 -3
  288. package/fesm2022/ngwr-switch.mjs +3 -3
  289. package/fesm2022/ngwr-table.mjs +18 -18
  290. package/fesm2022/ngwr-tabs-router.mjs +3 -3
  291. package/fesm2022/ngwr-tabs.mjs +6 -6
  292. package/fesm2022/ngwr-textarea.mjs +3 -3
  293. package/fesm2022/ngwr-theme.mjs +3 -3
  294. package/fesm2022/ngwr-timeline.mjs +6 -6
  295. package/fesm2022/ngwr-toast-testing.mjs +2 -1
  296. package/fesm2022/ngwr-toast-testing.mjs.map +1 -1
  297. package/fesm2022/ngwr-toast.mjs +34 -15
  298. package/fesm2022/ngwr-toast.mjs.map +1 -1
  299. package/fesm2022/ngwr-toolbar.mjs +3 -3
  300. package/fesm2022/ngwr-tour.mjs +6 -6
  301. package/fesm2022/ngwr-transfer.mjs +3 -3
  302. package/fesm2022/ngwr-tree.mjs +3 -3
  303. package/fesm2022/ngwr-typography.mjs +3 -3
  304. package/fesm2022/ngwr-utils.mjs +31 -1
  305. package/fesm2022/ngwr-utils.mjs.map +1 -1
  306. package/fesm2022/ngwr-version.mjs +1 -1
  307. package/fesm2022/ngwr-version.mjs.map +1 -1
  308. package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
  309. package/fesm2022/ngwr-window-testing.mjs +61 -5
  310. package/fesm2022/ngwr-window-testing.mjs.map +1 -1
  311. package/fesm2022/ngwr-window.mjs +1538 -895
  312. package/fesm2022/ngwr-window.mjs.map +1 -1
  313. package/fesm2022/ngwr.mjs.map +1 -1
  314. package/i18n/ar.json +84 -4
  315. package/i18n/cs.json +84 -4
  316. package/i18n/de.json +84 -4
  317. package/i18n/en.json +84 -4
  318. package/i18n/es.json +84 -4
  319. package/i18n/fr.json +84 -4
  320. package/i18n/he.json +84 -4
  321. package/i18n/hi.json +84 -4
  322. package/i18n/id.json +84 -4
  323. package/i18n/it.json +84 -4
  324. package/i18n/ja.json +84 -4
  325. package/i18n/ko.json +84 -4
  326. package/i18n/nl.json +84 -4
  327. package/i18n/pl.json +84 -4
  328. package/i18n/pt.json +84 -4
  329. package/i18n/ru.json +84 -4
  330. package/i18n/sv.json +84 -4
  331. package/i18n/tr.json +84 -4
  332. package/i18n/uk.json +84 -4
  333. package/i18n/vi.json +84 -4
  334. package/i18n/zh-TW.json +84 -4
  335. package/i18n/zh.json +84 -4
  336. package/llms-full.txt +266 -9
  337. package/llms.txt +30 -7
  338. package/mcp/api.js +69 -1
  339. package/mcp/catalog.js +10 -1
  340. package/mcp/server.js +15 -1
  341. package/mcp/tools.js +122 -26
  342. package/package.json +132 -1
  343. package/popover/styles/_index.scss +75 -7
  344. package/schematics/component-style/index.js +3 -0
  345. package/schematics/migrations/v15/index.js +3 -26
  346. package/schematics/ng-add/index.js +2 -2
  347. package/schematics/use/symbol-map.json +14 -0
  348. package/schematics/utility/global-styles.js +19 -4
  349. package/schematics/utility/v15-moves.js +55 -0
  350. package/skills/ngwr/SKILL.md +8 -2
  351. package/skills/ngwr/references/catalog.md +28 -0
  352. package/skills/ngwr/references/setup.md +5 -4
  353. package/theme/styles/_focus.scss +8 -0
  354. package/toast/styles/_index.scss +103 -12
  355. package/types/ngwr-bits-aurora.d.ts +11 -0
  356. package/types/ngwr-bits-border-glow-testing.d.ts +5 -6
  357. package/types/ngwr-bits-border-glow.d.ts +5 -1
  358. package/types/ngwr-bits-dot-grid-testing.d.ts +92 -0
  359. package/types/ngwr-bits-dot-grid.d.ts +158 -0
  360. package/types/ngwr-bits-iridescence-testing.d.ts +85 -0
  361. package/types/ngwr-bits-iridescence.d.ts +244 -0
  362. package/types/ngwr-bits-ripple-grid-testing.d.ts +96 -0
  363. package/types/ngwr-bits-ripple-grid.d.ts +294 -0
  364. package/types/ngwr-bits-splash-cursor.d.ts +0 -1
  365. package/types/ngwr-bits-spotlight-card-testing.d.ts +3 -1
  366. package/types/ngwr-bits-star-border-testing.d.ts +7 -7
  367. package/types/ngwr-bits-threads-testing.d.ts +97 -0
  368. package/types/ngwr-bits-threads.d.ts +216 -0
  369. package/types/ngwr-bits-waves-testing.d.ts +1 -1
  370. package/types/ngwr-bits-waves.d.ts +20 -3
  371. package/types/ngwr-charts-bar-chart-testing.d.ts +193 -14
  372. package/types/ngwr-charts-bar-chart.d.ts +546 -38
  373. package/types/ngwr-charts-boxplot-chart-testing.d.ts +165 -0
  374. package/types/ngwr-charts-boxplot-chart.d.ts +308 -0
  375. package/types/ngwr-charts-bullet-chart-testing.d.ts +99 -0
  376. package/types/ngwr-charts-bullet-chart.d.ts +262 -0
  377. package/types/ngwr-charts-calendar-heatmap-testing.d.ts +32 -1
  378. package/types/ngwr-charts-calendar-heatmap.d.ts +55 -6
  379. package/types/ngwr-charts-candlestick-chart-testing.d.ts +135 -0
  380. package/types/ngwr-charts-candlestick-chart.d.ts +361 -0
  381. package/types/ngwr-charts-chart-legend-testing.d.ts +84 -0
  382. package/types/ngwr-charts-chart-legend.d.ts +178 -0
  383. package/types/ngwr-charts-core.d.ts +391 -0
  384. package/types/ngwr-charts-donut-chart-testing.d.ts +28 -5
  385. package/types/ngwr-charts-donut-chart.d.ts +124 -12
  386. package/types/ngwr-charts-funnel-chart-testing.d.ts +130 -0
  387. package/types/ngwr-charts-funnel-chart.d.ts +296 -0
  388. package/types/ngwr-charts-gauge-testing.d.ts +5 -0
  389. package/types/ngwr-charts-gauge.d.ts +6 -4
  390. package/types/ngwr-charts-heatmap-chart-testing.d.ts +148 -0
  391. package/types/ngwr-charts-heatmap-chart.d.ts +359 -0
  392. package/types/ngwr-charts-line-chart-testing.d.ts +72 -11
  393. package/types/ngwr-charts-line-chart.d.ts +291 -67
  394. package/types/ngwr-charts-meter-group-testing.d.ts +16 -2
  395. package/types/ngwr-charts-meter-group.d.ts +71 -11
  396. package/types/ngwr-charts-radar-chart-testing.d.ts +162 -0
  397. package/types/ngwr-charts-radar-chart.d.ts +461 -0
  398. package/types/ngwr-charts-scatter-chart-testing.d.ts +147 -0
  399. package/types/ngwr-charts-scatter-chart.d.ts +396 -0
  400. package/types/ngwr-charts-sparkline-testing.d.ts +4 -1
  401. package/types/ngwr-charts-sparkline.d.ts +8 -6
  402. package/types/ngwr-charts-treemap-chart-testing.d.ts +131 -0
  403. package/types/ngwr-charts-treemap-chart.d.ts +295 -0
  404. package/types/ngwr-charts-waterfall-chart-testing.d.ts +149 -0
  405. package/types/ngwr-charts-waterfall-chart.d.ts +338 -0
  406. package/types/ngwr-color-picker.d.ts +0 -21
  407. package/types/ngwr-dropdown.d.ts +0 -52
  408. package/types/ngwr-editor.d.ts +2 -84
  409. package/types/ngwr-i18n.d.ts +0 -15
  410. package/types/ngwr-mention.d.ts +0 -13
  411. package/types/ngwr-popconfirm.d.ts +0 -33
  412. package/types/ngwr-popover.d.ts +29 -53
  413. package/types/ngwr-toast-testing.d.ts +6 -1
  414. package/types/ngwr-tour.d.ts +0 -2
  415. package/types/ngwr-utils.d.ts +49 -7
  416. package/types/ngwr-version.d.ts +1 -1
  417. package/types/ngwr-window-testing.d.ts +65 -7
  418. package/types/ngwr-window.d.ts +831 -207
  419. package/types/ngwr.d.ts +1 -0
  420. package/window/styles/_index.scss +528 -82
@@ -1,55 +1,31 @@
1
1
  import * as i0 from "@angular/core";
2
- import { Component, LOCALE_ID, ViewEncapsulation, computed, effect, inject, input, signal, viewChild } from "@angular/core";
2
+ import { Component, DestroyRef, LOCALE_ID, PLATFORM_ID, ViewEncapsulation, afterNextRender, afterRenderEffect, computed, effect, inject, input, model, signal, untracked, viewChild } from "@angular/core";
3
3
  import { coerceBooleanProperty, coerceNumberProperty } from "@angular/cdk/coercion";
4
- import { DOCUMENT as DOCUMENT$1 } from "@angular/common";
4
+ import { DOCUMENT as DOCUMENT$1, isPlatformBrowser } from "@angular/common";
5
5
  import { useI18nText } from "ngwr/i18n";
6
- import { clamp, round } from "ngwr/utils";
6
+ import { clamp } from "ngwr/utils";
7
+ import { WR_CHART_LEGEND_BLOCK, WrChartLegend } from "ngwr/charts/chart-legend";
8
+ import { WrChartTable, chartAxis, chartColor, chartDash, useChartNumbers } from "ngwr/charts/core";
7
9
  /**
8
10
  * @license
9
11
  *
10
12
  * Use of this source code is governed by an MIT-style license that can be
11
13
  * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
12
14
  */
13
- const TICK_COUNT = 4;
14
- function niceStep(raw) {
15
- if (!Number.isFinite(raw) || raw <= 0) return 1;
16
- const magnitude = 10 ** Math.floor(Math.log10(raw));
17
- const normalised = raw / magnitude;
18
- return (normalised <= 1 ? 1 : normalised <= 2 ? 2 : normalised <= 2.5 ? 2.5 : normalised <= 5 ? 5 : 10) * magnitude;
19
- }
20
- function fractionDigits(value) {
21
- for (let d = 0; d <= 6; d++) if (Math.abs(value * 10 ** d - Math.round(value * 10 ** d)) < 1e-9) return d;
22
- return 6;
23
- }
24
- function magnitude(value) {
25
- const abs = Math.abs(value);
26
- let m = Math.floor(Math.log10(abs));
27
- if (10 ** (m + 1) <= abs) m++;
28
- if (10 ** m > abs) m--;
29
- return m;
30
- }
31
- function lastDigit(step) {
32
- for (let e = magnitude(step); e > -21; e--) {
33
- const scaled = step / 10 ** e;
34
- if (Math.abs(scaled - Math.round(scaled)) < 1e-6) return e;
35
- }
36
- return -21;
37
- }
38
- const FALLBACK_COLORS = [
39
- "var(--wr-color-primary)",
40
- "var(--wr-color-success)",
41
- "var(--wr-color-warning)",
42
- "var(--wr-color-danger)",
43
- "var(--wr-color-on-surface-muted)"
44
- ];
15
+ const ASSUMED_WIDTH = 560;
16
+ const ASSUMED_INSET = 16;
17
+ const CHAR_WIDTH = 7;
18
+ const LABEL_GAP = 8;
19
+ const HOVER_RADIUS = 6;
20
+ const BESIDE = 12;
45
21
  var WrLineChart = class WrLineChart {
46
22
  series = input([], ...ngDevMode ? [{ debugName: "series" }] : /* istanbul ignore next */ []);
47
23
  ariaLabel = input(null, ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
48
- resolvedAriaLabel = useI18nText(this.ariaLabel, "lineChart.label", "Line chart");
24
+ lineLabel = useI18nText(this.ariaLabel, "lineChart.label", "Line chart");
25
+ areaLabel = useI18nText(this.ariaLabel, "lineChart.areaLabel", "Area chart");
26
+ resolvedAriaLabel = computed(() => this.showArea() ? this.areaLabel() : this.lineLabel(), ...ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []);
49
27
  valueFormat = input(null, ...ngDevMode ? [{ debugName: "valueFormat" }] : /* istanbul ignore next */ []);
50
- locale = inject(LOCALE_ID);
51
- numbers = new Intl.NumberFormat(this.locale);
52
- smallNumbers = new Intl.NumberFormat(this.locale, { maximumSignificantDigits: 3 });
28
+ numbers = useChartNumbers(this.valueFormat);
53
29
  xLabels = input([], ...ngDevMode ? [{ debugName: "xLabels" }] : /* istanbul ignore next */ []);
54
30
  height = input(240, {
55
31
  ...ngDevMode ? { debugName: "height" } : /* istanbul ignore next */ {},
@@ -63,10 +39,27 @@ var WrLineChart = class WrLineChart {
63
39
  ...ngDevMode ? { debugName: "showLegend" } : /* istanbul ignore next */ {},
64
40
  transform: coerceBooleanProperty
65
41
  });
42
+ toggleableLegend = input(false, {
43
+ ...ngDevMode ? { debugName: "toggleableLegend" } : /* istanbul ignore next */ {},
44
+ transform: coerceBooleanProperty
45
+ });
46
+ hiddenSeries = model([], ...ngDevMode ? [{ debugName: "hiddenSeries" }] : /* istanbul ignore next */ []);
66
47
  showDots = input(true, {
67
48
  ...ngDevMode ? { debugName: "showDots" } : /* istanbul ignore next */ {},
68
49
  transform: coerceBooleanProperty
69
50
  });
51
+ showArea = input(false, {
52
+ ...ngDevMode ? { debugName: "showArea" } : /* istanbul ignore next */ {},
53
+ transform: coerceBooleanProperty
54
+ });
55
+ stacked = input(false, {
56
+ ...ngDevMode ? { debugName: "stacked" } : /* istanbul ignore next */ {},
57
+ transform: coerceBooleanProperty
58
+ });
59
+ dataTable = input(false, {
60
+ ...ngDevMode ? { debugName: "dataTable" } : /* istanbul ignore next */ {},
61
+ transform: coerceBooleanProperty
62
+ });
70
63
  tooltip = input(true, {
71
64
  ...ngDevMode ? { debugName: "tooltip" } : /* istanbul ignore next */ {},
72
65
  transform: coerceBooleanProperty
@@ -74,6 +67,12 @@ var WrLineChart = class WrLineChart {
74
67
  vbW = 600;
75
68
  vbH = 300;
76
69
  svg = viewChild.required("svg", ...ngDevMode ? [{ debugName: "svg" }] : /* istanbul ignore next */ []);
70
+ plot = viewChild.required("plot", ...ngDevMode ? [{ debugName: "plot" }] : /* istanbul ignore next */ []);
71
+ probe = viewChild("probe", ...ngDevMode ? [{ debugName: "probe" }] : /* istanbul ignore next */ []);
72
+ tooltipEl = viewChild("tooltip", ...ngDevMode ? [{ debugName: "tooltipEl" }] : /* istanbul ignore next */ []);
73
+ ordinals = new Intl.NumberFormat(inject(LOCALE_ID));
74
+ measured = signal(null, ...ngDevMode ? [{ debugName: "measured" }] : /* istanbul ignore next */ []);
75
+ tooltipPlacement = signal("top", ...ngDevMode ? [{ debugName: "tooltipPlacement" }] : /* istanbul ignore next */ []);
77
76
  hoveredIndex = signal(null, ...ngDevMode ? [{ debugName: "hoveredIndex" }] : /* istanbul ignore next */ []);
78
77
  activeIndex = computed(() => this.tooltip() ? this.hoveredIndex() : null, ...ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []);
79
78
  dismissed = null;
@@ -89,61 +88,97 @@ var WrLineChart = class WrLineChart {
89
88
  document.addEventListener("keydown", onKeydown);
90
89
  onCleanup(() => document.removeEventListener("keydown", onKeydown));
91
90
  });
91
+ if (!isPlatformBrowser(inject(PLATFORM_ID))) return;
92
+ const destroyRef = inject(DestroyRef);
93
+ afterRenderEffect(() => {
94
+ this.probeText();
95
+ untracked(() => this.measure());
96
+ });
97
+ afterRenderEffect(() => {
98
+ const points = this.hoverPoints();
99
+ const tooltip = this.tooltipEl()?.nativeElement;
100
+ if (points.length === 0 || !tooltip) return;
101
+ untracked(() => this.placeTooltip(points, tooltip));
102
+ });
103
+ afterNextRender(() => {
104
+ if (typeof ResizeObserver === "undefined") return;
105
+ const observer = new ResizeObserver(() => this.measure());
106
+ observer.observe(this.svg().nativeElement);
107
+ destroyRef.onDestroy(() => observer.disconnect());
108
+ });
92
109
  }
93
- static DASHES = [
94
- "",
95
- "7 4",
96
- "2 3",
97
- "10 4 2 4",
98
- "1 4",
99
- "6 3 2 3"
100
- ];
101
110
  resolvedSeries = computed(() => this.series().map((s, i) => ({
111
+ index: i,
102
112
  label: s.label,
103
- dash: WrLineChart.DASHES[i % WrLineChart.DASHES.length],
104
- data: s.data.map((v) => Number.isFinite(v) ? v : null),
105
- color: s.color ?? FALLBACK_COLORS[i % FALLBACK_COLORS.length]
113
+ dash: chartDash(i),
114
+ data: s.data.map((v) => typeof v === "number" && Number.isFinite(v) ? v : null),
115
+ color: s.color ?? chartColor(i)
106
116
  })), ...ngDevMode ? [{ debugName: "resolvedSeries" }] : /* istanbul ignore next */ []);
117
+ legendItems = computed(() => this.resolvedSeries().map(({ label, color, dash }) => ({
118
+ label,
119
+ color,
120
+ dash
121
+ })), ...ngDevMode ? [{ debugName: "legendItems" }] : /* istanbul ignore next */ []);
122
+ visibleSeries = computed(() => {
123
+ const hidden = new Set(this.hiddenSeries());
124
+ return this.resolvedSeries().filter((s) => !hidden.has(s.index));
125
+ }, ...ngDevMode ? [{ debugName: "visibleSeries" }] : /* istanbul ignore next */ []);
126
+ plottedSeries = computed(() => {
127
+ const visible = this.visibleSeries();
128
+ if (!this.stacked()) return visible.map((s) => ({
129
+ ...s,
130
+ tops: s.data,
131
+ bases: null
132
+ }));
133
+ const up = [];
134
+ const down = [];
135
+ return visible.map((s) => {
136
+ const tops = [];
137
+ const bases = [];
138
+ s.data.forEach((v, i) => {
139
+ if (v === null) {
140
+ tops.push(null);
141
+ bases.push(null);
142
+ return;
143
+ }
144
+ const pile = v < 0 ? down : up;
145
+ const base = pile[i] ?? 0;
146
+ pile[i] = base + v;
147
+ bases.push(base);
148
+ tops.push(base + v);
149
+ });
150
+ return {
151
+ ...s,
152
+ tops,
153
+ bases
154
+ };
155
+ });
156
+ }, ...ngDevMode ? [{ debugName: "plottedSeries" }] : /* istanbul ignore next */ []);
107
157
  bounds = computed(() => {
108
- const all = this.resolvedSeries().flatMap((s) => s.data.filter((v) => v !== null));
109
- if (all.length === 0) return {
110
- min: 0,
111
- max: 1,
112
- step: .25
113
- };
114
- const rawMin = Math.min(0, Math.min(...all));
115
- const rawMax = Math.max(...all);
116
- const step = niceStep((rawMax - rawMin || Math.abs(rawMax) || 1) / TICK_COUNT);
117
- const min = Math.floor(rawMin / step) * step;
118
- let max = Math.ceil(rawMax / step) * step;
119
- if (max === rawMax) max += step;
120
- return {
121
- min,
122
- max,
123
- step
124
- };
158
+ let min = Number.POSITIVE_INFINITY;
159
+ let max = Number.NEGATIVE_INFINITY;
160
+ for (const s of this.plottedSeries()) for (const v of s.tops) {
161
+ if (v === null) continue;
162
+ if (v < min) min = v;
163
+ if (v > max) max = v;
164
+ }
165
+ if (min > max) return chartAxis(NaN, NaN);
166
+ if (this.showArea() || this.stacked()) return chartAxis(min, max, { includeZero: true });
167
+ return chartAxis(Math.min(0, min), max);
125
168
  }, ...ngDevMode ? [{ debugName: "bounds" }] : /* istanbul ignore next */ []);
126
169
  pointCount = computed(() => {
127
170
  const maxLen = this.resolvedSeries().reduce((acc, s) => Math.max(acc, s.data.length), 0);
128
171
  return Math.max(maxLen, this.xLabels().length);
129
172
  }, ...ngDevMode ? [{ debugName: "pointCount" }] : /* istanbul ignore next */ []);
130
173
  yTicks = computed(() => {
131
- const { min, max, step } = this.bounds();
132
- const out = [];
133
- const count = Math.round((max - min) / step);
134
- for (let i = 0; i <= count; i++) {
135
- const value = round(max - i * step, 6);
136
- out.push({
137
- value,
138
- y: (max - value) / (max - min) * this.vbH
139
- });
140
- }
141
- return out;
174
+ const { min, max, ticks } = this.bounds();
175
+ return ticks.map((value) => ({
176
+ value,
177
+ y: (max - value) / (max - min) * this.vbH
178
+ }));
142
179
  }, ...ngDevMode ? [{ debugName: "yTicks" }] : /* istanbul ignore next */ []);
143
- pathFor(series) {
180
+ pathFor(values) {
144
181
  const { min, max } = this.bounds();
145
- const count = this.pointCount();
146
- if (count <= 1) return "";
147
182
  const commands = [];
148
183
  let run = 0;
149
184
  let last = "";
@@ -151,12 +186,12 @@ var WrLineChart = class WrLineChart {
151
186
  if (run === 1) commands.push(`L ${last}`);
152
187
  run = 0;
153
188
  };
154
- series.data.forEach((v, i) => {
189
+ values.forEach((v, i) => {
155
190
  if (v === null) {
156
191
  closeRun();
157
192
  return;
158
193
  }
159
- const x = i / (count - 1) * this.vbW;
194
+ const x = this.pointX(i);
160
195
  const y = (max - v) / (max - min) * this.vbH;
161
196
  last = `${x.toFixed(2)} ${y.toFixed(2)}`;
162
197
  commands.push(`${run === 0 ? "M" : "L"} ${last}`);
@@ -165,6 +200,45 @@ var WrLineChart = class WrLineChart {
165
200
  closeRun();
166
201
  return commands.join(" ");
167
202
  }
203
+ drawn = computed(() => {
204
+ const dots = this.showDots();
205
+ return this.plottedSeries().map((s) => ({
206
+ index: s.index,
207
+ color: s.color,
208
+ dash: s.dash,
209
+ d: this.pathFor(s.tops),
210
+ dots: dots ? s.tops.map((v, i) => v === null ? null : this.dotPath(this.pointX(i), this.pointY(v))) : []
211
+ }));
212
+ }, ...ngDevMode ? [{ debugName: "drawn" }] : /* istanbul ignore next */ []);
213
+ areas = computed(() => {
214
+ if (!this.showArea() || this.pointCount() <= 1) return [];
215
+ return this.plottedSeries().flatMap((s) => {
216
+ const fills = [];
217
+ let start = -1;
218
+ const close = (end) => {
219
+ if (start >= 0 && end - start >= 2) fills.push({
220
+ key: `${s.index}:${start}`,
221
+ color: s.color,
222
+ d: this.areaPath(s, start, end)
223
+ });
224
+ start = -1;
225
+ };
226
+ s.tops.forEach((v, i) => {
227
+ if (v === null) close(i);
228
+ else if (start < 0) start = i;
229
+ });
230
+ close(s.tops.length);
231
+ return fills;
232
+ });
233
+ }, ...ngDevMode ? [{ debugName: "areas" }] : /* istanbul ignore next */ []);
234
+ areaPath(series, start, end) {
235
+ const at = (i, value) => `${this.pointX(i).toFixed(2)} ${this.pointY(value).toFixed(2)}`;
236
+ const commands = [];
237
+ for (let i = start; i < end; i++) commands.push(`${i === start ? "M" : "L"} ${at(i, series.tops[i] ?? 0)}`);
238
+ for (let i = end - 1; i >= start; i--) commands.push(`L ${at(i, series.bases?.[i] ?? 0)}`);
239
+ commands.push("Z");
240
+ return commands.join(" ");
241
+ }
168
242
  pointX(index) {
169
243
  const count = this.pointCount();
170
244
  if (count <= 1) return this.vbW / 2;
@@ -179,29 +253,63 @@ var WrLineChart = class WrLineChart {
179
253
  }
180
254
  xSlot = computed(() => {
181
255
  const count = this.pointCount();
182
- return count <= 1 ? 100 : 100 / (count - 1);
256
+ return count <= 1 ? 100 : Math.min(100, 100 * this.xAxis().every / (count - 1));
183
257
  }, ...ngDevMode ? [{ debugName: "xSlot" }] : /* istanbul ignore next */ []);
258
+ probeText = computed(() => [...new Set(this.xLabels().map((label) => label.replace(/\r\n?|\n/g, " ")))].join("\n"), ...ngDevMode ? [{ debugName: "probeText" }] : /* istanbul ignore next */ []);
259
+ xAxis = computed(() => {
260
+ const labels = this.xLabels();
261
+ const count = this.pointCount();
262
+ const measured = this.measured();
263
+ const width = measured?.width ?? ASSUMED_WIDTH;
264
+ const inset = measured?.inset ?? ASSUMED_INSET;
265
+ const strip = width + 2 * inset;
266
+ const longest = labels.reduce((most, label) => Math.max(most, label.length), 0);
267
+ const label = Math.min(measured && measured.label > 0 ? measured.label : longest * CHAR_WIDTH, strip);
268
+ const step = count <= 1 ? strip : width / (count - 1);
269
+ const start = (index) => clamp(inset + this.pointX(index) * (width / this.vbW) - label / 2, 0, strip - label);
270
+ const crowds = (from, previousEnd) => from + 1e-6 < previousEnd + LABEL_GAP;
271
+ let every = count <= 1 ? 1 : Math.max(1, Math.ceil((label + LABEL_GAP - 1e-6) / step));
272
+ while (every < labels.length - 1 && crowds(start(every), start(0) + label)) every++;
273
+ const ticks = [];
274
+ let end = Number.NEGATIVE_INFINITY;
275
+ for (let index = 0; index < labels.length; index += every) {
276
+ const from = start(index);
277
+ if (every > 1 && crowds(from, end)) break;
278
+ ticks.push({
279
+ index,
280
+ label: labels[index],
281
+ x: this.xPercent(index)
282
+ });
283
+ end = from + label;
284
+ }
285
+ return {
286
+ every,
287
+ ticks
288
+ };
289
+ }, ...ngDevMode ? [{ debugName: "xAxis" }] : /* istanbul ignore next */ []);
184
290
  hoverPoints = computed(() => {
185
291
  const i = this.activeIndex();
186
292
  if (i === null) return [];
187
- return this.resolvedSeries().flatMap((s) => {
293
+ return this.plottedSeries().flatMap((s) => {
188
294
  const value = s.data[i];
189
- if (value === void 0 || value === null) return [];
190
- const text = this.formatValue(value);
295
+ const plotted = s.tops[i];
296
+ if (value === void 0 || value === null || plotted === void 0 || plotted === null) return [];
297
+ const text = this.numbers.value(value);
191
298
  return [{
299
+ index: s.index,
192
300
  label: s.label,
193
301
  value,
194
302
  text,
195
303
  color: s.color,
196
304
  x: this.pointX(i),
197
- y: this.pointY(value)
305
+ y: this.pointY(plotted)
198
306
  }];
199
307
  });
200
308
  }, ...ngDevMode ? [{ debugName: "hoverPoints" }] : /* istanbul ignore next */ []);
201
309
  hoverLabel = computed(() => {
202
310
  const i = this.activeIndex();
203
311
  if (i === null) return "";
204
- return this.xLabels()[i] ?? String(i);
312
+ return this.xLabels()[i] ?? this.ordinals.format(i + 1);
205
313
  }, ...ngDevMode ? [{ debugName: "hoverLabel" }] : /* istanbul ignore next */ []);
206
314
  onPointerMove(event) {
207
315
  if (!this.tooltip()) return;
@@ -221,26 +329,66 @@ var WrLineChart = class WrLineChart {
221
329
  dotPath(x, y) {
222
330
  return `M ${x.toFixed(2)} ${y.toFixed(2)} h 0`;
223
331
  }
224
- formatValue(value) {
225
- const custom = this.valueFormat();
226
- if (custom) return custom(value);
227
- return (value !== 0 && Math.abs(value) < 1 ? this.smallNumbers : this.numbers).format(value);
332
+ measure() {
333
+ const box = this.svg().nativeElement.getBoundingClientRect();
334
+ if (box.width <= 0) return;
335
+ const inset = box.left - this.plot().nativeElement.getBoundingClientRect().left;
336
+ const label = this.probe()?.nativeElement.getBoundingClientRect().width ?? 0;
337
+ const last = this.measured();
338
+ if (last?.width === box.width && last.inset === inset && last.label === label) return;
339
+ this.measured.set({
340
+ width: box.width,
341
+ inset,
342
+ label
343
+ });
228
344
  }
229
- tickLabels = computed(() => {
230
- const ticks = this.yTicks();
231
- const custom = this.valueFormat();
232
- if (custom) return ticks.map((tick) => custom(tick.value));
233
- const { step } = this.bounds();
234
- const last = lastDigit(step);
235
- const full = new Intl.NumberFormat(this.locale, { maximumFractionDigits: fractionDigits(step) });
236
- const plain = ticks.map((tick) => full.format(tick.value));
237
- const compact = ticks.map(({ value }) => value === 0 ? full.format(0) : new Intl.NumberFormat(this.locale, {
238
- notation: "compact",
239
- maximumSignificantDigits: clamp(magnitude(value) - last + 1, 1, 21)
240
- }).format(value));
241
- const longest = (labels) => Math.max(...labels.map((label) => label.length));
242
- return longest(compact) <= longest(plain) ? compact : plain;
243
- }, ...ngDevMode ? [{ debugName: "tickLabels" }] : /* istanbul ignore next */ []);
345
+ placeTooltip(points, tooltip) {
346
+ const box = this.svg().nativeElement.getBoundingClientRect();
347
+ const plot = this.plot().nativeElement.getBoundingClientRect();
348
+ const rect = tooltip.getBoundingClientRect();
349
+ if (box.height <= 0 || rect.height <= 0 || rect.width <= 0) return;
350
+ const current = this.tooltipPlacement();
351
+ const inset = current === "below" ? box.bottom - rect.bottom : rect.top - box.top;
352
+ const { width, height } = rect;
353
+ const x = box.left + points[0].x / this.vbW * box.width;
354
+ const ys = points.map((p) => box.top + p.y / this.vbH * box.height);
355
+ const across = (left) => clamp(left, plot.left, plot.right - width);
356
+ const top = box.top + inset;
357
+ const candidates = [
358
+ {
359
+ placement: "top",
360
+ left: across(x - width / 2),
361
+ top
362
+ },
363
+ {
364
+ placement: "below",
365
+ left: across(x - width / 2),
366
+ top: box.bottom - inset - height
367
+ },
368
+ x - plot.left > plot.right - x ? {
369
+ placement: "left",
370
+ left: across(x - BESIDE - width),
371
+ top
372
+ } : {
373
+ placement: "right",
374
+ left: across(x + BESIDE),
375
+ top
376
+ }
377
+ ];
378
+ const covers = (c) => x + HOVER_RADIUS > c.left && x - HOVER_RADIUS < c.left + width ? ys.filter((y) => y + HOVER_RADIUS > c.top && y - HOVER_RADIUS < c.top + height).length : 0;
379
+ let best = candidates[0];
380
+ let fewest = covers(best);
381
+ for (const candidate of candidates.slice(1)) {
382
+ if (fewest === 0) break;
383
+ const count = covers(candidate);
384
+ if (count < fewest) {
385
+ best = candidate;
386
+ fewest = count;
387
+ }
388
+ }
389
+ if (best.placement !== current) this.tooltipPlacement.set(best.placement);
390
+ }
391
+ tickLabels = computed(() => this.numbers.ticks(this.yTicks().map((tick) => tick.value), this.bounds().step), ...ngDevMode ? [{ debugName: "tickLabels" }] : /* istanbul ignore next */ []);
244
392
  yAxis = computed(() => {
245
393
  const labels = this.tickLabels();
246
394
  return this.yTicks().map((tick, i) => ({
@@ -249,9 +397,25 @@ var WrLineChart = class WrLineChart {
249
397
  }));
250
398
  }, ...ngDevMode ? [{ debugName: "yAxis" }] : /* istanbul ignore next */ []);
251
399
  viewBox = computed(() => `0 0 ${this.vbW} ${this.vbH}`, ...ngDevMode ? [{ debugName: "viewBox" }] : /* istanbul ignore next */ []);
400
+ tableData = computed(() => {
401
+ const series = this.visibleSeries();
402
+ const labels = this.xLabels();
403
+ const rows = series.length === 0 ? [] : Array.from({ length: this.pointCount() }, (_, i) => ({
404
+ header: labels[i] ?? this.ordinals.format(i + 1),
405
+ cells: series.map((s) => {
406
+ const value = s.data[i];
407
+ return value === void 0 || value === null ? "" : this.numbers.value(value);
408
+ })
409
+ }));
410
+ return {
411
+ caption: this.resolvedAriaLabel(),
412
+ columns: series.map((s) => s.label),
413
+ groups: [{ rows }]
414
+ };
415
+ }, ...ngDevMode ? [{ debugName: "tableData" }] : /* istanbul ignore next */ []);
252
416
  static ɵfac = i0.ɵɵngDeclareFactory({
253
417
  minVersion: "12.0.0",
254
- version: "22.2.3",
418
+ version: "22.2.4",
255
419
  ngImport: i0,
256
420
  type: WrLineChart,
257
421
  deps: [],
@@ -259,7 +423,7 @@ var WrLineChart = class WrLineChart {
259
423
  });
260
424
  static ɵcmp = i0.ɵɵngDeclareComponent({
261
425
  minVersion: "17.0.0",
262
- version: "22.2.3",
426
+ version: "22.2.4",
263
427
  type: WrLineChart,
264
428
  isStandalone: true,
265
429
  selector: "wr-line-chart",
@@ -313,6 +477,20 @@ var WrLineChart = class WrLineChart {
313
477
  isRequired: false,
314
478
  transformFunction: null
315
479
  },
480
+ toggleableLegend: {
481
+ classPropertyName: "toggleableLegend",
482
+ publicName: "toggleableLegend",
483
+ isSignal: true,
484
+ isRequired: false,
485
+ transformFunction: null
486
+ },
487
+ hiddenSeries: {
488
+ classPropertyName: "hiddenSeries",
489
+ publicName: "hiddenSeries",
490
+ isSignal: true,
491
+ isRequired: false,
492
+ transformFunction: null
493
+ },
316
494
  showDots: {
317
495
  classPropertyName: "showDots",
318
496
  publicName: "showDots",
@@ -320,6 +498,27 @@ var WrLineChart = class WrLineChart {
320
498
  isRequired: false,
321
499
  transformFunction: null
322
500
  },
501
+ showArea: {
502
+ classPropertyName: "showArea",
503
+ publicName: "showArea",
504
+ isSignal: true,
505
+ isRequired: false,
506
+ transformFunction: null
507
+ },
508
+ stacked: {
509
+ classPropertyName: "stacked",
510
+ publicName: "stacked",
511
+ isSignal: true,
512
+ isRequired: false,
513
+ transformFunction: null
514
+ },
515
+ dataTable: {
516
+ classPropertyName: "dataTable",
517
+ publicName: "dataTable",
518
+ isSignal: true,
519
+ isRequired: false,
520
+ transformFunction: null
521
+ },
323
522
  tooltip: {
324
523
  classPropertyName: "tooltip",
325
524
  publicName: "tooltip",
@@ -328,22 +527,73 @@ var WrLineChart = class WrLineChart {
328
527
  transformFunction: null
329
528
  }
330
529
  },
331
- host: { classAttribute: "wr-line-chart" },
332
- viewQueries: [{
333
- propertyName: "svg",
334
- first: true,
335
- predicate: ["svg"],
336
- descendants: true,
337
- isSignal: true
338
- }],
530
+ outputs: { hiddenSeries: "hiddenSeriesChange" },
531
+ host: {
532
+ properties: {
533
+ "class.wr-line-chart--area": "showArea()",
534
+ "class.wr-line-chart--stacked": "stacked()"
535
+ },
536
+ classAttribute: "wr-line-chart"
537
+ },
538
+ viewQueries: [
539
+ {
540
+ propertyName: "svg",
541
+ first: true,
542
+ predicate: ["svg"],
543
+ descendants: true,
544
+ isSignal: true
545
+ },
546
+ {
547
+ propertyName: "plot",
548
+ first: true,
549
+ predicate: ["plot"],
550
+ descendants: true,
551
+ isSignal: true
552
+ },
553
+ {
554
+ propertyName: "probe",
555
+ first: true,
556
+ predicate: ["probe"],
557
+ descendants: true,
558
+ isSignal: true
559
+ },
560
+ {
561
+ propertyName: "tooltipEl",
562
+ first: true,
563
+ predicate: ["tooltip"],
564
+ descendants: true,
565
+ isSignal: true
566
+ }
567
+ ],
339
568
  ngImport: i0,
340
- template: "@let hovered = activeIndex();\n@if (showLegend() && resolvedSeries().length > 0) {\n <ul class=\"wr-line-chart__legend\">\n @for (s of resolvedSeries(); track s.label) {\n <li class=\"wr-line-chart__legend-item\">\n <!-- The swatch draws the series' own dash, not a solid block. A legend\n that pairs a coloured square with a name leaves the reader to match\n the square to the LINE, and matching by colour is the step the\n patterns exist to remove. -->\n <svg class=\"wr-line-chart__swatch\" viewBox=\"0 0 16 2\" aria-hidden=\"true\">\n <line\n x1=\"0\"\n y1=\"1\"\n x2=\"16\"\n y2=\"1\"\n [attr.stroke]=\"s.color\"\n [attr.stroke-dasharray]=\"s.dash || null\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n <span>{{ s.label }}</span>\n </li>\n }\n </ul>\n}\n\n<!-- Two columns: the y-axis labels at inline start, the drawing beside them, and the\n x labels under the drawing only, so their percentages are the drawing's. -->\n<div class=\"wr-line-chart__body\">\n @if (showGrid()) {\n <!-- The tick labels are HTML beside the drawing rather than `<text>` inside it: the\n drawing stretches with `preserveAspectRatio=\"none\"` and its type stretched with\n it. In flow, so the column is exactly as wide as the longest label; each one\n hands the stylesheet the y of its own gridline, as the x labels hand it their x.\n Hidden, as they were inside the plot's `img`: the plot's name is what is\n announced. -->\n <div class=\"wr-line-chart__y-axis\" aria-hidden=\"true\">\n @for (tick of yAxis(); track $index) {\n <span class=\"wr-line-chart__tick\" [style.--wr-line-chart-y]=\"tick.y\">{{ tick.label }}</span>\n }\n </div>\n }\n\n <div\n class=\"wr-line-chart__plot\"\n role=\"img\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [style.height.px]=\"height()\"\n (mousemove)=\"onPointerMove($event)\"\n (mouseleave)=\"onPointerLeave()\"\n >\n <!-- Named, where it was the only unnamed element in the component. The legend\n swatch is an `<svg>` too now, so `querySelector('svg')` no longer means\n \"the chart\" — and a plot that nothing can address by name is one a\n consumer's stylesheet and a spec both have to reach by position. -->\n <svg #svg class=\"wr-line-chart__svg\" [attr.viewBox]=\"viewBox()\" preserveAspectRatio=\"none\">\n @if (showGrid()) {\n @for (tick of yTicks(); track tick.value) {\n <line\n class=\"wr-line-chart__grid-line\"\n x1=\"0\"\n [attr.x2]=\"vbW\"\n [attr.y1]=\"tick.y\"\n [attr.y2]=\"tick.y\"\n stroke=\"color-mix(in srgb, var(--wr-border-base) 70%, transparent)\"\n stroke-width=\"1\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n }\n\n @for (s of resolvedSeries(); track s.label) {\n <path\n class=\"wr-line-chart__line\"\n [attr.d]=\"pathFor(s)\"\n fill=\"none\"\n [attr.stroke]=\"s.color\"\n [attr.stroke-dasharray]=\"s.dash || null\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n @if (showDots()) {\n @for (v of s.data; track $index; let i = $index) {\n <!-- A hole in the data gets no dot: the index still belongs to it, so the\n points after it stay on their own x. A dot is a zero-length line with a\n round cap and a non-scaling stroke, which stays a 6px circle however the\n drawing stretches; a `<circle>` scaled with it, into a 3 × 5px oval on a\n phone and a 9 × 5px one at 1920px. -->\n @if (v !== null) {\n <path\n class=\"wr-line-chart__dot\"\n [attr.d]=\"dotPath(pointX(i), pointY(v))\"\n fill=\"none\"\n [attr.stroke]=\"s.color\"\n stroke-width=\"6\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n }\n }\n }\n\n @if (hovered !== null && hoverPoints().length > 0) {\n <line\n class=\"wr-line-chart__crosshair\"\n [attr.x1]=\"pointX(hovered)\"\n [attr.x2]=\"pointX(hovered)\"\n y1=\"0\"\n [attr.y2]=\"vbH\"\n stroke=\"var(--wr-color-on-surface-muted)\"\n stroke-width=\"1\"\n stroke-dasharray=\"3 3\"\n vector-effect=\"non-scaling-stroke\"\n />\n <!-- A ring of the series' colour round a white centre, drawn the way a dot is\n and for the same reason. -->\n @for (p of hoverPoints(); track p.label) {\n <path\n [attr.d]=\"dotPath(p.x, p.y)\"\n fill=\"none\"\n [attr.stroke]=\"p.color\"\n stroke-width=\"12\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n <path\n [attr.d]=\"dotPath(p.x, p.y)\"\n fill=\"none\"\n stroke=\"var(--wr-color-white)\"\n stroke-width=\"8\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n }\n </svg>\n\n @if (hovered !== null && hoverPoints().length > 0) {\n <!-- The layer covers the plot and is what the tooltip's `cqw` measures. It is out of flow, so the containment it turns on\n costs the plot's own sizing nothing. The tooltip takes the same\n `--wr-line-chart-x` the x labels take, and the same clamp: centred on its\n point, never past either end. -->\n <div class=\"wr-line-chart__tooltip-layer\">\n <div class=\"wr-line-chart__tooltip\" [style.--wr-line-chart-x]=\"xPercent(hovered)\">\n <div class=\"wr-line-chart__tooltip-label\">{{ hoverLabel() }}</div>\n @for (p of hoverPoints(); track p.label) {\n <div class=\"wr-line-chart__tooltip-row\">\n <span class=\"wr-line-chart__swatch\" [style.background]=\"p.color\"></span>\n <span class=\"wr-line-chart__tooltip-name\">{{ p.label }}</span>\n <span class=\"wr-line-chart__tooltip-value\">{{ p.text }}</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n @if (xLabels().length > 0) {\n <!-- The strip is as wide as the plot, and hands the stylesheet the distance between\n two points; each label hands it the x of the point it names. Both are percentages\n of the drawing's width, so they track the drawing at any size: the stylesheet\n centres a label on its point and ellipsises it past its slot. Laying the labels\n out as equal centred flex slots instead is bar-chart geometry: only the middle\n label landed on its dot, and the outer ones sat up to half a column away. -->\n <div class=\"wr-line-chart__x-labels\" [style.--wr-line-chart-x-slot]=\"xSlot()\">\n @for (label of xLabels(); track $index) {\n <span class=\"wr-line-chart__x-label\" [style.--wr-line-chart-x]=\"xPercent($index)\">{{ label }}</span>\n }\n </div>\n }\n</div>\n",
569
+ template: "@let hovered = activeIndex();\n@if (showLegend() && resolvedSeries().length > 0) {\n <!-- Every row keys its series by the series' own dash rather than a solid block: a\n coloured square leaves the reader to match it to the LINE, and matching by colour\n is the step the patterns exist to remove. Rows are tracked by position, so two\n series that share a label are two rows. -->\n <ul\n wr-chart-legend\n class=\"wr-line-chart__legend\"\n [items]=\"legendItems()\"\n [toggleable]=\"toggleableLegend()\"\n [(hiddenSeries)]=\"hiddenSeries\"\n ></ul>\n}\n\n<!-- Two columns: the y-axis labels at inline start, the drawing beside them, and the\n x labels under the drawing only, so their percentages are the drawing's. -->\n<div class=\"wr-line-chart__body\">\n @if (showGrid()) {\n <!-- The tick labels are HTML beside the drawing rather than `<text>` inside it: the\n drawing stretches with `preserveAspectRatio=\"none\"` and its type stretched with\n it. In flow, so the column is exactly as wide as the longest label; each one\n hands the stylesheet the y of its own gridline, as the x labels hand it their x.\n Hidden, as they were inside the plot's `img`: the plot's name is what is\n announced. -->\n <div class=\"wr-line-chart__y-axis\" aria-hidden=\"true\">\n @for (tick of yAxis(); track $index) {\n <span class=\"wr-line-chart__tick\" [style.--wr-line-chart-y]=\"tick.y\">{{ tick.label }}</span>\n }\n </div>\n }\n\n <div\n #plot\n class=\"wr-line-chart__plot\"\n role=\"img\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [style.height.px]=\"height()\"\n (mousemove)=\"onPointerMove($event)\"\n (mouseleave)=\"onPointerLeave()\"\n >\n <!-- Named, where it was the only unnamed element in the component. The legend\n swatch is an `<svg>` too now, so `querySelector('svg')` no longer means\n \"the chart\" — and a plot that nothing can address by name is one a\n consumer's stylesheet and a spec both have to reach by position. -->\n <svg #svg class=\"wr-line-chart__svg\" [attr.viewBox]=\"viewBox()\" preserveAspectRatio=\"none\">\n @if (showGrid()) {\n @for (tick of yTicks(); track tick.value) {\n <!-- The colour is the stylesheet's, from `--wr-line-chart-grid-color`, so forced\n colors can swap it for the system's own. -->\n <line\n class=\"wr-line-chart__grid-line\"\n x1=\"0\"\n [attr.x2]=\"vbW\"\n [attr.y1]=\"tick.y\"\n [attr.y2]=\"tick.y\"\n stroke-width=\"1\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n }\n\n <!-- Every fill before every line, so the lines and their dashes stay on top where\n the fills overlap and the series are still told apart by shape. The opacity is\n the stylesheet's, from `--wr-line-chart-area-opacity`. -->\n @for (area of areas(); track area.key) {\n <path class=\"wr-line-chart__area\" [attr.d]=\"area.d\" [attr.fill]=\"area.color\" stroke=\"none\" />\n }\n\n <!-- By position, not by label: two series may share one, and a duplicate key\n makes Angular re-create rows it cannot tell apart. Each is drawn at its\n plotted values, which under `stacked` are the tops of its band. Every path is\n built once per data change (`drawn`), so hovering rebuilds none of them. -->\n @for (s of drawn(); track s.index) {\n <path\n class=\"wr-line-chart__line\"\n [attr.d]=\"s.d\"\n fill=\"none\"\n [attr.stroke]=\"s.color\"\n [attr.stroke-dasharray]=\"s.dash || null\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n @for (dot of s.dots; track $index) {\n <!-- A hole in the data gets no dot: the index still belongs to it, so the\n points after it stay on their own x. A dot is a zero-length line with a\n round cap and a non-scaling stroke, which stays a 6px circle however the\n drawing stretches; a `<circle>` scaled with it, into a 3 × 5px oval on a\n phone and a 9 × 5px one at 1920px. -->\n @if (dot !== null) {\n <path\n class=\"wr-line-chart__dot\"\n [attr.d]=\"dot\"\n fill=\"none\"\n [attr.stroke]=\"s.color\"\n stroke-width=\"6\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n }\n }\n\n @if (hovered !== null && hoverPoints().length > 0) {\n <line\n class=\"wr-line-chart__crosshair\"\n [attr.x1]=\"pointX(hovered)\"\n [attr.x2]=\"pointX(hovered)\"\n y1=\"0\"\n [attr.y2]=\"vbH\"\n stroke-width=\"1\"\n stroke-dasharray=\"3 3\"\n vector-effect=\"non-scaling-stroke\"\n />\n <!-- A ring of the series' colour round a surface-coloured centre, drawn the way a\n dot is and for the same reason. The centre's colour is the stylesheet's, from\n `--wr-line-chart-hover-center`. -->\n @for (p of hoverPoints(); track p.index) {\n <path\n class=\"wr-line-chart__hover-dot\"\n [attr.d]=\"dotPath(p.x, p.y)\"\n fill=\"none\"\n [attr.stroke]=\"p.color\"\n stroke-width=\"12\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n <path\n class=\"wr-line-chart__hover-dot-center\"\n [attr.d]=\"dotPath(p.x, p.y)\"\n fill=\"none\"\n stroke-width=\"8\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n }\n </svg>\n\n @if (hovered !== null && hoverPoints().length > 0) {\n <!-- The layer covers the plot and is what the tooltip's `cqw` measures. It is out of\n flow, so the containment it turns on costs the plot's own sizing nothing. The\n tooltip takes the same `--wr-line-chart-x` the x labels take, and the same\n clamp: centred on its point, never past either end. At the top of the plot, or\n where that would cover a marker it reads, at the bottom (`--below`) or beside the\n crosshair (`--left`, `--right`). -->\n <div class=\"wr-line-chart__tooltip-layer\">\n <div\n #tooltip\n class=\"wr-line-chart__tooltip\"\n [class.wr-line-chart__tooltip--below]=\"tooltipPlacement() === 'below'\"\n [class.wr-line-chart__tooltip--left]=\"tooltipPlacement() === 'left'\"\n [class.wr-line-chart__tooltip--right]=\"tooltipPlacement() === 'right'\"\n [style.--wr-line-chart-x]=\"xPercent(hovered)\"\n >\n <div class=\"wr-line-chart__tooltip-label\">{{ hoverLabel() }}</div>\n @for (p of hoverPoints(); track p.index) {\n <div class=\"wr-line-chart__tooltip-row\">\n <span class=\"wr-line-chart__swatch\" [style.background]=\"p.color\"></span>\n <span class=\"wr-line-chart__tooltip-name\">{{ p.label }}</span>\n <span class=\"wr-line-chart__tooltip-value\">{{ p.text }}</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n @if (xLabels().length > 0) {\n <!-- The strip is as wide as the plot, and hands the stylesheet the distance between\n two printed labels; each label hands it the x of the point it names. Both are\n percentages of the drawing's width, so they track the drawing at any size: the\n stylesheet centres a label on its point and ellipsises it past its slot. Laying the\n labels out as equal centred flex slots instead is bar-chart geometry: only the\n middle label landed on its dot, and the outer ones sat up to half a column away.\n The hidden copy of every label, a line each, is what the room they need is\n measured against: it is as wide as the widest. -->\n <div class=\"wr-line-chart__x-labels\" [style.--wr-line-chart-x-slot]=\"xSlot()\">\n <span #probe class=\"wr-line-chart__x-probe\" aria-hidden=\"true\">{{ probeText() }}</span>\n @for (tick of xAxis().ticks; track tick.index) {\n <span class=\"wr-line-chart__x-label\" [style.--wr-line-chart-x]=\"tick.x\">{{ tick.label }}</span>\n }\n </div>\n }\n</div>\n\n@if (dataTable()) {\n <!-- The figures for a screen reader, beside the plot's `img` and never inside it:\n `img` makes everything it holds presentational. Clipped to nothing by its own\n stylesheet, so it takes no room and draws nothing. -->\n <wr-chart-table [data]=\"tableData()\" />\n}\n",
570
+ dependencies: [{
571
+ kind: "component",
572
+ type: WrChartLegend,
573
+ selector: "ul[wr-chart-legend]",
574
+ inputs: [
575
+ "items",
576
+ "toggleable",
577
+ "hiddenSeries",
578
+ "ariaLabel"
579
+ ],
580
+ outputs: ["hiddenSeriesChange", "toggled"]
581
+ }, {
582
+ kind: "component",
583
+ type: WrChartTable,
584
+ selector: "wr-chart-table",
585
+ inputs: ["data"]
586
+ }],
587
+ viewProviders: [{
588
+ provide: WR_CHART_LEGEND_BLOCK,
589
+ useValue: "wr-line-chart"
590
+ }],
341
591
  encapsulation: i0.ViewEncapsulation.None
342
592
  });
343
593
  };
344
594
  i0.ɵɵngDeclareClassMetadata({
345
595
  minVersion: "12.0.0",
346
- version: "22.2.3",
596
+ version: "22.2.4",
347
597
  ngImport: i0,
348
598
  type: WrLineChart,
349
599
  decorators: [{
@@ -351,8 +601,17 @@ i0.ɵɵngDeclareClassMetadata({
351
601
  args: [{
352
602
  selector: "wr-line-chart",
353
603
  encapsulation: ViewEncapsulation.None,
354
- host: { class: "wr-line-chart" },
355
- template: "@let hovered = activeIndex();\n@if (showLegend() && resolvedSeries().length > 0) {\n <ul class=\"wr-line-chart__legend\">\n @for (s of resolvedSeries(); track s.label) {\n <li class=\"wr-line-chart__legend-item\">\n <!-- The swatch draws the series' own dash, not a solid block. A legend\n that pairs a coloured square with a name leaves the reader to match\n the square to the LINE, and matching by colour is the step the\n patterns exist to remove. -->\n <svg class=\"wr-line-chart__swatch\" viewBox=\"0 0 16 2\" aria-hidden=\"true\">\n <line\n x1=\"0\"\n y1=\"1\"\n x2=\"16\"\n y2=\"1\"\n [attr.stroke]=\"s.color\"\n [attr.stroke-dasharray]=\"s.dash || null\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n <span>{{ s.label }}</span>\n </li>\n }\n </ul>\n}\n\n<!-- Two columns: the y-axis labels at inline start, the drawing beside them, and the\n x labels under the drawing only, so their percentages are the drawing's. -->\n<div class=\"wr-line-chart__body\">\n @if (showGrid()) {\n <!-- The tick labels are HTML beside the drawing rather than `<text>` inside it: the\n drawing stretches with `preserveAspectRatio=\"none\"` and its type stretched with\n it. In flow, so the column is exactly as wide as the longest label; each one\n hands the stylesheet the y of its own gridline, as the x labels hand it their x.\n Hidden, as they were inside the plot's `img`: the plot's name is what is\n announced. -->\n <div class=\"wr-line-chart__y-axis\" aria-hidden=\"true\">\n @for (tick of yAxis(); track $index) {\n <span class=\"wr-line-chart__tick\" [style.--wr-line-chart-y]=\"tick.y\">{{ tick.label }}</span>\n }\n </div>\n }\n\n <div\n class=\"wr-line-chart__plot\"\n role=\"img\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [style.height.px]=\"height()\"\n (mousemove)=\"onPointerMove($event)\"\n (mouseleave)=\"onPointerLeave()\"\n >\n <!-- Named, where it was the only unnamed element in the component. The legend\n swatch is an `<svg>` too now, so `querySelector('svg')` no longer means\n \"the chart\" — and a plot that nothing can address by name is one a\n consumer's stylesheet and a spec both have to reach by position. -->\n <svg #svg class=\"wr-line-chart__svg\" [attr.viewBox]=\"viewBox()\" preserveAspectRatio=\"none\">\n @if (showGrid()) {\n @for (tick of yTicks(); track tick.value) {\n <line\n class=\"wr-line-chart__grid-line\"\n x1=\"0\"\n [attr.x2]=\"vbW\"\n [attr.y1]=\"tick.y\"\n [attr.y2]=\"tick.y\"\n stroke=\"color-mix(in srgb, var(--wr-border-base) 70%, transparent)\"\n stroke-width=\"1\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n }\n\n @for (s of resolvedSeries(); track s.label) {\n <path\n class=\"wr-line-chart__line\"\n [attr.d]=\"pathFor(s)\"\n fill=\"none\"\n [attr.stroke]=\"s.color\"\n [attr.stroke-dasharray]=\"s.dash || null\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n @if (showDots()) {\n @for (v of s.data; track $index; let i = $index) {\n <!-- A hole in the data gets no dot: the index still belongs to it, so the\n points after it stay on their own x. A dot is a zero-length line with a\n round cap and a non-scaling stroke, which stays a 6px circle however the\n drawing stretches; a `<circle>` scaled with it, into a 3 × 5px oval on a\n phone and a 9 × 5px one at 1920px. -->\n @if (v !== null) {\n <path\n class=\"wr-line-chart__dot\"\n [attr.d]=\"dotPath(pointX(i), pointY(v))\"\n fill=\"none\"\n [attr.stroke]=\"s.color\"\n stroke-width=\"6\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n }\n }\n }\n\n @if (hovered !== null && hoverPoints().length > 0) {\n <line\n class=\"wr-line-chart__crosshair\"\n [attr.x1]=\"pointX(hovered)\"\n [attr.x2]=\"pointX(hovered)\"\n y1=\"0\"\n [attr.y2]=\"vbH\"\n stroke=\"var(--wr-color-on-surface-muted)\"\n stroke-width=\"1\"\n stroke-dasharray=\"3 3\"\n vector-effect=\"non-scaling-stroke\"\n />\n <!-- A ring of the series' colour round a white centre, drawn the way a dot is\n and for the same reason. -->\n @for (p of hoverPoints(); track p.label) {\n <path\n [attr.d]=\"dotPath(p.x, p.y)\"\n fill=\"none\"\n [attr.stroke]=\"p.color\"\n stroke-width=\"12\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n <path\n [attr.d]=\"dotPath(p.x, p.y)\"\n fill=\"none\"\n stroke=\"var(--wr-color-white)\"\n stroke-width=\"8\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n }\n </svg>\n\n @if (hovered !== null && hoverPoints().length > 0) {\n <!-- The layer covers the plot and is what the tooltip's `cqw` measures. It is out of flow, so the containment it turns on\n costs the plot's own sizing nothing. The tooltip takes the same\n `--wr-line-chart-x` the x labels take, and the same clamp: centred on its\n point, never past either end. -->\n <div class=\"wr-line-chart__tooltip-layer\">\n <div class=\"wr-line-chart__tooltip\" [style.--wr-line-chart-x]=\"xPercent(hovered)\">\n <div class=\"wr-line-chart__tooltip-label\">{{ hoverLabel() }}</div>\n @for (p of hoverPoints(); track p.label) {\n <div class=\"wr-line-chart__tooltip-row\">\n <span class=\"wr-line-chart__swatch\" [style.background]=\"p.color\"></span>\n <span class=\"wr-line-chart__tooltip-name\">{{ p.label }}</span>\n <span class=\"wr-line-chart__tooltip-value\">{{ p.text }}</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n @if (xLabels().length > 0) {\n <!-- The strip is as wide as the plot, and hands the stylesheet the distance between\n two points; each label hands it the x of the point it names. Both are percentages\n of the drawing's width, so they track the drawing at any size: the stylesheet\n centres a label on its point and ellipsises it past its slot. Laying the labels\n out as equal centred flex slots instead is bar-chart geometry: only the middle\n label landed on its dot, and the outer ones sat up to half a column away. -->\n <div class=\"wr-line-chart__x-labels\" [style.--wr-line-chart-x-slot]=\"xSlot()\">\n @for (label of xLabels(); track $index) {\n <span class=\"wr-line-chart__x-label\" [style.--wr-line-chart-x]=\"xPercent($index)\">{{ label }}</span>\n }\n </div>\n }\n</div>\n"
604
+ host: {
605
+ class: "wr-line-chart",
606
+ "[class.wr-line-chart--area]": "showArea()",
607
+ "[class.wr-line-chart--stacked]": "stacked()"
608
+ },
609
+ imports: [WrChartLegend, WrChartTable],
610
+ viewProviders: [{
611
+ provide: WR_CHART_LEGEND_BLOCK,
612
+ useValue: "wr-line-chart"
613
+ }],
614
+ template: "@let hovered = activeIndex();\n@if (showLegend() && resolvedSeries().length > 0) {\n <!-- Every row keys its series by the series' own dash rather than a solid block: a\n coloured square leaves the reader to match it to the LINE, and matching by colour\n is the step the patterns exist to remove. Rows are tracked by position, so two\n series that share a label are two rows. -->\n <ul\n wr-chart-legend\n class=\"wr-line-chart__legend\"\n [items]=\"legendItems()\"\n [toggleable]=\"toggleableLegend()\"\n [(hiddenSeries)]=\"hiddenSeries\"\n ></ul>\n}\n\n<!-- Two columns: the y-axis labels at inline start, the drawing beside them, and the\n x labels under the drawing only, so their percentages are the drawing's. -->\n<div class=\"wr-line-chart__body\">\n @if (showGrid()) {\n <!-- The tick labels are HTML beside the drawing rather than `<text>` inside it: the\n drawing stretches with `preserveAspectRatio=\"none\"` and its type stretched with\n it. In flow, so the column is exactly as wide as the longest label; each one\n hands the stylesheet the y of its own gridline, as the x labels hand it their x.\n Hidden, as they were inside the plot's `img`: the plot's name is what is\n announced. -->\n <div class=\"wr-line-chart__y-axis\" aria-hidden=\"true\">\n @for (tick of yAxis(); track $index) {\n <span class=\"wr-line-chart__tick\" [style.--wr-line-chart-y]=\"tick.y\">{{ tick.label }}</span>\n }\n </div>\n }\n\n <div\n #plot\n class=\"wr-line-chart__plot\"\n role=\"img\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [style.height.px]=\"height()\"\n (mousemove)=\"onPointerMove($event)\"\n (mouseleave)=\"onPointerLeave()\"\n >\n <!-- Named, where it was the only unnamed element in the component. The legend\n swatch is an `<svg>` too now, so `querySelector('svg')` no longer means\n \"the chart\" — and a plot that nothing can address by name is one a\n consumer's stylesheet and a spec both have to reach by position. -->\n <svg #svg class=\"wr-line-chart__svg\" [attr.viewBox]=\"viewBox()\" preserveAspectRatio=\"none\">\n @if (showGrid()) {\n @for (tick of yTicks(); track tick.value) {\n <!-- The colour is the stylesheet's, from `--wr-line-chart-grid-color`, so forced\n colors can swap it for the system's own. -->\n <line\n class=\"wr-line-chart__grid-line\"\n x1=\"0\"\n [attr.x2]=\"vbW\"\n [attr.y1]=\"tick.y\"\n [attr.y2]=\"tick.y\"\n stroke-width=\"1\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n }\n\n <!-- Every fill before every line, so the lines and their dashes stay on top where\n the fills overlap and the series are still told apart by shape. The opacity is\n the stylesheet's, from `--wr-line-chart-area-opacity`. -->\n @for (area of areas(); track area.key) {\n <path class=\"wr-line-chart__area\" [attr.d]=\"area.d\" [attr.fill]=\"area.color\" stroke=\"none\" />\n }\n\n <!-- By position, not by label: two series may share one, and a duplicate key\n makes Angular re-create rows it cannot tell apart. Each is drawn at its\n plotted values, which under `stacked` are the tops of its band. Every path is\n built once per data change (`drawn`), so hovering rebuilds none of them. -->\n @for (s of drawn(); track s.index) {\n <path\n class=\"wr-line-chart__line\"\n [attr.d]=\"s.d\"\n fill=\"none\"\n [attr.stroke]=\"s.color\"\n [attr.stroke-dasharray]=\"s.dash || null\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n @for (dot of s.dots; track $index) {\n <!-- A hole in the data gets no dot: the index still belongs to it, so the\n points after it stay on their own x. A dot is a zero-length line with a\n round cap and a non-scaling stroke, which stays a 6px circle however the\n drawing stretches; a `<circle>` scaled with it, into a 3 × 5px oval on a\n phone and a 9 × 5px one at 1920px. -->\n @if (dot !== null) {\n <path\n class=\"wr-line-chart__dot\"\n [attr.d]=\"dot\"\n fill=\"none\"\n [attr.stroke]=\"s.color\"\n stroke-width=\"6\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n }\n }\n\n @if (hovered !== null && hoverPoints().length > 0) {\n <line\n class=\"wr-line-chart__crosshair\"\n [attr.x1]=\"pointX(hovered)\"\n [attr.x2]=\"pointX(hovered)\"\n y1=\"0\"\n [attr.y2]=\"vbH\"\n stroke-width=\"1\"\n stroke-dasharray=\"3 3\"\n vector-effect=\"non-scaling-stroke\"\n />\n <!-- A ring of the series' colour round a surface-coloured centre, drawn the way a\n dot is and for the same reason. The centre's colour is the stylesheet's, from\n `--wr-line-chart-hover-center`. -->\n @for (p of hoverPoints(); track p.index) {\n <path\n class=\"wr-line-chart__hover-dot\"\n [attr.d]=\"dotPath(p.x, p.y)\"\n fill=\"none\"\n [attr.stroke]=\"p.color\"\n stroke-width=\"12\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n <path\n class=\"wr-line-chart__hover-dot-center\"\n [attr.d]=\"dotPath(p.x, p.y)\"\n fill=\"none\"\n stroke-width=\"8\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n }\n </svg>\n\n @if (hovered !== null && hoverPoints().length > 0) {\n <!-- The layer covers the plot and is what the tooltip's `cqw` measures. It is out of\n flow, so the containment it turns on costs the plot's own sizing nothing. The\n tooltip takes the same `--wr-line-chart-x` the x labels take, and the same\n clamp: centred on its point, never past either end. At the top of the plot, or\n where that would cover a marker it reads, at the bottom (`--below`) or beside the\n crosshair (`--left`, `--right`). -->\n <div class=\"wr-line-chart__tooltip-layer\">\n <div\n #tooltip\n class=\"wr-line-chart__tooltip\"\n [class.wr-line-chart__tooltip--below]=\"tooltipPlacement() === 'below'\"\n [class.wr-line-chart__tooltip--left]=\"tooltipPlacement() === 'left'\"\n [class.wr-line-chart__tooltip--right]=\"tooltipPlacement() === 'right'\"\n [style.--wr-line-chart-x]=\"xPercent(hovered)\"\n >\n <div class=\"wr-line-chart__tooltip-label\">{{ hoverLabel() }}</div>\n @for (p of hoverPoints(); track p.index) {\n <div class=\"wr-line-chart__tooltip-row\">\n <span class=\"wr-line-chart__swatch\" [style.background]=\"p.color\"></span>\n <span class=\"wr-line-chart__tooltip-name\">{{ p.label }}</span>\n <span class=\"wr-line-chart__tooltip-value\">{{ p.text }}</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n @if (xLabels().length > 0) {\n <!-- The strip is as wide as the plot, and hands the stylesheet the distance between\n two printed labels; each label hands it the x of the point it names. Both are\n percentages of the drawing's width, so they track the drawing at any size: the\n stylesheet centres a label on its point and ellipsises it past its slot. Laying the\n labels out as equal centred flex slots instead is bar-chart geometry: only the\n middle label landed on its dot, and the outer ones sat up to half a column away.\n The hidden copy of every label, a line each, is what the room they need is\n measured against: it is as wide as the widest. -->\n <div class=\"wr-line-chart__x-labels\" [style.--wr-line-chart-x-slot]=\"xSlot()\">\n <span #probe class=\"wr-line-chart__x-probe\" aria-hidden=\"true\">{{ probeText() }}</span>\n @for (tick of xAxis().ticks; track tick.index) {\n <span class=\"wr-line-chart__x-label\" [style.--wr-line-chart-x]=\"tick.x\">{{ tick.label }}</span>\n }\n </div>\n }\n</div>\n\n@if (dataTable()) {\n <!-- The figures for a screen reader, beside the plot's `img` and never inside it:\n `img` makes everything it holds presentational. Clipped to nothing by its own\n stylesheet, so it takes no room and draws nothing. -->\n <wr-chart-table [data]=\"tableData()\" />\n}\n"
356
615
  }]
357
616
  }],
358
617
  ctorParameters: () => [],
@@ -413,6 +672,25 @@ i0.ɵɵngDeclareClassMetadata({
413
672
  required: false
414
673
  }]
415
674
  }],
675
+ toggleableLegend: [{
676
+ type: i0.Input,
677
+ args: [{
678
+ isSignal: true,
679
+ alias: "toggleableLegend",
680
+ required: false
681
+ }]
682
+ }],
683
+ hiddenSeries: [{
684
+ type: i0.Input,
685
+ args: [{
686
+ isSignal: true,
687
+ alias: "hiddenSeries",
688
+ required: false
689
+ }]
690
+ }, {
691
+ type: i0.Output,
692
+ args: ["hiddenSeriesChange"]
693
+ }],
416
694
  showDots: [{
417
695
  type: i0.Input,
418
696
  args: [{
@@ -421,6 +699,30 @@ i0.ɵɵngDeclareClassMetadata({
421
699
  required: false
422
700
  }]
423
701
  }],
702
+ showArea: [{
703
+ type: i0.Input,
704
+ args: [{
705
+ isSignal: true,
706
+ alias: "showArea",
707
+ required: false
708
+ }]
709
+ }],
710
+ stacked: [{
711
+ type: i0.Input,
712
+ args: [{
713
+ isSignal: true,
714
+ alias: "stacked",
715
+ required: false
716
+ }]
717
+ }],
718
+ dataTable: [{
719
+ type: i0.Input,
720
+ args: [{
721
+ isSignal: true,
722
+ alias: "dataTable",
723
+ required: false
724
+ }]
725
+ }],
424
726
  tooltip: [{
425
727
  type: i0.Input,
426
728
  args: [{
@@ -432,6 +734,18 @@ i0.ɵɵngDeclareClassMetadata({
432
734
  svg: [{
433
735
  type: i0.ViewChild,
434
736
  args: ["svg", { isSignal: true }]
737
+ }],
738
+ plot: [{
739
+ type: i0.ViewChild,
740
+ args: ["plot", { isSignal: true }]
741
+ }],
742
+ probe: [{
743
+ type: i0.ViewChild,
744
+ args: ["probe", { isSignal: true }]
745
+ }],
746
+ tooltipEl: [{
747
+ type: i0.ViewChild,
748
+ args: ["tooltip", { isSignal: true }]
435
749
  }]
436
750
  }
437
751
  });