@mui/x-charts 8.14.0 → 8.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/BarChart/BarChart.js +8 -0
  2. package/BarChart/BarChart.plugins.d.ts +2 -1
  3. package/BarChart/BarChart.plugins.js +2 -1
  4. package/BarChart/useBarChartProps.js +4 -2
  5. package/BarChart/useBarPlotData.js +20 -33
  6. package/CHANGELOG.md +202 -0
  7. package/ChartContainer/ChartContainer.js +8 -0
  8. package/ChartContainer/useChartContainerProps.js +4 -2
  9. package/ChartsBrushOverlay/ChartsBrushOverlay.classes.d.ts +12 -0
  10. package/ChartsBrushOverlay/ChartsBrushOverlay.classes.js +9 -0
  11. package/ChartsBrushOverlay/ChartsBrushOverlay.d.ts +6 -0
  12. package/ChartsBrushOverlay/ChartsBrushOverlay.js +102 -0
  13. package/ChartsBrushOverlay/index.d.ts +4 -0
  14. package/ChartsBrushOverlay/index.js +19 -0
  15. package/ChartsReferenceLine/ChartsReferenceLine.js +1 -1
  16. package/ChartsReferenceLine/ChartsXReferenceLine.js +13 -8
  17. package/ChartsReferenceLine/ChartsYReferenceLine.js +13 -8
  18. package/ChartsReferenceLine/common.d.ts +3 -1
  19. package/ChartsReferenceLine/common.js +3 -1
  20. package/ChartsTooltip/ChartsTooltipContainer.js +20 -2
  21. package/ChartsXAxis/getVisibleLabels.js +45 -25
  22. package/Gauge/Gauge.js +2 -9
  23. package/Gauge/GaugeReferenceArc.d.ts +4 -1
  24. package/Gauge/GaugeReferenceArc.js +12 -3
  25. package/Gauge/GaugeValueArc.d.ts +4 -1
  26. package/Gauge/GaugeValueArc.js +16 -8
  27. package/Gauge/GaugeValueText.js +3 -1
  28. package/LineChart/LineChart.js +8 -0
  29. package/LineChart/LineChart.plugins.d.ts +2 -1
  30. package/LineChart/LineChart.plugins.js +2 -1
  31. package/LineChart/useLineChartProps.js +4 -2
  32. package/ScatterChart/ScatterChart.js +8 -0
  33. package/ScatterChart/ScatterChart.plugins.d.ts +2 -1
  34. package/ScatterChart/ScatterChart.plugins.js +2 -1
  35. package/ScatterChart/seriesConfig/seriesProcessor.js +1 -1
  36. package/ScatterChart/useScatterChartProps.js +5 -3
  37. package/SparkLineChart/SparkLineChart.js +8 -0
  38. package/esm/BarChart/BarChart.js +8 -0
  39. package/esm/BarChart/BarChart.plugins.d.ts +2 -1
  40. package/esm/BarChart/BarChart.plugins.js +2 -1
  41. package/esm/BarChart/useBarChartProps.js +4 -2
  42. package/esm/BarChart/useBarPlotData.js +20 -33
  43. package/esm/ChartContainer/ChartContainer.js +8 -0
  44. package/esm/ChartContainer/useChartContainerProps.js +4 -2
  45. package/esm/ChartsBrushOverlay/ChartsBrushOverlay.classes.d.ts +12 -0
  46. package/esm/ChartsBrushOverlay/ChartsBrushOverlay.classes.js +2 -0
  47. package/esm/ChartsBrushOverlay/ChartsBrushOverlay.d.ts +6 -0
  48. package/esm/ChartsBrushOverlay/ChartsBrushOverlay.js +95 -0
  49. package/esm/ChartsBrushOverlay/index.d.ts +4 -0
  50. package/esm/ChartsBrushOverlay/index.js +2 -0
  51. package/esm/ChartsReferenceLine/ChartsReferenceLine.js +1 -1
  52. package/esm/ChartsReferenceLine/ChartsXReferenceLine.js +14 -9
  53. package/esm/ChartsReferenceLine/ChartsYReferenceLine.js +14 -9
  54. package/esm/ChartsReferenceLine/common.d.ts +3 -1
  55. package/esm/ChartsReferenceLine/common.js +2 -0
  56. package/esm/ChartsTooltip/ChartsTooltipContainer.js +20 -2
  57. package/esm/ChartsXAxis/getVisibleLabels.js +45 -25
  58. package/esm/Gauge/Gauge.js +2 -9
  59. package/esm/Gauge/GaugeReferenceArc.d.ts +4 -1
  60. package/esm/Gauge/GaugeReferenceArc.js +11 -2
  61. package/esm/Gauge/GaugeValueArc.d.ts +4 -1
  62. package/esm/Gauge/GaugeValueArc.js +16 -8
  63. package/esm/Gauge/GaugeValueText.js +3 -1
  64. package/esm/LineChart/LineChart.js +8 -0
  65. package/esm/LineChart/LineChart.plugins.d.ts +2 -1
  66. package/esm/LineChart/LineChart.plugins.js +2 -1
  67. package/esm/LineChart/useLineChartProps.js +4 -2
  68. package/esm/ScatterChart/ScatterChart.js +8 -0
  69. package/esm/ScatterChart/ScatterChart.plugins.d.ts +2 -1
  70. package/esm/ScatterChart/ScatterChart.plugins.js +2 -1
  71. package/esm/ScatterChart/seriesConfig/seriesProcessor.js +1 -1
  72. package/esm/ScatterChart/useScatterChartProps.js +5 -3
  73. package/esm/SparkLineChart/SparkLineChart.js +8 -0
  74. package/esm/hooks/index.d.ts +2 -1
  75. package/esm/hooks/index.js +2 -1
  76. package/esm/hooks/useBrush.d.ts +18 -0
  77. package/esm/hooks/useBrush.js +16 -0
  78. package/esm/index.d.ts +2 -1
  79. package/esm/index.js +2 -1
  80. package/esm/internals/Flatbush.d.ts +63 -0
  81. package/esm/internals/Flatbush.js +468 -0
  82. package/esm/internals/domUtils.d.ts +9 -4
  83. package/esm/internals/domUtils.js +115 -52
  84. package/esm/internals/index.d.ts +1 -0
  85. package/esm/internals/index.js +1 -0
  86. package/esm/internals/plugins/allPlugins.d.ts +4 -3
  87. package/esm/internals/plugins/allPlugins.js +2 -1
  88. package/esm/internals/plugins/corePlugins/useChartInteractionListener/useChartInteractionListener.js +16 -10
  89. package/esm/internals/plugins/corePlugins/useChartInteractionListener/useChartInteractionListener.types.d.ts +2 -2
  90. package/esm/internals/plugins/featurePlugins/useChartBrush/index.d.ts +3 -0
  91. package/esm/internals/plugins/featurePlugins/useChartBrush/index.js +3 -0
  92. package/esm/internals/plugins/featurePlugins/useChartBrush/useChartBrush.d.ts +3 -0
  93. package/esm/internals/plugins/featurePlugins/useChartBrush/useChartBrush.js +109 -0
  94. package/esm/internals/plugins/featurePlugins/useChartBrush/useChartBrush.selectors.d.ts +82 -0
  95. package/esm/internals/plugins/featurePlugins/useChartBrush/useChartBrush.selectors.js +75 -0
  96. package/esm/internals/plugins/featurePlugins/useChartBrush/useChartBrush.types.d.ts +72 -0
  97. package/esm/internals/plugins/featurePlugins/useChartBrush/useChartBrush.types.js +1 -0
  98. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/createZoomLookup.js +3 -2
  99. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/defaultizeAxis.js +2 -2
  100. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/defaultizeZoom.d.ts +2 -1
  101. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/defaultizeZoom.js +8 -3
  102. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/getAxisValue.d.ts +6 -2
  103. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/getAxisValue.js +3 -6
  104. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.types.d.ts +3 -1
  105. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.d.ts +19 -0
  106. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.js +41 -0
  107. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianHighlight.selectors.d.ts +4 -4
  108. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianHighlight.selectors.js +13 -6
  109. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianInteraction.selectors.js +4 -1
  110. package/esm/internals/plugins/featurePlugins/useChartClosestPoint/findClosestPoints.d.ts +5 -0
  111. package/esm/internals/plugins/featurePlugins/useChartClosestPoint/findClosestPoints.js +33 -0
  112. package/esm/internals/plugins/featurePlugins/useChartClosestPoint/useChartClosestPoint.js +40 -81
  113. package/esm/internals/plugins/utils/selectors.d.ts +1 -1
  114. package/esm/locales/elGR.js +97 -99
  115. package/esm/models/seriesType/scatter.d.ts +2 -0
  116. package/esm/tests/constants.js +1 -0
  117. package/esm/themeAugmentation/components.d.ts +3 -0
  118. package/esm/themeAugmentation/overrides.d.ts +2 -0
  119. package/hooks/index.d.ts +2 -1
  120. package/hooks/index.js +12 -0
  121. package/hooks/useBrush.d.ts +18 -0
  122. package/hooks/useBrush.js +21 -0
  123. package/index.d.ts +2 -1
  124. package/index.js +13 -1
  125. package/internals/Flatbush.d.ts +63 -0
  126. package/internals/Flatbush.js +477 -0
  127. package/internals/domUtils.d.ts +9 -4
  128. package/internals/domUtils.js +119 -54
  129. package/internals/index.d.ts +1 -0
  130. package/internals/index.js +12 -0
  131. package/internals/plugins/allPlugins.d.ts +4 -3
  132. package/internals/plugins/allPlugins.js +2 -1
  133. package/internals/plugins/corePlugins/useChartInteractionListener/useChartInteractionListener.js +16 -10
  134. package/internals/plugins/corePlugins/useChartInteractionListener/useChartInteractionListener.types.d.ts +2 -2
  135. package/internals/plugins/featurePlugins/useChartBrush/index.d.ts +3 -0
  136. package/internals/plugins/featurePlugins/useChartBrush/index.js +38 -0
  137. package/internals/plugins/featurePlugins/useChartBrush/useChartBrush.d.ts +3 -0
  138. package/internals/plugins/featurePlugins/useChartBrush/useChartBrush.js +117 -0
  139. package/internals/plugins/featurePlugins/useChartBrush/useChartBrush.selectors.d.ts +82 -0
  140. package/internals/plugins/featurePlugins/useChartBrush/useChartBrush.selectors.js +82 -0
  141. package/internals/plugins/featurePlugins/useChartBrush/useChartBrush.types.d.ts +72 -0
  142. package/internals/plugins/featurePlugins/useChartBrush/useChartBrush.types.js +5 -0
  143. package/internals/plugins/featurePlugins/useChartCartesianAxis/createZoomLookup.js +3 -2
  144. package/internals/plugins/featurePlugins/useChartCartesianAxis/defaultizeAxis.js +2 -2
  145. package/internals/plugins/featurePlugins/useChartCartesianAxis/defaultizeZoom.d.ts +2 -1
  146. package/internals/plugins/featurePlugins/useChartCartesianAxis/defaultizeZoom.js +8 -3
  147. package/internals/plugins/featurePlugins/useChartCartesianAxis/getAxisValue.d.ts +6 -2
  148. package/internals/plugins/featurePlugins/useChartCartesianAxis/getAxisValue.js +3 -6
  149. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.types.d.ts +3 -1
  150. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.d.ts +19 -0
  151. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.js +43 -1
  152. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianHighlight.selectors.d.ts +4 -4
  153. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianHighlight.selectors.js +13 -6
  154. package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianInteraction.selectors.js +4 -1
  155. package/internals/plugins/featurePlugins/useChartClosestPoint/findClosestPoints.d.ts +5 -0
  156. package/internals/plugins/featurePlugins/useChartClosestPoint/findClosestPoints.js +39 -0
  157. package/internals/plugins/featurePlugins/useChartClosestPoint/useChartClosestPoint.js +39 -80
  158. package/internals/plugins/utils/selectors.d.ts +1 -1
  159. package/locales/elGR.js +97 -99
  160. package/models/seriesType/scatter.d.ts +2 -0
  161. package/package.json +5 -4
  162. package/tests/constants.js +7 -0
  163. package/themeAugmentation/components.d.ts +3 -0
  164. package/themeAugmentation/overrides.d.ts +2 -0
