@mui/x-charts-pro 8.5.0 → 8.5.1

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 (90) hide show
  1. package/BarChartPro/BarChartPro.js +1 -1
  2. package/CHANGELOG.md +112 -0
  3. package/ChartContainerPro/ChartProApi.d.ts +2 -0
  4. package/ChartDataProviderPro/ChartDataProviderPro.js +1 -1
  5. package/ChartZoomSlider/internals/ChartAxisZoomSliderActiveTrack.d.ts +0 -2
  6. package/ChartZoomSlider/internals/ChartAxisZoomSliderActiveTrack.js +41 -9
  7. package/ChartZoomSlider/internals/ChartAxisZoomSliderTrack.js +0 -22
  8. package/ChartsToolbarPro/ChartsToolbarPro.d.ts +1 -4
  9. package/ChartsToolbarPro/ChartsToolbarPro.js +7 -13
  10. package/ChartsToolbarPro/{ChartsToolbarZoomInButton.d.ts → ChartsToolbarZoomInTrigger.d.ts} +6 -5
  11. package/ChartsToolbarPro/{ChartsToolbarZoomInButton.js → ChartsToolbarZoomInTrigger.js} +7 -6
  12. package/ChartsToolbarPro/{ChartsToolbarZoomOutButton.d.ts → ChartsToolbarZoomOutTrigger.d.ts} +6 -5
  13. package/ChartsToolbarPro/{ChartsToolbarZoomOutButton.js → ChartsToolbarZoomOutTrigger.js} +7 -6
  14. package/ChartsToolbarPro/index.d.ts +2 -2
  15. package/ChartsToolbarPro/index.js +8 -8
  16. package/FunnelChart/FunnelPlot.js +10 -22
  17. package/FunnelChart/FunnelSection.d.ts +1 -1
  18. package/FunnelChart/FunnelSectionLabel.d.ts +21 -0
  19. package/FunnelChart/FunnelSectionLabel.js +52 -0
  20. package/FunnelChart/curves/bump.d.ts +10 -4
  21. package/FunnelChart/curves/bump.js +73 -41
  22. package/FunnelChart/curves/curve.types.d.ts +6 -1
  23. package/FunnelChart/curves/getFunnelCurve.js +3 -0
  24. package/FunnelChart/curves/linear.d.ts +9 -1
  25. package/FunnelChart/curves/linear.js +82 -5
  26. package/FunnelChart/funnel.types.d.ts +1 -0
  27. package/FunnelChart/funnelPlotSlots.types.d.ts +11 -0
  28. package/FunnelChart/funnelSectionClasses.d.ts +2 -0
  29. package/FunnelChart/funnelSectionClasses.js +17 -4
  30. package/FunnelChart/index.d.ts +3 -1
  31. package/FunnelChart/index.js +18 -2
  32. package/Heatmap/Heatmap.d.ts +5 -0
  33. package/Heatmap/Heatmap.js +10 -2
  34. package/Heatmap/HeatmapTooltip/HeatmapTooltipAxesValue.d.ts +1 -1
  35. package/LineChartPro/LineChartPro.js +1 -1
  36. package/PieChartPro/PieChartPro.d.ts +21 -0
  37. package/PieChartPro/PieChartPro.js +204 -0
  38. package/PieChartPro/PieChartPro.plugins.d.ts +4 -0
  39. package/PieChartPro/PieChartPro.plugins.js +9 -0
  40. package/PieChartPro/index.d.ts +1 -0
  41. package/PieChartPro/index.js +16 -0
  42. package/RadarChartPro/RadarChartPro.js +1 -1
  43. package/ScatterChartPro/ScatterChartPro.js +1 -1
  44. package/esm/BarChartPro/BarChartPro.js +1 -1
  45. package/esm/ChartContainerPro/ChartProApi.d.ts +2 -0
  46. package/esm/ChartDataProviderPro/ChartDataProviderPro.js +1 -1
  47. package/esm/ChartZoomSlider/internals/ChartAxisZoomSliderActiveTrack.d.ts +0 -2
  48. package/esm/ChartZoomSlider/internals/ChartAxisZoomSliderActiveTrack.js +42 -10
  49. package/esm/ChartZoomSlider/internals/ChartAxisZoomSliderTrack.js +0 -22
  50. package/esm/ChartsToolbarPro/ChartsToolbarPro.d.ts +1 -4
  51. package/esm/ChartsToolbarPro/ChartsToolbarPro.js +8 -14
  52. package/esm/ChartsToolbarPro/{ChartsToolbarZoomInButton.d.ts → ChartsToolbarZoomInTrigger.d.ts} +6 -5
  53. package/esm/ChartsToolbarPro/{ChartsToolbarZoomInButton.js → ChartsToolbarZoomInTrigger.js} +8 -7
  54. package/esm/ChartsToolbarPro/{ChartsToolbarZoomOutButton.d.ts → ChartsToolbarZoomOutTrigger.d.ts} +6 -5
  55. package/esm/ChartsToolbarPro/{ChartsToolbarZoomOutButton.js → ChartsToolbarZoomOutTrigger.js} +8 -7
  56. package/esm/ChartsToolbarPro/index.d.ts +2 -2
  57. package/esm/ChartsToolbarPro/index.js +2 -2
  58. package/esm/FunnelChart/FunnelPlot.js +10 -22
  59. package/esm/FunnelChart/FunnelSection.d.ts +1 -1
  60. package/esm/FunnelChart/FunnelSectionLabel.d.ts +21 -0
  61. package/esm/FunnelChart/FunnelSectionLabel.js +46 -0
  62. package/esm/FunnelChart/curves/bump.d.ts +10 -4
  63. package/esm/FunnelChart/curves/bump.js +73 -41
  64. package/esm/FunnelChart/curves/curve.types.d.ts +6 -1
  65. package/esm/FunnelChart/curves/getFunnelCurve.js +3 -0
  66. package/esm/FunnelChart/curves/linear.d.ts +9 -1
  67. package/esm/FunnelChart/curves/linear.js +82 -5
  68. package/esm/FunnelChart/funnel.types.d.ts +1 -0
  69. package/esm/FunnelChart/funnelPlotSlots.types.d.ts +11 -0
  70. package/esm/FunnelChart/funnelSectionClasses.d.ts +2 -0
  71. package/esm/FunnelChart/funnelSectionClasses.js +15 -3
  72. package/esm/FunnelChart/index.d.ts +3 -1
  73. package/esm/FunnelChart/index.js +3 -1
  74. package/esm/Heatmap/Heatmap.d.ts +5 -0
  75. package/esm/Heatmap/Heatmap.js +10 -2
  76. package/esm/Heatmap/HeatmapTooltip/HeatmapTooltipAxesValue.d.ts +1 -1
  77. package/esm/LineChartPro/LineChartPro.js +1 -1
  78. package/esm/PieChartPro/PieChartPro.d.ts +21 -0
  79. package/esm/PieChartPro/PieChartPro.js +197 -0
  80. package/esm/PieChartPro/PieChartPro.plugins.d.ts +4 -0
  81. package/esm/PieChartPro/PieChartPro.plugins.js +3 -0
  82. package/esm/PieChartPro/index.d.ts +1 -0
  83. package/esm/PieChartPro/index.js +1 -0
  84. package/esm/RadarChartPro/RadarChartPro.js +1 -1
  85. package/esm/ScatterChartPro/ScatterChartPro.js +1 -1
  86. package/esm/index.d.ts +1 -0
  87. package/esm/index.js +2 -1
  88. package/index.d.ts +1 -0
  89. package/index.js +12 -1
  90. package/package.json +7 -7
