@cloudscape-design/chart-components 1.0.67 → 1.0.69
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/cartesian-chart/chart-series-cartesian.js +16 -7
- package/cartesian-chart/chart-series-cartesian.js.map +1 -1
- package/cartesian-chart/index.js +50 -21
- package/cartesian-chart/index.js.map +1 -1
- package/cartesian-chart/utils.d.ts +4 -0
- package/cartesian-chart/utils.js +20 -0
- package/cartesian-chart/utils.js.map +1 -0
- package/core/chart-api/chart-extra-context.d.ts +1 -1
- package/core/chart-api/chart-extra-context.js +30 -4
- package/core/chart-api/chart-extra-context.js.map +1 -1
- package/core/chart-api/chart-extra-highlight.js +20 -17
- package/core/chart-api/chart-extra-highlight.js.map +1 -1
- package/core/chart-api/chart-extra-legend.js +4 -3
- package/core/chart-api/chart-extra-legend.js.map +1 -1
- package/core/chart-api/chart-extra-navigation.d.ts +1 -1
- package/core/chart-api/chart-extra-navigation.js +25 -19
- package/core/chart-api/chart-extra-navigation.js.map +1 -1
- package/core/chart-api/chart-extra-tooltip.js +5 -2
- package/core/chart-api/chart-extra-tooltip.js.map +1 -1
- package/core/components/core-tooltip.js +4 -1
- package/core/components/core-tooltip.js.map +1 -1
- package/core/interfaces.d.ts +16 -6
- package/core/interfaces.js.map +1 -1
- package/internal/environment.js +1 -1
- package/internal/environment.json +1 -1
- package/internal/manifest.json +1 -1
- package/internal/utils/chart-series.d.ts +9 -1
- package/internal/utils/chart-series.js +16 -0
- package/internal/utils/chart-series.js.map +1 -1
- package/internal/utils/series-data.js +2 -1
- package/internal/utils/series-data.js.map +1 -1
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { colorChartsErrorBarMarker } from "@cloudscape-design/design-tokens";
|
|
4
4
|
import { createThresholdMetadata, getOptionsId } from "../core/utils";
|
|
5
5
|
import * as Styles from "../internal/chart-styles";
|
|
6
|
+
import { getMasterSeries, isThreshold } from "./utils";
|
|
6
7
|
// The utility transforms cartesian chart component's series to Highcharts series. This includes transforming
|
|
7
8
|
// custom x- and y-threshold series types, that are represented as a combination of invisible line series, and plot lines.
|
|
8
9
|
// The plot lines, unlike series, are rendered across the entire chart plot width or height.
|
|
@@ -23,6 +24,16 @@ export const transformCartesianSeries = (originalSeries, visibleSeries) => {
|
|
|
23
24
|
yPlotLines.push({ id: seriesId, value: s.value, ...style, dashStyle: (_c = s.dashStyle) !== null && _c !== void 0 ? _c : style.dashStyle });
|
|
24
25
|
}
|
|
25
26
|
}
|
|
27
|
+
// Assign linked series color to its respective master series color or color index.
|
|
28
|
+
const autoColorSeries = originalSeries.filter((s) => !isThreshold(s) && !s.linkedTo && !s.color);
|
|
29
|
+
const getColorProps = (s) => {
|
|
30
|
+
var _a;
|
|
31
|
+
const masterSeries = getMasterSeries(originalSeries, s);
|
|
32
|
+
if (!masterSeries) {
|
|
33
|
+
return {};
|
|
34
|
+
}
|
|
35
|
+
return { color: (_a = s.color) !== null && _a !== void 0 ? _a : masterSeries.color, colorIndex: autoColorSeries.indexOf(masterSeries) };
|
|
36
|
+
};
|
|
26
37
|
// The threshold series require data points to enable keyboard navigation and hover effects.
|
|
27
38
|
const thresholdX = getThresholdX(originalSeries, visibleSeries);
|
|
28
39
|
const thresholdY = getThresholdY(originalSeries, visibleSeries);
|
|
@@ -31,8 +42,9 @@ export const transformCartesianSeries = (originalSeries, visibleSeries) => {
|
|
|
31
42
|
// Highcharts does not properly update data on re-render. When the fake empty series is replaced with the real series,
|
|
32
43
|
// the properties are merged together, so the showInLegend=false is not overridden.
|
|
33
44
|
// That is why we explicitly override this property for all real series.
|
|
34
|
-
const
|
|
35
|
-
|
|
45
|
+
const isLinked = !isThreshold(s) && s.linkedTo !== undefined;
|
|
46
|
+
const shared = { showInLegend: !isLinked };
|
|
47
|
+
if (isThreshold(s)) {
|
|
36
48
|
const data = s.type === "x-threshold"
|
|
37
49
|
? thresholdY.map((y) => ({ x: s.value, y }))
|
|
38
50
|
: thresholdX.map((x) => ({ x, y: s.value }));
|
|
@@ -52,7 +64,7 @@ export const transformCartesianSeries = (originalSeries, visibleSeries) => {
|
|
|
52
64
|
const colors = { stemColor: color, whiskerColor: color };
|
|
53
65
|
return { ...s, data: s.data, ...colors };
|
|
54
66
|
}
|
|
55
|
-
return { ...s, data: s.data, ...shared };
|
|
67
|
+
return { ...s, data: s.data, ...shared, ...getColorProps(s) };
|
|
56
68
|
}
|
|
57
69
|
const series = originalSeries.map(transformSeriesToHighcharts);
|
|
58
70
|
// We inject a fake empty series so that the empty state still shows axes, if defined.
|
|
@@ -91,10 +103,7 @@ function getThresholdX(series, visibleSeries) {
|
|
|
91
103
|
function getVisibleDataSeries(series, visibleSeries) {
|
|
92
104
|
const dataSeries = [];
|
|
93
105
|
for (const s of series) {
|
|
94
|
-
if (s.type !== "
|
|
95
|
-
s.type !== "y-threshold" &&
|
|
96
|
-
s.type !== "errorbar" &&
|
|
97
|
-
visibleSeries.includes(getOptionsId(s))) {
|
|
106
|
+
if (!isThreshold(s) && s.type !== "errorbar" && visibleSeries.includes(getOptionsId(s))) {
|
|
98
107
|
dataSeries.push(s);
|
|
99
108
|
}
|
|
100
109
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-series-cartesian.js","sourceRoot":"","sources":["../../../src/cartesian-chart/chart-series-cartesian.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 { colorChartsErrorBarMarker } from \"@cloudscape-design/design-tokens\";\n\nimport { PointDataItemType, RangeDataItemOptions } from \"../core/interfaces\";\nimport { createThresholdMetadata, getOptionsId } from \"../core/utils\";\nimport * as Styles from \"../internal/chart-styles\";\nimport { Writeable } from \"../internal/utils/utils\";\nimport { CartesianChartProps } from \"./interfaces\";\n\n// The utility transforms cartesian chart component's series to Highcharts series. This includes transforming\n// custom x- and y-threshold series types, that are represented as a combination of invisible line series, and plot lines.\n// The plot lines, unlike series, are rendered across the entire chart plot width or height.\nexport const transformCartesianSeries = (\n originalSeries: readonly CartesianChartProps.SeriesOptions[],\n visibleSeries: readonly string[],\n) => {\n // The injected plot lines have IDs matching the IDs of the threshold series. This is used by the core chart\n // to manage visibility and highlight state for them, when the corresponding threshold series are toggled\n // or highlighted in the legend or filter.\n const xPlotLines: Highcharts.XAxisPlotLinesOptions[] = [];\n const yPlotLines: Highcharts.YAxisPlotLinesOptions[] = [];\n for (const s of originalSeries) {\n const seriesId = getOptionsId(s);\n const style = { ...Styles.thresholdPlotLine, color: s.color ?? Styles.thresholdPlotLine.color };\n if (s.type === \"x-threshold\" && visibleSeries.includes(seriesId)) {\n xPlotLines.push({ id: seriesId, value: s.value, ...style, dashStyle: s.dashStyle ?? style.dashStyle });\n }\n if (s.type === \"y-threshold\" && visibleSeries.includes(seriesId)) {\n yPlotLines.push({ id: seriesId, value: s.value, ...style, dashStyle: s.dashStyle ?? style.dashStyle });\n }\n }\n // The threshold series require data points to enable keyboard navigation and hover effects.\n const thresholdX = getThresholdX(originalSeries, visibleSeries);\n const thresholdY = getThresholdY(originalSeries, visibleSeries);\n function transformSeriesToHighcharts(s: CartesianChartProps.SeriesOptions): Highcharts.SeriesOptionsType {\n // Highcharts does not properly update data on re-render. When the fake empty series is replaced with the real series,\n // the properties are merged together, so the showInLegend=false is not overridden.\n // That is why we explicitly override this property for all real series.\n const shared = { showInLegend: true };\n if (s.type === \"x-threshold\" || s.type === \"y-threshold\") {\n const data =\n s.type === \"x-threshold\"\n ? thresholdY.map((y) => ({ x: s.value, y }))\n : thresholdX.map((x) => ({ x, y: s.value }));\n const { custom } = createThresholdMetadata(s.type, s.value);\n const enableMouseTracking = s.type === \"y-threshold\";\n const style = {\n ...Styles.thresholdSeries,\n color: s.color ?? Styles.thresholdSeries.color,\n dashStyle: s.dashStyle ?? Styles.thresholdSeries.dashStyle,\n };\n return { type: \"line\", id: s.id, name: s.name, data, custom, enableMouseTracking, ...style, ...shared };\n }\n if (s.type === \"errorbar\") {\n const color = s.color ?? colorChartsErrorBarMarker;\n // In Highcharts, the error-bar series graphic color is represented as stem-, and whisker colors.\n // We simplify that, and only expose a single color prop that sets both of those.\n const colors = { stemColor: color, whiskerColor: color };\n return { ...s, data: s.data as Writeable<RangeDataItemOptions[]>, ...colors };\n }\n return { ...s, data: s.data as Writeable<PointDataItemType[]>, ...shared };\n }\n const series = originalSeries.map(transformSeriesToHighcharts);\n // We inject a fake empty series so that the empty state still shows axes, if defined.\n if (series.length === 0) {\n series.push({ type: \"line\", data: [], showInLegend: false });\n }\n return { series, xPlotLines, yPlotLines };\n};\n\n// For x-threshold the point-based navigation is disabled as irrelevant. However, we still need at least\n// one data point for core chart to work correctly, so we find the first visible y value from other series.\nfunction getThresholdY(series: readonly CartesianChartProps.SeriesOptions[], visibleSeries: readonly string[]) {\n for (const s of getVisibleDataSeries(series, visibleSeries)) {\n for (const d of s.data) {\n const y = d === null ? null : typeof d === \"number\" ? d : d.y;\n if (y !== null) {\n return [y];\n }\n }\n }\n return [];\n}\n\n// For y-threshold we find all defined x values from other series and use it those to create an array of\n// data points. As result, the y-threshold series becomes properly navigable.\nfunction getThresholdX(series: readonly CartesianChartProps.SeriesOptions[], visibleSeries: readonly string[]) {\n const allX = new Set<number>();\n for (const s of getVisibleDataSeries(series, visibleSeries)) {\n for (let i = 0; i < s.data.length; i++) {\n const d = s.data[i];\n const x = (typeof d === \"object\" ? d?.x : i) ?? i;\n allX.add(x);\n }\n }\n return [...allX].sort((a, b) => a - b);\n}\n\nfunction getVisibleDataSeries(series: readonly CartesianChartProps.SeriesOptions[], visibleSeries: readonly string[]) {\n const dataSeries: Exclude<\n CartesianChartProps.SeriesOptions,\n | CartesianChartProps.XThresholdSeriesOptions\n | CartesianChartProps.YThresholdSeriesOptions\n | CartesianChartProps.ErrorBarSeriesOptions\n >[] = [];\n for (const s of series) {\n if (\n s.type !== \"x-threshold\" &&\n s.type !== \"y-threshold\" &&\n s.type !== \"errorbar\" &&\n visibleSeries.includes(getOptionsId(s))\n ) {\n dataSeries.push(s);\n }\n }\n return dataSeries;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chart-series-cartesian.js","sourceRoot":"","sources":["../../../src/cartesian-chart/chart-series-cartesian.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 { colorChartsErrorBarMarker } from \"@cloudscape-design/design-tokens\";\n\nimport { PointDataItemType, RangeDataItemOptions } from \"../core/interfaces\";\nimport { createThresholdMetadata, getOptionsId } from \"../core/utils\";\nimport * as Styles from \"../internal/chart-styles\";\nimport { Writeable } from \"../internal/utils/utils\";\nimport { CartesianChartProps } from \"./interfaces\";\nimport { getMasterSeries, isThreshold } from \"./utils\";\n\n// The utility transforms cartesian chart component's series to Highcharts series. This includes transforming\n// custom x- and y-threshold series types, that are represented as a combination of invisible line series, and plot lines.\n// The plot lines, unlike series, are rendered across the entire chart plot width or height.\nexport const transformCartesianSeries = (\n originalSeries: readonly CartesianChartProps.SeriesOptions[],\n visibleSeries: readonly string[],\n) => {\n // The injected plot lines have IDs matching the IDs of the threshold series. This is used by the core chart\n // to manage visibility and highlight state for them, when the corresponding threshold series are toggled\n // or highlighted in the legend or filter.\n const xPlotLines: Highcharts.XAxisPlotLinesOptions[] = [];\n const yPlotLines: Highcharts.YAxisPlotLinesOptions[] = [];\n for (const s of originalSeries) {\n const seriesId = getOptionsId(s);\n const style = { ...Styles.thresholdPlotLine, color: s.color ?? Styles.thresholdPlotLine.color };\n if (s.type === \"x-threshold\" && visibleSeries.includes(seriesId)) {\n xPlotLines.push({ id: seriesId, value: s.value, ...style, dashStyle: s.dashStyle ?? style.dashStyle });\n }\n if (s.type === \"y-threshold\" && visibleSeries.includes(seriesId)) {\n yPlotLines.push({ id: seriesId, value: s.value, ...style, dashStyle: s.dashStyle ?? style.dashStyle });\n }\n }\n\n // Assign linked series color to its respective master series color or color index.\n const autoColorSeries = originalSeries.filter((s) => !isThreshold(s) && !s.linkedTo && !s.color);\n const getColorProps = (s: CartesianChartProps.SeriesOptions) => {\n const masterSeries = getMasterSeries(originalSeries, s);\n if (!masterSeries) {\n return {};\n }\n return { color: s.color ?? masterSeries.color, colorIndex: autoColorSeries.indexOf(masterSeries) };\n };\n\n // The threshold series require data points to enable keyboard navigation and hover effects.\n const thresholdX = getThresholdX(originalSeries, visibleSeries);\n const thresholdY = getThresholdY(originalSeries, visibleSeries);\n function transformSeriesToHighcharts(s: CartesianChartProps.SeriesOptions): Highcharts.SeriesOptionsType {\n // Highcharts does not properly update data on re-render. When the fake empty series is replaced with the real series,\n // the properties are merged together, so the showInLegend=false is not overridden.\n // That is why we explicitly override this property for all real series.\n const isLinked = !isThreshold(s) && s.linkedTo !== undefined;\n const shared = { showInLegend: !isLinked };\n if (isThreshold(s)) {\n const data =\n s.type === \"x-threshold\"\n ? thresholdY.map((y) => ({ x: s.value, y }))\n : thresholdX.map((x) => ({ x, y: s.value }));\n const { custom } = createThresholdMetadata(s.type, s.value);\n const enableMouseTracking = s.type === \"y-threshold\";\n const style = {\n ...Styles.thresholdSeries,\n color: s.color ?? Styles.thresholdSeries.color,\n dashStyle: s.dashStyle ?? Styles.thresholdSeries.dashStyle,\n };\n return { type: \"line\", id: s.id, name: s.name, data, custom, enableMouseTracking, ...style, ...shared };\n }\n if (s.type === \"errorbar\") {\n const color = s.color ?? colorChartsErrorBarMarker;\n // In Highcharts, the error-bar series graphic color is represented as stem-, and whisker colors.\n // We simplify that, and only expose a single color prop that sets both of those.\n const colors = { stemColor: color, whiskerColor: color };\n return { ...s, data: s.data as Writeable<RangeDataItemOptions[]>, ...colors };\n }\n return { ...s, data: s.data as Writeable<PointDataItemType[]>, ...shared, ...getColorProps(s) };\n }\n const series = originalSeries.map(transformSeriesToHighcharts);\n // We inject a fake empty series so that the empty state still shows axes, if defined.\n if (series.length === 0) {\n series.push({ type: \"line\", data: [], showInLegend: false });\n }\n return { series, xPlotLines, yPlotLines };\n};\n\n// For x-threshold the point-based navigation is disabled as irrelevant. However, we still need at least\n// one data point for core chart to work correctly, so we find the first visible y value from other series.\nfunction getThresholdY(series: readonly CartesianChartProps.SeriesOptions[], visibleSeries: readonly string[]) {\n for (const s of getVisibleDataSeries(series, visibleSeries)) {\n for (const d of s.data) {\n const y = d === null ? null : typeof d === \"number\" ? d : d.y;\n if (y !== null) {\n return [y];\n }\n }\n }\n return [];\n}\n\n// For y-threshold we find all defined x values from other series and use it those to create an array of\n// data points. As result, the y-threshold series becomes properly navigable.\nfunction getThresholdX(series: readonly CartesianChartProps.SeriesOptions[], visibleSeries: readonly string[]) {\n const allX = new Set<number>();\n for (const s of getVisibleDataSeries(series, visibleSeries)) {\n for (let i = 0; i < s.data.length; i++) {\n const d = s.data[i];\n const x = (typeof d === \"object\" ? d?.x : i) ?? i;\n allX.add(x);\n }\n }\n return [...allX].sort((a, b) => a - b);\n}\n\nfunction getVisibleDataSeries(series: readonly CartesianChartProps.SeriesOptions[], visibleSeries: readonly string[]) {\n const dataSeries: Exclude<\n CartesianChartProps.SeriesOptions,\n | CartesianChartProps.XThresholdSeriesOptions\n | CartesianChartProps.YThresholdSeriesOptions\n | CartesianChartProps.ErrorBarSeriesOptions\n >[] = [];\n for (const s of series) {\n if (!isThreshold(s) && s.type !== \"errorbar\" && visibleSeries.includes(getOptionsId(s))) {\n dataSeries.push(s);\n }\n }\n return dataSeries;\n}\n"]}
|
package/cartesian-chart/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { getDataAttributes } from "../internal/base-component/get-data-attribute
|
|
|
7
7
|
import useBaseComponent from "../internal/base-component/use-base-component";
|
|
8
8
|
import { applyDisplayName } from "../internal/utils/apply-display-name";
|
|
9
9
|
import { InternalCartesianChart } from "./chart-cartesian-internal";
|
|
10
|
+
import { getMasterSeries, isErrorBar, isThreshold } from "./utils";
|
|
10
11
|
const CartesianChart = forwardRef(({ fitHeight = false, inverted = false, stacking = undefined, emphasizeBaseline = true, verticalAxisTitlePlacement = "top", ...props }, ref) => {
|
|
11
12
|
// We transform options before propagating them to the internal chart to ensure only those
|
|
12
13
|
// defined in the component's contract can be propagated down to the underlying Highcharts.
|
|
@@ -32,11 +33,11 @@ function transformSeries(untransformedSeries, stacking) {
|
|
|
32
33
|
case "areaspline":
|
|
33
34
|
case "line":
|
|
34
35
|
case "spline":
|
|
35
|
-
return transformLineLikeSeries(s);
|
|
36
|
+
return transformLineLikeSeries(s, untransformedSeries);
|
|
36
37
|
case "column":
|
|
37
|
-
return transformColumnSeries(s);
|
|
38
|
+
return transformColumnSeries(s, untransformedSeries);
|
|
38
39
|
case "scatter":
|
|
39
|
-
return transformScatterSeries(s);
|
|
40
|
+
return transformScatterSeries(s, untransformedSeries);
|
|
40
41
|
case "errorbar":
|
|
41
42
|
return transformErrorBarSeries(s, untransformedSeries, stacking);
|
|
42
43
|
case "x-threshold":
|
|
@@ -54,22 +55,59 @@ function transformSeries(untransformedSeries, stacking) {
|
|
|
54
55
|
}
|
|
55
56
|
return transformedSeries;
|
|
56
57
|
}
|
|
57
|
-
function
|
|
58
|
+
function validateLinkedTo(series, allSeries) {
|
|
59
|
+
if (isThreshold(series) || series.linkedTo === undefined) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
// The incorrectly linked series will not appear in our custom legend and tooltip, so we remove them
|
|
63
|
+
// from the series array. We also do not support linking series to errorbar or threshold series.
|
|
64
|
+
const masterSeries = getMasterSeries(allSeries, series);
|
|
65
|
+
if (!masterSeries || isErrorBar(masterSeries) || isThreshold(masterSeries)) {
|
|
66
|
+
warnOnce("CartesianChart", "The `linkedTo` property points to a missing or unsupported series.");
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
function transformLineLikeSeries(s, allSeries) {
|
|
72
|
+
if (!validateLinkedTo(s, allSeries)) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
58
75
|
const data = transformPointData(s.data);
|
|
59
|
-
return {
|
|
76
|
+
return {
|
|
77
|
+
type: s.type,
|
|
78
|
+
id: s.id,
|
|
79
|
+
name: s.name,
|
|
80
|
+
color: s.color,
|
|
81
|
+
dashStyle: s.dashStyle,
|
|
82
|
+
linkedTo: s.linkedTo,
|
|
83
|
+
data,
|
|
84
|
+
};
|
|
60
85
|
}
|
|
61
|
-
function transformColumnSeries(s) {
|
|
86
|
+
function transformColumnSeries(s, allSeries) {
|
|
87
|
+
if (!validateLinkedTo(s, allSeries)) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
62
90
|
const data = transformPointData(s.data);
|
|
63
|
-
return { type: s.type, id: s.id, name: s.name, color: s.color, data };
|
|
91
|
+
return { type: s.type, id: s.id, name: s.name, color: s.color, linkedTo: s.linkedTo, data };
|
|
64
92
|
}
|
|
65
|
-
function transformScatterSeries(s) {
|
|
93
|
+
function transformScatterSeries(s, allSeries) {
|
|
66
94
|
var _a;
|
|
95
|
+
if (!validateLinkedTo(s, allSeries)) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
67
98
|
const data = transformPointData(s.data);
|
|
68
99
|
const marker = (_a = s.marker) !== null && _a !== void 0 ? _a : {};
|
|
69
|
-
return { type: s.type, id: s.id, name: s.name, color: s.color, data, marker };
|
|
100
|
+
return { type: s.type, id: s.id, name: s.name, color: s.color, linkedTo: s.linkedTo, data, marker };
|
|
70
101
|
}
|
|
71
102
|
function transformThresholdSeries(s) {
|
|
72
|
-
return {
|
|
103
|
+
return {
|
|
104
|
+
type: s.type,
|
|
105
|
+
id: s.id,
|
|
106
|
+
name: s.name,
|
|
107
|
+
color: s.color,
|
|
108
|
+
value: s.value,
|
|
109
|
+
dashStyle: s.dashStyle,
|
|
110
|
+
};
|
|
73
111
|
}
|
|
74
112
|
function transformErrorBarSeries(series, allSeries, stacking) {
|
|
75
113
|
// Highcharts only supports error bars for non-stacked series.
|
|
@@ -78,17 +116,8 @@ function transformErrorBarSeries(series, allSeries, stacking) {
|
|
|
78
116
|
warnOnce("CartesianChart", "Error bars are not supported for stacked series.");
|
|
79
117
|
return null;
|
|
80
118
|
}
|
|
81
|
-
// We only support error bars that are linked to some other series.
|
|
82
|
-
|
|
83
|
-
// See: https://api.highcharts.com/highcharts/series.errorbar.linkedTo.
|
|
84
|
-
const linkedSeries = series.linkedTo === ":previous"
|
|
85
|
-
? allSeries[allSeries.indexOf(series) - 1]
|
|
86
|
-
: allSeries.find(({ id }) => id === series.linkedTo);
|
|
87
|
-
// The non-linked error bars are not supported: those will not appear in our custom legend and tooltip,
|
|
88
|
-
// so we remove them from the series array. We also do not support linking them to other error bars,
|
|
89
|
-
// or our custom threshold series.
|
|
90
|
-
if (!linkedSeries || ["errorbar", "x-threshold", "y-threshold"].includes(linkedSeries.type)) {
|
|
91
|
-
warnOnce("CartesianChart", 'The `linkedTo` property of "errorbar" series points to a missing, or unsupported series.');
|
|
119
|
+
// We only support error bars that are linked to some other series.
|
|
120
|
+
if (!validateLinkedTo(series, allSeries)) {
|
|
92
121
|
return null;
|
|
93
122
|
}
|
|
94
123
|
const data = transformRangeData(series.data);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cartesian-chart/index.tsx"],"names":[],"mappings":";AAAA,qEAAqE;AACrE,sCAAsC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAEnC,OAAO,EAAE,QAAQ,EAAE,MAAM,+CAA+C,CAAC;AAGzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AACnF,OAAO,gBAAgB,MAAM,+CAA+C,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAExE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAKpE,MAAM,cAAc,GAAG,UAAU,CAC/B,CACE,EACE,SAAS,GAAG,KAAK,EACjB,QAAQ,GAAG,KAAK,EAChB,QAAQ,GAAG,SAAS,EACpB,iBAAiB,GAAG,IAAI,EACxB,0BAA0B,GAAG,KAAK,EAClC,GAAG,KAAK,EACY,EACtB,GAAuC,EACvC,EAAE;IACF,0FAA0F;IAC1F,2FAA2F;IAC3F,0EAA0E;IAC1E,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,qBAAqB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,qBAAqB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAE7C,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,qBAAqB,EAAE;QACjE,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,EAAE,0BAA0B,EAAE;QACvF,QAAQ,EAAE,EAAE;KACb,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,sBAAsB,IACrB,GAAG,EAAE,GAAG,KACJ,KAAK,EACT,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,0BAA0B,EAAE,0BAA0B,EACtD,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,KACV,iBAAiB,CAAC,KAAK,CAAC,KACxB,kBAAkB,GACtB,CACH,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,gBAAgB,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;AAEnD,eAAe,cAAc,CAAC;AAE9B,SAAS,eAAe,CACtB,mBAAiE,EACjE,QAAmB;IAEnB,MAAM,iBAAiB,GAAwC,EAAE,CAAC;IAClE,SAAS,qBAAqB,CAAC,CAAoC;QACjE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,MAAM,CAAC;YACZ,KAAK,YAAY,CAAC;YAClB,KAAK,MAAM,CAAC;YACZ,KAAK,QAAQ;gBACX,OAAO,uBAAuB,CAAC,CAAC,CAAC,CAAC;YACpC,KAAK,QAAQ;gBACX,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC;YAClC,KAAK,SAAS;gBACZ,OAAO,sBAAsB,CAAC,CAAC,CAAC,CAAC;YACnC,KAAK,UAAU;gBACb,OAAO,uBAAuB,CAAC,CAAC,EAAE,mBAAmB,EAAE,QAAQ,CAAC,CAAC;YACnE,KAAK,aAAa,CAAC;YACnB,KAAK,aAAa;gBAChB,OAAO,wBAAwB,CAAC,CAAC,CAAC,CAAC;YACrC;gBACE,OAAO,IAAI,CAAC;QAChB,CAAC;IACH,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,mBAAmB,EAAE,CAAC;QACzC,MAAM,WAAW,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAClD,IAAI,WAAW,EAAE,CAAC;YAChB,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,SAAS,uBAAuB,CAM9B,CAAI;IACJ,MAAM,IAAI,GAAG,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,EAAO,CAAC;AACrG,CAAC;AAED,SAAS,qBAAqB,CAAoD,CAAI;IACpF,MAAM,IAAI,GAAG,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAO,CAAC;AAC7E,CAAC;AAED,SAAS,sBAAsB,CAAqD,CAAI;;IACtF,MAAM,IAAI,GAAG,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,MAAA,CAAC,CAAC,MAAM,mCAAI,EAAE,CAAC;IAC9B,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAO,CAAC;AACrF,CAAC;AAED,SAAS,wBAAwB,CAE/B,CAAI;IACJ,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAO,CAAC;AAC/G,CAAC;AAED,SAAS,uBAAuB,CAC9B,MAAiD,EACjD,SAAuD,EACvD,QAAmB;IAEnB,8DAA8D;IAC9D,8DAA8D;IAC9D,IAAI,QAAQ,EAAE,CAAC;QACb,QAAQ,CAAC,gBAAgB,EAAE,kDAAkD,CAAC,CAAC;QAC/E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,kGAAkG;IAClG,2EAA2E;IAC3E,uEAAuE;IACvE,MAAM,YAAY,GAChB,MAAM,CAAC,QAAQ,KAAK,WAAW;QAC7B,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1C,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzD,uGAAuG;IACvG,oGAAoG;IACpG,kCAAkC;IAClC,IAAI,CAAC,YAAY,IAAI,CAAC,UAAU,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5F,QAAQ,CACN,gBAAgB,EAChB,0FAA0F,CAC3F,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;AACvH,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAkC;IAC5D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAqC;IAC/D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAuC;IACpE,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAuC;IACpE,OAAO,EAAE,GAAG,oBAAoB,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,cAAc,EAAE,CAAC;AACjF,CAAC;AAED,SAAS,oBAAoB,CAC3B,IAAQ;IAER,OAAO;QACL,IAAI,EAAE,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,IAAI;QAChB,KAAK,EAAE,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,KAAK;QAClB,GAAG,EAAE,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,GAAG;QACd,GAAG,EAAE,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,GAAG;QACd,YAAY,EAAE,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,YAAY;QAChC,UAAU,EAAE,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,UAAU;QAC5B,cAAc,EAAE,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,cAAc;KAChC,CAAC;AACT,CAAC;AAED,SAAS,gBAAgB,CACvB,OAA4C;;IAE5C,OAAO;QACL,GAAG,OAAO;QACV,OAAO,EAAE,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,mCAAI,IAAI;QACjC,SAAS,EAAE,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,mCAAI,QAAQ;QACzC,IAAI,EAAE,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,mCAAI,QAAQ;KAChC,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,MAA0C;;IAE1C,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,mCAAI,IAAI,EAAE,CAAC;AACzD,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { forwardRef } from \"react\";\n\nimport { warnOnce } from \"@cloudscape-design/component-toolkit/internal\";\n\nimport { PointDataItemType, RangeDataItemOptions } from \"../core/interfaces\";\nimport { getDataAttributes } from \"../internal/base-component/get-data-attributes\";\nimport useBaseComponent from \"../internal/base-component/use-base-component\";\nimport { applyDisplayName } from \"../internal/utils/apply-display-name\";\nimport { SomeRequired } from \"../internal/utils/utils\";\nimport { InternalCartesianChart } from \"./chart-cartesian-internal\";\nimport { CartesianChartProps } from \"./interfaces\";\n\nexport type { CartesianChartProps };\n\nconst CartesianChart = forwardRef(\n (\n {\n fitHeight = false,\n inverted = false,\n stacking = undefined,\n emphasizeBaseline = true,\n verticalAxisTitlePlacement = \"top\",\n ...props\n }: CartesianChartProps,\n ref: React.Ref<CartesianChartProps.Ref>,\n ) => {\n // We transform options before propagating them to the internal chart to ensure only those\n // defined in the component's contract can be propagated down to the underlying Highcharts.\n // Additionally, we assign all default options, including the nested ones.\n const series = transformSeries(props.series, stacking);\n const xAxis = transformXAxisOptions(props.xAxis);\n const yAxis = transformYAxisOptions(props.yAxis);\n const tooltip = transformTooltip(props.tooltip);\n const legend = transformLegend(props.legend);\n\n const baseComponentProps = useBaseComponent(\"CartesianHighcharts\", {\n props: { fitHeight, inverted, stacking, emphasizeBaseline, verticalAxisTitlePlacement },\n metadata: {},\n });\n\n return (\n <InternalCartesianChart\n ref={ref}\n {...props}\n fitHeight={fitHeight}\n inverted={inverted}\n stacking={stacking}\n emphasizeBaseline={emphasizeBaseline}\n verticalAxisTitlePlacement={verticalAxisTitlePlacement}\n series={series}\n xAxis={xAxis}\n yAxis={yAxis}\n tooltip={tooltip}\n legend={legend}\n {...getDataAttributes(props)}\n {...baseComponentProps}\n />\n );\n },\n);\n\napplyDisplayName(CartesianChart, \"CartesianChart\");\n\nexport default CartesianChart;\n\nfunction transformSeries(\n untransformedSeries: readonly CartesianChartProps.SeriesOptions[],\n stacking?: \"normal\",\n): CartesianChartProps.SeriesOptions[] {\n const transformedSeries: CartesianChartProps.SeriesOptions[] = [];\n function transformSingleSeries(s: CartesianChartProps.SeriesOptions): null | CartesianChartProps.SeriesOptions {\n switch (s.type) {\n case \"area\":\n case \"areaspline\":\n case \"line\":\n case \"spline\":\n return transformLineLikeSeries(s);\n case \"column\":\n return transformColumnSeries(s);\n case \"scatter\":\n return transformScatterSeries(s);\n case \"errorbar\":\n return transformErrorBarSeries(s, untransformedSeries, stacking);\n case \"x-threshold\":\n case \"y-threshold\":\n return transformThresholdSeries(s);\n default:\n return null;\n }\n }\n for (const series of untransformedSeries) {\n const transformed = transformSingleSeries(series);\n if (transformed) {\n transformedSeries.push(transformed);\n }\n }\n return transformedSeries;\n}\n\nfunction transformLineLikeSeries<\n S extends\n | CartesianChartProps.AreaSeriesOptions\n | CartesianChartProps.AreaSplineSeriesOptions\n | CartesianChartProps.LineSeriesOptions\n | CartesianChartProps.SplineSeriesOptions,\n>(s: S): null | S {\n const data = transformPointData(s.data);\n return { type: s.type, id: s.id, name: s.name, color: s.color, dashStyle: s.dashStyle, data } as S;\n}\n\nfunction transformColumnSeries<S extends CartesianChartProps.ColumnSeriesOptions>(s: S): null | S {\n const data = transformPointData(s.data);\n return { type: s.type, id: s.id, name: s.name, color: s.color, data } as S;\n}\n\nfunction transformScatterSeries<S extends CartesianChartProps.ScatterSeriesOptions>(s: S): null | S {\n const data = transformPointData(s.data);\n const marker = s.marker ?? {};\n return { type: s.type, id: s.id, name: s.name, color: s.color, data, marker } as S;\n}\n\nfunction transformThresholdSeries<\n S extends CartesianChartProps.XThresholdSeriesOptions | CartesianChartProps.YThresholdSeriesOptions,\n>(s: S): null | S {\n return { type: s.type, id: s.id, name: s.name, color: s.color, value: s.value, dashStyle: s.dashStyle } as S;\n}\n\nfunction transformErrorBarSeries(\n series: CartesianChartProps.ErrorBarSeriesOptions,\n allSeries: readonly CartesianChartProps.SeriesOptions[],\n stacking?: \"normal\",\n): null | CartesianChartProps.ErrorBarSeriesOptions {\n // Highcharts only supports error bars for non-stacked series.\n // See: https://github.com/highcharts/highcharts/issues/23080.\n if (stacking) {\n warnOnce(\"CartesianChart\", \"Error bars are not supported for stacked series.\");\n return null;\n }\n // We only support error bars that are linked to some other series. It is only possible to link it\n // using series ID (but not name), or by using \":previous\" pseudo-selector.\n // See: https://api.highcharts.com/highcharts/series.errorbar.linkedTo.\n const linkedSeries =\n series.linkedTo === \":previous\"\n ? allSeries[allSeries.indexOf(series) - 1]\n : allSeries.find(({ id }) => id === series.linkedTo);\n // The non-linked error bars are not supported: those will not appear in our custom legend and tooltip,\n // so we remove them from the series array. We also do not support linking them to other error bars,\n // or our custom threshold series.\n if (!linkedSeries || [\"errorbar\", \"x-threshold\", \"y-threshold\"].includes(linkedSeries.type)) {\n warnOnce(\n \"CartesianChart\",\n 'The `linkedTo` property of \"errorbar\" series points to a missing, or unsupported series.',\n );\n return null;\n }\n const data = transformRangeData(series.data);\n return { type: series.type, id: series.id, name: series.name, color: series.color, linkedTo: series.linkedTo, data };\n}\n\nfunction transformPointData(data: readonly PointDataItemType[]): readonly PointDataItemType[] {\n return data.map((d) => (d && typeof d === \"object\" ? { x: d.x, y: d.y } : d));\n}\n\nfunction transformRangeData(data: readonly RangeDataItemOptions[]): readonly RangeDataItemOptions[] {\n return data.map((d) => ({ x: d.x, low: d.low, high: d.high }));\n}\n\nfunction transformXAxisOptions(axis?: CartesianChartProps.XAxisOptions): CartesianChartProps.XAxisOptions {\n return transformAxisOptions(axis);\n}\n\nfunction transformYAxisOptions(axis?: CartesianChartProps.YAxisOptions): CartesianChartProps.YAxisOptions {\n return { ...transformAxisOptions(axis), reversedStacks: axis?.reversedStacks };\n}\n\nfunction transformAxisOptions<O extends CartesianChartProps.XAxisOptions | CartesianChartProps.YAxisOptions>(\n axis?: O,\n): O {\n return {\n type: axis?.type,\n title: axis?.title,\n min: axis?.min,\n max: axis?.max,\n tickInterval: axis?.tickInterval,\n categories: axis?.categories,\n valueFormatter: axis?.valueFormatter,\n } as O;\n}\n\nfunction transformTooltip(\n tooltip?: CartesianChartProps.TooltipOptions,\n): SomeRequired<CartesianChartProps.TooltipOptions, \"enabled\" | \"placement\" | \"size\"> {\n return {\n ...tooltip,\n enabled: tooltip?.enabled ?? true,\n placement: tooltip?.placement ?? \"middle\",\n size: tooltip?.size ?? \"medium\",\n };\n}\n\nfunction transformLegend(\n legend?: CartesianChartProps.LegendOptions,\n): SomeRequired<CartesianChartProps.LegendOptions, \"enabled\"> {\n return { ...legend, enabled: legend?.enabled ?? true };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cartesian-chart/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 { forwardRef } from \"react\";\n\nimport { warnOnce } from \"@cloudscape-design/component-toolkit/internal\";\n\nimport { PointDataItemType, RangeDataItemOptions } from \"../core/interfaces\";\nimport { getDataAttributes } from \"../internal/base-component/get-data-attributes\";\nimport useBaseComponent from \"../internal/base-component/use-base-component\";\nimport { applyDisplayName } from \"../internal/utils/apply-display-name\";\nimport { SomeRequired } from \"../internal/utils/utils\";\nimport { InternalCartesianChart } from \"./chart-cartesian-internal\";\nimport { CartesianChartProps } from \"./interfaces\";\nimport { getMasterSeries, isErrorBar, isThreshold } from \"./utils\";\n\nexport type { CartesianChartProps };\n\nconst CartesianChart = forwardRef(\n (\n {\n fitHeight = false,\n inverted = false,\n stacking = undefined,\n emphasizeBaseline = true,\n verticalAxisTitlePlacement = \"top\",\n ...props\n }: CartesianChartProps,\n ref: React.Ref<CartesianChartProps.Ref>,\n ) => {\n // We transform options before propagating them to the internal chart to ensure only those\n // defined in the component's contract can be propagated down to the underlying Highcharts.\n // Additionally, we assign all default options, including the nested ones.\n const series = transformSeries(props.series, stacking);\n const xAxis = transformXAxisOptions(props.xAxis);\n const yAxis = transformYAxisOptions(props.yAxis);\n const tooltip = transformTooltip(props.tooltip);\n const legend = transformLegend(props.legend);\n\n const baseComponentProps = useBaseComponent(\"CartesianHighcharts\", {\n props: { fitHeight, inverted, stacking, emphasizeBaseline, verticalAxisTitlePlacement },\n metadata: {},\n });\n\n return (\n <InternalCartesianChart\n ref={ref}\n {...props}\n fitHeight={fitHeight}\n inverted={inverted}\n stacking={stacking}\n emphasizeBaseline={emphasizeBaseline}\n verticalAxisTitlePlacement={verticalAxisTitlePlacement}\n series={series}\n xAxis={xAxis}\n yAxis={yAxis}\n tooltip={tooltip}\n legend={legend}\n {...getDataAttributes(props)}\n {...baseComponentProps}\n />\n );\n },\n);\n\napplyDisplayName(CartesianChart, \"CartesianChart\");\n\nexport default CartesianChart;\n\nfunction transformSeries(\n untransformedSeries: readonly CartesianChartProps.SeriesOptions[],\n stacking?: \"normal\",\n): CartesianChartProps.SeriesOptions[] {\n const transformedSeries: CartesianChartProps.SeriesOptions[] = [];\n function transformSingleSeries(s: CartesianChartProps.SeriesOptions): null | CartesianChartProps.SeriesOptions {\n switch (s.type) {\n case \"area\":\n case \"areaspline\":\n case \"line\":\n case \"spline\":\n return transformLineLikeSeries(s, untransformedSeries);\n case \"column\":\n return transformColumnSeries(s, untransformedSeries);\n case \"scatter\":\n return transformScatterSeries(s, untransformedSeries);\n case \"errorbar\":\n return transformErrorBarSeries(s, untransformedSeries, stacking);\n case \"x-threshold\":\n case \"y-threshold\":\n return transformThresholdSeries(s);\n default:\n return null;\n }\n }\n for (const series of untransformedSeries) {\n const transformed = transformSingleSeries(series);\n if (transformed) {\n transformedSeries.push(transformed);\n }\n }\n return transformedSeries;\n}\n\nfunction validateLinkedTo(\n series: CartesianChartProps.SeriesOptions,\n allSeries: readonly CartesianChartProps.SeriesOptions[],\n): boolean {\n if (isThreshold(series) || series.linkedTo === undefined) {\n return true;\n }\n // The incorrectly linked series will not appear in our custom legend and tooltip, so we remove them\n // from the series array. We also do not support linking series to errorbar or threshold series.\n const masterSeries = getMasterSeries(allSeries, series);\n if (!masterSeries || isErrorBar(masterSeries) || isThreshold(masterSeries)) {\n warnOnce(\"CartesianChart\", \"The `linkedTo` property points to a missing or unsupported series.\");\n return false;\n }\n return true;\n}\n\nfunction transformLineLikeSeries<\n S extends\n | CartesianChartProps.AreaSeriesOptions\n | CartesianChartProps.AreaSplineSeriesOptions\n | CartesianChartProps.LineSeriesOptions\n | CartesianChartProps.SplineSeriesOptions,\n>(s: S, allSeries: readonly CartesianChartProps.SeriesOptions[]): null | S {\n if (!validateLinkedTo(s, allSeries)) {\n return null;\n }\n const data = transformPointData(s.data);\n return {\n type: s.type,\n id: s.id,\n name: s.name,\n color: s.color,\n dashStyle: s.dashStyle,\n linkedTo: s.linkedTo,\n data,\n } as S;\n}\n\nfunction transformColumnSeries<S extends CartesianChartProps.ColumnSeriesOptions>(\n s: S,\n allSeries: readonly CartesianChartProps.SeriesOptions[],\n): null | S {\n if (!validateLinkedTo(s, allSeries)) {\n return null;\n }\n const data = transformPointData(s.data);\n return { type: s.type, id: s.id, name: s.name, color: s.color, linkedTo: s.linkedTo, data } as S;\n}\n\nfunction transformScatterSeries<S extends CartesianChartProps.ScatterSeriesOptions>(\n s: S,\n allSeries: readonly CartesianChartProps.SeriesOptions[],\n): null | S {\n if (!validateLinkedTo(s, allSeries)) {\n return null;\n }\n const data = transformPointData(s.data);\n const marker = s.marker ?? {};\n return { type: s.type, id: s.id, name: s.name, color: s.color, linkedTo: s.linkedTo, data, marker } as S;\n}\n\nfunction transformThresholdSeries<\n S extends CartesianChartProps.XThresholdSeriesOptions | CartesianChartProps.YThresholdSeriesOptions,\n>(s: S): null | S {\n return {\n type: s.type,\n id: s.id,\n name: s.name,\n color: s.color,\n value: s.value,\n dashStyle: s.dashStyle,\n } as S;\n}\n\nfunction transformErrorBarSeries(\n series: CartesianChartProps.ErrorBarSeriesOptions,\n allSeries: readonly CartesianChartProps.SeriesOptions[],\n stacking?: \"normal\",\n): null | CartesianChartProps.ErrorBarSeriesOptions {\n // Highcharts only supports error bars for non-stacked series.\n // See: https://github.com/highcharts/highcharts/issues/23080.\n if (stacking) {\n warnOnce(\"CartesianChart\", \"Error bars are not supported for stacked series.\");\n return null;\n }\n // We only support error bars that are linked to some other series.\n if (!validateLinkedTo(series, allSeries)) {\n return null;\n }\n const data = transformRangeData(series.data);\n return { type: series.type, id: series.id, name: series.name, color: series.color, linkedTo: series.linkedTo, data };\n}\n\nfunction transformPointData(data: readonly PointDataItemType[]): readonly PointDataItemType[] {\n return data.map((d) => (d && typeof d === \"object\" ? { x: d.x, y: d.y } : d));\n}\n\nfunction transformRangeData(data: readonly RangeDataItemOptions[]): readonly RangeDataItemOptions[] {\n return data.map((d) => ({ x: d.x, low: d.low, high: d.high }));\n}\n\nfunction transformXAxisOptions(axis?: CartesianChartProps.XAxisOptions): CartesianChartProps.XAxisOptions {\n return transformAxisOptions(axis);\n}\n\nfunction transformYAxisOptions(axis?: CartesianChartProps.YAxisOptions): CartesianChartProps.YAxisOptions {\n return { ...transformAxisOptions(axis), reversedStacks: axis?.reversedStacks };\n}\n\nfunction transformAxisOptions<O extends CartesianChartProps.XAxisOptions | CartesianChartProps.YAxisOptions>(\n axis?: O,\n): O {\n return {\n type: axis?.type,\n title: axis?.title,\n min: axis?.min,\n max: axis?.max,\n tickInterval: axis?.tickInterval,\n categories: axis?.categories,\n valueFormatter: axis?.valueFormatter,\n } as O;\n}\n\nfunction transformTooltip(\n tooltip?: CartesianChartProps.TooltipOptions,\n): SomeRequired<CartesianChartProps.TooltipOptions, \"enabled\" | \"placement\" | \"size\"> {\n return {\n ...tooltip,\n enabled: tooltip?.enabled ?? true,\n placement: tooltip?.placement ?? \"middle\",\n size: tooltip?.size ?? \"medium\",\n };\n}\n\nfunction transformLegend(\n legend?: CartesianChartProps.LegendOptions,\n): SomeRequired<CartesianChartProps.LegendOptions, \"enabled\"> {\n return { ...legend, enabled: legend?.enabled ?? true };\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { CartesianChartProps } from "./interfaces";
|
|
2
|
+
export declare function isErrorBar(s: CartesianChartProps.SeriesOptions): s is CartesianChartProps.ErrorBarSeriesOptions;
|
|
3
|
+
export declare function isThreshold(s: CartesianChartProps.SeriesOptions): s is CartesianChartProps.XThresholdSeriesOptions | CartesianChartProps.YThresholdSeriesOptions;
|
|
4
|
+
export declare function getMasterSeries(series: readonly CartesianChartProps.SeriesOptions[], linked: CartesianChartProps.SeriesOptions): null | CartesianChartProps.SeriesOptions;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
export function isErrorBar(s) {
|
|
4
|
+
return s.type === "errorbar";
|
|
5
|
+
}
|
|
6
|
+
export function isThreshold(s) {
|
|
7
|
+
return s.type === "x-threshold" || s.type === "y-threshold";
|
|
8
|
+
}
|
|
9
|
+
// Series can be linked using `linkedTo` set to another series ID or to the ":previous" pseudo-selector.
|
|
10
|
+
// See: https://api.highcharts.com/highcharts/series.errorbar.linkedTo.
|
|
11
|
+
export function getMasterSeries(series, linked) {
|
|
12
|
+
var _a;
|
|
13
|
+
if (isThreshold(linked) || !linked.linkedTo) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
const linkedSeriesIndex = series.indexOf(linked);
|
|
17
|
+
const prevSeries = series[linkedSeriesIndex - 1];
|
|
18
|
+
return linked.linkedTo === ":previous" ? prevSeries : ((_a = series.find((m) => m.id === linked.linkedTo)) !== null && _a !== void 0 ? _a : null);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/cartesian-chart/utils.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAItC,MAAM,UAAU,UAAU,CAAC,CAAoC;IAC7D,OAAO,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,CAAoC;IAEpC,OAAO,CAAC,CAAC,IAAI,KAAK,aAAa,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC;AAC9D,CAAC;AAED,wGAAwG;AACxG,uEAAuE;AACvE,MAAM,UAAU,eAAe,CAC7B,MAAoD,EACpD,MAAyC;;IAEzC,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,MAAM,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC;IACjD,OAAO,MAAM,CAAC,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAA,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,QAAQ,CAAC,mCAAI,IAAI,CAAC,CAAC;AAC/G,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { CartesianChartProps } from \"./interfaces\";\n\nexport function isErrorBar(s: CartesianChartProps.SeriesOptions): s is CartesianChartProps.ErrorBarSeriesOptions {\n return s.type === \"errorbar\";\n}\n\nexport function isThreshold(\n s: CartesianChartProps.SeriesOptions,\n): s is CartesianChartProps.XThresholdSeriesOptions | CartesianChartProps.YThresholdSeriesOptions {\n return s.type === \"x-threshold\" || s.type === \"y-threshold\";\n}\n\n// Series can be linked using `linkedTo` set to another series ID or to the \":previous\" pseudo-selector.\n// See: https://api.highcharts.com/highcharts/series.errorbar.linkedTo.\nexport function getMasterSeries(\n series: readonly CartesianChartProps.SeriesOptions[],\n linked: CartesianChartProps.SeriesOptions,\n): null | CartesianChartProps.SeriesOptions {\n if (isThreshold(linked) || !linked.linkedTo) {\n return null;\n }\n const linkedSeriesIndex = series.indexOf(linked);\n const prevSeries = series[linkedSeriesIndex - 1];\n return linked.linkedTo === \":previous\" ? prevSeries : (series.find((m) => m.id === linked.linkedTo) ?? null);\n}\n"]}
|
|
@@ -30,8 +30,8 @@ export declare namespace ChartExtraContext {
|
|
|
30
30
|
}
|
|
31
31
|
interface DerivedState {
|
|
32
32
|
allX: number[];
|
|
33
|
-
getAllXInSeries: (series: Highcharts.Series) => number[];
|
|
34
33
|
getPointsByX: (x: number) => Highcharts.Point[];
|
|
34
|
+
getSeriesPoints: (series: Highcharts.Series) => Highcharts.Point[];
|
|
35
35
|
groupRects: {
|
|
36
36
|
group: Highcharts.Point[];
|
|
37
37
|
rect: Rect;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import { getChartSeries } from "../../internal/utils/chart-series";
|
|
4
4
|
import { getSeriesData } from "../../internal/utils/series-data";
|
|
5
|
-
import { getGroupRect, isSeriesStacked } from "../utils";
|
|
5
|
+
import { getGroupRect, isPointVisible, isSeriesStacked } from "../utils";
|
|
6
6
|
// The context is created when the chart component is rendered for the first time.
|
|
7
7
|
// On every subsequent render the settings and state are updated directly in the context object.
|
|
8
8
|
export function createChartContext() {
|
|
@@ -24,7 +24,7 @@ export function createChartContext() {
|
|
|
24
24
|
throw new Error("Invariant violation: using chart API before initialization.");
|
|
25
25
|
},
|
|
26
26
|
chartOrNull: null,
|
|
27
|
-
derived: { allX: [],
|
|
27
|
+
derived: { allX: [], getPointsByX: () => [], getSeriesPoints: () => [], groupRects: [] },
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
// The update method is called on every chart render, before any other initialization code.
|
|
@@ -35,6 +35,7 @@ export function updateChartContext(context, chart) {
|
|
|
35
35
|
context.derived = computeDerivedState(chart);
|
|
36
36
|
}
|
|
37
37
|
function computeDerivedState(chart) {
|
|
38
|
+
var _a;
|
|
38
39
|
const allXSet = new Set();
|
|
39
40
|
const allXInSeries = new WeakMap();
|
|
40
41
|
const pointsByX = new Map();
|
|
@@ -60,16 +61,41 @@ function computeDerivedState(chart) {
|
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
|
-
allXInSeries.set(s, Array.from(seriesX)
|
|
64
|
+
allXInSeries.set(s, Array.from(seriesX));
|
|
64
65
|
}
|
|
65
66
|
for (const [, points] of pointsByX) {
|
|
66
67
|
sortPoints(points);
|
|
67
68
|
}
|
|
68
69
|
const allX = Array.from(allXSet).sort(compareX);
|
|
70
|
+
// For each series, compute the ordered list of points to navigate through. For a linked family
|
|
71
|
+
// (primary + its linked children), all members share the same flat list: points sorted by X,
|
|
72
|
+
// with family members interleaved in series order within the same X value.
|
|
73
|
+
const seriesPointsMap = new WeakMap();
|
|
74
|
+
for (const s of getChartSeries(chart.series)) {
|
|
75
|
+
if (seriesPointsMap.has(s)) {
|
|
76
|
+
continue; // Already computed as part of a family.
|
|
77
|
+
}
|
|
78
|
+
const master = (_a = s.linkedParent) !== null && _a !== void 0 ? _a : s;
|
|
79
|
+
const family = [master, ...master.linkedSeries];
|
|
80
|
+
const familyXSet = new Set(family.flatMap((m) => { var _a; return (_a = allXInSeries.get(m)) !== null && _a !== void 0 ? _a : []; }));
|
|
81
|
+
const familyPoints = [];
|
|
82
|
+
for (const x of Array.from(familyXSet).sort(compareX)) {
|
|
83
|
+
for (const member of family) {
|
|
84
|
+
const point = member.data.find((d) => d.x === x && isPointVisible(d) && d.y !== null);
|
|
85
|
+
if (point && familyXSet.has(x)) {
|
|
86
|
+
familyPoints.push(point);
|
|
87
|
+
familyXSet.delete(x); // We ignore points that share X coordinate.
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
for (const member of family) {
|
|
92
|
+
seriesPointsMap.set(member, familyPoints);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
69
95
|
return {
|
|
70
96
|
allX,
|
|
71
|
-
getAllXInSeries: (s) => { var _a; return (_a = allXInSeries.get(s)) !== null && _a !== void 0 ? _a : []; },
|
|
72
97
|
getPointsByX: (x) => { var _a; return (_a = pointsByX.get(x)) !== null && _a !== void 0 ? _a : []; },
|
|
98
|
+
getSeriesPoints: (s) => { var _a; return (_a = seriesPointsMap.get(s)) !== null && _a !== void 0 ? _a : []; },
|
|
73
99
|
// Group rects are computed for every available x coordinate, each including at least one point with matching x value.
|
|
74
100
|
// They enclose all matching points of the group and are used to match hover position and place the tooltip or focus outline.
|
|
75
101
|
groupRects: allX.map((x) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-extra-context.js","sourceRoot":"","sources":["../../../../src/core/chart-api/chart-extra-context.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 { NonCancelableEventHandler } from \"../../internal/events\";\nimport { getChartSeries } from \"../../internal/utils/chart-series\";\nimport { getSeriesData } from \"../../internal/utils/series-data\";\nimport { ChartLabels } from \"../i18n-utils\";\nimport { CoreChartProps, Rect } from \"../interfaces\";\nimport { getGroupRect, isSeriesStacked } from \"../utils\";\n\n// Chart API context is used for dependency injection for chart utilities.\n// It is initialized on chart render, and includes the chart instance, consumer\n// settings and state, and derived state, which is computed from the chart instance\n// on each render, and reused across utilities to avoid duplicate work.\n\nexport interface ChartExtraContext {\n settings: ChartExtraContext.Settings;\n handlers: ChartExtraContext.Handlers;\n state: ChartExtraContext.State;\n derived: ChartExtraContext.DerivedState;\n chartOrNull: null | Highcharts.Chart;\n chart: () => Highcharts.Chart;\n}\n\nexport namespace ChartExtraContext {\n export interface Settings {\n chartId: string;\n noDataEnabled: boolean;\n legendEnabled: boolean;\n tooltipEnabled: boolean;\n keyboardNavigationEnabled: boolean;\n labels: ChartLabels;\n getItemOptions?: CoreChartProps.GetItemOptions;\n }\n\n export interface Handlers {\n onHighlight?: NonCancelableEventHandler<CoreChartProps.HighlightChangeDetail>;\n onClearHighlight?: NonCancelableEventHandler<CoreChartProps.HighlightClearDetail>;\n onVisibleItemsChange?: NonCancelableEventHandler<CoreChartProps.VisibleItemsChangeDetail>;\n }\n\n export interface State {\n visibleItems?: readonly string[];\n }\n\n export interface DerivedState {\n allX: number[];\n getAllXInSeries: (series: Highcharts.Series) => number[];\n getPointsByX: (x: number) => Highcharts.Point[];\n groupRects: { group: Highcharts.Point[]; rect: Rect }[];\n }\n}\n\n// The context is created when the chart component is rendered for the first time.\n// On every subsequent render the settings and state are updated directly in the context object.\nexport function createChartContext(): ChartExtraContext {\n return {\n settings: {\n chartId: \"\",\n noDataEnabled: false,\n legendEnabled: false,\n tooltipEnabled: false,\n keyboardNavigationEnabled: false,\n labels: {},\n },\n handlers: {},\n state: {},\n chart: () => {\n // Before the first chart render there is no chart instance, which is required for most of the utilities.\n // Instead of doing null checks in each utility, an attempt to access the chart instance before it is ready\n // will cause an exception, indicating an logical error in the code.\n throw new Error(\"Invariant violation: using chart API before initialization.\");\n },\n chartOrNull: null,\n derived: { allX: [], getAllXInSeries: () => [], getPointsByX: () => [], groupRects: [] },\n };\n}\n\n// The update method is called on every chart render, before any other initialization code.\n// This ensures the context state is up to date and can be used for subsequent computations.\nexport function updateChartContext(context: ChartExtraContext, chart: Highcharts.Chart) {\n context.chart = () => chart;\n context.chartOrNull = chart;\n context.derived = computeDerivedState(chart);\n}\n\nfunction computeDerivedState(chart: Highcharts.Chart): ChartExtraContext.DerivedState {\n const allXSet = new Set<number>();\n const allXInSeries = new WeakMap<Highcharts.Series, number[]>();\n const pointsByX = new Map<number, Highcharts.Point[]>();\n const getXPoints = (x: number) => pointsByX.get(x) ?? [];\n const addPoint = (point: Highcharts.Point) => {\n const xPoints = getXPoints(point.x);\n xPoints.push(point);\n pointsByX.set(point.x, xPoints);\n };\n const compareX = (a: number, b: number) => a - b;\n\n for (const s of getChartSeries(chart.series)) {\n const seriesX = new Set<number>();\n if (s.visible) {\n for (const d of getSeriesData(s.data)) {\n // Points with y=null represent the absence of value, there is no need to include them and those\n // should have no impact on computed rects or navigation.\n\n // Although \"d\" can't be undefined according to Highcharts API, it does become undefined for chart containing more datapoints\n // than the cropThreshold for that series (specific cases of re-rendering the chart with updated options listening to setExteme updates)\n if (d.visible && d.y !== null) {\n seriesX.add(d.x);\n allXSet.add(d.x);\n addPoint(d);\n }\n }\n }\n allXInSeries.set(s, Array.from(seriesX).sort(compareX));\n }\n for (const [, points] of pointsByX) {\n sortPoints(points);\n }\n const allX = Array.from(allXSet).sort(compareX);\n return {\n allX,\n getAllXInSeries: (s) => allXInSeries.get(s) ?? [],\n getPointsByX: (x) => pointsByX.get(x) ?? [],\n // Group rects are computed for every available x coordinate, each including at least one point with matching x value.\n // They enclose all matching points of the group and are used to match hover position and place the tooltip or focus outline.\n groupRects: allX.map((x) => ({\n group: getXPoints(x),\n rect: getGroupRect(getXPoints(x)),\n })),\n };\n}\n\n// The points are sorted to ensure consistent navigation, including inverted chart orientation.\n// The order of series in grouped column charts is kept, while stacked series are sorted by their\n// respective positions in the plot.\nfunction sortPoints(group: Highcharts.Point[]) {\n const reversed = !!group[0]?.series.yAxis?.reversed;\n group.sort((a, b) => {\n const ay = a.plotY === undefined || (a.series.type === \"column\" && !isSeriesStacked(a.series)) ? 0 : a.plotY;\n const by = b.plotY === undefined || (b.series.type === \"column\" && !isSeriesStacked(b.series)) ? 0 : b.plotY;\n return !reversed ? ay - by : by - ay;\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chart-extra-context.js","sourceRoot":"","sources":["../../../../src/core/chart-api/chart-extra-context.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 { NonCancelableEventHandler } from \"../../internal/events\";\nimport { getChartSeries } from \"../../internal/utils/chart-series\";\nimport { getSeriesData } from \"../../internal/utils/series-data\";\nimport { ChartLabels } from \"../i18n-utils\";\nimport { CoreChartProps, Rect } from \"../interfaces\";\nimport { getGroupRect, isPointVisible, isSeriesStacked } from \"../utils\";\n\n// Chart API context is used for dependency injection for chart utilities.\n// It is initialized on chart render, and includes the chart instance, consumer\n// settings and state, and derived state, which is computed from the chart instance\n// on each render, and reused across utilities to avoid duplicate work.\n\nexport interface ChartExtraContext {\n settings: ChartExtraContext.Settings;\n handlers: ChartExtraContext.Handlers;\n state: ChartExtraContext.State;\n derived: ChartExtraContext.DerivedState;\n chartOrNull: null | Highcharts.Chart;\n chart: () => Highcharts.Chart;\n}\n\nexport namespace ChartExtraContext {\n export interface Settings {\n chartId: string;\n noDataEnabled: boolean;\n legendEnabled: boolean;\n tooltipEnabled: boolean;\n keyboardNavigationEnabled: boolean;\n labels: ChartLabels;\n getItemOptions?: CoreChartProps.GetItemOptions;\n }\n\n export interface Handlers {\n onHighlight?: NonCancelableEventHandler<CoreChartProps.HighlightChangeDetail>;\n onClearHighlight?: NonCancelableEventHandler<CoreChartProps.HighlightClearDetail>;\n onVisibleItemsChange?: NonCancelableEventHandler<CoreChartProps.VisibleItemsChangeDetail>;\n }\n\n export interface State {\n visibleItems?: readonly string[];\n }\n\n export interface DerivedState {\n allX: number[];\n getPointsByX: (x: number) => Highcharts.Point[];\n getSeriesPoints: (series: Highcharts.Series) => Highcharts.Point[];\n groupRects: { group: Highcharts.Point[]; rect: Rect }[];\n }\n}\n\n// The context is created when the chart component is rendered for the first time.\n// On every subsequent render the settings and state are updated directly in the context object.\nexport function createChartContext(): ChartExtraContext {\n return {\n settings: {\n chartId: \"\",\n noDataEnabled: false,\n legendEnabled: false,\n tooltipEnabled: false,\n keyboardNavigationEnabled: false,\n labels: {},\n },\n handlers: {},\n state: {},\n chart: () => {\n // Before the first chart render there is no chart instance, which is required for most of the utilities.\n // Instead of doing null checks in each utility, an attempt to access the chart instance before it is ready\n // will cause an exception, indicating an logical error in the code.\n throw new Error(\"Invariant violation: using chart API before initialization.\");\n },\n chartOrNull: null,\n derived: { allX: [], getPointsByX: () => [], getSeriesPoints: () => [], groupRects: [] },\n };\n}\n\n// The update method is called on every chart render, before any other initialization code.\n// This ensures the context state is up to date and can be used for subsequent computations.\nexport function updateChartContext(context: ChartExtraContext, chart: Highcharts.Chart) {\n context.chart = () => chart;\n context.chartOrNull = chart;\n context.derived = computeDerivedState(chart);\n}\n\nfunction computeDerivedState(chart: Highcharts.Chart): ChartExtraContext.DerivedState {\n const allXSet = new Set<number>();\n const allXInSeries = new WeakMap<Highcharts.Series, number[]>();\n const pointsByX = new Map<number, Highcharts.Point[]>();\n const getXPoints = (x: number) => pointsByX.get(x) ?? [];\n const addPoint = (point: Highcharts.Point) => {\n const xPoints = getXPoints(point.x);\n xPoints.push(point);\n pointsByX.set(point.x, xPoints);\n };\n const compareX = (a: number, b: number) => a - b;\n\n for (const s of getChartSeries(chart.series)) {\n const seriesX = new Set<number>();\n if (s.visible) {\n for (const d of getSeriesData(s.data)) {\n // Points with y=null represent the absence of value, there is no need to include them and those\n // should have no impact on computed rects or navigation.\n\n // Although \"d\" can't be undefined according to Highcharts API, it does become undefined for chart containing more datapoints\n // than the cropThreshold for that series (specific cases of re-rendering the chart with updated options listening to setExteme updates)\n if (d.visible && d.y !== null) {\n seriesX.add(d.x);\n allXSet.add(d.x);\n addPoint(d);\n }\n }\n }\n allXInSeries.set(s, Array.from(seriesX));\n }\n for (const [, points] of pointsByX) {\n sortPoints(points);\n }\n const allX = Array.from(allXSet).sort(compareX);\n\n // For each series, compute the ordered list of points to navigate through. For a linked family\n // (primary + its linked children), all members share the same flat list: points sorted by X,\n // with family members interleaved in series order within the same X value.\n const seriesPointsMap = new WeakMap<Highcharts.Series, Highcharts.Point[]>();\n for (const s of getChartSeries(chart.series)) {\n if (seriesPointsMap.has(s)) {\n continue; // Already computed as part of a family.\n }\n const master = s.linkedParent ?? s;\n const family = [master, ...master.linkedSeries];\n const familyXSet = new Set(family.flatMap((m) => allXInSeries.get(m) ?? []));\n const familyPoints: Highcharts.Point[] = [];\n for (const x of Array.from(familyXSet).sort(compareX)) {\n for (const member of family) {\n const point = member.data.find((d) => d.x === x && isPointVisible(d) && d.y !== null);\n if (point && familyXSet.has(x)) {\n familyPoints.push(point);\n familyXSet.delete(x); // We ignore points that share X coordinate.\n }\n }\n }\n for (const member of family) {\n seriesPointsMap.set(member, familyPoints);\n }\n }\n return {\n allX,\n getPointsByX: (x) => pointsByX.get(x) ?? [],\n getSeriesPoints: (s) => seriesPointsMap.get(s) ?? [],\n // Group rects are computed for every available x coordinate, each including at least one point with matching x value.\n // They enclose all matching points of the group and are used to match hover position and place the tooltip or focus outline.\n groupRects: allX.map((x) => ({\n group: getXPoints(x),\n rect: getGroupRect(getXPoints(x)),\n })),\n };\n}\n\n// The points are sorted to ensure consistent navigation, including inverted chart orientation.\n// The order of series in grouped column charts is kept, while stacked series are sorted by their\n// respective positions in the plot.\nfunction sortPoints(group: Highcharts.Point[]) {\n const reversed = !!group[0]?.series.yAxis?.reversed;\n group.sort((a, b) => {\n const ay = a.plotY === undefined || (a.series.type === \"column\" && !isSeriesStacked(a.series)) ? 0 : a.plotY;\n const by = b.plotY === undefined || (b.series.type === \"column\" && !isSeriesStacked(b.series)) ? 0 : b.plotY;\n return !reversed ? ay - by : by - ay;\n });\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import * as Styles from "../../internal/chart-styles";
|
|
4
|
+
import { getLinkedSeries, getMasterSeries } from "../../internal/utils/chart-series";
|
|
4
5
|
import { getSeriesData } from "../../internal/utils/series-data";
|
|
5
6
|
import { getPointId, getSeriesId } from "../utils";
|
|
6
7
|
const SET_STATE_LOCK = Symbol("awsui-set-state-lock");
|
|
@@ -15,20 +16,23 @@ export class ChartExtraHighlight {
|
|
|
15
16
|
this.pointState = new Map();
|
|
16
17
|
// The method highlights specified series or points (by id). It is used when hovering over the legend items.
|
|
17
18
|
this.highlightChartItems = (itemIds) => {
|
|
19
|
+
const itemIdsSet = new Set(itemIds);
|
|
18
20
|
for (const s of this.context.chart().series) {
|
|
19
21
|
// In pie charts it is the points, not series, that are shown in the legend, and can be highlighted.
|
|
20
22
|
if (s.type === "pie") {
|
|
21
|
-
for (const p of s.data) {
|
|
22
|
-
if (
|
|
23
|
+
for (const p of getSeriesData(s.data)) {
|
|
24
|
+
if (itemIdsSet.has(getPointId(p))) {
|
|
23
25
|
this.setPointState(p, "hover");
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
}
|
|
27
29
|
else {
|
|
28
|
-
|
|
30
|
+
const seriesActive = itemIdsSet.has(getSeriesId(s));
|
|
31
|
+
const masterSeriesActive = s.linkedParent ? itemIdsSet.has(getSeriesId(s.linkedParent)) : false;
|
|
32
|
+
this.setSeriesState(s, seriesActive || masterSeriesActive ? "" : "inactive");
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
|
-
setPlotLinesState(this.context.chart(), (lineId) =>
|
|
35
|
+
setPlotLinesState(this.context.chart(), (lineId) => itemIdsSet.has(lineId));
|
|
32
36
|
};
|
|
33
37
|
// This method is similar to the above, but it takes a group of points. The cartesian chart points
|
|
34
38
|
// do not have IDs, so we match points and series by their references instead. This is used to control
|
|
@@ -39,15 +43,17 @@ export class ChartExtraHighlight {
|
|
|
39
43
|
const includedSeriesIds = new Set();
|
|
40
44
|
points.forEach((point) => {
|
|
41
45
|
includedPoints.add(point);
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
getLinkedSeries(point).forEach((s) => {
|
|
47
|
+
includedSeries.add(s);
|
|
48
|
+
includedSeriesIds.add(getSeriesId(s));
|
|
49
|
+
});
|
|
44
50
|
});
|
|
45
51
|
for (const s of this.context.chart().series) {
|
|
46
52
|
this.setSeriesState(s, includedSeries.has(s) ? "" : "inactive");
|
|
47
53
|
// For column series we ensure only one group/stack that matches selected X is highlighted.
|
|
48
54
|
// See: https://github.com/highcharts/highcharts/issues/23076.
|
|
49
55
|
if (s.type === "column") {
|
|
50
|
-
for (const d of s.data) {
|
|
56
|
+
for (const d of getSeriesData(s.data)) {
|
|
51
57
|
this.setPointState(d, includedPoints.has(d) ? "" : "inactive");
|
|
52
58
|
}
|
|
53
59
|
}
|
|
@@ -57,37 +63,34 @@ export class ChartExtraHighlight {
|
|
|
57
63
|
// This method is similar to the above, but it takes a single point. This is used for point highlighting
|
|
58
64
|
// in cartesian charts, and for pie chart segments.
|
|
59
65
|
this.highlightChartPoint = (point) => {
|
|
66
|
+
const masterSeries = getMasterSeries(point);
|
|
67
|
+
const linkedSeries = new Set(getLinkedSeries(point));
|
|
60
68
|
for (const s of this.context.chart().series) {
|
|
61
|
-
this.setSeriesState(s, point.series === s ? "hover" : "inactive");
|
|
62
69
|
// For pie charts it is important that the hover actions comes last, as otherwise the segment's highlight "halo"
|
|
63
70
|
// is removed whenever any segment is made inactive.
|
|
71
|
+
this.setSeriesState(s, linkedSeries.has(s) ? "hover" : "inactive");
|
|
64
72
|
if (s.type === "pie") {
|
|
65
|
-
for (const d of s.data) {
|
|
73
|
+
for (const d of getSeriesData(s.data)) {
|
|
66
74
|
this.setPointState(d, "inactive");
|
|
67
75
|
}
|
|
68
76
|
this.setPointState(point, "hover");
|
|
69
77
|
}
|
|
70
78
|
// For column series we ensure only one group/stack that matches selected X is highlighted.
|
|
71
79
|
else if (s.type === "column") {
|
|
72
|
-
for (const d of s.data) {
|
|
80
|
+
for (const d of getSeriesData(s.data)) {
|
|
73
81
|
this.setPointState(d, d === point ? "hover" : "inactive");
|
|
74
82
|
}
|
|
75
83
|
}
|
|
76
84
|
}
|
|
77
|
-
// Highlight linked series when target series is highlighted.
|
|
78
|
-
this.context
|
|
79
|
-
.chart()
|
|
80
|
-
.series.filter((series) => series === point.series)
|
|
81
|
-
.forEach((series) => series.linkedSeries.forEach((linked) => this.setSeriesState(linked, "hover")));
|
|
82
85
|
// Highlight threshold series plot lines.
|
|
83
|
-
setPlotLinesState(this.context.chart(), (lineId) => lineId === getSeriesId(
|
|
86
|
+
setPlotLinesState(this.context.chart(), (lineId) => lineId === getSeriesId(masterSeries));
|
|
84
87
|
};
|
|
85
88
|
// Removes dimmed state from all series and points.
|
|
86
89
|
this.clearChartItemsHighlight = () => {
|
|
87
90
|
var _a;
|
|
88
91
|
for (const s of (_a = this.context.chart().series) !== null && _a !== void 0 ? _a : []) {
|
|
89
92
|
this.setSeriesState(s, "");
|
|
90
|
-
for (const p of s.data) {
|
|
93
|
+
for (const p of getSeriesData(s.data)) {
|
|
91
94
|
this.setPointState(p, "");
|
|
92
95
|
}
|
|
93
96
|
}
|