@mui/x-charts 8.8.0 → 8.9.2
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 +3 -2
- package/BarChart/BarChart.js +95 -2
- package/BarChart/BarClipPath.d.ts +17 -12
- package/BarChart/BarClipPath.js +70 -57
- package/BarChart/BarPlot.js +4 -0
- package/BarChart/barClasses.d.ts +1 -1
- package/BarChart/seriesConfig/extremums.js +2 -3
- package/BarChart/seriesConfig/seriesProcessor.js +5 -3
- package/BarChart/useBarChartProps.d.ts +1 -1
- package/BarChart/useBarPlotData.js +32 -5
- package/CHANGELOG.md +225 -24
- package/ChartContainer/ChartContainer.js +141 -0
- package/ChartsLabel/ChartsLabelMark.d.ts +2 -1
- package/ChartsLabel/index.d.ts +1 -0
- package/ChartsLabel/index.js +18 -0
- package/ChartsLegend/chartsLegendClasses.d.ts +1 -1
- package/ChartsLegend/piecewiseColorLegendClasses.d.ts +1 -1
- package/{internals/components/ChartsWrapper → ChartsWrapper}/ChartsWrapper.d.ts +13 -4
- package/{internals/components/ChartsWrapper → ChartsWrapper}/ChartsWrapper.js +33 -7
- package/LineChart/LineChart.d.ts +3 -2
- package/LineChart/LineChart.js +95 -2
- package/LineChart/seriesConfig/extremums.js +2 -3
- package/LineChart/useLineChartProps.d.ts +1 -1
- package/PieChart/PieArcLabelPlot.js +3 -0
- package/PieChart/PieArcPlot.js +3 -0
- package/PieChart/PieChart.d.ts +3 -2
- package/PieChart/PieChart.js +2 -2
- package/PieChart/pieClasses.d.ts +1 -1
- package/RadarChart/RadarAxisHighlight/RadarAxisHighlight.js +3 -5
- package/RadarChart/RadarAxisHighlight/useRadarAxisHighlight.d.ts +2 -13
- package/RadarChart/RadarAxisHighlight/useRadarAxisHighlight.js +8 -45
- package/RadarChart/RadarChart.d.ts +3 -2
- package/RadarChart/RadarChart.js +24 -3
- package/RadarChart/RadarDataProvider/RadarDataProvider.d.ts +3 -2
- package/RadarChart/RadarMetricLabels/useRadarMetricData.js +4 -2
- package/RadarChart/RadarSeriesPlot/RadarSeriesArea.js +19 -3
- package/RadarChart/RadarSeriesPlot/RadarSeriesMarks.js +20 -4
- package/RadarChart/RadarSeriesPlot/RadarSeriesPlot.js +38 -4
- package/RadarChart/RadarSeriesPlot/RadarSeriesPlot.types.d.ts +32 -3
- package/RadarChart/RadarSeriesPlot/useRadarRotationIndex.d.ts +8 -0
- package/RadarChart/RadarSeriesPlot/useRadarRotationIndex.js +38 -0
- package/RadarChart/RadarSeriesPlot/useRadarSeriesData.d.ts +2 -2
- package/RadarChart/index.d.ts +1 -1
- package/RadarChart/useRadarChartProps.d.ts +4 -1
- package/RadarChart/useRadarChartProps.js +15 -3
- package/ScatterChart/ScatterChart.d.ts +3 -2
- package/ScatterChart/ScatterChart.js +95 -2
- package/ScatterChart/seriesConfig/extremums.js +50 -23
- package/ScatterChart/useScatterChartProps.d.ts +1 -1
- package/SparkLineChart/SparkLineChart.js +93 -0
- package/esm/BarChart/BarChart.d.ts +3 -2
- package/esm/BarChart/BarChart.js +95 -2
- package/esm/BarChart/BarClipPath.d.ts +17 -12
- package/esm/BarChart/BarClipPath.js +69 -55
- package/esm/BarChart/BarPlot.js +4 -0
- package/esm/BarChart/barClasses.d.ts +1 -1
- package/esm/BarChart/seriesConfig/extremums.js +2 -3
- package/esm/BarChart/seriesConfig/seriesProcessor.js +5 -3
- package/esm/BarChart/useBarChartProps.d.ts +1 -1
- package/esm/BarChart/useBarPlotData.js +32 -5
- package/esm/ChartContainer/ChartContainer.js +141 -0
- package/esm/ChartsLabel/ChartsLabelMark.d.ts +2 -1
- package/esm/ChartsLabel/index.d.ts +1 -0
- package/esm/ChartsLabel/index.js +1 -0
- package/esm/ChartsLegend/chartsLegendClasses.d.ts +1 -1
- package/esm/ChartsLegend/piecewiseColorLegendClasses.d.ts +1 -1
- package/esm/{internals/components/ChartsWrapper → ChartsWrapper}/ChartsWrapper.d.ts +13 -4
- package/esm/{internals/components/ChartsWrapper → ChartsWrapper}/ChartsWrapper.js +31 -6
- package/esm/LineChart/LineChart.d.ts +3 -2
- package/esm/LineChart/LineChart.js +95 -2
- package/esm/LineChart/seriesConfig/extremums.js +2 -3
- package/esm/LineChart/useLineChartProps.d.ts +1 -1
- package/esm/PieChart/PieArcLabelPlot.js +3 -0
- package/esm/PieChart/PieArcPlot.js +3 -0
- package/esm/PieChart/PieChart.d.ts +3 -2
- package/esm/PieChart/PieChart.js +2 -2
- package/esm/PieChart/pieClasses.d.ts +1 -1
- package/esm/RadarChart/RadarAxisHighlight/RadarAxisHighlight.js +3 -5
- package/esm/RadarChart/RadarAxisHighlight/useRadarAxisHighlight.d.ts +2 -13
- package/esm/RadarChart/RadarAxisHighlight/useRadarAxisHighlight.js +8 -45
- package/esm/RadarChart/RadarChart.d.ts +3 -2
- package/esm/RadarChart/RadarChart.js +24 -3
- package/esm/RadarChart/RadarDataProvider/RadarDataProvider.d.ts +3 -2
- package/esm/RadarChart/RadarMetricLabels/useRadarMetricData.js +4 -2
- package/esm/RadarChart/RadarSeriesPlot/RadarSeriesArea.js +19 -3
- package/esm/RadarChart/RadarSeriesPlot/RadarSeriesMarks.js +20 -4
- package/esm/RadarChart/RadarSeriesPlot/RadarSeriesPlot.js +38 -4
- package/esm/RadarChart/RadarSeriesPlot/RadarSeriesPlot.types.d.ts +32 -3
- package/esm/RadarChart/RadarSeriesPlot/useRadarRotationIndex.d.ts +8 -0
- package/esm/RadarChart/RadarSeriesPlot/useRadarRotationIndex.js +32 -0
- package/esm/RadarChart/RadarSeriesPlot/useRadarSeriesData.d.ts +2 -2
- package/esm/RadarChart/index.d.ts +1 -1
- package/esm/RadarChart/useRadarChartProps.d.ts +4 -1
- package/esm/RadarChart/useRadarChartProps.js +15 -3
- package/esm/ScatterChart/ScatterChart.d.ts +3 -2
- package/esm/ScatterChart/ScatterChart.js +95 -2
- package/esm/ScatterChart/seriesConfig/extremums.js +50 -23
- package/esm/ScatterChart/useScatterChartProps.d.ts +1 -1
- package/esm/SparkLineChart/SparkLineChart.js +93 -0
- package/esm/hooks/useTicks.d.ts +6 -1
- package/esm/hooks/useTicks.js +94 -58
- package/esm/index.d.ts +2 -1
- package/esm/index.js +6 -2
- package/esm/internals/findMinMax.d.ts +1 -0
- package/esm/internals/findMinMax.js +13 -0
- package/esm/internals/getScale.js +3 -0
- package/esm/internals/index.d.ts +1 -1
- package/esm/internals/index.js +1 -1
- package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/computeAxisValue.js +4 -1
- package/esm/internals/plugins/featurePlugins/useChartHighlight/createIsFaded.d.ts +1 -1
- package/esm/internals/plugins/featurePlugins/useChartHighlight/createIsFaded.js +19 -11
- package/esm/internals/plugins/featurePlugins/useChartHighlight/createIsHighlighted.d.ts +1 -1
- package/esm/internals/plugins/featurePlugins/useChartHighlight/createIsHighlighted.js +19 -11
- package/esm/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.selectors.js +10 -4
- package/esm/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.js +4 -4
- package/esm/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.js +44 -1
- package/esm/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.types.d.ts +8 -1
- package/esm/internals/plugins/featurePlugins/useChartVoronoi/useChartVoronoi.js +17 -12
- package/esm/internals/symlogScale.d.ts +2 -0
- package/esm/internals/symlogScale.js +94 -0
- package/esm/models/axis.d.ts +47 -5
- package/esm/models/axis.js +3 -0
- package/esm/models/seriesType/bar.d.ts +11 -1
- package/esm/models/seriesType/common.d.ts +9 -3
- package/esm/models/seriesType/line.d.ts +3 -1
- package/esm/models/seriesType/scatter.d.ts +4 -1
- package/esm/tests/web-components.js +49 -0
- package/hooks/useTicks.d.ts +6 -1
- package/hooks/useTicks.js +95 -58
- package/index.d.ts +2 -1
- package/index.js +13 -1
- package/internals/findMinMax.d.ts +1 -0
- package/internals/findMinMax.js +19 -0
- package/internals/getScale.js +3 -0
- package/internals/index.d.ts +1 -1
- package/internals/index.js +12 -12
- package/internals/plugins/featurePlugins/useChartCartesianAxis/computeAxisValue.js +3 -0
- package/internals/plugins/featurePlugins/useChartHighlight/createIsFaded.d.ts +1 -1
- package/internals/plugins/featurePlugins/useChartHighlight/createIsFaded.js +20 -13
- package/internals/plugins/featurePlugins/useChartHighlight/createIsHighlighted.d.ts +1 -1
- package/internals/plugins/featurePlugins/useChartHighlight/createIsHighlighted.js +20 -13
- package/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.selectors.js +10 -4
- package/internals/plugins/featurePlugins/useChartInteraction/useChartInteraction.js +4 -4
- package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.js +44 -1
- package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.types.d.ts +8 -1
- package/internals/plugins/featurePlugins/useChartVoronoi/useChartVoronoi.js +17 -12
- package/internals/symlogScale.d.ts +2 -0
- package/internals/symlogScale.js +100 -0
- package/models/axis.d.ts +47 -5
- package/models/axis.js +4 -0
- package/models/seriesType/bar.d.ts +11 -1
- package/models/seriesType/common.d.ts +9 -3
- package/models/seriesType/line.d.ts +3 -1
- package/models/seriesType/scatter.d.ts +4 -1
- package/package.json +6 -7
- package/tests/web-components.js +55 -0
- package/BarChart/getRadius.d.ts +0 -20
- package/BarChart/getRadius.js +0 -37
- package/esm/BarChart/getRadius.d.ts +0 -20
- package/esm/BarChart/getRadius.js +0 -30
- /package/{esm/internals/components/ChartsWrapper → ChartsWrapper}/index.d.ts +0 -0
- /package/{internals/components/ChartsWrapper → ChartsWrapper}/index.js +0 -0
- /package/{internals/components → esm}/ChartsWrapper/index.d.ts +0 -0
- /package/esm/{internals/components/ChartsWrapper → ChartsWrapper}/index.js +0 -0
|
@@ -4,7 +4,7 @@ import { fastObjectShallowCompare } from '@mui/x-internals/fastObjectShallowComp
|
|
|
4
4
|
export const useChartInteraction = ({
|
|
5
5
|
store
|
|
6
6
|
}) => {
|
|
7
|
-
const cleanInteraction = useEventCallback(()
|
|
7
|
+
const cleanInteraction = useEventCallback(function cleanInteraction() {
|
|
8
8
|
store.update(prev => {
|
|
9
9
|
return _extends({}, prev, {
|
|
10
10
|
interaction: {
|
|
@@ -14,7 +14,7 @@ export const useChartInteraction = ({
|
|
|
14
14
|
});
|
|
15
15
|
});
|
|
16
16
|
});
|
|
17
|
-
const removeItemInteraction = useEventCallback(itemToRemove
|
|
17
|
+
const removeItemInteraction = useEventCallback(function removeItemInteraction(itemToRemove) {
|
|
18
18
|
store.update(prev => {
|
|
19
19
|
const prevItem = prev.interaction.item;
|
|
20
20
|
if (!itemToRemove) {
|
|
@@ -36,7 +36,7 @@ export const useChartInteraction = ({
|
|
|
36
36
|
});
|
|
37
37
|
});
|
|
38
38
|
});
|
|
39
|
-
const setItemInteraction = useEventCallback(newItem
|
|
39
|
+
const setItemInteraction = useEventCallback(function setItemInteraction(newItem) {
|
|
40
40
|
store.update(prev => {
|
|
41
41
|
if (fastObjectShallowCompare(prev.interaction.item, newItem)) {
|
|
42
42
|
return prev;
|
|
@@ -48,7 +48,7 @@ export const useChartInteraction = ({
|
|
|
48
48
|
});
|
|
49
49
|
});
|
|
50
50
|
});
|
|
51
|
-
const setPointerCoordinate = useEventCallback(coordinate
|
|
51
|
+
const setPointerCoordinate = useEventCallback(function setPointerCoordinate(coordinate) {
|
|
52
52
|
store.update(prev => _extends({}, prev, {
|
|
53
53
|
interaction: _extends({}, prev.interaction, {
|
|
54
54
|
pointer: coordinate
|
|
@@ -10,6 +10,8 @@ import { selectorChartsInteractionIsInitialized } from "../useChartInteraction/i
|
|
|
10
10
|
import { selectorChartPolarCenter, selectorChartRadiusAxis, selectorChartRotationAxis } from "./useChartPolarAxis.selectors.js";
|
|
11
11
|
import { getSVGPoint } from "../../../getSVGPoint.js";
|
|
12
12
|
import { generatePolar2svg, generateSvg2polar, generateSvg2rotation } from "./coordinateTransformation.js";
|
|
13
|
+
import { getAxisIndex } from "./getAxisIndex.js";
|
|
14
|
+
import { selectorChartSeriesProcessed } from "../../corePlugins/useChartSeries/index.js";
|
|
13
15
|
export const useChartPolarAxis = ({
|
|
14
16
|
params,
|
|
15
17
|
store,
|
|
@@ -30,6 +32,7 @@ export const useChartPolarAxis = ({
|
|
|
30
32
|
}
|
|
31
33
|
}
|
|
32
34
|
const drawingArea = useSelector(store, selectorChartDrawingArea);
|
|
35
|
+
const processedSeries = useSelector(store, selectorChartSeriesProcessed);
|
|
33
36
|
const center = useSelector(store, selectorChartPolarCenter);
|
|
34
37
|
const isInteractionEnabled = useSelector(store, selectorChartsInteractionIsInitialized);
|
|
35
38
|
const {
|
|
@@ -156,6 +159,45 @@ export const useChartPolarAxis = ({
|
|
|
156
159
|
pressEndHandler.cleanup();
|
|
157
160
|
};
|
|
158
161
|
}, [svgRef, store, center, radiusAxisWithScale, usedRadiusAxisId, rotationAxisWithScale, usedRotationAxisId, instance, params.disableAxisListener, isInteractionEnabled, svg2rotation]);
|
|
162
|
+
React.useEffect(() => {
|
|
163
|
+
const element = svgRef.current;
|
|
164
|
+
const onAxisClick = params.onAxisClick;
|
|
165
|
+
if (element === null || !onAxisClick) {
|
|
166
|
+
return () => {};
|
|
167
|
+
}
|
|
168
|
+
const axisClickHandler = instance.addInteractionListener('tap', event => {
|
|
169
|
+
let dataIndex = null;
|
|
170
|
+
let isRotationAxis = false;
|
|
171
|
+
const svgPoint = getSVGPoint(element, event.detail.srcEvent);
|
|
172
|
+
const rotation = generateSvg2rotation(center)(svgPoint.x, svgPoint.y);
|
|
173
|
+
const rotationIndex = getAxisIndex(rotationAxisWithScale[usedRotationAxisId], rotation);
|
|
174
|
+
isRotationAxis = rotationIndex !== -1;
|
|
175
|
+
dataIndex = isRotationAxis ? rotationIndex : null; // radius index is not yet implemented.
|
|
176
|
+
|
|
177
|
+
const USED_AXIS_ID = isRotationAxis ? usedRotationAxisId : usedRadiusAxisId;
|
|
178
|
+
if (dataIndex == null || dataIndex === -1) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// The .data exist because otherwise the dataIndex would be null or -1.
|
|
183
|
+
const axisValue = (isRotationAxis ? rotationAxisWithScale : radiusAxisWithScale)[USED_AXIS_ID].data[dataIndex];
|
|
184
|
+
const seriesValues = {};
|
|
185
|
+
Object.keys(processedSeries).filter(seriesType => seriesType === 'radar').forEach(seriesType => {
|
|
186
|
+
processedSeries[seriesType]?.seriesOrder.forEach(seriesId => {
|
|
187
|
+
const seriesItem = processedSeries[seriesType].series[seriesId];
|
|
188
|
+
seriesValues[seriesId] = seriesItem.data[dataIndex];
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
onAxisClick(event.detail.srcEvent, {
|
|
192
|
+
dataIndex,
|
|
193
|
+
axisValue,
|
|
194
|
+
seriesValues
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
return () => {
|
|
198
|
+
axisClickHandler.cleanup();
|
|
199
|
+
};
|
|
200
|
+
}, [center, instance, params.onAxisClick, processedSeries, radiusAxisWithScale, rotationAxisWithScale, svgRef, usedRadiusAxisId, usedRotationAxisId]);
|
|
159
201
|
return {
|
|
160
202
|
instance: {
|
|
161
203
|
svg2polar,
|
|
@@ -168,7 +210,8 @@ useChartPolarAxis.params = {
|
|
|
168
210
|
rotationAxis: true,
|
|
169
211
|
radiusAxis: true,
|
|
170
212
|
dataset: true,
|
|
171
|
-
disableAxisListener: true
|
|
213
|
+
disableAxisListener: true,
|
|
214
|
+
onAxisClick: true
|
|
172
215
|
};
|
|
173
216
|
useChartPolarAxis.getInitialState = params => ({
|
|
174
217
|
polarAxis: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ChartPluginSignature } from "../../models/index.js";
|
|
2
2
|
import { ChartSeriesType, DatasetType } from "../../../../models/seriesType/config.js";
|
|
3
|
-
import { ScaleName, AxisConfig, ChartsRotationAxisProps, ChartsRadiusAxisProps, RadiusAxis, RotationAxis } from "../../../../models/axis.js";
|
|
3
|
+
import { ScaleName, AxisConfig, ChartsRotationAxisProps, ChartsRadiusAxisProps, RadiusAxis, RotationAxis, ChartsAxisData } from "../../../../models/axis.js";
|
|
4
4
|
import { UseChartSeriesSignature } from "../../corePlugins/useChartSeries/index.js";
|
|
5
5
|
import { UseChartInteractionSignature } from "../useChartInteraction/index.js";
|
|
6
6
|
export interface UseChartPolarAxisInstance {
|
|
@@ -49,6 +49,13 @@ export interface UseChartPolarAxisParameters {
|
|
|
49
49
|
* @default false
|
|
50
50
|
*/
|
|
51
51
|
disableAxisListener?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* The function called for onClick events.
|
|
54
|
+
* The second argument contains information about all line/bar elements at the current mouse position.
|
|
55
|
+
* @param {MouseEvent} event The mouse event recorded on the `<svg/>` element.
|
|
56
|
+
* @param {null | ChartsAxisData} data The data about the clicked axis and items associated with it.
|
|
57
|
+
*/
|
|
58
|
+
onAxisClick?: (event: MouseEvent, data: null | ChartsAxisData) => void;
|
|
52
59
|
}
|
|
53
60
|
export type UseChartPolarAxisDefaultizedParameters = UseChartPolarAxisParameters & {};
|
|
54
61
|
export interface UseChartPolarAxisState {
|
|
@@ -67,22 +67,24 @@ export const useChartVoronoi = ({
|
|
|
67
67
|
const yScale = yAxis[yAxisId ?? defaultYAxisId].scale;
|
|
68
68
|
const getXPosition = getValueToPositionMapper(xScale);
|
|
69
69
|
const getYPosition = getValueToPositionMapper(yScale);
|
|
70
|
-
const seriesPoints =
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
const seriesPoints = [];
|
|
71
|
+
const seriesIndexes = [];
|
|
72
|
+
for (let dataIndex = 0; dataIndex < data.length; dataIndex += 1) {
|
|
73
|
+
const {
|
|
74
|
+
x,
|
|
75
|
+
y
|
|
76
|
+
} = data[dataIndex];
|
|
74
77
|
const pointX = getXPosition(x);
|
|
75
78
|
const pointY = getYPosition(y);
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return [-drawingArea.width, -drawingArea.height];
|
|
79
|
+
if (instance.isPointInside(pointX, pointY)) {
|
|
80
|
+
seriesPoints.push(pointX);
|
|
81
|
+
seriesPoints.push(pointY);
|
|
82
|
+
seriesIndexes.push(dataIndex);
|
|
81
83
|
}
|
|
82
|
-
|
|
83
|
-
});
|
|
84
|
+
}
|
|
84
85
|
voronoiRef.current[seriesId] = {
|
|
85
86
|
seriesId,
|
|
87
|
+
seriesIndexes,
|
|
86
88
|
startIndex: points.length,
|
|
87
89
|
endIndex: points.length + seriesPoints.length
|
|
88
90
|
};
|
|
@@ -117,7 +119,10 @@ export const useChartVoronoi = ({
|
|
|
117
119
|
if (closestSeries === undefined) {
|
|
118
120
|
return 'no-point-found';
|
|
119
121
|
}
|
|
120
|
-
|
|
122
|
+
|
|
123
|
+
// The point index in the series with id=closestSeries.seriesId.
|
|
124
|
+
const seriesPointIndex = (2 * closestPointIndex - voronoiRef.current[closestSeries.seriesId].startIndex) / 2;
|
|
125
|
+
const dataIndex = voronoiRef.current[closestSeries.seriesId].seriesIndexes[seriesPointIndex];
|
|
121
126
|
if (voronoiMaxRadius !== undefined) {
|
|
122
127
|
const pointX = delauneyRef.current.points[2 * closestPointIndex];
|
|
123
128
|
const pointY = delauneyRef.current.points[2 * closestPointIndex + 1];
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { scaleSymlog as originalScaleSymlog, scaleLog, scaleLinear } from '@mui/x-charts-vendor/d3-scale';
|
|
2
|
+
export function scaleSymlog(_domain, _range) {
|
|
3
|
+
const scale = originalScaleSymlog(_domain, _range);
|
|
4
|
+
const originalTicks = scale.ticks;
|
|
5
|
+
const {
|
|
6
|
+
negativeScale,
|
|
7
|
+
linearScale,
|
|
8
|
+
positiveScale
|
|
9
|
+
} = generateScales(scale);
|
|
10
|
+
|
|
11
|
+
// Workaround for https://github.com/d3/d3-scale/issues/162
|
|
12
|
+
scale.ticks = count => {
|
|
13
|
+
const ticks = originalTicks(count);
|
|
14
|
+
const constant = scale.constant();
|
|
15
|
+
let negativeLogTickCount = 0;
|
|
16
|
+
let linearTickCount = 0;
|
|
17
|
+
let positiveLogTickCount = 0;
|
|
18
|
+
ticks.forEach(tick => {
|
|
19
|
+
if (tick > -constant && tick < constant) {
|
|
20
|
+
linearTickCount += 1;
|
|
21
|
+
}
|
|
22
|
+
if (tick <= -constant) {
|
|
23
|
+
negativeLogTickCount += 1;
|
|
24
|
+
}
|
|
25
|
+
if (tick >= constant) {
|
|
26
|
+
positiveLogTickCount += 1;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
const finalTicks = [];
|
|
30
|
+
if (negativeLogTickCount > 0) {
|
|
31
|
+
finalTicks.push(...negativeScale.ticks(negativeLogTickCount));
|
|
32
|
+
}
|
|
33
|
+
if (linearTickCount > 0) {
|
|
34
|
+
const linearTicks = linearScale.ticks(linearTickCount);
|
|
35
|
+
if (finalTicks.at(-1) === linearTicks[0]) {
|
|
36
|
+
finalTicks.push(...linearTicks.slice(1));
|
|
37
|
+
} else {
|
|
38
|
+
finalTicks.push(...linearTicks);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (positiveLogTickCount > 0) {
|
|
42
|
+
const positiveTicks = positiveScale.ticks(positiveLogTickCount);
|
|
43
|
+
if (finalTicks.at(-1) === positiveTicks[0]) {
|
|
44
|
+
finalTicks.push(...positiveTicks.slice(1));
|
|
45
|
+
} else {
|
|
46
|
+
finalTicks.push(...positiveTicks);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return finalTicks;
|
|
50
|
+
};
|
|
51
|
+
scale.tickFormat = (count = 10, specifier) => {
|
|
52
|
+
// Calculates the proportion of the domain that each scale occupies, and use that ratio to determine the number of ticks for each scale.
|
|
53
|
+
const constant = scale.constant();
|
|
54
|
+
const [start, end] = scale.domain();
|
|
55
|
+
const extent = end - start;
|
|
56
|
+
const negativeScaleDomain = negativeScale.domain();
|
|
57
|
+
const negativeScaleExtent = negativeScaleDomain[1] - negativeScaleDomain[0];
|
|
58
|
+
const negativeScaleRatio = extent === 0 ? 0 : negativeScaleExtent / extent;
|
|
59
|
+
const negativeScaleTickCount = negativeScaleRatio * count;
|
|
60
|
+
const linearScaleDomain = linearScale.domain();
|
|
61
|
+
const linearScaleExtent = linearScaleDomain[1] - linearScaleDomain[0];
|
|
62
|
+
const linearScaleRatio = extent === 0 ? 0 : linearScaleExtent / extent;
|
|
63
|
+
const linearScaleTickCount = linearScaleRatio * count;
|
|
64
|
+
const positiveScaleDomain = positiveScale.domain();
|
|
65
|
+
const positiveScaleExtent = positiveScaleDomain[1] - positiveScaleDomain[0];
|
|
66
|
+
const positiveScaleRatio = extent === 0 ? 0 : positiveScaleExtent / extent;
|
|
67
|
+
const positiveScaleTickCount = positiveScaleRatio * count;
|
|
68
|
+
const negativeTickFormat = negativeScale.tickFormat(negativeScaleTickCount, specifier);
|
|
69
|
+
const linearTickFormat = linearScale.tickFormat(linearScaleTickCount, specifier);
|
|
70
|
+
const positiveTickFormat = positiveScale.tickFormat(positiveScaleTickCount, specifier);
|
|
71
|
+
return tick => {
|
|
72
|
+
const tickFormat =
|
|
73
|
+
// eslint-disable-next-line no-nested-ternary
|
|
74
|
+
tick.valueOf() <= -constant ? negativeTickFormat : tick.valueOf() >= constant ? positiveTickFormat : linearTickFormat;
|
|
75
|
+
return tickFormat(tick);
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
return scale;
|
|
79
|
+
}
|
|
80
|
+
function generateScales(scale) {
|
|
81
|
+
const constant = scale.constant();
|
|
82
|
+
const domain = scale.domain();
|
|
83
|
+
const negativeDomain = [domain[0], Math.min(domain[1], -constant)];
|
|
84
|
+
const negativeLogScale = scaleLog(negativeDomain, scale.range());
|
|
85
|
+
const linearDomain = [Math.max(domain[0], -constant), Math.min(domain[1], constant)];
|
|
86
|
+
const linearScale = scaleLinear(linearDomain, scale.range());
|
|
87
|
+
const positiveDomain = [Math.max(domain[0], constant), domain[1]];
|
|
88
|
+
const positiveLogScale = scaleLog(positiveDomain, scale.range());
|
|
89
|
+
return {
|
|
90
|
+
negativeScale: negativeLogScale,
|
|
91
|
+
linearScale,
|
|
92
|
+
positiveScale: positiveLogScale
|
|
93
|
+
};
|
|
94
|
+
}
|
package/esm/models/axis.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ScaleBand, ScaleLinear, ScaleLogarithmic, ScaleOrdinal, ScalePoint, ScalePower, ScaleSequential, ScaleThreshold, ScaleTime } from '@mui/x-charts-vendor/d3-scale';
|
|
1
|
+
import type { ScaleBand, ScaleLinear, ScaleLogarithmic, ScaleOrdinal, ScalePoint, ScalePower, ScaleSequential, ScaleThreshold, ScaleTime, ScaleSymLog } from '@mui/x-charts-vendor/d3-scale';
|
|
2
2
|
import { SxProps } from '@mui/system/styleFunctionSx';
|
|
3
3
|
import { type MakeOptional, MakeRequired } from '@mui/x-internals/types';
|
|
4
4
|
import type { DefaultizedZoomOptions } from "../internals/plugins/featurePlugins/useChartCartesianAxis/index.js";
|
|
@@ -9,8 +9,8 @@ import { ContinuousColorConfig, OrdinalColorConfig, PiecewiseColorConfig } from
|
|
|
9
9
|
export type AxisId = string | number;
|
|
10
10
|
export type D3Scale<Domain extends {
|
|
11
11
|
toString(): string;
|
|
12
|
-
} = number | Date | string, Range = number, Output = number> = ScaleBand<Domain> | ScaleLogarithmic<Range, Output> | ScalePoint<Domain> | ScalePower<Range, Output> | ScaleTime<Range, Output> | ScaleLinear<Range, Output>;
|
|
13
|
-
export type D3ContinuousScale<Range = number, Output = number> = ScaleLogarithmic<Range, Output> | ScalePower<Range, Output> | ScaleTime<Range, Output> | ScaleLinear<Range, Output>;
|
|
12
|
+
} = number | Date | string, Range = number, Output = number> = ScaleBand<Domain> | ScaleSymLog<Range, Output> | ScaleLogarithmic<Range, Output> | ScalePoint<Domain> | ScalePower<Range, Output> | ScaleTime<Range, Output> | ScaleLinear<Range, Output>;
|
|
13
|
+
export type D3ContinuousScale<Range = number, Output = number> = ScaleSymLog<Range, Output> | ScaleLogarithmic<Range, Output> | ScalePower<Range, Output> | ScaleTime<Range, Output> | ScaleLinear<Range, Output>;
|
|
14
14
|
export interface ChartsAxisSlots {
|
|
15
15
|
/**
|
|
16
16
|
* Custom component for the axis main line.
|
|
@@ -179,7 +179,7 @@ export interface ChartsRadiusAxisProps extends ChartsAxisProps {
|
|
|
179
179
|
maxRadius?: number;
|
|
180
180
|
}
|
|
181
181
|
export type ScaleName = keyof AxisScaleConfig;
|
|
182
|
-
export type ContinuousScaleName = 'linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc';
|
|
182
|
+
export type ContinuousScaleName = 'linear' | 'log' | 'symlog' | 'pow' | 'sqrt' | 'time' | 'utc';
|
|
183
183
|
export interface AxisScaleConfig {
|
|
184
184
|
band: {
|
|
185
185
|
scaleType: 'band';
|
|
@@ -208,6 +208,16 @@ export interface AxisScaleConfig {
|
|
|
208
208
|
scale: ScaleLogarithmic<number, number>;
|
|
209
209
|
colorMap?: ContinuousColorConfig | PiecewiseColorConfig;
|
|
210
210
|
};
|
|
211
|
+
symlog: {
|
|
212
|
+
scaleType: 'symlog';
|
|
213
|
+
scale: ScaleSymLog<number, number>;
|
|
214
|
+
colorMap?: ContinuousColorConfig | PiecewiseColorConfig;
|
|
215
|
+
/**
|
|
216
|
+
* The constant used to define the zero point of the symlog scale.
|
|
217
|
+
* @default 1
|
|
218
|
+
*/
|
|
219
|
+
constant?: number;
|
|
220
|
+
};
|
|
211
221
|
pow: {
|
|
212
222
|
scaleType: 'pow';
|
|
213
223
|
scale: ScalePower<number, number>;
|
|
@@ -248,6 +258,9 @@ export interface AxisScaleComputedConfig {
|
|
|
248
258
|
log: {
|
|
249
259
|
colorScale?: ScaleSequential<string, string | null> | ScaleThreshold<number, string | null>;
|
|
250
260
|
};
|
|
261
|
+
symlog: {
|
|
262
|
+
colorScale?: ScaleSequential<string, string | null> | ScaleThreshold<number, string | null>;
|
|
263
|
+
};
|
|
251
264
|
pow: {
|
|
252
265
|
colorScale?: ScaleSequential<string, string | null> | ScaleThreshold<number, string | null>;
|
|
253
266
|
};
|
|
@@ -281,11 +294,37 @@ export type AxisValueFormatterContext<S extends ScaleName = ScaleName> = {
|
|
|
281
294
|
* - `'legend'` The value is displayed in the legend when using color legend.
|
|
282
295
|
* - `'zoom-slider-tooltip'` The value is displayed in the zoom slider tooltip.
|
|
283
296
|
*/
|
|
284
|
-
location: '
|
|
297
|
+
location: 'tooltip' | 'zoom-slider-tooltip';
|
|
285
298
|
/**
|
|
286
299
|
* The d3-scale instance associated to the axis.
|
|
287
300
|
*/
|
|
288
301
|
scale: AxisScaleConfig[S]['scale'];
|
|
302
|
+
} | {
|
|
303
|
+
/**
|
|
304
|
+
* Location indicates where the value will be displayed.
|
|
305
|
+
* - `'tick'` The value is displayed on the axis ticks.
|
|
306
|
+
* - `'tooltip'` The value is displayed in the tooltip when hovering the chart.
|
|
307
|
+
* - `'legend'` The value is displayed in the legend when using color legend.
|
|
308
|
+
* - `'zoom-slider-tooltip'` The value is displayed in the zoom slider tooltip.
|
|
309
|
+
*/
|
|
310
|
+
location: 'tick';
|
|
311
|
+
/**
|
|
312
|
+
* The d3-scale instance associated to the axis.
|
|
313
|
+
*/
|
|
314
|
+
scale: AxisScaleConfig[S]['scale'];
|
|
315
|
+
/**
|
|
316
|
+
* The tick label shown by default if the value isn't formatted.
|
|
317
|
+
* This value might be an empty string if no tick label should be displayed, which is particularly useful in log
|
|
318
|
+
* scales where we want to show ticks to demonstrate it's a log scale, but not labels to avoid them overlapping.
|
|
319
|
+
* @see See {@link https://d3js.org/d3-scale/log#log_tickFormat D3 log scale docs} for more details.
|
|
320
|
+
*/
|
|
321
|
+
defaultTickLabel: string;
|
|
322
|
+
/**
|
|
323
|
+
* A suggestion of the number of ticks to show.
|
|
324
|
+
* Can be provided to the scale's `ticks` method to compute the ticks, or to `tickFormat` to format the ticks.
|
|
325
|
+
* Can be `undefined` if the scale doesn't support it, e.g., band, point scales.
|
|
326
|
+
*/
|
|
327
|
+
tickNumber?: number;
|
|
289
328
|
};
|
|
290
329
|
/**
|
|
291
330
|
* Config that is shared between cartesian and polar axes.
|
|
@@ -391,6 +430,9 @@ export declare function isBandScaleConfig(scaleConfig: AxisConfig<ScaleName>): s
|
|
|
391
430
|
export declare function isPointScaleConfig(scaleConfig: AxisConfig<ScaleName>): scaleConfig is AxisConfig<'point'> & {
|
|
392
431
|
scaleType: 'point';
|
|
393
432
|
};
|
|
433
|
+
export declare function isSymlogScaleConfig(scaleConfig: AxisConfig<ScaleName>): scaleConfig is AxisConfig<'symlog'> & {
|
|
434
|
+
scaleType: 'symlog';
|
|
435
|
+
};
|
|
394
436
|
/**
|
|
395
437
|
* The data format returned by onAxisClick.
|
|
396
438
|
*/
|
package/esm/models/axis.js
CHANGED
|
@@ -17,6 +17,9 @@ export function isBandScaleConfig(scaleConfig) {
|
|
|
17
17
|
export function isPointScaleConfig(scaleConfig) {
|
|
18
18
|
return scaleConfig.scaleType === 'point';
|
|
19
19
|
}
|
|
20
|
+
export function isSymlogScaleConfig(scaleConfig) {
|
|
21
|
+
return scaleConfig.scaleType === 'symlog';
|
|
22
|
+
}
|
|
20
23
|
|
|
21
24
|
/**
|
|
22
25
|
* The data format returned by onAxisClick.
|
|
@@ -25,6 +25,16 @@ export interface BarSeriesType extends CommonSeriesType<number | null>, Cartesia
|
|
|
25
25
|
* @default 'diverging'
|
|
26
26
|
*/
|
|
27
27
|
stackOffset?: StackOffsetType;
|
|
28
|
+
/**
|
|
29
|
+
* If provided, the value will be used as the minimum size of the bar in pixels.
|
|
30
|
+
* This is useful to avoid bars with a size of 0.
|
|
31
|
+
*
|
|
32
|
+
* The property is ignored if the series value is `null` or `0`.
|
|
33
|
+
* It also doesn't work with stacked series.
|
|
34
|
+
*
|
|
35
|
+
* @default 0px
|
|
36
|
+
*/
|
|
37
|
+
minBarSize?: number;
|
|
28
38
|
}
|
|
29
39
|
/**
|
|
30
40
|
* An object that allows to identify a single bar.
|
|
@@ -35,4 +45,4 @@ export type BarItemIdentifier = {
|
|
|
35
45
|
seriesId: SeriesId;
|
|
36
46
|
dataIndex: number;
|
|
37
47
|
};
|
|
38
|
-
export interface DefaultizedBarSeriesType extends DefaultizedProps<BarSeriesType, CommonDefaultizedProps | 'color' | 'layout'> {}
|
|
48
|
+
export interface DefaultizedBarSeriesType extends DefaultizedProps<BarSeriesType, CommonDefaultizedProps | 'color' | 'layout' | 'minBarSize'> {}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ChartsLabelMarkProps } from "../../ChartsLabel/index.js";
|
|
2
1
|
import { HighlightScope } from "../../internals/plugins/featurePlugins/useChartHighlight/highlightConfig.types.js";
|
|
3
2
|
import type { StackOffsetType, StackOrderType } from "../stacking.js";
|
|
3
|
+
import type { ChartsLabelMarkType } from "../../ChartsLabel/ChartsLabelMark.js";
|
|
4
4
|
export type SeriesId = number | string;
|
|
5
5
|
export type SeriesValueFormatterContext = {
|
|
6
6
|
/**
|
|
@@ -10,7 +10,13 @@ export type SeriesValueFormatterContext = {
|
|
|
10
10
|
};
|
|
11
11
|
export type SeriesValueFormatter<TValue> = (value: TValue, context: SeriesValueFormatterContext) => string | null;
|
|
12
12
|
export type CommonSeriesType<TValue> = {
|
|
13
|
+
/**
|
|
14
|
+
* The id of this series.
|
|
15
|
+
*/
|
|
13
16
|
id?: SeriesId;
|
|
17
|
+
/**
|
|
18
|
+
* Color to use when displaying the series.
|
|
19
|
+
*/
|
|
14
20
|
color?: string;
|
|
15
21
|
/**
|
|
16
22
|
* Formatter used to render values in tooltip or other data display.
|
|
@@ -22,13 +28,13 @@ export type CommonSeriesType<TValue> = {
|
|
|
22
28
|
/**
|
|
23
29
|
* The scope to apply when the series is highlighted.
|
|
24
30
|
*/
|
|
25
|
-
highlightScope?:
|
|
31
|
+
highlightScope?: HighlightScope;
|
|
26
32
|
/**
|
|
27
33
|
* Defines the mark type for the series.
|
|
28
34
|
*
|
|
29
35
|
* There is a default mark type for each series type.
|
|
30
36
|
*/
|
|
31
|
-
labelMarkType?:
|
|
37
|
+
labelMarkType?: ChartsLabelMarkType;
|
|
32
38
|
};
|
|
33
39
|
export type CommonDefaultizedProps = 'id' | 'valueFormatter' | 'data';
|
|
34
40
|
export type CartesianSeriesType = {
|
|
@@ -34,7 +34,9 @@ export interface LineSeriesType extends CommonSeriesType<number | null>, Cartesi
|
|
|
34
34
|
* The key used to retrieve data from the dataset.
|
|
35
35
|
*/
|
|
36
36
|
dataKey?: string;
|
|
37
|
-
|
|
37
|
+
/**
|
|
38
|
+
* If `true`, the series is rendered as an area instead of a line.
|
|
39
|
+
*/
|
|
38
40
|
area?: boolean;
|
|
39
41
|
/**
|
|
40
42
|
* The label to display on the tooltip or the legend. It can be a string or a function.
|
|
@@ -12,6 +12,9 @@ export type ScatterValueType = {
|
|
|
12
12
|
export interface ScatterSeriesType extends CommonSeriesType<ScatterValueType | null>, CartesianSeriesType {
|
|
13
13
|
type: 'scatter';
|
|
14
14
|
data?: readonly ScatterValueType[];
|
|
15
|
+
/**
|
|
16
|
+
* Size of the markers in the scatter plot, in pixels.
|
|
17
|
+
*/
|
|
15
18
|
markerSize?: number;
|
|
16
19
|
/**
|
|
17
20
|
* The label to display on the tooltip or the legend. It can be a string or a function.
|
|
@@ -52,7 +55,7 @@ export interface ScatterSeriesType extends CommonSeriesType<ScatterValueType | n
|
|
|
52
55
|
};
|
|
53
56
|
preview?: {
|
|
54
57
|
/**
|
|
55
|
-
* The size of the preview marker.
|
|
58
|
+
* The size of the preview marker in pixels.
|
|
56
59
|
* @default 1
|
|
57
60
|
*/
|
|
58
61
|
markerSize?: number;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const renderSymbol = Symbol.for('render');
|
|
2
|
+
const connectedSymbol = Symbol.for('connected');
|
|
3
|
+
const contextSymbol = Symbol.for('context');
|
|
4
|
+
const propsSymbol = Symbol.for('props');
|
|
5
|
+
|
|
6
|
+
// This function creates a custom web component that wraps a React component.
|
|
7
|
+
// Adapted from https://github.com/bitovi/react-to-web-component/blob/b1372bfd7bc67fe49920db840f1ed9cf736b2724/packages/core/src/core.ts
|
|
8
|
+
export function reactToWebComponent(ReactComponent, options, renderer) {
|
|
9
|
+
class ReactWebComponent extends HTMLElement {
|
|
10
|
+
static get observedAttributes() {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
constructor() {
|
|
14
|
+
super();
|
|
15
|
+
this[connectedSymbol] = true;
|
|
16
|
+
this[contextSymbol] = void 0;
|
|
17
|
+
this[propsSymbol] = {};
|
|
18
|
+
this.container = void 0;
|
|
19
|
+
if (options.shadow) {
|
|
20
|
+
this.container = this.attachShadow({
|
|
21
|
+
mode: options.shadow
|
|
22
|
+
});
|
|
23
|
+
} else {
|
|
24
|
+
this.container = this;
|
|
25
|
+
}
|
|
26
|
+
this[propsSymbol].container = this.container;
|
|
27
|
+
}
|
|
28
|
+
connectedCallback() {
|
|
29
|
+
this[connectedSymbol] = true;
|
|
30
|
+
this[renderSymbol]();
|
|
31
|
+
}
|
|
32
|
+
disconnectedCallback() {
|
|
33
|
+
this[connectedSymbol] = false;
|
|
34
|
+
if (this[contextSymbol]) {
|
|
35
|
+
renderer.unmount(this[contextSymbol]);
|
|
36
|
+
}
|
|
37
|
+
delete this[contextSymbol];
|
|
38
|
+
}
|
|
39
|
+
[renderSymbol]() {
|
|
40
|
+
if (!this[connectedSymbol]) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (!this[contextSymbol]) {
|
|
44
|
+
this[contextSymbol] = renderer.mount(this.container, ReactComponent, this[propsSymbol]);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return ReactWebComponent;
|
|
49
|
+
}
|
package/hooks/useTicks.d.ts
CHANGED
|
@@ -49,8 +49,13 @@ export type TickItemType = {
|
|
|
49
49
|
offset: number;
|
|
50
50
|
labelOffset: number;
|
|
51
51
|
};
|
|
52
|
+
export declare function getTicks(options: {
|
|
53
|
+
scale: D3Scale;
|
|
54
|
+
valueFormatter?: AxisConfig['valueFormatter'];
|
|
55
|
+
isInside: (offset: number) => boolean;
|
|
56
|
+
} & Pick<TickParams, 'tickInterval' | 'tickPlacement' | 'tickLabelPlacement'> & Required<Pick<TickParams, 'tickNumber'>>): TickItemType[];
|
|
52
57
|
export declare function useTicks(options: {
|
|
53
58
|
scale: D3Scale;
|
|
54
59
|
valueFormatter?: AxisConfig['valueFormatter'];
|
|
55
60
|
direction: 'x' | 'y';
|
|
56
|
-
} & Pick<TickParams, '
|
|
61
|
+
} & Pick<TickParams, 'tickInterval' | 'tickPlacement' | 'tickLabelPlacement'> & Required<Pick<TickParams, 'tickNumber'>>): TickItemType[];
|