@mui/x-charts 9.0.3 → 9.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/BarChart/FocusedBar.js +3 -0
  2. package/BarChart/FocusedBar.mjs +3 -0
  3. package/CHANGELOG.md +87 -0
  4. package/ChartsTooltip/useAxesTooltip.js +11 -3
  5. package/ChartsTooltip/useAxesTooltip.mjs +11 -3
  6. package/LineChart/FocusedLineMark.js +3 -0
  7. package/LineChart/FocusedLineMark.mjs +3 -0
  8. package/LineChart/seriesConfig/getItemAtPosition.js +12 -35
  9. package/LineChart/seriesConfig/getItemAtPosition.mjs +10 -33
  10. package/PieChart/FocusedPieArc.js +3 -0
  11. package/PieChart/FocusedPieArc.mjs +3 -0
  12. package/RadarChart/FocusedRadarMark.js +3 -0
  13. package/RadarChart/FocusedRadarMark.mjs +3 -0
  14. package/ScatterChart/FocusedScatterMark.js +3 -0
  15. package/ScatterChart/FocusedScatterMark.mjs +3 -0
  16. package/index.js +1 -1
  17. package/index.mjs +1 -1
  18. package/internals/commonNextFocusItem.js +62 -8
  19. package/internals/commonNextFocusItem.mjs +62 -8
  20. package/internals/findClosestIndex.d.mts +5 -0
  21. package/internals/findClosestIndex.d.ts +5 -0
  22. package/internals/findClosestIndex.js +27 -0
  23. package/internals/findClosestIndex.mjs +22 -0
  24. package/internals/getAsNumber.d.mts +1 -0
  25. package/internals/getAsNumber.d.ts +1 -0
  26. package/internals/getAsNumber.js +9 -0
  27. package/internals/getAsNumber.mjs +3 -0
  28. package/internals/index.d.mts +1 -0
  29. package/internals/index.d.ts +1 -0
  30. package/internals/index.js +12 -0
  31. package/internals/index.mjs +1 -0
  32. package/internals/plugins/featurePlugins/useChartCartesianAxis/getAxisValue.js +4 -21
  33. package/internals/plugins/featurePlugins/useChartCartesianAxis/getAxisValue.mjs +4 -21
  34. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/findVisibleDataIndex.d.mts +30 -0
  35. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/findVisibleDataIndex.d.ts +30 -0
  36. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/findVisibleDataIndex.js +57 -0
  37. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/findVisibleDataIndex.mjs +51 -0
  38. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getMaxSeriesLength.js +7 -1
  39. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getMaxSeriesLength.mjs +7 -1
  40. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getNonEmptySeriesArray.js +7 -1
  41. package/internals/plugins/featurePlugins/useChartKeyboardNavigation/utils/getNonEmptySeriesArray.mjs +7 -1
  42. package/internals/plugins/featurePlugins/useChartPolarAxis/computeAxisValue.js +2 -1
  43. package/internals/plugins/featurePlugins/useChartPolarAxis/computeAxisValue.mjs +2 -1
  44. package/internals/plugins/featurePlugins/useChartPolarAxis/getAxisIndex.js +9 -4
  45. package/internals/plugins/featurePlugins/useChartPolarAxis/getAxisIndex.mjs +9 -3
  46. package/package.json +143 -143
@@ -1,8 +1,13 @@
1
1
  import { getPreviousNonEmptySeries } from "./plugins/featurePlugins/useChartKeyboardNavigation/utils/getPreviousNonEmptySeries.mjs";
2
2
  import { getMaxSeriesLength } from "./plugins/featurePlugins/useChartKeyboardNavigation/utils/getMaxSeriesLength.mjs";
3
3
  import { getNextNonEmptySeries } from "./plugins/featurePlugins/useChartKeyboardNavigation/utils/getNextNonEmptySeries.mjs";
4
+ import { findVisibleDataIndex } from "./plugins/featurePlugins/useChartKeyboardNavigation/utils/findVisibleDataIndex.mjs";
4
5
  import { seriesHasData } from "./seriesHasData.mjs";
5
6
  import { selectorChartSeriesProcessed } from "./plugins/corePlugins/useChartSeries/useChartSeries.selectors.mjs";
