@mui/x-charts-pro 8.5.2 → 8.6.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 (110) hide show
  1. package/CHANGELOG.md +203 -11
  2. package/ChartDataProviderPro/ChartDataProviderPro.js +1 -1
  3. package/ChartZoomSlider/internals/ChartAxisZoomSlider.js +1 -1
  4. package/ChartZoomSlider/internals/ChartAxisZoomSliderActiveTrack.js +20 -31
  5. package/ChartZoomSlider/internals/ChartAxisZoomSliderTrack.js +1 -8
  6. package/ChartZoomSlider/internals/zoom-utils.d.ts +3 -1
  7. package/ChartZoomSlider/internals/zoom-utils.js +19 -8
  8. package/ChartsToolbarPro/ChartsToolbarImageExportTrigger.d.ts +27 -0
  9. package/ChartsToolbarPro/ChartsToolbarImageExportTrigger.js +77 -0
  10. package/ChartsToolbarPro/ChartsToolbarPrintExportTrigger.d.ts +33 -0
  11. package/ChartsToolbarPro/ChartsToolbarPrintExportTrigger.js +75 -0
  12. package/ChartsToolbarPro/ChartsToolbarPro.d.ts +16 -3
  13. package/ChartsToolbarPro/ChartsToolbarPro.js +118 -8
  14. package/ChartsToolbarPro/index.d.ts +3 -1
  15. package/ChartsToolbarPro/index.js +22 -0
  16. package/ChartsToolbarPro/internals/ChartsMenu.d.ts +14 -0
  17. package/ChartsToolbarPro/internals/ChartsMenu.js +73 -0
  18. package/ChartsToolbarPro/internals/ChartsToolbarDivider.d.ts +5 -0
  19. package/ChartsToolbarPro/internals/ChartsToolbarDivider.js +47 -0
  20. package/FunnelChart/FunnelPlot.js +56 -40
  21. package/FunnelChart/FunnelSection.js +2 -0
  22. package/FunnelChart/curves/bump.d.ts +3 -3
  23. package/FunnelChart/curves/bump.js +3 -0
  24. package/FunnelChart/curves/curve.types.d.ts +14 -1
  25. package/FunnelChart/curves/getFunnelCurve.d.ts +7 -2
  26. package/FunnelChart/curves/linear.d.ts +3 -3
  27. package/FunnelChart/curves/linear.js +23 -18
  28. package/FunnelChart/curves/pyramid.d.ts +3 -3
  29. package/FunnelChart/curves/pyramid.js +17 -12
  30. package/FunnelChart/curves/step-pyramid.d.ts +5 -5
  31. package/FunnelChart/curves/step-pyramid.js +20 -18
  32. package/FunnelChart/curves/step.d.ts +3 -3
  33. package/FunnelChart/curves/step.js +14 -12
  34. package/FunnelChart/funnelAxisPlugin/useChartFunnelAxisRendering.selectors.d.ts +18 -1444
  35. package/FunnelChart/labelUtils.d.ts +4 -12
  36. package/FunnelChart/labelUtils.js +43 -44
  37. package/esm/ChartDataProviderPro/ChartDataProviderPro.js +1 -1
  38. package/esm/ChartZoomSlider/internals/ChartAxisZoomSlider.js +1 -1
  39. package/esm/ChartZoomSlider/internals/ChartAxisZoomSliderActiveTrack.js +21 -32
  40. package/esm/ChartZoomSlider/internals/ChartAxisZoomSliderTrack.js +1 -8
  41. package/esm/ChartZoomSlider/internals/zoom-utils.d.ts +3 -1
  42. package/esm/ChartZoomSlider/internals/zoom-utils.js +19 -9
  43. package/esm/ChartsToolbarPro/ChartsToolbarImageExportTrigger.d.ts +27 -0
  44. package/esm/ChartsToolbarPro/ChartsToolbarImageExportTrigger.js +70 -0
  45. package/esm/ChartsToolbarPro/ChartsToolbarPrintExportTrigger.d.ts +33 -0
  46. package/esm/ChartsToolbarPro/ChartsToolbarPrintExportTrigger.js +68 -0
  47. package/esm/ChartsToolbarPro/ChartsToolbarPro.d.ts +16 -3
  48. package/esm/ChartsToolbarPro/ChartsToolbarPro.js +120 -8
  49. package/esm/ChartsToolbarPro/index.d.ts +3 -1
  50. package/esm/ChartsToolbarPro/index.js +3 -1
  51. package/esm/ChartsToolbarPro/internals/ChartsMenu.d.ts +14 -0
  52. package/esm/ChartsToolbarPro/internals/ChartsMenu.js +67 -0
  53. package/esm/ChartsToolbarPro/internals/ChartsToolbarDivider.d.ts +5 -0
  54. package/esm/ChartsToolbarPro/internals/ChartsToolbarDivider.js +40 -0
  55. package/esm/FunnelChart/FunnelPlot.js +56 -40
  56. package/esm/FunnelChart/FunnelSection.js +2 -0
  57. package/esm/FunnelChart/curves/bump.d.ts +3 -3
  58. package/esm/FunnelChart/curves/bump.js +3 -0
  59. package/esm/FunnelChart/curves/curve.types.d.ts +14 -1
  60. package/esm/FunnelChart/curves/getFunnelCurve.d.ts +7 -2
  61. package/esm/FunnelChart/curves/linear.d.ts +3 -3
  62. package/esm/FunnelChart/curves/linear.js +23 -18
  63. package/esm/FunnelChart/curves/pyramid.d.ts +3 -3
  64. package/esm/FunnelChart/curves/pyramid.js +17 -12
  65. package/esm/FunnelChart/curves/step-pyramid.d.ts +5 -5
  66. package/esm/FunnelChart/curves/step-pyramid.js +20 -18
  67. package/esm/FunnelChart/curves/step.d.ts +3 -3
  68. package/esm/FunnelChart/curves/step.js +14 -12
  69. package/esm/FunnelChart/funnelAxisPlugin/useChartFunnelAxisRendering.selectors.d.ts +18 -1444
  70. package/esm/FunnelChart/labelUtils.d.ts +4 -12
  71. package/esm/FunnelChart/labelUtils.js +43 -44
  72. package/esm/index.d.ts +2 -1
  73. package/esm/index.js +1 -1
  74. package/esm/internals/material/components/BaseMenuItem.d.ts +3 -0
  75. package/esm/internals/material/components/BaseMenuItem.js +27 -0
  76. package/esm/internals/material/components/BasePopper.d.ts +3 -0
  77. package/esm/internals/material/components/BasePopper.js +122 -0
  78. package/esm/internals/material/icons.d.ts +2 -1
  79. package/esm/internals/material/icons.js +4 -1
  80. package/esm/internals/material/index.d.ts +1 -0
  81. package/esm/internals/material/index.js +12 -3
  82. package/esm/internals/plugins/useChartProExport/print.js +1 -1
  83. package/esm/internals/plugins/useChartProExport/useChartProExport.types.d.ts +7 -6
  84. package/esm/internals/plugins/useChartProZoom/useChartProZoom.selectors.d.ts +16 -595
  85. package/esm/internals/plugins/useChartProZoom/useChartProZoom.selectors.js +2 -2
  86. package/esm/internals/slots/chartBaseSlotProps.d.ts +50 -3
  87. package/esm/internals/slots/chartsBaseSlots.d.ts +5 -1
  88. package/esm/internals/slots/chartsIconSlots.d.ts +5 -0
  89. package/index.d.ts +2 -1
  90. package/index.js +1 -1
  91. package/internals/material/components/BaseMenuItem.d.ts +3 -0
  92. package/internals/material/components/BaseMenuItem.js +35 -0
  93. package/internals/material/components/BasePopper.d.ts +3 -0
  94. package/internals/material/components/BasePopper.js +130 -0
  95. package/internals/material/icons.d.ts +2 -1
  96. package/internals/material/icons.js +5 -2
  97. package/internals/material/index.d.ts +1 -0
  98. package/internals/material/index.js +11 -2
  99. package/internals/plugins/useChartProExport/print.js +1 -1
  100. package/internals/plugins/useChartProExport/useChartProExport.types.d.ts +7 -6
  101. package/internals/plugins/useChartProZoom/useChartProZoom.selectors.d.ts +16 -595
  102. package/internals/plugins/useChartProZoom/useChartProZoom.selectors.js +2 -2
  103. package/internals/slots/chartBaseSlotProps.d.ts +50 -3
  104. package/internals/slots/chartsBaseSlots.d.ts +5 -1
  105. package/internals/slots/chartsIconSlots.d.ts +5 -0
  106. package/package.json +5 -5
  107. package/FunnelChart/positionGetter.d.ts +0 -1
  108. package/FunnelChart/positionGetter.js +0 -5
  109. package/esm/FunnelChart/positionGetter.d.ts +0 -1
  110. package/esm/FunnelChart/positionGetter.js +0 -1
