@cloudscape-design/chart-components 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/LICENSE +175 -0
  2. package/NOTICE +1 -0
  3. package/README.md +25 -0
  4. package/cartesian-chart/chart-cartesian-internal.d.ts +10 -0
  5. package/cartesian-chart/chart-cartesian-internal.js +99 -0
  6. package/cartesian-chart/chart-cartesian-internal.js.map +1 -0
  7. package/cartesian-chart/chart-series-cartesian.d.ts +7 -0
  8. package/cartesian-chart/chart-series-cartesian.js +95 -0
  9. package/cartesian-chart/chart-series-cartesian.js.map +1 -0
  10. package/cartesian-chart/index.d.ts +5 -0
  11. package/cartesian-chart/index.js +133 -0
  12. package/cartesian-chart/index.js.map +1 -0
  13. package/cartesian-chart/interfaces.d.ts +166 -0
  14. package/cartesian-chart/interfaces.js +4 -0
  15. package/cartesian-chart/interfaces.js.map +1 -0
  16. package/cartesian-chart/test-classes/styles.css.js +6 -0
  17. package/cartesian-chart/test-classes/styles.scoped.css +7 -0
  18. package/cartesian-chart/test-classes/styles.selectors.js +7 -0
  19. package/core/chart-api/chart-extra-axis-titles.d.ts +10 -0
  20. package/core/chart-api/chart-extra-axis-titles.js +42 -0
  21. package/core/chart-api/chart-extra-axis-titles.js.map +1 -0
  22. package/core/chart-api/chart-extra-context.d.ts +41 -0
  23. package/core/chart-api/chart-extra-context.js +93 -0
  24. package/core/chart-api/chart-extra-context.js.map +1 -0
  25. package/core/chart-api/chart-extra-highlight.d.ts +20 -0
  26. package/core/chart-api/chart-extra-highlight.js +205 -0
  27. package/core/chart-api/chart-extra-highlight.js.map +1 -0
  28. package/core/chart-api/chart-extra-legend.d.ts +27 -0
  29. package/core/chart-api/chart-extra-legend.js +118 -0
  30. package/core/chart-api/chart-extra-legend.js.map +1 -0
  31. package/core/chart-api/chart-extra-navigation.d.ts +84 -0
  32. package/core/chart-api/chart-extra-navigation.js +470 -0
  33. package/core/chart-api/chart-extra-navigation.js.map +1 -0
  34. package/core/chart-api/chart-extra-nodata.d.ts +15 -0
  35. package/core/chart-api/chart-extra-nodata.js +45 -0
  36. package/core/chart-api/chart-extra-nodata.js.map +1 -0
  37. package/core/chart-api/chart-extra-pointer.d.ts +33 -0
  38. package/core/chart-api/chart-extra-pointer.js +173 -0
  39. package/core/chart-api/chart-extra-pointer.js.map +1 -0
  40. package/core/chart-api/chart-extra-tooltip.d.ts +33 -0
  41. package/core/chart-api/chart-extra-tooltip.js +209 -0
  42. package/core/chart-api/chart-extra-tooltip.js.map +1 -0
  43. package/core/chart-api/index.d.ts +75 -0
  44. package/core/chart-api/index.js +383 -0
  45. package/core/chart-api/index.js.map +1 -0
  46. package/core/chart-container.d.ts +20 -0
  47. package/core/chart-container.js +55 -0
  48. package/core/chart-container.js.map +1 -0
  49. package/core/chart-core.d.ts +7 -0
  50. package/core/chart-core.js +287 -0
  51. package/core/chart-core.js.map +1 -0
  52. package/core/components/core-application.d.ts +6 -0
  53. package/core/components/core-application.js +16 -0
  54. package/core/components/core-application.js.map +1 -0
  55. package/core/components/core-filters.d.ts +9 -0
  56. package/core/components/core-filters.js +22 -0
  57. package/core/components/core-filters.js.map +1 -0
  58. package/core/components/core-legend.d.ts +13 -0
  59. package/core/components/core-legend.js +27 -0
  60. package/core/components/core-legend.js.map +1 -0
  61. package/core/components/core-no-data.d.ts +6 -0
  62. package/core/components/core-no-data.js +48 -0
  63. package/core/components/core-no-data.js.map +1 -0
  64. package/core/components/core-slots.d.ts +7 -0
  65. package/core/components/core-slots.js +11 -0
  66. package/core/components/core-slots.js.map +1 -0
  67. package/core/components/core-tooltip.d.ts +7 -0
  68. package/core/components/core-tooltip.js +183 -0
  69. package/core/components/core-tooltip.js.map +1 -0
  70. package/core/components/core-vertical-axis-title.d.ts +5 -0
  71. package/core/components/core-vertical-axis-title.js +15 -0
  72. package/core/components/core-vertical-axis-title.js.map +1 -0
  73. package/core/formatters.d.ts +2 -0
  74. package/core/formatters.js +113 -0
  75. package/core/formatters.js.map +1 -0
  76. package/core/i18n-utils.d.ts +21 -0
  77. package/core/i18n-utils.js +18 -0
  78. package/core/i18n-utils.js.map +1 -0
  79. package/core/interfaces.d.ts +436 -0
  80. package/core/interfaces.js +4 -0
  81. package/core/interfaces.js.map +1 -0
  82. package/core/styles.css.js +25 -0
  83. package/core/styles.scoped.css +115 -0
  84. package/core/styles.selectors.js +26 -0
  85. package/core/test-classes/styles.css.js +33 -0
  86. package/core/test-classes/styles.scoped.css +34 -0
  87. package/core/test-classes/styles.selectors.js +34 -0
  88. package/core/utils.d.ts +45 -0
  89. package/core/utils.js +262 -0
  90. package/core/utils.js.map +1 -0
  91. package/index.d.ts +4 -0
  92. package/index.js +5 -0
  93. package/index.js.map +1 -0
  94. package/internal/api-docs/components/cartesian-chart.js +571 -0
  95. package/internal/api-docs/components/index.d.ts +3 -0
  96. package/internal/api-docs/components/index.js +4 -0
  97. package/internal/api-docs/components/interfaces.d.ts +81 -0
  98. package/internal/api-docs/components/pie-chart.js +430 -0
  99. package/internal/api-docs/test-utils-doc/dom.js +4 -0
  100. package/internal/api-docs/test-utils-doc/selectors.js +4 -0
  101. package/internal/base-component/get-data-attributes.d.ts +1 -0
  102. package/internal/base-component/get-data-attributes.js +12 -0
  103. package/internal/base-component/get-data-attributes.js.map +1 -0
  104. package/internal/base-component/use-base-component.d.ts +13 -0
  105. package/internal/base-component/use-base-component.js +18 -0
  106. package/internal/base-component/use-base-component.js.map +1 -0
  107. package/internal/base-component/use-telemetry.d.ts +2 -0
  108. package/internal/base-component/use-telemetry.js +8 -0
  109. package/internal/base-component/use-telemetry.js.map +1 -0
  110. package/internal/chart-styles.d.ts +88 -0
  111. package/internal/chart-styles.js +145 -0
  112. package/internal/chart-styles.js.map +1 -0
  113. package/internal/components/chart-legend/index.d.ts +14 -0
  114. package/internal/components/chart-legend/index.js +245 -0
  115. package/internal/components/chart-legend/index.js.map +1 -0
  116. package/internal/components/chart-legend/styles.css.js +22 -0
  117. package/internal/components/chart-legend/styles.scoped.css +233 -0
  118. package/internal/components/chart-legend/styles.selectors.js +23 -0
  119. package/internal/components/chart-legend/test-classes/styles.css.js +11 -0
  120. package/internal/components/chart-legend/test-classes/styles.scoped.css +12 -0
  121. package/internal/components/chart-legend/test-classes/styles.selectors.js +12 -0
  122. package/internal/components/chart-series-filter/index.d.ts +17 -0
  123. package/internal/components/chart-series-filter/index.js +14 -0
  124. package/internal/components/chart-series-filter/index.js.map +1 -0
  125. package/internal/components/interfaces.d.ts +17 -0
  126. package/internal/components/interfaces.js +4 -0
  127. package/internal/components/interfaces.js.map +1 -0
  128. package/internal/components/series-details/index.d.ts +23 -0
  129. package/internal/components/series-details/index.js +45 -0
  130. package/internal/components/series-details/index.js.map +1 -0
  131. package/internal/components/series-details/styles.css.js +22 -0
  132. package/internal/components/series-details/styles.scoped.css +150 -0
  133. package/internal/components/series-details/styles.selectors.js +23 -0
  134. package/internal/components/series-details/test-classes/styles.css.js +10 -0
  135. package/internal/components/series-details/test-classes/styles.scoped.css +11 -0
  136. package/internal/components/series-details/test-classes/styles.selectors.js +11 -0
  137. package/internal/components/series-marker/index.d.ts +8 -0
  138. package/internal/components/series-marker/index.js +45 -0
  139. package/internal/components/series-marker/index.js.map +1 -0
  140. package/internal/components/series-marker/interfaces.d.ts +1 -0
  141. package/internal/components/series-marker/interfaces.js +4 -0
  142. package/internal/components/series-marker/interfaces.js.map +1 -0
  143. package/internal/components/series-marker/render-marker.d.ts +3 -0
  144. package/internal/components/series-marker/render-marker.js +74 -0
  145. package/internal/components/series-marker/render-marker.js.map +1 -0
  146. package/internal/components/series-marker/styles.css.js +7 -0
  147. package/internal/components/series-marker/styles.scoped.css +55 -0
  148. package/internal/components/series-marker/styles.selectors.js +8 -0
  149. package/internal/environment.d.ts +4 -0
  150. package/internal/environment.js +5 -0
  151. package/internal/environment.json +7 -0
  152. package/internal/events/index.d.ts +23 -0
  153. package/internal/events/index.js +41 -0
  154. package/internal/events/index.js.map +1 -0
  155. package/internal/generated/styles/tokens.d.ts +756 -0
  156. package/internal/generated/styles/tokens.js +756 -0
  157. package/internal/generated/theming/index.cjs +12584 -0
  158. package/internal/generated/theming/index.cjs.d.ts +2399 -0
  159. package/internal/generated/theming/index.d.ts +2399 -0
  160. package/internal/generated/theming/index.js +12584 -0
  161. package/internal/manifest.json +3 -0
  162. package/internal/styles.css.js +6 -0
  163. package/internal/styles.scoped.css +13 -0
  164. package/internal/styles.selectors.js +7 -0
  165. package/internal/utils/apply-display-name.d.ts +1 -0
  166. package/internal/utils/apply-display-name.js +6 -0
  167. package/internal/utils/apply-display-name.js.map +1 -0
  168. package/internal/utils/async-store.d.ts +19 -0
  169. package/internal/utils/async-store.js +58 -0
  170. package/internal/utils/async-store.js.map +1 -0
  171. package/internal/utils/chart-series.d.ts +8 -0
  172. package/internal/utils/chart-series.js +11 -0
  173. package/internal/utils/chart-series.js.map +1 -0
  174. package/internal/utils/renderer-utils.d.ts +17 -0
  175. package/internal/utils/renderer-utils.js +95 -0
  176. package/internal/utils/renderer-utils.js.map +1 -0
  177. package/internal/utils/series-data.d.ts +2 -0
  178. package/internal/utils/series-data.js +8 -0
  179. package/internal/utils/series-data.js.map +1 -0
  180. package/internal/utils/test-i18n-provider.d.ts +8 -0
  181. package/internal/utils/test-i18n-provider.js +8 -0
  182. package/internal/utils/test-i18n-provider.js.map +1 -0
  183. package/internal/utils/use-previous.d.ts +4 -0
  184. package/internal/utils/use-previous.js +14 -0
  185. package/internal/utils/use-previous.js.map +1 -0
  186. package/internal/utils/utils.d.ts +16 -0
  187. package/internal/utils/utils.js +49 -0
  188. package/internal/utils/utils.js.map +1 -0
  189. package/internal-do-not-use/core-chart/index.d.ts +4 -0
  190. package/internal-do-not-use/core-chart/index.js +13 -0
  191. package/internal-do-not-use/core-chart/index.js.map +1 -0
  192. package/internal-do-not-use/core-legend/index.d.ts +2 -0
  193. package/internal-do-not-use/core-legend/index.js +11 -0
  194. package/internal-do-not-use/core-legend/index.js.map +1 -0
  195. package/package.json +106 -0
  196. package/pie-chart/chart-inner-area.d.ts +10 -0
  197. package/pie-chart/chart-inner-area.js +63 -0
  198. package/pie-chart/chart-inner-area.js.map +1 -0
  199. package/pie-chart/chart-pie-internal.d.ts +11 -0
  200. package/pie-chart/chart-pie-internal.js +103 -0
  201. package/pie-chart/chart-pie-internal.js.map +1 -0
  202. package/pie-chart/index.d.ts +5 -0
  203. package/pie-chart/index.js +48 -0
  204. package/pie-chart/index.js.map +1 -0
  205. package/pie-chart/interfaces.d.ts +101 -0
  206. package/pie-chart/interfaces.js +4 -0
  207. package/pie-chart/interfaces.js.map +1 -0
  208. package/pie-chart/test-classes/styles.css.js +8 -0
  209. package/pie-chart/test-classes/styles.scoped.css +9 -0
  210. package/pie-chart/test-classes/styles.selectors.js +9 -0
  211. package/test-utils/dom/cartesian-chart/index.d.ts +14 -0
  212. package/test-utils/dom/cartesian-chart/index.js +24 -0
  213. package/test-utils/dom/cartesian-chart/index.js.map +1 -0
  214. package/test-utils/dom/cartesian-chart/tooltip.d.ts +28 -0
  215. package/test-utils/dom/cartesian-chart/tooltip.js +48 -0
  216. package/test-utils/dom/cartesian-chart/tooltip.js.map +1 -0
  217. package/test-utils/dom/index.d.ts +46 -0
  218. package/test-utils/dom/index.js +35 -0
  219. package/test-utils/dom/index.js.map +1 -0
  220. package/test-utils/dom/internal/base.d.ts +93 -0
  221. package/test-utils/dom/internal/base.js +146 -0
  222. package/test-utils/dom/internal/base.js.map +1 -0
  223. package/test-utils/dom/internal/core.d.ts +14 -0
  224. package/test-utils/dom/internal/core.js +37 -0
  225. package/test-utils/dom/internal/core.js.map +1 -0
  226. package/test-utils/dom/pie-chart/index.d.ts +17 -0
  227. package/test-utils/dom/pie-chart/index.js +29 -0
  228. package/test-utils/dom/pie-chart/index.js.map +1 -0
  229. package/test-utils/selectors/cartesian-chart/index.d.ts +14 -0
  230. package/test-utils/selectors/cartesian-chart/index.js +24 -0
  231. package/test-utils/selectors/cartesian-chart/index.js.map +1 -0
  232. package/test-utils/selectors/cartesian-chart/tooltip.d.ts +28 -0
  233. package/test-utils/selectors/cartesian-chart/tooltip.js +48 -0
  234. package/test-utils/selectors/cartesian-chart/tooltip.js.map +1 -0
  235. package/test-utils/selectors/index.d.ts +46 -0
  236. package/test-utils/selectors/index.js +32 -0
  237. package/test-utils/selectors/index.js.map +1 -0
  238. package/test-utils/selectors/internal/base.d.ts +93 -0
  239. package/test-utils/selectors/internal/base.js +146 -0
  240. package/test-utils/selectors/internal/base.js.map +1 -0
  241. package/test-utils/selectors/internal/core.d.ts +14 -0
  242. package/test-utils/selectors/internal/core.js +37 -0
  243. package/test-utils/selectors/internal/core.js.map +1 -0
  244. package/test-utils/selectors/pie-chart/index.d.ts +17 -0
  245. package/test-utils/selectors/pie-chart/index.js +29 -0
  246. package/test-utils/selectors/pie-chart/index.js.map +1 -0