7
+ function isSeriesHidden(processedSeries, type, seriesId) {
8
+ const seriesItem = processedSeries[type]?.series[seriesId];
9
+ return Boolean(seriesItem && 'hidden' in seriesItem && seriesItem.hidden);
10
+ }
6
11
  export function createGetNextIndexFocusedItem(
7
12
  /**
8
13
  * The set of series types compatible with this navigation action.
@@ -16,7 +21,7 @@ allowCycles = false) {
16
21
  const processedSeries = selectorChartSeriesProcessed(state);
17
22
  let seriesId = currentItem?.seriesId;
18
23
  let type = currentItem?.type;
19
- if (!type || seriesId == null || !seriesHasData(processedSeries, type, seriesId)) {
24
+ if (!type || seriesId == null || !seriesHasData(processedSeries, type, seriesId) || isSeriesHidden(processedSeries, type, seriesId)) {
20
25
  const nextSeries = getNextNonEmptySeries(processedSeries, compatibleSeriesTypes, type, seriesId);
21
26
  if (nextSeries === null) {
22
27
  return null;
@@ -31,10 +36,22 @@ allowCycles = false) {
31
36
  } else {
32
37
  dataIndex = Math.min(maxLength - 1, dataIndex);
33
38
  }
39
+ const visibleDataIndex = findVisibleDataIndex({
40
+ processedSeries,
41
+ type,
42
+ seriesId,
43
+ startIndex: dataIndex,
44
+ dataLength: maxLength,
45
+ direction: 1,
46
+ allowCycles
47
+ });
48
+ if (visibleDataIndex === null) {
49
+ return null;
50
+ }
34
51
  return {
35
52
  type: type,
36
53
  seriesId,
37
- dataIndex
54
+ dataIndex: visibleDataIndex
38
55
  };
39
56
  };
40
57
  }
@@ -51,7 +68,7 @@ allowCycles = false) {
51
68
  const processedSeries = selectorChartSeriesProcessed(state);
52
69
  let seriesId = currentItem?.seriesId;
53
70
  let type = currentItem?.type;
54
- if (!type || seriesId == null || !seriesHasData(processedSeries, type, seriesId)) {
71
+ if (!type || seriesId == null || !seriesHasData(processedSeries, type, seriesId) || isSeriesHidden(processedSeries, type, seriesId)) {
55
72
  const previousSeries = getPreviousNonEmptySeries(processedSeries, compatibleSeriesTypes, type, seriesId);
56
73
  if (previousSeries === null) {
57
74
  return null;
@@ -66,10 +83,22 @@ allowCycles = false) {
66
83
  } else {
67
84
  dataIndex = Math.max(0, dataIndex);
68
85
  }
86
+ const visibleDataIndex = findVisibleDataIndex({
87
+ processedSeries,
88
+ type,
89
+ seriesId,
90
+ startIndex: dataIndex,
91
+ dataLength: maxLength,
92
+ direction: -1,
93
+ allowCycles
94
+ });
95
+ if (visibleDataIndex === null) {
96
+ return null;
97
+ }
69
98
  return {
70
99
  type: type,
71
100
  seriesId,
72
- dataIndex
101
+ dataIndex: visibleDataIndex
73
102
  };
74
103
  };
75
104
  }
@@ -88,11 +117,24 @@ compatibleSeriesTypes) {
88
117
  }
89
118
  type = nextSeries.type;
90
119
  seriesId = nextSeries.seriesId;
91
- const dataIndex = currentItem?.dataIndex == null ? 0 : currentItem.dataIndex;
120
+ const data = processedSeries[type].series[seriesId].data;
121
+ const startIndex = currentItem?.dataIndex == null ? 0 : Math.min(currentItem.dataIndex, data.length - 1);
122
+ const visibleDataIndex = findVisibleDataIndex({
123
+ processedSeries,
124
+ type,
125
+ seriesId,
126
+ startIndex,
127
+ dataLength: data.length,
128
+ direction: 1,
129
+ allowCycles: true
130
+ });
131
+ if (visibleDataIndex === null) {
132
+ return null;
133
+ }
92
134
  return {
93
135
  type: type,
94
136
  seriesId,
95
- dataIndex
137
+ dataIndex: visibleDataIndex
96
138
  };
97
139
  };
98
140
  }
@@ -112,11 +154,23 @@ compatibleSeriesTypes) {
112
154
  type = previousSeries.type;
113
155
  seriesId = previousSeries.seriesId;
114
156
  const data = processedSeries[type].series[seriesId].data;
115
- const dataIndex = currentItem?.dataIndex == null ? data.length - 1 : currentItem.dataIndex;
157
+ const startIndex = currentItem?.dataIndex == null ? data.length - 1 : Math.min(currentItem.dataIndex, data.length - 1);
158
+ const visibleDataIndex = findVisibleDataIndex({
159
+ processedSeries,
160
+ type,
161
+ seriesId,
162
+ startIndex,
163
+ dataLength: data.length,
164
+ direction: -1,
165
+ allowCycles: true
166
+ });
167
+ if (visibleDataIndex === null) {
168
+ return null;
169
+ }
116
170
  return {
117
171
  type: type,
118
172
  seriesId,
119
- dataIndex
173
+ dataIndex: visibleDataIndex
120
174
  };
121
175
  };
122
176
  }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Returns the index of the entry in `axisData` whose numeric value is closest
3
+ * to `valueAsNumber`. Returns -1 if `axisData` is empty.
4
+ */
5
+ export declare function findClosestIndex(axisData: readonly any[], valueAsNumber: number): number;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Returns the index of the entry in `axisData` whose numeric value is closest
3
+ * to `valueAsNumber`. Returns -1 if `axisData` is empty.
4
+ */
5
+ export declare function findClosestIndex(axisData: readonly any[], valueAsNumber: number): number;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.findClosestIndex = findClosestIndex;
7
+ var _getAsNumber = require("./getAsNumber");
8
+ /**
9
+ * Returns the index of the entry in `axisData` whose numeric value is closest
10
+ * to `valueAsNumber`. Returns -1 if `axisData` is empty.
11
+ */
12
+ function findClosestIndex(axisData, valueAsNumber) {
13
+ return axisData.findIndex((pointValue, index) => {
14
+ const v = (0, _getAsNumber.getAsNumber)(pointValue);
15
+ if (v > valueAsNumber) {
16
+ if (index === 0 || Math.abs(valueAsNumber - v) <= Math.abs(valueAsNumber - (0, _getAsNumber.getAsNumber)(axisData[index - 1]))) {
17
+ return true;
18
+ }
19
+ }
20
+ if (v <= valueAsNumber) {
21
+ if (index === axisData.length - 1 || Math.abs(valueAsNumber - v) < Math.abs(valueAsNumber - (0, _getAsNumber.getAsNumber)(axisData[index + 1]))) {
22
+ return true;
23
+ }
24
+ }
25
+ return false;
26
+ });
27
+ }
@@ -0,0 +1,22 @@
1
+ import { getAsNumber } from "./getAsNumber.mjs";
2
+
3
+ /**
4
+ * Returns the index of the entry in `axisData` whose numeric value is closest
5
+ * to `valueAsNumber`. Returns -1 if `axisData` is empty.
6
+ */
7
+ export function findClosestIndex(axisData, valueAsNumber) {
8
+ return axisData.findIndex((pointValue, index) => {
9
+ const v = getAsNumber(pointValue);
10
+ if (v > valueAsNumber) {
11
+ if (index === 0 || Math.abs(valueAsNumber - v) <= Math.abs(valueAsNumber - getAsNumber(axisData[index - 1]))) {
12
+ return true;
13
+ }
14
+ }
15
+ if (v <= valueAsNumber) {
16
+ if (index === axisData.length - 1 || Math.abs(valueAsNumber - v) < Math.abs(valueAsNumber - getAsNumber(axisData[index + 1]))) {
17
+ return true;
18
+ }
19
+ }
20
+ return false;
21
+ });
22
+ }
@@ -0,0 +1 @@
1
+ export declare function getAsNumber(value: number | Date): number;
@@ -0,0 +1 @@
1
+ export declare function getAsNumber(value: number | Date): number;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getAsNumber = getAsNumber;
7
+ function getAsNumber(value) {
8
+ return value instanceof Date ? value.getTime() : value;
9
+ }
@@ -0,0 +1,3 @@
1
+ export function getAsNumber(value) {
2
+ return value instanceof Date ? value.getTime() : value;
3
+ }
@@ -55,6 +55,7 @@ export * from "./isDefined.mjs";
55
55
  export * from "./getScale.mjs";
56
56
  export * from "./stacking/index.mjs";
57
57
  export * from "./getCurve.mjs";
58
+ export * from "./getSymbol.mjs";
58
59
  export * from "./consumeSlots.mjs";
59
60
  export * from "./consumeThemeProps.mjs";
60
61
  export * from "./defaultizeMargin.mjs";
@@ -55,6 +55,7 @@ export * from "./isDefined.js";
55
55
  export * from "./getScale.js";
56
56
  export * from "./stacking/index.js";
57
57
  export * from "./getCurve.js";
58
+ export * from "./getSymbol.js";
58
59
  export * from "./consumeSlots.js";
59
60
  export * from "./consumeThemeProps.js";
60
61
  export * from "./defaultizeMargin.js";
@@ -686,6 +686,18 @@ Object.keys(_getCurve).forEach(function (key) {
686
686
  }
687
687
  });