@@ -1,16 +1,35 @@
1
+ 'use client';
2
+
1
3
  import _extends from "@babel/runtime/helpers/esm/extends";
2
- import { Toolbar, ToolbarButton } from '@mui/x-charts/Toolbar';
4
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
5
+ const _excluded = ["printOptions", "imageExportOptions"];
3
6
  import * as React from 'react';
7
+ import PropTypes from 'prop-types';
8
+ import { Toolbar, ToolbarButton } from '@mui/x-charts/Toolbar';
4
9
  import { useChartContext, useSelector, useChartsSlots } from '@mui/x-charts/internals';
5
10
  import { useChartsLocalization } from '@mui/x-charts/hooks';
11
+ import useId from '@mui/utils/useId';
12
+ import { ChartsToolbarDivider } from "./internals/ChartsToolbarDivider.js";
13
+ import { ChartsMenu } from "./internals/ChartsMenu.js";
6
14
  import { selectorChartZoomIsEnabled } from "../internals/plugins/useChartProZoom/index.js";
7
15
  import { ChartsToolbarZoomInTrigger } from "./ChartsToolbarZoomInTrigger.js";
8
16
  import { ChartsToolbarZoomOutTrigger } from "./ChartsToolbarZoomOutTrigger.js";
9
- import { jsx as _jsx } from "react/jsx-runtime";
17
+ import { ChartsToolbarPrintExportTrigger } from "./ChartsToolbarPrintExportTrigger.js";
18
+ import { ChartsToolbarImageExportTrigger } from "./ChartsToolbarImageExportTrigger.js";
19
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
+ const DEFAULT_IMAGE_EXPORT_OPTIONS = [{
21
+ type: 'image/png'
22
+ }];
23
+
10
24
  /**
11
25
  * The chart toolbar component for the pro package.
12
26
  */
