@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.
- package/BarChartPro/BarChartPro.js +1 -1
- package/CHANGELOG.md +112 -0
- package/ChartContainerPro/ChartProApi.d.ts +2 -0
- package/ChartDataProviderPro/ChartDataProviderPro.js +1 -1
- package/ChartZoomSlider/internals/ChartAxisZoomSliderActiveTrack.d.ts +0 -2
- package/ChartZoomSlider/internals/ChartAxisZoomSliderActiveTrack.js +41 -9
- package/ChartZoomSlider/internals/ChartAxisZoomSliderTrack.js +0 -22
- package/ChartsToolbarPro/ChartsToolbarPro.d.ts +1 -4
- package/ChartsToolbarPro/ChartsToolbarPro.js +7 -13
- package/ChartsToolbarPro/{ChartsToolbarZoomInButton.d.ts → ChartsToolbarZoomInTrigger.d.ts} +6 -5
- package/ChartsToolbarPro/{ChartsToolbarZoomInButton.js → ChartsToolbarZoomInTrigger.js} +7 -6
- package/ChartsToolbarPro/{ChartsToolbarZoomOutButton.d.ts → ChartsToolbarZoomOutTrigger.d.ts} +6 -5
- package/ChartsToolbarPro/{ChartsToolbarZoomOutButton.js → ChartsToolbarZoomOutTrigger.js} +7 -6
- package/ChartsToolbarPro/index.d.ts +2 -2
- package/ChartsToolbarPro/index.js +8 -8
- package/FunnelChart/FunnelPlot.js +10 -22
- package/FunnelChart/FunnelSection.d.ts +1 -1
- package/FunnelChart/FunnelSectionLabel.d.ts +21 -0
- package/FunnelChart/FunnelSectionLabel.js +52 -0
- package/FunnelChart/curves/bump.d.ts +10 -4
- package/FunnelChart/curves/bump.js +73 -41
- package/FunnelChart/curves/curve.types.d.ts +6 -1
- package/FunnelChart/curves/getFunnelCurve.js +3 -0
- package/FunnelChart/curves/linear.d.ts +9 -1
- package/FunnelChart/curves/linear.js +82 -5
- package/FunnelChart/funnel.types.d.ts +1 -0
- package/FunnelChart/funnelPlotSlots.types.d.ts +11 -0
- package/FunnelChart/funnelSectionClasses.d.ts +2 -0
- package/FunnelChart/funnelSectionClasses.js +17 -4
- package/FunnelChart/index.d.ts +3 -1
- package/FunnelChart/index.js +18 -2
- package/Heatmap/Heatmap.d.ts +5 -0
- package/Heatmap/Heatmap.js +10 -2
- package/Heatmap/HeatmapTooltip/HeatmapTooltipAxesValue.d.ts +1 -1
- package/LineChartPro/LineChartPro.js +1 -1
- package/PieChartPro/PieChartPro.d.ts +21 -0
- package/PieChartPro/PieChartPro.js +204 -0
- package/PieChartPro/PieChartPro.plugins.d.ts +4 -0
- package/PieChartPro/PieChartPro.plugins.js +9 -0
- package/PieChartPro/index.d.ts +1 -0
- package/PieChartPro/index.js +16 -0
- package/RadarChartPro/RadarChartPro.js +1 -1
- package/ScatterChartPro/ScatterChartPro.js +1 -1
- package/esm/BarChartPro/BarChartPro.js +1 -1
- package/esm/ChartContainerPro/ChartProApi.d.ts +2 -0
- package/esm/ChartDataProviderPro/ChartDataProviderPro.js +1 -1
- package/esm/ChartZoomSlider/internals/ChartAxisZoomSliderActiveTrack.d.ts +0 -2
- package/esm/ChartZoomSlider/internals/ChartAxisZoomSliderActiveTrack.js +42 -10
- package/esm/ChartZoomSlider/internals/ChartAxisZoomSliderTrack.js +0 -22
- package/esm/ChartsToolbarPro/ChartsToolbarPro.d.ts +1 -4
- package/esm/ChartsToolbarPro/ChartsToolbarPro.js +8 -14
- package/esm/ChartsToolbarPro/{ChartsToolbarZoomInButton.d.ts → ChartsToolbarZoomInTrigger.d.ts} +6 -5
- package/esm/ChartsToolbarPro/{ChartsToolbarZoomInButton.js → ChartsToolbarZoomInTrigger.js} +8 -7
- package/esm/ChartsToolbarPro/{ChartsToolbarZoomOutButton.d.ts → ChartsToolbarZoomOutTrigger.d.ts} +6 -5
- package/esm/ChartsToolbarPro/{ChartsToolbarZoomOutButton.js → ChartsToolbarZoomOutTrigger.js} +8 -7
- package/esm/ChartsToolbarPro/index.d.ts +2 -2
- package/esm/ChartsToolbarPro/index.js +2 -2
- package/esm/FunnelChart/FunnelPlot.js +10 -22
- package/esm/FunnelChart/FunnelSection.d.ts +1 -1
- package/esm/FunnelChart/FunnelSectionLabel.d.ts +21 -0
- package/esm/FunnelChart/FunnelSectionLabel.js +46 -0
- package/esm/FunnelChart/curves/bump.d.ts +10 -4
- package/esm/FunnelChart/curves/bump.js +73 -41
- package/esm/FunnelChart/curves/curve.types.d.ts +6 -1
- package/esm/FunnelChart/curves/getFunnelCurve.js +3 -0
- package/esm/FunnelChart/curves/linear.d.ts +9 -1
- package/esm/FunnelChart/curves/linear.js +82 -5
- package/esm/FunnelChart/funnel.types.d.ts +1 -0
- package/esm/FunnelChart/funnelPlotSlots.types.d.ts +11 -0
- package/esm/FunnelChart/funnelSectionClasses.d.ts +2 -0
- package/esm/FunnelChart/funnelSectionClasses.js +15 -3
- package/esm/FunnelChart/index.d.ts +3 -1
- package/esm/FunnelChart/index.js +3 -1
- package/esm/Heatmap/Heatmap.d.ts +5 -0
- package/esm/Heatmap/Heatmap.js +10 -2
- package/esm/Heatmap/HeatmapTooltip/HeatmapTooltipAxesValue.d.ts +1 -1
- package/esm/LineChartPro/LineChartPro.js +1 -1
- package/esm/PieChartPro/PieChartPro.d.ts +21 -0
- package/esm/PieChartPro/PieChartPro.js +197 -0
- package/esm/PieChartPro/PieChartPro.plugins.d.ts +4 -0
- package/esm/PieChartPro/PieChartPro.plugins.js +3 -0
- package/esm/PieChartPro/index.d.ts +1 -0
- package/esm/PieChartPro/index.js +1 -0
- package/esm/RadarChartPro/RadarChartPro.js +1 -1
- package/esm/ScatterChartPro/ScatterChartPro.js +1 -1
- package/esm/index.d.ts +1 -0
- package/esm/index.js +2 -1
- package/index.d.ts +1 -0
- package/index.js +12 -1
- package/package.json +7 -7
package/esm/ChartsToolbarPro/{ChartsToolbarZoomOutButton.js → ChartsToolbarZoomOutTrigger.js}
RENAMED
|
@@ -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,
|
|
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
|
-
*
|
|
13
|
+
* A button that zooms the chart out.
|
|
14
|
+
* It renders the `baseButton` slot.
|
|
14
15
|
*/
|
|
15
|
-
const
|
|
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.
|
|
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")
|
|
40
|
-
process.env.NODE_ENV !== "production" ?
|
|
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 {
|
|
51
|
+
export { ChartsToolbarZoomOutTrigger };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from "./ChartsToolbarPro.js";
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./
|
|
2
|
+
export * from "./ChartsToolbarZoomInTrigger.js";
|
|
3
|
+
export * from "./ChartsToolbarZoomOutTrigger.js";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from "./ChartsToolbarPro.js";
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./
|
|
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(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (this.
|
|
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
|
-
//
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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.
|
|
66
|
-
}
|
|
67
|
-
if (this.currentPoint === 3) {
|
|
68
|
-
this.context.closePath();
|
|
69
|
+
this.drawVerticalPath();
|
|
69
70
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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.
|
|
45
|
-
|
|
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.
|
|
48
|
-
|
|
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
|
|
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";
|
package/esm/FunnelChart/index.js
CHANGED
|
@@ -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";
|
package/esm/Heatmap/Heatmap.d.ts
CHANGED
|
@@ -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 {}
|