@mui/x-charts-pro 8.5.1 → 8.5.3
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 +3 -2
- package/CHANGELOG.md +187 -10
- package/ChartDataProviderPro/ChartDataProviderPro.js +1 -1
- package/ChartZoomSlider/internals/ChartAxisZoomSlider.js +1 -1
- package/ChartZoomSlider/internals/ChartAxisZoomSliderActiveTrack.js +22 -32
- package/ChartZoomSlider/internals/ChartAxisZoomSliderTrack.js +1 -8
- package/ChartZoomSlider/internals/zoom-utils.d.ts +3 -1
- package/ChartZoomSlider/internals/zoom-utils.js +19 -8
- package/ChartsToolbarPro/ChartsToolbarPro.d.ts +2 -1
- package/ChartsToolbarPro/Toolbar.types.d.ts +15 -0
- package/ChartsToolbarPro/Toolbar.types.js +5 -0
- package/FunnelChart/FunnelChart.js +4 -11
- package/FunnelChart/FunnelChart.plugins.d.ts +3 -2
- package/FunnelChart/FunnelChart.plugins.js +2 -1
- package/FunnelChart/FunnelPlot.d.ts +0 -5
- package/FunnelChart/FunnelPlot.js +85 -67
- package/FunnelChart/FunnelSection.js +2 -0
- package/FunnelChart/categoryAxis.types.d.ts +2 -1
- package/FunnelChart/curves/bump.d.ts +3 -5
- package/FunnelChart/curves/bump.js +13 -13
- package/FunnelChart/curves/curve.types.d.ts +14 -1
- package/FunnelChart/curves/getFunnelCurve.d.ts +7 -2
- package/FunnelChart/curves/linear.d.ts +4 -4
- package/FunnelChart/curves/linear.js +42 -34
- package/FunnelChart/curves/pyramid.d.ts +3 -3
- package/FunnelChart/curves/pyramid.js +25 -24
- package/FunnelChart/curves/step-pyramid.d.ts +5 -5
- package/FunnelChart/curves/step-pyramid.js +24 -24
- package/FunnelChart/curves/step.d.ts +3 -3
- package/FunnelChart/curves/step.js +14 -26
- package/FunnelChart/funnelAxisPlugin/computeAxisValue.d.ts +25 -0
- package/FunnelChart/funnelAxisPlugin/computeAxisValue.js +124 -0
- package/FunnelChart/funnelAxisPlugin/useChartFunnelAxis.d.ts +3 -0
- package/FunnelChart/funnelAxisPlugin/useChartFunnelAxis.js +173 -0
- package/FunnelChart/funnelAxisPlugin/useChartFunnelAxis.types.d.ts +27 -0
- package/FunnelChart/funnelAxisPlugin/useChartFunnelAxis.types.js +5 -0
- package/FunnelChart/funnelAxisPlugin/useChartFunnelAxisRendering.selectors.d.ts +56 -0
- package/FunnelChart/funnelAxisPlugin/useChartFunnelAxisRendering.selectors.js +27 -0
- package/FunnelChart/labelUtils.d.ts +4 -11
- package/FunnelChart/labelUtils.js +43 -44
- package/FunnelChart/useFunnelChartProps.js +1 -3
- package/Heatmap/Heatmap.d.ts +3 -3
- package/LineChartPro/LineChartPro.d.ts +3 -2
- package/PieChartPro/PieChartPro.d.ts +3 -2
- package/RadarChartPro/RadarChartPro.d.ts +17 -2
- package/ScatterChartPro/ScatterChartPro.d.ts +3 -2
- package/esm/BarChartPro/BarChartPro.d.ts +3 -2
- package/esm/ChartDataProviderPro/ChartDataProviderPro.js +1 -1
- package/esm/ChartZoomSlider/internals/ChartAxisZoomSlider.js +1 -1
- package/esm/ChartZoomSlider/internals/ChartAxisZoomSliderActiveTrack.js +23 -33
- package/esm/ChartZoomSlider/internals/ChartAxisZoomSliderTrack.js +1 -8
- package/esm/ChartZoomSlider/internals/zoom-utils.d.ts +3 -1
- package/esm/ChartZoomSlider/internals/zoom-utils.js +19 -9
- package/esm/ChartsToolbarPro/ChartsToolbarPro.d.ts +2 -1
- package/esm/ChartsToolbarPro/Toolbar.types.d.ts +15 -0
- package/esm/ChartsToolbarPro/Toolbar.types.js +1 -0
- package/esm/FunnelChart/FunnelChart.js +4 -11
- package/esm/FunnelChart/FunnelChart.plugins.d.ts +3 -2
- package/esm/FunnelChart/FunnelChart.plugins.js +3 -2
- package/esm/FunnelChart/FunnelPlot.d.ts +0 -5
- package/esm/FunnelChart/FunnelPlot.js +86 -68
- package/esm/FunnelChart/FunnelSection.js +2 -0
- package/esm/FunnelChart/categoryAxis.types.d.ts +2 -1
- package/esm/FunnelChart/curves/bump.d.ts +3 -5
- package/esm/FunnelChart/curves/bump.js +13 -13
- package/esm/FunnelChart/curves/curve.types.d.ts +14 -1
- package/esm/FunnelChart/curves/getFunnelCurve.d.ts +7 -2
- package/esm/FunnelChart/curves/linear.d.ts +4 -4
- package/esm/FunnelChart/curves/linear.js +42 -34
- package/esm/FunnelChart/curves/pyramid.d.ts +3 -3
- package/esm/FunnelChart/curves/pyramid.js +25 -24
- package/esm/FunnelChart/curves/step-pyramid.d.ts +5 -5
- package/esm/FunnelChart/curves/step-pyramid.js +24 -24
- package/esm/FunnelChart/curves/step.d.ts +3 -3
- package/esm/FunnelChart/curves/step.js +14 -26
- package/esm/FunnelChart/funnelAxisPlugin/computeAxisValue.d.ts +25 -0
- package/esm/FunnelChart/funnelAxisPlugin/computeAxisValue.js +114 -0
- package/esm/FunnelChart/funnelAxisPlugin/useChartFunnelAxis.d.ts +3 -0
- package/esm/FunnelChart/funnelAxisPlugin/useChartFunnelAxis.js +165 -0
- package/esm/FunnelChart/funnelAxisPlugin/useChartFunnelAxis.types.d.ts +27 -0
- package/esm/FunnelChart/funnelAxisPlugin/useChartFunnelAxis.types.js +1 -0
- package/esm/FunnelChart/funnelAxisPlugin/useChartFunnelAxisRendering.selectors.d.ts +56 -0
- package/esm/FunnelChart/funnelAxisPlugin/useChartFunnelAxisRendering.selectors.js +20 -0
- package/esm/FunnelChart/labelUtils.d.ts +4 -11
- package/esm/FunnelChart/labelUtils.js +43 -44
- package/esm/FunnelChart/useFunnelChartProps.js +1 -3
- package/esm/Heatmap/Heatmap.d.ts +3 -3
- package/esm/LineChartPro/LineChartPro.d.ts +3 -2
- package/esm/PieChartPro/PieChartPro.d.ts +3 -2
- package/esm/RadarChartPro/RadarChartPro.d.ts +17 -2
- package/esm/ScatterChartPro/ScatterChartPro.d.ts +3 -2
- package/esm/index.js +1 -1
- package/esm/internals/plugins/useChartProZoom/useChartProZoom.selectors.d.ts +16 -595
- package/esm/internals/plugins/useChartProZoom/useChartProZoom.selectors.js +2 -2
- package/index.js +1 -1
- package/internals/plugins/useChartProZoom/useChartProZoom.selectors.d.ts +16 -595
- package/internals/plugins/useChartProZoom/useChartProZoom.selectors.js +2 -2
- package/package.json +6 -6
|
@@ -42,7 +42,7 @@ class StepPyramid {
|
|
|
42
42
|
this.points = [];
|
|
43
43
|
this.context = context;
|
|
44
44
|
this.isHorizontal = isHorizontal ?? false;
|
|
45
|
-
this.gap =
|
|
45
|
+
this.gap = gap ?? 0;
|
|
46
46
|
this.position = position ?? 0;
|
|
47
47
|
this.sections = sections ?? 1;
|
|
48
48
|
this.borderRadius = borderRadius ?? 0;
|
|
@@ -135,48 +135,48 @@ class StepPyramid {
|
|
|
135
135
|
y: this.max.y
|
|
136
136
|
};
|
|
137
137
|
}
|
|
138
|
-
initialX(index) {
|
|
138
|
+
initialX(index, points) {
|
|
139
139
|
if (this.isIncreasing) {
|
|
140
|
-
return index === 0 || index === 1 ?
|
|
140
|
+
return index === 0 || index === 1 ? points.at(1).x : points.at(2).x;
|
|
141
141
|
}
|
|
142
|
-
return index === 0 || index === 1 ?
|
|
142
|
+
return index === 0 || index === 1 ? points.at(0).x : points.at(3).x;
|
|
143
143
|
}
|
|
144
|
-
initialY(index) {
|
|
144
|
+
initialY(index, points) {
|
|
145
145
|
if (this.isIncreasing) {
|
|
146
|
-
return index === 0 || index === 1 ?
|
|
146
|
+
return index === 0 || index === 1 ? points.at(1).y : points.at(2).y;
|
|
147
147
|
}
|
|
148
|
-
return index === 0 || index === 1 ?
|
|
148
|
+
return index === 0 || index === 1 ? points.at(0).y : points.at(3).y;
|
|
149
149
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
y: yIn
|
|
154
|
-
});
|
|
155
|
-
if (this.points.length < 4) {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Add gaps where they are needed.
|
|
160
|
-
this.points = this.points.map((point, index) => {
|
|
150
|
+
processPoints(points) {
|
|
151
|
+
// Replace funnel points by pyramids ones.
|
|
152
|
+
const processedPoints = points.map((point, index) => {
|
|
161
153
|
const slopeStart = this.slopeStart(index);
|
|
162
154
|
const slopeEnd = this.slopeEnd(index);
|
|
163
155
|
if (this.isHorizontal) {
|
|
164
156
|
const yGetter = (0, _utils.lerpY)(slopeStart.x, slopeStart.y, slopeEnd.x, slopeEnd.y);
|
|
165
|
-
const
|
|
166
|
-
const xInitial = this.initialX(index);
|
|
157
|
+
const xInitial = this.initialX(index, points);
|
|
167
158
|
return {
|
|
168
|
-
x:
|
|
159
|
+
x: point.x,
|
|
169
160
|
y: yGetter(xInitial)
|
|
170
161
|
};
|
|
171
162
|
}
|
|
172
163
|
const xGetter = (0, _utils.lerpX)(slopeStart.x, slopeStart.y, slopeEnd.x, slopeEnd.y);
|
|
173
|
-
const
|
|
174
|
-
const yInitial = this.initialY(index);
|
|
164
|
+
const yInitial = this.initialY(index, points);
|
|
175
165
|
return {
|
|
176
166
|
x: xGetter(yInitial),
|
|
177
|
-
y:
|
|
167
|
+
y: point.y
|
|
178
168
|
};
|
|
179
169
|
});
|
|
170
|
+
return processedPoints;
|
|
171
|
+
}
|
|
172
|
+
point(xIn, yIn) {
|
|
173
|
+
this.points.push({
|
|
174
|
+
x: xIn,
|
|
175
|
+
y: yIn
|
|
176
|
+
});
|
|
177
|
+
if (this.points.length < 4) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
180
|
(0, _borderRadiusPolygon.borderRadiusPolygon)(this.context, this.points, this.getBorderRadius());
|
|
181
181
|
}
|
|
182
182
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CurveOptions } from "./curve.types.js";
|
|
1
|
+
import { FunnelCurveGenerator, CurveOptions, Point } from "./curve.types.js";
|
|
3
2
|
/**
|
|
4
3
|
* This is a custom "step" curve generator.
|
|
5
4
|
* It is used to draw "rectangles" from 4 points without having to rework the rendering logic,
|
|
@@ -10,7 +9,7 @@ import { CurveOptions } from "./curve.types.js";
|
|
|
10
9
|
* The implementation is based on the d3-shape step curve generator.
|
|
11
10
|
* https://github.com/d3/d3-shape/blob/a82254af78f08799c71d7ab25df557c4872a3c51/src/curve/step.js
|
|
12
11
|
*/
|
|
13
|
-
export declare class Step implements
|
|
12
|
+
export declare class Step implements FunnelCurveGenerator {
|
|
14
13
|
private context;
|
|
15
14
|
private isHorizontal;
|
|
16
15
|
private isIncreasing;
|
|
@@ -32,5 +31,6 @@ export declare class Step implements CurveGenerator {
|
|
|
32
31
|
lineStart(): void;
|
|
33
32
|
lineEnd(): void;
|
|
34
33
|
protected getBorderRadius(): number | number[];
|
|
34
|
+
processPoints(points: Point[]): Point[];
|
|
35
35
|
point(xIn: number, yIn: number): void;
|
|
36
36
|
}
|
|
@@ -37,7 +37,7 @@ class Step {
|
|
|
37
37
|
this.points = [];
|
|
38
38
|
this.context = context;
|
|
39
39
|
this.isHorizontal = isHorizontal ?? false;
|
|
40
|
-
this.gap =
|
|
40
|
+
this.gap = gap ?? 0;
|
|
41
41
|
this.position = position ?? 0;
|
|
42
42
|
this.sections = sections ?? 1;
|
|
43
43
|
this.borderRadius = borderRadius ?? 0;
|
|
@@ -62,19 +62,11 @@ class Step {
|
|
|
62
62
|
}
|
|
63
63
|
return [this.borderRadius, this.borderRadius];
|
|
64
64
|
}
|
|
65
|
-
|
|
66
|
-
this.points.push({
|
|
67
|
-
x: xIn,
|
|
68
|
-
y: yIn
|
|
69
|
-
});
|
|
70
|
-
if (this.points.length < 4) {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
|
|
65
|
+
processPoints(points) {
|
|
74
66
|
// Ensure we have rectangles instead of trapezoids.
|
|
75
|
-
|
|
76
|
-
const allX =
|
|
77
|
-
const allY =
|
|
67
|
+
const processedPoints = points.map((_, index) => {
|
|
68
|
+
const allX = points.map(p => p.x);
|
|
69
|
+
const allY = points.map(p => p.y);
|
|
78
70
|
if (this.isHorizontal) {
|
|
79
71
|
return {
|
|
80
72
|
x: index === 1 || index === 2 ? (0, _utils.max)(allX) : (0, _utils.min)(allX),
|
|
@@ -86,20 +78,16 @@ class Step {
|
|
|
86
78
|
y: index === 1 || index === 2 ? (0, _utils.max)(allY) : (0, _utils.min)(allY)
|
|
87
79
|
};
|
|
88
80
|
});
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
y: point.y
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
return {
|
|
99
|
-
x: point.x,
|
|
100
|
-
y: point.y + (index === 0 || index === 3 ? this.gap : -this.gap)
|
|
101
|
-
};
|
|
81
|
+
return processedPoints;
|
|
82
|
+
}
|
|
83
|
+
point(xIn, yIn) {
|
|
84
|
+
this.points.push({
|
|
85
|
+
x: xIn,
|
|
86
|
+
y: yIn
|
|
102
87
|
});
|
|
88
|
+
if (this.points.length < 4) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
103
91
|
(0, _borderRadiusPolygon.borderRadiusPolygon)(this.context, this.points, this.getBorderRadius());
|
|
104
92
|
}
|
|
105
93
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ChartsAxisProps } from '@mui/x-charts/ChartsAxis';
|
|
2
|
+
import { ChartDrawingArea } from '@mui/x-charts/hooks';
|
|
3
|
+
import { ComputedAxisConfig, ChartSeriesType, ProcessedSeries, ChartSeriesConfig, DefaultedYAxis, DefaultedXAxis } from '@mui/x-charts/internals';
|
|
4
|
+
import { ChartsXAxisProps, ChartsYAxisProps } from '@mui/x-charts/models';
|
|
5
|
+
export declare const xRangeGetter: (drawingArea: ChartDrawingArea, reverse?: boolean, removedSpace?: number) => [number, number];
|
|
6
|
+
export declare const yRangeGetter: (drawingArea: ChartDrawingArea, reverse?: boolean, removedSpace?: number) => [number, number];
|
|
7
|
+
export type ComputeResult<T extends ChartsAxisProps> = {
|
|
8
|
+
axis: ComputedAxisConfig<T>;
|
|
9
|
+
axisIds: string[];
|
|
10
|
+
};
|
|
11
|
+
type ComputeCommonParams<T extends ChartSeriesType = 'funnel'> = {
|
|
12
|
+
drawingArea: ChartDrawingArea;
|
|
13
|
+
formattedSeries: ProcessedSeries<T>;
|
|
14
|
+
seriesConfig: ChartSeriesConfig<T>;
|
|
15
|
+
gap: number;
|
|
16
|
+
};
|
|
17
|
+
export declare function computeAxisValue(options: ComputeCommonParams<'funnel'> & {
|
|
18
|
+
axis?: DefaultedYAxis[];
|
|
19
|
+
axisDirection: 'y';
|
|
20
|
+
}): ComputeResult<ChartsYAxisProps>;
|
|
21
|
+
export declare function computeAxisValue(options: ComputeCommonParams<'funnel'> & {
|
|
22
|
+
axis?: DefaultedXAxis[];
|
|
23
|
+
axisDirection: 'x';
|
|
24
|
+
}): ComputeResult<ChartsXAxisProps>;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.computeAxisValue = computeAxisValue;
|
|
8
|
+
exports.yRangeGetter = exports.xRangeGetter = void 0;
|
|
9
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
10
|
+
var _d3Scale = require("@mui/x-charts-vendor/d3-scale");
|
|
11
|
+
var _internals = require("@mui/x-charts/internals");
|
|
12
|
+
const xRangeGetter = (drawingArea, reverse, removedSpace = 0) => {
|
|
13
|
+
const range = [drawingArea.left, drawingArea.left + drawingArea.width - removedSpace];
|
|
14
|
+
return reverse ? [range[1], range[0]] : [range[0], range[1]];
|
|
15
|
+
};
|
|
16
|
+
exports.xRangeGetter = xRangeGetter;
|
|
17
|
+
const yRangeGetter = (drawingArea, reverse, removedSpace = 0) => {
|
|
18
|
+
const range = [drawingArea.top + drawingArea.height - removedSpace, drawingArea.top];
|
|
19
|
+
return reverse ? [range[1], range[0]] : [range[0], range[1]];
|
|
20
|
+
};
|
|
21
|
+
exports.yRangeGetter = yRangeGetter;
|
|
22
|
+
function getRange(drawingArea, axisDirection, axis, removedSpace = 0) {
|
|
23
|
+
return axisDirection === 'x' ? xRangeGetter(drawingArea, axis.reverse, removedSpace) : yRangeGetter(drawingArea, axis.reverse, removedSpace);
|
|
24
|
+
}
|
|
25
|
+
function computeAxisValue({
|
|
26
|
+
drawingArea,
|
|
27
|
+
formattedSeries,
|
|
28
|
+
axis: allAxis,
|
|
29
|
+
seriesConfig,
|
|
30
|
+
axisDirection,
|
|
31
|
+
gap
|
|
32
|
+
}) {
|
|
33
|
+
if (allAxis === undefined) {
|
|
34
|
+
return {
|
|
35
|
+
axis: {},
|
|
36
|
+
axisIds: []
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const axisIdsTriggeringTooltip = (0, _internals.getCartesianAxisTriggerTooltip)(axisDirection, seriesConfig, formattedSeries, allAxis[0].id);
|
|
40
|
+
const completeAxis = {};
|
|
41
|
+
allAxis.forEach((eachAxis, axisIndex) => {
|
|
42
|
+
const axis = eachAxis;
|
|
43
|
+
let range = getRange(drawingArea, axisDirection, axis);
|
|
44
|
+
const [minData, maxData] = (0, _internals.getAxisExtremum)(axis, axisDirection, seriesConfig, axisIndex, formattedSeries);
|
|
45
|
+
const triggerTooltip = !axis.ignoreTooltip && axisIdsTriggeringTooltip.has(axis.id);
|
|
46
|
+
const data = axis.data ?? [];
|
|
47
|
+
if ((0, _internals.isBandScaleConfig)(axis)) {
|
|
48
|
+
// Reverse range because ordinal scales are presented from top to bottom on y-axis
|
|
49
|
+
const scaleRange = axisDirection === 'y' ? [range[1], range[0]] : range;
|
|
50
|
+
const rangeSpace = Math.abs(range[1] - range[0]);
|
|
51
|
+
const N = axis.data.length;
|
|
52
|
+
const bandWidth = (rangeSpace - gap * (N - 1)) / N;
|
|
53
|
+
const step = bandWidth + gap;
|
|
54
|
+
completeAxis[axis.id] = (0, _extends2.default)({
|
|
55
|
+
offset: 0,
|
|
56
|
+
height: 0,
|
|
57
|
+
categoryGapRatio: 0,
|
|
58
|
+
barGapRatio: 0,
|
|
59
|
+
triggerTooltip
|
|
60
|
+
}, axis, {
|
|
61
|
+
data,
|
|
62
|
+
scale: (0, _d3Scale.scaleBand)(axis.data, scaleRange).paddingInner(gap / step).paddingOuter(0),
|
|
63
|
+
tickNumber: axis.data.length,
|
|
64
|
+
colorScale: axis.colorMap && (axis.colorMap.type === 'ordinal' ? (0, _internals.getOrdinalColorScale)((0, _extends2.default)({
|
|
65
|
+
values: axis.data
|
|
66
|
+
}, axis.colorMap)) : (0, _internals.getColorScale)(axis.colorMap))
|
|
67
|
+
});
|
|
68
|
+
if ((0, _internals.isDateData)(axis.data)) {
|
|
69
|
+
const dateFormatter = (0, _internals.createDateFormatter)(axis, scaleRange);
|
|
70
|
+
completeAxis[axis.id].valueFormatter = axis.valueFormatter ?? dateFormatter;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (axis.scaleType === 'band') {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (axis.scaleType === 'point') {
|
|
77
|
+
throw new Error('Point scale is not supported in FunnelChart. Please use band scale instead.');
|
|
78
|
+
}
|
|
79
|
+
const isHorizontal = Object.values(formattedSeries.funnel?.series ?? {}).some(s => s.layout === 'horizontal');
|
|
80
|
+
if (isHorizontal ? axisDirection === 'x' : axisDirection === 'y') {
|
|
81
|
+
// For linear scale replacing the band scale, we remove the space needed for gap from the scale range.
|
|
82
|
+
const itemNumber = formattedSeries.funnel?.series[formattedSeries.funnel.seriesOrder[0]].data.length ?? 0;
|
|
83
|
+
const spaceToRemove = gap * (itemNumber - 1);
|
|
84
|
+
range = getRange(drawingArea, axisDirection, axis, spaceToRemove);
|
|
85
|
+
}
|
|
86
|
+
const scaleType = axis.scaleType ?? 'linear';
|
|
87
|
+
const domainLimit = axis.domainLimit ?? 'nice';
|
|
88
|
+
const axisExtremums = [axis.min ?? minData, axis.max ?? maxData];
|
|
89
|
+
if (typeof domainLimit === 'function') {
|
|
90
|
+
const {
|
|
91
|
+
min,
|
|
92
|
+
max
|
|
93
|
+
} = domainLimit(minData, maxData);
|
|
94
|
+
axisExtremums[0] = min;
|
|
95
|
+
axisExtremums[1] = max;
|
|
96
|
+
}
|
|
97
|
+
const rawTickNumber = (0, _internals.getTickNumber)((0, _extends2.default)({}, axis, {
|
|
98
|
+
range,
|
|
99
|
+
domain: axisExtremums
|
|
100
|
+
}));
|
|
101
|
+
const tickNumber = (0, _internals.scaleTickNumberByRange)(rawTickNumber, range);
|
|
102
|
+
const scale = (0, _internals.getScale)(scaleType, axisExtremums, range);
|
|
103
|
+
const finalScale = domainLimit === 'nice' ? scale.nice(rawTickNumber) : scale;
|
|
104
|
+
const [minDomain, maxDomain] = finalScale.domain();
|
|
105
|
+
const domain = [axis.min ?? minDomain, axis.max ?? maxDomain];
|
|
106
|
+
completeAxis[axis.id] = (0, _extends2.default)({
|
|
107
|
+
offset: 0,
|
|
108
|
+
height: 0,
|
|
109
|
+
triggerTooltip
|
|
110
|
+
}, axis, {
|
|
111
|
+
data,
|
|
112
|
+
scaleType: scaleType,
|
|
113
|
+
scale: finalScale.domain(domain),
|
|
114
|
+
tickNumber,
|
|
115
|
+
colorScale: axis.colorMap && (0, _internals.getColorScale)(axis.colorMap)
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
return {
|
|
119
|
+
axis: completeAxis,
|
|
120
|
+
axisIds: allAxis.map(({
|
|
121
|
+
id
|
|
122
|
+
}) => id)
|
|
123
|
+
};
|
|
124
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
|
|
4
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
5
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
6
|
+
Object.defineProperty(exports, "__esModule", {
|
|
7
|
+
value: true
|
|
8
|
+
});
|
|
9
|
+
exports.useChartFunnelAxis = void 0;
|
|
10
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
11
|
+
var React = _interopRequireWildcard(require("react"));
|
|
12
|
+
var _warning = require("@mui/x-internals/warning");
|
|
13
|
+
var _internals = require("@mui/x-charts/internals");
|
|
14
|
+
var _useChartFunnelAxisRendering = require("./useChartFunnelAxisRendering.selectors");
|
|
15
|
+
const useChartFunnelAxis = ({
|
|
16
|
+
params,
|
|
17
|
+
store,
|
|
18
|
+
seriesConfig,
|
|
19
|
+
svgRef,
|
|
20
|
+
instance
|
|
21
|
+
}) => {
|
|
22
|
+
const {
|
|
23
|
+
xAxis,
|
|
24
|
+
yAxis,
|
|
25
|
+
dataset,
|
|
26
|
+
gap
|
|
27
|
+
} = params;
|
|
28
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
29
|
+
const ids = [...(xAxis ?? []), ...(yAxis ?? [])].filter(axis => axis.id).map(axis => axis.id);
|
|
30
|
+
const duplicates = new Set(ids.filter((id, index) => ids.indexOf(id) !== index));
|
|
31
|
+
if (duplicates.size > 0) {
|
|
32
|
+
(0, _warning.warnOnce)([`MUI X Charts: The following axis ids are duplicated: ${Array.from(duplicates).join(', ')}.`, `Please make sure that each axis has a unique id.`].join('\n'), 'error');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const drawingArea = (0, _internals.useSelector)(store, _internals.selectorChartDrawingArea);
|
|
36
|
+
const isInteractionEnabled = (0, _internals.useSelector)(store, _internals.selectorChartsInteractionIsInitialized);
|
|
37
|
+
const isFirstRender = React.useRef(true);
|
|
38
|
+
React.useEffect(() => {
|
|
39
|
+
if (isFirstRender.current) {
|
|
40
|
+
isFirstRender.current = false;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
store.update(prev => (0, _extends2.default)({}, prev, {
|
|
44
|
+
funnel: {
|
|
45
|
+
gap: gap ?? 0
|
|
46
|
+
},
|
|
47
|
+
cartesianAxis: (0, _extends2.default)({}, prev.cartesianAxis, {
|
|
48
|
+
x: (0, _internals.defaultizeXAxis)(xAxis, dataset),
|
|
49
|
+
y: (0, _internals.defaultizeYAxis)(yAxis, dataset)
|
|
50
|
+
})
|
|
51
|
+
}));
|
|
52
|
+
}, [seriesConfig, drawingArea, xAxis, yAxis, dataset, store, gap]);
|
|
53
|
+
React.useEffect(() => {
|
|
54
|
+
const element = svgRef.current;
|
|
55
|
+
if (!isInteractionEnabled || element === null || params.disableAxisListener) {
|
|
56
|
+
return () => {};
|
|
57
|
+
}
|
|
58
|
+
const handleOut = () => {
|
|
59
|
+
instance.cleanInteraction?.();
|
|
60
|
+
};
|
|
61
|
+
const handleMove = event => {
|
|
62
|
+
const target = 'targetTouches' in event ? event.targetTouches[0] : event;
|
|
63
|
+
const svgPoint = (0, _internals.getSVGPoint)(element, target);
|
|
64
|
+
if (!instance.isPointInside(svgPoint.x, svgPoint.y, event.target)) {
|
|
65
|
+
instance.cleanInteraction?.();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
instance.setPointerCoordinate?.(svgPoint);
|
|
69
|
+
};
|
|
70
|
+
const handleDown = event => {
|
|
71
|
+
const target = event.currentTarget;
|
|
72
|
+
if (!target) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if ('hasPointerCapture' in target && target.hasPointerCapture(event.pointerId)) {
|
|
76
|
+
target.releasePointerCapture(event.pointerId);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
element.addEventListener('pointerdown', handleDown);
|
|
80
|
+
element.addEventListener('pointermove', handleMove);
|
|
81
|
+
element.addEventListener('pointercancel', handleOut);
|
|
82
|
+
element.addEventListener('pointerleave', handleOut);
|
|
83
|
+
return () => {
|
|
84
|
+
element.removeEventListener('pointerdown', handleDown);
|
|
85
|
+
element.removeEventListener('pointermove', handleMove);
|
|
86
|
+
element.removeEventListener('pointercancel', handleOut);
|
|
87
|
+
element.removeEventListener('pointerleave', handleOut);
|
|
88
|
+
};
|
|
89
|
+
}, [svgRef, instance, params.disableAxisListener, isInteractionEnabled]);
|
|
90
|
+
React.useEffect(() => {
|
|
91
|
+
const element = svgRef.current;
|
|
92
|
+
const onAxisClick = params.onAxisClick;
|
|
93
|
+
if (element === null || !onAxisClick) {
|
|
94
|
+
return () => {};
|
|
95
|
+
}
|
|
96
|
+
const handleMouseClick = event => {
|
|
97
|
+
event.preventDefault();
|
|
98
|
+
const {
|
|
99
|
+
axis: xAxisWithScale,
|
|
100
|
+
axisIds: xAxisIds
|
|
101
|
+
} = (0, _useChartFunnelAxisRendering.selectorChartXAxis)(store.value);
|
|
102
|
+
const {
|
|
103
|
+
axis: yAxisWithScale,
|
|
104
|
+
axisIds: yAxisIds
|
|
105
|
+
} = (0, _useChartFunnelAxisRendering.selectorChartYAxis)(store.value);
|
|
106
|
+
const processedSeries = (0, _internals.selectorChartSeriesProcessed)(store.value);
|
|
107
|
+
const usedXAxis = xAxisIds[0];
|
|
108
|
+
const usedYAxis = yAxisIds[0];
|
|
109
|
+
let dataIndex = null;
|
|
110
|
+
let isXAxis = false;
|
|
111
|
+
const svgPoint = (0, _internals.getSVGPoint)(element, event);
|
|
112
|
+
const xIndex = (0, _internals.getCartesianAxisIndex)(xAxisWithScale[usedXAxis], svgPoint.x);
|
|
113
|
+
isXAxis = xIndex !== -1;
|
|
114
|
+
dataIndex = isXAxis ? xIndex : (0, _internals.getCartesianAxisIndex)(yAxisWithScale[usedYAxis], svgPoint.y);
|
|
115
|
+
const USED_AXIS_ID = isXAxis ? xAxisIds[0] : yAxisIds[0];
|
|
116
|
+
if (dataIndex == null || dataIndex === -1) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// The .data exist because otherwise the dataIndex would be null or -1.
|
|
121
|
+
const axisValue = (isXAxis ? xAxisWithScale : yAxisWithScale)[USED_AXIS_ID].data[dataIndex];
|
|
122
|
+
const seriesValues = {};
|
|
123
|
+
processedSeries.funnel?.seriesOrder.forEach(seriesId => {
|
|
124
|
+
const seriesItem = processedSeries.funnel.series[seriesId];
|
|
125
|
+
const providedXAxisId = seriesItem.xAxisId;
|
|
126
|
+
const providedYAxisId = seriesItem.yAxisId;
|
|
127
|
+
const axisKey = isXAxis ? providedXAxisId : providedYAxisId;
|
|
128
|
+
if (axisKey === undefined || axisKey === USED_AXIS_ID) {
|
|
129
|
+
seriesValues[seriesId] = seriesItem.data[dataIndex].value;
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
onAxisClick(event, {
|
|
133
|
+
dataIndex,
|
|
134
|
+
axisValue,
|
|
135
|
+
seriesValues
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
element.addEventListener('click', handleMouseClick);
|
|
139
|
+
return () => {
|
|
140
|
+
element.removeEventListener('click', handleMouseClick);
|
|
141
|
+
};
|
|
142
|
+
}, [params.onAxisClick, svgRef, store]);
|
|
143
|
+
return {};
|
|
144
|
+
};
|
|
145
|
+
exports.useChartFunnelAxis = useChartFunnelAxis;
|
|
146
|
+
useChartFunnelAxis.params = {
|
|
147
|
+
xAxis: true,
|
|
148
|
+
yAxis: true,
|
|
149
|
+
gap: true,
|
|
150
|
+
dataset: true,
|
|
151
|
+
onAxisClick: true,
|
|
152
|
+
disableAxisListener: true
|
|
153
|
+
};
|
|
154
|
+
useChartFunnelAxis.getDefaultizedParams = ({
|
|
155
|
+
params
|
|
156
|
+
}) => {
|
|
157
|
+
return (0, _extends2.default)({}, params, {
|
|
158
|
+
gap: params.gap ?? 0,
|
|
159
|
+
defaultizedXAxis: (0, _internals.defaultizeXAxis)(params.xAxis, params.dataset),
|
|
160
|
+
defaultizedYAxis: (0, _internals.defaultizeYAxis)(params.yAxis, params.dataset)
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
useChartFunnelAxis.getInitialState = params => {
|
|
164
|
+
return {
|
|
165
|
+
funnel: {
|
|
166
|
+
gap: params.gap ?? 0
|
|
167
|
+
},
|
|
168
|
+
cartesianAxis: {
|
|
169
|
+
x: params.defaultizedXAxis,
|
|
170
|
+
y: params.defaultizedYAxis
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ChartPluginSignature, UseChartCartesianAxisDefaultizedParameters, UseChartCartesianAxisParameters, UseChartCartesianAxisState, UseChartInteractionSignature, UseChartSeriesSignature, ChartsAxisData } from '@mui/x-charts/internals';
|
|
2
|
+
export type UseChartFunnelAxisSignature = ChartPluginSignature<{
|
|
3
|
+
params: Omit<UseChartCartesianAxisParameters, 'onAxisClick'> & {
|
|
4
|
+
/**
|
|
5
|
+
* The gap, in pixels, between funnel sections.
|
|
6
|
+
* @default 0
|
|
7
|
+
*/
|
|
8
|
+
gap?: number;
|
|
9
|
+
/**
|
|
10
|
+
* The function called for onClick events.
|
|
11
|
+
* The second argument contains information about all funnel elements at the current position.
|
|
12
|
+
* @param {MouseEvent} event The mouse event recorded on the `<svg/>` element.
|
|
13
|
+
* @param {null | ChartsAxisData} data The data about the clicked axis and items associated with it.
|
|
14
|
+
*/
|
|
15
|
+
onAxisClick?: (event: MouseEvent, data: null | ChartsAxisData) => void;
|
|
16
|
+
};
|
|
17
|
+
defaultizedParams: UseChartCartesianAxisDefaultizedParameters & {
|
|
18
|
+
gap: number;
|
|
19
|
+
};
|
|
20
|
+
state: Pick<UseChartCartesianAxisState, 'cartesianAxis'> & {
|
|
21
|
+
funnel: {
|
|
22
|
+
gap: number;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
dependencies: [UseChartSeriesSignature<'funnel'>];
|
|
26
|
+
optionalDependencies: [UseChartInteractionSignature];
|
|
27
|
+
}>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ChartState } from '@mui/x-charts/internals';
|
|
2
|
+
import { UseChartFunnelAxisSignature } from "./useChartFunnelAxis.types.js";
|
|
3
|
+
export declare const selectorFunnel: (state: ChartState<[], [UseChartFunnelAxisSignature]>) => {
|
|
4
|
+
gap: number;
|
|
5
|
+
} | undefined;
|
|
6
|
+
export declare const selectorFunnelGap: import("reselect").Selector<import("@mui/x-charts/internals/plugins/corePlugins/useChartId/useChartId.types").UseChartIdState & import("@mui/x-charts/internals/plugins/corePlugins/useChartDimensions/useChartDimensions.types").UseChartDimensionsState & import("@mui/x-charts/internals/plugins/corePlugins/useChartSeries/useChartSeries.types").UseChartSeriesState<keyof import("@mui/x-charts/internals").ChartsSeriesConfig> & import("@mui/x-charts/internals/plugins/corePlugins/useChartAnimation/useChartAnimation.types").UseChartAnimationState & Partial<Pick<import("@mui/x-charts/internals").UseChartCartesianAxisState, "cartesianAxis"> & {
|
|
7
|
+
funnel: {
|
|
8
|
+
gap: number;
|
|
9
|
+
};
|
|
10
|
+
}> & {
|
|
11
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
12
|
+
} & {
|
|
13
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
14
|
+
}, number, []>;
|
|
15
|
+
export declare const selectorChartXAxis: import("reselect").Selector<import("@mui/x-charts/internals/plugins/corePlugins/useChartId/useChartId.types").UseChartIdState & import("@mui/x-charts/internals/plugins/corePlugins/useChartDimensions/useChartDimensions.types").UseChartDimensionsState & import("@mui/x-charts/internals/plugins/corePlugins/useChartSeries/useChartSeries.types").UseChartSeriesState<keyof import("@mui/x-charts/internals").ChartsSeriesConfig> & import("@mui/x-charts/internals/plugins/corePlugins/useChartAnimation/useChartAnimation.types").UseChartAnimationState & Partial<import("@mui/x-charts/internals").UseChartCartesianAxisState> & {
|
|
16
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
17
|
+
} & Partial<{}> & {
|
|
18
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
19
|
+
} & {
|
|
20
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
21
|
+
} & {
|
|
22
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
23
|
+
} & {
|
|
24
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
25
|
+
} & {
|
|
26
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
27
|
+
} & {
|
|
28
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
29
|
+
} & Partial<Pick<import("@mui/x-charts/internals").UseChartCartesianAxisState, "cartesianAxis"> & {
|
|
30
|
+
funnel: {
|
|
31
|
+
gap: number;
|
|
32
|
+
};
|
|
33
|
+
}> & {
|
|
34
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
35
|
+
}, import("./computeAxisValue.js").ComputeResult<import("@mui/x-charts").ChartsXAxisProps>, []>;
|
|
36
|
+
export declare const selectorChartYAxis: import("reselect").Selector<import("@mui/x-charts/internals/plugins/corePlugins/useChartId/useChartId.types").UseChartIdState & import("@mui/x-charts/internals/plugins/corePlugins/useChartDimensions/useChartDimensions.types").UseChartDimensionsState & import("@mui/x-charts/internals/plugins/corePlugins/useChartSeries/useChartSeries.types").UseChartSeriesState<keyof import("@mui/x-charts/internals").ChartsSeriesConfig> & import("@mui/x-charts/internals/plugins/corePlugins/useChartAnimation/useChartAnimation.types").UseChartAnimationState & Partial<import("@mui/x-charts/internals").UseChartCartesianAxisState> & {
|
|
37
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
38
|
+
} & Partial<{}> & {
|
|
39
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
40
|
+
} & {
|
|
41
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
42
|
+
} & {
|
|
43
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
44
|
+
} & {
|
|
45
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
46
|
+
} & {
|
|
47
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
48
|
+
} & {
|
|
49
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
50
|
+
} & Partial<Pick<import("@mui/x-charts/internals").UseChartCartesianAxisState, "cartesianAxis"> & {
|
|
51
|
+
funnel: {
|
|
52
|
+
gap: number;
|
|
53
|
+
};
|
|
54
|
+
}> & {
|
|
55
|
+
cacheKey: import("@mui/x-charts/internals").ChartStateCacheKey;
|
|
56
|
+
}, import("./computeAxisValue.js").ComputeResult<import("@mui/x-charts").ChartsYAxisProps>, []>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.selectorFunnelGap = exports.selectorFunnel = exports.selectorChartYAxis = exports.selectorChartXAxis = void 0;
|
|
7
|
+
var _internals = require("@mui/x-charts/internals");
|
|
8
|
+
var _computeAxisValue = require("./computeAxisValue");
|
|
9
|
+
const selectorFunnel = state => state.funnel;
|
|
10
|
+
exports.selectorFunnel = selectorFunnel;
|
|
11
|
+
const selectorFunnelGap = exports.selectorFunnelGap = (0, _internals.createSelector)([selectorFunnel], funnel => funnel?.gap ?? 0);
|
|
12
|
+
const selectorChartXAxis = exports.selectorChartXAxis = (0, _internals.createSelector)([_internals.selectorChartRawXAxis, _internals.selectorChartDrawingArea, _internals.selectorChartSeriesProcessed, _internals.selectorChartSeriesConfig, selectorFunnelGap], (axis, drawingArea, formattedSeries, seriesConfig, gap) => (0, _computeAxisValue.computeAxisValue)({
|
|
13
|
+
drawingArea,
|
|
14
|
+
formattedSeries,
|
|
15
|
+
axis,
|
|
16
|
+
seriesConfig,
|
|
17
|
+
axisDirection: 'x',
|
|
18
|
+
gap
|
|
19
|
+
}));
|
|
20
|
+
const selectorChartYAxis = exports.selectorChartYAxis = (0, _internals.createSelector)([_internals.selectorChartRawYAxis, _internals.selectorChartDrawingArea, _internals.selectorChartSeriesProcessed, _internals.selectorChartSeriesConfig, selectorFunnelGap], (axis, drawingArea, formattedSeries, seriesConfig, gap) => (0, _computeAxisValue.computeAxisValue)({
|
|
21
|
+
drawingArea,
|
|
22
|
+
formattedSeries,
|
|
23
|
+
axis,
|
|
24
|
+
seriesConfig,
|
|
25
|
+
axisDirection: 'y',
|
|
26
|
+
gap
|
|
27
|
+
}));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FunnelLabelOptions } from "./funnel.types.js";
|
|
2
|
+
import { Point } from "./curves/index.js";
|
|
2
3
|
/**
|
|
3
4
|
* It tries to keep the label inside the bounds of the section based on the position.
|
|
4
5
|
*
|
|
@@ -23,19 +24,11 @@ export declare const alignLabel: ({
|
|
|
23
24
|
export declare const positionLabel: ({
|
|
24
25
|
position,
|
|
25
26
|
offset,
|
|
26
|
-
xPosition,
|
|
27
|
-
yPosition,
|
|
28
27
|
isHorizontal,
|
|
29
|
-
values
|
|
30
|
-
dataIndex,
|
|
31
|
-
baseScaleData
|
|
28
|
+
values
|
|
32
29
|
}: Omit<FunnelLabelOptions, "textAnchor" | "dominantBaseline"> & {
|
|
33
|
-
xPosition: (value: number, bandIndex: number, stackOffset?: number, useBand?: boolean) => number | undefined;
|
|
34
|
-
yPosition: (value: number, bandIndex: number, stackOffset?: number, useBand?: boolean) => number | undefined;
|
|
35
30
|
isHorizontal: boolean;
|
|
36
|
-
values: readonly
|
|
37
|
-
dataIndex: number;
|
|
38
|
-
baseScaleData: readonly number[];
|
|
31
|
+
values: readonly Point[];
|
|
39
32
|
}) => {
|
|
40
33
|
x: number;
|
|
41
34
|
y: number;
|