@mui/x-charts 8.9.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.
Files changed (76) hide show
  1. package/BarChart/BarChart.js +94 -1
  2. package/BarChart/BarClipPath.d.ts +17 -12
  3. package/BarChart/BarClipPath.js +70 -57
  4. package/BarChart/BarPlot.js +4 -0
  5. package/BarChart/seriesConfig/extremums.js +2 -3
  6. package/BarChart/useBarChartProps.d.ts +1 -1
  7. package/CHANGELOG.md +124 -0
  8. package/ChartContainer/ChartContainer.js +141 -0
  9. package/{internals/components/ChartsWrapper → ChartsWrapper}/ChartsWrapper.d.ts +13 -4
  10. package/{internals/components/ChartsWrapper → ChartsWrapper}/ChartsWrapper.js +33 -7
  11. package/LineChart/LineChart.js +94 -1
  12. package/LineChart/seriesConfig/extremums.js +2 -3
  13. package/LineChart/useLineChartProps.d.ts +1 -1
  14. package/PieChart/PieChart.js +1 -1
  15. package/RadarChart/RadarChart.d.ts +1 -1
  16. package/RadarChart/RadarChart.js +1 -1
  17. package/RadarChart/useRadarChartProps.d.ts +1 -1
  18. package/ScatterChart/ScatterChart.js +94 -1
  19. package/ScatterChart/seriesConfig/extremums.js +50 -23
  20. package/ScatterChart/useScatterChartProps.d.ts +1 -1
  21. package/SparkLineChart/SparkLineChart.js +93 -0
  22. package/esm/BarChart/BarChart.js +94 -1
  23. package/esm/BarChart/BarClipPath.d.ts +17 -12
  24. package/esm/BarChart/BarClipPath.js +69 -55
  25. package/esm/BarChart/BarPlot.js +4 -0
  26. package/esm/BarChart/seriesConfig/extremums.js +2 -3
  27. package/esm/BarChart/useBarChartProps.d.ts +1 -1
  28. package/esm/ChartContainer/ChartContainer.js +141 -0
  29. package/esm/{internals/components/ChartsWrapper → ChartsWrapper}/ChartsWrapper.d.ts +13 -4
  30. package/esm/{internals/components/ChartsWrapper → ChartsWrapper}/ChartsWrapper.js +31 -6
  31. package/esm/LineChart/LineChart.js +94 -1
  32. package/esm/LineChart/seriesConfig/extremums.js +2 -3
  33. package/esm/LineChart/useLineChartProps.d.ts +1 -1
  34. package/esm/PieChart/PieChart.js +1 -1
  35. package/esm/RadarChart/RadarChart.d.ts +1 -1
  36. package/esm/RadarChart/RadarChart.js +1 -1
  37. package/esm/RadarChart/useRadarChartProps.d.ts +1 -1
  38. package/esm/ScatterChart/ScatterChart.js +94 -1
  39. package/esm/ScatterChart/seriesConfig/extremums.js +50 -23
  40. package/esm/ScatterChart/useScatterChartProps.d.ts +1 -1
  41. package/esm/SparkLineChart/SparkLineChart.js +93 -0
  42. package/esm/index.d.ts +2 -1
  43. package/esm/index.js +6 -2
  44. package/esm/internals/findMinMax.d.ts +1 -0
  45. package/esm/internals/findMinMax.js +13 -0
  46. package/esm/internals/getScale.js +3 -0
  47. package/esm/internals/index.d.ts +1 -1
  48. package/esm/internals/index.js +1 -1
  49. package/esm/internals/plugins/featurePlugins/useChartCartesianAxis/computeAxisValue.js +4 -1
  50. package/esm/internals/plugins/featurePlugins/useChartVoronoi/useChartVoronoi.js +17 -12
  51. package/esm/internals/symlogScale.d.ts +2 -0
  52. package/esm/internals/symlogScale.js +94 -0
  53. package/esm/models/axis.d.ts +20 -4
  54. package/esm/models/axis.js +3 -0
  55. package/index.d.ts +2 -1
  56. package/index.js +13 -1
  57. package/internals/findMinMax.d.ts +1 -0
  58. package/internals/findMinMax.js +19 -0
  59. package/internals/getScale.js +3 -0
  60. package/internals/index.d.ts +1 -1
  61. package/internals/index.js +12 -12
  62. package/internals/plugins/featurePlugins/useChartCartesianAxis/computeAxisValue.js +3 -0
  63. package/internals/plugins/featurePlugins/useChartVoronoi/useChartVoronoi.js +17 -12
  64. package/internals/symlogScale.d.ts +2 -0
  65. package/internals/symlogScale.js +100 -0
  66. package/models/axis.d.ts +20 -4
  67. package/models/axis.js +4 -0
  68. package/package.json +5 -6
  69. package/BarChart/getRadius.d.ts +0 -20
  70. package/BarChart/getRadius.js +0 -37
  71. package/esm/BarChart/getRadius.d.ts +0 -20
  72. package/esm/BarChart/getRadius.js +0 -30
  73. /package/{esm/internals/components/ChartsWrapper → ChartsWrapper}/index.d.ts +0 -0
  74. /package/{internals/components/ChartsWrapper → ChartsWrapper}/index.js +0 -0
  75. /package/{internals/components → esm}/ChartsWrapper/index.d.ts +0 -0
  76. /package/esm/{internals/components/ChartsWrapper → ChartsWrapper}/index.js +0 -0
