@mui/x-charts 7.9.0 → 7.11.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 (222) hide show
  1. package/BarChart/BarChart.js +2 -2
  2. package/BarChart/formatter.js +1 -1
  3. package/BarChart/useBarChartProps.js +38 -33
  4. package/CHANGELOG.md +159 -0
  5. package/ChartContainer/ChartContainer.d.ts +28 -2
  6. package/ChartContainer/ChartContainer.js +25 -66
  7. package/ChartContainer/useChartContainerHooks.d.ts +1 -1
  8. package/ChartContainer/useChartContainerHooks.js +2 -2
  9. package/ChartContainer/useChartContainerProps.d.ts +86 -0
  10. package/ChartContainer/useChartContainerProps.js +95 -0
  11. package/ChartContainer/useDefaultizeAxis.d.ts +36 -0
  12. package/ChartContainer/useDefaultizeAxis.js +29 -0
  13. package/ChartsLegend/ChartsLegend.d.ts +3 -12
  14. package/ChartsLegend/ContinuousColorLegend.d.ts +65 -0
  15. package/ChartsLegend/ContinuousColorLegend.js +398 -0
  16. package/ChartsLegend/DefaultChartsLegend.d.ts +7 -50
  17. package/ChartsLegend/DefaultChartsLegend.js +13 -198
  18. package/ChartsLegend/LegendPerItem.d.ts +61 -0
  19. package/ChartsLegend/LegendPerItem.js +151 -0
  20. package/ChartsLegend/PiecewiseColorLegend.d.ts +26 -0
  21. package/ChartsLegend/PiecewiseColorLegend.js +169 -0
  22. package/ChartsLegend/chartsLegend.types.d.ts +31 -0
  23. package/ChartsLegend/chartsLegend.types.js +5 -0
  24. package/ChartsLegend/index.d.ts +2 -0
  25. package/ChartsLegend/index.js +22 -0
  26. package/ChartsLegend/legend.types.d.ts +62 -0
  27. package/ChartsLegend/legend.types.js +5 -0
  28. package/ChartsLegend/legendItemsPlacement.d.ts +3 -0
  29. package/ChartsLegend/legendItemsPlacement.js +79 -0
  30. package/ChartsLegend/useAxis.d.ts +7 -0
  31. package/ChartsLegend/useAxis.js +47 -0
  32. package/ChartsLegend/utils.d.ts +1 -8
  33. package/ChartsReferenceLine/ChartsReferenceLine.d.ts +1 -1
  34. package/ChartsSurface.js +3 -1
  35. package/ChartsVoronoiHandler/ChartsVoronoiHandler.js +26 -18
  36. package/ChartsXAxis/ChartsXAxis.js +1 -1
  37. package/ChartsYAxis/ChartsYAxis.js +15 -3
  38. package/Gauge/Gauge.d.ts +1 -4
  39. package/Gauge/Gauge.js +9 -6
  40. package/Gauge/GaugeContainer.js +8 -4
  41. package/Gauge/GaugeProvider.js +9 -9
  42. package/LineChart/AnimatedArea.js +2 -2
  43. package/LineChart/AnimatedLine.js +2 -2
  44. package/LineChart/AreaPlot.js +7 -1
  45. package/LineChart/LineChart.js +2 -2
  46. package/LineChart/LineHighlightPlot.js +8 -0
  47. package/LineChart/MarkElement.js +2 -2
  48. package/LineChart/MarkPlot.js +4 -20
  49. package/LineChart/extremums.js +1 -1
  50. package/LineChart/formatter.js +1 -1
  51. package/LineChart/useLineChartProps.js +38 -33
  52. package/PieChart/PieChart.d.ts +1 -4
  53. package/PieChart/PieChart.js +40 -34
  54. package/PieChart/PiePlot.js +6 -6
  55. package/PieChart/getPieCoordinates.js +3 -3
  56. package/ResponsiveChartContainer/ResponsiveChartContainer.js +8 -20
  57. package/ResponsiveChartContainer/useChartContainerDimensions.d.ts +5 -1
  58. package/ResponsiveChartContainer/useChartContainerDimensions.js +6 -2
  59. package/ResponsiveChartContainer/useResponsiveChartContainerProps.d.ts +20 -0
  60. package/ResponsiveChartContainer/useResponsiveChartContainerProps.js +73 -0
  61. package/ScatterChart/Scatter.js +6 -9
  62. package/ScatterChart/useScatterChartProps.js +35 -30
  63. package/SparkLineChart/SparkLineChart.js +27 -22
  64. package/context/CartesianProvider/CartesianProvider.d.ts +2 -3
  65. package/context/CartesianProvider/CartesianProvider.js +18 -7
  66. package/context/CartesianProvider/computeValue.d.ts +32 -9
  67. package/context/CartesianProvider/computeValue.js +20 -16
  68. package/context/CartesianProvider/defaultizeAxis.d.ts +36 -0
  69. package/context/CartesianProvider/defaultizeAxis.js +21 -0
  70. package/context/CartesianProvider/index.d.ts +0 -1
  71. package/context/CartesianProvider/index.js +1 -3
  72. package/context/CartesianProvider/normalizeAxis.d.ts +1 -1
  73. package/context/CartesianProvider/normalizeAxis.js +1 -1
  74. package/context/DrawingProvider.d.ts +11 -0
  75. package/context/DrawingProvider.js +9 -2
  76. package/context/HighlightedProvider/HighlightedProvider.js +2 -2
  77. package/esm/BarChart/BarChart.js +2 -2
  78. package/esm/BarChart/formatter.js +1 -1
  79. package/esm/BarChart/useBarChartProps.js +38 -33
  80. package/esm/ChartContainer/ChartContainer.js +25 -66
  81. package/esm/ChartContainer/useChartContainerHooks.js +2 -2
  82. package/esm/ChartContainer/useChartContainerProps.js +87 -0
  83. package/esm/ChartContainer/useDefaultizeAxis.js +19 -0
  84. package/esm/ChartsLegend/ContinuousColorLegend.js +390 -0
  85. package/esm/ChartsLegend/DefaultChartsLegend.js +14 -198
  86. package/esm/ChartsLegend/LegendPerItem.js +141 -0
  87. package/esm/ChartsLegend/PiecewiseColorLegend.js +161 -0
  88. package/esm/ChartsLegend/chartsLegend.types.js +1 -0
  89. package/esm/ChartsLegend/index.js +2 -0
  90. package/esm/ChartsLegend/legend.types.js +1 -0
  91. package/esm/ChartsLegend/legendItemsPlacement.js +72 -0
  92. package/esm/ChartsLegend/useAxis.js +39 -0
  93. package/esm/ChartsSurface.js +3 -1
  94. package/esm/ChartsVoronoiHandler/ChartsVoronoiHandler.js +26 -18
  95. package/esm/ChartsXAxis/ChartsXAxis.js +1 -1
  96. package/esm/ChartsYAxis/ChartsYAxis.js +15 -3
  97. package/esm/Gauge/Gauge.js +8 -5
  98. package/esm/Gauge/GaugeContainer.js +8 -4
  99. package/esm/Gauge/GaugeProvider.js +1 -1
  100. package/esm/LineChart/AnimatedArea.js +1 -1
  101. package/esm/LineChart/AnimatedLine.js +1 -1
  102. package/esm/LineChart/AreaPlot.js +7 -1
  103. package/esm/LineChart/LineChart.js +2 -2
  104. package/esm/LineChart/LineHighlightPlot.js +8 -0
  105. package/esm/LineChart/MarkElement.js +1 -1
  106. package/esm/LineChart/MarkPlot.js +3 -19
  107. package/esm/LineChart/extremums.js +1 -1
  108. package/esm/LineChart/formatter.js +1 -1
  109. package/esm/LineChart/useLineChartProps.js +38 -33
  110. package/esm/PieChart/PieChart.js +39 -33
  111. package/esm/PieChart/PiePlot.js +1 -1
  112. package/esm/PieChart/getPieCoordinates.js +1 -1
  113. package/esm/ResponsiveChartContainer/ResponsiveChartContainer.js +8 -20
  114. package/esm/ResponsiveChartContainer/useChartContainerDimensions.js +6 -2
  115. package/esm/ResponsiveChartContainer/useResponsiveChartContainerProps.js +65 -0
  116. package/esm/ScatterChart/Scatter.js +6 -9
  117. package/esm/ScatterChart/useScatterChartProps.js +35 -30
  118. package/esm/SparkLineChart/SparkLineChart.js +27 -22
  119. package/esm/context/CartesianProvider/CartesianProvider.js +18 -7
  120. package/esm/context/CartesianProvider/computeValue.js +20 -16
  121. package/esm/context/CartesianProvider/defaultizeAxis.js +13 -0
  122. package/esm/context/CartesianProvider/index.js +1 -3
  123. package/esm/context/CartesianProvider/normalizeAxis.js +1 -1
  124. package/esm/context/DrawingProvider.js +9 -2
  125. package/esm/context/HighlightedProvider/HighlightedProvider.js +2 -2
  126. package/esm/hooks/useAxisEvents.js +3 -10
  127. package/esm/hooks/useDrawingArea.js +5 -3
  128. package/esm/hooks/useReducedMotion.js +4 -2
  129. package/esm/internals/cleanId.js +6 -0
  130. package/esm/internals/components/ChartsAxesGradients/ChartsContinuousGradient.js +3 -2
  131. package/esm/internals/{utils.js → getPercentageValue.js} +1 -13
  132. package/esm/internals/getSymbol.js +5 -0
  133. package/esm/internals/index.js +3 -1
  134. package/esm/internals/isDefined.js +3 -0
  135. package/esm/internals/notNull.js +3 -0
  136. package/esm/internals/ts-generic.js +1 -0
  137. package/hooks/useAxisEvents.js +3 -10
  138. package/hooks/useDrawingArea.js +5 -3
  139. package/hooks/useReducedMotion.js +4 -2
  140. package/index.js +1 -1
  141. package/internals/cleanId.d.ts +4 -0
  142. package/internals/cleanId.js +12 -0
  143. package/internals/components/ChartsAxesGradients/ChartsContinuousGradient.d.ts +6 -0
  144. package/internals/components/ChartsAxesGradients/ChartsContinuousGradient.js +3 -2
  145. package/internals/getPercentageValue.d.ts +7 -0
  146. package/internals/{utils.js → getPercentageValue.js} +1 -15
  147. package/internals/getSymbol.d.ts +2 -0
  148. package/internals/getSymbol.js +11 -0
  149. package/internals/index.d.ts +3 -1
  150. package/internals/index.js +25 -5
  151. package/internals/isDefined.d.ts +1 -0
  152. package/internals/isDefined.js +9 -0
  153. package/internals/notNull.d.ts +1 -0
  154. package/internals/notNull.js +9 -0
  155. package/internals/ts-generic.d.ts +5 -0
  156. package/internals/ts-generic.js +5 -0
  157. package/models/axis.d.ts +5 -2
  158. package/models/helpers.d.ts +1 -0
  159. package/models/seriesType/config.d.ts +2 -16
  160. package/modern/BarChart/BarChart.js +2 -2
  161. package/modern/BarChart/formatter.js +1 -1
  162. package/modern/BarChart/useBarChartProps.js +38 -33
  163. package/modern/ChartContainer/ChartContainer.js +25 -66
  164. package/modern/ChartContainer/useChartContainerHooks.js +2 -2
  165. package/modern/ChartContainer/useChartContainerProps.js +87 -0
  166. package/modern/ChartContainer/useDefaultizeAxis.js +19 -0
  167. package/modern/ChartsLegend/ContinuousColorLegend.js +390 -0
  168. package/modern/ChartsLegend/DefaultChartsLegend.js +14 -198
  169. package/modern/ChartsLegend/LegendPerItem.js +141 -0
  170. package/modern/ChartsLegend/PiecewiseColorLegend.js +161 -0
  171. package/modern/ChartsLegend/chartsLegend.types.js +1 -0
  172. package/modern/ChartsLegend/index.js +2 -0
  173. package/modern/ChartsLegend/legend.types.js +1 -0
  174. package/modern/ChartsLegend/legendItemsPlacement.js +72 -0
  175. package/modern/ChartsLegend/useAxis.js +39 -0
  176. package/modern/ChartsSurface.js +3 -1
  177. package/modern/ChartsVoronoiHandler/ChartsVoronoiHandler.js +26 -18
  178. package/modern/ChartsXAxis/ChartsXAxis.js +1 -1
  179. package/modern/ChartsYAxis/ChartsYAxis.js +15 -3
  180. package/modern/Gauge/Gauge.js +8 -5
  181. package/modern/Gauge/GaugeContainer.js +8 -4
  182. package/modern/Gauge/GaugeProvider.js +1 -1
  183. package/modern/LineChart/AnimatedArea.js +1 -1
  184. package/modern/LineChart/AnimatedLine.js +1 -1
  185. package/modern/LineChart/AreaPlot.js +7 -1
  186. package/modern/LineChart/LineChart.js +2 -2
  187. package/modern/LineChart/LineHighlightPlot.js +8 -0
  188. package/modern/LineChart/MarkElement.js +1 -1
  189. package/modern/LineChart/MarkPlot.js +3 -19
  190. package/modern/LineChart/extremums.js +1 -1
  191. package/modern/LineChart/formatter.js +1 -1
  192. package/modern/LineChart/useLineChartProps.js +38 -33
  193. package/modern/PieChart/PieChart.js +39 -33
  194. package/modern/PieChart/PiePlot.js +1 -1
  195. package/modern/PieChart/getPieCoordinates.js +1 -1
  196. package/modern/ResponsiveChartContainer/ResponsiveChartContainer.js +8 -20
  197. package/modern/ResponsiveChartContainer/useChartContainerDimensions.js +6 -2
  198. package/modern/ResponsiveChartContainer/useResponsiveChartContainerProps.js +65 -0
  199. package/modern/ScatterChart/Scatter.js +6 -9
  200. package/modern/ScatterChart/useScatterChartProps.js +35 -30
  201. package/modern/SparkLineChart/SparkLineChart.js +27 -22
  202. package/modern/context/CartesianProvider/CartesianProvider.js +18 -7
  203. package/modern/context/CartesianProvider/computeValue.js +20 -16
  204. package/modern/context/CartesianProvider/defaultizeAxis.js +13 -0
  205. package/modern/context/CartesianProvider/index.js +1 -3
  206. package/modern/context/CartesianProvider/normalizeAxis.js +1 -1
  207. package/modern/context/DrawingProvider.js +9 -2
  208. package/modern/context/HighlightedProvider/HighlightedProvider.js +2 -2
  209. package/modern/hooks/useAxisEvents.js +3 -10
  210. package/modern/hooks/useDrawingArea.js +5 -3
  211. package/modern/hooks/useReducedMotion.js +4 -2
  212. package/modern/index.js +1 -1
  213. package/modern/internals/cleanId.js +6 -0
  214. package/modern/internals/components/ChartsAxesGradients/ChartsContinuousGradient.js +3 -2
  215. package/modern/internals/{utils.js → getPercentageValue.js} +1 -13
  216. package/modern/internals/getSymbol.js +5 -0
  217. package/modern/internals/index.js +3 -1
  218. package/modern/internals/isDefined.js +3 -0
  219. package/modern/internals/notNull.js +3 -0
  220. package/modern/internals/ts-generic.js +1 -0
  221. package/package.json +4 -4
  222. package/internals/utils.d.ts +0 -18