@@ -2,7 +2,7 @@
2
2
 
3
3
  import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
5
- const _excluded = ["xAxis", "yAxis", "series", "width", "height", "margin", "colors", "dataset", "sx", "axisHighlight", "grid", "children", "slots", "slotProps", "skipAnimation", "loading", "layout", "onItemClick", "highlightedItem", "onHighlightChange", "borderRadius", "barLabel", "className", "hideLegend", "showToolbar"];
5
+ const _excluded = ["xAxis", "yAxis", "series", "width", "height", "margin", "colors", "dataset", "sx", "axisHighlight", "grid", "children", "slots", "slotProps", "skipAnimation", "loading", "layout", "onItemClick", "highlightedItem", "onHighlightChange", "borderRadius", "barLabel", "className", "hideLegend", "showToolbar", "brushConfig"];
6
6
  import * as React from 'react';
7
7
  import useId from '@mui/utils/useId';
8
8
  import { DEFAULT_X_AXIS_KEY, DEFAULT_Y_AXIS_KEY } from "../constants/index.js";
@@ -39,7 +39,8 @@ export const useBarChartProps = props => {
39
39
  onHighlightChange,
40
40
  borderRadius,
41
41
  barLabel,
42
- className
42
+ className,
43
+ brushConfig
43
44
  } = props,
