@mui/x-charts-pro 8.1.0 → 8.3.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.
- package/BarChartPro/BarChartPro.d.ts +7 -1
- package/BarChartPro/BarChartPro.js +62 -5
- package/CHANGELOG.md +233 -7
- package/ChartContainerPro/useChartContainerProProps.d.ts +1 -1
- package/ChartDataProviderPro/ChartDataProviderPro.js +1 -1
- package/ChartDataProviderPro/useChartDataProviderProProps.d.ts +2 -2
- package/ChartZoomSlider/ChartZoomSlider.d.ts +5 -0
- package/ChartZoomSlider/ChartZoomSlider.js +47 -0
- package/ChartZoomSlider/index.d.ts +2 -0
- package/ChartZoomSlider/index.js +27 -0
- package/ChartZoomSlider/internals/ChartAxisZoomSlider.d.ts +23 -0
- package/ChartZoomSlider/internals/ChartAxisZoomSlider.js +348 -0
- package/ChartZoomSlider/internals/ChartAxisZoomSliderHandle.d.ts +12 -0
- package/ChartZoomSlider/internals/ChartAxisZoomSliderHandle.js +92 -0
- package/ChartZoomSlider/internals/chartAxisZoomSliderHandleClasses.d.ts +17 -0
- package/ChartZoomSlider/internals/chartAxisZoomSliderHandleClasses.js +27 -0
- package/ChartsToolbarPro/ChartsToolbarPro.d.ts +2 -0
- package/ChartsToolbarPro/ChartsToolbarPro.js +31 -0
- package/ChartsToolbarPro/index.d.ts +1 -0
- package/ChartsToolbarPro/index.js +16 -0
- package/ChartsToolbarPro/internal/ChartsToolbarZoomInButton.d.ts +13 -0
- package/ChartsToolbarPro/internal/ChartsToolbarZoomInButton.js +36 -0
- package/ChartsToolbarPro/internal/ChartsToolbarZoomOutButton.d.ts +13 -0
- package/ChartsToolbarPro/internal/ChartsToolbarZoomOutButton.js +36 -0
- package/FunnelChart/FunnelChart.js +9 -8
- package/FunnelChart/FunnelPlot.d.ts +5 -0
- package/FunnelChart/FunnelPlot.js +36 -18
- package/FunnelChart/FunnelSection.d.ts +1 -0
- package/FunnelChart/FunnelSection.js +12 -7
- package/FunnelChart/curves/borderRadiusPolygon.d.ts +8 -0
- package/FunnelChart/curves/borderRadiusPolygon.js +42 -0
- package/FunnelChart/curves/bump.d.ts +27 -0
- package/FunnelChart/curves/bump.js +81 -0
- package/FunnelChart/curves/curve.types.d.ts +38 -0
- package/FunnelChart/curves/curve.types.js +5 -0
- package/FunnelChart/curves/getFunnelCurve.d.ts +3 -0
- package/FunnelChart/curves/getFunnelCurve.js +30 -0
- package/FunnelChart/curves/index.d.ts +2 -0
- package/FunnelChart/curves/index.js +27 -0
- package/FunnelChart/curves/linear.d.ts +32 -0
- package/FunnelChart/curves/linear.js +88 -0
- package/FunnelChart/curves/pyramid.d.ts +34 -0
- package/FunnelChart/curves/pyramid.js +127 -0
- package/FunnelChart/curves/step-pyramid.d.ts +31 -0
- package/FunnelChart/curves/step-pyramid.js +107 -0
- package/FunnelChart/curves/step.d.ts +32 -0
- package/FunnelChart/curves/step.js +88 -0
- package/FunnelChart/curves/utils.d.ts +4 -0
- package/FunnelChart/curves/utils.js +29 -0
- package/FunnelChart/funnel.types.d.ts +25 -4
- package/FunnelChart/funnelPlotSlots.types.d.ts +1 -1
- package/FunnelChart/funnelSectionClasses.d.ts +6 -2
- package/FunnelChart/funnelSectionClasses.js +5 -2
- package/FunnelChart/index.d.ts +3 -2
- package/FunnelChart/seriesConfig/getSeriesWithDefaultValues.js +1 -0
- package/FunnelChart/useFunnelChartProps.d.ts +1 -6
- package/FunnelChart/useFunnelChartProps.js +7 -15
- package/Heatmap/Heatmap.d.ts +3 -3
- package/Heatmap/Heatmap.js +3 -21
- package/LineChartPro/LineChartPro.d.ts +7 -1
- package/LineChartPro/LineChartPro.js +62 -5
- package/ScatterChartPro/ScatterChartPro.d.ts +7 -1
- package/ScatterChartPro/ScatterChartPro.js +62 -5
- package/esm/BarChartPro/BarChartPro.d.ts +7 -1
- package/esm/BarChartPro/BarChartPro.js +62 -5
- package/esm/ChartContainerPro/useChartContainerProProps.d.ts +1 -1
- package/esm/ChartDataProviderPro/ChartDataProviderPro.js +1 -1
- package/esm/ChartDataProviderPro/useChartDataProviderProProps.d.ts +2 -2
- package/esm/ChartZoomSlider/ChartZoomSlider.d.ts +5 -0
- package/esm/ChartZoomSlider/ChartZoomSlider.js +41 -0
- package/esm/ChartZoomSlider/index.d.ts +2 -0
- package/esm/ChartZoomSlider/index.js +2 -0
- package/esm/ChartZoomSlider/internals/ChartAxisZoomSlider.d.ts +23 -0
- package/esm/ChartZoomSlider/internals/ChartAxisZoomSlider.js +339 -0
- package/esm/ChartZoomSlider/internals/ChartAxisZoomSliderHandle.d.ts +12 -0
- package/esm/ChartZoomSlider/internals/ChartAxisZoomSliderHandle.js +85 -0
- package/esm/ChartZoomSlider/internals/chartAxisZoomSliderHandleClasses.d.ts +17 -0
- package/esm/ChartZoomSlider/internals/chartAxisZoomSliderHandleClasses.js +17 -0
- package/esm/ChartsToolbarPro/ChartsToolbarPro.d.ts +2 -0
- package/esm/ChartsToolbarPro/ChartsToolbarPro.js +24 -0
- package/esm/ChartsToolbarPro/index.d.ts +1 -0
- package/esm/ChartsToolbarPro/index.js +1 -0
- package/esm/ChartsToolbarPro/internal/ChartsToolbarZoomInButton.d.ts +13 -0
- package/esm/ChartsToolbarPro/internal/ChartsToolbarZoomInButton.js +29 -0
- package/esm/ChartsToolbarPro/internal/ChartsToolbarZoomOutButton.d.ts +13 -0
- package/esm/ChartsToolbarPro/internal/ChartsToolbarZoomOutButton.js +29 -0
- package/esm/FunnelChart/FunnelChart.js +9 -8
- package/esm/FunnelChart/FunnelPlot.d.ts +5 -0
- package/esm/FunnelChart/FunnelPlot.js +37 -19
- package/esm/FunnelChart/FunnelSection.d.ts +1 -0
- package/esm/FunnelChart/FunnelSection.js +12 -7
- package/esm/FunnelChart/curves/borderRadiusPolygon.d.ts +8 -0
- package/esm/FunnelChart/curves/borderRadiusPolygon.js +36 -0
- package/esm/FunnelChart/curves/bump.d.ts +27 -0
- package/esm/FunnelChart/curves/bump.js +74 -0
- package/esm/FunnelChart/curves/curve.types.d.ts +38 -0
- package/esm/FunnelChart/curves/curve.types.js +1 -0
- package/esm/FunnelChart/curves/getFunnelCurve.d.ts +3 -0
- package/esm/FunnelChart/curves/getFunnelCurve.js +23 -0
- package/esm/FunnelChart/curves/index.d.ts +2 -0
- package/esm/FunnelChart/curves/index.js +2 -0
- package/esm/FunnelChart/curves/linear.d.ts +32 -0
- package/esm/FunnelChart/curves/linear.js +82 -0
- package/esm/FunnelChart/curves/pyramid.d.ts +34 -0
- package/esm/FunnelChart/curves/pyramid.js +121 -0
- package/esm/FunnelChart/curves/step-pyramid.d.ts +31 -0
- package/esm/FunnelChart/curves/step-pyramid.js +101 -0
- package/esm/FunnelChart/curves/step.d.ts +32 -0
- package/esm/FunnelChart/curves/step.js +82 -0
- package/esm/FunnelChart/curves/utils.d.ts +4 -0
- package/esm/FunnelChart/curves/utils.js +19 -0
- package/esm/FunnelChart/funnel.types.d.ts +25 -4
- package/esm/FunnelChart/funnelPlotSlots.types.d.ts +1 -1
- package/esm/FunnelChart/funnelSectionClasses.d.ts +6 -2
- package/esm/FunnelChart/funnelSectionClasses.js +5 -2
- package/esm/FunnelChart/index.d.ts +3 -2
- package/esm/FunnelChart/seriesConfig/getSeriesWithDefaultValues.js +1 -0
- package/esm/FunnelChart/useFunnelChartProps.d.ts +1 -6
- package/esm/FunnelChart/useFunnelChartProps.js +7 -15
- package/esm/Heatmap/Heatmap.d.ts +3 -3
- package/esm/Heatmap/Heatmap.js +3 -21
- package/esm/LineChartPro/LineChartPro.d.ts +7 -1
- package/esm/LineChartPro/LineChartPro.js +62 -5
- package/esm/ScatterChartPro/ScatterChartPro.d.ts +7 -1
- package/esm/ScatterChartPro/ScatterChartPro.js +62 -5
- package/esm/index.d.ts +4 -1
- package/esm/index.js +5 -2
- package/esm/internals/material/icons.d.ts +3 -0
- package/esm/internals/material/icons.js +13 -0
- package/esm/internals/material/index.d.ts +4 -0
- package/esm/internals/material/index.js +12 -0
- package/esm/internals/plugins/useChartProExport/common.d.ts +1 -0
- package/esm/internals/plugins/useChartProExport/common.js +8 -0
- package/esm/internals/plugins/useChartProExport/exportImage.d.ts +3 -0
- package/esm/internals/plugins/useChartProExport/exportImage.js +85 -0
- package/esm/internals/plugins/useChartProExport/print.js +6 -50
- package/esm/internals/plugins/useChartProExport/useChartProExport.js +22 -2
- package/esm/internals/plugins/useChartProExport/useChartProExport.types.d.ts +32 -0
- package/esm/internals/plugins/useChartProZoom/calculateZoom.d.ts +23 -0
- package/esm/internals/plugins/useChartProZoom/calculateZoom.js +32 -0
- package/esm/internals/plugins/useChartProZoom/useChartProZoom.d.ts +1 -1
- package/esm/internals/plugins/useChartProZoom/useChartProZoom.js +46 -4
- package/esm/internals/plugins/useChartProZoom/useChartProZoom.selectors.d.ts +84 -32
- package/esm/internals/plugins/useChartProZoom/useChartProZoom.selectors.js +3 -2
- package/esm/internals/plugins/useChartProZoom/useChartProZoom.types.d.ts +17 -2
- package/esm/internals/slots/chartBaseSlotProps.d.ts +10 -0
- package/esm/internals/slots/chartBaseSlotProps.js +1 -0
- package/esm/internals/slots/chartsBaseSlots.d.ts +6 -0
- package/esm/internals/slots/chartsBaseSlots.js +1 -0
- package/esm/internals/slots/chartsIconSlots.d.ts +14 -0
- package/esm/internals/slots/chartsIconSlots.js +1 -0
- package/esm/themeAugmentation/components.d.ts +0 -4
- package/esm/themeAugmentation/components.js +1 -0
- package/esm/themeAugmentation/index.d.ts +3 -3
- package/esm/themeAugmentation/overrides.d.ts +0 -3
- package/esm/themeAugmentation/overrides.js +2 -0
- package/esm/themeAugmentation/props.d.ts +0 -6
- package/esm/themeAugmentation/props.js +2 -0
- package/esm/typeOverloads/modules.d.ts +1 -1
- package/index.d.ts +4 -1
- package/index.js +90 -1
- package/internals/material/icons.d.ts +3 -0
- package/internals/material/icons.js +20 -0
- package/internals/material/index.d.ts +4 -0
- package/internals/material/index.js +19 -0
- package/internals/plugins/useChartProExport/common.d.ts +1 -0
- package/internals/plugins/useChartProExport/common.js +14 -0
- package/internals/plugins/useChartProExport/exportImage.d.ts +3 -0
- package/internals/plugins/useChartProExport/exportImage.js +95 -0
- package/internals/plugins/useChartProExport/print.js +6 -50
- package/internals/plugins/useChartProExport/useChartProExport.js +22 -2
- package/internals/plugins/useChartProExport/useChartProExport.types.d.ts +32 -0
- package/internals/plugins/useChartProZoom/calculateZoom.d.ts +23 -0
- package/internals/plugins/useChartProZoom/calculateZoom.js +39 -0
- package/internals/plugins/useChartProZoom/useChartProZoom.d.ts +1 -1
- package/internals/plugins/useChartProZoom/useChartProZoom.js +45 -3
- package/internals/plugins/useChartProZoom/useChartProZoom.selectors.d.ts +84 -32
- package/internals/plugins/useChartProZoom/useChartProZoom.selectors.js +3 -2
- package/internals/plugins/useChartProZoom/useChartProZoom.types.d.ts +17 -2
- package/internals/slots/chartBaseSlotProps.d.ts +10 -0
- package/internals/slots/chartBaseSlotProps.js +5 -0
- package/internals/slots/chartsBaseSlots.d.ts +6 -0
- package/internals/slots/chartsBaseSlots.js +5 -0
- package/internals/slots/chartsIconSlots.d.ts +14 -0
- package/internals/slots/chartsIconSlots.js +5 -0
- package/package.json +10 -7
- package/themeAugmentation/components.d.ts +0 -4
- package/themeAugmentation/components.js +5 -0
- package/themeAugmentation/index.d.ts +3 -3
- package/themeAugmentation/overrides.d.ts +0 -3
- package/themeAugmentation/overrides.js +5 -0
- package/themeAugmentation/props.d.ts +0 -6
- package/themeAugmentation/props.js +5 -0
- package/typeOverloads/modules.d.ts +1 -1
- package/FunnelChart/funnelStepCurve.d.ts +0 -4
- package/FunnelChart/funnelStepCurve.js +0 -74
- package/esm/FunnelChart/funnelStepCurve.d.ts +0 -4
- package/esm/FunnelChart/funnelStepCurve.js +0 -67
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { styled } from '@mui/material/styles';
|
|
5
|
+
import useForkRef from '@mui/utils/useForkRef';
|
|
6
|
+
import useEventCallback from '@mui/utils/useEventCallback';
|
|
7
|
+
import { rafThrottle } from '@mui/x-internals/rafThrottle';
|
|
8
|
+
import { chartAxisZoomSliderHandleClasses, useUtilityClasses } from "./chartAxisZoomSliderHandleClasses.js";
|
|
9
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
|
+
const Rect = styled('rect')(({
|
|
11
|
+
theme
|
|
12
|
+
}) => ({
|
|
13
|
+
[`&.${chartAxisZoomSliderHandleClasses.root}`]: {
|
|
14
|
+
fill: theme.palette.mode === 'dark' ? (theme.vars || theme).palette.grey[300] : (theme.vars || theme).palette.common.white,
|
|
15
|
+
stroke: theme.palette.mode === 'dark' ? (theme.vars || theme).palette.grey[600] : (theme.vars || theme).palette.grey[500]
|
|
16
|
+
},
|
|
17
|
+
[`&.${chartAxisZoomSliderHandleClasses.horizontal}`]: {
|
|
18
|
+
cursor: 'ew-resize'
|
|
19
|
+
},
|
|
20
|
+
[`&.${chartAxisZoomSliderHandleClasses.vertical}`]: {
|
|
21
|
+
cursor: 'ns-resize'
|
|
22
|
+
}
|
|
23
|
+
}));
|
|
24
|
+
/**
|
|
25
|
+
* Renders the zoom slider handle, which is responsible for resizing the zoom range.
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export const ChartAxisZoomSliderHandle = /*#__PURE__*/React.forwardRef(function ChartPreviewHandle({
|
|
29
|
+
x,
|
|
30
|
+
y,
|
|
31
|
+
width,
|
|
32
|
+
height,
|
|
33
|
+
onResize,
|
|
34
|
+
orientation,
|
|
35
|
+
placement,
|
|
36
|
+
rx = 4,
|
|
37
|
+
ry = 4
|
|
38
|
+
}, forwardedRef) {
|
|
39
|
+
const classes = useUtilityClasses({
|
|
40
|
+
onResize,
|
|
41
|
+
orientation,
|
|
42
|
+
placement
|
|
43
|
+
});
|
|
44
|
+
const handleRef = React.useRef(null);
|
|
45
|
+
const ref = useForkRef(handleRef, forwardedRef);
|
|
46
|
+
const onResizeEvent = useEventCallback(onResize);
|
|
47
|
+
React.useEffect(() => {
|
|
48
|
+
const handle = handleRef.current;
|
|
49
|
+
if (!handle) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const onPointerMove = rafThrottle(event => {
|
|
53
|
+
onResizeEvent(event);
|
|
54
|
+
});
|
|
55
|
+
const onPointerUp = () => {
|
|
56
|
+
handle.removeEventListener('pointermove', onPointerMove);
|
|
57
|
+
handle.removeEventListener('pointerup', onPointerUp);
|
|
58
|
+
};
|
|
59
|
+
const onPointerDown = event => {
|
|
60
|
+
// Prevent text selection when dragging the handle
|
|
61
|
+
event.preventDefault();
|
|
62
|
+
event.stopPropagation();
|
|
63
|
+
handle.setPointerCapture(event.pointerId);
|
|
64
|
+
handle.addEventListener('pointerup', onPointerUp);
|
|
65
|
+
handle.addEventListener('pointermove', onPointerMove);
|
|
66
|
+
};
|
|
67
|
+
handle.addEventListener('pointerdown', onPointerDown);
|
|
68
|
+
|
|
69
|
+
// eslint-disable-next-line consistent-return
|
|
70
|
+
return () => {
|
|
71
|
+
handle.removeEventListener('pointerdown', onPointerDown);
|
|
72
|
+
onPointerMove.clear();
|
|
73
|
+
};
|
|
74
|
+
}, [onResizeEvent, orientation]);
|
|
75
|
+
return /*#__PURE__*/_jsx(Rect, {
|
|
76
|
+
className: classes.root,
|
|
77
|
+
ref: ref,
|
|
78
|
+
x: x,
|
|
79
|
+
y: y,
|
|
80
|
+
width: width,
|
|
81
|
+
height: height,
|
|
82
|
+
rx: rx,
|
|
83
|
+
ry: ry
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ChartZoomSliderHandleOwnerState } from "./ChartAxisZoomSliderHandle.js";
|
|
2
|
+
export interface ChartAxisZoomSliderHandleClasses {
|
|
3
|
+
/** Styles applied to the root element. */
|
|
4
|
+
root: string;
|
|
5
|
+
/** Styles applied to the root element when it is horizontal. */
|
|
6
|
+
horizontal: string;
|
|
7
|
+
/** Styles applied to the root element when it is vertical. */
|
|
8
|
+
vertical: string;
|
|
9
|
+
/** Styles applied to the root element when it is a start handle. */
|
|
10
|
+
start: string;
|
|
11
|
+
/** Styles applied to the root element when it is an end handle. */
|
|
12
|
+
end: string;
|
|
13
|
+
}
|
|
14
|
+
export type ChartAxisZoomSliderHandleClassKey = keyof ChartAxisZoomSliderHandleClasses;
|
|
15
|
+
export declare const chartAxisZoomSliderHandleClasses: ChartAxisZoomSliderHandleClasses;
|
|
16
|
+
export declare function getAxisZoomSliderHandleUtilityClass(slot: string): string;
|
|
17
|
+
export declare const useUtilityClasses: (ownerState: ChartZoomSliderHandleOwnerState) => Record<"root", string>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
|
|
2
|
+
import composeClasses from '@mui/utils/composeClasses';
|
|
3
|
+
import generateUtilityClass from '@mui/utils/generateUtilityClass';
|
|
4
|
+
export const chartAxisZoomSliderHandleClasses = generateUtilityClasses('MuiChartAxisZoomSliderHandle', ['root', 'horizontal', 'vertical', 'start', 'end']);
|
|
5
|
+
export function getAxisZoomSliderHandleUtilityClass(slot) {
|
|
6
|
+
return generateUtilityClass('MuiChartAxisZoomSliderHandle', slot);
|
|
7
|
+
}
|
|
8
|
+
export const useUtilityClasses = ownerState => {
|
|
9
|
+
const {
|
|
10
|
+
orientation,
|
|
11
|
+
placement
|
|
12
|
+
} = ownerState;
|
|
13
|
+
const slots = {
|
|
14
|
+
root: ['root', orientation === 'horizontal' ? 'horizontal' : 'vertical', placement === 'start' ? 'start' : 'end']
|
|
15
|
+
};
|
|
16
|
+
return composeClasses(slots, getAxisZoomSliderHandleUtilityClass);
|
|
17
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Toolbar } from '@mui/x-charts/Toolbar';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { useChartContext, useSelector } from '@mui/x-charts/internals';
|
|
4
|
+
import { selectorChartZoomIsEnabled } from "../internals/plugins/useChartProZoom/index.js";
|
|
5
|
+
import { ChartsToolbarZoomInButton } from "./internal/ChartsToolbarZoomInButton.js";
|
|
6
|
+
import { ChartsToolbarZoomOutButton } from "./internal/ChartsToolbarZoomOutButton.js";
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
export function ChartsToolbarPro() {
|
|
9
|
+
const {
|
|
10
|
+
store
|
|
11
|
+
} = useChartContext();
|
|
12
|
+
const isZoomEnabled = useSelector(store, selectorChartZoomIsEnabled);
|
|
13
|
+
const children = [];
|
|
14
|
+
if (isZoomEnabled) {
|
|
15
|
+
children.push(/*#__PURE__*/_jsx(ChartsToolbarZoomInButton, {}, "zoom-in"));
|
|
16
|
+
children.push(/*#__PURE__*/_jsx(ChartsToolbarZoomOutButton, {}, "zoom-out"));
|
|
17
|
+
}
|
|
18
|
+
if (children.length === 0) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return /*#__PURE__*/_jsx(Toolbar, {
|
|
22
|
+
children: children
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ChartsToolbarPro.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ChartsToolbarPro.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ChartsSlotsPro } from "../../internals/material/index.js";
|
|
3
|
+
type ChartsToolbarZoomInButtonSlots = Partial<Pick<ChartsSlotsPro, 'baseTooltip' | 'zoomInIcon'>>;
|
|
4
|
+
type ChartsToolbarZoomInButtonSlotProps = { [K in keyof Required<ChartsToolbarZoomInButtonSlots>]: React.ComponentProps<Required<ChartsToolbarZoomInButtonSlots>[K]> };
|
|
5
|
+
interface ChartsToolbarZoomInButtonProps {
|
|
6
|
+
slots?: ChartsToolbarZoomInButtonSlots;
|
|
7
|
+
slotProps?: ChartsToolbarZoomInButtonSlotProps;
|
|
8
|
+
}
|
|
9
|
+
export declare function ChartsToolbarZoomInButton({
|
|
10
|
+
slots,
|
|
11
|
+
slotProps
|
|
12
|
+
}: ChartsToolbarZoomInButtonProps): React.JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import { ToolbarButton } from '@mui/x-charts/Toolbar';
|
|
6
|
+
import { useChartContext } from '@mui/x-charts/internals';
|
|
7
|
+
import { useChartsLocalization } from '@mui/x-charts/hooks';
|
|
8
|
+
import { defaultSlotsMaterial } from "../../internals/material/index.js";
|
|
9
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
|
+
export function ChartsToolbarZoomInButton({
|
|
11
|
+
slots,
|
|
12
|
+
slotProps
|
|
13
|
+
}) {
|
|
14
|
+
const {
|
|
15
|
+
instance
|
|
16
|
+
} = useChartContext();
|
|
17
|
+
const ZoomInIcon = slots?.zoomInIcon ?? defaultSlotsMaterial.zoomInIcon;
|
|
18
|
+
const Tooltip = slots?.baseTooltip ?? defaultSlotsMaterial.baseTooltip;
|
|
19
|
+
const {
|
|
20
|
+
localeText
|
|
21
|
+
} = useChartsLocalization();
|
|
22
|
+
return /*#__PURE__*/_jsx(Tooltip, {
|
|
23
|
+
title: localeText.zoomIn,
|
|
24
|
+
children: /*#__PURE__*/_jsx(ToolbarButton, {
|
|
25
|
+
onClick: () => instance.zoomIn(),
|
|
26
|
+
children: /*#__PURE__*/_jsx(ZoomInIcon, _extends({}, slotProps?.zoomInIcon))
|
|
27
|
+
})
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ChartsSlotsPro } from "../../internals/material/index.js";
|
|
3
|
+
type ChartsToolbarZoomOutButtonSlots = Partial<Pick<ChartsSlotsPro, 'baseTooltip' | 'zoomOutIcon'>>;
|
|
4
|
+
type ChartsToolbarZoomOutButtonSlotProps = { [K in keyof Required<ChartsToolbarZoomOutButtonSlots>]: React.ComponentProps<Required<ChartsToolbarZoomOutButtonSlots>[K]> };
|
|
5
|
+
interface ChartsToolbarZoomOutButtonProps {
|
|
6
|
+
slots?: ChartsToolbarZoomOutButtonSlots;
|
|
7
|
+
slotProps?: ChartsToolbarZoomOutButtonSlotProps;
|
|
8
|
+
}
|
|
9
|
+
export declare function ChartsToolbarZoomOutButton({
|
|
10
|
+
slots,
|
|
11
|
+
slotProps
|
|
12
|
+
}: ChartsToolbarZoomOutButtonProps): React.JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import { ToolbarButton } from '@mui/x-charts/Toolbar';
|
|
6
|
+
import { useChartContext } from '@mui/x-charts/internals';
|
|
7
|
+
import { useChartsLocalization } from '@mui/x-charts/hooks';
|
|
8
|
+
import { defaultSlotsMaterial } from "../../internals/material/index.js";
|
|
9
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
|
+
export function ChartsToolbarZoomOutButton({
|
|
11
|
+
slots,
|
|
12
|
+
slotProps
|
|
13
|
+
}) {
|
|
14
|
+
const {
|
|
15
|
+
instance
|
|
16
|
+
} = useChartContext();
|
|
17
|
+
const ZoomOutIcon = slots?.zoomOutIcon ?? defaultSlotsMaterial.zoomOutIcon;
|
|
18
|
+
const Tooltip = slots?.baseTooltip ?? defaultSlotsMaterial.baseTooltip;
|
|
19
|
+
const {
|
|
20
|
+
localeText
|
|
21
|
+
} = useChartsLocalization();
|
|
22
|
+
return /*#__PURE__*/_jsx(Tooltip, {
|
|
23
|
+
title: localeText.zoomOut,
|
|
24
|
+
children: /*#__PURE__*/_jsx(ToolbarButton, {
|
|
25
|
+
onClick: () => instance.zoomOut(),
|
|
26
|
+
children: /*#__PURE__*/_jsx(ZoomOutIcon, _extends({}, slotProps?.zoomOutIcon))
|
|
27
|
+
})
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -8,7 +8,6 @@ import { ChartsOverlay } from '@mui/x-charts/ChartsOverlay';
|
|
|
8
8
|
import { ChartsTooltip } from '@mui/x-charts/ChartsTooltip';
|
|
9
9
|
import { ChartsWrapper } from '@mui/x-charts/internals';
|
|
10
10
|
import { ChartsLegend } from '@mui/x-charts/ChartsLegend';
|
|
11
|
-
import { ChartsClipPath } from '@mui/x-charts/ChartsClipPath';
|
|
12
11
|
import { ChartsSurface } from '@mui/x-charts/ChartsSurface';
|
|
13
12
|
import { ChartsAxisHighlight } from '@mui/x-charts/ChartsAxisHighlight';
|
|
14
13
|
import { ChartsAxis } from '@mui/x-charts/ChartsAxis';
|
|
@@ -31,9 +30,7 @@ const FunnelChart = /*#__PURE__*/React.forwardRef(function FunnelChart(props, re
|
|
|
31
30
|
funnelPlotProps,
|
|
32
31
|
overlayProps,
|
|
33
32
|
legendProps,
|
|
34
|
-
clipPathGroupProps,
|
|
35
33
|
chartsAxisProps,
|
|
36
|
-
clipPathProps,
|
|
37
34
|
chartsWrapperProps,
|
|
38
35
|
axisHighlightProps,
|
|
39
36
|
children
|
|
@@ -47,11 +44,9 @@ const FunnelChart = /*#__PURE__*/React.forwardRef(function FunnelChart(props, re
|
|
|
47
44
|
seriesConfig: seriesConfig,
|
|
48
45
|
children: /*#__PURE__*/_jsxs(ChartsWrapper, _extends({}, chartsWrapperProps, {
|
|
49
46
|
children: [!themedProps.hideLegend && /*#__PURE__*/_jsx(ChartsLegend, _extends({}, legendProps)), /*#__PURE__*/_jsxs(ChartsSurface, _extends({}, chartsSurfaceProps, {
|
|
50
|
-
children: [/*#__PURE__*/
|
|
51
|
-
children: [/*#__PURE__*/_jsx(FunnelPlot, _extends({}, funnelPlotProps)), /*#__PURE__*/_jsx(ChartsOverlay, _extends({}, overlayProps)), /*#__PURE__*/_jsx(ChartsAxisHighlight, _extends({}, axisHighlightProps))]
|
|
52
|
-
})), !themedProps.loading && /*#__PURE__*/_jsx(Tooltip, _extends({}, themedProps.slotProps?.tooltip, {
|
|
47
|
+
children: [/*#__PURE__*/_jsx(FunnelPlot, _extends({}, funnelPlotProps)), /*#__PURE__*/_jsx(ChartsOverlay, _extends({}, overlayProps)), /*#__PURE__*/_jsx(ChartsAxisHighlight, _extends({}, axisHighlightProps)), !themedProps.loading && /*#__PURE__*/_jsx(Tooltip, _extends({}, themedProps.slotProps?.tooltip, {
|
|
53
48
|
trigger: "item"
|
|
54
|
-
})), /*#__PURE__*/_jsx(ChartsAxis, _extends({}, chartsAxisProps)),
|
|
49
|
+
})), /*#__PURE__*/_jsx(ChartsAxis, _extends({}, chartsAxisProps)), children]
|
|
55
50
|
}))]
|
|
56
51
|
}))
|
|
57
52
|
}));
|
|
@@ -63,6 +58,7 @@ process.env.NODE_ENV !== "production" ? FunnelChart.propTypes = {
|
|
|
63
58
|
// ----------------------------------------------------------------------
|
|
64
59
|
apiRef: PropTypes.shape({
|
|
65
60
|
current: PropTypes.shape({
|
|
61
|
+
exportAsImage: PropTypes.func.isRequired,
|
|
66
62
|
exportAsPrint: PropTypes.func.isRequired,
|
|
67
63
|
setZoomData: PropTypes.func.isRequired
|
|
68
64
|
})
|
|
@@ -176,6 +172,11 @@ process.env.NODE_ENV !== "production" ? FunnelChart.propTypes = {
|
|
|
176
172
|
* @default false
|
|
177
173
|
*/
|
|
178
174
|
disableAxisListener: PropTypes.bool,
|
|
175
|
+
/**
|
|
176
|
+
* The gap, in pixels, between funnel sections.
|
|
177
|
+
* @default 0
|
|
178
|
+
*/
|
|
179
|
+
gap: PropTypes.number,
|
|
179
180
|
/**
|
|
180
181
|
* The height of the chart in px. If not defined, it takes the height of the parent element.
|
|
181
182
|
*/
|
|
@@ -232,7 +233,7 @@ process.env.NODE_ENV !== "production" ? FunnelChart.propTypes = {
|
|
|
232
233
|
* The function called for onClick events.
|
|
233
234
|
* The second argument contains information about all line/bar elements at the current mouse position.
|
|
234
235
|
* @param {MouseEvent} event The mouse event recorded on the `<svg/>` element.
|
|
235
|
-
* @param {null |
|
|
236
|
+
* @param {null | ChartsAxisData} data The data about the clicked axis and items associated with it.
|
|
236
237
|
*/
|
|
237
238
|
onAxisClick: PropTypes.func,
|
|
238
239
|
/**
|
|
@@ -2,6 +2,11 @@ import * as React from 'react';
|
|
|
2
2
|
import { FunnelItemIdentifier } from "./funnel.types.js";
|
|
3
3
|
import { FunnelPlotSlotExtension } from "./funnelPlotSlots.types.js";
|
|
4
4
|
export interface FunnelPlotProps extends FunnelPlotSlotExtension {
|
|
5
|
+
/**
|
|
6
|
+
* The gap, in pixels, between funnel sections.
|
|
7
|
+
* @default 0
|
|
8
|
+
*/
|
|
9
|
+
gap?: number;
|
|
5
10
|
/**
|
|
6
11
|
* Callback fired when a funnel item is clicked.
|
|
7
12
|
* @param {React.MouseEvent<SVGElement, MouseEvent>} event The event source of the callback.
|
|
@@ -1,29 +1,20 @@
|
|
|
1
1
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
2
2
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
3
|
-
const _excluded = ["onItemClick"];
|
|
3
|
+
const _excluded = ["onItemClick", "gap"];
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import { line as d3Line } from '@mui/x-charts-vendor/d3-shape';
|
|
7
|
-
import {
|
|
7
|
+
import { cartesianSeriesTypes } from '@mui/x-charts/internals';
|
|
8
8
|
import { useXAxes, useYAxes } from '@mui/x-charts/hooks';
|
|
9
9
|
import { useTheme } from '@mui/material/styles';
|
|
10
10
|
import { FunnelSection } from "./FunnelSection.js";
|
|
11
11
|
import { alignLabel, positionLabel } from "./labelUtils.js";
|
|
12
|
-
import { funnelHorizontalStepCurve, funnelVerticalStepCurve } from "./funnelStepCurve.js";
|
|
13
12
|
import { useFunnelSeriesContext } from "../hooks/useFunnelSeries.js";
|
|
13
|
+
import { getFunnelCurve } from "./curves/index.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');
|
|
17
|
-
const
|
|
18
|
-
if (curve === 'step') {
|
|
19
|
-
return isHorizontal ? funnelHorizontalStepCurve : funnelVerticalStepCurve;
|
|
20
|
-
}
|
|
21
|
-
if (curve === 'bump') {
|
|
22
|
-
return isHorizontal ? getCurveFactory('bumpX') : getCurveFactory('bumpY');
|
|
23
|
-
}
|
|
24
|
-
return getCurveFactory(curve ?? 'linear');
|
|
25
|
-
};
|
|
26
|
-
const useAggregatedData = () => {
|
|
17
|
+
const useAggregatedData = gap => {
|
|
27
18
|
const seriesData = useFunnelSeriesContext();
|
|
28
19
|
const {
|
|
29
20
|
xAxis,
|
|
@@ -55,7 +46,6 @@ const useAggregatedData = () => {
|
|
|
55
46
|
const bandWidth = (isXAxisBand || isYAxisBand) && baseScaleConfig.scale?.bandwidth() || 0;
|
|
56
47
|
const xScale = xAxis[xAxisId].scale;
|
|
57
48
|
const yScale = yAxis[yAxisId].scale;
|
|
58
|
-
const curve = getFunnelCurve(currentSeries.curve, isHorizontal);
|
|
59
49
|
const xPosition = (value, bandIndex, stackOffset, useBand) => {
|
|
60
50
|
if (isXAxisBand) {
|
|
61
51
|
const position = xScale(bandIndex);
|
|
@@ -70,7 +60,17 @@ const useAggregatedData = () => {
|
|
|
70
60
|
}
|
|
71
61
|
return yScale(isHorizontal ? value : value + (stackOffset || 0));
|
|
72
62
|
};
|
|
73
|
-
|
|
63
|
+
const allY = currentSeries.dataPoints.flatMap((d, dataIndex) => d.flatMap(v => yPosition(v.y, baseScaleConfig.data?.[dataIndex], v.stackOffset, v.useBandWidth)));
|
|
64
|
+
const allX = currentSeries.dataPoints.flatMap((d, dataIndex) => d.flatMap(v => xPosition(v.x, baseScaleConfig.data?.[dataIndex], v.stackOffset, v.useBandWidth)));
|
|
65
|
+
const minPoint = {
|
|
66
|
+
x: Math.min(...allX),
|
|
67
|
+
y: Math.min(...allY)
|
|
68
|
+
};
|
|
69
|
+
const maxPoint = {
|
|
70
|
+
x: Math.max(...allX),
|
|
71
|
+
y: Math.max(...allY)
|
|
72
|
+
};
|
|
73
|
+
return currentSeries.dataPoints.flatMap((values, dataIndex) => {
|
|
74
74
|
const color = currentSeries.data[dataIndex].color;
|
|
75
75
|
const id = `${seriesId}-${dataIndex}`;
|
|
76
76
|
const sectionLabel = typeof currentSeries.sectionLabel === 'function' ? currentSeries.sectionLabel({
|
|
@@ -78,6 +78,15 @@ const useAggregatedData = () => {
|
|
|
78
78
|
seriesId,
|
|
79
79
|
value: currentSeries.data[dataIndex].value
|
|
80
80
|
}) : currentSeries.sectionLabel;
|
|
81
|
+
const curve = getFunnelCurve(currentSeries.curve, {
|
|
82
|
+
isHorizontal,
|
|
83
|
+
gap,
|
|
84
|
+
position: dataIndex,
|
|
85
|
+
sections: currentSeries.dataPoints.length,
|
|
86
|
+
borderRadius: currentSeries.borderRadius,
|
|
87
|
+
min: minPoint,
|
|
88
|
+
max: maxPoint
|
|
89
|
+
});
|
|
81
90
|
const line = d3Line().x(d => xPosition(d.x, baseScaleConfig.data?.[dataIndex], d.stackOffset, d.useBandWidth)).y(d => yPosition(d.y, baseScaleConfig.data?.[dataIndex], d.stackOffset, d.useBandWidth)).curve(curve);
|
|
82
91
|
return {
|
|
83
92
|
d: line(values),
|
|
@@ -85,6 +94,7 @@ const useAggregatedData = () => {
|
|
|
85
94
|
id,
|
|
86
95
|
seriesId,
|
|
87
96
|
dataIndex,
|
|
97
|
+
variant: currentSeries.variant,
|
|
88
98
|
label: sectionLabel !== false && _extends({}, positionLabel(_extends({}, sectionLabel, {
|
|
89
99
|
xPosition,
|
|
90
100
|
yPosition,
|
|
@@ -101,29 +111,32 @@ const useAggregatedData = () => {
|
|
|
101
111
|
});
|
|
102
112
|
});
|
|
103
113
|
return result.flat();
|
|
104
|
-
}, [seriesData, xAxis, xAxisIds, yAxis, yAxisIds]);
|
|
114
|
+
}, [seriesData, xAxis, xAxisIds, yAxis, yAxisIds, gap]);
|
|
105
115
|
return allData;
|
|
106
116
|
};
|
|
107
117
|
function FunnelPlot(props) {
|
|
108
118
|
const {
|
|
109
|
-
onItemClick
|
|
119
|
+
onItemClick,
|
|
120
|
+
gap
|
|
110
121
|
} = props,
|
|
111
122
|
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
112
123
|
const theme = useTheme();
|
|
113
|
-
const data = useAggregatedData();
|
|
124
|
+
const data = useAggregatedData(gap);
|
|
114
125
|
return /*#__PURE__*/_jsxs(React.Fragment, {
|
|
115
126
|
children: [data.map(({
|
|
116
127
|
d,
|
|
117
128
|
color,
|
|
118
129
|
id,
|
|
119
130
|
seriesId,
|
|
120
|
-
dataIndex
|
|
131
|
+
dataIndex,
|
|
132
|
+
variant
|
|
121
133
|
}) => /*#__PURE__*/_createElement(FunnelSection, _extends({}, other, {
|
|
122
134
|
d: d,
|
|
123
135
|
color: color,
|
|
124
136
|
key: id,
|
|
125
137
|
dataIndex: dataIndex,
|
|
126
138
|
seriesId: seriesId,
|
|
139
|
+
variant: variant,
|
|
127
140
|
onClick: onItemClick && (event => {
|
|
128
141
|
onItemClick(event, {
|
|
129
142
|
type: 'funnel',
|
|
@@ -164,6 +177,11 @@ process.env.NODE_ENV !== "production" ? FunnelPlot.propTypes = {
|
|
|
164
177
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
165
178
|
// | To update them edit the TypeScript types and run "pnpm proptypes" |
|
|
166
179
|
// ----------------------------------------------------------------------
|
|
180
|
+
/**
|
|
181
|
+
* The gap, in pixels, between funnel sections.
|
|
182
|
+
* @default 0
|
|
183
|
+
*/
|
|
184
|
+
gap: PropTypes.number,
|
|
167
185
|
/**
|
|
168
186
|
* Callback fired when a funnel item is clicked.
|
|
169
187
|
* @param {React.MouseEvent<SVGElement, MouseEvent>} event The event source of the callback.
|
|
@@ -6,6 +6,7 @@ export interface FunnelSectionProps extends Omit<React.SVGProps<SVGPathElement>,
|
|
|
6
6
|
dataIndex: number;
|
|
7
7
|
color: string;
|
|
8
8
|
classes?: Partial<FunnelSectionClasses>;
|
|
9
|
+
variant?: 'filled' | 'outlined';
|
|
9
10
|
}
|
|
10
11
|
export declare const FunnelSectionPath: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, React.SVGProps<SVGPathElement>, {}>;
|
|
11
12
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
4
4
|
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
|
5
|
-
const _excluded = ["seriesId", "dataIndex", "classes", "color", "onClick", "className"];
|
|
5
|
+
const _excluded = ["seriesId", "dataIndex", "classes", "color", "onClick", "className", "variant"];
|
|
6
6
|
import * as React from 'react';
|
|
7
7
|
import { styled } from '@mui/material/styles';
|
|
8
8
|
import { useInteractionItemProps, consumeSlots } from '@mui/x-charts/internals';
|
|
@@ -11,7 +11,7 @@ import clsx from 'clsx';
|
|
|
11
11
|
import { useUtilityClasses } from "./funnelSectionClasses.js";
|
|
12
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
13
|
export const FunnelSectionPath = styled('path')(() => ({
|
|
14
|
-
transition: 'opacity 0.2s ease-in, fill 0.2s ease-in'
|
|
14
|
+
transition: 'opacity 0.2s ease-in, fill 0.2s ease-in, fill-opacity 0.2s ease-in, filter 0.2s ease-in'
|
|
15
15
|
}));
|
|
16
16
|
|
|
17
17
|
/**
|
|
@@ -26,7 +26,8 @@ const FunnelSection = consumeSlots('MuiFunnelSection', 'funnelSection', {
|
|
|
26
26
|
classes,
|
|
27
27
|
color,
|
|
28
28
|
onClick,
|
|
29
|
-
className
|
|
29
|
+
className,
|
|
30
|
+
variant = 'filled'
|
|
30
31
|
} = props,
|
|
31
32
|
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
32
33
|
const interactionProps = useInteractionItemProps({
|
|
@@ -41,14 +42,18 @@ const FunnelSection = consumeSlots('MuiFunnelSection', 'funnelSection', {
|
|
|
41
42
|
seriesId,
|
|
42
43
|
dataIndex
|
|
43
44
|
});
|
|
45
|
+
const isOutlined = variant === 'outlined';
|
|
44
46
|
return /*#__PURE__*/_jsx(FunnelSectionPath, _extends({}, interactionProps, {
|
|
45
|
-
filter: isHighlighted ? 'brightness(120%)' : undefined,
|
|
46
|
-
opacity: isFaded ? 0.3 : 1,
|
|
47
|
+
filter: isHighlighted && !isOutlined ? 'brightness(120%)' : undefined,
|
|
48
|
+
opacity: isFaded && !isOutlined ? 0.3 : 1,
|
|
47
49
|
fill: color,
|
|
48
|
-
stroke:
|
|
50
|
+
stroke: isOutlined ? color : 'none',
|
|
51
|
+
fillOpacity: isOutlined && !isHighlighted ? 0.4 : 1,
|
|
52
|
+
strokeOpacity: 1,
|
|
53
|
+
strokeWidth: isOutlined ? 1.5 : 0,
|
|
49
54
|
cursor: onClick ? 'pointer' : 'unset',
|
|
50
55
|
onClick: onClick,
|
|
51
|
-
className: clsx(classes?.root, className, isHighlighted && classes?.highlighted, isFaded && classes?.faded)
|
|
56
|
+
className: clsx(classes?.root, className, isOutlined ? classes?.outlined : classes?.filled, isHighlighted && classes?.highlighted, isFaded && classes?.faded)
|
|
52
57
|
}, other, {
|
|
53
58
|
ref: ref
|
|
54
59
|
}));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Point } from "./curve.types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Draws a polygon with rounded corners
|
|
4
|
+
* @param {CanvasRenderingContext2D} ctx The canvas context
|
|
5
|
+
* @param {Array} points A list of `{x, y}` points
|
|
6
|
+
* @param {number} radius how much to round the corners
|
|
7
|
+
*/
|
|
8
|
+
export declare function borderRadiusPolygon(ctx: CanvasRenderingContext2D, points: Point[], radius: number | number[]): void;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const distance = (p1, p2) => Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
|
|
2
|
+
const lerp = (a, b, x) => a + (b - a) * x;
|
|
3
|
+
const lerp2D = (p1, p2, t) => ({
|
|
4
|
+
x: lerp(p1.x, p2.x, t),
|
|
5
|
+
y: lerp(p1.y, p2.y, t)
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Draws a polygon with rounded corners
|
|
10
|
+
* @param {CanvasRenderingContext2D} ctx The canvas context
|
|
11
|
+
* @param {Array} points A list of `{x, y}` points
|
|
12
|
+
* @param {number} radius how much to round the corners
|
|
13
|
+
*/
|
|
14
|
+
export function borderRadiusPolygon(ctx, points, radius) {
|
|
15
|
+
const numPoints = points.length;
|
|
16
|
+
radius = Array.isArray(radius) ? radius : Array(numPoints).fill(radius);
|
|
17
|
+
const corners = [];
|
|
18
|
+
for (let i = 0; i < numPoints; i += 1) {
|
|
19
|
+
const lastPoint = points[i];
|
|
20
|
+
const thisPoint = points[(i + 1) % numPoints];
|
|
21
|
+
const nextPoint = points[(i + 2) % numPoints];
|
|
22
|
+
const lastEdgeLength = distance(lastPoint, thisPoint);
|
|
23
|
+
const lastOffsetDistance = Math.min(lastEdgeLength / 2, radius[i] ?? 0);
|
|
24
|
+
const start = lerp2D(thisPoint, lastPoint, lastOffsetDistance / lastEdgeLength);
|
|
25
|
+
const nextEdgeLength = distance(nextPoint, thisPoint);
|
|
26
|
+
const nextOffsetDistance = Math.min(nextEdgeLength / 2, radius[i] ?? 0);
|
|
27
|
+
const end = lerp2D(thisPoint, nextPoint, nextOffsetDistance / nextEdgeLength);
|
|
28
|
+
corners.push([start, thisPoint, end]);
|
|
29
|
+
}
|
|
30
|
+
ctx.moveTo(corners[0][0].x, corners[0][0].y);
|
|
31
|
+
for (const [start, ctrl, end] of corners) {
|
|
32
|
+
ctx.lineTo(start.x, start.y);
|
|
33
|
+
ctx.quadraticCurveTo(ctrl.x, ctrl.y, end.x, end.y);
|
|
34
|
+
}
|
|
35
|
+
ctx.closePath();
|
|
36
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { CurveGenerator } from '@mui/x-charts-vendor/d3-shape';
|
|
2
|
+
import { CurveOptions } from "./curve.types.js";
|
|
3
|
+
/**
|
|
4
|
+
* This is a custom "bump" curve generator.
|
|
5
|
+
* It draws smooth curves for the 4 provided points,
|
|
6
|
+
* with the option to add a gap between sections while also properly handling the border radius.
|
|
7
|
+
*
|
|
8
|
+
* The implementation is based on the d3-shape bump curve generator.
|
|
9
|
+
* https://github.com/d3/d3-shape/blob/a82254af78f08799c71d7ab25df557c4872a3c51/src/curve/bump.js
|
|
10
|
+
*/
|
|
11
|
+
export declare class Bump implements CurveGenerator {
|
|
12
|
+
private context;
|
|
13
|
+
private x;
|
|
14
|
+
private y;
|
|
15
|
+
private currentPoint;
|
|
16
|
+
private isHorizontal;
|
|
17
|
+
private gap;
|
|
18
|
+
constructor(context: CanvasRenderingContext2D, {
|
|
19
|
+
isHorizontal,
|
|
20
|
+
gap
|
|
21
|
+
}: CurveOptions);
|
|
22
|
+
areaStart(): void;
|
|
23
|
+
areaEnd(): void;
|
|
24
|
+
lineStart(): void;
|
|
25
|
+
lineEnd(): void;
|
|
26
|
+
point(x: number, y: number): void;
|
|
27
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/* eslint-disable class-methods-use-this */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This is a custom "bump" curve generator.
|
|
5
|
+
* It draws smooth curves for the 4 provided points,
|
|
6
|
+
* with the option to add a gap between sections while also properly handling the border radius.
|
|
7
|
+
*
|
|
8
|
+
* The implementation is based on the d3-shape bump curve generator.
|
|
9
|
+
* https://github.com/d3/d3-shape/blob/a82254af78f08799c71d7ab25df557c4872a3c51/src/curve/bump.js
|
|
10
|
+
*/
|
|
11
|
+
export class Bump {
|
|
12
|
+
constructor(context, {
|
|
13
|
+
isHorizontal,
|
|
14
|
+
gap
|
|
15
|
+
}) {
|
|
16
|
+
this.context = void 0;
|
|
17
|
+
this.x = NaN;
|
|
18
|
+
this.y = NaN;
|
|
19
|
+
this.currentPoint = 0;
|
|
20
|
+
this.isHorizontal = false;
|
|
21
|
+
this.gap = 0;
|
|
22
|
+
this.context = context;
|
|
23
|
+
this.isHorizontal = isHorizontal ?? false;
|
|
24
|
+
this.gap = (gap ?? 0) / 2;
|
|
25
|
+
}
|
|
26
|
+
areaStart() {}
|
|
27
|
+
areaEnd() {}
|
|
28
|
+
lineStart() {}
|
|
29
|
+
lineEnd() {}
|
|
30
|
+
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;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
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);
|
|
64
|
+
} 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
|
+
}
|
|
70
|
+
this.currentPoint += 1;
|
|
71
|
+
this.x = x;
|
|
72
|
+
this.y = y;
|
|
73
|
+
}
|
|
74
|
+
}
|