@@ -0,0 +1,141 @@
1
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
2
+ import _extends from "@babel/runtime/helpers/esm/extends";
3
+ const _excluded = ["rotate", "dominantBaseline"];
4
+ import * as React from 'react';
5
+ import { NoSsr } from '@mui/base/NoSsr';
6
+ import { useTheme, styled } from '@mui/material/styles';
7
+ import { ChartsText } from '../ChartsText';
8
+ import { getWordsByLines } from '../internals/getWordsByLines';
9
+ import { legendItemPlacements } from './legendItemsPlacement';
10
+ import { useDrawingArea } from '../hooks/useDrawingArea';
11
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
+ export const ChartsLegendRoot = styled('g', {
13
+ name: 'MuiChartsLegend',
14
+ slot: 'Root',
15
+ overridesResolver: (props, styles) => styles.root
16
+ })({});
17
+ /**
18
+ * Transforms number or partial padding object to a defaultized padding object.
19
+ */
20
+ const getStandardizedPadding = padding => {
21
+ if (typeof padding === 'number') {
22
+ return {
23
+ left: padding,
24
+ right: padding,
25
+ top: padding,
26
+ bottom: padding
27
+ };
28
+ }
29
+ return _extends({
30
+ left: 0,
31
+ right: 0,
32
+ top: 0,
33
+ bottom: 0
34
+ }, padding);
35
+ };
36
+
37
+ /**
38
+ * Internal component to display an array of items as a legend.
39
+ * Used for series legend, and threshold color legend.
40
+ * @ignore - Do not document
41
+ */
42
+ export function LegendPerItem(props) {
43
+ const {
44
+ hidden,
45
+ position,
46
+ direction,
47
+ itemsToDisplay,
48
+ classes,
49
+ itemMarkWidth = 20,
50
+ itemMarkHeight = 20,
51
+ markGap = 5,
52
+ itemGap = 10,
53
+ padding: paddingProps = 10,
54
+ labelStyle: inLabelStyle
55
+ } = props;
56
+ const theme = useTheme();
57
+ const isRTL = theme.direction === 'rtl';
58
+ const drawingArea = useDrawingArea();
59
+ const labelStyle = React.useMemo(() => _extends({}, theme.typography.subtitle1, {
60
+ color: 'inherit',
61
+ dominantBaseline: 'central',
62
+ textAnchor: 'start',
63
+ fill: (theme.vars || theme).palette.text.primary,
64
+ lineHeight: 1
65
+ }, inLabelStyle),
66
+ // To say to TS that the dominantBaseline and textAnchor are correct
67
+ [inLabelStyle, theme]);
68
+ const padding = React.useMemo(() => getStandardizedPadding(paddingProps), [paddingProps]);
69
+ const getItemSpace = React.useCallback((label, inStyle = {}) => {
70
+ const style = _objectWithoutPropertiesLoose(inStyle, _excluded);
71
+ const linesSize = getWordsByLines({
72
+ style,
73
+ needsComputation: true,
74
+ text: label
75
+ });
76
+ const innerSize = {
77
+ innerWidth: itemMarkWidth + markGap + Math.max(...linesSize.map(size => size.width)),
78
+ innerHeight: Math.max(itemMarkHeight, linesSize.length * linesSize[0].height)
79
+ };
80
+ return _extends({}, innerSize, {
81
+ outerWidth: innerSize.innerWidth + itemGap,
82
+ outerHeight: innerSize.innerHeight + itemGap
83
+ });
84
+ }, [itemGap, itemMarkHeight, itemMarkWidth, markGap]);
85
+ const totalWidth = drawingArea.left + drawingArea.width + drawingArea.right;
86
+ const totalHeight = drawingArea.top + drawingArea.height + drawingArea.bottom;
87
+ const availableWidth = totalWidth - padding.left - padding.right;
88
+ const availableHeight = totalHeight - padding.top - padding.bottom;
89
+ const [itemsWithPosition, legendWidth, legendHeight] = React.useMemo(() => legendItemPlacements(itemsToDisplay, getItemSpace, labelStyle, direction, availableWidth, availableHeight, itemGap), [itemsToDisplay, getItemSpace, labelStyle, direction, availableWidth, availableHeight, itemGap]);
90
+ const gapX = React.useMemo(() => {
91
+ switch (position.horizontal) {
92
+ case 'left':
93
+ return padding.left;
94
+ case 'right':
95
+ return totalWidth - padding.right - legendWidth;
96
+ default:
97
+ return (totalWidth - legendWidth) / 2;
98
+ }
99
+ }, [position.horizontal, padding.left, padding.right, totalWidth, legendWidth]);
100
+ const gapY = React.useMemo(() => {
101
+ switch (position.vertical) {
102
+ case 'top':
103
+ return padding.top;
104
+ case 'bottom':
105
+ return totalHeight - padding.bottom - legendHeight;
106
+ default:
107
+ return (totalHeight - legendHeight) / 2;
108
+ }
109
+ }, [position.vertical, padding.top, padding.bottom, totalHeight, legendHeight]);
110
+ if (hidden) {
111
+ return null;
112
+ }
113
+ return /*#__PURE__*/_jsx(NoSsr, {
114
+ children: /*#__PURE__*/_jsx(ChartsLegendRoot, {
115
+ className: classes?.root,
116
+ children: itemsWithPosition.map(({
117
+ id,
118
+ label,
119
+ color,
120
+ positionX,
121
+ positionY
122
+ }) => /*#__PURE__*/_jsxs("g", {
123
+ className: classes?.series,
124
+ transform: `translate(${gapX + (isRTL ? legendWidth - positionX : positionX)} ${gapY + positionY})`,
125
+ children: [/*#__PURE__*/_jsx("rect", {
126
+ className: classes?.mark,
127
+ x: isRTL ? -itemMarkWidth : 0,
128
+ y: -itemMarkHeight / 2,
129
+ width: itemMarkWidth,
130
+ height: itemMarkHeight,
131
+ fill: color
132
+ }), /*#__PURE__*/_jsx(ChartsText, {
133
+ style: labelStyle,
134
+ text: label,
135
+ x: (isRTL ? -1 : 1) * (itemMarkWidth + markGap),
136
+ y: 0
137
+ })]
138
+ }, id))
139
+ })
140
+ });
141
+ }
@@ -0,0 +1,161 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["axisDirection", "axisId", "hideFirst", "hideLast", "labelFormatter"];
4
+ import * as React from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import { useAxis } from './useAxis';
7
+ import { LegendPerItem } from './LegendPerItem';
8
+ import { notNull } from '../internals/notNull';
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ function defaultLabelFormatter(params) {
11
+ if (params.min === null) {
12
+ return `<${params.formattedMax}`;
13
+ }
14
+ if (params.max === null) {
15
+ return `>${params.formattedMin}`;
16
+ }
17
+ return `${params.formattedMin}-${params.formattedMax}`;
18
+ }
19
+ function PiecewiseColorLegend(props) {
20
+ const {
21
+ axisDirection,
22
+ axisId,
23
+ hideFirst,
24
+ hideLast,
25
+ labelFormatter = defaultLabelFormatter
26
+ } = props,
27
+ other = _objectWithoutPropertiesLoose(props, _excluded);
28
+ const axisItem = useAxis({
29
+ axisDirection,
30
+ axisId
31
+ });
32
+ const colorMap = axisItem?.colorMap;
33
+ if (!colorMap || !colorMap.type || colorMap.type !== 'piecewise') {
34
+ return null;
35
+ }
36
+ const valueFormatter = v => axisItem.valueFormatter?.(v, {
37
+ location: 'legend'
38
+ }) ?? v.toLocaleString();
39
+ const formattedLabels = colorMap.thresholds.map(valueFormatter);
40
+ const itemsToDisplay = colorMap.colors.map((color, index) => {
41
+ const isFirst = index === 0;
42
+ const isLast = index === colorMap.colors.length - 1;
43
+ if (hideFirst && isFirst || hideLast && isLast) {
44
+ return null;
45
+ }
46
+ const label = labelFormatter(_extends({}, index === 0 ? {
47
+ min: null,
48
+ formattedMin: null
49
+ } : {
50
+ min: colorMap.thresholds[index - 1],
51
+ formattedMin: formattedLabels[index - 1]
52
+ }, index === colorMap.colors.length - 1 ? {
53
+ max: null,
54
+ formattedMax: null
55
+ } : {
56
+ max: colorMap.thresholds[index],
57
+ formattedMax: formattedLabels[index]
58
+ }));
59
+ if (label === null) {
60
+ return null;
61
+ }
62
+ return {
63
+ id: label,
64
+ color,
65
+ label
66
+ };
67
+ }).filter(notNull);
68
+ return /*#__PURE__*/_jsx(LegendPerItem, _extends({}, other, {
69
+ itemsToDisplay: itemsToDisplay
70
+ }));
71
+ }
72
+ process.env.NODE_ENV !== "production" ? PiecewiseColorLegend.propTypes = {
73
+ // ----------------------------- Warning --------------------------------
74
+ // | These PropTypes are generated from the TypeScript type definitions |
75
+ // | To update them edit the TypeScript types and run "pnpm proptypes" |
76
+ // ----------------------------------------------------------------------
77
+ /**
78
+ * The axis direction containing the color configuration to represent.
79
+ * @default 'z'
80
+ */
81
+ axisDirection: PropTypes.oneOf(['x', 'y', 'z']),
82
+ /**
83
+ * The id of the axis item with the color configuration to represent.
84
+ * @default The first axis item.
85
+ */
86
+ axisId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
87
+ /**
88
+ * Override or extend the styles applied to the component.
89
+ */
90
+ classes: PropTypes.object,
91
+ /**
92
+ * The direction of the legend layout.
93
+ * The default depends on the chart.
94
+ */
95
+ direction: PropTypes.oneOf(['column', 'row']).isRequired,
96
+ /**
97
+ * Set to true to hide the legend.
98
+ * @default false
99
+ */
100
+ hidden: PropTypes.bool,
101
+ /**
102
+ * Hide the first item of the legend, corresponding to the [-infinity, min] piece.
103
+ * @default false
104
+ */
105
+ hideFirst: PropTypes.bool,
106
+ /**
107
+ * Hide the last item of the legend, corresponding to the [max, +infinity] piece.
108
+ * @default false
109
+ */
110
+ hideLast: PropTypes.bool,
111
+ /**
112
+ * Space between two legend items (in px).
113
+ * @default 10
114
+ */
115
+ itemGap: PropTypes.number,
116
+ /**
117
+ * Height of the item mark (in px).
118
+ * @default 20
119
+ */
120
+ itemMarkHeight: PropTypes.number,
121
+ /**
122
+ * Width of the item mark (in px).
123
+ * @default 20
124
+ */
125
+ itemMarkWidth: PropTypes.number,
126
+ /**
127
+ * Format the legend labels.
128
+ * @param {PiecewiseLabelFormatterParams} params The bound of the piece to format.
129
+ * @returns {string|null} The displayed label, or `null` to skip the item.
130
+ */
131
+ labelFormatter: PropTypes.func,
132
+ /**
133
+ * Style applied to legend labels.
134
+ * @default theme.typography.subtitle1
135
+ */
136
+ labelStyle: PropTypes.object,
137
+ /**
138
+ * Space between the mark and the label (in px).
139
+ * @default 5
140
+ */
141
+ markGap: PropTypes.number,
142
+ /**
143
+ * Legend padding (in px).
144
+ * Can either be a single number, or an object with top, left, bottom, right properties.
145
+ * @default 10
146
+ */
147
+ padding: PropTypes.oneOfType([PropTypes.number, PropTypes.shape({
148
+ bottom: PropTypes.number,
149
+ left: PropTypes.number,
150
+ right: PropTypes.number,
151
+ top: PropTypes.number
152
+ })]),
153
+ /**
154
+ * The position of the legend.
155
+ */
156
+ position: PropTypes.shape({
157
+ horizontal: PropTypes.oneOf(['left', 'middle', 'right']).isRequired,
158
+ vertical: PropTypes.oneOf(['bottom', 'middle', 'top']).isRequired
159
+ }).isRequired
160
+ } : void 0;
161
+ export { PiecewiseColorLegend };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,6 @@
1
1
  export * from './ChartsLegend';