@@ -5,14 +5,15 @@ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWith
5
5
  const _excluded = ["render"];
6
6
  import * as React from 'react';
7
7
  import PropTypes from 'prop-types';
8
- import { useChartContext, useChartsSlots, useSelector } from '@mui/x-charts/internals';
8
+ import { useChartContext, useSelector, useChartsSlots } from '@mui/x-charts/internals';
9
9
  import { useComponentRenderer } from '@mui/x-internals/useComponentRenderer';
10
10
  import { selectorChartCanZoomOut } from "../internals/plugins/useChartProZoom/index.js";
11
11
  import { jsx as _jsx } from "react/jsx-runtime";
12
12
  /**
13
- * The zoom-out button for the chart toolbar.
13
+ * A button that zooms the chart out.
14
+ * It renders the `baseButton` slot.
14
15
  */
15
- const ChartsToolbarZoomOutButton = /*#__PURE__*/React.forwardRef(function ChartsToolbarZoomOutButton(_ref, ref) {
16
+ const ChartsToolbarZoomOutTrigger = /*#__PURE__*/React.forwardRef(function ChartsToolbarZoomOutTrigger(_ref, ref) {
16
17
  let {
17
18
  render
18
19
  } = _ref,
@@ -26,7 +27,7 @@ const ChartsToolbarZoomOutButton = /*#__PURE__*/React.forwardRef(function Charts
26
27
  store
27
28
  } = useChartContext();
28
29
  const disabled = useSelector(store, selectorChartCanZoomOut);
29
- const element = useComponentRenderer(slots.baseIconButton, render, _extends({}, slotProps?.baseIconButton, {
30
+ const element = useComponentRenderer(slots.baseButton, render, _extends({}, slotProps.baseButton, {
30
31
  onClick: () => instance.zoomOut(),
31
32
  disabled
32
33
  }, other, {
@@ -36,8 +37,8 @@ const ChartsToolbarZoomOutButton = /*#__PURE__*/React.forwardRef(function Charts
36
37
  children: element
37
38
  });
38
39
  });
39
- if (process.env.NODE_ENV !== "production") ChartsToolbarZoomOutButton.displayName = "ChartsToolbarZoomOutButton";
40
- process.env.NODE_ENV !== "production" ? ChartsToolbarZoomOutButton.propTypes = {
40
+ if (process.env.NODE_ENV !== "production") ChartsToolbarZoomOutTrigger.displayName = "ChartsToolbarZoomOutTrigger";
41
+ process.env.NODE_ENV !== "production" ? ChartsToolbarZoomOutTrigger.propTypes = {
41
42
  // ----------------------------- Warning --------------------------------
42
43
  // | These PropTypes are generated from the TypeScript type definitions |
43
44
  // | To update them edit the TypeScript types and run "pnpm proptypes" |
@@ -47,4 +48,4 @@ process.env.NODE_ENV !== "production" ? ChartsToolbarZoomOutButton.propTypes = {
47
48
  */
48
49
  render: PropTypes.oneOfType([PropTypes.element, PropTypes.func])
49
50
  } : void 0;
50
- export { ChartsToolbarZoomOutButton };
51
+ export { ChartsToolbarZoomOutTrigger };
@@ -1,3 +1,3 @@
1
1
  export * from "./ChartsToolbarPro.js";
2
- export * from "./ChartsToolbarZoomInButton.js";
3
- export * from "./ChartsToolbarZoomOutButton.js";
2
+ export * from "./ChartsToolbarZoomInTrigger.js";
3
+ export * from "./ChartsToolbarZoomOutTrigger.js";
@@ -1,3 +1,3 @@
1
1
  export * from "./ChartsToolbarPro.js";
2
- export * from "./ChartsToolbarZoomInButton.js";
3
- export * from "./ChartsToolbarZoomOutButton.js";
2
+ export * from "./ChartsToolbarZoomInTrigger.js";
3
+ export * from "./ChartsToolbarZoomOutTrigger.js";
@@ -6,11 +6,11 @@ import PropTypes from 'prop-types';
6
6
  import { line as d3Line } from '@mui/x-charts-vendor/d3-shape';
7
7
  import { cartesianSeriesTypes } from '@mui/x-charts/internals';
8
8
  import { useXAxes, useYAxes } from '@mui/x-charts/hooks';
9
- import { useTheme } from '@mui/material/styles';
10
9
  import { FunnelSection } from "./FunnelSection.js";
11
10
  import { alignLabel, positionLabel } from "./labelUtils.js";
12
11
  import { useFunnelSeriesContext } from "../hooks/useFunnelSeries.js";
13
12
  import { getFunnelCurve } from "./curves/index.js";
13
+ import { FunnelSectionLabel } from "./FunnelSectionLabel.js";
14
14
  import { createElement as _createElement } from "react";
15
15
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
16
16
  cartesianSeriesTypes.addType('funnel');
@@ -122,7 +122,6 @@ function FunnelPlot(props) {
122
122
  gap
123
123
  } = props,
124
124
  other = _objectWithoutPropertiesLoose(props, _excluded);
125
- const theme = useTheme();
126
125
  const data = useAggregatedData(gap);
127
126
  return /*#__PURE__*/_jsxs(React.Fragment, {
128
127
  children: [data.map(({
@@ -148,29 +147,18 @@ function FunnelPlot(props) {
148
147
  })
149
148
  }))), data.map(({
150
149
  id,
151
- label
150
+ label,
151
+ seriesId,
152
+ dataIndex
152
153
  }) => {
153
- if (!label) {
154
+ if (!label || !label.value) {
154
155
  return null;
155
156
  }
156
- return /*#__PURE__*/_jsx("text", {
157
- x: label.x,
158
- y: label.y,
159
- textAnchor: label.textAnchor,
160
- dominantBaseline: label.dominantBaseline,
161
- stroke: "none",
162
- pointerEvents: "none",
163
- fontFamily: theme.typography.body2.fontFamily,
164
- fontSize: theme.typography.body2.fontSize,
165
- fontSizeAdjust: theme.typography.body2.fontSizeAdjust,
166
- fontWeight: theme.typography.body2.fontWeight,
167
- letterSpacing: theme.typography.body2.letterSpacing,
168
- fontStretch: theme.typography.body2.fontStretch,
169
- fontStyle: theme.typography.body2.fontStyle,
170
- fontVariant: theme.typography.body2.fontVariant,
171
- fill: (theme.vars || theme)?.palette?.text?.primary,
172
- children: label.value
173
- }, id);
157
+ return /*#__PURE__*/_jsx(FunnelSectionLabel, _extends({
158
+ label: label,
159
+ dataIndex: dataIndex,
160
+ seriesId: seriesId
161
+ }, other), id);
174
162
  })]
175
163
  });
176
164
  }
@@ -8,7 +8,7 @@ export interface FunnelSectionProps extends Omit<React.SVGProps<SVGPathElement>,
8
8
  classes?: Partial<FunnelSectionClasses>;
9
9
  variant?: 'filled' | 'outlined';
10
10
  }
11
- export declare const FunnelSectionPath: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, React.SVGProps<SVGPathElement>, {}>;
11
+ export declare const FunnelSectionPath: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material/styles").Theme>, React.SVGProps<SVGPathElement>, {}>;
12
12
  /**
13
13
  * @ignore - internal component.
14
14
  */
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+ import { SeriesId } from '@mui/x-charts/internals';
3
+ import { FunnelSectionClasses } from "./funnelSectionClasses.js";
4
+ export interface FunnelSectionLabelConfig {
5
+ x: number;
6
+ y: number;
7
+ value: string | null;
8
+ textAnchor?: React.SVGProps<SVGTextElement>['textAnchor'];
9
+ dominantBaseline?: React.SVGProps<SVGTextElement>['dominantBaseline'];
10
+ }
11
+ export interface FunnelSectionLabelProps extends Omit<React.SVGProps<SVGTextElement>, 'ref' | 'id'> {
12
+ classes?: Partial<FunnelSectionClasses>;
13
+ label: FunnelSectionLabelConfig;
14
+ seriesId: SeriesId;
15
+ dataIndex: number;
16
+ }
17
+ /**
18
+ * @ignore - internal component.
19
+ */
20
+ declare const FunnelSectionLabel: React.ForwardRefExoticComponent<FunnelSectionLabelProps & React.RefAttributes<{}>>;
21
+ export { FunnelSectionLabel };
@@ -0,0 +1,46 @@
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 = ["classes", "color", "onClick", "className", "label", "seriesId", "dataIndex"];
6
+ import * as React from 'react';
7
+ import { useTheme } from '@mui/material/styles';
8
+ import { consumeSlots } from '@mui/x-charts/internals';
9
+ import { useLabelUtilityClasses } from "./funnelSectionClasses.js";
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ /**
12
+ * @ignore - internal component.
13
+ */
14
+ const FunnelSectionLabel = consumeSlots('MuiFunnelSectionLabel', 'funnelSectionLabel', {
15
+ classesResolver: useLabelUtilityClasses
16
+ }, /*#__PURE__*/React.forwardRef(function FunnelSectionLabel(props, ref) {
17
+ const {
18
+ classes,
19
+ label
20
+ } = props,
21
+ other = _objectWithoutPropertiesLoose(props, _excluded);
22
+ const theme = useTheme();
23
+ return /*#__PURE__*/_jsx("text", _extends({
24
+ stroke: "none",
25
+ pointerEvents: "none",
26
+ fontFamily: theme.typography.body2.fontFamily,
27
+ fontSize: theme.typography.body2.fontSize,
28
+ fontSizeAdjust: theme.typography.body2.fontSizeAdjust,
29
+ fontWeight: theme.typography.body2.fontWeight,
30
+ letterSpacing: theme.typography.body2.letterSpacing,
31
+ fontStretch: theme.typography.body2.fontStretch,
32
+ fontStyle: theme.typography.body2.fontStyle,
33
+ fontVariant: theme.typography.body2.fontVariant,
34
+ fill: (theme.vars || theme)?.palette?.text?.primary,
35
+ className: classes?.label,
36
+ x: label.x,
37
+ y: label.y,
38
+ textAnchor: label.textAnchor ?? 'middle',
39
+ dominantBaseline: label.dominantBaseline ?? 'central'
40
+ }, other, {
41
+ ref: ref,
42
+ children: label.value
43
+ }));
44
+ }));
45
+ if (process.env.NODE_ENV !== "production") FunnelSectionLabel.displayName = "FunnelSectionLabel";
46
+ export { FunnelSectionLabel };
@@ -10,18 +10,24 @@ import { CurveOptions } from "./curve.types.js";
10
10
  */
11
11
  export declare class Bump implements CurveGenerator {
12
12
  private context;
13
- private x;
14
- private y;
15
- private currentPoint;
16
13
  private isHorizontal;
17
14
  private gap;
15
+ private min;
16
+ private max;
17
+ private points;
18
18
  constructor(context: CanvasRenderingContext2D, {
19
19
  isHorizontal,
20
- gap
20
+ gap,
21
+ min,
22
+ max,
23
+ isIncreasing
21
24
  }: CurveOptions);
22
25
  areaStart(): void;
23
26
  areaEnd(): void;
24
27
  lineStart(): void;
25
28
  lineEnd(): void;
26
29
  point(x: number, y: number): void;
30
+ private drawPath;
31
+ private drawHorizontalPath;
32
+ private drawVerticalPath;
27
33
  }
@@ -11,64 +11,96 @@
11
11
  export class Bump {
12
12
  constructor(context, {
13
13
  isHorizontal,
14
- gap
14
+ gap,
15
+ min,
16
+ max,
17
+ isIncreasing
15
18
  }) {
16
19
  this.context = void 0;
17
- this.x = NaN;
18
- this.y = NaN;
19
- this.currentPoint = 0;
20
20
  this.isHorizontal = false;
21
21
  this.gap = 0;
22
+ this.min = {
23
+ x: 0,
24
+ y: 0
25
+ };
26
+ this.max = {
27
+ x: 0,
28
+ y: 0
29
+ };
30
+ this.points = [];
22
31
  this.context = context;
23
32
  this.isHorizontal = isHorizontal ?? false;
24
33
  this.gap = (gap ?? 0) / 2;
34
+ this.min = min ?? {
35
+ x: 0,
36
+ y: 0
37
+ };
38
+ this.max = max ?? {
39
+ x: 0,
40
+ y: 0
41
+ };
42
+ if (isIncreasing) {
43
+ const currentMin = this.min;
44
+ const currentMax = this.max;
45
+ this.min = currentMax;
46
+ this.max = currentMin;
47
+ }
25
48
  }
26
49
  areaStart() {}
27
50
  areaEnd() {}
28
51
  lineStart() {}
29
52
  lineEnd() {}
30
53
  point(x, y) {
31
- x = +x;
32
- y = +y;
33
-
34
- // 0 is the top-left corner.
35
- if (this.isHorizontal) {
36
- if (this.currentPoint === 0) {
37
- this.context.moveTo(x + this.gap, y);
38
- this.context.lineTo(x + this.gap, y);
39
- } else if (this.currentPoint === 1) {
40
- this.context.bezierCurveTo((this.x + x) / 2, this.y, (this.x + x) / 2, y, x - this.gap, y);
41
- } else if (this.currentPoint === 2) {
42
- this.context.lineTo(x - this.gap, y);
43
- } else {
44
- this.context.bezierCurveTo((this.x + x) / 2, this.y, (this.x + x) / 2, y, x + this.gap, y);
45
- }
46
- if (this.currentPoint === 3) {
47
- this.context.closePath();
48
- }
49
- this.currentPoint += 1;
50
- this.x = x;
51
- this.y = y;
54
+ this.points.push({
55
+ x,
56
+ y
57
+ });
58
+ if (this.points.length < 4) {
52
59
  return;
53
60
  }
54
61
 
55
- // 0 is the top-right corner.
56
- if (this.currentPoint === 0) {
57
- // X from Y
58
- this.context.moveTo(x, y + this.gap);
59
- this.context.lineTo(x, y + this.gap);
60
- } else if (this.currentPoint === 1) {
61
- this.context.bezierCurveTo(this.x, (this.y + y) / 2, x, (this.y + y) / 2, x, y - this.gap);
62
- } else if (this.currentPoint === 2) {
63
- this.context.lineTo(x, y - this.gap);
62
+ // Draw the path using bezier curves
63
+ this.drawPath();
64
+ }
65
+ drawPath() {
66
+ if (this.isHorizontal) {
67
+ this.drawHorizontalPath();
64
68
  } else {
65
- this.context.bezierCurveTo(this.x, (this.y + y) / 2, x, (this.y + y) / 2, x, y + this.gap);
66
- }
67
- if (this.currentPoint === 3) {
68
- this.context.closePath();
69
+ this.drawVerticalPath();
69
70
  }
70
- this.currentPoint += 1;
71
- this.x = x;
72
- this.y = y;
71
+ }
72
+ drawHorizontalPath() {
73
+ const [p0, p1, p2, p3] = this.points;
74
+
75
+ // 0 is the top-left corner
76
+ this.context.moveTo(p0.x + this.gap, p0.y);
77
+ this.context.lineTo(p0.x + this.gap, p0.y);
78
+
79
+ // Bezier curve to point 1
80
+ this.context.bezierCurveTo((p0.x + p1.x) / 2, p0.y, (p0.x + p1.x) / 2, p1.y, p1.x - this.gap, p1.y);
81
+
82
+ // Line to point 2
83
+ this.context.lineTo(p2.x - this.gap, p2.y);
84
+
85
+ // Bezier curve back to point 3
86
+ this.context.bezierCurveTo((p2.x + p3.x) / 2, p2.y, (p2.x + p3.x) / 2, p3.y, p3.x + this.gap, p3.y);
87
+ this.context.closePath();
88
+ }
89
+ drawVerticalPath() {
90
+ const [p0, p1, p2, p3] = this.points;
91
+
92
+ // 0 is the top-right corner
93
+ this.context.moveTo(p0.x, p0.y + this.gap);
94
+ this.context.lineTo(p0.x, p0.y + this.gap);
95
+
96
+ // Bezier curve to point 1
97
+ this.context.bezierCurveTo(p0.x, (p0.y + p1.y) / 2, p1.x, (p0.y + p1.y) / 2, p1.x, p1.y - this.gap);
98
+
99
+ // Line to point 2
100
+ this.context.lineTo(p2.x, p2.y - this.gap);
101
+
102
+ // Bezier curve back to point 3
103
+ this.context.bezierCurveTo(p2.x, (p2.y + p3.y) / 2, p3.x, (p2.y + p3.y) / 2, p3.x, p3.y + this.gap);
104
+ this.context.closePath();
73
105
  }
74
106
  }
@@ -34,8 +34,13 @@ export type CurveOptions = {
34
34
  * The maximum point for all the segments.
35
35
  */
36
36
  max?: Point;
37
+ /**
38
+ * The shape of the point of the funnel for the curves that support it.
39
+ */
40
+ pointShape?: FunnelPointShape;
37
41
  };
38
- export type FunnelCurveType = 'linear' | 'step' | 'bump' | 'pyramid' | 'step-pyramid';
42
+ export type FunnelCurveType = 'linear' | 'linear-sharp' | 'step' | 'bump' | 'pyramid' | 'step-pyramid';
43
+ export type FunnelPointShape = 'square' | 'sharp';
39
44
  export type Point = {
40
45
  x: number;
41
46
  y: number;
@@ -19,5 +19,8 @@ const curveConstructor = curve => {
19
19
  return Linear;
20
20
  };
21
21
  export const getFunnelCurve = (curve, options) => {
22
+ if (curve === 'linear-sharp') {
23
+ options.pointShape = 'sharp';
24
+ }
22
25
  return context => new (curveConstructor(curve))(context, options);
23
26
  };
@@ -13,15 +13,23 @@ export declare class Linear implements CurveGenerator {
13
13
  private position;
14
14
  private sections;
15
15
  private isHorizontal;
16
+ private isIncreasing;
16
17
  private gap;
17
18
  private borderRadius;
19
+ private min;
20
+ private max;
18
21
  private points;
22
+ private pointShape;
19
23
  constructor(context: CanvasRenderingContext2D, {
20
24
  isHorizontal,
21
25
  gap,
22
26
  position,
23
27
  sections,
24
- borderRadius
28
+ borderRadius,
29
+ min,
30
+ max,
31
+ isIncreasing,
32
+ pointShape
25
33
  }: CurveOptions);
26
34
  areaStart(): void;
27
35
  areaEnd(): void;
@@ -17,21 +17,51 @@ export class Linear {
17
17
  gap,
18
18
  position,
19
19
  sections,
20
- borderRadius
20
+ borderRadius,
21
+ min,
22
+ max,
23
+ isIncreasing,
24
+ pointShape
21
25
  }) {
22
26
  this.context = void 0;
23
27
  this.position = 0;
24
28
  this.sections = 0;
25
29
  this.isHorizontal = false;
30
+ this.isIncreasing = false;
26
31
  this.gap = 0;
27
32
  this.borderRadius = 0;
33
+ this.min = {
34
+ x: 0,
35
+ y: 0
36
+ };
37
+ this.max = {
38
+ x: 0,
39
+ y: 0
40
+ };
28
41
  this.points = [];
42
+ this.pointShape = 'square';
29
43
  this.context = context;
30
44
  this.isHorizontal = isHorizontal ?? false;
31
45
  this.gap = (gap ?? 0) / 2;
32
46
  this.position = position ?? 0;
33
47
  this.sections = sections ?? 1;
34
48
  this.borderRadius = borderRadius ?? 0;
49
+ this.isIncreasing = isIncreasing ?? false;
50
+ this.min = min ?? {
51
+ x: 0,
52
+ y: 0
53
+ };
54
+ this.max = max ?? {
55
+ x: 0,
56
+ y: 0
57
+ };
58
+ this.pointShape = pointShape ?? 'square';
59
+ if (isIncreasing) {
60
+ const currentMin = this.min;
61
+ const currentMax = this.max;
62
+ this.min = currentMax;
63
+ this.max = currentMin;
64
+ }
35
65
  }
36
66
  areaStart() {}
37
67
  areaEnd() {}
@@ -41,11 +71,34 @@ export class Linear {
41
71
  if (this.gap > 0) {
42
72
  return this.borderRadius;
43
73
  }
44
- if (this.position === 0) {
45
- return [0, 0, this.borderRadius, this.borderRadius];
74
+ if (this.isIncreasing) {
75
+ // Is largest section
76
+ if (this.position === this.sections - 1) {
77
+ return [this.borderRadius, this.borderRadius];
78
+ }
79
+ // Is smallest section and shaped like a triangle
80
+ if (this.position === 0 && this.pointShape === 'sharp') {
81
+ return [0, 0, this.borderRadius];
82
+ }
83
+ // Is smallest section
84
+ if (this.position === 0) {
85
+ return [0, 0, this.borderRadius, this.borderRadius];
86
+ }
46
87
  }
47
- if (this.position === this.sections - 1) {
48
- return [this.borderRadius, this.borderRadius];
88
+ if (!this.isIncreasing) {
89
+ // Is largest section
90
+ if (this.position === 0) {
91
+ return [0, 0, this.borderRadius, this.borderRadius];
92
+ }
93
+ // Is smallest section and shaped like a triangle
94
+ if (this.position === this.sections - 1 && this.pointShape === 'sharp') {
95
+ return [this.borderRadius];
96
+ }
97
+
98
+ // Is smallest section
99
+ if (this.position === this.sections - 1) {
100
+ return [this.borderRadius, this.borderRadius];
101
+ }
49
102
  }
50
103
  return 0;
51
104
  }
@@ -77,6 +130,30 @@ export class Linear {
77
130
  y: yGap
78
131
  };
79
132
  });
133
+ if (this.pointShape === 'sharp') {
134
+ // In the last section, to form a triangle we need 3 points instead of 4
135
+ // Else the algorithm will break.
136
+ const isLastSection = this.position === this.sections - 1;
137
+ const isFirstSection = this.position === 0;
138
+ if (isFirstSection && this.isIncreasing) {
139
+ this.points = [this.isHorizontal ? {
140
+ x: this.max.x + this.gap,
141
+ y: (this.max.y + this.min.y) / 2
142
+ } : {
143
+ x: (this.max.x + this.min.x) / 2,
144
+ y: this.max.y + this.gap
145
+ }, this.points[1], this.points[2]];
146
+ }
147
+ if (isLastSection && !this.isIncreasing) {
148
+ this.points = [this.points[0], this.isHorizontal ? {
149
+ x: this.max.x - this.gap,
150
+ y: (this.max.y + this.min.y) / 2
151
+ } : {
152
+ x: (this.max.x + this.min.x) / 2,
153
+ y: this.max.y - this.gap
154
+ }, this.points[3]];
155
+ }
156
+ }
80
157
  borderRadiusPolygon(this.context, this.points, this.getBorderRadius());
81
158
  }
82
159
  }
@@ -47,6 +47,7 @@ export interface FunnelSeriesType extends Omit<CommonSeriesType<FunnelValueType>
47
47
  *
48
48
  * - `bump`: A curve that creates a smooth transition between points, with a bump in the middle.
49
49
  * - `linear`: A straight line between points.
50
+ * - `linear-sharp`: A straight line between points, the smaller end of the funnel is a triangle.
50
51
  * - `step`: A step line that creates a staircase effect.
51
52
  * - `pyramid`: A pyramid shape that connects the points.
52
53
  * - `step-pyramid`: A step line that creates a staircase effect, with a pyramid shape.
@@ -1,10 +1,21 @@
1
1
  import * as React from 'react';
2
2
  import type { FunnelSectionProps } from "./FunnelSection.js";
3
+ import { FunnelSectionLabelProps } from "./FunnelSectionLabel.js";
3
4
  export interface FunnelPlotSlots {
5
+ /**
6
+ * Custom component for funnel section.
7
+ * @default FunnelSection
8
+ */
4
9
  funnelSection?: React.ElementType<FunnelSectionProps>;
10
+ /**
11
+ * Custom component for funnel section label.
12
+ * @default FunnelSectionLabel
13
+ */
14
+ funnelSectionLabel?: React.ElementType<FunnelSectionLabelProps>;
5
15
  }
6
16
  export interface FunnelPlotSlotProps {
7
17
  funnelSection?: FunnelSectionProps;
18
+ funnelSectionLabel?: FunnelSectionLabelProps;
8
19
  }
9
20
  export interface FunnelPlotSlotExtension {
10
21
  /**
@@ -1,4 +1,5 @@
1
1
  import type { FunnelSectionProps } from "./FunnelSection.js";
2
+ import type { FunnelSectionLabelProps } from "./FunnelSectionLabel.js";
2
3
  export interface FunnelSectionClasses {
3
4
  /** Styles applied to the root element. */
4
5
  root: string;
@@ -19,4 +20,5 @@ export interface FunnelSectionClasses {
19
20
  series: string;
20
21
  }
21
22
  export declare const useUtilityClasses: (props: FunnelSectionProps) => Record<"label" | "filled" | "outlined" | "highlighted" | "faded" | "root", string>;
23
+ export declare const useLabelUtilityClasses: (props: FunnelSectionLabelProps) => Record<"label", string>;
22
24
  export declare const funnelSectionClasses: FunnelSectionClasses;
@@ -8,10 +8,11 @@ export const useUtilityClasses = props => {
8
8
  const {
9
9
  classes,
10
10
  seriesId,
11
- variant
11
+ variant,
12
+ dataIndex
12
13
  } = props;
13
14
  const slots = {
14
- root: ['root', `series-${seriesId}`],
15
+ root: ['root', `series-${seriesId}`, `data-index-${dataIndex}`],
15
16
  highlighted: ['highlighted'],
16
17
  faded: ['faded'],
17
18
  outlined: variant === 'outlined' ? ['outlined'] : [],
@@ -20,4 +21,15 @@ export const useUtilityClasses = props => {
20
21
  };
21
22
  return composeClasses(slots, getFunnelSectionUtilityClass, classes);
22
23
  };
23
- export const funnelSectionClasses = generateUtilityClasses('MuiFunnelSection', ['root', 'highlighted', 'faded', 'filled', 'outlined', 'label', 'series']);
24
+ export const useLabelUtilityClasses = props => {
25
+ const {
26
+ classes,
27
+ seriesId,
28
+ dataIndex
29
+ } = props;
30
+ const slots = {
31
+ label: ['label', `series-${seriesId}`, `data-index-${dataIndex}`]
32
+ };
33
+ return composeClasses(slots, getFunnelSectionUtilityClass, classes);
34
+ };
35
+ export const funnelSectionClasses = generateUtilityClasses('MuiFunnelSection', ['root', 'highlighted', 'faded', 'filled', 'outlined', 'label', 'series', 'data-index']);
@@ -6,4 +6,6 @@ export * from "./categoryAxis.types.js";
6
6
  export * from "./funnelSlots.types.js";
7
7
  export type { FunnelCurveType } from "./curves/index.js";
8
8
  export { funnelSectionClasses } from "./funnelSectionClasses.js";
9
- export type { FunnelSectionClasses } from "./funnelSectionClasses.js";
9
+ export type { FunnelSectionClasses } from "./funnelSectionClasses.js";
10
+ export { FunnelSection } from "./FunnelSection.js";
11
+ export { FunnelSectionLabel } from "./FunnelSectionLabel.js";
@@ -3,4 +3,6 @@ export * from "./FunnelPlot.js";
3
3
  export * from "./funnel.types.js";
4
4
  export * from "./categoryAxis.types.js";
5
5
  export * from "./funnelSlots.types.js";
6
- export { funnelSectionClasses } from "./funnelSectionClasses.js";
6
+ export { funnelSectionClasses } from "./funnelSectionClasses.js";
7
+ export { FunnelSection } from "./FunnelSection.js";
8
+ export { FunnelSectionLabel } from "./FunnelSectionLabel.js";
@@ -55,6 +55,11 @@ export interface HeatmapProps extends Omit<ChartContainerProProps<'heatmap', Hea
55
55
  * @default true
56
56
  */
57
57
  hideLegend?: boolean;
58
+ /**
59
+ * If true, shows the default chart toolbar.
60
+ * @default false
61
+ */
62
+ showToolbar?: boolean;
58
63
  /**
59
64
  * Overridable component slots.
60
65
  * @default {}