@@ -0,0 +1,383 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { useEffect, useRef } from "react";
4
+ import { fireNonCancelableEvent } from "../../internal/events";
5
+ import { getChartSeries } from "../../internal/utils/chart-series";
6
+ import { getSeriesData } from "../../internal/utils/series-data";
7
+ import { getChartAccessibleDescription, getGroupAccessibleDescription, getPointAccessibleDescription, isXThreshold, } from "../utils";
8
+ import { ChartExtraAxisTitles } from "./chart-extra-axis-titles";
9
+ import { createChartContext, updateChartContext } from "./chart-extra-context";
10
+ import { ChartExtraHighlight } from "./chart-extra-highlight";
11
+ import { ChartExtraLegend } from "./chart-extra-legend";
12
+ import { ChartExtraNavigation } from "./chart-extra-navigation";
13
+ import { ChartExtraNodata } from "./chart-extra-nodata";
14
+ import { ChartExtraPointer } from "./chart-extra-pointer";
15
+ import { ChartExtraTooltip } from "./chart-extra-tooltip";
16
+ // The API helper injects Cloudscape custom behaviors, and returns the API instance that comes with
17
+ // reactive state and handlers to be assigned as Highcharts options, used by Cloudscape components
18
+ // (tooltip, legend, and other), or exposed as public core chart API.
19
+ export function useChartAPI(settings, handlers, state) {
20
+ // The API helper instance defines many pieces of internal state with different lifecycles, most
21
+ // of which are not be invalidated when the hook re-renders, or properties change. That is why we
22
+ // create the instance once, when the component is mounted.
23
+ const api = useRef(new ChartAPI(settings, handlers, state)).current;
24
+ // The consumer-defined properties can still change during the component lifecycle. We propagate the
25
+ // changes by updating the helper's context directly. That is fine for most of the properties, as those
26
+ // are only used in event-based callbacks, and require nothing to recompute when there is a change.
27
+ useEffect(() => {
28
+ api.context.settings = settings;
29
+ api.context.handlers = handlers;
30
+ api.context.state = state;
31
+ });
32
+ // The only property that does require notifying the helper when it changes, is the visible items state.
33
+ // We stringify the visible items array so that it is compared by value, and the effect is only fired when
34
+ // there is an actual change to the visible items, including items order.
35
+ const visibleItemsIndex = state.visibleItems ? state.visibleItems.join("::") : null;
36
+ useEffect(() => {
37
+ // When visibleItemsIndex === null, it means the visible items state is managed internally inside the helper,
38
+ // so no need to call the API method.
39
+ // The api.updateItemsVisibility() can only be used once the chart is initialized, so we check for api.ready.
40
+ // The initialization happens after the first React render, so the chart is expected to not be ready when the
41
+ // effect is called for the first time. This is fine, as the initial visibility state is handled by the helper.
42
+ // The code below is needed to notify the helper any time the visible items state changes.
43
+ if (api.ready && visibleItemsIndex !== null) {
44
+ api.updateItemsVisibility();
45
+ }
46
+ }, [api, visibleItemsIndex]);
47
+ // Run cleanup code when the component unmounts.
48
+ useEffect(() => () => api.onChartDestroy(), [api]);
49
+ return api;
50
+ }
51
+ // The main chart helper that provides customizations to Highcharts, including tooltip, legend, keyboard navigation, and more.
52
+ // It is split into multiple dedicated (chart-extra) helpers (highlight, tooltip, navigation, and other), most of which define
53
+ // internal state, and have a lifecycle based on Highcharts render event.
54
+ // The helper code has a shared context, which includes the consumer settings, visible items state, and derived state, computed
55
+ // from Highcharts.Chart on each render, and reused for downstream computations for better efficiency.
56
+ export class ChartAPI {
57
+ constructor(settings, handlers, state) {
58
+ this.context = createChartContext();
59
+ this.chartExtraHighlight = new ChartExtraHighlight(this.context);
60
+ this.chartExtraTooltip = new ChartExtraTooltip(this.context);
61
+ this.chartExtraNavigation = new ChartExtraNavigation(this.context, this.navigationHandlers);
62
+ this.chartExtraPointer = new ChartExtraPointer(this.context, this.pointerHandlers);
63
+ this.chartExtraLegend = new ChartExtraLegend(this.context);
64
+ this.chartExtraNodata = new ChartExtraNodata(this.context);
65
+ this.chartExtraAxisTitles = new ChartExtraAxisTitles(this.context);
66
+ // There is no cleanup or destroy event in Highcharts options, so we define a custom one
67
+ // to be used when the React component unmounts.
68
+ this.onChartDestroy = () => {
69
+ this.chartExtraNavigation.onChartDestroy();
70
+ this.chartExtraPointer.onChartDestroy();
71
+ this.chartExtraTooltip.onChartDestroy();
72
+ };
73
+ // References to SVG elements used for tooltip placement.
74
+ this.getTargetTrack = this.chartExtraTooltip.getTargetTrack.bind(this.chartExtraTooltip);
75
+ this.getGroupTrack = this.chartExtraTooltip.getGroupTrack.bind(this.chartExtraTooltip);
76
+ // Legend marker renderer.
77
+ this.renderMarker = this.chartExtraLegend.renderMarker.bind(this.chartExtraLegend);
78
+ // Callbacks assigned to the tooltip.
79
+ this.onMouseEnterTooltip = this.chartExtraPointer.onMouseEnterTooltip.bind(this.chartExtraPointer);
80
+ this.onMouseLeaveTooltip = this.chartExtraPointer.onMouseLeaveTooltip.bind(this.chartExtraPointer);
81
+ this.onDismissTooltip = (outsideClick) => {
82
+ const { pinned, point, group } = this.chartExtraTooltip.get();
83
+ if (pinned) {
84
+ this.chartExtraTooltip.hideTooltip();
85
+ // The chart highlight is preserved while the tooltip is pinned. We need to clear it manually here, for the case
86
+ // when the pointer lands outside the chart after the tooltip is dismissed, so that the mouse-out event won't fire.
87
+ this.clearChartHighlight({ isApiCall: false });
88
+ // If the tooltip was not dismissed by clicking outside, we bring focus to the point or group, that was
89
+ // associated with the tooltip, so that we user can continue keyboard navigation from that spot.
90
+ if (!outsideClick) {
91
+ this.chartExtraNavigation.focusApplication(point, group);
92
+ }
93
+ }
94
+ };
95
+ // Reference to the role="application" element used for navigation.
96
+ this.setApplication = this.chartExtraNavigation.setApplication.bind(this.chartExtraNavigation);
97
+ // A callback to notify the helper when items visibility state changes.
98
+ this.updateItemsVisibility = this.chartExtraLegend.updateItemsVisibility.bind(this.chartExtraLegend);
99
+ // A callback used by the legend and filter components when series/segments visibility changes.
100
+ this.onItemVisibilityChange = (items) => this.chartExtraLegend.onItemVisibilityChange(items, { isApiCall: false });
101
+ // Callbacks used by the legend component when items highlight state changes.
102
+ this.onHighlightChartItems = (itemIds) => {
103
+ if (!this.isTooltipPinned) {
104
+ this.chartExtraHighlight.highlightChartItems(itemIds);
105
+ this.chartExtraLegend.onHighlightItems(itemIds);
106
+ }
107
+ };
108
+ this.onClearChartItemsHighlight = () => {
109
+ if (!this.isTooltipPinned) {
110
+ this.chartExtraHighlight.clearChartItemsHighlight();
111
+ this.chartExtraLegend.onClearHighlight();
112
+ }
113
+ };
114
+ // Callbacks used for hover and keyboard navigation, and also exposed to the public API to give the ability
115
+ // to highlight and show tooltip for the given point or group manually.
116
+ this.highlightChartItems = (itemIds) => {
117
+ if (!this.isTooltipPinned) {
118
+ this.chartExtraHighlight.highlightChartItems(itemIds);
119
+ this.chartExtraLegend.onHighlightItems(itemIds);
120
+ }
121
+ };
122
+ this.setItemsVisible = (visibleItemsIds, { isApiCall }) => {
123
+ this.chartExtraLegend.onItemVisibilityChange(visibleItemsIds, { isApiCall });
124
+ };
125
+ this.highlightChartPoint = (point, { isApiCall }) => {
126
+ if (!this.isTooltipPinned) {
127
+ this.highlightActions(point, { isApiCall });
128
+ }
129
+ };
130
+ this.highlightChartGroup = (group, { isApiCall }) => {
131
+ if (!this.isTooltipPinned) {
132
+ this.highlightActions(group, { isApiCall });
133
+ }
134
+ };
135
+ this.clearChartHighlight = ({ isApiCall }) => {
136
+ if (!this.isTooltipPinned) {
137
+ this.clearHighlightActions({ isApiCall });
138
+ }
139
+ };
140
+ this.pinTooltipOnPoint = (point) => {
141
+ const currentPoint = this.chartExtraTooltip.get().point;
142
+ const currentGroup = this.chartExtraTooltip.get().group;
143
+ const positionsMatch = isPointsPositionsEqual(currentPoint !== null && currentPoint !== void 0 ? currentPoint : currentGroup[0], point);
144
+ // If the previously hovered and now clicked positions match, and the the tooltip wasn't
145
+ // dismissed just a moment ago, we make the tooltip pinned in this position.
146
+ if (positionsMatch && !this.chartExtraTooltip.tooltipLock) {
147
+ this.highlightActions(point, { isApiCall: false });
148
+ this.chartExtraTooltip.pinTooltip();
149
+ }
150
+ // If the tooltip was just dismissed, it means this happened by clicking somewhere in the plot area.
151
+ // If the clicked position differs from the one that was pinned - we show tooltip in the new position.
152
+ else if (!positionsMatch && this.chartExtraTooltip.tooltipLock) {
153
+ this.highlightActions(point, { isApiCall: false, overrideTooltipLock: true });
154
+ }
155
+ };
156
+ this.pinTooltipOnGroup = (group) => {
157
+ const currentPoint = this.chartExtraTooltip.get().point;
158
+ const currentGroup = this.chartExtraTooltip.get().group;
159
+ const positionsMatch = isPointsPositionsEqual(currentPoint !== null && currentPoint !== void 0 ? currentPoint : currentGroup[0], group[0]);
160
+ // If the previously hovered and now clicked positions match, and the the tooltip wasn't
161
+ // dismissed just a moment ago, we make the tooltip pinned in this position.
162
+ if (positionsMatch && !this.chartExtraTooltip.tooltipLock) {
163
+ this.highlightActions(group, { isApiCall: false });
164
+ this.chartExtraTooltip.pinTooltip();
165
+ }
166
+ // If the tooltip was just dismissed, it means this happened by clicking somewhere in the plot area.
167
+ // If the clicked position differs from the one that was pinned - we show tooltip in the new position.
168
+ else if (!positionsMatch && this.chartExtraTooltip.tooltipLock) {
169
+ this.highlightActions(group, { isApiCall: false, overrideTooltipLock: true });
170
+ }
171
+ };
172
+ this.clearHighlightActions = ({ isApiCall }) => {
173
+ if (!this.isTooltipPinned) {
174
+ // Update Highcharts elements state.
175
+ this.chartExtraHighlight.clearChartItemsHighlight();
176
+ // Update tooltip and legend state.
177
+ this.chartExtraTooltip.hideTooltip();
178
+ this.chartExtraLegend.onClearHighlight();
179
+ // Notify the consumer that a clear-highlight action was made.
180
+ fireNonCancelableEvent(this.context.handlers.onClearHighlight, { isApiCall });
181
+ }
182
+ };
183
+ this.context.settings = settings;
184
+ this.context.handlers = handlers;
185
+ this.context.state = state;
186
+ }
187
+ // The ready() returns true if the chart is initialized and helper methods are safe to use (after Highcharts triggers onChartRender).
188
+ // Using any of the helper methods before the chart is initialized will result in an exception.
189
+ get ready() {
190
+ return !!this.context.chartOrNull;
191
+ }
192
+ // The Highcharts options to be merged with the rest of the configuration defined in the chart-core.
193
+ getOptions() {
194
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
195
+ const chartAPI = this;
196
+ const onChartLoad = function () {
197
+ chartAPI.chartExtraPointer.onChartLoad(this);
198
+ };
199
+ const onChartRender = function () {
200
+ updateChartContext(chartAPI.context, this);
201
+ chartAPI.chartExtraHighlight.onChartRender();
202
+ chartAPI.chartExtraLegend.onChartRender();
203
+ chartAPI.chartExtraNodata.onChartRender();
204
+ chartAPI.chartExtraAxisTitles.onChartRender();
205
+ chartAPI.handleDestroyedPoints();
206
+ chartAPI.resetColorCounter();
207
+ chartAPI.showMarkersForIsolatedPoints();
208
+ };
209
+ const onChartClick = function () {
210
+ chartAPI.chartExtraPointer.onChartClick(this.hoverPoint);
211
+ };
212
+ const onSeriesPointMouseOver = function () {
213
+ chartAPI.chartExtraPointer.onSeriesPointMouseOver(this);
214
+ };
215
+ const onSeriesPointMouseOut = function () {
216
+ chartAPI.chartExtraPointer.onSeriesPointMouseOut();
217
+ };
218
+ const onSeriesPointClick = function () {
219
+ chartAPI.chartExtraPointer.onSeriesPointClick(this);
220
+ };
221
+ return {
222
+ onChartLoad,
223
+ onChartRender,
224
+ onChartClick,
225
+ onSeriesPointMouseOver,
226
+ onSeriesPointMouseOut,
227
+ onSeriesPointClick,
228
+ };
229
+ }
230
+ // Reactive state stores.
231
+ get tooltipStore() {
232
+ return this.chartExtraTooltip;
233
+ }
234
+ get legendStore() {
235
+ return this.chartExtraLegend;
236
+ }
237
+ get nodataStore() {
238
+ return this.chartExtraNodata;
239
+ }
240
+ get axisTitlesStore() {
241
+ return this.chartExtraAxisTitles;
242
+ }
243
+ get publicApi() {
244
+ return {
245
+ highlightItems: (itemIds) => this.highlightChartItems(itemIds),
246
+ setItemsVisible: (visibleItemIds) => this.setItemsVisible(visibleItemIds, { isApiCall: true }),
247
+ highlightChartPoint: (point) => this.highlightChartPoint(point, { isApiCall: true }),
248
+ highlightChartGroup: (group) => this.highlightChartGroup(group, { isApiCall: true }),
249
+ clearChartHighlight: () => this.clearChartHighlight({ isApiCall: true }),
250
+ };
251
+ }
252
+ // A set of callbacks required for keyboard navigation.
253
+ get navigationHandlers() {
254
+ return {
255
+ onFocusChart: () => {
256
+ this.clearChartHighlight({ isApiCall: false });
257
+ this.chartExtraNavigation.announceChart(getChartAccessibleDescription(this.context.chart()));
258
+ },
259
+ onFocusGroup: (group) => {
260
+ this.highlightActions(group, { isApiCall: false, overrideTooltipLock: true });
261
+ this.chartExtraNavigation.announceElement(getGroupAccessibleDescription(group), false);
262
+ },
263
+ onFocusPoint: (point) => {
264
+ const labels = this.context.settings.labels;
265
+ this.highlightActions(point, { isApiCall: false, overrideTooltipLock: true });
266
+ this.chartExtraNavigation.announceElement(getPointAccessibleDescription(point, labels), false);
267
+ },
268
+ onBlur: () => this.clearChartHighlight({ isApiCall: false }),
269
+ onActivateGroup: () => {
270
+ const current = this.chartExtraTooltip.get();
271
+ if (current.group.length > 0) {
272
+ this.chartExtraTooltip.pinTooltip();
273
+ this.chartExtraNavigation.announceElement(getGroupAccessibleDescription(current.group), true);
274
+ }
275
+ },
276
+ onActivatePoint: () => {
277
+ const current = this.chartExtraTooltip.get();
278
+ if (current.point) {
279
+ const labels = this.context.settings.labels;
280
+ this.chartExtraTooltip.pinTooltip();
281
+ this.chartExtraNavigation.announceElement(getPointAccessibleDescription(current.point, labels), true);
282
+ }
283
+ },
284
+ };
285
+ }
286
+ // A set of callbacks required for pointer navigation.
287
+ get pointerHandlers() {
288
+ return {
289
+ onPointHover: (point) => {
290
+ this.highlightChartPoint(point, { isApiCall: false });
291
+ },
292
+ onGroupHover: (group) => {
293
+ this.highlightChartGroup(group, { isApiCall: false });
294
+ },
295
+ onHoverLost: () => {
296
+ this.clearChartHighlight({ isApiCall: false });
297
+ },
298
+ onPointClick: (point) => {
299
+ this.pinTooltipOnPoint(point);
300
+ },
301
+ onGroupClick: (group) => {
302
+ this.pinTooltipOnGroup(group);
303
+ },
304
+ };
305
+ }
306
+ // Area- or line series can be defined with just a single point, or include missing data (y=null) in such
307
+ // a way, that certain points become isolated. As we prefer the markers to not be shown for area- and line
308
+ // series by default, those points become invisible, unless hovered. To fix this, we use the function below,
309
+ // that finds isolates points and overrides the marker.enabled configuration for those.
310
+ // See: https://github.com/highcharts/highcharts/issues/1210.
311
+ showMarkersForIsolatedPoints() {
312
+ var _a, _b, _c, _d, _e;
313
+ let shouldRedraw = false;
314
+ for (const s of this.context.chart().series) {
315
+ const seriesData = getSeriesData(s.data);
316
+ for (let i = 0; i < seriesData.length; i++) {
317
+ const isEligibleSeries = !isXThreshold(s) && s.type !== "scatter" && !((_a = seriesData[i].options.marker) === null || _a === void 0 ? void 0 : _a.enabled);
318
+ if (isEligibleSeries &&
319
+ (((_b = seriesData[i - 1]) === null || _b === void 0 ? void 0 : _b.y) === undefined || ((_c = seriesData[i - 1]) === null || _c === void 0 ? void 0 : _c.y) === null) &&
320
+ (((_d = seriesData[i + 1]) === null || _d === void 0 ? void 0 : _d.y) === undefined || ((_e = seriesData[i + 1]) === null || _e === void 0 ? void 0 : _e.y) === null)) {
321
+ seriesData[i].update({ marker: { enabled: true } }, false);
322
+ shouldRedraw = true;
323
+ }
324
+ }
325
+ }
326
+ if (shouldRedraw) {
327
+ this.context.chart().redraw();
328
+ }
329
+ }
330
+ // Highcharts sometimes destroys points upon re-rendering. As result, the already stored points can get
331
+ // replaced by `{ destroyed: true }`. This can affect the tooltip state, making the component crash when
332
+ // obtaining data from points, or making it hidden yet pinned, so not visible on hover until a click is made.
333
+ // To prevent these issues, on each render we check for destroyed points in the tooltip state, and proactively
334
+ // hide the tooltip if found. The behavior is only observed during the initial chart loading, and is not expected
335
+ // to cause UX issues with the tooltip being closed unexpectedly.
336
+ // See: https://github.com/highcharts/highcharts/issues/23175.
337
+ handleDestroyedPoints() {
338
+ const tooltipState = this.chartExtraTooltip.get();
339
+ if (tooltipState.group.some((p) => !p.series)) {
340
+ this.chartExtraTooltip.hideTooltip();
341
+ }
342
+ }
343
+ // We reset color counter so that when a series is removed and then added back - it will
344
+ // have the same color as before, not the next one in the color sequence.
345
+ // See: https://github.com/highcharts/highcharts/issues/23077.
346
+ resetColorCounter() {
347
+ const chart = this.context.chart();
348
+ if ("colorCounter" in chart && typeof chart.colorCounter === "number") {
349
+ chart.colorCounter = getChartSeries(chart.series).length;
350
+ }
351
+ }
352
+ highlightActions(target, { isApiCall, overrideTooltipLock }) {
353
+ const point = Array.isArray(target) ? null : target;
354
+ const group = Array.isArray(target) ? target : this.context.derived.getPointsByX(target.x);
355
+ if (!this.isTooltipPinned) {
356
+ // Update Highcharts elements state.
357
+ if (point) {
358
+ this.chartExtraHighlight.highlightChartPoint(point);
359
+ }
360
+ else {
361
+ this.chartExtraHighlight.highlightChartGroup(group);
362
+ }
363
+ // Update tooltip and legend state.
364
+ if (point) {
365
+ this.chartExtraLegend.onHighlightPoint(point);
366
+ this.chartExtraTooltip.showTooltipOnPoint(point, group, overrideTooltipLock);
367
+ }
368
+ else {
369
+ this.chartExtraLegend.onHighlightGroup(group);
370
+ this.chartExtraTooltip.showTooltipOnGroup(group, overrideTooltipLock);
371
+ }
372
+ // Notify the consumer that a highlight action was made.
373
+ fireNonCancelableEvent(this.context.handlers.onHighlight, { point, group, isApiCall });
374
+ }
375
+ }
376
+ get isTooltipPinned() {
377
+ return this.chartExtraTooltip.get().pinned;
378
+ }
379
+ }
380
+ function isPointsPositionsEqual(current, next) {
381
+ return (current === null || current === void 0 ? void 0 : current.x) === (next === null || next === void 0 ? void 0 : next.x) && (current === null || current === void 0 ? void 0 : current.y) === (next === null || next === void 0 ? void 0 : next.y);
382
+ }
383
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/chart-api/index.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { useEffect, useRef } from \"react\";\nimport type Highcharts from \"highcharts\";\n\nimport { fireNonCancelableEvent } from \"../../internal/events\";\nimport { ReadonlyAsyncStore } from \"../../internal/utils/async-store\";\nimport { getChartSeries } from \"../../internal/utils/chart-series\";\nimport { getSeriesData } from \"../../internal/utils/series-data\";\nimport { Writeable } from \"../../internal/utils/utils\";\nimport {\n getChartAccessibleDescription,\n getGroupAccessibleDescription,\n getPointAccessibleDescription,\n isXThreshold,\n} from \"../utils\";\nimport { ChartExtraAxisTitles, ReactiveAxisTitlesState } from \"./chart-extra-axis-titles\";\nimport { ChartExtraContext, createChartContext, updateChartContext } from \"./chart-extra-context\";\nimport { ChartExtraHighlight } from \"./chart-extra-highlight\";\nimport { ChartExtraLegend, ReactiveLegendState } from \"./chart-extra-legend\";\nimport { ChartExtraNavigation, ChartExtraNavigationHandlers } from \"./chart-extra-navigation\";\nimport { ChartExtraNodata, ReactiveNodataState } from \"./chart-extra-nodata\";\nimport { ChartExtraPointer, ChartExtraPointerHandlers } from \"./chart-extra-pointer\";\nimport { ChartExtraTooltip, ReactiveTooltipState } from \"./chart-extra-tooltip\";\n\n// The API helper injects Cloudscape custom behaviors, and returns the API instance that comes with\n// reactive state and handlers to be assigned as Highcharts options, used by Cloudscape components\n// (tooltip, legend, and other), or exposed as public core chart API.\nexport function useChartAPI(\n settings: ChartExtraContext.Settings,\n handlers: ChartExtraContext.Handlers,\n state: ChartExtraContext.State,\n) {\n // The API helper instance defines many pieces of internal state with different lifecycles, most\n // of which are not be invalidated when the hook re-renders, or properties change. That is why we\n // create the instance once, when the component is mounted.\n const api = useRef(new ChartAPI(settings, handlers, state)).current;\n // The consumer-defined properties can still change during the component lifecycle. We propagate the\n // changes by updating the helper's context directly. That is fine for most of the properties, as those\n // are only used in event-based callbacks, and require nothing to recompute when there is a change.\n useEffect(() => {\n api.context.settings = settings;\n api.context.handlers = handlers;\n api.context.state = state;\n });\n\n // The only property that does require notifying the helper when it changes, is the visible items state.\n // We stringify the visible items array so that it is compared by value, and the effect is only fired when\n // there is an actual change to the visible items, including items order.\n const visibleItemsIndex = state.visibleItems ? state.visibleItems.join(\"::\") : null;\n useEffect(() => {\n // When visibleItemsIndex === null, it means the visible items state is managed internally inside the helper,\n // so no need to call the API method.\n // The api.updateItemsVisibility() can only be used once the chart is initialized, so we check for api.ready.\n // The initialization happens after the first React render, so the chart is expected to not be ready when the\n // effect is called for the first time. This is fine, as the initial visibility state is handled by the helper.\n // The code below is needed to notify the helper any time the visible items state changes.\n if (api.ready && visibleItemsIndex !== null) {\n api.updateItemsVisibility();\n }\n }, [api, visibleItemsIndex]);\n\n // Run cleanup code when the component unmounts.\n useEffect(() => () => api.onChartDestroy(), [api]);\n\n return api;\n}\n\n// The main chart helper that provides customizations to Highcharts, including tooltip, legend, keyboard navigation, and more.\n// It is split into multiple dedicated (chart-extra) helpers (highlight, tooltip, navigation, and other), most of which define\n// internal state, and have a lifecycle based on Highcharts render event.\n// The helper code has a shared context, which includes the consumer settings, visible items state, and derived state, computed\n// from Highcharts.Chart on each render, and reused for downstream computations for better efficiency.\nexport class ChartAPI {\n public context = createChartContext();\n private chartExtraHighlight = new ChartExtraHighlight(this.context);\n private chartExtraTooltip = new ChartExtraTooltip(this.context);\n private chartExtraNavigation = new ChartExtraNavigation(this.context, this.navigationHandlers);\n private chartExtraPointer = new ChartExtraPointer(this.context, this.pointerHandlers);\n private chartExtraLegend = new ChartExtraLegend(this.context);\n private chartExtraNodata = new ChartExtraNodata(this.context);\n private chartExtraAxisTitles = new ChartExtraAxisTitles(this.context);\n\n constructor(\n settings: ChartExtraContext.Settings,\n handlers: ChartExtraContext.Handlers,\n state: ChartExtraContext.State,\n ) {\n this.context.settings = settings;\n this.context.handlers = handlers;\n this.context.state = state;\n }\n\n // The ready() returns true if the chart is initialized and helper methods are safe to use (after Highcharts triggers onChartRender).\n // Using any of the helper methods before the chart is initialized will result in an exception.\n public get ready() {\n return !!this.context.chartOrNull;\n }\n\n // The Highcharts options to be merged with the rest of the configuration defined in the chart-core.\n public getOptions() {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const chartAPI = this;\n const onChartLoad: Highcharts.ChartLoadCallbackFunction = function (this) {\n chartAPI.chartExtraPointer.onChartLoad(this);\n };\n const onChartRender: Highcharts.ChartRenderCallbackFunction = function (this) {\n updateChartContext(chartAPI.context, this);\n chartAPI.chartExtraHighlight.onChartRender();\n chartAPI.chartExtraLegend.onChartRender();\n chartAPI.chartExtraNodata.onChartRender();\n chartAPI.chartExtraAxisTitles.onChartRender();\n chartAPI.handleDestroyedPoints();\n chartAPI.resetColorCounter();\n chartAPI.showMarkersForIsolatedPoints();\n };\n const onChartClick: Highcharts.ChartClickCallbackFunction = function () {\n chartAPI.chartExtraPointer.onChartClick(this.hoverPoint);\n };\n const onSeriesPointMouseOver: Highcharts.PointMouseOverCallbackFunction = function () {\n chartAPI.chartExtraPointer.onSeriesPointMouseOver(this);\n };\n const onSeriesPointMouseOut: Highcharts.PointMouseOutCallbackFunction = function () {\n chartAPI.chartExtraPointer.onSeriesPointMouseOut();\n };\n const onSeriesPointClick: Highcharts.PointClickCallbackFunction = function () {\n chartAPI.chartExtraPointer.onSeriesPointClick(this);\n };\n return {\n onChartLoad,\n onChartRender,\n onChartClick,\n onSeriesPointMouseOver,\n onSeriesPointMouseOut,\n onSeriesPointClick,\n };\n }\n\n // There is no cleanup or destroy event in Highcharts options, so we define a custom one\n // to be used when the React component unmounts.\n public onChartDestroy = () => {\n this.chartExtraNavigation.onChartDestroy();\n this.chartExtraPointer.onChartDestroy();\n this.chartExtraTooltip.onChartDestroy();\n };\n\n // Reactive state stores.\n public get tooltipStore() {\n return this.chartExtraTooltip as ReadonlyAsyncStore<ReactiveTooltipState>;\n }\n public get legendStore() {\n return this.chartExtraLegend as ReadonlyAsyncStore<ReactiveLegendState>;\n }\n public get nodataStore() {\n return this.chartExtraNodata as ReadonlyAsyncStore<ReactiveNodataState>;\n }\n public get axisTitlesStore() {\n return this.chartExtraAxisTitles as ReadonlyAsyncStore<ReactiveAxisTitlesState>;\n }\n\n // References to SVG elements used for tooltip placement.\n public getTargetTrack = this.chartExtraTooltip.getTargetTrack.bind(this.chartExtraTooltip);\n public getGroupTrack = this.chartExtraTooltip.getGroupTrack.bind(this.chartExtraTooltip);\n\n // Legend marker renderer.\n public renderMarker = this.chartExtraLegend.renderMarker.bind(this.chartExtraLegend);\n\n // Callbacks assigned to the tooltip.\n public onMouseEnterTooltip = this.chartExtraPointer.onMouseEnterTooltip.bind(this.chartExtraPointer);\n public onMouseLeaveTooltip = this.chartExtraPointer.onMouseLeaveTooltip.bind(this.chartExtraPointer);\n public onDismissTooltip = (outsideClick?: boolean) => {\n const { pinned, point, group } = this.chartExtraTooltip.get();\n if (pinned) {\n this.chartExtraTooltip.hideTooltip();\n // The chart highlight is preserved while the tooltip is pinned. We need to clear it manually here, for the case\n // when the pointer lands outside the chart after the tooltip is dismissed, so that the mouse-out event won't fire.\n this.clearChartHighlight({ isApiCall: false });\n // If the tooltip was not dismissed by clicking outside, we bring focus to the point or group, that was\n // associated with the tooltip, so that we user can continue keyboard navigation from that spot.\n if (!outsideClick) {\n this.chartExtraNavigation.focusApplication(point, group);\n }\n }\n };\n\n // Reference to the role=\"application\" element used for navigation.\n public setApplication = this.chartExtraNavigation.setApplication.bind(this.chartExtraNavigation);\n\n // A callback to notify the helper when items visibility state changes.\n public updateItemsVisibility = this.chartExtraLegend.updateItemsVisibility.bind(this.chartExtraLegend);\n\n // A callback used by the legend and filter components when series/segments visibility changes.\n public onItemVisibilityChange = (items: readonly string[]) =>\n this.chartExtraLegend.onItemVisibilityChange(items, { isApiCall: false });\n\n // Callbacks used by the legend component when items highlight state changes.\n public onHighlightChartItems = (itemIds: readonly string[]) => {\n if (!this.isTooltipPinned) {\n this.chartExtraHighlight.highlightChartItems(itemIds);\n this.chartExtraLegend.onHighlightItems(itemIds);\n }\n };\n public onClearChartItemsHighlight = () => {\n if (!this.isTooltipPinned) {\n this.chartExtraHighlight.clearChartItemsHighlight();\n this.chartExtraLegend.onClearHighlight();\n }\n };\n\n // Callbacks used for hover and keyboard navigation, and also exposed to the public API to give the ability\n // to highlight and show tooltip for the given point or group manually.\n public highlightChartItems = (itemIds: readonly string[]) => {\n if (!this.isTooltipPinned) {\n this.chartExtraHighlight.highlightChartItems(itemIds);\n this.chartExtraLegend.onHighlightItems(itemIds);\n }\n };\n public setItemsVisible = (visibleItemsIds: readonly string[], { isApiCall }: { isApiCall: boolean }) => {\n this.chartExtraLegend.onItemVisibilityChange(visibleItemsIds, { isApiCall });\n };\n public highlightChartPoint = (point: Highcharts.Point, { isApiCall }: { isApiCall: boolean }) => {\n if (!this.isTooltipPinned) {\n this.highlightActions(point, { isApiCall });\n }\n };\n public highlightChartGroup = (group: readonly Highcharts.Point[], { isApiCall }: { isApiCall: boolean }) => {\n if (!this.isTooltipPinned) {\n this.highlightActions(group as Writeable<Highcharts.Point[]>, { isApiCall });\n }\n };\n public clearChartHighlight = ({ isApiCall }: { isApiCall: boolean }) => {\n if (!this.isTooltipPinned) {\n this.clearHighlightActions({ isApiCall });\n }\n };\n public get publicApi() {\n return {\n highlightItems: (itemIds: readonly string[]) => this.highlightChartItems(itemIds),\n setItemsVisible: (visibleItemIds: readonly string[]) => this.setItemsVisible(visibleItemIds, { isApiCall: true }),\n highlightChartPoint: (point: Highcharts.Point) => this.highlightChartPoint(point, { isApiCall: true }),\n highlightChartGroup: (group: readonly Highcharts.Point[]) => this.highlightChartGroup(group, { isApiCall: true }),\n clearChartHighlight: () => this.clearChartHighlight({ isApiCall: true }),\n };\n }\n\n // A set of callbacks required for keyboard navigation.\n private get navigationHandlers(): ChartExtraNavigationHandlers {\n return {\n onFocusChart: () => {\n this.clearChartHighlight({ isApiCall: false });\n this.chartExtraNavigation.announceChart(getChartAccessibleDescription(this.context.chart()));\n },\n onFocusGroup: (group: Highcharts.Point[]) => {\n this.highlightActions(group, { isApiCall: false, overrideTooltipLock: true });\n this.chartExtraNavigation.announceElement(getGroupAccessibleDescription(group), false);\n },\n onFocusPoint: (point: Highcharts.Point) => {\n const labels = this.context.settings.labels;\n this.highlightActions(point, { isApiCall: false, overrideTooltipLock: true });\n this.chartExtraNavigation.announceElement(getPointAccessibleDescription(point, labels), false);\n },\n onBlur: () => this.clearChartHighlight({ isApiCall: false }),\n onActivateGroup: () => {\n const current = this.chartExtraTooltip.get();\n if (current.group.length > 0) {\n this.chartExtraTooltip.pinTooltip();\n this.chartExtraNavigation.announceElement(getGroupAccessibleDescription(current.group), true);\n }\n },\n onActivatePoint: () => {\n const current = this.chartExtraTooltip.get();\n if (current.point) {\n const labels = this.context.settings.labels;\n this.chartExtraTooltip.pinTooltip();\n this.chartExtraNavigation.announceElement(getPointAccessibleDescription(current.point, labels), true);\n }\n },\n };\n }\n\n // A set of callbacks required for pointer navigation.\n private get pointerHandlers(): ChartExtraPointerHandlers {\n return {\n onPointHover: (point) => {\n this.highlightChartPoint(point, { isApiCall: false });\n },\n onGroupHover: (group) => {\n this.highlightChartGroup(group, { isApiCall: false });\n },\n onHoverLost: () => {\n this.clearChartHighlight({ isApiCall: false });\n },\n onPointClick: (point) => {\n this.pinTooltipOnPoint(point);\n },\n onGroupClick: (group) => {\n this.pinTooltipOnGroup(group);\n },\n };\n }\n\n // Area- or line series can be defined with just a single point, or include missing data (y=null) in such\n // a way, that certain points become isolated. As we prefer the markers to not be shown for area- and line\n // series by default, those points become invisible, unless hovered. To fix this, we use the function below,\n // that finds isolates points and overrides the marker.enabled configuration for those.\n // See: https://github.com/highcharts/highcharts/issues/1210.\n private showMarkersForIsolatedPoints() {\n let shouldRedraw = false;\n for (const s of this.context.chart().series) {\n const seriesData = getSeriesData(s.data);\n for (let i = 0; i < seriesData.length; i++) {\n const isEligibleSeries = !isXThreshold(s) && s.type !== \"scatter\" && !seriesData[i].options.marker?.enabled;\n if (\n isEligibleSeries &&\n (seriesData[i - 1]?.y === undefined || seriesData[i - 1]?.y === null) &&\n (seriesData[i + 1]?.y === undefined || seriesData[i + 1]?.y === null)\n ) {\n seriesData[i].update({ marker: { enabled: true } }, false);\n shouldRedraw = true;\n }\n }\n }\n if (shouldRedraw) {\n this.context.chart().redraw();\n }\n }\n\n // Highcharts sometimes destroys points upon re-rendering. As result, the already stored points can get\n // replaced by `{ destroyed: true }`. This can affect the tooltip state, making the component crash when\n // obtaining data from points, or making it hidden yet pinned, so not visible on hover until a click is made.\n // To prevent these issues, on each render we check for destroyed points in the tooltip state, and proactively\n // hide the tooltip if found. The behavior is only observed during the initial chart loading, and is not expected\n // to cause UX issues with the tooltip being closed unexpectedly.\n // See: https://github.com/highcharts/highcharts/issues/23175.\n private handleDestroyedPoints() {\n const tooltipState = this.chartExtraTooltip.get();\n if (tooltipState.group.some((p) => !p.series)) {\n this.chartExtraTooltip.hideTooltip();\n }\n }\n\n // We reset color counter so that when a series is removed and then added back - it will\n // have the same color as before, not the next one in the color sequence.\n // See: https://github.com/highcharts/highcharts/issues/23077.\n private resetColorCounter() {\n const chart = this.context.chart();\n if (\"colorCounter\" in chart && typeof chart.colorCounter === \"number\") {\n chart.colorCounter = getChartSeries(chart.series).length;\n }\n }\n\n private pinTooltipOnPoint = (point: Highcharts.Point) => {\n const currentPoint = this.chartExtraTooltip.get().point;\n const currentGroup = this.chartExtraTooltip.get().group;\n const positionsMatch = isPointsPositionsEqual(currentPoint ?? currentGroup[0], point);\n\n // If the previously hovered and now clicked positions match, and the the tooltip wasn't\n // dismissed just a moment ago, we make the tooltip pinned in this position.\n if (positionsMatch && !this.chartExtraTooltip.tooltipLock) {\n this.highlightActions(point, { isApiCall: false });\n this.chartExtraTooltip.pinTooltip();\n }\n // If the tooltip was just dismissed, it means this happened by clicking somewhere in the plot area.\n // If the clicked position differs from the one that was pinned - we show tooltip in the new position.\n else if (!positionsMatch && this.chartExtraTooltip.tooltipLock) {\n this.highlightActions(point, { isApiCall: false, overrideTooltipLock: true });\n }\n };\n\n private pinTooltipOnGroup = (group: Highcharts.Point[]) => {\n const currentPoint = this.chartExtraTooltip.get().point;\n const currentGroup = this.chartExtraTooltip.get().group;\n const positionsMatch = isPointsPositionsEqual(currentPoint ?? currentGroup[0], group[0]);\n\n // If the previously hovered and now clicked positions match, and the the tooltip wasn't\n // dismissed just a moment ago, we make the tooltip pinned in this position.\n if (positionsMatch && !this.chartExtraTooltip.tooltipLock) {\n this.highlightActions(group, { isApiCall: false });\n this.chartExtraTooltip.pinTooltip();\n }\n // If the tooltip was just dismissed, it means this happened by clicking somewhere in the plot area.\n // If the clicked position differs from the one that was pinned - we show tooltip in the new position.\n else if (!positionsMatch && this.chartExtraTooltip.tooltipLock) {\n this.highlightActions(group, { isApiCall: false, overrideTooltipLock: true });\n }\n };\n\n private highlightActions(\n target: Highcharts.Point | Highcharts.Point[],\n { isApiCall, overrideTooltipLock }: { isApiCall: boolean; overrideTooltipLock?: boolean },\n ) {\n const point = Array.isArray(target) ? null : target;\n const group = Array.isArray(target) ? target : this.context.derived.getPointsByX(target.x);\n\n if (!this.isTooltipPinned) {\n // Update Highcharts elements state.\n if (point) {\n this.chartExtraHighlight.highlightChartPoint(point);\n } else {\n this.chartExtraHighlight.highlightChartGroup(group);\n }\n\n // Update tooltip and legend state.\n if (point) {\n this.chartExtraLegend.onHighlightPoint(point);\n this.chartExtraTooltip.showTooltipOnPoint(point, group, overrideTooltipLock);\n } else {\n this.chartExtraLegend.onHighlightGroup(group);\n this.chartExtraTooltip.showTooltipOnGroup(group, overrideTooltipLock);\n }\n\n // Notify the consumer that a highlight action was made.\n fireNonCancelableEvent(this.context.handlers.onHighlight, { point, group, isApiCall });\n }\n }\n\n private clearHighlightActions = ({ isApiCall }: { isApiCall: boolean }) => {\n if (!this.isTooltipPinned) {\n // Update Highcharts elements state.\n this.chartExtraHighlight.clearChartItemsHighlight();\n\n // Update tooltip and legend state.\n this.chartExtraTooltip.hideTooltip();\n this.chartExtraLegend.onClearHighlight();\n\n // Notify the consumer that a clear-highlight action was made.\n fireNonCancelableEvent(this.context.handlers.onClearHighlight, { isApiCall });\n }\n };\n\n private get isTooltipPinned() {\n return this.chartExtraTooltip.get().pinned;\n }\n}\n\nfunction isPointsPositionsEqual(current?: Highcharts.Point, next?: Highcharts.Point) {\n return current?.x === next?.x && current?.y === next?.y;\n}\n"]}
@@ -0,0 +1,20 @@
1
+ /// <reference types="react" />
2
+ interface ChartContainerProps {
3
+ chart: (height: undefined | number) => React.ReactNode;
4
+ verticalAxisTitle?: React.ReactNode;
5
+ verticalAxisTitlePlacement: "top" | "side";
6
+ header?: React.ReactNode;
7
+ filter?: React.ReactNode;
8
+ navigator?: React.ReactNode;
9
+ legend?: React.ReactNode;
10
+ legendBottomMaxHeight?: number;
11
+ legendPosition: "bottom" | "side";
12
+ footer?: React.ReactNode;
13
+ noData?: React.ReactNode;
14
+ fitHeight?: boolean;
15
+ chartHeight?: number;
16
+ chartMinHeight?: number;
17
+ chartMinWidth?: number;
18
+ }
19
+ export declare function ChartContainer({ chart, verticalAxisTitle, verticalAxisTitlePlacement, header, filter, footer, legend, legendPosition, legendBottomMaxHeight, navigator, noData, fitHeight, chartHeight, chartMinHeight, chartMinWidth, }: ChartContainerProps): import("react/jsx-runtime").JSX.Element;
20
+ export {};
@@ -0,0 +1,55 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ import { useCallback, useRef, useState } from "react";
5
+ import clsx from "clsx";
6
+ import { useResizeObserver } from "@cloudscape-design/component-toolkit/internal";
7
+ import * as Styles from "../internal/chart-styles";
8
+ import { DebouncedCall } from "../internal/utils/utils";
9
+ import styles from "./styles.css.js";
10
+ import testClasses from "./test-classes/styles.css.js";
11
+ // Chart container implements the layout for top-level components, including chart plot, legend, and more.
12
+ // It also implements the height- and width overflow behaviors.
13
+ const DEFAULT_CHART_HEIGHT = 400;
14
+ const DEFAULT_CHART_MIN_HEIGHT = 200;
15
+ export function ChartContainer({ chart, verticalAxisTitle, verticalAxisTitlePlacement, header, filter, footer, legend, legendPosition, legendBottomMaxHeight, navigator, noData, fitHeight, chartHeight, chartMinHeight, chartMinWidth, }) {
16
+ const { refs, measures } = useContainerQueries();
17
+ // The vertical axis title is rendered above the chart, and is technically not a part of the chart plot.
18
+ // However, we want to include it to the chart's height computations as it does belong to the chart logically.
19
+ // We do so by taking the title's constant height into account, when "top" axis placement is chosen.
20
+ const verticalTitleOffset = Styles.verticalAxisTitleBlockSize + Styles.verticalAxisTitleMargin;
21
+ const heightOffset = verticalAxisTitlePlacement === "top" ? verticalTitleOffset : 0;
22
+ const withMinHeight = (height) => Math.max(chartMinHeight !== null && chartMinHeight !== void 0 ? chartMinHeight : DEFAULT_CHART_MIN_HEIGHT, height) - heightOffset;
23
+ const measuredChartHeight = withMinHeight(measures.chart - measures.header - measures.footer);
24
+ const effectiveChartHeight = fitHeight ? measuredChartHeight : withMinHeight(chartHeight !== null && chartHeight !== void 0 ? chartHeight : DEFAULT_CHART_HEIGHT);
25
+ return (_jsxs("div", { ref: refs.chart, className: clsx({
26
+ [styles["chart-container-fit-height"]]: fitHeight,
27
+ [styles["chart-container-min-width"]]: chartMinWidth !== undefined,
28
+ }), children: [_jsxs("div", { ref: refs.header, children: [header, filter] }), legend && legendPosition === "side" ? (_jsxs("div", { className: styles["chart-plot-and-legend-wrapper"], children: [_jsxs("div", { style: { minInlineSize: chartMinWidth !== null && chartMinWidth !== void 0 ? chartMinWidth : 0 }, className: clsx(styles["chart-plot-wrapper"], testClasses["chart-plot-wrapper"]), children: [verticalAxisTitle, chart(effectiveChartHeight), noData] }), _jsx("div", { className: styles["side-legend-container"], style: { maxBlockSize: effectiveChartHeight }, children: legend })] })) : (_jsxs("div", { style: chartMinWidth !== undefined ? { minInlineSize: chartMinWidth } : {}, className: clsx(styles["chart-plot-wrapper"], testClasses["chart-plot-wrapper"]), children: [verticalAxisTitle, chart(effectiveChartHeight), !legend || legendPosition === "bottom" ? noData : null] })), _jsxs("div", { ref: refs.footer, style: chartMinWidth !== undefined ? { minInlineSize: chartMinWidth } : {}, children: [navigator && _jsx("div", { className: testClasses["chart-navigator"], children: navigator }), legend &&
29
+ legendPosition === "bottom" &&
30
+ (legendBottomMaxHeight ? _jsx("div", { style: { maxHeight: `${legendBottomMaxHeight}px` }, children: legend }) : legend), footer] })] }));
31
+ }
32
+ // This hook combines 3 resize observer and does a small optimization to batch their updates in a single set-state.
33
+ function useContainerQueries() {
34
+ const [measuresState, setMeasuresState] = useState({ ready: false, chart: 0, header: 0, footer: 0 });
35
+ const measuresRef = useRef({ ready: false, chart: 0, header: 0, footer: 0 });
36
+ const measureDebounce = useRef(new DebouncedCall()).current;
37
+ const setMeasure = (type, value) => {
38
+ measuresRef.current[type] = value;
39
+ measureDebounce.call(() => setMeasuresState({ ...measuresRef.current }), 0);
40
+ };
41
+ const chartMeasureRef = useRef(null);
42
+ const getChart = useCallback(() => chartMeasureRef.current, []);
43
+ useResizeObserver(getChart, (entry) => setMeasure("chart", entry.contentBoxHeight));
44
+ const headerMeasureRef = useRef(null);
45
+ const getHeader = useCallback(() => headerMeasureRef.current, []);
46
+ useResizeObserver(getHeader, (entry) => setMeasure("header", entry.contentBoxHeight));
47
+ const footerMeasureRef = useRef(null);
48
+ const getFooter = useCallback(() => footerMeasureRef.current, []);
49
+ useResizeObserver(getFooter, (entry) => setMeasure("footer", entry.contentBoxHeight));
50
+ return {
51
+ refs: { chart: chartMeasureRef, header: headerMeasureRef, footer: footerMeasureRef },
52
+ measures: measuresState,
53
+ };
54
+ }
55
+ //# sourceMappingURL=chart-container.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chart-container.js","sourceRoot":"","sources":["../../../src/core/chart-container.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { useCallback, useRef, useState } from \"react\";\nimport clsx from \"clsx\";\n\nimport { useResizeObserver } from \"@cloudscape-design/component-toolkit/internal\";\n\nimport * as Styles from \"../internal/chart-styles\";\nimport { DebouncedCall } from \"../internal/utils/utils\";\n\nimport styles from \"./styles.css.js\";\nimport testClasses from \"./test-classes/styles.css.js\";\n\n// Chart container implements the layout for top-level components, including chart plot, legend, and more.\n// It also implements the height- and width overflow behaviors.\n\nconst DEFAULT_CHART_HEIGHT = 400;\nconst DEFAULT_CHART_MIN_HEIGHT = 200;\n\ninterface ChartContainerProps {\n // The header, footer, vertical axis title, and legend are rendered as is, and we measure the height of these components\n // to compute the available height for the chart plot when fitHeight=true. When there is not enough vertical space, the\n // container will ensure the overflow behavior.\n chart: (height: undefined | number) => React.ReactNode;\n verticalAxisTitle?: React.ReactNode;\n verticalAxisTitlePlacement: \"top\" | \"side\";\n header?: React.ReactNode;\n filter?: React.ReactNode;\n navigator?: React.ReactNode;\n legend?: React.ReactNode;\n legendBottomMaxHeight?: number;\n legendPosition: \"bottom\" | \"side\";\n footer?: React.ReactNode;\n noData?: React.ReactNode;\n fitHeight?: boolean;\n chartHeight?: number;\n chartMinHeight?: number;\n chartMinWidth?: number;\n}\n\nexport function ChartContainer({\n chart,\n verticalAxisTitle,\n verticalAxisTitlePlacement,\n header,\n filter,\n footer,\n legend,\n legendPosition,\n legendBottomMaxHeight,\n navigator,\n noData,\n fitHeight,\n chartHeight,\n chartMinHeight,\n chartMinWidth,\n}: ChartContainerProps) {\n const { refs, measures } = useContainerQueries();\n\n // The vertical axis title is rendered above the chart, and is technically not a part of the chart plot.\n // However, we want to include it to the chart's height computations as it does belong to the chart logically.\n // We do so by taking the title's constant height into account, when \"top\" axis placement is chosen.\n const verticalTitleOffset = Styles.verticalAxisTitleBlockSize + Styles.verticalAxisTitleMargin;\n const heightOffset = verticalAxisTitlePlacement === \"top\" ? verticalTitleOffset : 0;\n const withMinHeight = (height: number) => Math.max(chartMinHeight ?? DEFAULT_CHART_MIN_HEIGHT, height) - heightOffset;\n const measuredChartHeight = withMinHeight(measures.chart - measures.header - measures.footer);\n const effectiveChartHeight = fitHeight ? measuredChartHeight : withMinHeight(chartHeight ?? DEFAULT_CHART_HEIGHT);\n return (\n <div\n ref={refs.chart}\n className={clsx({\n [styles[\"chart-container-fit-height\"]]: fitHeight,\n [styles[\"chart-container-min-width\"]]: chartMinWidth !== undefined,\n })}\n >\n <div ref={refs.header}>\n {header}\n {filter}\n </div>\n\n {legend && legendPosition === \"side\" ? (\n <div className={styles[\"chart-plot-and-legend-wrapper\"]}>\n <div\n style={{ minInlineSize: chartMinWidth ?? 0 }}\n className={clsx(styles[\"chart-plot-wrapper\"], testClasses[\"chart-plot-wrapper\"])}\n >\n {verticalAxisTitle}\n {chart(effectiveChartHeight)}\n {noData}\n </div>\n <div className={styles[\"side-legend-container\"]} style={{ maxBlockSize: effectiveChartHeight }}>\n {legend}\n </div>\n </div>\n ) : (\n <div\n style={chartMinWidth !== undefined ? { minInlineSize: chartMinWidth } : {}}\n className={clsx(styles[\"chart-plot-wrapper\"], testClasses[\"chart-plot-wrapper\"])}\n >\n {verticalAxisTitle}\n {chart(effectiveChartHeight)}\n {!legend || legendPosition === \"bottom\" ? noData : null}\n </div>\n )}\n\n <div ref={refs.footer} style={chartMinWidth !== undefined ? { minInlineSize: chartMinWidth } : {}}>\n {navigator && <div className={testClasses[\"chart-navigator\"]}>{navigator}</div>}\n {legend &&\n legendPosition === \"bottom\" &&\n (legendBottomMaxHeight ? <div style={{ maxHeight: `${legendBottomMaxHeight}px` }}>{legend}</div> : legend)}\n {footer}\n </div>\n </div>\n );\n}\n\n// This hook combines 3 resize observer and does a small optimization to batch their updates in a single set-state.\nfunction useContainerQueries() {\n const [measuresState, setMeasuresState] = useState({ ready: false, chart: 0, header: 0, footer: 0 });\n const measuresRef = useRef({ ready: false, chart: 0, header: 0, footer: 0 });\n const measureDebounce = useRef(new DebouncedCall()).current;\n const setMeasure = (type: \"chart\" | \"header\" | \"footer\", value: number) => {\n measuresRef.current[type] = value;\n measureDebounce.call(() => setMeasuresState({ ...measuresRef.current }), 0);\n };\n\n const chartMeasureRef = useRef<HTMLDivElement>(null);\n const getChart = useCallback(() => chartMeasureRef.current, []);\n useResizeObserver(getChart, (entry) => setMeasure(\"chart\", entry.contentBoxHeight));\n\n const headerMeasureRef = useRef<HTMLDivElement>(null);\n const getHeader = useCallback(() => headerMeasureRef.current, []);\n useResizeObserver(getHeader, (entry) => setMeasure(\"header\", entry.contentBoxHeight));\n\n const footerMeasureRef = useRef<HTMLDivElement>(null);\n const getFooter = useCallback(() => footerMeasureRef.current, []);\n useResizeObserver(getFooter, (entry) => setMeasure(\"footer\", entry.contentBoxHeight));\n\n return {\n refs: { chart: chartMeasureRef, header: headerMeasureRef, footer: footerMeasureRef },\n measures: measuresState,\n };\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import { InternalBaseComponentProps } from "../internal/base-component/use-base-component";
2
+ import { CoreChartProps } from "./interfaces";
3
+ /**
4
+ * CoreChart is the core internal abstraction that accepts the entire set of Highcharts options along
5
+ * with Cloudscape props to define custom tooltip, no-data, formatters, items visibility, and more.
6
+ */
7
+ export declare function InternalCoreChart({ options, ariaLabel, ariaDescription, fitHeight, chartHeight, chartMinHeight, chartMinWidth, tooltip: tooltipOptions, noData: noDataOptions, navigator, legend: legendOptions, fallback, callback, emphasizeBaseline, verticalAxisTitlePlacement, i18nStrings, className, header, footer, filter, keyboardNavigation, onHighlight, onLegendItemHighlight, onClearHighlight, onVisibleItemsChange, visibleItems, __internalRootRef, ...rest }: CoreChartProps & InternalBaseComponentProps): import("react/jsx-runtime").JSX.Element;