2
2
  export * from './DefaultChartsLegend';
3
+ export * from './ContinuousColorLegend';
4
+ export * from './PiecewiseColorLegend';
3
5
  export * from './chartsLegendClasses';
4
6
  export * from './utils';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,72 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
+ const _excluded = ["label"];
4
+ export function legendItemPlacements(itemsToDisplay, getItemSpace, labelStyle, direction, availableWidth, availableHeight, itemGap) {
5
+ // Start at 0, 0. Will be modified later by padding and position.
6
+ let x = 0;
7
+ let y = 0;
8
+
9
+ // total values used to align legend later.
10
+ let totalWidthUsed = 0;
11
+ let totalHeightUsed = 0;
12
+ let rowIndex = 0;
13
+ const rowMaxHeight = [0];
14
+ const seriesWithRawPosition = itemsToDisplay.map(_ref => {
15
+ let {
16
+ label
17
+ } = _ref,
18
+ other = _objectWithoutPropertiesLoose(_ref, _excluded);
19
+ const itemSpace = getItemSpace(label, labelStyle);
20
+ const rep = _extends({}, other, {
21
+ label,
22
+ positionX: x,
23
+ positionY: y,
24
+ innerHeight: itemSpace.innerHeight,
25
+ innerWidth: itemSpace.innerWidth,
26
+ outerHeight: itemSpace.outerHeight,
27
+ outerWidth: itemSpace.outerWidth,
28
+ rowIndex
29
+ });
30
+ if (direction === 'row') {
31
+ if (x + itemSpace.innerWidth > availableWidth) {
32
+ // This legend item would create overflow along the x-axis, so we start a new row.
33
+ x = 0;
34
+ y += rowMaxHeight[rowIndex];
35
+ rowIndex += 1;
36
+ if (rowMaxHeight.length <= rowIndex) {
37
+ rowMaxHeight.push(0);
38
+ }
39
+ rep.positionX = x;
40
+ rep.positionY = y;
41
+ rep.rowIndex = rowIndex;
42
+ }
43
+ totalWidthUsed = Math.max(totalWidthUsed, x + itemSpace.outerWidth);
44
+ totalHeightUsed = Math.max(totalHeightUsed, y + itemSpace.outerHeight);
45
+ rowMaxHeight[rowIndex] = Math.max(rowMaxHeight[rowIndex], itemSpace.outerHeight);
46
+ x += itemSpace.outerWidth;
47
+ }
48
+ if (direction === 'column') {
49
+ if (y + itemSpace.innerHeight > availableHeight) {
50
+ // This legend item would create overflow along the y-axis, so we start a new column.
51
+ x = totalWidthUsed + itemGap;
52
+ y = 0;
53
+ rowIndex = 0;
54
+ rep.positionX = x;
55
+ rep.positionY = y;
56
+ rep.rowIndex = rowIndex;
57
+ }
58
+ if (rowMaxHeight.length <= rowIndex) {
59
+ rowMaxHeight.push(0);
60
+ }
61
+ totalWidthUsed = Math.max(totalWidthUsed, x + itemSpace.outerWidth);
62
+ totalHeightUsed = Math.max(totalHeightUsed, y + itemSpace.outerHeight);
63
+ rowIndex += 1;
64
+ y += itemSpace.outerHeight;
65
+ }
66
+ return rep;
67
+ });
68
+ return [seriesWithRawPosition.map(item => _extends({}, item, {
69
+ positionY: item.positionY + (direction === 'row' ? rowMaxHeight[item.rowIndex] / 2 // Get the center of the entire row
70
+ : item.outerHeight / 2) // Get the center of the item
71
+ })), totalWidthUsed, totalHeightUsed];
72
+ }
@@ -0,0 +1,39 @@
1
+ import * as React from 'react';
2
+ import { ZAxisContext } from '../context/ZAxisContextProvider';
3
+ import { useCartesianContext } from '../context/CartesianProvider/useCartesianContext';
4
+ /**
5
+ * Helper to select an axis definition according to its direction and id.
6
+ */
7
+ export function useAxis({
8
+ axisDirection,
9
+ axisId
10
+ }) {
11
+ const {
12
+ xAxis,
13
+ xAxisIds,
14
+ yAxis,
15
+ yAxisIds
16
+ } = useCartesianContext();
17
+ const {
18
+ zAxis,
19
+ zAxisIds
20
+ } = React.useContext(ZAxisContext);
21
+ switch (axisDirection) {
22
+ case 'x':
23
+ {
24
+ const id = typeof axisId === 'string' ? axisId : xAxisIds[axisId ?? 0];
25
+ return xAxis[id];
26
+ }
27
+ case 'y':
28
+ {
29
+ const id = typeof axisId === 'string' ? axisId : yAxisIds[axisId ?? 0];
30
+ return yAxis[id];
31
+ }
32
+ case 'z':
33
+ default:
34
+ {
35
+ const id = typeof axisId === 'string' ? axisId : zAxisIds[axisId ?? 0];
36
+ return zAxis[id];
37
+ }
38
+ }
39
+ }
@@ -21,6 +21,7 @@ const ChartsSurface = /*#__PURE__*/React.forwardRef(function ChartsSurface(props
21
21
  height,
22
22
  viewBox,
23
23
  disableAxisListener = false,
24
+ className,
24
25
  title,
25
26
  desc
26
27
  } = props,
@@ -36,7 +37,8 @@ const ChartsSurface = /*#__PURE__*/React.forwardRef(function ChartsSurface(props
36
37
  width: width,
37
38
  height: height,
38
39
  viewBox: `${svgView.x} ${svgView.y} ${svgView.width} ${svgView.height}`,
39
- ref: ref
40
+ ref: ref,
41
+ className: className
40
42
  }, other, {
41
43
  children: [/*#__PURE__*/_jsx("title", {
42
44
  children: title
@@ -16,12 +16,7 @@ function ChartsVoronoiHandler(props) {
16
16
  onItemClick
17
17
  } = props;
18
18
  const svgRef = useSvgRef();
19
- const {
20
- left,
21
- top,
22
- width,
23
- height
24
- } = useDrawingArea();
19
+ const drawingArea = useDrawingArea();
25
20
  const {
26
21
  xAxis,
27
22
  yAxis,
@@ -37,6 +32,7 @@ function ChartsVoronoiHandler(props) {
37
32
  } = useScatterSeries() ?? {};
38
33
  const voronoiRef = React.useRef({});
39
34
  const delauneyRef = React.useRef(undefined);
35
+ const lastFind = React.useRef(undefined);
40
36
  const {
41
37
  setHighlighted,
42
38
  clearHighlighted
@@ -77,7 +73,20 @@ function ChartsVoronoiHandler(props) {
77
73
  const seriesPoints = data.flatMap(({
78
74
  x,
79
75
  y
80
- }) => [getXPosition(x), getYPosition(y)]);
76
+ }) => {
77
+ const pointX = getXPosition(x);
78
+ const pointY = getYPosition(y);
79
+ if (!drawingArea.isPointInside({
80
+ x: pointX,
81
+ y: pointY
82
+ })) {
83
+ // If the point is not displayed we move them to a trash coordinate.
84
+ // This avoids managing index mapping before/after filtering.
85
+ // The trash point is far enough such that any point in the drawing area will be closer to the mouse than the trash coordinate.
86
+ return [-drawingArea.width, -drawingArea.height];
87
+ }
88
+ return [pointX, pointY];
89
+ });
81
90
  voronoiRef.current[seriesId] = {
82
91
  seriesId,
83
92
  startIndex: points.length,
@@ -86,29 +95,28 @@ function ChartsVoronoiHandler(props) {
86
95
  points = points.concat(seriesPoints);
87
96
  });
88
97
  delauneyRef.current = new Delaunay(points);
89
- }, [defaultXAxisId, defaultYAxisId, series, seriesOrder, xAxis, yAxis]);
98
+ lastFind.current = undefined;
99
+ }, [defaultXAxisId, defaultYAxisId, series, seriesOrder, xAxis, yAxis, drawingArea]);
90
100
  React.useEffect(() => {
91
101
  const element = svgRef.current;
92
102
  if (element === null) {
93
103
  return undefined;
94
104
  }
95
-
96
- // TODO: A perf optimisation of voronoi could be to use the last point as the initial point for the next search.
97
105
  function getClosestPoint(event) {
98
106
  // Get mouse coordinate in global SVG space
99
107
  const svgPoint = getSVGPoint(element, event);
100
- const outsideX = svgPoint.x < left || svgPoint.x > left + width;
101
- const outsideY = svgPoint.y < top || svgPoint.y > top + height;
102
- if (outsideX || outsideY) {
108
+ if (!drawingArea.isPointInside(svgPoint)) {
109
+ lastFind.current = undefined;
103
110
  return 'outside-chart';
104
111
  }
105
112
  if (!delauneyRef.current) {
106
113
  return 'no-point-found';
107
114
  }
108
- const closestPointIndex = delauneyRef.current.find(svgPoint.x, svgPoint.y);
115
+ const closestPointIndex = delauneyRef.current.find(svgPoint.x, svgPoint.y, lastFind.current);
109
116
  if (closestPointIndex === undefined) {
110
117
  return 'no-point-found';
111
118
  }
119
+ lastFind.current = closestPointIndex;
112
120
  const closestSeries = Object.values(voronoiRef.current).find(value => {
113
121
  return 2 * closestPointIndex >= value.startIndex && 2 * closestPointIndex < value.endIndex;
114
122
  });
@@ -130,7 +138,7 @@ function ChartsVoronoiHandler(props) {
130
138
  dataIndex
131
139
  };
132
140
  }
133
- const handleMouseOut = () => {
141
+ const handleMouseLeave = () => {
134
142
  dispatch({
135
143
  type: 'exitChart'
136
144
  });
@@ -191,15 +199,15 @@ function ChartsVoronoiHandler(props) {
191
199
  dataIndex
192
200
  });
193
201
  };
194
- element.addEventListener('pointerout', handleMouseOut);
202
+ element.addEventListener('pointerleave', handleMouseLeave);
195
203
  element.addEventListener('pointermove', handleMouseMove);
196
204
  element.addEventListener('click', handleMouseClick);
197
205
  return () => {
198
- element.removeEventListener('pointerout', handleMouseOut);
206
+ element.removeEventListener('pointerleave', handleMouseLeave);
199
207
  element.removeEventListener('pointermove', handleMouseMove);
200
208
  element.removeEventListener('click', handleMouseClick);
201
209
  };
202
- }, [svgRef, dispatch, left, width, top, height, yAxis, xAxis, voronoiMaxRadius, onItemClick, setHighlighted, clearHighlighted]);
210
+ }, [svgRef, dispatch, yAxis, xAxis, voronoiMaxRadius, onItemClick, setHighlighted, clearHighlighted, drawingArea]);
203
211
 
204
212
  // eslint-disable-next-line react/jsx-no-useless-fragment
205
213
  return /*#__PURE__*/_jsx(React.Fragment, {});
@@ -212,7 +212,7 @@ function ChartsXAxis(inProps) {
212
212
  x1: left,
213
213
  x2: left + width,
214
214
  className: classes.line
215
- }, slotProps?.axisLine)), xTicksWithDimension.filter(tick => tick.offset >= left - 1 && tick.offset <= left + width + 1).map(({
215
+ }, slotProps?.axisLine)), xTicksWithDimension.map(({
216
216
  formattedValue,
217
217
  offset,
218
218
  labelOffset,
@@ -136,6 +136,14 @@ function ChartsYAxis(inProps) {
136
136
  },
137
137
  ownerState: {}
138
138
  });
139
+ const lineSlotProps = useSlotProps({
140
+ elementType: Line,
141
+ externalSlotProps: slotProps?.axisLine,
142
+ additionalProps: {
143
+ strokeLinecap: 'square'
144
+ },
145
+ ownerState: {}
146
+ });
139
147
  const domain = yScale.domain();
140
148
  if (domain.length === 0 || domain[0] === domain[1]) {
141
149
  // Skip axis rendering if
@@ -147,10 +155,10 @@ function ChartsYAxis(inProps) {
147
155
  transform: `translate(${position === 'right' ? left + width : left}, 0)`,
148
156
  className: classes.root,
149
157
  children: [!disableLine && /*#__PURE__*/_jsx(Line, _extends({
150
- y1: yScale.range()[0],
151
- y2: yScale.range()[1],
158
+ y1: top,
159
+ y2: top + height,
152
160
  className: classes.line
153
- }, slotProps?.axisLine)), yTicks.map(({
161
+ }, lineSlotProps)), yTicks.map(({
154
162
  formattedValue,
155
163
  offset,
156
164
  labelOffset,
@@ -159,6 +167,10 @@ function ChartsYAxis(inProps) {
159
167
  const xTickLabel = positionSign * (tickSize + 2);
160
168
  const yTickLabel = labelOffset;
161
169
  const skipLabel = typeof tickLabelInterval === 'function' && !tickLabelInterval?.(value, index);
170
+ const showLabel = offset >= top - 1 && offset <= height + top + 1;
171
+ if (!showLabel) {
172
+ return null;
173
+ }
162
174
  return /*#__PURE__*/_jsxs("g", {
163
175
  transform: `translate(0, ${offset})`,
164
176
  className: classes.tickContainer,
@@ -1,9 +1,10 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- const _excluded = ["text", "children", "classes"];
3
+ const _excluded = ["text", "children", "classes", "className"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import composeClasses from '@mui/utils/composeClasses';
7
+ import clsx from 'clsx';
7
8
  import { GaugeContainer } from './GaugeContainer';
8
9
  import { GaugeValueArc } from './GaugeValueArc';
9
10
  import { GaugeReferenceArc } from './GaugeReferenceArc';
@@ -22,15 +23,17 @@ const useUtilityClasses = props => {
22
23
  };
23
24
  return composeClasses(slots, getGaugeUtilityClass, classes);
24
25
  };
25
- function Gauge(props) {
26
+ const Gauge = /*#__PURE__*/React.forwardRef(function Gauge(props, ref) {
26
27
  const {
27
28
  text,
28
- children
29
+ children,
30
+ className
29
31
  } = props,
30
32
  other = _objectWithoutPropertiesLoose(props, _excluded);
31
33
  const classes = useUtilityClasses(props);
32
34
  return /*#__PURE__*/_jsxs(GaugeContainer, _extends({}, other, {
33
- className: classes.root,
35
+ className: clsx(classes.root, className),
36
+ ref: ref,
34
37
  children: [/*#__PURE__*/_jsx(GaugeReferenceArc, {
35
38
  className: classes.referenceArc
36
39
  }), /*#__PURE__*/_jsx(GaugeValueArc, {
@@ -40,7 +43,7 @@ function Gauge(props) {
40
43
  text: text
41
44
  }), children]
42
45
  }));
43
- }
46
+ });
44
47
  process.env.NODE_ENV !== "production" ? Gauge.propTypes = {
45
48
  // ----------------------------- Warning --------------------------------
46
49
  // | These PropTypes are generated from the TypeScript type definitions |
@@ -3,8 +3,8 @@ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWith
3
3
  const _excluded = ["width", "height", "margin", "title", "desc", "value", "valueMin", "valueMax", "startAngle", "endAngle", "outerRadius", "innerRadius", "cornerRadius", "cx", "cy", "children"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
- import useForkRef from '@mui/utils/useForkRef';
7
6
  import { styled } from '@mui/material/styles';
7
+ import useForkRef from '@mui/utils/useForkRef';
8
8
  import { useChartContainerDimensions } from '../ResponsiveChartContainer/useChartContainerDimensions';
9
9
  import { ChartsSurface } from '../ChartsSurface';
10
10
  import { DrawingProvider } from '../context/DrawingProvider';
@@ -54,9 +54,13 @@ const GaugeContainer = /*#__PURE__*/React.forwardRef(function GaugeContainer(pro
54
54
  children
55
55
  } = props,
56
56
  other = _objectWithoutPropertiesLoose(props, _excluded);
57
- const [containerRef, width, height] = useChartContainerDimensions(inWidth, inHeight);
57
+ const {
58
+ containerRef,
59
+ width,
60
+ height
61
+ } = useChartContainerDimensions(inWidth, inHeight);
58
62
  const svgRef = React.useRef(null);
59
- const handleRef = useForkRef(ref, svgRef);
63
+ const chartSurfaceRef = useForkRef(ref, svgRef);
60
64
  return /*#__PURE__*/_jsx(ResizableContainer, _extends({
61
65
  ref: containerRef,
62
66
  ownerState: {
@@ -92,7 +96,7 @@ const GaugeContainer = /*#__PURE__*/React.forwardRef(function GaugeContainer(pro
92
96
  children: /*#__PURE__*/_jsx(ChartsSurface, {
93
97
  width: width,
94
98
  height: height,
95
- ref: handleRef,
99
+ ref: chartSurfaceRef,
96
100
  title: title,
97
101
  desc: desc,
98
102
  disableAxisListener: true,