@mui/x-charts 6.0.0-alpha.2 → 6.0.0-alpha.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/BarChart/BarChart.d.ts +1 -4
- package/BarChart/BarChart.js +5 -3
- package/BarChart/BarPlot.js +42 -8
- package/CHANGELOG.md +232 -114
- package/ChartContainer/index.d.ts +3 -1
- package/ChartContainer/index.js +10 -6
- package/ChartsAxisHighlight/ChartsAxisHighlight.js +3 -2
- package/LineChart/LineChart.d.ts +1 -4
- package/LineChart/LineChart.js +5 -3
- package/ResponsiveChartContainer/index.d.ts +1 -1
- package/ResponsiveChartContainer/index.js +11 -9
- package/ScatterChart/Scatter.d.ts +1 -1
- package/ScatterChart/ScatterChart.d.ts +1 -4
- package/ScatterChart/ScatterChart.js +5 -3
- package/context/CartesianContextProvider.js +31 -20
- package/context/SeriesContextProvider.js +2 -2
- package/esm/BarChart/BarChart.js +3 -2
- package/esm/BarChart/BarPlot.js +44 -8
- package/esm/ChartContainer/index.js +7 -5
- package/esm/ChartsAxisHighlight/ChartsAxisHighlight.js +3 -2
- package/esm/LineChart/LineChart.js +3 -2
- package/esm/ResponsiveChartContainer/index.js +9 -8
- package/esm/ScatterChart/ScatterChart.js +3 -2
- package/esm/context/CartesianContextProvider.js +31 -18
- package/esm/context/SeriesContextProvider.js +2 -2
- package/esm/hooks/index.js +2 -0
- package/esm/hooks/useAxisEvents.js +12 -7
- package/esm/hooks/useDrawingArea.js +16 -0
- package/esm/hooks/useScale.js +19 -21
- package/esm/hooks/useTicks.js +26 -13
- package/esm/index.js +1 -0
- package/esm/internals/getScale.js +17 -0
- package/esm/internals/isBandScale.js +3 -0
- package/esm/models/axis.js +6 -1
- package/hooks/index.d.ts +2 -0
- package/hooks/index.js +27 -0
- package/hooks/package.json +6 -0
- package/hooks/useAxisEvents.js +14 -9
- package/hooks/useDrawingArea.d.ts +6 -0
- package/hooks/useDrawingArea.js +24 -0
- package/hooks/useScale.d.ts +3 -6
- package/hooks/useScale.js +24 -24
- package/hooks/useTicks.d.ts +1 -1
- package/hooks/useTicks.js +19 -9
- package/index.d.ts +1 -0
- package/index.js +12 -1
- package/internals/getScale.d.ts +2 -0
- package/internals/getScale.js +23 -0
- package/internals/isBandScale.d.ts +3 -0
- package/internals/isBandScale.js +9 -0
- package/legacy/BarChart/BarChart.js +3 -2
- package/legacy/BarChart/BarPlot.js +44 -10
- package/legacy/ChartContainer/index.js +7 -5
- package/legacy/ChartsAxisHighlight/ChartsAxisHighlight.js +3 -2
- package/legacy/LineChart/LineChart.js +3 -2
- package/legacy/ResponsiveChartContainer/index.js +9 -8
- package/legacy/ScatterChart/ScatterChart.js +3 -2
- package/legacy/context/CartesianContextProvider.js +31 -18
- package/legacy/context/SeriesContextProvider.js +2 -2
- package/legacy/hooks/index.js +2 -0
- package/legacy/hooks/useAxisEvents.js +12 -7
- package/legacy/hooks/useDrawingArea.js +17 -0
- package/legacy/hooks/useScale.js +17 -21
- package/legacy/hooks/useTicks.js +26 -13
- package/legacy/index.js +2 -1
- package/legacy/internals/getScale.js +17 -0
- package/legacy/internals/isBandScale.js +3 -0
- package/legacy/models/axis.js +6 -1
- package/models/axis.d.ts +25 -12
- package/models/axis.js +9 -1
- package/models/seriesType/pie.d.ts +2 -2
- package/modern/BarChart/BarChart.js +3 -2
- package/modern/BarChart/BarPlot.js +44 -8
- package/modern/ChartContainer/index.js +7 -5
- package/modern/ChartsAxisHighlight/ChartsAxisHighlight.js +3 -2
- package/modern/LineChart/LineChart.js +3 -2
- package/modern/ResponsiveChartContainer/index.js +9 -8
- package/modern/ScatterChart/ScatterChart.js +3 -2
- package/modern/context/CartesianContextProvider.js +29 -18
- package/modern/context/SeriesContextProvider.js +2 -2
- package/modern/hooks/index.js +2 -0
- package/modern/hooks/useAxisEvents.js +12 -7
- package/modern/hooks/useDrawingArea.js +16 -0
- package/modern/hooks/useScale.js +19 -21
- package/modern/hooks/useTicks.js +18 -8
- package/modern/index.js +2 -1
- package/modern/internals/getScale.js +17 -0
- package/modern/internals/isBandScale.js +3 -0
- package/modern/models/axis.js +6 -1
- package/package.json +1 -1
package/models/axis.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ScaleBand, ScaleLogarithmic, ScalePower, ScaleTime, ScaleLinear, ScalePoint } from 'd3-scale';
|
|
2
2
|
import { ChartsAxisClasses } from '../ChartsAxis/axisClasses';
|
|
3
3
|
import type { TickParams } from '../hooks/useTicks';
|
|
4
|
+
export type D3Scale = ScaleBand<any> | ScaleLogarithmic<any, any> | ScalePoint<any> | ScalePower<any, any> | ScaleTime<any, any> | ScaleLinear<any, any>;
|
|
5
|
+
export type D3ContinuouseScale = ScaleLogarithmic<any, any> | ScalePower<any, any> | ScaleTime<any, any> | ScaleLinear<any, any>;
|
|
4
6
|
export interface ChartsAxisProps {
|
|
5
7
|
/**
|
|
6
8
|
* Id of the axis to render.
|
|
@@ -68,51 +70,62 @@ interface AxisScaleConfig {
|
|
|
68
70
|
band: {
|
|
69
71
|
scaleType: 'band';
|
|
70
72
|
scale: ScaleBand<any>;
|
|
71
|
-
|
|
73
|
+
/**
|
|
74
|
+
* The ratio between the space allocated for padding between two categories and the category width.
|
|
75
|
+
* 0 means no gap, and 1 no data.
|
|
76
|
+
* @default 0.1
|
|
77
|
+
*/
|
|
78
|
+
categoryGapRatio: number;
|
|
79
|
+
/**
|
|
80
|
+
* The ratio between the width of a bar, and the gap between two bars.
|
|
81
|
+
* 0 means no gap, and 1 no bar.
|
|
82
|
+
* @default 0
|
|
83
|
+
*/
|
|
84
|
+
barGapRatio: number;
|
|
72
85
|
};
|
|
73
86
|
point: {
|
|
74
87
|
scaleType: 'point';
|
|
75
88
|
scale: ScalePoint<any>;
|
|
76
|
-
ticksNumber: number;
|
|
77
89
|
};
|
|
78
90
|
log: {
|
|
79
91
|
scaleType: 'log';
|
|
80
92
|
scale: ScaleLogarithmic<any, any>;
|
|
81
|
-
ticksNumber: number;
|
|
82
93
|
};
|
|
83
94
|
pow: {
|
|
84
95
|
scaleType: 'pow';
|
|
85
96
|
scale: ScalePower<any, any>;
|
|
86
|
-
ticksNumber: number;
|
|
87
97
|
};
|
|
88
98
|
sqrt: {
|
|
89
99
|
scaleType: 'sqrt';
|
|
90
100
|
scale: ScalePower<any, any>;
|
|
91
|
-
ticksNumber: number;
|
|
92
101
|
};
|
|
93
102
|
time: {
|
|
94
103
|
scaleType: 'time';
|
|
95
104
|
scale: ScaleTime<any, any>;
|
|
96
|
-
ticksNumber: number;
|
|
97
105
|
};
|
|
98
106
|
utc: {
|
|
99
107
|
scaleType: 'utc';
|
|
100
108
|
scale: ScaleTime<any, any>;
|
|
101
|
-
ticksNumber: number;
|
|
102
109
|
};
|
|
103
110
|
linear: {
|
|
104
111
|
scaleType: 'linear';
|
|
105
112
|
scale: ScaleLinear<any, any>;
|
|
106
|
-
ticksNumber: number;
|
|
107
113
|
};
|
|
108
114
|
}
|
|
109
|
-
export type AxisConfig<S = ScaleName, V = any> = {
|
|
115
|
+
export type AxisConfig<S extends ScaleName = ScaleName, V = any> = {
|
|
110
116
|
id: string;
|
|
111
|
-
scaleType?: S;
|
|
112
117
|
min?: number;
|
|
113
118
|
max?: number;
|
|
114
119
|
data?: V[];
|
|
115
120
|
valueFormatter?: (value: V) => string;
|
|
116
|
-
} & Partial<ChartsXAxisProps | ChartsYAxisProps> & TickParams;
|
|
117
|
-
export type AxisDefaultized<S extends ScaleName = ScaleName, V = any> = Omit<AxisConfig<S, V>, 'scaleType'> & AxisScaleConfig[S]
|
|
121
|
+
} & Partial<ChartsXAxisProps | ChartsYAxisProps> & Partial<Omit<AxisScaleConfig[S], 'scale'>> & TickParams;
|
|
122
|
+
export type AxisDefaultized<S extends ScaleName = ScaleName, V = any> = Omit<AxisConfig<S, V>, 'scaleType'> & AxisScaleConfig[S] & {
|
|
123
|
+
ticksNumber: number;
|
|
124
|
+
};
|
|
125
|
+
export declare function isBandScaleConfig(scaleConfig: AxisConfig<ScaleName>): scaleConfig is AxisConfig<'band'> & {
|
|
126
|
+
scaleType: 'band';
|
|
127
|
+
};
|
|
128
|
+
export declare function isPointScaleConfig(scaleConfig: AxisConfig<ScaleName>): scaleConfig is AxisConfig<'point'> & {
|
|
129
|
+
scaleType: 'point';
|
|
130
|
+
};
|
|
118
131
|
export {};
|
package/models/axis.js
CHANGED
|
@@ -2,4 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
|
-
});
|
|
5
|
+
});
|
|
6
|
+
exports.isBandScaleConfig = isBandScaleConfig;
|
|
7
|
+
exports.isPointScaleConfig = isPointScaleConfig;
|
|
8
|
+
function isBandScaleConfig(scaleConfig) {
|
|
9
|
+
return scaleConfig.scaleType === 'band';
|
|
10
|
+
}
|
|
11
|
+
function isPointScaleConfig(scaleConfig) {
|
|
12
|
+
return scaleConfig.scaleType === 'point';
|
|
13
|
+
}
|
|
@@ -70,7 +70,7 @@ export interface PieSeriesType<Tdata = PieValueType> extends CommonSeriesType<Td
|
|
|
70
70
|
highlighted?: {
|
|
71
71
|
/**
|
|
72
72
|
* Value added to the default `outerRadius`.
|
|
73
|
-
* Can be negative.
|
|
73
|
+
* Can be negative. It is ignored if you provide a `highlighted.outerRadius` value.
|
|
74
74
|
*/
|
|
75
75
|
additionalRadius?: number;
|
|
76
76
|
innerRadius?: number;
|
|
@@ -83,7 +83,7 @@ export interface PieSeriesType<Tdata = PieValueType> extends CommonSeriesType<Td
|
|
|
83
83
|
faded?: {
|
|
84
84
|
/**
|
|
85
85
|
* Value added to the default `outerRadius`.
|
|
86
|
-
* Can be negative.
|
|
86
|
+
* Can be negative. It is ignored if you provide a `faded.outerRadius` value.
|
|
87
87
|
*/
|
|
88
88
|
additionalRadius?: number;
|
|
89
89
|
innerRadius?: number;
|
|
@@ -12,7 +12,7 @@ import { ChartsAxisHighlight } from '../ChartsAxisHighlight';
|
|
|
12
12
|
import { ChartsClipPath } from '../ChartsClipPath';
|
|
13
13
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
14
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
|
-
function BarChart(props) {
|
|
15
|
+
const BarChart = /*#__PURE__*/React.forwardRef(function BarChart(props, ref) {
|
|
16
16
|
const {
|
|
17
17
|
xAxis,
|
|
18
18
|
yAxis,
|
|
@@ -34,6 +34,7 @@ function BarChart(props) {
|
|
|
34
34
|
const id = useId();
|
|
35
35
|
const clipPathId = `${id}-clip-path`;
|
|
36
36
|
return /*#__PURE__*/_jsxs(ResponsiveChartContainer, {
|
|
37
|
+
ref: ref,
|
|
37
38
|
series: series.map(s => _extends({
|
|
38
39
|
type: 'bar'
|
|
39
40
|
}, s)),
|
|
@@ -65,7 +66,7 @@ function BarChart(props) {
|
|
|
65
66
|
id: clipPathId
|
|
66
67
|
}), children]
|
|
67
68
|
});
|
|
68
|
-
}
|
|
69
|
+
});
|
|
69
70
|
process.env.NODE_ENV !== "production" ? BarChart.propTypes = {
|
|
70
71
|
// ----------------------------- Warning --------------------------------
|
|
71
72
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
@@ -1,9 +1,37 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { SeriesContext } from '../context/SeriesContextProvider';
|
|
3
3
|
import { CartesianContext } from '../context/CartesianContextProvider';
|
|
4
|
-
import { isBandScale } from '../hooks/useScale';
|
|
5
4
|
import { BarElement } from './BarElement';
|
|
5
|
+
import { isBandScaleConfig } from '../models/axis';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Solution of the equations
|
|
9
|
+
* W = barWidth * N + offset * (N-1)
|
|
10
|
+
* offset / (offset + barWidth) = r
|
|
11
|
+
* @param bandWidth The width available to place bars.
|
|
12
|
+
* @param numberOfGroups The number of bars to place in that space.
|
|
13
|
+
* @param gapRatio The ratio of the gap between bars over the bar width.
|
|
14
|
+
* @returns The bar width and the offset between bars.
|
|
15
|
+
*/
|
|
6
16
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
17
|
+
function getBandSize({
|
|
18
|
+
bandWidth: W,
|
|
19
|
+
numberOfGroups: N,
|
|
20
|
+
gapRatio: r
|
|
21
|
+
}) {
|
|
22
|
+
if (r === 0) {
|
|
23
|
+
return {
|
|
24
|
+
barWidth: W / N,
|
|
25
|
+
offset: 0
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const barWidth = W / (N + (N - 1) * r);
|
|
29
|
+
const offset = r * barWidth;
|
|
30
|
+
return {
|
|
31
|
+
barWidth,
|
|
32
|
+
offset
|
|
33
|
+
};
|
|
34
|
+
}
|
|
7
35
|
export function BarPlot() {
|
|
8
36
|
const seriesData = React.useContext(SeriesContext).bar;
|
|
9
37
|
const axisData = React.useContext(CartesianContext);
|
|
@@ -29,19 +57,27 @@ export function BarPlot() {
|
|
|
29
57
|
return groupIds.flatMap(seriesId => {
|
|
30
58
|
const xAxisKey = series[seriesId].xAxisKey ?? defaultXAxisId;
|
|
31
59
|
const yAxisKey = series[seriesId].yAxisKey ?? defaultYAxisId;
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
if (!
|
|
35
|
-
throw new Error(`Axis with id "${xAxisKey}" shoud be of type "band" to display the bar series ${
|
|
60
|
+
const xAxisConfig = xAxis[xAxisKey];
|
|
61
|
+
const yAxisConfig = yAxis[yAxisKey];
|
|
62
|
+
if (!isBandScaleConfig(xAxisConfig)) {
|
|
63
|
+
throw new Error(`Axis with id "${xAxisKey}" shoud be of type "band" to display the bar series of id "${seriesId}"`);
|
|
36
64
|
}
|
|
37
65
|
if (xAxis[xAxisKey].data === undefined) {
|
|
38
66
|
throw new Error(`Axis with id "${xAxisKey}" shoud have data property`);
|
|
39
67
|
}
|
|
68
|
+
const xScale = xAxisConfig.scale;
|
|
69
|
+
const yScale = yAxisConfig.scale;
|
|
40
70
|
|
|
41
71
|
// Currently assuming all bars are vertical
|
|
42
72
|
const bandWidth = xScale.bandwidth();
|
|
43
|
-
const
|
|
44
|
-
|
|
73
|
+
const {
|
|
74
|
+
barWidth,
|
|
75
|
+
offset
|
|
76
|
+
} = getBandSize({
|
|
77
|
+
bandWidth,
|
|
78
|
+
numberOfGroups: stackingGroups.length,
|
|
79
|
+
gapRatio: xAxisConfig.barGapRatio
|
|
80
|
+
});
|
|
45
81
|
|
|
46
82
|
// @ts-ignore TODO: fix when adding a correct API for customisation
|
|
47
83
|
const {
|
|
@@ -54,7 +90,7 @@ export function BarPlot() {
|
|
|
54
90
|
return /*#__PURE__*/_jsx(BarElement, {
|
|
55
91
|
id: seriesId,
|
|
56
92
|
dataIndex: dataIndex,
|
|
57
|
-
x: xScale(xAxis[xAxisKey].data?.[dataIndex]) + groupIndex * barWidth + offset,
|
|
93
|
+
x: xScale(xAxis[xAxisKey].data?.[dataIndex]) + groupIndex * (barWidth + offset),
|
|
58
94
|
y: yScale(value),
|
|
59
95
|
height: yScale(baseline) - yScale(value),
|
|
60
96
|
width: barWidth,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import useForkRef from '@mui/utils/useForkRef';
|
|
2
3
|
import { DrawingProvider } from '../context/DrawingProvider';
|
|
3
4
|
import { SeriesContextProvider } from '../context/SeriesContextProvider';
|
|
4
5
|
import { InteractionProvider } from '../context/InteractionProvider';
|
|
@@ -6,7 +7,7 @@ import { ChartsSurface } from '../ChartsSurface';
|
|
|
6
7
|
import { CartesianContextProvider } from '../context/CartesianContextProvider';
|
|
7
8
|
import { HighlightProvider } from '../context/HighlightProvider';
|
|
8
9
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
-
export function ChartContainer(props) {
|
|
10
|
+
export const ChartContainer = /*#__PURE__*/React.forwardRef(function ChartContainer(props, ref) {
|
|
10
11
|
const {
|
|
11
12
|
width,
|
|
12
13
|
height,
|
|
@@ -21,12 +22,13 @@ export function ChartContainer(props) {
|
|
|
21
22
|
disableAxisListener,
|
|
22
23
|
children
|
|
23
24
|
} = props;
|
|
24
|
-
const
|
|
25
|
+
const svgRef = React.useRef(null);
|
|
26
|
+
const handleRef = useForkRef(ref, svgRef);
|
|
25
27
|
return /*#__PURE__*/_jsx(DrawingProvider, {
|
|
26
28
|
width: width,
|
|
27
29
|
height: height,
|
|
28
30
|
margin: margin,
|
|
29
|
-
svgRef:
|
|
31
|
+
svgRef: svgRef,
|
|
30
32
|
children: /*#__PURE__*/_jsx(SeriesContextProvider, {
|
|
31
33
|
series: series,
|
|
32
34
|
colors: colors,
|
|
@@ -38,7 +40,7 @@ export function ChartContainer(props) {
|
|
|
38
40
|
children: /*#__PURE__*/_jsx(ChartsSurface, {
|
|
39
41
|
width: width,
|
|
40
42
|
height: height,
|
|
41
|
-
ref:
|
|
43
|
+
ref: handleRef,
|
|
42
44
|
sx: sx,
|
|
43
45
|
title: title,
|
|
44
46
|
desc: desc,
|
|
@@ -50,4 +52,4 @@ export function ChartContainer(props) {
|
|
|
50
52
|
})
|
|
51
53
|
})
|
|
52
54
|
});
|
|
53
|
-
}
|
|
55
|
+
});
|
|
@@ -2,7 +2,8 @@ import * as React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { InteractionContext } from '../context/InteractionProvider';
|
|
4
4
|
import { CartesianContext } from '../context/CartesianContextProvider';
|
|
5
|
-
import { getValueToPositionMapper
|
|
5
|
+
import { getValueToPositionMapper } from '../hooks/useScale';
|
|
6
|
+
import { isBandScale } from '../internals/isBandScale';
|
|
6
7
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
8
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
9
|
function ChartsAxisHighlight(props) {
|
|
@@ -26,7 +27,7 @@ function ChartsAxisHighlight(props) {
|
|
|
26
27
|
const getXPosition = getValueToPositionMapper(xScale);
|
|
27
28
|
return /*#__PURE__*/_jsxs(React.Fragment, {
|
|
28
29
|
children: [xAxisHighlight === 'band' && axis.x !== null && isBandScale(xScale) && /*#__PURE__*/_jsx("path", {
|
|
29
|
-
d: `M ${xScale(axis.x.value)
|
|
30
|
+
d: `M ${xScale(axis.x.value) - (xScale.step() - xScale.bandwidth()) / 2} ${yScale.range()[0]} l ${xScale.step()} 0 l 0 ${yScale.range()[1] - yScale.range()[0]} l ${-xScale.step()} 0 Z`,
|
|
30
31
|
fill: "gray",
|
|
31
32
|
fillOpacity: 0.1,
|
|
32
33
|
style: {
|
|
@@ -14,7 +14,7 @@ import { ChartsAxisHighlight } from '../ChartsAxisHighlight';
|
|
|
14
14
|
import { ChartsClipPath } from '../ChartsClipPath';
|
|
15
15
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
16
16
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
17
|
-
function LineChart(props) {
|
|
17
|
+
const LineChart = /*#__PURE__*/React.forwardRef(function LineChart(props, ref) {
|
|
18
18
|
const {
|
|
19
19
|
xAxis,
|
|
20
20
|
yAxis,
|
|
@@ -38,6 +38,7 @@ function LineChart(props) {
|
|
|
38
38
|
const id = useId();
|
|
39
39
|
const clipPathId = `${id}-clip-path`;
|
|
40
40
|
return /*#__PURE__*/_jsxs(ResponsiveChartContainer, {
|
|
41
|
+
ref: ref,
|
|
41
42
|
series: series.map(s => _extends({
|
|
42
43
|
type: 'line'
|
|
43
44
|
}, s)),
|
|
@@ -67,7 +68,7 @@ function LineChart(props) {
|
|
|
67
68
|
id: clipPathId
|
|
68
69
|
}), children]
|
|
69
70
|
});
|
|
70
|
-
}
|
|
71
|
+
});
|
|
71
72
|
process.env.NODE_ENV !== "production" ? LineChart.propTypes = {
|
|
72
73
|
// ----------------------------- Warning --------------------------------
|
|
73
74
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
@@ -90,22 +90,23 @@ const ResizableContainer = styled('div', {
|
|
|
90
90
|
height: '100%'
|
|
91
91
|
}
|
|
92
92
|
}));
|
|
93
|
-
export function ResponsiveChartContainer(props) {
|
|
93
|
+
export const ResponsiveChartContainer = /*#__PURE__*/React.forwardRef(function ResponsiveChartContainer(props, ref) {
|
|
94
94
|
const {
|
|
95
|
-
width:
|
|
96
|
-
height:
|
|
95
|
+
width: inWidth,
|
|
96
|
+
height: inHeight
|
|
97
97
|
} = props,
|
|
98
98
|
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
99
|
-
const [containerRef, width, height] = useChartDimensions(
|
|
99
|
+
const [containerRef, width, height] = useChartDimensions(inWidth, inHeight);
|
|
100
100
|
return /*#__PURE__*/_jsx(ResizableContainer, {
|
|
101
101
|
ref: containerRef,
|
|
102
102
|
ownerState: {
|
|
103
|
-
width:
|
|
104
|
-
height:
|
|
103
|
+
width: inWidth,
|
|
104
|
+
height: inHeight
|
|
105
105
|
},
|
|
106
106
|
children: /*#__PURE__*/_jsx(ChartContainer, _extends({}, other, {
|
|
107
107
|
width: width,
|
|
108
|
-
height: height
|
|
108
|
+
height: height,
|
|
109
|
+
ref: ref
|
|
109
110
|
}))
|
|
110
111
|
});
|
|
111
|
-
}
|
|
112
|
+
});
|
|
@@ -9,7 +9,7 @@ import { ChartsLegend } from '../ChartsLegend';
|
|
|
9
9
|
import { ChartsAxisHighlight } from '../ChartsAxisHighlight';
|
|
10
10
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
11
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
12
|
-
function ScatterChart(props) {
|
|
12
|
+
const ScatterChart = /*#__PURE__*/React.forwardRef(function ScatterChart(props, ref) {
|
|
13
13
|
const {
|
|
14
14
|
xAxis,
|
|
15
15
|
yAxis,
|
|
@@ -29,6 +29,7 @@ function ScatterChart(props) {
|
|
|
29
29
|
children
|
|
30
30
|
} = props;
|
|
31
31
|
return /*#__PURE__*/_jsxs(ResponsiveChartContainer, {
|
|
32
|
+
ref: ref,
|
|
32
33
|
series: series.map(s => _extends({
|
|
33
34
|
type: 'scatter'
|
|
34
35
|
}, s)),
|
|
@@ -51,7 +52,7 @@ function ScatterChart(props) {
|
|
|
51
52
|
trigger: "item"
|
|
52
53
|
}, tooltip)), children]
|
|
53
54
|
});
|
|
54
|
-
}
|
|
55
|
+
});
|
|
55
56
|
process.env.NODE_ENV !== "production" ? ScatterChart.propTypes = {
|
|
56
57
|
// ----------------------------- Warning --------------------------------
|
|
57
58
|
// | These PropTypes are generated from the TypeScript type definitions |
|
|
@@ -5,12 +5,15 @@ import PropTypes from 'prop-types';
|
|
|
5
5
|
import { getExtremumX as getBarExtremumX, getExtremumY as getBarExtremumY } from '../BarChart/extremums';
|
|
6
6
|
import { getExtremumX as getScatterExtremumX, getExtremumY as getScatterExtremumY } from '../ScatterChart/extremums';
|
|
7
7
|
import { getExtremumX as getLineExtremumX, getExtremumY as getLineExtremumY } from '../LineChart/extremums';
|
|
8
|
-
import {
|
|
8
|
+
import { isBandScaleConfig, isPointScaleConfig } from '../models/axis';
|
|
9
|
+
import { getScale } from '../internals/getScale';
|
|
9
10
|
import { DrawingContext } from './DrawingProvider';
|
|
10
11
|
import { SeriesContext } from './SeriesContextProvider';
|
|
11
12
|
import { DEFAULT_X_AXIS_KEY, DEFAULT_Y_AXIS_KEY } from '../constants';
|
|
12
13
|
import { getTicksNumber } from '../hooks/useTicks';
|
|
13
14
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
15
|
+
const DEFAULT_CATEGORY_GAP_RATIO = 0.1;
|
|
16
|
+
|
|
14
17
|
// TODO: those might be better placed in a distinct file
|
|
15
18
|
const xExtremumGetters = {
|
|
16
19
|
bar: getBarExtremumX,
|
|
@@ -71,24 +74,28 @@ function CartesianContextProvider({
|
|
|
71
74
|
allXAxis.forEach((axis, axisIndex) => {
|
|
72
75
|
const isDefaultAxis = axisIndex === 0;
|
|
73
76
|
const [minData, maxData] = getAxisExtremum(axis, xExtremumGetters, isDefaultAxis);
|
|
74
|
-
const scaleType = axis.scaleType ?? 'linear';
|
|
75
77
|
const range = [drawingArea.left, drawingArea.left + drawingArea.width];
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
if (isBandScaleConfig(axis)) {
|
|
79
|
+
const categoryGapRatio = axis.categoryGapRatio ?? DEFAULT_CATEGORY_GAP_RATIO;
|
|
80
|
+
completedXAxis[axis.id] = _extends({
|
|
81
|
+
categoryGapRatio,
|
|
82
|
+
barGapRatio: 0
|
|
83
|
+
}, axis, {
|
|
84
|
+
scale: scaleBand(axis.data, range).paddingInner(categoryGapRatio).paddingOuter(categoryGapRatio / 2),
|
|
80
85
|
ticksNumber: axis.data.length
|
|
81
86
|
});
|
|
82
|
-
return;
|
|
83
87
|
}
|
|
84
|
-
if (
|
|
88
|
+
if (isPointScaleConfig(axis)) {
|
|
85
89
|
completedXAxis[axis.id] = _extends({}, axis, {
|
|
86
|
-
scaleType,
|
|
87
90
|
scale: scalePoint(axis.data, range),
|
|
88
91
|
ticksNumber: axis.data.length
|
|
89
92
|
});
|
|
93
|
+
}
|
|
94
|
+
if (axis.scaleType === 'band' || axis.scaleType === 'point') {
|
|
95
|
+
// Could be merged with the two previous "if conditions" but then TS does not get that `axis.scaleType` can't be `band` or `point`.
|
|
90
96
|
return;
|
|
91
97
|
}
|
|
98
|
+
const scaleType = axis.scaleType ?? 'linear';
|
|
92
99
|
const extremums = [axis.min ?? minData, axis.max ?? maxData];
|
|
93
100
|
const ticksNumber = getTicksNumber(_extends({}, axis, {
|
|
94
101
|
range
|
|
@@ -115,23 +122,27 @@ function CartesianContextProvider({
|
|
|
115
122
|
const isDefaultAxis = axisIndex === 0;
|
|
116
123
|
const [minData, maxData] = getAxisExtremum(axis, yExtremumGetters, isDefaultAxis);
|
|
117
124
|
const range = [drawingArea.top + drawingArea.height, drawingArea.top];
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
125
|
+
if (isBandScaleConfig(axis)) {
|
|
126
|
+
const categoryGapRatio = axis.categoryGapRatio ?? DEFAULT_CATEGORY_GAP_RATIO;
|
|
127
|
+
completedXAxis[axis.id] = _extends({
|
|
128
|
+
categoryGapRatio,
|
|
129
|
+
barGapRatio: 0
|
|
130
|
+
}, axis, {
|
|
131
|
+
scale: scaleBand(axis.data, range).paddingInner(categoryGapRatio).paddingOuter(categoryGapRatio / 2),
|
|
123
132
|
ticksNumber: axis.data.length
|
|
124
133
|
});
|
|
125
|
-
return;
|
|
126
134
|
}
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
scaleType,
|
|
135
|
+
if (isPointScaleConfig(axis)) {
|
|
136
|
+
completedXAxis[axis.id] = _extends({}, axis, {
|
|
130
137
|
scale: scalePoint(axis.data, range),
|
|
131
138
|
ticksNumber: axis.data.length
|
|
132
139
|
});
|
|
140
|
+
}
|
|
141
|
+
if (axis.scaleType === 'band' || axis.scaleType === 'point') {
|
|
142
|
+
// Could be merged with the two previous "if conditions" but then TS does not get that `axis.scaleType` can't be `band` or `point`.
|
|
133
143
|
return;
|
|
134
144
|
}
|
|
145
|
+
const scaleType = axis.scaleType ?? 'linear';
|
|
135
146
|
const extremums = [axis.min ?? minData, axis.max ?? maxData];
|
|
136
147
|
const ticksNumber = getTicksNumber(_extends({}, axis, {
|
|
137
148
|
range
|
|
@@ -16,8 +16,8 @@ const seriesTypeFormatter = {
|
|
|
16
16
|
pie: pieSeriesFormatter
|
|
17
17
|
};
|
|
18
18
|
/**
|
|
19
|
-
* This methods is the interface between what the
|
|
20
|
-
* To simplify the components behaviors, it groups series by type, such that LinePlots props are not updated if
|
|
19
|
+
* This methods is the interface between what the developer is providing and what components receives
|
|
20
|
+
* To simplify the components behaviors, it groups series by type, such that LinePlots props are not updated if some line data are modified
|
|
21
21
|
* It also add defaultized values such as the ids, colors
|
|
22
22
|
* @param series The array of series provided by devs
|
|
23
23
|
* @param colors The color palette used to defaultize series colors
|
|
@@ -2,7 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
import { InteractionContext } from '../context/InteractionProvider';
|
|
3
3
|
import { CartesianContext } from '../context/CartesianContextProvider';
|
|
4
4
|
import { SVGContext, DrawingContext } from '../context/DrawingProvider';
|
|
5
|
-
import { isBandScale } from '
|
|
5
|
+
import { isBandScale } from '../internals/isBandScale';
|
|
6
6
|
export const useAxisEvents = disableAxisListener => {
|
|
7
7
|
const svgRef = React.useContext(SVGContext);
|
|
8
8
|
const {
|
|
@@ -109,12 +109,17 @@ export const useAxisEvents = disableAxisListener => {
|
|
|
109
109
|
});
|
|
110
110
|
};
|
|
111
111
|
const handleMouseMove = event => {
|
|
112
|
+
// Get mouse coordinate in global SVG space
|
|
113
|
+
const pt = svgRef.current.createSVGPoint();
|
|
114
|
+
pt.x = event.clientX;
|
|
115
|
+
pt.y = event.clientY;
|
|
116
|
+
const svgPt = pt.matrixTransform(svgRef.current.getScreenCTM().inverse());
|
|
112
117
|
mousePosition.current = {
|
|
113
|
-
x:
|
|
114
|
-
y:
|
|
118
|
+
x: svgPt.x,
|
|
119
|
+
y: svgPt.y
|
|
115
120
|
};
|
|
116
|
-
const outsideX =
|
|
117
|
-
const outsideY =
|
|
121
|
+
const outsideX = svgPt.x < left || svgPt.x > left + width;
|
|
122
|
+
const outsideY = svgPt.y < top || svgPt.y > top + height;
|
|
118
123
|
if (outsideX || outsideY) {
|
|
119
124
|
dispatch({
|
|
120
125
|
type: 'updateAxis',
|
|
@@ -125,8 +130,8 @@ export const useAxisEvents = disableAxisListener => {
|
|
|
125
130
|
});
|
|
126
131
|
return;
|
|
127
132
|
}
|
|
128
|
-
const newStateX = getUpdateX(
|
|
129
|
-
const newStateY = getUpdateY(
|
|
133
|
+
const newStateX = getUpdateX(svgPt.x);
|
|
134
|
+
const newStateY = getUpdateY(svgPt.y);
|
|
130
135
|
dispatch({
|
|
131
136
|
type: 'updateAxis',
|
|
132
137
|
data: {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { DrawingContext } from '../context/DrawingProvider';
|
|
3
|
+
export function useDrawingArea() {
|
|
4
|
+
const {
|
|
5
|
+
left,
|
|
6
|
+
top,
|
|
7
|
+
width,
|
|
8
|
+
height
|
|
9
|
+
} = React.useContext(DrawingContext);
|
|
10
|
+
return React.useMemo(() => ({
|
|
11
|
+
left,
|
|
12
|
+
top,
|
|
13
|
+
width,
|
|
14
|
+
height
|
|
15
|
+
}), [height, left, top, width]);
|
|
16
|
+
}
|
package/modern/hooks/useScale.js
CHANGED
|
@@ -1,24 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
case 'log':
|
|
5
|
-
return scaleLog(domain, range);
|
|
6
|
-
case 'pow':
|
|
7
|
-
return scalePow(domain, range);
|
|
8
|
-
case 'sqrt':
|
|
9
|
-
return scaleSqrt(domain, range);
|
|
10
|
-
case 'time':
|
|
11
|
-
return scaleTime(domain, range);
|
|
12
|
-
case 'utc':
|
|
13
|
-
return scaleUtc(domain, range);
|
|
14
|
-
default:
|
|
15
|
-
return scaleLinear(domain, range);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
export function isBandScale(scale) {
|
|
19
|
-
return scale.bandwidth !== undefined;
|
|
20
|
-
}
|
|
21
|
-
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { CartesianContext } from '../context/CartesianContextProvider';
|
|
3
|
+
import { isBandScale } from '../internals/isBandScale';
|
|
22
4
|
/**
|
|
23
5
|
* For a given scale return a function that map value to their position.
|
|
24
6
|
* Usefull when dealing with specific scale such as band.
|
|
@@ -30,4 +12,20 @@ export function getValueToPositionMapper(scale) {
|
|
|
30
12
|
return value => scale(value) + scale.bandwidth() / 2;
|
|
31
13
|
}
|
|
32
14
|
return value => scale(value);
|
|
15
|
+
}
|
|
16
|
+
export function useXScale(identifier) {
|
|
17
|
+
const {
|
|
18
|
+
xAxis,
|
|
19
|
+
xAxisIds
|
|
20
|
+
} = React.useContext(CartesianContext);
|
|
21
|
+
const id = typeof identifier === 'string' ? identifier : xAxisIds[identifier ?? 0];
|
|
22
|
+
return xAxis[id].scale;
|
|
23
|
+
}
|
|
24
|
+
export function useYScale(identifier) {
|
|
25
|
+
const {
|
|
26
|
+
yAxis,
|
|
27
|
+
yAxisIds
|
|
28
|
+
} = React.useContext(CartesianContext);
|
|
29
|
+
const id = typeof identifier === 'string' ? identifier : yAxisIds[identifier ?? 0];
|
|
30
|
+
return yAxis[id].scale;
|
|
33
31
|
}
|
package/modern/hooks/useTicks.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { isBandScale } from '
|
|
2
|
+
import { isBandScale } from '../internals/isBandScale';
|
|
3
3
|
export function getTicksNumber(params) {
|
|
4
4
|
const {
|
|
5
5
|
maxTicks = 999,
|
|
@@ -20,15 +20,25 @@ function useTicks(options) {
|
|
|
20
20
|
// band scale
|
|
21
21
|
if (isBandScale(scale)) {
|
|
22
22
|
const domain = scale.domain();
|
|
23
|
-
|
|
23
|
+
if (scale.bandwidth() > 0) {
|
|
24
|
+
// scale type = 'band'
|
|
25
|
+
return [...domain.map((value, index) => ({
|
|
26
|
+
formattedValue: valueFormatter?.(value) ?? value,
|
|
27
|
+
offset: index === 0 ? scale.range()[0] : scale(value) - (scale.step() - scale.bandwidth()) / 2,
|
|
28
|
+
labelOffset: scale.step() / 2
|
|
29
|
+
})), {
|
|
30
|
+
formattedValue: undefined,
|
|
31
|
+
offset: scale.range()[1],
|
|
32
|
+
labelOffset: 0
|
|
33
|
+
}];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// scale type = 'point'
|
|
37
|
+
return domain.map(value => ({
|
|
24
38
|
formattedValue: valueFormatter?.(value) ?? value,
|
|
25
|
-
offset: scale(value)
|
|
26
|
-
labelOffset: scale.bandwidth() / 2
|
|
27
|
-
})), ...(scale.bandwidth() > 0 ? [{
|
|
28
|
-
formattedValue: undefined,
|
|
29
|
-
offset: scale.range()[1],
|
|
39
|
+
offset: scale(value),
|
|
30
40
|
labelOffset: 0
|
|
31
|
-
}
|
|
41
|
+
}));
|
|
32
42
|
}
|
|
33
43
|
return scale.ticks(ticksNumber).map(value => ({
|
|
34
44
|
formattedValue: valueFormatter?.(value) ?? scale.tickFormat(ticksNumber)(value),
|
package/modern/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @mui/x-charts v6.0.0-alpha.
|
|
2
|
+
* @mui/x-charts v6.0.0-alpha.3
|
|
3
3
|
*
|
|
4
4
|
* @license MIT
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export * from './constants';
|
|
9
9
|
export * from './context';
|
|
10
|
+
export * from './hooks';
|
|
10
11
|
export * from './colorPalettes';
|
|
11
12
|
export * from './models';
|
|
12
13
|
export * from './ChartsClipPath';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { scaleLog, scalePow, scaleSqrt, scaleTime, scaleUtc, scaleLinear } from 'd3-scale';
|
|
2
|
+
export function getScale(scaleType, domain, range) {
|
|
3
|
+
switch (scaleType) {
|
|
4
|
+
case 'log':
|
|
5
|
+
return scaleLog(domain, range);
|
|
6
|
+
case 'pow':
|
|
7
|
+
return scalePow(domain, range);
|
|
8
|
+
case 'sqrt':
|
|
9
|
+
return scaleSqrt(domain, range);
|
|
10
|
+
case 'time':
|
|
11
|
+
return scaleTime(domain, range);
|
|
12
|
+
case 'utc':
|
|
13
|
+
return scaleUtc(domain, range);
|
|
14
|
+
default:
|
|
15
|
+
return scaleLinear(domain, range);
|
|
16
|
+
}
|
|
17
|
+
}
|