@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.
- package/LICENSE +175 -0
- package/NOTICE +1 -0
- package/README.md +25 -0
- package/cartesian-chart/chart-cartesian-internal.d.ts +10 -0
- package/cartesian-chart/chart-cartesian-internal.js +99 -0
- package/cartesian-chart/chart-cartesian-internal.js.map +1 -0
- package/cartesian-chart/chart-series-cartesian.d.ts +7 -0
- package/cartesian-chart/chart-series-cartesian.js +95 -0
- package/cartesian-chart/chart-series-cartesian.js.map +1 -0
- package/cartesian-chart/index.d.ts +5 -0
- package/cartesian-chart/index.js +133 -0
- package/cartesian-chart/index.js.map +1 -0
- package/cartesian-chart/interfaces.d.ts +166 -0
- package/cartesian-chart/interfaces.js +4 -0
- package/cartesian-chart/interfaces.js.map +1 -0
- package/cartesian-chart/test-classes/styles.css.js +6 -0
- package/cartesian-chart/test-classes/styles.scoped.css +7 -0
- package/cartesian-chart/test-classes/styles.selectors.js +7 -0
- package/core/chart-api/chart-extra-axis-titles.d.ts +10 -0
- package/core/chart-api/chart-extra-axis-titles.js +42 -0
- package/core/chart-api/chart-extra-axis-titles.js.map +1 -0
- package/core/chart-api/chart-extra-context.d.ts +41 -0
- package/core/chart-api/chart-extra-context.js +93 -0
- package/core/chart-api/chart-extra-context.js.map +1 -0
- package/core/chart-api/chart-extra-highlight.d.ts +20 -0
- package/core/chart-api/chart-extra-highlight.js +205 -0
- package/core/chart-api/chart-extra-highlight.js.map +1 -0
- package/core/chart-api/chart-extra-legend.d.ts +27 -0
- package/core/chart-api/chart-extra-legend.js +118 -0
- package/core/chart-api/chart-extra-legend.js.map +1 -0
- package/core/chart-api/chart-extra-navigation.d.ts +84 -0
- package/core/chart-api/chart-extra-navigation.js +470 -0
- package/core/chart-api/chart-extra-navigation.js.map +1 -0
- package/core/chart-api/chart-extra-nodata.d.ts +15 -0
- package/core/chart-api/chart-extra-nodata.js +45 -0
- package/core/chart-api/chart-extra-nodata.js.map +1 -0
- package/core/chart-api/chart-extra-pointer.d.ts +33 -0
- package/core/chart-api/chart-extra-pointer.js +173 -0
- package/core/chart-api/chart-extra-pointer.js.map +1 -0
- package/core/chart-api/chart-extra-tooltip.d.ts +33 -0
- package/core/chart-api/chart-extra-tooltip.js +209 -0
- package/core/chart-api/chart-extra-tooltip.js.map +1 -0
- package/core/chart-api/index.d.ts +75 -0
- package/core/chart-api/index.js +383 -0
- package/core/chart-api/index.js.map +1 -0
- package/core/chart-container.d.ts +20 -0
- package/core/chart-container.js +55 -0
- package/core/chart-container.js.map +1 -0
- package/core/chart-core.d.ts +7 -0
- package/core/chart-core.js +287 -0
- package/core/chart-core.js.map +1 -0
- package/core/components/core-application.d.ts +6 -0
- package/core/components/core-application.js +16 -0
- package/core/components/core-application.js.map +1 -0
- package/core/components/core-filters.d.ts +9 -0
- package/core/components/core-filters.js +22 -0
- package/core/components/core-filters.js.map +1 -0
- package/core/components/core-legend.d.ts +13 -0
- package/core/components/core-legend.js +27 -0
- package/core/components/core-legend.js.map +1 -0
- package/core/components/core-no-data.d.ts +6 -0
- package/core/components/core-no-data.js +48 -0
- package/core/components/core-no-data.js.map +1 -0
- package/core/components/core-slots.d.ts +7 -0
- package/core/components/core-slots.js +11 -0
- package/core/components/core-slots.js.map +1 -0
- package/core/components/core-tooltip.d.ts +7 -0
- package/core/components/core-tooltip.js +183 -0
- package/core/components/core-tooltip.js.map +1 -0
- package/core/components/core-vertical-axis-title.d.ts +5 -0
- package/core/components/core-vertical-axis-title.js +15 -0
- package/core/components/core-vertical-axis-title.js.map +1 -0
- package/core/formatters.d.ts +2 -0
- package/core/formatters.js +113 -0
- package/core/formatters.js.map +1 -0
- package/core/i18n-utils.d.ts +21 -0
- package/core/i18n-utils.js +18 -0
- package/core/i18n-utils.js.map +1 -0
- package/core/interfaces.d.ts +436 -0
- package/core/interfaces.js +4 -0
- package/core/interfaces.js.map +1 -0
- package/core/styles.css.js +25 -0
- package/core/styles.scoped.css +115 -0
- package/core/styles.selectors.js +26 -0
- package/core/test-classes/styles.css.js +33 -0
- package/core/test-classes/styles.scoped.css +34 -0
- package/core/test-classes/styles.selectors.js +34 -0
- package/core/utils.d.ts +45 -0
- package/core/utils.js +262 -0
- package/core/utils.js.map +1 -0
- package/index.d.ts +4 -0
- package/index.js +5 -0
- package/index.js.map +1 -0
- package/internal/api-docs/components/cartesian-chart.js +571 -0
- package/internal/api-docs/components/index.d.ts +3 -0
- package/internal/api-docs/components/index.js +4 -0
- package/internal/api-docs/components/interfaces.d.ts +81 -0
- package/internal/api-docs/components/pie-chart.js +430 -0
- package/internal/api-docs/test-utils-doc/dom.js +4 -0
- package/internal/api-docs/test-utils-doc/selectors.js +4 -0
- package/internal/base-component/get-data-attributes.d.ts +1 -0
- package/internal/base-component/get-data-attributes.js +12 -0
- package/internal/base-component/get-data-attributes.js.map +1 -0
- package/internal/base-component/use-base-component.d.ts +13 -0
- package/internal/base-component/use-base-component.js +18 -0
- package/internal/base-component/use-base-component.js.map +1 -0
- package/internal/base-component/use-telemetry.d.ts +2 -0
- package/internal/base-component/use-telemetry.js +8 -0
- package/internal/base-component/use-telemetry.js.map +1 -0
- package/internal/chart-styles.d.ts +88 -0
- package/internal/chart-styles.js +145 -0
- package/internal/chart-styles.js.map +1 -0
- package/internal/components/chart-legend/index.d.ts +14 -0
- package/internal/components/chart-legend/index.js +245 -0
- package/internal/components/chart-legend/index.js.map +1 -0
- package/internal/components/chart-legend/styles.css.js +22 -0
- package/internal/components/chart-legend/styles.scoped.css +233 -0
- package/internal/components/chart-legend/styles.selectors.js +23 -0
- package/internal/components/chart-legend/test-classes/styles.css.js +11 -0
- package/internal/components/chart-legend/test-classes/styles.scoped.css +12 -0
- package/internal/components/chart-legend/test-classes/styles.selectors.js +12 -0
- package/internal/components/chart-series-filter/index.d.ts +17 -0
- package/internal/components/chart-series-filter/index.js +14 -0
- package/internal/components/chart-series-filter/index.js.map +1 -0
- package/internal/components/interfaces.d.ts +17 -0
- package/internal/components/interfaces.js +4 -0
- package/internal/components/interfaces.js.map +1 -0
- package/internal/components/series-details/index.d.ts +23 -0
- package/internal/components/series-details/index.js +45 -0
- package/internal/components/series-details/index.js.map +1 -0
- package/internal/components/series-details/styles.css.js +22 -0
- package/internal/components/series-details/styles.scoped.css +150 -0
- package/internal/components/series-details/styles.selectors.js +23 -0
- package/internal/components/series-details/test-classes/styles.css.js +10 -0
- package/internal/components/series-details/test-classes/styles.scoped.css +11 -0
- package/internal/components/series-details/test-classes/styles.selectors.js +11 -0
- package/internal/components/series-marker/index.d.ts +8 -0
- package/internal/components/series-marker/index.js +45 -0
- package/internal/components/series-marker/index.js.map +1 -0
- package/internal/components/series-marker/interfaces.d.ts +1 -0
- package/internal/components/series-marker/interfaces.js +4 -0
- package/internal/components/series-marker/interfaces.js.map +1 -0
- package/internal/components/series-marker/render-marker.d.ts +3 -0
- package/internal/components/series-marker/render-marker.js +74 -0
- package/internal/components/series-marker/render-marker.js.map +1 -0
- package/internal/components/series-marker/styles.css.js +7 -0
- package/internal/components/series-marker/styles.scoped.css +55 -0
- package/internal/components/series-marker/styles.selectors.js +8 -0
- package/internal/environment.d.ts +4 -0
- package/internal/environment.js +5 -0
- package/internal/environment.json +7 -0
- package/internal/events/index.d.ts +23 -0
- package/internal/events/index.js +41 -0
- package/internal/events/index.js.map +1 -0
- package/internal/generated/styles/tokens.d.ts +756 -0
- package/internal/generated/styles/tokens.js +756 -0
- package/internal/generated/theming/index.cjs +12584 -0
- package/internal/generated/theming/index.cjs.d.ts +2399 -0
- package/internal/generated/theming/index.d.ts +2399 -0
- package/internal/generated/theming/index.js +12584 -0
- package/internal/manifest.json +3 -0
- package/internal/styles.css.js +6 -0
- package/internal/styles.scoped.css +13 -0
- package/internal/styles.selectors.js +7 -0
- package/internal/utils/apply-display-name.d.ts +1 -0
- package/internal/utils/apply-display-name.js +6 -0
- package/internal/utils/apply-display-name.js.map +1 -0
- package/internal/utils/async-store.d.ts +19 -0
- package/internal/utils/async-store.js +58 -0
- package/internal/utils/async-store.js.map +1 -0
- package/internal/utils/chart-series.d.ts +8 -0
- package/internal/utils/chart-series.js +11 -0
- package/internal/utils/chart-series.js.map +1 -0
- package/internal/utils/renderer-utils.d.ts +17 -0
- package/internal/utils/renderer-utils.js +95 -0
- package/internal/utils/renderer-utils.js.map +1 -0
- package/internal/utils/series-data.d.ts +2 -0
- package/internal/utils/series-data.js +8 -0
- package/internal/utils/series-data.js.map +1 -0
- package/internal/utils/test-i18n-provider.d.ts +8 -0
- package/internal/utils/test-i18n-provider.js +8 -0
- package/internal/utils/test-i18n-provider.js.map +1 -0
- package/internal/utils/use-previous.d.ts +4 -0
- package/internal/utils/use-previous.js +14 -0
- package/internal/utils/use-previous.js.map +1 -0
- package/internal/utils/utils.d.ts +16 -0
- package/internal/utils/utils.js +49 -0
- package/internal/utils/utils.js.map +1 -0
- package/internal-do-not-use/core-chart/index.d.ts +4 -0
- package/internal-do-not-use/core-chart/index.js +13 -0
- package/internal-do-not-use/core-chart/index.js.map +1 -0
- package/internal-do-not-use/core-legend/index.d.ts +2 -0
- package/internal-do-not-use/core-legend/index.js +11 -0
- package/internal-do-not-use/core-legend/index.js.map +1 -0
- package/package.json +106 -0
- package/pie-chart/chart-inner-area.d.ts +10 -0
- package/pie-chart/chart-inner-area.js +63 -0
- package/pie-chart/chart-inner-area.js.map +1 -0
- package/pie-chart/chart-pie-internal.d.ts +11 -0
- package/pie-chart/chart-pie-internal.js +103 -0
- package/pie-chart/chart-pie-internal.js.map +1 -0
- package/pie-chart/index.d.ts +5 -0
- package/pie-chart/index.js +48 -0
- package/pie-chart/index.js.map +1 -0
- package/pie-chart/interfaces.d.ts +101 -0
- package/pie-chart/interfaces.js +4 -0
- package/pie-chart/interfaces.js.map +1 -0
- package/pie-chart/test-classes/styles.css.js +8 -0
- package/pie-chart/test-classes/styles.scoped.css +9 -0
- package/pie-chart/test-classes/styles.selectors.js +9 -0
- package/test-utils/dom/cartesian-chart/index.d.ts +14 -0
- package/test-utils/dom/cartesian-chart/index.js +24 -0
- package/test-utils/dom/cartesian-chart/index.js.map +1 -0
- package/test-utils/dom/cartesian-chart/tooltip.d.ts +28 -0
- package/test-utils/dom/cartesian-chart/tooltip.js +48 -0
- package/test-utils/dom/cartesian-chart/tooltip.js.map +1 -0
- package/test-utils/dom/index.d.ts +46 -0
- package/test-utils/dom/index.js +35 -0
- package/test-utils/dom/index.js.map +1 -0
- package/test-utils/dom/internal/base.d.ts +93 -0
- package/test-utils/dom/internal/base.js +146 -0
- package/test-utils/dom/internal/base.js.map +1 -0
- package/test-utils/dom/internal/core.d.ts +14 -0
- package/test-utils/dom/internal/core.js +37 -0
- package/test-utils/dom/internal/core.js.map +1 -0
- package/test-utils/dom/pie-chart/index.d.ts +17 -0
- package/test-utils/dom/pie-chart/index.js +29 -0
- package/test-utils/dom/pie-chart/index.js.map +1 -0
- package/test-utils/selectors/cartesian-chart/index.d.ts +14 -0
- package/test-utils/selectors/cartesian-chart/index.js +24 -0
- package/test-utils/selectors/cartesian-chart/index.js.map +1 -0
- package/test-utils/selectors/cartesian-chart/tooltip.d.ts +28 -0
- package/test-utils/selectors/cartesian-chart/tooltip.js +48 -0
- package/test-utils/selectors/cartesian-chart/tooltip.js.map +1 -0
- package/test-utils/selectors/index.d.ts +46 -0
- package/test-utils/selectors/index.js +32 -0
- package/test-utils/selectors/index.js.map +1 -0
- package/test-utils/selectors/internal/base.d.ts +93 -0
- package/test-utils/selectors/internal/base.js +146 -0
- package/test-utils/selectors/internal/base.js.map +1 -0
- package/test-utils/selectors/internal/core.d.ts +14 -0
- package/test-utils/selectors/internal/core.js +37 -0
- package/test-utils/selectors/internal/core.js.map +1 -0
- package/test-utils/selectors/pie-chart/index.d.ts +17 -0
- package/test-utils/selectors/pie-chart/index.js +29 -0
- package/test-utils/selectors/pie-chart/index.js.map +1 -0
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { circleIndex, getIsRtl, handleKey as toolkitHandleKey, KeyCode, } from "@cloudscape-design/component-toolkit/internal";
|
|
4
|
+
import * as Styles from "../../internal/chart-styles";
|
|
5
|
+
import { SVGRendererPool } from "../../internal/utils/renderer-utils";
|
|
6
|
+
import { getGroupRect, getPointRect, isPointVisible, isXThreshold } from "../utils";
|
|
7
|
+
// In charts with many data points one can navigate faster by using Page Down/Up keys that
|
|
8
|
+
// navigate PAGE_SIZE_PERCENTAGE of the points forwards or backwards.
|
|
9
|
+
const PAGE_SIZE_PERCENTAGE = 0.05;
|
|
10
|
+
// Navigation controller handles focus behavior and keyboard navigation for all charts.
|
|
11
|
+
// When the chart is first focused, the focus lands on the chart plot. Once navigation is engaged,
|
|
12
|
+
// the focus can land either on the group of points matched by X value, or on a specific point.
|
|
13
|
+
// The focused X value and point are stored so that navigating back to the chart will focus the previously
|
|
14
|
+
// focused point. If the stored point no longer belongs to the chart the focus falls back to the chart plot.
|
|
15
|
+
export class ChartExtraNavigation {
|
|
16
|
+
constructor(context, handlers) {
|
|
17
|
+
// The application element is a dom element with role="application", rendered right before the chart plot.
|
|
18
|
+
// When the application element is in focus, the keyboard navigation is possible. Upon using navigation commands,
|
|
19
|
+
// we bring the visible focus state to the chart elements, such as points and groups of points. The last visible
|
|
20
|
+
// focus state is persisted.
|
|
21
|
+
this.applicationElement = null;
|
|
22
|
+
this.focusedState = null;
|
|
23
|
+
this.ignoreFocus = false;
|
|
24
|
+
// This function is used as React ref on the application element, positioned right before the chart plot in the DOM.
|
|
25
|
+
// Once the element reference is obtained, we assign the required event listeners directly to the element.
|
|
26
|
+
// That is done for simplicity to avoid passing React event handlers down to the element.
|
|
27
|
+
this.setApplication = (element) => {
|
|
28
|
+
if (this.applicationElement) {
|
|
29
|
+
this.applicationElement.removeEventListener("focus", this.onFocus);
|
|
30
|
+
this.applicationElement.removeEventListener("blur", this.onBlur);
|
|
31
|
+
this.applicationElement.removeEventListener("keydown", this.onKeyDown);
|
|
32
|
+
}
|
|
33
|
+
if (this.context.settings.keyboardNavigationEnabled || !element) {
|
|
34
|
+
this.applicationElement = element;
|
|
35
|
+
}
|
|
36
|
+
if (this.applicationElement) {
|
|
37
|
+
this.applicationElement.addEventListener("focus", this.onFocus);
|
|
38
|
+
this.applicationElement.addEventListener("blur", this.onBlur);
|
|
39
|
+
this.applicationElement.addEventListener("keydown", this.onKeyDown);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
// Upon obtaining focus, we show the visible focus state and announce the previously focused element
|
|
43
|
+
// (chart, point, or group). If the previously focused point or group is no longer available, the focus
|
|
44
|
+
// is shown for their respective parent.
|
|
45
|
+
this.onFocus = () => {
|
|
46
|
+
if (!this.ignoreFocus) {
|
|
47
|
+
if (!this.focusedState || this.focusedState.type === "chart") {
|
|
48
|
+
this.focusChart();
|
|
49
|
+
}
|
|
50
|
+
else if (this.focusedState.type === "group") {
|
|
51
|
+
this.focusGroup(this.focusedState.group);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
this.focusPoint(this.focusedState.point, this.focusedState.group);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
this.onBlur = () => {
|
|
59
|
+
if (!this.ignoreFocus) {
|
|
60
|
+
this.focusOutline.hide();
|
|
61
|
+
this.handlers.onBlur();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
this.onKeyDown = (event) => {
|
|
65
|
+
// The `handleKey` helper we use does not prevent the default keys behavior, so we do it here for
|
|
66
|
+
// all used keyboard commands.
|
|
67
|
+
if ([
|
|
68
|
+
KeyCode.up,
|
|
69
|
+
KeyCode.down,
|
|
70
|
+
KeyCode.left,
|
|
71
|
+
KeyCode.right,
|
|
72
|
+
KeyCode.enter,
|
|
73
|
+
KeyCode.escape,
|
|
74
|
+
KeyCode.pageUp,
|
|
75
|
+
KeyCode.pageDown,
|
|
76
|
+
KeyCode.home,
|
|
77
|
+
KeyCode.end,
|
|
78
|
+
].includes(event.keyCode)) {
|
|
79
|
+
event.preventDefault();
|
|
80
|
+
}
|
|
81
|
+
// We execute different actions depending on the current focus target (chart, group, or point).
|
|
82
|
+
// It is expected, that the focused element is still available in the chart.
|
|
83
|
+
if (this.focusedState && this.focusedState.type === "group") {
|
|
84
|
+
this.onKeyDownGroup(event, this.focusedState.group);
|
|
85
|
+
}
|
|
86
|
+
else if (this.focusedState && this.focusedState.type === "point") {
|
|
87
|
+
this.onKeyDownPoint(event, this.focusedState.point, this.focusedState.group);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
this.onKeyDownChart(event);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
this.onKeyDownChart = (event) => {
|
|
94
|
+
handleKey(event, {
|
|
95
|
+
onActivate: () => this.moveToFirstGroup(),
|
|
96
|
+
onInlineStart: () => this.moveToLastGroup(),
|
|
97
|
+
onInlineEnd: () => this.moveToFirstGroup(),
|
|
98
|
+
onBlockStart: () => this.moveToLastGroup(),
|
|
99
|
+
onBlockEnd: () => this.moveToFirstGroup(),
|
|
100
|
+
onHome: () => this.moveToFirstGroup(),
|
|
101
|
+
onEnd: () => this.moveToLastGroup(),
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
this.onKeyDownGroup = (event, group) => {
|
|
105
|
+
const i = !!this.context.chart().inverted;
|
|
106
|
+
handleKey(event, {
|
|
107
|
+
onActivate: () => this.activateGroup(group),
|
|
108
|
+
onEscape: () => this.moveToChart(),
|
|
109
|
+
onInlineStart: () => (i ? this.moveToFirstInGroup(group) : this.moveToPrevGroup(group)),
|
|
110
|
+
onInlineEnd: () => (i ? this.moveToLastInGroup(group) : this.moveToNextGroup(group)),
|
|
111
|
+
onBlockStart: () => (i ? this.moveToPrevGroup(group) : this.moveToLastInGroup(group)),
|
|
112
|
+
onBlockEnd: () => (i ? this.moveToNextGroup(group) : this.moveToFirstInGroup(group)),
|
|
113
|
+
onPageDown: () => this.moveToNextPageGroup(group),
|
|
114
|
+
onPageUp: () => this.moveToPrevPageGroup(group),
|
|
115
|
+
onHome: () => this.moveToFirstGroup(),
|
|
116
|
+
onEnd: () => this.moveToLastGroup(),
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
this.onKeyDownPoint = (event, point, group) => {
|
|
120
|
+
const i = !!this.context.chart().inverted;
|
|
121
|
+
handleKey(event, {
|
|
122
|
+
onActivate: () => this.activatePoint(point, group),
|
|
123
|
+
onEscape: () => this.moveToParentGroup(point),
|
|
124
|
+
onInlineEnd: () => (i ? this.moveToPrevInGroup(point) : this.moveToNextInSeries(point)),
|
|
125
|
+
onInlineStart: () => (i ? this.moveToNextInGroup(point) : this.moveToPrevInSeries(point)),
|
|
126
|
+
onBlockEnd: () => (i ? this.moveToNextInSeries(point) : this.moveToNextInGroup(point)),
|
|
127
|
+
onBlockStart: () => (i ? this.moveToPrevInSeries(point) : this.moveToPrevInGroup(point)),
|
|
128
|
+
onPageDown: () => this.moveToNextPageInSeries(point),
|
|
129
|
+
onPageUp: () => this.moveToPrevPageInSeries(point),
|
|
130
|
+
onHome: () => this.moveToFirstInSeries(point),
|
|
131
|
+
onEnd: () => this.moveToLastInSeries(point),
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
this.focusChart = () => {
|
|
135
|
+
this.focusedState = { type: "chart" };
|
|
136
|
+
this.focusOutline.chart();
|
|
137
|
+
this.handlers.onFocusChart();
|
|
138
|
+
};
|
|
139
|
+
this.getAllXInSeries = (series) => {
|
|
140
|
+
return this.context.derived.getAllXInSeries(series);
|
|
141
|
+
};
|
|
142
|
+
this.getPointsByX = (x) => {
|
|
143
|
+
return this.context.derived.getPointsByX(x);
|
|
144
|
+
};
|
|
145
|
+
this.findMatchingGroup = (point) => {
|
|
146
|
+
return this.getPointsByX(point.x);
|
|
147
|
+
};
|
|
148
|
+
this.findFirstGroup = () => {
|
|
149
|
+
return this.getPointsByX(this.allX[0]);
|
|
150
|
+
};
|
|
151
|
+
this.findLastGroup = () => {
|
|
152
|
+
return this.getPointsByX(this.allX[this.allX.length - 1]);
|
|
153
|
+
};
|
|
154
|
+
this.findNextGroup = (point) => {
|
|
155
|
+
const nextIndex = getNextIndex(this.allX, this.allX.indexOf(point.x), 1);
|
|
156
|
+
return this.getPointsByX(this.allX[nextIndex]);
|
|
157
|
+
};
|
|
158
|
+
this.findPrevGroup = (point) => {
|
|
159
|
+
const nextIndex = getNextIndex(this.allX, this.allX.indexOf(point.x), -1);
|
|
160
|
+
return this.getPointsByX(this.allX[nextIndex]);
|
|
161
|
+
};
|
|
162
|
+
this.findNextPageGroup = (point) => {
|
|
163
|
+
const nextIndex = getNextPageIndex(this.allX, this.allX.indexOf(point.x), 1);
|
|
164
|
+
return this.getPointsByX(this.allX[nextIndex]);
|
|
165
|
+
};
|
|
166
|
+
this.findPrevPageGroup = (point) => {
|
|
167
|
+
const nextIndex = getNextPageIndex(this.allX, this.allX.indexOf(point.x), -1);
|
|
168
|
+
return this.getPointsByX(this.allX[nextIndex]);
|
|
169
|
+
};
|
|
170
|
+
this.findFirstPointInSeries = (point) => {
|
|
171
|
+
var _a;
|
|
172
|
+
const seriesX = this.getAllXInSeries(point.series);
|
|
173
|
+
return (_a = point.series.data.find((d) => d.x === seriesX[0])) !== null && _a !== void 0 ? _a : null;
|
|
174
|
+
};
|
|
175
|
+
this.findLastPointInSeries = (point) => {
|
|
176
|
+
var _a;
|
|
177
|
+
const seriesX = this.getAllXInSeries(point.series);
|
|
178
|
+
return (_a = point.series.data.find((d) => d.x === seriesX[seriesX.length - 1])) !== null && _a !== void 0 ? _a : null;
|
|
179
|
+
};
|
|
180
|
+
this.findNextPointInSeries = (point) => {
|
|
181
|
+
var _a;
|
|
182
|
+
const seriesX = this.getAllXInSeries(point.series);
|
|
183
|
+
const delta = !shouldInvertPointsDirection(point) ? 1 : -1;
|
|
184
|
+
const nextIndex = getNextIndex(seriesX, seriesX.indexOf(point.x), delta);
|
|
185
|
+
return (_a = point.series.data.find((d) => d.x === seriesX[nextIndex])) !== null && _a !== void 0 ? _a : null;
|
|
186
|
+
};
|
|
187
|
+
this.findPrevPointInSeries = (point) => {
|
|
188
|
+
var _a;
|
|
189
|
+
const seriesX = this.getAllXInSeries(point.series);
|
|
190
|
+
const delta = !shouldInvertPointsDirection(point) ? -1 : 1;
|
|
191
|
+
const nextIndex = getNextIndex(seriesX, seriesX.indexOf(point.x), delta);
|
|
192
|
+
return (_a = point.series.data.find((d) => d.x === seriesX[nextIndex])) !== null && _a !== void 0 ? _a : null;
|
|
193
|
+
};
|
|
194
|
+
this.findNextPagePointInSeries = (point) => {
|
|
195
|
+
var _a;
|
|
196
|
+
const seriesX = this.getAllXInSeries(point.series);
|
|
197
|
+
const delta = !shouldInvertPointsDirection(point) ? 1 : -1;
|
|
198
|
+
const nextIndex = getNextPageIndex(seriesX, seriesX.indexOf(point.x), delta);
|
|
199
|
+
return (_a = point.series.data.find((d) => d.x === seriesX[nextIndex])) !== null && _a !== void 0 ? _a : null;
|
|
200
|
+
};
|
|
201
|
+
this.findPrevPagePointInSeries = (point) => {
|
|
202
|
+
var _a;
|
|
203
|
+
const seriesX = this.getAllXInSeries(point.series);
|
|
204
|
+
const delta = !shouldInvertPointsDirection(point) ? -1 : 1;
|
|
205
|
+
const nextIndex = getNextPageIndex(seriesX, seriesX.indexOf(point.x), delta);
|
|
206
|
+
return (_a = point.series.data.find((d) => d.x === seriesX[nextIndex])) !== null && _a !== void 0 ? _a : null;
|
|
207
|
+
};
|
|
208
|
+
this.context = context;
|
|
209
|
+
this.handlers = handlers;
|
|
210
|
+
this.focusOutline = new FocusOutline(context);
|
|
211
|
+
}
|
|
212
|
+
onChartDestroy() {
|
|
213
|
+
this.focusOutline.destroy();
|
|
214
|
+
}
|
|
215
|
+
// Casting focus to the application element brings the visible focus state to the chart or last focused
|
|
216
|
+
// chart point or group of points. This is used to restore focus after the tooltip is dismissed.
|
|
217
|
+
focusApplication(point, group) {
|
|
218
|
+
var _a;
|
|
219
|
+
if (this.context.settings.keyboardNavigationEnabled) {
|
|
220
|
+
this.focusedState = point ? { type: "point", point, group } : { type: "group", group };
|
|
221
|
+
(_a = this.applicationElement) === null || _a === void 0 ? void 0 : _a.focus();
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
announceChart(ariaLabel) {
|
|
225
|
+
this.announce({ role: "application", "aria-label": ariaLabel });
|
|
226
|
+
}
|
|
227
|
+
announceElement(ariaLabel, pinned) {
|
|
228
|
+
this.announce({ role: "button", "aria-label": ariaLabel, "aria-haspopup": true, "aria-expanded": pinned });
|
|
229
|
+
}
|
|
230
|
+
// Every time the chart focus is obtained or a navigation action is performed, this needs to be announced
|
|
231
|
+
// to screen-readers. The announcement is made by updating the application element with the attributes of
|
|
232
|
+
// the visually focused element (chart, point, or group), and re-focusing it.
|
|
233
|
+
announce(elementAttributes) {
|
|
234
|
+
if (this.applicationElement) {
|
|
235
|
+
// Remove prev attributes.
|
|
236
|
+
for (const attributeName of this.applicationElement.getAttributeNames()) {
|
|
237
|
+
if (attributeName === "role" || attributeName.slice(0, 4) === "aria") {
|
|
238
|
+
this.applicationElement.removeAttribute(attributeName);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// Copy new attributes.
|
|
242
|
+
for (const [attributeName, attributeValue] of Object.entries(elementAttributes)) {
|
|
243
|
+
this.applicationElement.setAttribute(attributeName, `${attributeValue}`);
|
|
244
|
+
}
|
|
245
|
+
// Temporarily disable focus/blur event handlers to not respond to the next programmatically
|
|
246
|
+
// cast focus event, which has the only purpose of making the application element announced to
|
|
247
|
+
// the assistive software.
|
|
248
|
+
this.ignoreFocus = true;
|
|
249
|
+
// Re-attach and re-focus application element to trigger a screen-reader announcement.
|
|
250
|
+
const container = this.applicationElement.parentElement;
|
|
251
|
+
container.removeChild(this.applicationElement);
|
|
252
|
+
container.appendChild(this.applicationElement);
|
|
253
|
+
this.applicationElement.focus({ preventScroll: true });
|
|
254
|
+
// Remove focus lock. The blur and focus events should have already occurred at this point.
|
|
255
|
+
setTimeout(() => (this.ignoreFocus = false), 0);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
moveToFirstGroup() {
|
|
259
|
+
this.focusGroup(this.findFirstGroup());
|
|
260
|
+
}
|
|
261
|
+
moveToLastGroup() {
|
|
262
|
+
this.focusGroup(this.findLastGroup());
|
|
263
|
+
}
|
|
264
|
+
moveToNextGroup(group) {
|
|
265
|
+
const nextGroup = group[0] ? this.findNextGroup(group[0]) : [];
|
|
266
|
+
this.focusGroup(nextGroup);
|
|
267
|
+
}
|
|
268
|
+
moveToPrevGroup(group) {
|
|
269
|
+
const prevGroup = group[0] ? this.findPrevGroup(group[0]) : [];
|
|
270
|
+
this.focusGroup(prevGroup);
|
|
271
|
+
}
|
|
272
|
+
moveToParentGroup(point) {
|
|
273
|
+
const group = this.findMatchingGroup(point);
|
|
274
|
+
if (group.length > 0 && group[0].series.type !== "pie") {
|
|
275
|
+
this.focusGroup(group);
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
this.focusChart();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
moveToChart() {
|
|
282
|
+
this.focusChart();
|
|
283
|
+
}
|
|
284
|
+
moveToFirstInGroup(group) {
|
|
285
|
+
const points = group.filter((p) => !isXThreshold(p.series));
|
|
286
|
+
this.focusPoint(points[0], group);
|
|
287
|
+
}
|
|
288
|
+
moveToLastInGroup(group) {
|
|
289
|
+
const points = group.filter((p) => !isXThreshold(p.series));
|
|
290
|
+
this.focusPoint(points[points.length - 1], group);
|
|
291
|
+
}
|
|
292
|
+
moveToPrevInGroup(point) {
|
|
293
|
+
const points = this.findMatchingGroup(point).filter((p) => !isXThreshold(p.series));
|
|
294
|
+
const pointIndex = points.indexOf(point);
|
|
295
|
+
this.focusPoint(points[circleIndex(pointIndex - 1, [0, points.length - 1])], points);
|
|
296
|
+
}
|
|
297
|
+
moveToNextInGroup(point) {
|
|
298
|
+
const points = this.findMatchingGroup(point).filter((p) => !isXThreshold(p.series));
|
|
299
|
+
const pointIndex = points.indexOf(point);
|
|
300
|
+
this.focusPoint(points[circleIndex(pointIndex + 1, [0, points.length - 1])], points);
|
|
301
|
+
}
|
|
302
|
+
moveToFirstInSeries(point) {
|
|
303
|
+
const firstPoint = this.findFirstPointInSeries(point);
|
|
304
|
+
if (firstPoint) {
|
|
305
|
+
this.focusPoint(firstPoint, this.findMatchingGroup(firstPoint));
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
this.focusChart();
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
moveToLastInSeries(point) {
|
|
312
|
+
const lastPoint = this.findLastPointInSeries(point);
|
|
313
|
+
if (lastPoint) {
|
|
314
|
+
this.focusPoint(lastPoint, this.findMatchingGroup(lastPoint));
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
this.focusChart();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
moveToNextInSeries(point) {
|
|
321
|
+
const nextPoint = this.findNextPointInSeries(point);
|
|
322
|
+
if (nextPoint) {
|
|
323
|
+
this.focusPoint(nextPoint, this.findMatchingGroup(nextPoint));
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
this.focusChart();
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
moveToPrevInSeries(point) {
|
|
330
|
+
const prevPoint = this.findPrevPointInSeries(point);
|
|
331
|
+
if (prevPoint) {
|
|
332
|
+
this.focusPoint(prevPoint, this.findMatchingGroup(prevPoint));
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
this.focusChart();
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
moveToNextPageGroup(group) {
|
|
339
|
+
const nextPageGroup = group[0] ? this.findNextPageGroup(group[0]) : [];
|
|
340
|
+
this.focusGroup(nextPageGroup);
|
|
341
|
+
}
|
|
342
|
+
moveToPrevPageGroup(group) {
|
|
343
|
+
const prevPageGroup = group[0] ? this.findPrevPageGroup(group[0]) : [];
|
|
344
|
+
this.focusGroup(prevPageGroup);
|
|
345
|
+
}
|
|
346
|
+
moveToNextPageInSeries(point) {
|
|
347
|
+
const nextPagePoint = this.findNextPagePointInSeries(point);
|
|
348
|
+
if (nextPagePoint) {
|
|
349
|
+
this.focusPoint(nextPagePoint, this.findMatchingGroup(nextPagePoint));
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
this.focusChart();
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
moveToPrevPageInSeries(point) {
|
|
356
|
+
const prevPagePoint = this.findPrevPagePointInSeries(point);
|
|
357
|
+
if (prevPagePoint) {
|
|
358
|
+
this.focusPoint(prevPagePoint, this.findMatchingGroup(prevPagePoint));
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
this.focusChart();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
activateGroup(group) {
|
|
365
|
+
this.handlers.onActivateGroup(group);
|
|
366
|
+
}
|
|
367
|
+
activatePoint(point, group) {
|
|
368
|
+
this.handlers.onActivatePoint(point, group);
|
|
369
|
+
}
|
|
370
|
+
focusGroup(group) {
|
|
371
|
+
var _a;
|
|
372
|
+
// When the chart is re-focused, the group that was focused before might no longer be valid if its
|
|
373
|
+
// points are no longer visible or were destroyed by Highcharts. In that case we focus the chart as
|
|
374
|
+
// a fallback.
|
|
375
|
+
const visiblePoints = group.filter(isPointVisible);
|
|
376
|
+
if (visiblePoints.length === 0) {
|
|
377
|
+
this.focusChart();
|
|
378
|
+
}
|
|
379
|
+
// In pie charts we only focus points, so moving focus to points and groups is equivalent.
|
|
380
|
+
else if (visiblePoints[0].series.type === "pie") {
|
|
381
|
+
this.focusPoint((_a = visiblePoints[0]) !== null && _a !== void 0 ? _a : null, group);
|
|
382
|
+
}
|
|
383
|
+
// When focusing a group we draw the focus outline around the corresponding group rect, including
|
|
384
|
+
// all points of that group.
|
|
385
|
+
else {
|
|
386
|
+
this.focusedState = { type: "group", group: visiblePoints };
|
|
387
|
+
this.focusOutline.group(getGroupRect(visiblePoints));
|
|
388
|
+
this.handlers.onFocusGroup(visiblePoints);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
focusPoint(point, group) {
|
|
392
|
+
// When the chart is re-focused, the point that was focused before might no longer be valid it became
|
|
393
|
+
// hidden or was destroyed by Highcharts. In that case we focus the point's parent group as a fallback.
|
|
394
|
+
if (!point || !isPointVisible(point)) {
|
|
395
|
+
this.focusGroup(group);
|
|
396
|
+
}
|
|
397
|
+
// When focusing a point we draw the focus outline around its corresponding rect, but with different offsets,
|
|
398
|
+
// depending on the point's series type.
|
|
399
|
+
else {
|
|
400
|
+
this.focusedState = { type: "point", point, group };
|
|
401
|
+
this.focusOutline.point(getPointRect(point), point);
|
|
402
|
+
this.handlers.onFocusPoint(point, group);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
get allX() {
|
|
406
|
+
return this.context.derived.allX;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
function handleKey(event, handlers) {
|
|
410
|
+
if (!event.currentTarget) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
if (!(event.currentTarget instanceof HTMLElement) && !(event.currentTarget instanceof SVGElement)) {
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
toolkitHandleKey({ keyCode: event.keyCode, currentTarget: event.currentTarget }, handlers);
|
|
417
|
+
}
|
|
418
|
+
// A helper class to draw the focus outline around given chart elements.
|
|
419
|
+
class FocusOutline {
|
|
420
|
+
constructor(context) {
|
|
421
|
+
this.elementsPool = new SVGRendererPool();
|
|
422
|
+
this.chart = () => {
|
|
423
|
+
const [x, y, width, height] = [
|
|
424
|
+
this.context.chart().plotLeft,
|
|
425
|
+
this.context.chart().plotTop,
|
|
426
|
+
this.context.chart().plotWidth,
|
|
427
|
+
this.context.chart().plotHeight,
|
|
428
|
+
];
|
|
429
|
+
this.rect({ x, y, width, height }, Styles.focusOutlineOffsets.chart);
|
|
430
|
+
};
|
|
431
|
+
this.group = (rect) => {
|
|
432
|
+
this.rect(rect, Styles.focusOutlineOffsets.group);
|
|
433
|
+
};
|
|
434
|
+
this.point = (rect, point) => {
|
|
435
|
+
const offsetByType = Styles.focusOutlineOffsets.pointByType[point.series.type];
|
|
436
|
+
const offset = offsetByType !== null && offsetByType !== void 0 ? offsetByType : Styles.focusOutlineOffsets.point;
|
|
437
|
+
this.rect(rect, offset);
|
|
438
|
+
};
|
|
439
|
+
this.rect = ({ x, y, width, height }, offset) => {
|
|
440
|
+
this.elementsPool.hideAll();
|
|
441
|
+
this.elementsPool.rect(this.context.chart().renderer, {
|
|
442
|
+
x: x - offset,
|
|
443
|
+
y: y - offset,
|
|
444
|
+
width: width + offset * 2,
|
|
445
|
+
height: height + offset * 2,
|
|
446
|
+
...Styles.navigationFocusOutline,
|
|
447
|
+
});
|
|
448
|
+
};
|
|
449
|
+
this.context = context;
|
|
450
|
+
}
|
|
451
|
+
hide() {
|
|
452
|
+
this.elementsPool.hideAll();
|
|
453
|
+
}
|
|
454
|
+
destroy() {
|
|
455
|
+
this.elementsPool.destroyAll();
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
// We do not invert the direction of pie segments when RTL, but swap the left/right keys.
|
|
459
|
+
// To offset for that, the prev/next points direction is swapped, too.
|
|
460
|
+
function shouldInvertPointsDirection(point) {
|
|
461
|
+
const isRTL = getIsRtl(point.series.chart.container.parentElement);
|
|
462
|
+
return point.series.type === "pie" && isRTL;
|
|
463
|
+
}
|
|
464
|
+
function getNextIndex(array, pointIndex, delta) {
|
|
465
|
+
return circleIndex(pointIndex + delta, [0, array.length - 1]);
|
|
466
|
+
}
|
|
467
|
+
function getNextPageIndex(array, pointIndex, delta) {
|
|
468
|
+
return Math.min(array.length - 1, Math.max(0, pointIndex + delta * Math.round(array.length * PAGE_SIZE_PERCENTAGE)));
|
|
469
|
+
}
|
|
470
|
+
//# sourceMappingURL=chart-extra-navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-extra-navigation.js","sourceRoot":"","sources":["../../../../src/core/chart-api/chart-extra-navigation.ts"],"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 type Highcharts from \"highcharts\";\n\nimport {\n circleIndex,\n getIsRtl,\n handleKey as toolkitHandleKey,\n KeyCode,\n} from \"@cloudscape-design/component-toolkit/internal\";\n\nimport * as Styles from \"../../internal/chart-styles\";\nimport { SVGRendererPool } from \"../../internal/utils/renderer-utils\";\nimport { Rect } from \"../interfaces\";\nimport { getGroupRect, getPointRect, isPointVisible, isXThreshold } from \"../utils\";\nimport { ChartExtraContext } from \"./chart-extra-context\";\n\n// In charts with many data points one can navigate faster by using Page Down/Up keys that\n// navigate PAGE_SIZE_PERCENTAGE of the points forwards or backwards.\nconst PAGE_SIZE_PERCENTAGE = 0.05;\n\nexport interface ChartExtraNavigationHandlers {\n onFocusChart(): void;\n onFocusPoint(point: Highcharts.Point, group: readonly Highcharts.Point[]): void;\n onFocusGroup(group: readonly Highcharts.Point[]): void;\n onBlur(): void;\n onActivatePoint(point: Highcharts.Point, group: readonly Highcharts.Point[]): void;\n onActivateGroup(group: readonly Highcharts.Point[]): void;\n}\n\nexport type FocusedState = FocusedStateChart | FocusedStateGroup | FocusedStatePoint;\n\ninterface FocusedStateChart {\n type: \"chart\";\n}\ninterface FocusedStateGroup {\n type: \"group\";\n group: readonly Highcharts.Point[];\n}\ninterface FocusedStatePoint {\n type: \"point\";\n point: Highcharts.Point;\n group: readonly Highcharts.Point[];\n}\n\n// Navigation controller handles focus behavior and keyboard navigation for all charts.\n// When the chart is first focused, the focus lands on the chart plot. Once navigation is engaged,\n// the focus can land either on the group of points matched by X value, or on a specific point.\n// The focused X value and point are stored so that navigating back to the chart will focus the previously\n// focused point. If the stored point no longer belongs to the chart the focus falls back to the chart plot.\nexport class ChartExtraNavigation {\n private context: ChartExtraContext;\n private handlers: ChartExtraNavigationHandlers;\n private focusOutline: FocusOutline;\n // The application element is a dom element with role=\"application\", rendered right before the chart plot.\n // When the application element is in focus, the keyboard navigation is possible. Upon using navigation commands,\n // we bring the visible focus state to the chart elements, such as points and groups of points. The last visible\n // focus state is persisted.\n private applicationElement: null | HTMLElement = null;\n private focusedState: null | FocusedState = null;\n private ignoreFocus = false;\n\n constructor(context: ChartExtraContext, handlers: ChartExtraNavigationHandlers) {\n this.context = context;\n this.handlers = handlers;\n this.focusOutline = new FocusOutline(context);\n }\n\n public onChartDestroy() {\n this.focusOutline.destroy();\n }\n\n // This function is used as React ref on the application element, positioned right before the chart plot in the DOM.\n // Once the element reference is obtained, we assign the required event listeners directly to the element.\n // That is done for simplicity to avoid passing React event handlers down to the element.\n public setApplication = (element: null | HTMLElement) => {\n if (this.applicationElement) {\n this.applicationElement.removeEventListener(\"focus\", this.onFocus);\n this.applicationElement.removeEventListener(\"blur\", this.onBlur);\n this.applicationElement.removeEventListener(\"keydown\", this.onKeyDown);\n }\n\n if (this.context.settings.keyboardNavigationEnabled || !element) {\n this.applicationElement = element;\n }\n\n if (this.applicationElement) {\n this.applicationElement.addEventListener(\"focus\", this.onFocus);\n this.applicationElement.addEventListener(\"blur\", this.onBlur);\n this.applicationElement.addEventListener(\"keydown\", this.onKeyDown);\n }\n };\n\n // Casting focus to the application element brings the visible focus state to the chart or last focused\n // chart point or group of points. This is used to restore focus after the tooltip is dismissed.\n public focusApplication(point: null | Highcharts.Point, group: readonly Highcharts.Point[]) {\n if (this.context.settings.keyboardNavigationEnabled) {\n this.focusedState = point ? { type: \"point\", point, group } : { type: \"group\", group };\n this.applicationElement?.focus();\n }\n }\n\n public announceChart(ariaLabel: string) {\n this.announce({ role: \"application\", \"aria-label\": ariaLabel });\n }\n\n public announceElement(ariaLabel: string, pinned: boolean) {\n this.announce({ role: \"button\", \"aria-label\": ariaLabel, \"aria-haspopup\": true, \"aria-expanded\": pinned });\n }\n\n // Every time the chart focus is obtained or a navigation action is performed, this needs to be announced\n // to screen-readers. The announcement is made by updating the application element with the attributes of\n // the visually focused element (chart, point, or group), and re-focusing it.\n private announce(elementAttributes: React.ButtonHTMLAttributes<unknown>) {\n if (this.applicationElement) {\n // Remove prev attributes.\n for (const attributeName of this.applicationElement.getAttributeNames()) {\n if (attributeName === \"role\" || attributeName.slice(0, 4) === \"aria\") {\n this.applicationElement.removeAttribute(attributeName);\n }\n }\n // Copy new attributes.\n for (const [attributeName, attributeValue] of Object.entries(elementAttributes)) {\n this.applicationElement.setAttribute(attributeName, `${attributeValue}`);\n }\n // Temporarily disable focus/blur event handlers to not respond to the next programmatically\n // cast focus event, which has the only purpose of making the application element announced to\n // the assistive software.\n this.ignoreFocus = true;\n // Re-attach and re-focus application element to trigger a screen-reader announcement.\n const container = this.applicationElement.parentElement!;\n container.removeChild(this.applicationElement);\n container.appendChild(this.applicationElement);\n this.applicationElement.focus({ preventScroll: true });\n // Remove focus lock. The blur and focus events should have already occurred at this point.\n setTimeout(() => (this.ignoreFocus = false), 0);\n }\n }\n\n // Upon obtaining focus, we show the visible focus state and announce the previously focused element\n // (chart, point, or group). If the previously focused point or group is no longer available, the focus\n // is shown for their respective parent.\n private onFocus = () => {\n if (!this.ignoreFocus) {\n if (!this.focusedState || this.focusedState.type === \"chart\") {\n this.focusChart();\n } else if (this.focusedState.type === \"group\") {\n this.focusGroup(this.focusedState.group);\n } else {\n this.focusPoint(this.focusedState.point, this.focusedState.group);\n }\n }\n };\n\n private onBlur = () => {\n if (!this.ignoreFocus) {\n this.focusOutline.hide();\n this.handlers.onBlur();\n }\n };\n\n private onKeyDown = (event: KeyboardEvent) => {\n // The `handleKey` helper we use does not prevent the default keys behavior, so we do it here for\n // all used keyboard commands.\n if (\n [\n KeyCode.up,\n KeyCode.down,\n KeyCode.left,\n KeyCode.right,\n KeyCode.enter,\n KeyCode.escape,\n KeyCode.pageUp,\n KeyCode.pageDown,\n KeyCode.home,\n KeyCode.end,\n ].includes(event.keyCode)\n ) {\n event.preventDefault();\n }\n // We execute different actions depending on the current focus target (chart, group, or point).\n // It is expected, that the focused element is still available in the chart.\n if (this.focusedState && this.focusedState.type === \"group\") {\n this.onKeyDownGroup(event, this.focusedState.group);\n } else if (this.focusedState && this.focusedState.type === \"point\") {\n this.onKeyDownPoint(event, this.focusedState.point, this.focusedState.group);\n } else {\n this.onKeyDownChart(event);\n }\n };\n\n private onKeyDownChart = (event: KeyboardEvent) => {\n handleKey(event, {\n onActivate: () => this.moveToFirstGroup(),\n onInlineStart: () => this.moveToLastGroup(),\n onInlineEnd: () => this.moveToFirstGroup(),\n onBlockStart: () => this.moveToLastGroup(),\n onBlockEnd: () => this.moveToFirstGroup(),\n onHome: () => this.moveToFirstGroup(),\n onEnd: () => this.moveToLastGroup(),\n });\n };\n\n private onKeyDownGroup = (event: KeyboardEvent, group: readonly Highcharts.Point[]) => {\n const i = !!this.context.chart().inverted;\n handleKey(event, {\n onActivate: () => this.activateGroup(group),\n onEscape: () => this.moveToChart(),\n onInlineStart: () => (i ? this.moveToFirstInGroup(group) : this.moveToPrevGroup(group)),\n onInlineEnd: () => (i ? this.moveToLastInGroup(group) : this.moveToNextGroup(group)),\n onBlockStart: () => (i ? this.moveToPrevGroup(group) : this.moveToLastInGroup(group)),\n onBlockEnd: () => (i ? this.moveToNextGroup(group) : this.moveToFirstInGroup(group)),\n onPageDown: () => this.moveToNextPageGroup(group),\n onPageUp: () => this.moveToPrevPageGroup(group),\n onHome: () => this.moveToFirstGroup(),\n onEnd: () => this.moveToLastGroup(),\n });\n };\n\n private onKeyDownPoint = (event: KeyboardEvent, point: Highcharts.Point, group: readonly Highcharts.Point[]) => {\n const i = !!this.context.chart().inverted;\n handleKey(event, {\n onActivate: () => this.activatePoint(point, group),\n onEscape: () => this.moveToParentGroup(point),\n onInlineEnd: () => (i ? this.moveToPrevInGroup(point) : this.moveToNextInSeries(point)),\n onInlineStart: () => (i ? this.moveToNextInGroup(point) : this.moveToPrevInSeries(point)),\n onBlockEnd: () => (i ? this.moveToNextInSeries(point) : this.moveToNextInGroup(point)),\n onBlockStart: () => (i ? this.moveToPrevInSeries(point) : this.moveToPrevInGroup(point)),\n onPageDown: () => this.moveToNextPageInSeries(point),\n onPageUp: () => this.moveToPrevPageInSeries(point),\n onHome: () => this.moveToFirstInSeries(point),\n onEnd: () => this.moveToLastInSeries(point),\n });\n };\n\n private moveToFirstGroup() {\n this.focusGroup(this.findFirstGroup());\n }\n\n private moveToLastGroup() {\n this.focusGroup(this.findLastGroup());\n }\n\n private moveToNextGroup(group: readonly Highcharts.Point[]) {\n const nextGroup = group[0] ? this.findNextGroup(group[0]) : [];\n this.focusGroup(nextGroup);\n }\n\n private moveToPrevGroup(group: readonly Highcharts.Point[]) {\n const prevGroup = group[0] ? this.findPrevGroup(group[0]) : [];\n this.focusGroup(prevGroup);\n }\n\n private moveToParentGroup(point: Highcharts.Point) {\n const group = this.findMatchingGroup(point);\n if (group.length > 0 && group[0].series.type !== \"pie\") {\n this.focusGroup(group);\n } else {\n this.focusChart();\n }\n }\n\n private moveToChart() {\n this.focusChart();\n }\n\n private moveToFirstInGroup(group: readonly Highcharts.Point[]) {\n const points = group.filter((p) => !isXThreshold(p.series));\n this.focusPoint(points[0], group);\n }\n\n private moveToLastInGroup(group: readonly Highcharts.Point[]) {\n const points = group.filter((p) => !isXThreshold(p.series));\n this.focusPoint(points[points.length - 1], group);\n }\n\n private moveToPrevInGroup(point: Highcharts.Point) {\n const points = this.findMatchingGroup(point).filter((p) => !isXThreshold(p.series));\n const pointIndex = points.indexOf(point);\n this.focusPoint(points[circleIndex(pointIndex - 1, [0, points.length - 1])], points);\n }\n\n private moveToNextInGroup(point: Highcharts.Point) {\n const points = this.findMatchingGroup(point).filter((p) => !isXThreshold(p.series));\n const pointIndex = points.indexOf(point);\n this.focusPoint(points[circleIndex(pointIndex + 1, [0, points.length - 1])], points);\n }\n\n private moveToFirstInSeries(point: Highcharts.Point) {\n const firstPoint = this.findFirstPointInSeries(point);\n if (firstPoint) {\n this.focusPoint(firstPoint, this.findMatchingGroup(firstPoint));\n } else {\n this.focusChart();\n }\n }\n\n private moveToLastInSeries(point: Highcharts.Point) {\n const lastPoint = this.findLastPointInSeries(point);\n if (lastPoint) {\n this.focusPoint(lastPoint, this.findMatchingGroup(lastPoint));\n } else {\n this.focusChart();\n }\n }\n\n private moveToNextInSeries(point: Highcharts.Point) {\n const nextPoint = this.findNextPointInSeries(point);\n if (nextPoint) {\n this.focusPoint(nextPoint, this.findMatchingGroup(nextPoint));\n } else {\n this.focusChart();\n }\n }\n\n private moveToPrevInSeries(point: Highcharts.Point) {\n const prevPoint = this.findPrevPointInSeries(point);\n if (prevPoint) {\n this.focusPoint(prevPoint, this.findMatchingGroup(prevPoint));\n } else {\n this.focusChart();\n }\n }\n\n private moveToNextPageGroup(group: readonly Highcharts.Point[]) {\n const nextPageGroup = group[0] ? this.findNextPageGroup(group[0]) : [];\n this.focusGroup(nextPageGroup);\n }\n\n private moveToPrevPageGroup(group: readonly Highcharts.Point[]) {\n const prevPageGroup = group[0] ? this.findPrevPageGroup(group[0]) : [];\n this.focusGroup(prevPageGroup);\n }\n\n private moveToNextPageInSeries(point: Highcharts.Point) {\n const nextPagePoint = this.findNextPagePointInSeries(point);\n if (nextPagePoint) {\n this.focusPoint(nextPagePoint, this.findMatchingGroup(nextPagePoint));\n } else {\n this.focusChart();\n }\n }\n\n private moveToPrevPageInSeries(point: Highcharts.Point) {\n const prevPagePoint = this.findPrevPagePointInSeries(point);\n if (prevPagePoint) {\n this.focusPoint(prevPagePoint, this.findMatchingGroup(prevPagePoint));\n } else {\n this.focusChart();\n }\n }\n\n private activateGroup(group: readonly Highcharts.Point[]) {\n this.handlers.onActivateGroup(group);\n }\n\n private activatePoint(point: Highcharts.Point, group: readonly Highcharts.Point[]) {\n this.handlers.onActivatePoint(point, group);\n }\n\n private focusChart = () => {\n this.focusedState = { type: \"chart\" };\n this.focusOutline.chart();\n this.handlers.onFocusChart();\n };\n\n private focusGroup(group: readonly Highcharts.Point[]) {\n // When the chart is re-focused, the group that was focused before might no longer be valid if its\n // points are no longer visible or were destroyed by Highcharts. In that case we focus the chart as\n // a fallback.\n const visiblePoints = group.filter(isPointVisible);\n if (visiblePoints.length === 0) {\n this.focusChart();\n }\n // In pie charts we only focus points, so moving focus to points and groups is equivalent.\n else if (visiblePoints[0].series.type === \"pie\") {\n this.focusPoint(visiblePoints[0] ?? null, group);\n }\n // When focusing a group we draw the focus outline around the corresponding group rect, including\n // all points of that group.\n else {\n this.focusedState = { type: \"group\", group: visiblePoints };\n this.focusOutline.group(getGroupRect(visiblePoints));\n this.handlers.onFocusGroup(visiblePoints);\n }\n }\n\n private focusPoint(point: null | Highcharts.Point, group: readonly Highcharts.Point[]) {\n // When the chart is re-focused, the point that was focused before might no longer be valid it became\n // hidden or was destroyed by Highcharts. In that case we focus the point's parent group as a fallback.\n if (!point || !isPointVisible(point)) {\n this.focusGroup(group);\n }\n // When focusing a point we draw the focus outline around its corresponding rect, but with different offsets,\n // depending on the point's series type.\n else {\n this.focusedState = { type: \"point\", point, group };\n this.focusOutline.point(getPointRect(point), point);\n this.handlers.onFocusPoint(point, group);\n }\n }\n\n private get allX(): number[] {\n return this.context.derived.allX;\n }\n\n private getAllXInSeries = (series: Highcharts.Series): number[] => {\n return this.context.derived.getAllXInSeries(series);\n };\n\n private getPointsByX = (x: number): Highcharts.Point[] => {\n return this.context.derived.getPointsByX(x);\n };\n\n private findMatchingGroup = (point: Highcharts.Point): Highcharts.Point[] => {\n return this.getPointsByX(point.x);\n };\n\n private findFirstGroup = (): Highcharts.Point[] => {\n return this.getPointsByX(this.allX[0]);\n };\n\n private findLastGroup = (): Highcharts.Point[] => {\n return this.getPointsByX(this.allX[this.allX.length - 1]);\n };\n\n private findNextGroup = (point: Highcharts.Point): Highcharts.Point[] => {\n const nextIndex = getNextIndex(this.allX, this.allX.indexOf(point.x), 1);\n return this.getPointsByX(this.allX[nextIndex]);\n };\n\n private findPrevGroup = (point: Highcharts.Point): Highcharts.Point[] => {\n const nextIndex = getNextIndex(this.allX, this.allX.indexOf(point.x), -1);\n return this.getPointsByX(this.allX[nextIndex]);\n };\n\n private findNextPageGroup = (point: Highcharts.Point): Highcharts.Point[] => {\n const nextIndex = getNextPageIndex(this.allX, this.allX.indexOf(point.x), 1);\n return this.getPointsByX(this.allX[nextIndex]);\n };\n\n private findPrevPageGroup = (point: Highcharts.Point): Highcharts.Point[] => {\n const nextIndex = getNextPageIndex(this.allX, this.allX.indexOf(point.x), -1);\n return this.getPointsByX(this.allX[nextIndex]);\n };\n\n private findFirstPointInSeries = (point: Highcharts.Point): null | Highcharts.Point => {\n const seriesX = this.getAllXInSeries(point.series);\n return point.series.data.find((d) => d.x === seriesX[0]) ?? null;\n };\n\n private findLastPointInSeries = (point: Highcharts.Point): null | Highcharts.Point => {\n const seriesX = this.getAllXInSeries(point.series);\n return point.series.data.find((d) => d.x === seriesX[seriesX.length - 1]) ?? null;\n };\n\n private findNextPointInSeries = (point: Highcharts.Point): null | Highcharts.Point => {\n const seriesX = this.getAllXInSeries(point.series);\n const delta = !shouldInvertPointsDirection(point) ? 1 : -1;\n const nextIndex = getNextIndex(seriesX, seriesX.indexOf(point.x), delta);\n return point.series.data.find((d) => d.x === seriesX[nextIndex]) ?? null;\n };\n\n private findPrevPointInSeries = (point: Highcharts.Point): null | Highcharts.Point => {\n const seriesX = this.getAllXInSeries(point.series);\n const delta = !shouldInvertPointsDirection(point) ? -1 : 1;\n const nextIndex = getNextIndex(seriesX, seriesX.indexOf(point.x), delta);\n return point.series.data.find((d) => d.x === seriesX[nextIndex]) ?? null;\n };\n\n private findNextPagePointInSeries = (point: Highcharts.Point): null | Highcharts.Point => {\n const seriesX = this.getAllXInSeries(point.series);\n const delta = !shouldInvertPointsDirection(point) ? 1 : -1;\n const nextIndex = getNextPageIndex(seriesX, seriesX.indexOf(point.x), delta);\n return point.series.data.find((d) => d.x === seriesX[nextIndex]) ?? null;\n };\n\n private findPrevPagePointInSeries = (point: Highcharts.Point): null | Highcharts.Point => {\n const seriesX = this.getAllXInSeries(point.series);\n const delta = !shouldInvertPointsDirection(point) ? -1 : 1;\n const nextIndex = getNextPageIndex(seriesX, seriesX.indexOf(point.x), delta);\n return point.series.data.find((d) => d.x === seriesX[nextIndex]) ?? null;\n };\n}\n\nfunction handleKey(\n event: KeyboardEvent,\n handlers: {\n onActivate?: () => void;\n onBlockEnd?: () => void;\n onBlockStart?: () => void;\n onDefault?: () => void;\n onEnd?: () => void;\n onEscape?: () => void;\n onHome?: () => void;\n onInlineEnd?: () => void;\n onInlineStart?: () => void;\n onPageDown?: () => void;\n onPageUp?: () => void;\n },\n) {\n if (!event.currentTarget) {\n return;\n }\n if (!(event.currentTarget instanceof HTMLElement) && !(event.currentTarget instanceof SVGElement)) {\n return;\n }\n toolkitHandleKey({ keyCode: event.keyCode, currentTarget: event.currentTarget }, handlers);\n}\n\n// A helper class to draw the focus outline around given chart elements.\nclass FocusOutline {\n private context: ChartExtraContext;\n private elementsPool = new SVGRendererPool();\n\n constructor(context: ChartExtraContext) {\n this.context = context;\n }\n\n public chart = () => {\n const [x, y, width, height] = [\n this.context.chart().plotLeft,\n this.context.chart().plotTop,\n this.context.chart().plotWidth,\n this.context.chart().plotHeight,\n ];\n this.rect({ x, y, width, height }, Styles.focusOutlineOffsets.chart);\n };\n\n public group = (rect: Rect) => {\n this.rect(rect, Styles.focusOutlineOffsets.group);\n };\n\n public point = (rect: Rect, point: Highcharts.Point) => {\n const offsetByType = Styles.focusOutlineOffsets.pointByType[point.series.type];\n const offset = offsetByType ?? Styles.focusOutlineOffsets.point;\n this.rect(rect, offset);\n };\n\n public hide() {\n this.elementsPool.hideAll();\n }\n\n public destroy() {\n this.elementsPool.destroyAll();\n }\n\n private rect = ({ x, y, width, height }: Rect, offset: number) => {\n this.elementsPool.hideAll();\n this.elementsPool.rect(this.context.chart().renderer, {\n x: x - offset,\n y: y - offset,\n width: width + offset * 2,\n height: height + offset * 2,\n ...Styles.navigationFocusOutline,\n });\n };\n}\n\n// We do not invert the direction of pie segments when RTL, but swap the left/right keys.\n// To offset for that, the prev/next points direction is swapped, too.\nfunction shouldInvertPointsDirection(point: Highcharts.Point) {\n const isRTL = getIsRtl(point.series.chart.container.parentElement);\n return point.series.type === \"pie\" && isRTL;\n}\n\nfunction getNextIndex(array: unknown[], pointIndex: number, delta: -1 | 1): number {\n return circleIndex(pointIndex + delta, [0, array.length - 1]);\n}\n\nfunction getNextPageIndex(array: unknown[], pointIndex: number, delta: -1 | 1): number {\n return Math.min(array.length - 1, Math.max(0, pointIndex + delta * Math.round(array.length * PAGE_SIZE_PERCENTAGE)));\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import AsyncStore from "../../internal/utils/async-store";
|
|
3
|
+
import { ChartExtraContext } from "./chart-extra-context";
|
|
4
|
+
export interface ReactiveNodataState {
|
|
5
|
+
visible: boolean;
|
|
6
|
+
style: React.CSSProperties;
|
|
7
|
+
noMatch: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare class ChartExtraNodata extends AsyncStore<ReactiveNodataState> {
|
|
10
|
+
private context;
|
|
11
|
+
constructor(context: ChartExtraContext);
|
|
12
|
+
onChartRender: () => void;
|
|
13
|
+
private getContainerStyle;
|
|
14
|
+
private get chart();
|
|
15
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import AsyncStore from "../../internal/utils/async-store";
|
|
4
|
+
import { getChartSeries } from "../../internal/utils/chart-series";
|
|
5
|
+
// Chart helper that implements custom nodata behaviors.
|
|
6
|
+
export class ChartExtraNodata extends AsyncStore {
|
|
7
|
+
constructor(context) {
|
|
8
|
+
super({ visible: false, style: {}, noMatch: false });
|
|
9
|
+
this.onChartRender = () => {
|
|
10
|
+
if (!this.context.settings.noDataEnabled) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const allSeriesWithData = findAllSeriesWithData(this.chart);
|
|
14
|
+
const visibleSeries = findAllVisibleSeries(this.chart);
|
|
15
|
+
// The no-data is not shown when there is at least one series or point (for pie series) non-empty and visible.
|
|
16
|
+
if (visibleSeries.length > 0) {
|
|
17
|
+
this.set(() => ({ visible: false, style: {}, noMatch: false }));
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
this.set(() => ({ visible: true, style: this.getContainerStyle(), noMatch: allSeriesWithData.length > 0 }));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
this.context = context;
|
|
24
|
+
}
|
|
25
|
+
getContainerStyle() {
|
|
26
|
+
const blockOffset = this.chart.chartHeight - this.chart.plotHeight;
|
|
27
|
+
return { insetBlockEnd: `${blockOffset}px` };
|
|
28
|
+
}
|
|
29
|
+
get chart() {
|
|
30
|
+
return this.context.chart();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function findAllSeriesWithData(chart) {
|
|
34
|
+
// When a series becomes hidden, Highcharts no longer computes the data array, so the series.data is empty.
|
|
35
|
+
// That is why we assert the data from series.options instead.
|
|
36
|
+
return getChartSeries(chart.series).filter((s) => {
|
|
37
|
+
const data = "data" in s.options && s.options.data && Array.isArray(s.options.data) ? s.options.data : [];
|
|
38
|
+
return data.some((i) => i !== null && (typeof i === "object" && "y" in i ? i.y !== null : true));
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function findAllVisibleSeries(chart) {
|
|
42
|
+
const allSeriesWithData = findAllSeriesWithData(chart);
|
|
43
|
+
return allSeriesWithData.filter((s) => s.visible && (s.type !== "pie" || s.data.some((d) => d.y !== null && d.visible)));
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=chart-extra-nodata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-extra-nodata.js","sourceRoot":"","sources":["../../../../src/core/chart-api/chart-extra-nodata.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 type Highcharts from \"highcharts\";\n\nimport AsyncStore from \"../../internal/utils/async-store\";\nimport { getChartSeries } from \"../../internal/utils/chart-series\";\nimport { ChartExtraContext } from \"./chart-extra-context\";\n\n// The reactive state is used to propagate updates to the corresponding no-data React component.\n// It can be used by other components to assert if the chart is in no-data state (by checking if container is present).\nexport interface ReactiveNodataState {\n visible: boolean;\n style: React.CSSProperties;\n noMatch: boolean;\n}\n\n// Chart helper that implements custom nodata behaviors.\nexport class ChartExtraNodata extends AsyncStore<ReactiveNodataState> {\n private context: ChartExtraContext;\n\n constructor(context: ChartExtraContext) {\n super({ visible: false, style: {}, noMatch: false });\n this.context = context;\n }\n\n public onChartRender = () => {\n if (!this.context.settings.noDataEnabled) {\n return;\n }\n const allSeriesWithData = findAllSeriesWithData(this.chart);\n const visibleSeries = findAllVisibleSeries(this.chart);\n // The no-data is not shown when there is at least one series or point (for pie series) non-empty and visible.\n if (visibleSeries.length > 0) {\n this.set(() => ({ visible: false, style: {}, noMatch: false }));\n } else {\n this.set(() => ({ visible: true, style: this.getContainerStyle(), noMatch: allSeriesWithData.length > 0 }));\n }\n };\n\n private getContainerStyle(): React.CSSProperties {\n const blockOffset = this.chart.chartHeight - this.chart.plotHeight;\n return { insetBlockEnd: `${blockOffset}px` };\n }\n\n private get chart() {\n return this.context.chart();\n }\n}\n\nfunction findAllSeriesWithData(chart: Highcharts.Chart) {\n // When a series becomes hidden, Highcharts no longer computes the data array, so the series.data is empty.\n // That is why we assert the data from series.options instead.\n return getChartSeries(chart.series).filter((s) => {\n const data = \"data\" in s.options && s.options.data && Array.isArray(s.options.data) ? s.options.data : [];\n return data.some((i) => i !== null && (typeof i === \"object\" && \"y\" in i ? i.y !== null : true));\n });\n}\n\nfunction findAllVisibleSeries(chart: Highcharts.Chart) {\n const allSeriesWithData = findAllSeriesWithData(chart);\n return allSeriesWithData.filter(\n (s) => s.visible && (s.type !== \"pie\" || s.data.some((d) => d.y !== null && d.visible)),\n );\n}\n"]}
|