688
688
  });
689
+ var _getSymbol = require("./getSymbol");
690
+ Object.keys(_getSymbol).forEach(function (key) {
691
+ if (key === "default" || key === "__esModule") return;
692
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
693
+ if (key in exports && exports[key] === _getSymbol[key]) return;
694
+ Object.defineProperty(exports, key, {
695
+ enumerable: true,
696
+ get: function () {
697
+ return _getSymbol[key];
698
+ }
699
+ });
700
+ });
689
701
  var _consumeSlots = require("./consumeSlots");
690
702
  Object.keys(_consumeSlots).forEach(function (key) {
691
703
  if (key === "default" || key === "__esModule") return;
@@ -64,6 +64,7 @@ export * from "./isDefined.mjs";
64
64
  export * from "./getScale.mjs";
65
65
  export * from "./stacking/index.mjs";
66
66
  export * from "./getCurve.mjs";
67
+ export * from "./getSymbol.mjs";
67
68
  export * from "./consumeSlots.mjs";
68
69
  export * from "./consumeThemeProps.mjs";
69
70
  export * from "./defaultizeMargin.mjs";
@@ -6,10 +6,8 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.getAxisIndex = getAxisIndex;
7
7
  exports.getAxisValue = getAxisValue;
8
8
  var _scaleGuards = require("../../../scaleGuards");
9
- function getAsANumber(value) {
10
- return value instanceof Date ? value.getTime() : value;
11
- }
12
-
9
+ var _getAsNumber = require("../../../getAsNumber");
10
+ var _findClosestIndex = require("../../../findClosestIndex");
13
11
  /**
14
12
  * For a pointer coordinate, this function returns the dataIndex associated.
15
13
  * Returns `-1` if no dataIndex matches.
@@ -21,26 +19,11 @@ function getAxisIndex(axisConfig, pointerValue) {
21
19
  reverse
22
20
  } = axisConfig;
23
21
  if (!(0, _scaleGuards.isOrdinalScale)(scale)) {
24
- const value = scale.invert(pointerValue);
25
22
  if (axisData === undefined) {
26
23
  return -1;
27
24
  }
28
- const valueAsNumber = getAsANumber(value);
29
- const closestIndex = axisData?.findIndex((pointValue, index) => {
30
- const v = getAsANumber(pointValue);
31
- if (v > valueAsNumber) {
32
- if (index === 0 || Math.abs(valueAsNumber - v) <= Math.abs(valueAsNumber - getAsANumber(axisData[index - 1]))) {
33
- return true;
34
- }
35
- }
36
- if (v <= valueAsNumber) {
37
- if (index === axisData.length - 1 || Math.abs(getAsANumber(value) - v) < Math.abs(getAsANumber(value) - getAsANumber(axisData[index + 1]))) {
38
- return true;
39
- }
40
- }
41
- return false;
42
- });
43
- return closestIndex;
25
+ const valueAsNumber = (0, _getAsNumber.getAsNumber)(scale.invert(pointerValue));
26
+ return (0, _findClosestIndex.findClosestIndex)(axisData, valueAsNumber);
44
27
  }
45
28
  const dataIndex = scale.bandwidth() === 0 ? Math.floor((pointerValue - Math.min(...scale.range()) + scale.step() / 2) / scale.step()) : Math.floor((pointerValue - Math.min(...scale.range())) / scale.step());
46
29
  if (dataIndex < 0 || dataIndex >= axisData.length) {
@@ -1,8 +1,6 @@
1
1
  import { isOrdinalScale } from "../../../scaleGuards.mjs";
2
- function getAsANumber(value) {
3
- return value instanceof Date ? value.getTime() : value;
4
- }
5
-
2
+ import { getAsNumber } from "../../../getAsNumber.mjs";
3
+ import { findClosestIndex } from "../../../findClosestIndex.mjs";
6
4
  /**
7
5
  * For a pointer coordinate, this function returns the dataIndex associated.
8
6
  * Returns `-1` if no dataIndex matches.
@@ -14,26 +12,11 @@ export function getAxisIndex(axisConfig, pointerValue) {
14
12
  reverse
15
13
  } = axisConfig;
16
14
  if (!isOrdinalScale(scale)) {
17
- const value = scale.invert(pointerValue);
18
15
  if (axisData === undefined) {
19
16
  return -1;
20
17
  }
21
- const valueAsNumber = getAsANumber(value);
22
- const closestIndex = axisData?.findIndex((pointValue, index) => {
23
- const v = getAsANumber(pointValue);
24
- if (v > valueAsNumber) {
25
- if (index === 0 || Math.abs(valueAsNumber - v) <= Math.abs(valueAsNumber - getAsANumber(axisData[index - 1]))) {
26
- return true;
27
- }
28
- }
29
- if (v <= valueAsNumber) {
30
- if (index === axisData.length - 1 || Math.abs(getAsANumber(value) - v) < Math.abs(getAsANumber(value) - getAsANumber(axisData[index + 1]))) {
31
- return true;
32
- }
33
- }
34
- return false;
35
- });
36
- return closestIndex;
18
+ const valueAsNumber = getAsNumber(scale.invert(pointerValue));
19
+ return findClosestIndex(axisData, valueAsNumber);
37
20
  }
38
21
  const dataIndex = scale.bandwidth() === 0 ? Math.floor((pointerValue - Math.min(...scale.range()) + scale.step() / 2) / scale.step()) : Math.floor((pointerValue - Math.min(...scale.range())) / scale.step());
39
22
  if (dataIndex < 0 || dataIndex >= axisData.length) {
@@ -0,0 +1,30 @@
1
+ import type { SeriesId } from "../../../../../models/seriesType/common.mjs";
2
+ import type { ChartSeriesType } from "../../../../../models/seriesType/config.mjs";
3
+ import type { ProcessedSeries } from "../../../corePlugins/useChartSeries/useChartSeries.types.mjs";
4
+ /**
5
+ * Walk forward (or backward) from `startIndex` and return the first dataIndex
6
+ * whose data point is visible. Returns `null` if every traversed index is hidden.
7
+ *
8
+ * Series-level hidden flags are filtered upstream (see `getNonEmptySeriesArray`),
9
+ * so only per-data-point hidden flags are relevant here. Today only Pie sets a
10
+ * `hidden` flag on individual data items; for other series types the data
11
+ * elements are scalars or objects without that field, and this helper returns
12
+ * the proposed index unchanged.
13
+ */
14
+ export declare function findVisibleDataIndex({
15
+ processedSeries,
16
+ type,
17
+ seriesId,
18
+ startIndex,
19
+ dataLength,
20
+ direction,
21
+ allowCycles
22
+ }: {
23
+ processedSeries: ProcessedSeries<ChartSeriesType>;
24
+ type: ChartSeriesType;
25
+ seriesId: SeriesId;
26
+ startIndex: number;
27
+ dataLength: number;
28
+ direction: 1 | -1;
29
+ allowCycles: boolean;
30
+ }): number | null;
@@ -0,0 +1,30 @@
1
+ import type { SeriesId } from "../../../../../models/seriesType/common.js";
2
+ import type { ChartSeriesType } from "../../../../../models/seriesType/config.js";
3
+ import type { ProcessedSeries } from "../../../corePlugins/useChartSeries/useChartSeries.types.js";
4
+ /**
5
+ * Walk forward (or backward) from `startIndex` and return the first dataIndex
6
+ * whose data point is visible. Returns `null` if every traversed index is hidden.
7
+ *
8
+ * Series-level hidden flags are filtered upstream (see `getNonEmptySeriesArray`),
9
+ * so only per-data-point hidden flags are relevant here. Today only Pie sets a
10
+ * `hidden` flag on individual data items; for other series types the data
11
+ * elements are scalars or objects without that field, and this helper returns
12
+ * the proposed index unchanged.
13
+ */
14
+ export declare function findVisibleDataIndex({
15
+ processedSeries,
16
+ type,
17
+ seriesId,
18
+ startIndex,
19
+ dataLength,
20
+ direction,
21
+ allowCycles
22
+ }: {
23
+ processedSeries: ProcessedSeries<ChartSeriesType>;
24
+ type: ChartSeriesType;
25
+ seriesId: SeriesId;
26
+ startIndex: number;
27
+ dataLength: number;
28
+ direction: 1 | -1;
29
+ allowCycles: boolean;
30
+ }): number | null;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.findVisibleDataIndex = findVisibleDataIndex;
7
+ /**
8
+ * Walk forward (or backward) from `startIndex` and return the first dataIndex
9
+ * whose data point is visible. Returns `null` if every traversed index is hidden.
10
+ *
11
+ * Series-level hidden flags are filtered upstream (see `getNonEmptySeriesArray`),
12
+ * so only per-data-point hidden flags are relevant here. Today only Pie sets a
13
+ * `hidden` flag on individual data items; for other series types the data
14
+ * elements are scalars or objects without that field, and this helper returns
15
+ * the proposed index unchanged.
16
+ */
17
+ function findVisibleDataIndex({
18
+ processedSeries,
19
+ type,
20
+ seriesId,
21
+ startIndex,
22
+ dataLength,
23
+ direction,
24
+ allowCycles
25
+ }) {
26
+ if (dataLength <= 0) {
27
+ return null;
28
+ }
29
+ const seriesItem = processedSeries[type]?.series[seriesId];
30
+ if (seriesItem && 'hidden' in seriesItem && seriesItem.hidden) {
31
+ return null;
32
+ }
33
+ const seriesData = seriesItem?.data;
34
+ const isIndexHidden = idx => {
35
+ if (!seriesData) {
36
+ return false;
37
+ }
38
+ const item = seriesData[idx];
39
+ return typeof item === 'object' && item !== null && 'hidden' in item && Boolean(item.hidden);
40
+ };
41
+ let dataIndex = startIndex;
42
+ for (let attempt = 0; attempt < dataLength; attempt += 1) {
43
+ if (dataIndex >= 0 && dataIndex < dataLength && !isIndexHidden(dataIndex)) {
44
+ return dataIndex;
45
+ }
46
+ if (allowCycles) {
47
+ dataIndex = (dataIndex + direction + dataLength) % dataLength;
48
+ } else {
49
+ const next = dataIndex + direction;
50
+ if (next < 0 || next >= dataLength) {
51
+ return null;
52
+ }
53
+ dataIndex = next;
54
+ }
55
+ }
56
+ return null;
57
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Walk forward (or backward) from `startIndex` and return the first dataIndex
3
+ * whose data point is visible. Returns `null` if every traversed index is hidden.
4
+ *
5
+ * Series-level hidden flags are filtered upstream (see `getNonEmptySeriesArray`),
6
+ * so only per-data-point hidden flags are relevant here. Today only Pie sets a
7
+ * `hidden` flag on individual data items; for other series types the data
8
+ * elements are scalars or objects without that field, and this helper returns
9
+ * the proposed index unchanged.
10
+ */
11
+ export function findVisibleDataIndex({
12
+ processedSeries,
13
+ type,
14
+ seriesId,
15
+ startIndex,
16
+ dataLength,
17
+ direction,
18
+ allowCycles
19
+ }) {
20
+ if (dataLength <= 0) {
21
+ return null;
22
+ }
23
+ const seriesItem = processedSeries[type]?.series[seriesId];
24
+ if (seriesItem && 'hidden' in seriesItem && seriesItem.hidden) {
25
+ return null;
26
+ }
27
+ const seriesData = seriesItem?.data;
28
+ const isIndexHidden = idx => {
29
+ if (!seriesData) {
30
+ return false;
31
+ }
32
+ const item = seriesData[idx];
33
+ return typeof item === 'object' && item !== null && 'hidden' in item && Boolean(item.hidden);
34
+ };
35
+ let dataIndex = startIndex;
36
+ for (let attempt = 0; attempt < dataLength; attempt += 1) {
37
+ if (dataIndex >= 0 && dataIndex < dataLength && !isIndexHidden(dataIndex)) {
38
+ return dataIndex;
39
+ }
40
+ if (allowCycles) {
41
+ dataIndex = (dataIndex + direction + dataLength) % dataLength;
42
+ } else {
43
+ const next = dataIndex + direction;
44
+ if (next < 0 || next >= dataLength) {
45
+ return null;
46
+ }
47
+ dataIndex = next;
48
+ }
49
+ }
50
+ return null;
51
+ }
@@ -7,6 +7,12 @@ exports.getMaxSeriesLength = getMaxSeriesLength;
7
7
  function getMaxSeriesLength(series, availableSeriesTypes) {
8
8
  return Object.keys(series).filter(type => availableSeriesTypes.has(type)).flatMap(type => {
9
9
  const seriesOfType = series[type];
10
- return seriesOfType.seriesOrder.filter(seriesId => seriesOfType.series[seriesId].data.length > 0 && seriesOfType.series[seriesId].data.some(value => value != null)).map(seriesId => seriesOfType.series[seriesId].data.length);
10
+ return seriesOfType.seriesOrder.filter(seriesId => {
11
+ const seriesItem = seriesOfType.series[seriesId];
12
+ if ('hidden' in seriesItem && seriesItem.hidden) {
13
+ return false;
14
+ }
15
+ return seriesItem.data.length > 0 && seriesItem.data.some(value => value != null && !(typeof value === 'object' && 'hidden' in value && value.hidden));
16
+ }).map(seriesId => seriesOfType.series[seriesId].data.length);
11
17
  }).reduce((maxLengths, length) => Math.max(maxLengths, length), 0);
12
18
  }
@@ -1,6 +1,12 @@
1
1
  export function getMaxSeriesLength(series, availableSeriesTypes) {
2
2
  return Object.keys(series).filter(type => availableSeriesTypes.has(type)).flatMap(type => {
3
3
  const seriesOfType = series[type];
4
- return seriesOfType.seriesOrder.filter(seriesId => seriesOfType.series[seriesId].data.length > 0 && seriesOfType.series[seriesId].data.some(value => value != null)).map(seriesId => seriesOfType.series[seriesId].data.length);
4
+ return seriesOfType.seriesOrder.filter(seriesId => {
5
+ const seriesItem = seriesOfType.series[seriesId];
6
+ if ('hidden' in seriesItem && seriesItem.hidden) {
7
+ return false;
8
+ }
9
+ return seriesItem.data.length > 0 && seriesItem.data.some(value => value != null && !(typeof value === 'object' && 'hidden' in value && value.hidden));
10
+ }).map(seriesId => seriesOfType.series[seriesId].data.length);
5
11
  }).reduce((maxLengths, length) => Math.max(maxLengths, length), 0);
6
12
  }
@@ -7,7 +7,13 @@ exports.getNonEmptySeriesArray = getNonEmptySeriesArray;
7
7
  function getNonEmptySeriesArray(series, availableSeriesTypes) {
8
8
  return Object.keys(series).filter(type => availableSeriesTypes.has(type)).flatMap(type => {
9
9
  const seriesOfType = series[type];
10
- return seriesOfType.seriesOrder.filter(seriesId => seriesOfType.series[seriesId].data.length > 0 && seriesOfType.series[seriesId].data.some(value => value != null)).map(seriesId => ({
10
+ return seriesOfType.seriesOrder.filter(seriesId => {
11
+ const seriesItem = seriesOfType.series[seriesId];
12
+ if ('hidden' in seriesItem && seriesItem.hidden) {
13
+ return false;
14
+ }
15
+ return seriesItem.data.length > 0 && seriesItem.data.some(value => value != null);
16
+ }).map(seriesId => ({
11
17
  type,
12
18
  seriesId
13
19
  }));
@@ -1,7 +1,13 @@
1
1
  export function getNonEmptySeriesArray(series, availableSeriesTypes) {
2
2
  return Object.keys(series).filter(type => availableSeriesTypes.has(type)).flatMap(type => {
3
3
  const seriesOfType = series[type];
4
- return seriesOfType.seriesOrder.filter(seriesId => seriesOfType.series[seriesId].data.length > 0 && seriesOfType.series[seriesId].data.some(value => value != null)).map(seriesId => ({
4
+ return seriesOfType.seriesOrder.filter(seriesId => {
5
+ const seriesItem = seriesOfType.series[seriesId];
6
+ if ('hidden' in seriesItem && seriesItem.hidden) {
7
+ return false;
8
+ }
9
+ return seriesItem.data.length > 0 && seriesItem.data.some(value => value != null);
10
+ }).map(seriesId => ({
5
11
  type,
6
12
  seriesId
7
13
  }));
@@ -133,7 +133,8 @@ function computeAxisValue({
133
133
  scaleType: scaleType,
134
134
  scale: finalScale.domain(domain),
135
135
  tickNumber,
136
- colorScale: axis.colorMap && (0, _colorScale.getColorScale)(axis.colorMap)
136
+ colorScale: axis.colorMap && (0, _colorScale.getColorScale)(axis.colorMap),
137
+ isFullCircle
137
138
  });
138
139
  });
139
140
  return {
@@ -126,7 +126,8 @@ export function computeAxisValue({
126
126
  scaleType: scaleType,
127
127
  scale: finalScale.domain(domain),
128
128
  tickNumber,
129
- colorScale: axis.colorMap && getColorScale(axis.colorMap)
129
+ colorScale: axis.colorMap && getColorScale(axis.colorMap),
130
+ isFullCircle
130
131
  });
131
132
  });
132
133
  return {
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
 
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
3
  Object.defineProperty(exports, "__esModule", {
5
4
  value: true
6
5
  });
7
6
  exports.getAxisIndex = getAxisIndex;
8
- var _formatErrorMessage2 = _interopRequireDefault(require("@mui/x-internals/formatErrorMessage"));
9
7
  var _scaleGuards = require("../../../scaleGuards");
8
+ var _getAsNumber = require("../../../getAsNumber");
9
+ var _findClosestIndex = require("../../../findClosestIndex");
10
10
  var _clampAngle = require("../../../clampAngle");
11
11
  /**
12
12
  * For a pointer coordinate, this function returns the value and dataIndex associated.
@@ -19,12 +19,17 @@ function getAxisIndex(axisConfig, pointerValue) {
19
19
  reverse
20
20
  } = axisConfig;
21
21
  if (!(0, _scaleGuards.isOrdinalScale)(scale)) {
22
- throw new Error(process.env.NODE_ENV !== "production" ? 'MUI X Charts: getAxisValue is not implemented for polar continuous axes. ' + 'This function only supports ordinal (band/point) scales.' : (0, _formatErrorMessage2.default)(40));
22
+ if (axisData === undefined) {
23
+ return -1;
24
+ }
25
+ const angle = scale.range()[0] + (0, _clampAngle.clampAngleRad)(pointerValue - scale.range()[0]);
26
+ const valueAsNumber = (0, _getAsNumber.getAsNumber)(scale.invert(angle));
27
+ return (0, _findClosestIndex.findClosestIndex)(axisData, valueAsNumber);
23
28
  }
24
29
  if (!axisData) {
25
30
  return -1;
26
31
  }
27
- const angleGap = (0, _clampAngle.clampAngleRad)(pointerValue - Math.min(...scale.range()));
32
+ const angleGap = (0, _clampAngle.clampAngleRad)(pointerValue - scale.range()[0]);
28
33
  const dataIndex = scale.bandwidth() === 0 ? Math.floor((angleGap + scale.step() / 2) / scale.step()) % axisData.length : Math.floor(angleGap / scale.step());
29
34
  if (dataIndex < 0 || dataIndex >= axisData.length) {
30
35
  return -1;