13
- export function ChartsToolbarPro(props) {
27
+ function ChartsToolbarPro(_ref) {
28
+ let {
29
+ printOptions,
30
+ imageExportOptions: rawImageExportOptions
31
+ } = _ref,
32
+ other = _objectWithoutPropertiesLoose(_ref, _excluded);
14
33
  const {
15
34
  slots,
16
35
  slotProps
@@ -21,7 +40,13 @@ export function ChartsToolbarPro(props) {
21
40
  const {
22
41
  localeText
23
42
  } = useChartsLocalization();
43
+ const [exportMenuOpen, setExportMenuOpen] = React.useState(false);
44
+ const exportMenuTriggerRef = React.useRef(null);
45
+ const exportMenuId = useId();
46
+ const exportMenuTriggerId = useId();
24
47
  const isZoomEnabled = useSelector(store, selectorChartZoomIsEnabled);
48
+ const imageExportOptionList = rawImageExportOptions ?? DEFAULT_IMAGE_EXPORT_OPTIONS;
49
+ const showExportMenu = !printOptions?.disableToolbarButton || imageExportOptionList.length > 0;
25
50
  const children = [];
26
51
  if (isZoomEnabled) {
27
52
  const Tooltip = slots.baseTooltip;
@@ -30,22 +55,109 @@ export function ChartsToolbarPro(props) {
30
55
  children.push(/*#__PURE__*/_jsx(Tooltip, _extends({}, slotProps.baseTooltip, {
31
56
  title: localeText.zoomIn,
32
57
  children: /*#__PURE__*/_jsx(ChartsToolbarZoomInTrigger, {
33
- render: /*#__PURE__*/_jsx(ToolbarButton, {}),
34
- children: /*#__PURE__*/_jsx(ZoomInIcon, _extends({}, slotProps.zoomInIcon))
58
+ render: /*#__PURE__*/_jsx(ToolbarButton, {
59
+ size: "small"
60
+ }),
61
+ children: /*#__PURE__*/_jsx(ZoomInIcon, _extends({
62
+ fontSize: "small"
63
+ }, slotProps.zoomInIcon))
35
64
  })
36
65
  }), "zoom-in"));
37
66
  children.push(/*#__PURE__*/_jsx(Tooltip, _extends({}, slotProps.baseTooltip, {
38
67
  title: localeText.zoomOut,
39
68
  children: /*#__PURE__*/_jsx(ChartsToolbarZoomOutTrigger, {
40
- render: /*#__PURE__*/_jsx(ToolbarButton, {}),
41
- children: /*#__PURE__*/_jsx(ZoomOutIcon, _extends({}, slotProps.zoomOutIcon))
69
+ render: /*#__PURE__*/_jsx(ToolbarButton, {
70
+ size: "small"
71
+ }),
72
+ children: /*#__PURE__*/_jsx(ZoomOutIcon, _extends({
73
+ fontSize: "small"
74
+ }, slotProps.zoomOutIcon))
42
75
  })
43
76
  }), "zoom-out"));
44
77
  }
78
+ if (showExportMenu) {
79
+ const Tooltip = slots.baseTooltip;
80
+ const MenuList = slots.baseMenuList;
81
+ const MenuItem = slots.baseMenuItem;
82
+ const ExportIcon = slots.exportIcon;
83
+ const closeExportMenu = () => setExportMenuOpen(false);
84
+ const handleListKeyDown = event => {
85
+ if (event.key === 'Tab') {
86
+ event.preventDefault();
87
+ }
88
+ if (isHideMenuKey(event.key)) {
89
+ closeExportMenu();
90
+ }
91
+ };
92
+ if (children.length > 0) {
93
+ children.push(/*#__PURE__*/_jsx(ChartsToolbarDivider, {}, "divider"));
94
+ }
95
+ children.push(/*#__PURE__*/_jsxs(React.Fragment, {
96
+ children: [/*#__PURE__*/_jsx(Tooltip, {
97
+ title: localeText.toolbarExport,
98
+ disableInteractive: exportMenuOpen,
99
+ children: /*#__PURE__*/_jsx(ToolbarButton, {
100
+ ref: exportMenuTriggerRef,
101
+ id: exportMenuTriggerId,
102
+ "aria-controls": exportMenuId,
103
+ "aria-haspopup": "true",
104
+ "aria-expanded": exportMenuOpen ? 'true' : undefined,
105
+ onClick: () => setExportMenuOpen(!exportMenuOpen),
106
+ size: "small",
107
+ children: /*#__PURE__*/_jsx(ExportIcon, {
108
+ fontSize: "small"
109
+ })
110
+ })
111
+ }), /*#__PURE__*/_jsx(ChartsMenu, {
112
+ target: exportMenuTriggerRef.current,
113
+ open: exportMenuOpen,
114
+ onClose: closeExportMenu,
115
+ position: "bottom-end",
116
+ children: /*#__PURE__*/_jsxs(MenuList, _extends({
117
+ id: exportMenuId,
118
+ "aria-labelledby": exportMenuTriggerId,
119
+ onKeyDown: handleListKeyDown,
120
+ autoFocusItem: true
121
+ }, slotProps?.baseMenuList, {
122
+ children: [!printOptions?.disableToolbarButton && /*#__PURE__*/_jsx(ChartsToolbarPrintExportTrigger, {
123
+ render: /*#__PURE__*/_jsx(MenuItem, _extends({
124
+ dense: true
125
+ }, slotProps?.baseMenuItem)),
126
+ options: printOptions,
127
+ onClick: closeExportMenu,
128
+ children: localeText.toolbarExportPrint
129
+ }), imageExportOptionList.map(imageExportOptions => /*#__PURE__*/_jsx(ChartsToolbarImageExportTrigger, {
130
+ render: /*#__PURE__*/_jsx(MenuItem, _extends({
131
+ dense: true
132
+ }, slotProps?.baseMenuItem)),
133
+ options: imageExportOptions,
134
+ onClick: closeExportMenu,
135
+ children: localeText.toolbarExportImage(imageExportOptions.type)
136
+ }, imageExportOptions.type))]
137
+ }))
138
+ })]
139
+ }, "export-menu"));
140
+ }
45
141
  if (children.length === 0) {
46
142
  return null;
47
143
  }
48
- return /*#__PURE__*/_jsx(Toolbar, _extends({}, props, {
144
+ return /*#__PURE__*/_jsx(Toolbar, _extends({}, other, {
49
145
  children: children
50
146
  }));
147
+ }
148
+ process.env.NODE_ENV !== "production" ? ChartsToolbarPro.propTypes = {
149
+ // ----------------------------- Warning --------------------------------
150
+ // | These PropTypes are generated from the TypeScript type definitions |
151
+ // | To update them edit the TypeScript types and run "pnpm proptypes" |
152
+ // ----------------------------------------------------------------------
153
+ imageExportOptions: PropTypes.arrayOf(PropTypes.shape({
154
+ fileName: PropTypes.string,
155
+ quality: PropTypes.number,
156
+ type: PropTypes.string.isRequired
157
+ })),
158
+ printOptions: PropTypes.object
159
+ } : void 0;
160
+ export { ChartsToolbarPro };
161
+ function isHideMenuKey(key) {
162
+ return key === 'Tab' || key === 'Escape';
51
163
  }
@@ -1,3 +1,5 @@
1
1
  export * from "./ChartsToolbarPro.js";
2
2
  export * from "./ChartsToolbarZoomInTrigger.js";
3
- export * from "./ChartsToolbarZoomOutTrigger.js";
3
+ export * from "./ChartsToolbarZoomOutTrigger.js";
4
+ export * from "./ChartsToolbarPrintExportTrigger.js";
5
+ export * from "./ChartsToolbarImageExportTrigger.js";
@@ -1,3 +1,5 @@
1
1
  export * from "./ChartsToolbarPro.js";
2
2
  export * from "./ChartsToolbarZoomInTrigger.js";
3
- export * from "./ChartsToolbarZoomOutTrigger.js";
3
+ export * from "./ChartsToolbarZoomOutTrigger.js";
4
+ export * from "./ChartsToolbarPrintExportTrigger.js";
5
+ export * from "./ChartsToolbarImageExportTrigger.js";
@@ -0,0 +1,14 @@
1
+ import * as React from 'react';
2
+ import { ChartBasePopperProps, Placement } from "../../internals/slots/chartBaseSlotProps.js";
3
+ export interface ChartsMenuProps extends Pick<ChartBasePopperProps, 'className' | 'onExited'> {
4
+ open: boolean;
5
+ target: HTMLElement | null;
6
+ onClose: (event?: Event) => void;
7
+ position?: Placement;
8
+ children: React.ReactNode;
9
+ }
10
+ declare function ChartsMenu(props: ChartsMenuProps): React.JSX.Element;
11
+ declare namespace ChartsMenu {
12
+ var propTypes: any;
13
+ }
14
+ export { ChartsMenu };
@@ -0,0 +1,67 @@
1
+ 'use client';
2
+
3
+ import _extends from "@babel/runtime/helpers/esm/extends";
4
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
5
+ const _excluded = ["open", "target", "onClose", "children", "position", "className", "onExited"];
6
+ import * as React from 'react';
7
+ import PropTypes from 'prop-types';
8
+ import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
9
+ import HTMLElementType from '@mui/utils/HTMLElementType';
10
+ import { useChartsSlots } from '@mui/x-charts/internals';
11
+ import { jsx as _jsx } from "react/jsx-runtime";
12
+ function ChartsMenu(props) {
13
+ const {
14
+ open,
15
+ target,
16
+ onClose,
17
+ children,
18
+ position,
19
+ onExited
20
+ } = props,
21
+ other = _objectWithoutPropertiesLoose(props, _excluded);
22
+ const {
23
+ slots,
24
+ slotProps
25
+ } = useChartsSlots();
26
+ const Popper = slots.basePopper;
27
+ const savedFocusRef = React.useRef(null);
28
+ useEnhancedEffect(() => {
29
+ if (open) {
30
+ savedFocusRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
31
+ } else {
32
+ savedFocusRef.current?.focus?.();
33
+ savedFocusRef.current = null;
34
+ }
35
+ }, [open]);
36
+ const handleClickAway = event => {
37
+ if (event.target && (target === event.target || target?.contains(event.target))) {
38
+ return;
39
+ }
40
+ onClose(event);
41
+ };
42
+ return /*#__PURE__*/_jsx(Popper, _extends({
43
+ open: open,
44
+ target: target,
45
+ transition: true,
46
+ placement: position,
47
+ onClickAway: handleClickAway,
48
+ onExited: onExited,
49
+ clickAwayMouseEvent: "onMouseDown"
50
+ }, other, slotProps?.basePopper, {
51
+ children: children
52
+ }));
53
+ }
54
+ process.env.NODE_ENV !== "production" ? ChartsMenu.propTypes = {
55
+ // ----------------------------- Warning --------------------------------
56
+ // | These PropTypes are generated from the TypeScript type definitions |
57
+ // | To update them edit the TypeScript types and run "pnpm proptypes" |
58
+ // ----------------------------------------------------------------------
59
+ children: PropTypes.node,
60
+ className: PropTypes.string,
61
+ onClose: PropTypes.func.isRequired,
62
+ onExited: PropTypes.func,
63
+ open: PropTypes.bool.isRequired,
64
+ position: PropTypes.oneOf(['bottom-end', 'bottom-start', 'bottom', 'left-end', 'left-start', 'left', 'right-end', 'right-start', 'right', 'top-end', 'top-start', 'top']),
65
+ target: HTMLElementType
66
+ } : void 0;
67
+ export { ChartsMenu };
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+ import { ChartBaseDividerProps } from "../../internals/slots/chartBaseSlotProps.js";
3
+ export interface ChartsToolbarDividerProps extends ChartBaseDividerProps {}
4
+ declare const ChartsToolbarDivider: React.ForwardRefExoticComponent<Omit<ChartsToolbarDividerProps, "ref"> & React.RefAttributes<HTMLHRElement>>;
5
+ export { ChartsToolbarDivider };
@@ -0,0 +1,40 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import * as React from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import { styled } from '@mui/system';
5
+ import { NotRendered, useChartsSlots } from '@mui/x-charts/internals';
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ // This is workaround because api-docs-builder does not support the `NotRendered<ChartBaseDividerProps>` syntax.
8
+ const NotRenderedDivider = NotRendered;
9
+ const Divider = styled(NotRenderedDivider, {
10
+ name: 'MuiChartsToolbar',
11
+ slot: 'Divider'
12
+ })(({
13
+ theme
14
+ }) => ({
15
+ margin: theme.spacing(0, 0.5),
16
+ height: '50%'
17
+ }));
18
+ const ChartsToolbarDivider = /*#__PURE__*/React.forwardRef(function ChartsToolbarDivider(props, ref) {
19
+ const {
20
+ slots,
21
+ slotProps
22
+ } = useChartsSlots();
23
+ return /*#__PURE__*/_jsx(Divider, _extends({
24
+ as: slots.baseDivider,
25
+ orientation: "vertical"
26
+ }, slotProps.baseDivider, props, {
27
+ ref: ref
28
+ }));
29
+ });
30
+ if (process.env.NODE_ENV !== "production") ChartsToolbarDivider.displayName = "ChartsToolbarDivider";
31
+ process.env.NODE_ENV !== "production" ? ChartsToolbarDivider.propTypes = {
32
+ // ----------------------------- Warning --------------------------------
33
+ // | These PropTypes are generated from the TypeScript type definitions |
34
+ // | To update them edit the TypeScript types and run "pnpm proptypes" |
35
+ // ----------------------------------------------------------------------
36
+ className: PropTypes.string,
37
+ orientation: PropTypes.oneOf(['horizontal', 'vertical']),
38
+ style: PropTypes.object
39
+ } : void 0;
40
+ export { ChartsToolbarDivider };
@@ -97,21 +97,21 @@ const useAggregatedData = () => {
97
97
  min: minPoint,
98
98
  max: maxPoint
99
99
  });
100
- const line = d3Line().x(d => xPosition(d.x, dataIndex, baseScaleConfig.data?.[dataIndex], d.stackOffset, d.useBandWidth)).y(d => yPosition(d.y, dataIndex, baseScaleConfig.data?.[dataIndex], d.stackOffset, d.useBandWidth)).curve(curve);
100
+ const bandPoints = curve({}).processPoints(values.map(v => ({
101
+ x: xPosition(v.x, dataIndex, baseScaleConfig.data?.[dataIndex], v.stackOffset, v.useBandWidth),
102
+ y: yPosition(v.y, dataIndex, baseScaleConfig.data?.[dataIndex], v.stackOffset, v.useBandWidth)
103
+ })));
104
+ const line = d3Line().x(v => v.x).y(v => v.y).curve(curve);
101
105
  return {
102
- d: line(values),
106
+ d: line(bandPoints),
103
107
  color,
104
108
  id,
105
109
  seriesId,
106
110
  dataIndex,
107
111
  variant: currentSeries.variant,
108
112
  label: sectionLabel !== false && _extends({}, positionLabel(_extends({}, sectionLabel, {
109
- xPosition,
110
- yPosition,
111
113
  isHorizontal,
112
- values,
113
- dataIndex,
114
- baseScaleData: baseScaleConfig.data ?? []
114
+ values: bandPoints
115
115
  })), alignLabel(sectionLabel ?? {}), {
116
116
  value: valueFormatter ? valueFormatter(currentSeries.data[dataIndex], {
117
117
  dataIndex
@@ -120,7 +120,7 @@ const useAggregatedData = () => {
120
120
  };
121
121
  });
122
122
  });
123
- return result.flat();
123
+ return result;
124
124
  }, [seriesData, xAxis, xAxisIds, yAxis, yAxisIds, gap]);
125
125
  return allData;
126
126
  };
@@ -131,41 +131,57 @@ function FunnelPlot(props) {
131
131
  other = _objectWithoutPropertiesLoose(props, _excluded);
132
132
  const data = useAggregatedData();
133
133
  return /*#__PURE__*/_jsxs(React.Fragment, {
134
- children: [data.map(({
135
- d,
136
- color,
137
- id,
138
- seriesId,
139
- dataIndex,
140
- variant
141
- }) => /*#__PURE__*/_createElement(FunnelSection, _extends({}, other, {
142
- d: d,
143
- color: color,
144
- key: id,
145
- dataIndex: dataIndex,
146
- seriesId: seriesId,
147
- variant: variant,
148
- onClick: onItemClick && (event => {
149
- onItemClick(event, {
150
- type: 'funnel',
134
+ children: [data.map(series => {
135
+ if (series.length === 0) {
136
+ return null;
137
+ }
138
+ return /*#__PURE__*/_jsx("g", {
139
+ "data-series": series[0].seriesId,
140
+ children: series.map(({
141
+ d,
142
+ color,
143
+ id,
151
144
  seriesId,
152
- dataIndex
153
- });
154
- })
155
- }))), data.map(({
156
- id,
157
- label,
158
- seriesId,
159
- dataIndex
160
- }) => {
161
- if (!label || !label.value) {
145
+ dataIndex,
146
+ variant
147
+ }) => /*#__PURE__*/_createElement(FunnelSection, _extends({}, other, {
148
+ d: d,
149
+ color: color,
150
+ key: id,
151
+ dataIndex: dataIndex,
152
+ seriesId: seriesId,
153
+ variant: variant,
154
+ onClick: onItemClick && (event => {
155
+ onItemClick(event, {
156
+ type: 'funnel',
157
+ seriesId,
158
+ dataIndex
159
+ });
160
+ })
161
+ })))
162
+ }, series[0].seriesId);
163
+ }), data.map(series => {
164
+ if (series.length === 0) {
162
165
  return null;
163
166
  }
164
- return /*#__PURE__*/_jsx(FunnelSectionLabel, _extends({
165
- label: label,
166
- dataIndex: dataIndex,
167
- seriesId: seriesId
168
- }, other), id);
167
+ return /*#__PURE__*/_jsx("g", {
168
+ "data-series": series[0].seriesId,
169
+ children: series.map(({
170
+ id,
171
+ label,
172
+ seriesId,
173
+ dataIndex
174
+ }) => {
175
+ if (!label || !label.value) {
176
+ return null;
177
+ }
178
+ return /*#__PURE__*/_jsx(FunnelSectionLabel, _extends({
179
+ label: label,
180
+ dataIndex: dataIndex,
181
+ seriesId: seriesId
182
+ }, other), id);
183
+ })
184
+ }, series[0].seriesId);
169
185
  })]
170
186
  });
171
187
  }
@@ -53,6 +53,8 @@ const FunnelSection = consumeSlots('MuiFunnelSection', 'funnelSection', {
53
53
  strokeWidth: isOutlined ? 1.5 : 0,
54
54
  cursor: onClick ? 'pointer' : 'unset',
55
55
  onClick: onClick,
56
+ "data-highlighted": isHighlighted || undefined,
57
+ "data-faded": isFaded || undefined,
56
58
  className: clsx(classes?.root, className, isOutlined ? classes?.outlined : classes?.filled, isHighlighted && classes?.highlighted, isFaded && classes?.faded)
57
59
  }, other, {
58
60
  ref: ref
@@ -1,5 +1,4 @@
1
- import { CurveGenerator } from '@mui/x-charts-vendor/d3-shape';
2
- import { CurveOptions } from "./curve.types.js";
1
+ import { FunnelCurveGenerator, CurveOptions, Point } from "./curve.types.js";
3
2
  /**
4
3
  * This is a custom "bump" curve generator.
5
4
  * It draws smooth curves for the 4 provided points,
@@ -8,7 +7,7 @@ import { CurveOptions } from "./curve.types.js";
8
7
  * The implementation is based on the d3-shape bump curve generator.
9
8
  * https://github.com/d3/d3-shape/blob/a82254af78f08799c71d7ab25df557c4872a3c51/src/curve/bump.js
10
9
  */
11
- export declare class Bump implements CurveGenerator {
10
+ export declare class Bump implements FunnelCurveGenerator {
12
11
  private context;
13
12
  private isHorizontal;
14
13
  private min;
@@ -24,6 +23,7 @@ export declare class Bump implements CurveGenerator {
24
23
  areaEnd(): void;
25
24
  lineStart(): void;
26
25
  lineEnd(): void;
26
+ processPoints(points: Point[]): Point[];
27
27
  point(x: number, y: number): void;
28
28
  private drawPath;
29
29
  private drawHorizontalPath;
@@ -47,6 +47,9 @@ export class Bump {
47
47
  areaEnd() {}
48
48
  lineStart() {}
49
49
  lineEnd() {}
50
+ processPoints(points) {
51
+ return points;
52
+ }
50
53
  point(x, y) {
51
54
  this.points.push({
52
55
  x,
@@ -1,3 +1,4 @@
1
+ import { CurveGenerator } from '@mui/x-charts-vendor/d3-shape';
1
2
  export type CurveOptions = {
2
3
  /**
3
4
  * The gap between each segment.
@@ -44,4 +45,16 @@ export type FunnelPointShape = 'square' | 'sharp';
44
45
  export type Point = {
45
46
  x: number;
46
47
  y: number;
47
- };
48
+ };
49
+ export interface FunnelCurveGenerator extends CurveGenerator {
50
+ /**
51
+ * Processes the points to create a curve based on the provided options.
52
+ * This does not draw the curve but prepares the points for rendering.
53
+ *
54
+ * @param points The points to process.
55
+ * @param options The options for the curve.
56
+ * @returns The processed points.
57
+ */
58
+ processPoints(points: Point[], xPosition: PositionGetter, yPosition: PositionGetter): Point[];
59
+ }
60
+ export type PositionGetter = (value: number, bandIndex: number, bandIdentifier: string | number, stackOffset?: number, useBand?: boolean) => number;
@@ -1,3 +1,8 @@
1
- import { CurveFactory } from '@mui/x-charts-vendor/d3-shape';
1
+ import type { Path } from '@mui/x-charts-vendor/d3-path';
2
2
  import { CurveOptions, FunnelCurveType } from "./curve.types.js";
3
- export declare const getFunnelCurve: (curve: FunnelCurveType | undefined, options: CurveOptions) => CurveFactory;
3
+ import { Step } from "./step.js";
4
+ import { Linear } from "./linear.js";
5
+ import { Bump } from "./bump.js";
6
+ import { Pyramid } from "./pyramid.js";
7
+ import { StepPyramid } from "./step-pyramid.js";
8
+ export declare const getFunnelCurve: (curve: FunnelCurveType | undefined, options: CurveOptions) => (context: CanvasRenderingContext2D | Path) => Step | Linear | Bump | Pyramid | StepPyramid;
@@ -1,5 +1,4 @@
1
- import { CurveGenerator } from '@mui/x-charts-vendor/d3-shape';
2
- import { CurveOptions } from "./curve.types.js";
1
+ import { FunnelCurveGenerator, CurveOptions, Point } from "./curve.types.js";
3
2
  /**
4
3
  * This is a custom "linear" curve generator.
5
4
  * It draws straight lines for the 4 provided points,
@@ -8,7 +7,7 @@ import { CurveOptions } from "./curve.types.js";
8
7
  * The implementation is based on the d3-shape linear curve generator.
9
8
  * https://github.com/d3/d3-shape/blob/a82254af78f08799c71d7ab25df557c4872a3c51/src/curve/linear.js
10
9
  */
11
- export declare class Linear implements CurveGenerator {
10
+ export declare class Linear implements FunnelCurveGenerator {
12
11
  private context;
13
12
  private position;
14
13
  private sections;
@@ -36,5 +35,6 @@ export declare class Linear implements CurveGenerator {
36
35
  lineStart(): void;
37
36
  lineEnd(): void;
38
37
  protected getBorderRadius(): number | number[];
38
+ processPoints(points: Point[]): Point[];
39
39
  point(xIn: number, yIn: number): void;
40
40
  }
@@ -92,7 +92,7 @@ export class Linear {
92
92
  }
93
93
  // Is smallest section and shaped like a triangle
94
94
  if (this.position === this.sections - 1 && this.pointShape === 'sharp') {
95
- return [this.borderRadius];
95
+ return [0, 0, this.borderRadius];
96
96
  }
97
97
 
98
98
  // Is smallest section
@@ -102,19 +102,11 @@ export class Linear {
102
102
  }
103
103
  return 0;
104
104
  }
105
- point(xIn, yIn) {
106
- this.points.push({
107
- x: xIn,
108
- y: yIn
109
- });
110
- if (this.points.length < 4) {
111
- return;
112
- }
113
-
105
+ processPoints(points) {
114
106
  // Add gaps where they are needed.
115
- this.points = this.points.map((point, index) => {
116
- const slopeStart = this.points.at(index <= 1 ? 0 : 3);
117
- const slopeEnd = this.points.at(index <= 1 ? 1 : 2);
107
+ const processedPoints = points.map((point, index) => {
108
+ const slopeStart = points.at(index <= 1 ? 0 : 3);
109
+ const slopeEnd = points.at(index <= 1 ? 1 : 2);
118
110
  if (this.isHorizontal) {
119
111
  const yGetter = lerpY(slopeStart.x - this.gap, slopeStart.y, slopeEnd.x, slopeEnd.y);
120
112
  return {
@@ -136,15 +128,15 @@ export class Linear {
136
128
  let firstPoint = null;
137
129
  let secondPoint = null;
138
130
  if (isFirstSection && this.isIncreasing) {
139
- firstPoint = this.points[1];
140
- secondPoint = this.points[2];
131
+ firstPoint = processedPoints[1];
132
+ secondPoint = processedPoints[2];
141
133
  }
142
134
  if (isLastSection && !this.isIncreasing) {
143
- firstPoint = this.points[3];
144
- secondPoint = this.points[0];
135
+ firstPoint = processedPoints[3];
136
+ secondPoint = processedPoints[0];
145
137
  }
146
138
  if (firstPoint && secondPoint) {
147
- this.points = [
139
+ return [
148
140
  // Sharp point at the start
149
141
  this.isHorizontal ? {
150
142
  x: this.max.x,
@@ -157,6 +149,19 @@ export class Linear {
157
149
  firstPoint, secondPoint];
158
150
  }
159
151
  }
152
+ return processedPoints;
153
+ }
154
+ point(xIn, yIn) {
155
+ this.points.push({
156
+ x: xIn,
157
+ y: yIn
158
+ });
159
+ const isLastSection = this.position === this.sections - 1;
160
+ const isFirstSection = this.position === 0;
161
+ const isSharpPoint = this.pointShape === 'sharp' && (isLastSection && !this.isIncreasing || isFirstSection && this.isIncreasing);
162
+ if (this.points.length < (isSharpPoint ? 3 : 4)) {
163
+ return;
164
+ }
160
165
  borderRadiusPolygon(this.context, this.points, this.getBorderRadius());
161
166
  }
162
167
  }
@@ -1,12 +1,11 @@
1
- import { CurveGenerator } from '@mui/x-charts-vendor/d3-shape';
2
- import { CurveOptions } from "./curve.types.js";
1
+ import { FunnelCurveGenerator, CurveOptions, Point } from "./curve.types.js";
3
2
  /**
4
3
  * This is a custom "pyramid" curve generator.
5
4
  * It draws straight lines for the 4 provided points. The slopes are calculated
6
5
  * based on the min and max values of the x and y axes.
7
6
  * with the option to add a gap between sections while also properly handling the border radius.
8
7
  */
9
- export declare class Pyramid implements CurveGenerator {
8
+ export declare class Pyramid implements FunnelCurveGenerator {
10
9
  private context;
11
10
  private position;
12
11
  private sections;
@@ -32,5 +31,6 @@ export declare class Pyramid implements CurveGenerator {
32
31
  lineStart(): void;
33
32
  lineEnd(): void;
34
33
  protected getBorderRadius(): number | number[];
34
+ processPoints(points: Point[]): Point[];
35
35
  point(xIn: number, yIn: number): void;
36
36
  }