44
45
  other = _objectWithoutPropertiesLoose(props, _excluded);
45
46
  const id = useId();
@@ -96,6 +97,7 @@ export const useBarChartProps = props => {
96
97
  disableAxisListener: slotProps?.tooltip?.trigger !== 'axis' && axisHighlight?.x === 'none' && axisHighlight?.y === 'none',
97
98
  className,
98
99
  skipAnimation,
100
+ brushConfig,
99
101
  plugins: BAR_CHART_PLUGINS
100
102
  });
101
103
  const barPlotProps = {
@@ -29,6 +29,7 @@ export function useBarPlotData(drawingArea, xAxes, yAxes) {
29
29
  const xAxisConfig = xAxes[xAxisId];
30
30
  const yAxisConfig = yAxes[yAxisId];
31
31
  const verticalLayout = series[seriesId].layout === 'vertical';
32
+ const reverse = (verticalLayout ? yAxisConfig.reverse : xAxisConfig.reverse) ?? false;
32
33
  checkScaleErrors(verticalLayout, seriesId, series[seriesId], xAxisId, xAxes, yAxisId, yAxes);
33
34
  const baseScaleConfig = verticalLayout ? xAxisConfig : yAxisConfig;
34
35
  const xScale = xAxisConfig.scale;
@@ -50,19 +51,20 @@ export function useBarPlotData(drawingArea, xAxes, yAxes) {
50
51
  layout,
51
52
  minBarSize
52
53
  } = series[seriesId];
53
- const seriesDataPoints = baseScaleConfig.data.map((baseValue, dataIndex) => {
54
- if (currentSeriesData[dataIndex] == null) {
55
- return null;
54
+ const seriesDataPoints = [];
55
+ for (let dataIndex = 0; dataIndex < baseScaleConfig.data.length; dataIndex += 1) {
56
+ const baseValue = baseScaleConfig.data[dataIndex];
57
+ const seriesValue = currentSeriesData[dataIndex];
58
+ if (seriesValue == null) {
59
+ continue;
56
60
  }
57
61
  const values = stackedData[dataIndex];
58
62
  const valueCoordinates = values.map(v => verticalLayout ? yScale(v) : xScale(v));
59
63
  const minValueCoord = Math.round(Math.min(...valueCoordinates));
60
64
  const maxValueCoord = Math.round(Math.max(...valueCoordinates));
61
65
  const stackId = series[seriesId].stack;
62
- const {
63
- barSize,
64
- startCoordinate
65
- } = getValueCoordinate(verticalLayout, minValueCoord, maxValueCoord, currentSeriesData[dataIndex], minBarSize);
66
+ const barSize = seriesValue === 0 ? 0 : Math.max(minBarSize, maxValueCoord - minValueCoord);
67
+ const startCoordinate = shouldInvertStartCoordinate(verticalLayout, seriesValue, reverse) ? maxValueCoord - barSize : minValueCoord;
66
68
  const result = {
67
69
  seriesId,
68
70
  dataIndex,
@@ -78,7 +80,7 @@ export function useBarPlotData(drawingArea, xAxes, yAxes) {
78
80
  maskId: `${chartId}_${stackId || seriesId}_${groupIndex}_${dataIndex}`
79
81
  };
80
82
  if (result.x > xMax || result.x + result.width < xMin || result.y > yMax || result.y + result.height < yMin) {
81
- return null;
83
+ continue;
82
84
  }
83
85
  if (!masks[result.maskId]) {
84
86
  masks[result.maskId] = {
@@ -99,10 +101,11 @@ export function useBarPlotData(drawingArea, xAxes, yAxes) {
99
101
  mask.height = result.layout === 'vertical' ? mask.height + result.height : result.height;
100
102
  mask.x = Math.min(mask.x === 0 ? Infinity : mask.x, result.x);
101
103
  mask.y = Math.min(mask.y === 0 ? Infinity : mask.y, result.y);
102
- mask.hasNegative = mask.hasNegative || (result.value ?? 0) < 0;
103
- mask.hasPositive = mask.hasPositive || (result.value ?? 0) > 0;
104
- return result;
105
- }).filter(rectangle => rectangle !== null);
104
+ const value = result.value ?? 0;
105
+ mask.hasNegative = mask.hasNegative || (reverse ? value > 0 : value < 0);
106
+ mask.hasPositive = mask.hasPositive || (reverse ? value < 0 : value > 0);
107
+ seriesDataPoints.push(result);
108
+ }
106
109
  return {
107
110
  seriesId,
108
111
  data: seriesDataPoints
@@ -142,25 +145,9 @@ function getBandSize({
142
145
  offset
143
146
  };
144
147
  }
145
- function getValueCoordinate(isVertical, minValueCoord, maxValueCoord, baseValue, minBarSize) {
146
- if (baseValue === 0 || baseValue == null) {
147
- return {
148
- barSize: 0,
149
- startCoordinate: minValueCoord
150
- };
151
- }
152
- const isSizeLessThanMin = maxValueCoord - minValueCoord < minBarSize;
153
- const barSize = isSizeLessThanMin ? minBarSize : maxValueCoord - minValueCoord;
154
- const isVerticalAndPositive = isVertical && baseValue >= 0;
155
- const isHorizontalAndNegative = !isVertical && baseValue < 0;
156
- if (isSizeLessThanMin && (isVerticalAndPositive || isHorizontalAndNegative)) {
157
- return {
158
- barSize,
159
- startCoordinate: maxValueCoord - barSize
160
- };
161
- }
162
- return {
163
- barSize,
164
- startCoordinate: minValueCoord
165
- };
148
+ function shouldInvertStartCoordinate(verticalLayout, baseValue, reverse) {
149
+ const isVerticalAndPositive = verticalLayout && baseValue > 0;
150
+ const isHorizontalAndNegative = !verticalLayout && baseValue < 0;
151
+ const invertStartCoordinate = isVerticalAndPositive || isHorizontalAndNegative;
152
+ return reverse ? !invertStartCoordinate : invertStartCoordinate;
166
153
  }
@@ -54,6 +54,14 @@ process.env.NODE_ENV !== "production" ? ChartContainer.propTypes = {
54
54
  apiRef: PropTypes.shape({
55
55
  current: PropTypes.object
56
56
  }),
57
+ /**
58
+ * Configuration for the brush interaction.
59
+ */
60
+ brushConfig: PropTypes.shape({
61
+ enabled: PropTypes.bool,
62
+ preventHighlight: PropTypes.bool,
63
+ preventTooltip: PropTypes.bool
64
+ }),
57
65
  children: PropTypes.node,
58
66
  className: PropTypes.string,
59
67
  /**
@@ -2,7 +2,7 @@
2
2
 
3
3
  import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
5
- const _excluded = ["width", "height", "margin", "children", "series", "colors", "dataset", "desc", "onAxisClick", "highlightedAxis", "onHighlightedAxisChange", "disableVoronoi", "voronoiMaxRadius", "onItemClick", "disableAxisListener", "highlightedItem", "onHighlightChange", "sx", "title", "xAxis", "yAxis", "zAxis", "rotationAxis", "radiusAxis", "skipAnimation", "seriesConfig", "plugins", "localeText", "slots", "slotProps", "experimentalFeatures", "enableKeyboardNavigation"];
5
+ const _excluded = ["width", "height", "margin", "children", "series", "colors", "dataset", "desc", "onAxisClick", "highlightedAxis", "onHighlightedAxisChange", "disableVoronoi", "voronoiMaxRadius", "onItemClick", "disableAxisListener", "highlightedItem", "onHighlightChange", "sx", "title", "xAxis", "yAxis", "zAxis", "rotationAxis", "radiusAxis", "skipAnimation", "seriesConfig", "plugins", "localeText", "slots", "slotProps", "experimentalFeatures", "enableKeyboardNavigation", "brushConfig"];
6
6
  import { DEFAULT_PLUGINS } from "../internals/plugins/allPlugins.js";
7
7
  export const useChartContainerProps = (props, ref) => {
8
8
  const _ref = props,
@@ -38,7 +38,8 @@ export const useChartContainerProps = (props, ref) => {
38
38
  slots,
39
39
  slotProps,
40
40
  experimentalFeatures,
41
- enableKeyboardNavigation
41
+ enableKeyboardNavigation,
42
+ brushConfig
42
43
  } = _ref,
43
44
  other = _objectWithoutPropertiesLoose(_ref, _excluded);
44
45
  const chartsSurfaceProps = _extends({
@@ -73,6 +74,7 @@ export const useChartContainerProps = (props, ref) => {
73
74
  seriesConfig,
74
75
  experimentalFeatures,
75
76
  enableKeyboardNavigation,
77
+ brushConfig,
76
78
  plugins: plugins ?? DEFAULT_PLUGINS,
77
79
  slots,
78
80
  slotProps
@@ -0,0 +1,12 @@
1
+ export interface BrushOverlayClasses {
2
+ /** Styles applied to the root element. */
3
+ root: string;
4
+ /** Styles applied to the brush lines. */
5
+ rect: string;
6
+ /** Styles applied when the brush is selecting the x axis. */
7
+ x: string;
8
+ /** Styles applied when the brush is selecting the y axis. */
9
+ y: string;
10
+ }
11
+ export type BrushOverlayClassKey = keyof BrushOverlayClasses;
12
+ export declare const brushOverlayClasses: BrushOverlayClasses;
@@ -0,0 +1,2 @@
1
+ import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
2
+ export const brushOverlayClasses = generateUtilityClasses('MuiChartsBrushOverlay', ['root', 'rect', 'x', 'y']);
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+ export interface ChartsBrushOverlayProps {}
3
+ /**
4
+ * Component that renders visual feedback during brush interaction
5
+ */
6
+ export declare function ChartsBrushOverlay(props: ChartsBrushOverlayProps): React.JSX.Element | null;
@@ -0,0 +1,95 @@
1
+ 'use client';
2
+
3
+ import _extends from "@babel/runtime/helpers/esm/extends";
4
+ import * as React from 'react';
5
+ import clsx from 'clsx';
6
+ import { useTheme } from '@mui/material/styles';
7
+ import { brushOverlayClasses } from "./ChartsBrushOverlay.classes.js";
8
+ import { selectorChartDrawingArea } from "../internals/plugins/corePlugins/useChartDimensions/index.js";
9
+ import { selectorBrushStartX, selectorBrushStartY, selectorBrushCurrentX, selectorBrushCurrentY, selectorBrushConfig } from "../internals/plugins/featurePlugins/useChartBrush/index.js";
10
+ import { useSelector } from "../internals/store/useSelector.js";
11
+ import { useStore } from "../internals/store/useStore.js";
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ function BrushRect(props) {
14
+ return /*#__PURE__*/_jsx("rect", _extends({
15
+ className: brushOverlayClasses.rect,
16
+ strokeWidth: 1,
17
+ fillOpacity: 0.2,
18
+ pointerEvents: 'none'
19
+ }, props));
20
+ }
21
+ /**
22
+ * Component that renders visual feedback during brush interaction
23
+ */
24
+ export function ChartsBrushOverlay(props) {
25
+ const store = useStore();
26
+ const drawingArea = useSelector(store, selectorChartDrawingArea);
27
+ const theme = useTheme();
28
+ const brushStartX = useSelector(store, selectorBrushStartX);
29
+ const brushStartY = useSelector(store, selectorBrushStartY);
30
+ const brushCurrentX = useSelector(store, selectorBrushCurrentX);
31
+ const brushCurrentY = useSelector(store, selectorBrushCurrentY);
32
+ const brushConfig = useSelector(store, selectorBrushConfig);
33
+ if (brushStartX === null || brushStartY === null || brushCurrentX === null || brushCurrentY === null) {
34
+ return null;
35
+ }
36
+ const {
37
+ left,
38
+ top,
39
+ width,
40
+ height
41
+ } = drawingArea;
42
+
43
+ // Clamp coordinates to drawing area
44
+ const clampX = x => Math.max(left, Math.min(left + width, x));
45
+ const clampY = y => Math.max(top, Math.min(top + height, y));
46
+ const startX = clampX(brushStartX);
47
+ const startY = clampY(brushStartY);
48
+ const currentX = clampX(brushCurrentX);
49
+ const currentY = clampY(brushCurrentY);
50
+ const rectColor = theme.palette.mode === 'light' ? theme.palette.common.black : theme.palette.common.white;
51
+
52
+ // For scatter charts, show only the rectangle without guide lines
53
+ if (brushConfig === 'xy') {
54
+ const rectWidth = currentX - startX;
55
+ const rectHeight = currentY - startY;
56
+ return /*#__PURE__*/_jsx("g", {
57
+ className: clsx(brushOverlayClasses.root, brushOverlayClasses.x, brushOverlayClasses.y),
58
+ children: /*#__PURE__*/_jsx(BrushRect, _extends({
59
+ fill: rectColor,
60
+ x: rectWidth >= 0 ? startX : currentX,
61
+ y: rectHeight >= 0 ? startY : currentY,
62
+ width: Math.abs(rectWidth),
63
+ height: Math.abs(rectHeight)
64
+ }, props))
65
+ });
66
+ }
67
+ if (brushConfig === 'y') {
68
+ const minY = Math.min(startY, currentY);
69
+ const maxY = Math.max(startY, currentY);
70
+ const rectHeight = maxY - minY;
71
+ return /*#__PURE__*/_jsx("g", {
72
+ className: clsx(brushOverlayClasses.root, brushOverlayClasses.y),
73
+ children: /*#__PURE__*/_jsx(BrushRect, _extends({
74
+ fill: rectColor,
75
+ x: left,
76
+ y: minY,
77
+ width: width,
78
+ height: rectHeight
79
+ }, props))
80
+ });
81
+ }
82
+ const minX = Math.min(startX, currentX);
83
+ const maxX = Math.max(startX, currentX);
84
+ const rectWidth = maxX - minX;
85
+ return /*#__PURE__*/_jsx("g", {
86
+ className: clsx(brushOverlayClasses.root, brushOverlayClasses.x),
87
+ children: /*#__PURE__*/_jsx(BrushRect, _extends({
88
+ fill: rectColor,
89
+ x: minX,
90
+ y: top,
91
+ width: rectWidth,
92
+ height: height
93
+ }, props))
94
+ });
95
+ }
@@ -0,0 +1,4 @@
1
+ export { ChartsBrushOverlay } from "./ChartsBrushOverlay.js";
2
+ export type { ChartsBrushOverlayProps } from "./ChartsBrushOverlay.js";
3
+ export { brushOverlayClasses } from "./ChartsBrushOverlay.classes.js";
4
+ export type { BrushOverlayClasses, BrushOverlayClassKey } from "./ChartsBrushOverlay.classes.js";
@@ -0,0 +1,2 @@
1
+ export { ChartsBrushOverlay } from "./ChartsBrushOverlay.js";
2
+ export { brushOverlayClasses } from "./ChartsBrushOverlay.classes.js";
@@ -56,7 +56,7 @@ process.env.NODE_ENV !== "production" ? ChartsReferenceLine.propTypes = {
56
56
  /**
57
57
  * Additional space around the label in px.
58
58
  * Can be a number or an object `{ x, y }` to distinguish space with the reference line and space with axes.
59
- * @default 5
59
+ * @default { x: 0, y: 5 } on a horizontal line and { x: 5, y: 0 } on a vertical line.
60
60
  */
61
61
  spacing: PropTypes.oneOfType([PropTypes.number, PropTypes.shape({
62
62
  x: PropTypes.number,
@@ -6,19 +6,24 @@ import PropTypes from 'prop-types';
6
6
  import composeClasses from '@mui/utils/composeClasses';
7
7
  import { warnOnce } from '@mui/x-internals/warning';
8
8
  import { useDrawingArea, useXScale } from "../hooks/index.js";
9
- import { ReferenceLineRoot } from "./common.js";
9
+ import { DEFAULT_SPACING, DEFAULT_SPACING_MIDDLE_OTHER_AXIS, ReferenceLineRoot } from "./common.js";
10
10
  import { ChartsText } from "../ChartsText/index.js";
11
11
  import { getReferenceLineUtilityClass } from "./chartsReferenceLineClasses.js";
12
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  const getTextParams = ({
14
14
  top,
15
15
  height,
16
- spacingY,
16
+ spacing,
17
+ position,
17
18
  labelAlign = 'middle'
18
19
  }) => {
20
+ const defaultSpacingOtherAxis = labelAlign === 'middle' ? DEFAULT_SPACING_MIDDLE_OTHER_AXIS : DEFAULT_SPACING;
21
+ const spacingX = (typeof spacing === 'object' ? spacing.x : spacing) ?? DEFAULT_SPACING;
22
+ const spacingY = (typeof spacing === 'object' ? spacing.y : defaultSpacingOtherAxis) ?? defaultSpacingOtherAxis;
19
23
  switch (labelAlign) {
20
24
  case 'start':
21
25
  return {
26
+ x: position + spacingX,
22
27
  y: top + spacingY,
23
28
  style: {
24
29
  dominantBaseline: 'hanging',
@@ -27,6 +32,7 @@ const getTextParams = ({
27
32
  };
28
33
  case 'end':
29
34
  return {
35
+ x: position + spacingX,
30
36
  y: top + height - spacingY,
31
37
  style: {
32
38
  dominantBaseline: 'auto',
@@ -35,7 +41,8 @@ const getTextParams = ({
35
41
  };
36
42
  default:
37
43
  return {
38
- y: top + height / 2,
44
+ x: position + spacingX,
45
+ y: top + height / 2 + spacingY,
39
46
  style: {
40
47
  dominantBaseline: 'central',
41
48
  textAnchor: 'start'
@@ -54,9 +61,9 @@ function ChartsXReferenceLine(props) {
54
61
  const {
55
62
  x,
56
63
  label = '',
57
- spacing = 5,
64
+ spacing,
58
65
  classes: inClasses,
59
- labelAlign,
66
+ labelAlign = 'middle',
60
67
  lineStyle,
61
68
  labelStyle,
62
69
  axisId
@@ -75,16 +82,14 @@ function ChartsXReferenceLine(props) {
75
82
  }
76
83
  const d = `M ${xPosition} ${top} l 0 ${height}`;
77
84
  const classes = getXReferenceLineClasses(inClasses);
78
- const spacingX = typeof spacing === 'object' ? spacing.x ?? 0 : spacing;
79
- const spacingY = typeof spacing === 'object' ? spacing.y ?? 0 : spacing;
80
85
  const textParams = _extends({
81
- x: xPosition + spacingX,
82
86
  text: label,
83
87
  fontSize: 12
84
88
  }, getTextParams({
85
89
  top,
86
90
  height,
87
- spacingY,
91
+ spacing,
92
+ position: xPosition,
88
93
  labelAlign
89
94
  }), {
90
95
  className: classes.label
@@ -6,19 +6,24 @@ import PropTypes from 'prop-types';
6
6
  import composeClasses from '@mui/utils/composeClasses';
7
7
  import { warnOnce } from '@mui/x-internals/warning';
8
8
  import { useDrawingArea, useYScale } from "../hooks/index.js";
9
- import { ReferenceLineRoot } from "./common.js";
9
+ import { DEFAULT_SPACING, DEFAULT_SPACING_MIDDLE_OTHER_AXIS, ReferenceLineRoot } from "./common.js";
10
10
  import { ChartsText } from "../ChartsText/index.js";
11
11
  import { getReferenceLineUtilityClass } from "./chartsReferenceLineClasses.js";
12
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  const getTextParams = ({
14
14
  left,
15
15
  width,
16
- spacingX,
16
+ spacing,
17
+ position,
17
18
  labelAlign = 'middle'
18
19
  }) => {
20
+ const defaultSpacingOtherAxis = labelAlign === 'middle' ? DEFAULT_SPACING_MIDDLE_OTHER_AXIS : DEFAULT_SPACING;
21
+ const spacingX = (typeof spacing === 'object' ? spacing.x : defaultSpacingOtherAxis) ?? defaultSpacingOtherAxis;
22
+ const spacingY = (typeof spacing === 'object' ? spacing.y : spacing) ?? DEFAULT_SPACING;
19
23
  switch (labelAlign) {
20
24
  case 'start':
21
25
  return {
26
+ y: position - spacingY,
22
27
  x: left + spacingX,
23
28
  style: {
24
29
  dominantBaseline: 'auto',
@@ -27,6 +32,7 @@ const getTextParams = ({
27
32
  };
28
33
  case 'end':
29
34
  return {
35
+ y: position - spacingY,
30
36
  x: left + width - spacingX,
31
37
  style: {
32
38
  dominantBaseline: 'auto',
@@ -35,7 +41,8 @@ const getTextParams = ({
35
41
  };
36
42
  default:
37
43
  return {
38
- x: left + width / 2,
44
+ y: position - spacingY,
45
+ x: left + width / 2 + spacingX,
39
46
  style: {
40
47
  dominantBaseline: 'auto',
41
48
  textAnchor: 'middle'
@@ -54,9 +61,9 @@ function ChartsYReferenceLine(props) {
54
61
  const {
55
62
  y,
56
63
  label = '',
57
- spacing = 5,
64
+ spacing,
58
65
  classes: inClasses,
59
- labelAlign,
66
+ labelAlign = 'middle',
60
67
  lineStyle,
61
68
  labelStyle,
62
69
  axisId
@@ -75,16 +82,14 @@ function ChartsYReferenceLine(props) {
75
82
  }
76
83
  const d = `M ${left} ${yPosition} l ${width} 0`;
77
84
  const classes = getYReferenceLineClasses(inClasses);
78
- const spacingX = typeof spacing === 'object' ? spacing.x ?? 0 : spacing;
79
- const spacingY = typeof spacing === 'object' ? spacing.y ?? 0 : spacing;
80
85
  const textParams = _extends({
81
- y: yPosition - spacingY,
82
86
  text: label,
83
87
  fontSize: 12
84
88
  }, getTextParams({
85
89
  left,
86
90
  width,
87
- spacingX,
91
+ spacing,
92
+ position: yPosition,
88
93
  labelAlign
89
94
  }), {
90
95
  className: classes.label
@@ -1,6 +1,8 @@
1
1
  import { ChartsReferenceLineClasses } from "./chartsReferenceLineClasses.js";
2
2
  import { ChartsTextStyle } from "../ChartsText/index.js";
3
3
  import { AxisId } from "../models/axis.js";
4
+ export declare const DEFAULT_SPACING = 5;
5
+ export declare const DEFAULT_SPACING_MIDDLE_OTHER_AXIS = 0;
4
6
  export type CommonChartsReferenceLineProps = {
5
7
  /**
6
8
  * The alignment if the label is in the chart drawing area.
@@ -14,7 +16,7 @@ export type CommonChartsReferenceLineProps = {
14
16
  /**
15
17
  * Additional space around the label in px.
16
18
  * Can be a number or an object `{ x, y }` to distinguish space with the reference line and space with axes.
17
- * @default 5
19
+ * @default { x: 0, y: 5 } on a horizontal line and { x: 5, y: 0 } on a vertical line.
18
20
  */
19
21
  spacing?: number | {
20
22
  x?: number;
@@ -1,6 +1,8 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import { styled } from '@mui/material/styles';
3
3
  import { referenceLineClasses } from "./chartsReferenceLineClasses.js";
4
+ export const DEFAULT_SPACING = 5;
5
+ export const DEFAULT_SPACING_MIDDLE_OTHER_AXIS = 0;
4
6
  export const ReferenceLineRoot = styled('g')(({
5
7
  theme
6
8
  }) => ({
@@ -20,8 +20,10 @@ import { selectorChartsInteractionAxisTooltip } from "../internals/plugins/featu
20
20
  import { selectorChartsInteractionPolarAxisTooltip } from "../internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarInteraction.selectors.js";
21
21
  import { useAxisSystem } from "../hooks/useAxisSystem.js";
22
22
  import { useSvgRef } from "../hooks/index.js";
23
+ import { selectorBrushShouldPreventTooltip } from "../internals/plugins/featurePlugins/useChartBrush/index.js";
24
+ import { createSelector } from "../internals/plugins/utils/selectors.js";
23
25
  import { jsx as _jsx } from "react/jsx-runtime";
24
- const noAxis = () => false;
26
+ const selectorReturnFalse = () => false;
25
27
  const ChartsTooltipRoot = styled(Popper, {
26
28
  name: 'MuiChartsTooltip',
27
29
  slot: 'Root'
@@ -31,6 +33,21 @@ const ChartsTooltipRoot = styled(Popper, {
31
33
  pointerEvents: 'none',
32
34
  zIndex: theme.zIndex.modal
33
35
  }));
36
+ const selectorSelectIsOpenSelector = createSelector([selectorBrushShouldPreventTooltip, (_, trigger) => trigger, (_, __, axisSystem) => axisSystem], (shouldPreventBecauseOfBrush, trigger, axisSystem) => {
37
+ if (shouldPreventBecauseOfBrush) {
38
+ return selectorReturnFalse;
39
+ }
40
+ if (trigger === 'item') {
41
+ return selectorChartsInteractionItemIsDefined;
42
+ }
43
+ if (axisSystem === 'polar') {
44
+ return selectorChartsInteractionPolarAxisTooltip;
45
+ }
46
+ if (axisSystem === 'cartesian') {
47
+ return selectorChartsInteractionAxisTooltip;
48
+ }
49
+ return selectorReturnFalse;
50
+ });
34
51
 
35
52
  /**
36
53
  * Demos:
@@ -63,7 +80,8 @@ function ChartsTooltipContainer(inProps) {
63
80
  }));
64
81
  const axisSystem = useAxisSystem();
65
82
  const store = useStore();
66
- const isOpen = useSelector(store, trigger === 'axis' ? axisSystem === 'polar' && selectorChartsInteractionPolarAxisTooltip || axisSystem === 'cartesian' && selectorChartsInteractionAxisTooltip || noAxis : selectorChartsInteractionItemIsDefined);
83
+ const isOpenSelector = useSelector(store, selectorSelectIsOpenSelector, [trigger, axisSystem]);
84
+ const isOpen = useSelector(store, isOpenSelector);
67
85
  React.useEffect(() => {
68
86
  const element = svgRef.current;
69
87
  if (element === null) {
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { getMinXTranslation } from "../internals/geometry.js";
4
- import { getWordsByLines } from "../internals/getWordsByLines.js";
4
+ import { batchMeasureStrings } from "../internals/domUtils.js";
5
5
 
6
6
  /* Returns a set of indices of the tick labels that should be visible. */
7
7
  export function getVisibleLabels(xTicks, {
@@ -12,23 +12,6 @@ export function getVisibleLabels(xTicks, {
12
12
  isMounted,
13
13
  isXInside
14
14
  }) {
15
- const getTickLabelSize = tick => {
16
- if (!isMounted || tick.formattedValue === undefined) {
17
- return {
18
- width: 0,
19
- height: 0
20
- };
21
- }
22
- const tickSizes = getWordsByLines({
23
- style,
24
- needsComputation: true,
25
- text: tick.formattedValue
26
- });
27
- return {
28
- width: Math.max(...tickSizes.map(size => size.width)),
29
- height: Math.max(tickSizes.length * tickSizes[0].height)
30
- };
31
- };
32
15
  if (typeof tickLabelInterval === 'function') {
33
16
  return new Set(xTicks.filter((item, index) => tickLabelInterval(item.value, index)));
34
17
  }
@@ -36,7 +19,7 @@ export function getVisibleLabels(xTicks, {
36
19
  // Filter label to avoid overlap
37
20
  let previousTextLimit = 0;
38
21
  const direction = reverse ? -1 : 1;
39
- return new Set(xTicks.filter((item, labelIndex) => {
22
+ const candidateTickLabels = xTicks.filter(item => {
40
23
  const {
41
24
  offset,
42
25
  labelOffset,
@@ -46,18 +29,25 @@ export function getVisibleLabels(xTicks, {
46
29
  return false;
47
30
  }
48
31
  const textPosition = offset + labelOffset;
32
+ return isXInside(textPosition);
33
+ });
34
+ const sizeMap = measureTickLabels(candidateTickLabels, style);
35
+ return new Set(candidateTickLabels.filter((item, labelIndex) => {
36
+ const {
37
+ offset,
38
+ labelOffset
39
+ } = item;
40
+ const textPosition = offset + labelOffset;
49
41
  if (labelIndex > 0 && direction * textPosition < direction * (previousTextLimit + tickLabelMinGap)) {
50
42
  return false;
51
43
  }
52
- if (!isXInside(textPosition)) {
53
- return false;
54
- }
55
-
56
- /* Measuring text width is expensive, so we need to delay it as much as possible to improve performance. */
57
44
  const {
58
45
  width,
59
46
  height
60
- } = getTickLabelSize(item);
47
+ } = isMounted ? getTickLabelSize(sizeMap, item) : {
48
+ width: 0,
49
+ height: 0
50
+ };
61
51
  const distance = getMinXTranslation(width, height, style?.angle);
62
52
  const currentTextLimit = textPosition - direction * distance / 2;
63
53
  if (labelIndex > 0 && direction * currentTextLimit < direction * (previousTextLimit + tickLabelMinGap)) {
@@ -68,4 +58,34 @@ export function getVisibleLabels(xTicks, {
68
58
  previousTextLimit = textPosition + direction * distance / 2;
69
59
  return true;
70
60
  }));
61
+ }
62
+ function getTickLabelSize(sizeMap, tick) {
63
+ if (tick.formattedValue === undefined) {
64
+ return {
65
+ width: 0,
66
+ height: 0
67
+ };
68
+ }
69
+ let width = 0;
70
+ let height = 0;
71
+ for (const line of tick.formattedValue.split('\n')) {
72
+ const lineSize = sizeMap.get(line);
73
+ if (lineSize) {
74
+ width = Math.max(width, lineSize.width);
75
+ height += lineSize.height;
76
+ }
77
+ }
78
+ return {
79
+ width,
80
+ height
81
+ };
82
+ }
83
+ function measureTickLabels(ticks, style) {
84
+ const strings = new Set();
85
+ for (const tick of ticks) {
86
+ if (tick.formattedValue) {
87
+ tick.formattedValue.split('\n').forEach(line => strings.add(line));
88
+ }
89
+ }
90
+ return batchMeasureStrings(strings, style);
71
91
  }
@@ -18,10 +18,7 @@ const useUtilityClasses = props => {
18
18
  classes
19
19
  } = props;
20
20
  const slots = {
21
- root: ['root'],
22
- valueArc: ['valueArc'],
23
- referenceArc: ['referenceArc'],
24
- valueText: ['valueText']
21
+ root: ['root']
25
22
  };
26
23
  return composeClasses(slots, getGaugeUtilityClass, classes);
27
24
  };
@@ -37,13 +34,9 @@ const Gauge = /*#__PURE__*/React.forwardRef(function Gauge(props, ref) {
37
34
  return /*#__PURE__*/_jsxs(GaugeContainer, _extends({}, other, {
38
35
  className: clsx(classes.root, className),
39
36
  ref: ref,
40
- children: [/*#__PURE__*/_jsx(GaugeReferenceArc, {
41
- className: classes.referenceArc
42
- }), /*#__PURE__*/_jsx(GaugeValueArc, {
43
- className: classes.valueArc,
37
+ children: [/*#__PURE__*/_jsx(GaugeReferenceArc, {}), /*#__PURE__*/_jsx(GaugeValueArc, {
44
38
  skipAnimation: skipAnimation
45
39
  }), /*#__PURE__*/_jsx(GaugeValueText, {
46
- className: classes.valueText,
47
40
  text: text
48
41
  }), children]
49
42
  }));