@@ -477,6 +477,53 @@ process.env.NODE_ENV !== "production" ? SparkLineChart.propTypes = {
477
477
  tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
478
478
  tickSize: PropTypes.number,
479
479
  valueFormatter: PropTypes.func
480
+ }), PropTypes.shape({
481
+ axis: PropTypes.oneOf(['x']),
482
+ classes: PropTypes.object,
483
+ colorMap: PropTypes.oneOfType([PropTypes.shape({
484
+ color: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string.isRequired), PropTypes.func]).isRequired,
485
+ max: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.number]),
486
+ min: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.number]),
487
+ type: PropTypes.oneOf(['continuous']).isRequired
488
+ }), PropTypes.shape({
489
+ colors: PropTypes.arrayOf(PropTypes.string).isRequired,
490
+ thresholds: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.number]).isRequired).isRequired,
491
+ type: PropTypes.oneOf(['piecewise']).isRequired
492
+ })]),
493
+ constant: PropTypes.number,
494
+ data: PropTypes.array,
495
+ dataKey: PropTypes.string,
496
+ disableLine: PropTypes.bool,
497
+ disableTicks: PropTypes.bool,
498
+ domainLimit: PropTypes.oneOfType([PropTypes.oneOf(['nice', 'strict']), PropTypes.func]),
499
+ fill: PropTypes.string,
500
+ height: PropTypes.number,
501
+ hideTooltip: PropTypes.bool,
502
+ id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
503
+ ignoreTooltip: PropTypes.bool,
504
+ label: PropTypes.string,
505
+ labelStyle: PropTypes.object,
506
+ max: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.number]),
507
+ min: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.number]),
508
+ offset: PropTypes.number,
509
+ position: PropTypes.oneOf(['bottom', 'none', 'top']),
510
+ reverse: PropTypes.bool,
511
+ scaleType: PropTypes.oneOf(['symlog']),
512
+ slotProps: PropTypes.object,
513
+ slots: PropTypes.object,
514
+ stroke: PropTypes.string,
515
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
516
+ tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
517
+ tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
518
+ tickLabelMinGap: PropTypes.number,
519
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
520
+ tickLabelStyle: PropTypes.object,
521
+ tickMaxStep: PropTypes.number,
522
+ tickMinStep: PropTypes.number,
523
+ tickNumber: PropTypes.number,
524
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
525
+ tickSize: PropTypes.number,
526
+ valueFormatter: PropTypes.func
480
527
  }), PropTypes.shape({
481
528
  axis: PropTypes.oneOf(['x']),
482
529
  classes: PropTypes.object,
@@ -859,6 +906,52 @@ process.env.NODE_ENV !== "production" ? SparkLineChart.propTypes = {
859
906
  tickSize: PropTypes.number,
860
907
  valueFormatter: PropTypes.func,
861
908
  width: PropTypes.number
909
+ }), PropTypes.shape({
910
+ axis: PropTypes.oneOf(['y']),
911
+ classes: PropTypes.object,
912
+ colorMap: PropTypes.oneOfType([PropTypes.shape({
913
+ color: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string.isRequired), PropTypes.func]).isRequired,
914
+ max: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.number]),
915
+ min: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.number]),
916
+ type: PropTypes.oneOf(['continuous']).isRequired
917
+ }), PropTypes.shape({
918
+ colors: PropTypes.arrayOf(PropTypes.string).isRequired,
919
+ thresholds: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.number]).isRequired).isRequired,
920
+ type: PropTypes.oneOf(['piecewise']).isRequired
921
+ })]),
922
+ constant: PropTypes.number,
923
+ data: PropTypes.array,
924
+ dataKey: PropTypes.string,
925
+ disableLine: PropTypes.bool,
926
+ disableTicks: PropTypes.bool,
927
+ domainLimit: PropTypes.oneOfType([PropTypes.oneOf(['nice', 'strict']), PropTypes.func]),
928
+ fill: PropTypes.string,
929
+ hideTooltip: PropTypes.bool,
930
+ id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
931
+ ignoreTooltip: PropTypes.bool,
932
+ label: PropTypes.string,
933
+ labelStyle: PropTypes.object,
934
+ max: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.number]),
935
+ min: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.number]),
936
+ offset: PropTypes.number,
937
+ position: PropTypes.oneOf(['left', 'none', 'right']),
938
+ reverse: PropTypes.bool,
939
+ scaleType: PropTypes.oneOf(['symlog']),
940
+ slotProps: PropTypes.object,
941
+ slots: PropTypes.object,
942
+ stroke: PropTypes.string,
943
+ sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
944
+ tickInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.array, PropTypes.func]),
945
+ tickLabelInterval: PropTypes.oneOfType([PropTypes.oneOf(['auto']), PropTypes.func]),
946
+ tickLabelPlacement: PropTypes.oneOf(['middle', 'tick']),
947
+ tickLabelStyle: PropTypes.object,
948
+ tickMaxStep: PropTypes.number,
949
+ tickMinStep: PropTypes.number,
950
+ tickNumber: PropTypes.number,
951
+ tickPlacement: PropTypes.oneOf(['end', 'extremities', 'middle', 'start']),
952
+ tickSize: PropTypes.number,
953
+ valueFormatter: PropTypes.func,
954
+ width: PropTypes.number
862
955
  }), PropTypes.shape({
863
956
  axis: PropTypes.oneOf(['y']),
864
957
  classes: PropTypes.object,
package/esm/index.d.ts CHANGED
@@ -26,4 +26,5 @@ export * from "./ChartsSurface/index.js";
26
26
  export { ChartContainer } from "./ChartContainer/index.js";
27
27
  export type { ChartContainerProps } from "./ChartContainer/index.js";
28
28
  export * from "./ChartDataProvider/index.js";
29
- export * from "./Toolbar/index.js";
29
+ export * from "./Toolbar/index.js";
30
+ export * from "./ChartsWrapper/index.js";
package/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-charts v8.9.0
2
+ * @mui/x-charts v8.9.2
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -32,4 +32,8 @@ export * from "./RadarChart/index.js";
32
32
  export * from "./ChartsSurface/index.js";
33
33
  export { ChartContainer } from "./ChartContainer/index.js";
34
34
  export * from "./ChartDataProvider/index.js";
35
- export * from "./Toolbar/index.js";
35
+ export * from "./Toolbar/index.js";
36
+ export * from "./ChartsWrapper/index.js";
37
+
38
+ // Locales should be imported from `@mui/x-charts/locales`
39
+ // export * from './locales';
@@ -0,0 +1 @@
1
+ export declare function findMinMax(data: readonly number[]): [number, number];
@@ -0,0 +1,13 @@
1
+ export function findMinMax(data) {
2
+ let min = Infinity;
3
+ let max = -Infinity;
4
+ for (const value of data ?? []) {
5
+ if (value < min) {
6
+ min = value;
7
+ }
8
+ if (value > max) {
9
+ max = value;
10
+ }
11
+ }
12
+ return [min, max];
13
+ }
@@ -1,4 +1,5 @@
1
1
  import { scaleLog, scalePow, scaleSqrt, scaleTime, scaleUtc, scaleLinear } from '@mui/x-charts-vendor/d3-scale';
2
+ import { scaleSymlog } from "./symlogScale.js";
2
3
  export function getScale(scaleType, domain, range) {
3
4
  switch (scaleType) {
4
5
  case 'log':
@@ -11,6 +12,8 @@ export function getScale(scaleType, domain, range) {
11
12
  return scaleTime(domain, range);
12
13
  case 'utc':
13
14
  return scaleUtc(domain, range);
15
+ case 'symlog':
16
+ return scaleSymlog(domain, range);
14
17
  default:
15
18
  return scaleLinear(domain, range);
16
19
  }
@@ -1,5 +1,4 @@
1
1
  export * from "./components/ChartsAxesGradients/index.js";
2
- export * from "./components/ChartsWrapper/index.js";
3
2
  export * from "../ChartsLabel/ChartsLabelMark.js";
4
3
  export * from "./components/NotRendered.js";
5
4
  export { useSeries } from "../hooks/useSeries.js";
@@ -54,6 +53,7 @@ export * from "./ticks.js";
54
53
  export * from "./dateHelpers.js";
55
54
  export * from "./invertScale.js";
56
55
  export * from "./isBandScale.js";
56
+ export * from "./findMinMax.js";
57
57
  export { getAxisExtremum } from "./plugins/featurePlugins/useChartCartesianAxis/getAxisExtremum.js";
58
58
  export * from "../context/ChartProvider/index.js";
59
59
  export * from "../context/ChartsSlotsContext.js";
@@ -1,6 +1,5 @@
1
1
  // Components
2
2
  export * from "./components/ChartsAxesGradients/index.js";
3
- export * from "./components/ChartsWrapper/index.js";
4
3
  export * from "../ChartsLabel/ChartsLabelMark.js";
5
4
  export * from "./components/NotRendered.js";
6
5
 
@@ -64,6 +63,7 @@ export * from "./ticks.js";
64
63
  export * from "./dateHelpers.js";
65
64
  export * from "./invertScale.js";
66
65
  export * from "./isBandScale.js";
66
+ export * from "./findMinMax.js";
67
67
 
68
68
  // contexts
69
69
  export { getAxisExtremum } from "./plugins/featurePlugins/useChartCartesianAxis/getAxisExtremum.js";
@@ -1,7 +1,7 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import { scaleBand, scalePoint } from '@mui/x-charts-vendor/d3-scale';
3
3
  import { createScalarFormatter } from "../../../defaultValueFormatters.js";
4
- import { isBandScaleConfig, isPointScaleConfig } from "../../../../models/axis.js";
4
+ import { isBandScaleConfig, isPointScaleConfig, isSymlogScaleConfig } from "../../../../models/axis.js";
5
5
  import { getColorScale, getOrdinalColorScale } from "../../../colorScale.js";
6
6
  import { getTickNumber, scaleTickNumberByRange } from "../../../ticks.js";
7
7
  import { getScale } from "../../../getScale.js";
@@ -114,6 +114,9 @@ export function computeAxisValue({
114
114
  const tickNumber = scaleTickNumberByRange(rawTickNumber, zoomRange);
115
115
  const zoomedRange = zoomScaleRange(range, zoomRange);
116
116
  const scale = getScale(scaleType, axisExtremums, zoomedRange);
117
+ if (isSymlogScaleConfig(axis) && axis.constant != null) {
118
+ scale.constant(axis.constant);
119
+ }
117
120
  const finalScale = domainLimit === 'nice' ? scale.nice(rawTickNumber) : scale;
118
121
  const [minDomain, maxDomain] = finalScale.domain();
119
122
  const domain = [axis.min ?? minDomain, axis.max ?? maxDomain];
@@ -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 = data.flatMap(({
71
- x,
72
- y
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 (!instance.isPointInside(pointX, pointY)) {
77
- // If the point is not displayed we move them to a trash coordinate.
78
- // This avoids managing index mapping before/after filtering.
79
- // The trash point is far enough such that any point in the drawing area will be closer to the mouse than the trash coordinate.
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
- return [pointX, pointY];
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
- const dataIndex = (2 * closestPointIndex - voronoiRef.current[closestSeries.seriesId].startIndex) / 2;
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,2 @@
1
+ import { NumberValue, ScaleSymLog } from '@mui/x-charts-vendor/d3-scale';
2
+ export declare function scaleSymlog<Range, Output = Range, Unknown = never>(_domain: Iterable<NumberValue>, _range: Iterable<Range>): ScaleSymLog<Range, Output, Unknown>;
@@ -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
+ }
@@ -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
  };
@@ -417,6 +430,9 @@ export declare function isBandScaleConfig(scaleConfig: AxisConfig<ScaleName>): s
417
430
  export declare function isPointScaleConfig(scaleConfig: AxisConfig<ScaleName>): scaleConfig is AxisConfig<'point'> & {
418
431
  scaleType: 'point';
419
432
  };
433
+ export declare function isSymlogScaleConfig(scaleConfig: AxisConfig<ScaleName>): scaleConfig is AxisConfig<'symlog'> & {
434
+ scaleType: 'symlog';
435
+ };
420
436
  /**
421
437
  * The data format returned by onAxisClick.
422
438
  */
@@ -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.
package/index.d.ts CHANGED
@@ -26,4 +26,5 @@ export * from "./ChartsSurface/index.js";
26
26
  export { ChartContainer } from "./ChartContainer/index.js";
27
27
  export type { ChartContainerProps } from "./ChartContainer/index.js";
28
28
  export * from "./ChartDataProvider/index.js";
29
- export * from "./Toolbar/index.js";
29
+ export * from "./Toolbar/index.js";
30
+ export * from "./ChartsWrapper/index.js";
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-charts v8.9.0
2
+ * @mui/x-charts v8.9.2
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -343,4 +343,16 @@ Object.keys(_Toolbar).forEach(function (key) {
343
343
  return _Toolbar[key];
344
344
  }
345
345
  });
346
+ });
347
+ var _ChartsWrapper = require("./ChartsWrapper");
348
+ Object.keys(_ChartsWrapper).forEach(function (key) {
349
+ if (key === "default" || key === "__esModule") return;
350
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
351
+ if (key in exports && exports[key] === _ChartsWrapper[key]) return;
352
+ Object.defineProperty(exports, key, {
353
+ enumerable: true,
354
+ get: function () {
355
+ return _ChartsWrapper[key];
356
+ }
357
+ });
346
358
  });
@@ -0,0 +1 @@
1
+ export declare function findMinMax(data: readonly number[]): [number, number];
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.findMinMax = findMinMax;
7
+ function findMinMax(data) {
8
+ let min = Infinity;
9
+ let max = -Infinity;
10
+ for (const value of data ?? []) {
11
+ if (value < min) {
12
+ min = value;
13
+ }
14
+ if (value > max) {
15
+ max = value;
16
+ }
17
+ }
18
+ return [min, max];
19
+ }
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.getScale = getScale;
7
7
  var _d3Scale = require("@mui/x-charts-vendor/d3-scale");
8
+ var _symlogScale = require("./symlogScale");
8
9
  function getScale(scaleType, domain, range) {
9
10
  switch (scaleType) {
10
11
  case 'log':
@@ -17,6 +18,8 @@ function getScale(scaleType, domain, range) {
17
18
  return (0, _d3Scale.scaleTime)(domain, range);
18
19
  case 'utc':
19
20
  return (0, _d3Scale.scaleUtc)(domain, range);
21
+ case 'symlog':
22
+ return (0, _symlogScale.scaleSymlog)(domain, range);
20
23
  default:
21
24
  return (0, _d3Scale.scaleLinear)(domain, range);
22
25
  }
@@ -1,5 +1,4 @@
1
1
  export * from "./components/ChartsAxesGradients/index.js";
2
- export * from "./components/ChartsWrapper/index.js";
3
2
  export * from "../ChartsLabel/ChartsLabelMark.js";
4
3
  export * from "./components/NotRendered.js";
5
4
  export { useSeries } from "../hooks/useSeries.js";
@@ -54,6 +53,7 @@ export * from "./ticks.js";
54
53
  export * from "./dateHelpers.js";
55
54
  export * from "./invertScale.js";
56
55
  export * from "./isBandScale.js";
56
+ export * from "./findMinMax.js";
57
57
  export { getAxisExtremum } from "./plugins/featurePlugins/useChartCartesianAxis/getAxisExtremum.js";
58
58
  export * from "../context/ChartProvider/index.js";
59
59
  export * from "../context/ChartsSlotsContext.js";
@@ -122,18 +122,6 @@ Object.keys(_ChartsAxesGradients).forEach(function (key) {
122
122
  }
123
123
  });
124
124
  });
125
- var _ChartsWrapper = require("./components/ChartsWrapper");
126
- Object.keys(_ChartsWrapper).forEach(function (key) {
127
- if (key === "default" || key === "__esModule") return;
128
- if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
129
- if (key in exports && exports[key] === _ChartsWrapper[key]) return;
130
- Object.defineProperty(exports, key, {
131
- enumerable: true,
132
- get: function () {
133
- return _ChartsWrapper[key];
134
- }
135
- });
136
- });
137
125
  var _ChartsLabelMark = require("../ChartsLabel/ChartsLabelMark");
138
126
  Object.keys(_ChartsLabelMark).forEach(function (key) {
139
127
  if (key === "default" || key === "__esModule") return;
@@ -628,6 +616,18 @@ Object.keys(_isBandScale).forEach(function (key) {
628
616
  }
629
617
  });
630
618
  });
619
+ var _findMinMax = require("./findMinMax");
620
+ Object.keys(_findMinMax).forEach(function (key) {
621
+ if (key === "default" || key === "__esModule") return;
622
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
623
+ if (key in exports && exports[key] === _findMinMax[key]) return;
624
+ Object.defineProperty(exports, key, {
625
+ enumerable: true,
626
+ get: function () {
627
+ return _findMinMax[key];
628
+ }
629
+ });
630
+ });
631
631
  var _getAxisExtremum = require("./plugins/featurePlugins/useChartCartesianAxis/getAxisExtremum");
632
632
  var _ChartProvider = require("../context/ChartProvider");
633
633
  Object.keys(_ChartProvider).forEach(function (key) {
@@ -121,6 +121,9 @@ function computeAxisValue({
121
121
  const tickNumber = (0, _ticks.scaleTickNumberByRange)(rawTickNumber, zoomRange);
122
122
  const zoomedRange = (0, _zoom.zoomScaleRange)(range, zoomRange);
123
123
  const scale = (0, _getScale.getScale)(scaleType, axisExtremums, zoomedRange);
124
+ if ((0, _axis.isSymlogScaleConfig)(axis) && axis.constant != null) {
125
+ scale.constant(axis.constant);
126
+ }
124
127
  const finalScale = domainLimit === 'nice' ? scale.nice(rawTickNumber) : scale;
125
128
  const [minDomain, maxDomain] = finalScale.domain();
126
129
  const domain = [axis.min ?? minDomain, axis.max ?? maxDomain];
@@ -74,22 +74,24 @@ const useChartVoronoi = ({
74
74
  const yScale = yAxis[yAxisId ?? defaultYAxisId].scale;
75
75
  const getXPosition = (0, _useScale.getValueToPositionMapper)(xScale);
76
76
  const getYPosition = (0, _useScale.getValueToPositionMapper)(yScale);
77
- const seriesPoints = data.flatMap(({
78
- x,
79
- y
80
- }) => {
77
+ const seriesPoints = [];
78
+ const seriesIndexes = [];
79
+ for (let dataIndex = 0; dataIndex < data.length; dataIndex += 1) {
80
+ const {
81
+ x,
82
+ y
83
+ } = data[dataIndex];
81
84
  const pointX = getXPosition(x);
82
85
  const pointY = getYPosition(y);
83
- if (!instance.isPointInside(pointX, pointY)) {
84
- // If the point is not displayed we move them to a trash coordinate.
85
- // This avoids managing index mapping before/after filtering.
86
- // The trash point is far enough such that any point in the drawing area will be closer to the mouse than the trash coordinate.
87
- return [-drawingArea.width, -drawingArea.height];
86
+ if (instance.isPointInside(pointX, pointY)) {
87
+ seriesPoints.push(pointX);
88
+ seriesPoints.push(pointY);
89
+ seriesIndexes.push(dataIndex);
88
90
  }
89
- return [pointX, pointY];
90
- });
91
+ }
91
92
  voronoiRef.current[seriesId] = {
92
93
  seriesId,
94
+ seriesIndexes,
93
95
  startIndex: points.length,
94
96
  endIndex: points.length + seriesPoints.length
95
97
  };
@@ -124,7 +126,10 @@ const useChartVoronoi = ({
124
126
  if (closestSeries === undefined) {
125
127
  return 'no-point-found';
126
128
  }
127
- const dataIndex = (2 * closestPointIndex - voronoiRef.current[closestSeries.seriesId].startIndex) / 2;
129
+
130
+ // The point index in the series with id=closestSeries.seriesId.
131
+ const seriesPointIndex = (2 * closestPointIndex - voronoiRef.current[closestSeries.seriesId].startIndex) / 2;
132
+ const dataIndex = voronoiRef.current[closestSeries.seriesId].seriesIndexes[seriesPointIndex];
128
133
  if (voronoiMaxRadius !== undefined) {
129
134
  const pointX = delauneyRef.current.points[2 * closestPointIndex];
130
135
  const pointY = delauneyRef.current.points[2 * closestPointIndex + 1];
@@ -0,0 +1,2 @@
1
+ import { NumberValue, ScaleSymLog } from '@mui/x-charts-vendor/d3-scale';
2
+ export declare function scaleSymlog<Range, Output = Range, Unknown = never>(_domain: Iterable<NumberValue>, _range: Iterable<Range>): ScaleSymLog<Range, Output, Unknown>;