@mui/x-charts 6.0.0-alpha.1 → 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.
Files changed (179) hide show
  1. package/BarChart/BarChart.d.ts +1 -4
  2. package/BarChart/BarChart.js +6 -3
  3. package/BarChart/BarPlot.js +42 -8
  4. package/BarChart/legend.d.ts +3 -0
  5. package/BarChart/legend.js +20 -0
  6. package/CHANGELOG.md +287 -107
  7. package/ChartContainer/index.d.ts +3 -1
  8. package/ChartContainer/index.js +10 -6
  9. package/ChartsAxisHighlight/ChartsAxisHighlight.js +3 -2
  10. package/ChartsLegend/ChartsLegend.d.ts +5 -1
  11. package/ChartsLegend/ChartsLegend.js +5 -1
  12. package/ChartsLegend/utils.d.ts +1 -1
  13. package/ChartsLegend/utils.js +12 -1
  14. package/ChartsTooltip/ChartsAxisTooltipContent.js +1 -1
  15. package/ChartsTooltip/ChartsItemTooltipContent.js +11 -2
  16. package/LineChart/LineChart.d.ts +1 -4
  17. package/LineChart/LineChart.js +6 -3
  18. package/LineChart/legend.d.ts +3 -0
  19. package/LineChart/legend.js +20 -0
  20. package/PieChart/PieArc.d.ts +36 -0
  21. package/PieChart/PieArc.js +128 -0
  22. package/PieChart/PieArcLabel.d.ts +36 -0
  23. package/PieChart/PieArcLabel.js +113 -0
  24. package/PieChart/PieChart.d.ts +20 -0
  25. package/PieChart/PieChart.js +292 -0
  26. package/PieChart/PiePlot.d.ts +2 -0
  27. package/PieChart/PiePlot.js +98 -0
  28. package/PieChart/formatter.d.ts +3 -0
  29. package/PieChart/formatter.js +49 -0
  30. package/PieChart/index.d.ts +4 -0
  31. package/PieChart/index.js +47 -0
  32. package/PieChart/legend.d.ts +3 -0
  33. package/PieChart/legend.js +19 -0
  34. package/PieChart/package.json +6 -0
  35. package/README.md +2 -2
  36. package/ResponsiveChartContainer/index.d.ts +1 -1
  37. package/ResponsiveChartContainer/index.js +22 -9
  38. package/ScatterChart/Scatter.d.ts +1 -1
  39. package/ScatterChart/Scatter.js +1 -1
  40. package/ScatterChart/ScatterChart.d.ts +1 -4
  41. package/ScatterChart/ScatterChart.js +6 -3
  42. package/ScatterChart/legend.d.ts +3 -0
  43. package/ScatterChart/legend.js +20 -0
  44. package/context/CartesianContextProvider.js +31 -20
  45. package/context/SeriesContextProvider.js +11 -1
  46. package/esm/BarChart/BarChart.js +4 -2
  47. package/esm/BarChart/BarPlot.js +44 -8
  48. package/esm/BarChart/legend.js +13 -0
  49. package/esm/ChartContainer/index.js +7 -5
  50. package/esm/ChartsAxisHighlight/ChartsAxisHighlight.js +3 -2
  51. package/esm/ChartsLegend/ChartsLegend.js +5 -1
  52. package/esm/ChartsLegend/utils.js +11 -1
  53. package/esm/ChartsTooltip/ChartsAxisTooltipContent.js +1 -1
  54. package/esm/ChartsTooltip/ChartsItemTooltipContent.js +11 -3
  55. package/esm/LineChart/LineChart.js +4 -2
  56. package/esm/LineChart/legend.js +13 -0
  57. package/esm/PieChart/PieArc.js +117 -0
  58. package/esm/PieChart/PieArcLabel.js +101 -0
  59. package/esm/PieChart/PieChart.js +285 -0
  60. package/esm/PieChart/PiePlot.js +92 -0
  61. package/esm/PieChart/formatter.js +48 -0
  62. package/esm/PieChart/index.js +4 -0
  63. package/esm/PieChart/legend.js +12 -0
  64. package/esm/ResponsiveChartContainer/index.js +20 -8
  65. package/esm/ScatterChart/Scatter.js +1 -1
  66. package/esm/ScatterChart/ScatterChart.js +4 -2
  67. package/esm/ScatterChart/legend.js +13 -0
  68. package/esm/context/CartesianContextProvider.js +31 -18
  69. package/esm/context/SeriesContextProvider.js +11 -1
  70. package/esm/hooks/index.js +2 -0
  71. package/esm/hooks/useAxisEvents.js +12 -7
  72. package/esm/hooks/useDrawingArea.js +16 -0
  73. package/esm/hooks/useScale.js +19 -21
  74. package/esm/hooks/useTicks.js +26 -13
  75. package/esm/index.js +2 -0
  76. package/esm/internals/defaultizeColor.js +7 -0
  77. package/esm/internals/getScale.js +17 -0
  78. package/esm/internals/isBandScale.js +3 -0
  79. package/esm/models/axis.js +6 -1
  80. package/esm/models/seriesType/index.js +1 -8
  81. package/hooks/index.d.ts +2 -0
  82. package/hooks/index.js +27 -0
  83. package/hooks/package.json +6 -0
  84. package/hooks/useAxisEvents.js +14 -9
  85. package/hooks/useDrawingArea.d.ts +6 -0
  86. package/hooks/useDrawingArea.js +24 -0
  87. package/hooks/useScale.d.ts +3 -6
  88. package/hooks/useScale.js +24 -24
  89. package/hooks/useTicks.d.ts +1 -1
  90. package/hooks/useTicks.js +19 -9
  91. package/index.d.ts +2 -0
  92. package/index.js +23 -1
  93. package/internals/defaultizeColor.d.ts +35 -0
  94. package/internals/defaultizeColor.js +7 -0
  95. package/internals/getScale.d.ts +2 -0
  96. package/internals/getScale.js +23 -0
  97. package/internals/isBandScale.d.ts +3 -0
  98. package/internals/isBandScale.js +9 -0
  99. package/legacy/BarChart/BarChart.js +4 -2
  100. package/legacy/BarChart/BarPlot.js +44 -10
  101. package/legacy/BarChart/legend.js +15 -0
  102. package/legacy/ChartContainer/index.js +7 -5
  103. package/legacy/ChartsAxisHighlight/ChartsAxisHighlight.js +3 -2
  104. package/legacy/ChartsLegend/ChartsLegend.js +5 -1
  105. package/legacy/ChartsLegend/utils.js +12 -6
  106. package/legacy/ChartsTooltip/ChartsAxisTooltipContent.js +3 -1
  107. package/legacy/ChartsTooltip/ChartsItemTooltipContent.js +10 -3
  108. package/legacy/LineChart/LineChart.js +4 -2
  109. package/legacy/LineChart/legend.js +15 -0
  110. package/legacy/PieChart/PieArc.js +118 -0
  111. package/legacy/PieChart/PieArcLabel.js +101 -0
  112. package/legacy/PieChart/PieChart.js +297 -0
  113. package/legacy/PieChart/PiePlot.js +89 -0
  114. package/legacy/PieChart/formatter.js +55 -0
  115. package/legacy/PieChart/index.js +4 -0
  116. package/legacy/PieChart/legend.js +16 -0
  117. package/legacy/ResponsiveChartContainer/index.js +18 -8
  118. package/legacy/ScatterChart/Scatter.js +1 -1
  119. package/legacy/ScatterChart/ScatterChart.js +4 -2
  120. package/legacy/ScatterChart/legend.js +15 -0
  121. package/legacy/context/CartesianContextProvider.js +31 -18
  122. package/legacy/context/SeriesContextProvider.js +11 -1
  123. package/legacy/hooks/index.js +2 -0
  124. package/legacy/hooks/useAxisEvents.js +12 -7
  125. package/legacy/hooks/useDrawingArea.js +17 -0
  126. package/legacy/hooks/useScale.js +17 -21
  127. package/legacy/hooks/useTicks.js +26 -13
  128. package/legacy/index.js +3 -1
  129. package/legacy/internals/defaultizeColor.js +9 -0
  130. package/legacy/internals/getScale.js +17 -0
  131. package/legacy/internals/isBandScale.js +3 -0
  132. package/legacy/models/axis.js +6 -1
  133. package/legacy/models/seriesType/index.js +1 -8
  134. package/models/axis.d.ts +25 -12
  135. package/models/axis.js +9 -1
  136. package/models/seriesType/bar.d.ts +1 -1
  137. package/models/seriesType/common.d.ts +1 -1
  138. package/models/seriesType/config.d.ts +29 -2
  139. package/models/seriesType/index.d.ts +7 -3
  140. package/models/seriesType/index.js +11 -0
  141. package/models/seriesType/line.d.ts +1 -1
  142. package/models/seriesType/pie.d.ts +103 -3
  143. package/models/seriesType/scatter.d.ts +1 -1
  144. package/modern/BarChart/BarChart.js +4 -2
  145. package/modern/BarChart/BarPlot.js +44 -8
  146. package/modern/BarChart/legend.js +13 -0
  147. package/modern/ChartContainer/index.js +7 -5
  148. package/modern/ChartsAxisHighlight/ChartsAxisHighlight.js +3 -2
  149. package/modern/ChartsLegend/ChartsLegend.js +5 -1
  150. package/modern/ChartsLegend/utils.js +11 -1
  151. package/modern/ChartsTooltip/ChartsAxisTooltipContent.js +1 -1
  152. package/modern/ChartsTooltip/ChartsItemTooltipContent.js +11 -2
  153. package/modern/LineChart/LineChart.js +4 -2
  154. package/modern/LineChart/legend.js +13 -0
  155. package/modern/PieChart/PieArc.js +116 -0
  156. package/modern/PieChart/PieArcLabel.js +101 -0
  157. package/modern/PieChart/PieChart.js +285 -0
  158. package/modern/PieChart/PiePlot.js +91 -0
  159. package/modern/PieChart/formatter.js +41 -0
  160. package/modern/PieChart/index.js +4 -0
  161. package/modern/PieChart/legend.js +12 -0
  162. package/modern/ResponsiveChartContainer/index.js +20 -8
  163. package/modern/ScatterChart/Scatter.js +1 -1
  164. package/modern/ScatterChart/ScatterChart.js +4 -2
  165. package/modern/ScatterChart/legend.js +13 -0
  166. package/modern/context/CartesianContextProvider.js +29 -18
  167. package/modern/context/SeriesContextProvider.js +11 -1
  168. package/modern/hooks/index.js +2 -0
  169. package/modern/hooks/useAxisEvents.js +12 -7
  170. package/modern/hooks/useDrawingArea.js +16 -0
  171. package/modern/hooks/useScale.js +19 -21
  172. package/modern/hooks/useTicks.js +18 -8
  173. package/modern/index.js +3 -1
  174. package/modern/internals/defaultizeColor.js +7 -0
  175. package/modern/internals/getScale.js +17 -0
  176. package/modern/internals/isBandScale.js +3 -0
  177. package/modern/models/axis.js +6 -1
  178. package/modern/models/seriesType/index.js +1 -8
  179. package/package.json +1 -1
@@ -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 { getScale } from '../hooks/useScale';
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,
@@ -74,24 +77,29 @@ function CartesianContextProvider({
74
77
  var _axis$scaleType, _axis$min, _axis$max, _axis$min2, _axis$max2;
75
78
  const isDefaultAxis = axisIndex === 0;
76
79
  const [minData, maxData] = getAxisExtremum(axis, xExtremumGetters, isDefaultAxis);
77
- const scaleType = (_axis$scaleType = axis.scaleType) != null ? _axis$scaleType : 'linear';
78
80
  const range = [drawingArea.left, drawingArea.left + drawingArea.width];
79
- if (scaleType === 'band') {
80
- completedXAxis[axis.id] = _extends({}, axis, {
81
- scaleType,
82
- scale: scaleBand(axis.data, range),
81
+ if (isBandScaleConfig(axis)) {
82
+ var _axis$categoryGapRati;
83
+ const categoryGapRatio = (_axis$categoryGapRati = axis.categoryGapRatio) != null ? _axis$categoryGapRati : DEFAULT_CATEGORY_GAP_RATIO;
84
+ completedXAxis[axis.id] = _extends({
85
+ categoryGapRatio,
86
+ barGapRatio: 0
87
+ }, axis, {
88
+ scale: scaleBand(axis.data, range).paddingInner(categoryGapRatio).paddingOuter(categoryGapRatio / 2),
83
89
  ticksNumber: axis.data.length
84
90
  });
85
- return;
86
91
  }
87
- if (scaleType === 'point') {
92
+ if (isPointScaleConfig(axis)) {
88
93
  completedXAxis[axis.id] = _extends({}, axis, {
89
- scaleType,
90
94
  scale: scalePoint(axis.data, range),
91
95
  ticksNumber: axis.data.length
92
96
  });
97
+ }
98
+ if (axis.scaleType === 'band' || axis.scaleType === 'point') {
99
+ // Could be merged with the two previous "if conditions" but then TS does not get that `axis.scaleType` can't be `band` or `point`.
93
100
  return;
94
101
  }
102
+ const scaleType = (_axis$scaleType = axis.scaleType) != null ? _axis$scaleType : 'linear';
95
103
  const extremums = [(_axis$min = axis.min) != null ? _axis$min : minData, (_axis$max = axis.max) != null ? _axis$max : maxData];
96
104
  const ticksNumber = getTicksNumber(_extends({}, axis, {
97
105
  range
@@ -119,23 +127,28 @@ function CartesianContextProvider({
119
127
  const isDefaultAxis = axisIndex === 0;
120
128
  const [minData, maxData] = getAxisExtremum(axis, yExtremumGetters, isDefaultAxis);
121
129
  const range = [drawingArea.top + drawingArea.height, drawingArea.top];
122
- const scaleType = (_axis$scaleType2 = axis.scaleType) != null ? _axis$scaleType2 : 'linear';
123
- if (scaleType === 'band') {
124
- completedYAxis[axis.id] = _extends({}, axis, {
125
- scaleType,
126
- scale: scaleBand(axis.data, range),
130
+ if (isBandScaleConfig(axis)) {
131
+ var _axis$categoryGapRati2;
132
+ const categoryGapRatio = (_axis$categoryGapRati2 = axis.categoryGapRatio) != null ? _axis$categoryGapRati2 : DEFAULT_CATEGORY_GAP_RATIO;
133
+ completedXAxis[axis.id] = _extends({
134
+ categoryGapRatio,
135
+ barGapRatio: 0
136
+ }, axis, {
137
+ scale: scaleBand(axis.data, range).paddingInner(categoryGapRatio).paddingOuter(categoryGapRatio / 2),
127
138
  ticksNumber: axis.data.length
128
139
  });
129
- return;
130
140
  }
131
- if (scaleType === 'point') {
132
- completedYAxis[axis.id] = _extends({}, axis, {
133
- scaleType,
141
+ if (isPointScaleConfig(axis)) {
142
+ completedXAxis[axis.id] = _extends({}, axis, {
134
143
  scale: scalePoint(axis.data, range),
135
144
  ticksNumber: axis.data.length
136
145
  });
146
+ }
147
+ if (axis.scaleType === 'band' || axis.scaleType === 'point') {
148
+ // Could be merged with the two previous "if conditions" but then TS does not get that `axis.scaleType` can't be `band` or `point`.
137
149
  return;
138
150
  }
151
+ const scaleType = (_axis$scaleType2 = axis.scaleType) != null ? _axis$scaleType2 : 'linear';
139
152
  const extremums = [(_axis$min3 = axis.min) != null ? _axis$min3 : minData, (_axis$max3 = axis.max) != null ? _axis$max3 : maxData];
140
153
  const ticksNumber = getTicksNumber(_extends({}, axis, {
141
154
  range
@@ -4,6 +4,7 @@ import { useTheme } from '@mui/material/styles';
4
4
  import barSeriesFormatter from '../BarChart/formatter';
5
5
  import scatterSeriesFormatter from '../ScatterChart/formatter';
6
6
  import lineSeriesFormatter from '../LineChart/formatter';
7
+ import pieSeriesFormatter from '../PieChart/formatter';
7
8
  import { defaultizeColor } from '../internals/defaultizeColor';
8
9
  import { blueberryTwilightPalette } from '../colorPalettes';
9
10
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -11,8 +12,17 @@ export const SeriesContext = /*#__PURE__*/React.createContext({});
11
12
  const seriesTypeFormatter = {
12
13
  bar: barSeriesFormatter,
13
14
  scatter: scatterSeriesFormatter,
14
- line: lineSeriesFormatter
15
+ line: lineSeriesFormatter,
16
+ pie: pieSeriesFormatter
15
17
  };
18
+ /**
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
+ * It also add defaultized values such as the ids, colors
22
+ * @param series The array of series provided by devs
23
+ * @param colors The color palette used to defaultize series colors
24
+ * @returns An object structuring all the series by type.
25
+ */
16
26
  const formatSeries = (series, colors) => {
17
27
  // Group series by type
18
28
  const seriesGroups = {};
@@ -0,0 +1,2 @@
1
+ export * from './useDrawingArea';
2
+ export * from './useScale';
@@ -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 './useScale';
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: event.offsetX,
114
- y: event.offsetY
118
+ x: svgPt.x,
119
+ y: svgPt.y
115
120
  };
116
- const outsideX = event.offsetX < left || event.offsetX > left + width;
117
- const outsideY = event.offsetY < top || event.offsetY > top + height;
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(event.offsetX);
129
- const newStateY = getUpdateY(event.offsetY);
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
+ }
@@ -1,24 +1,6 @@
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
- }
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 != null ? 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 != null ? identifier : 0];
30
+ return yAxis[id].scale;
33
31
  }
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { isBandScale } from './useScale';
2
+ import { isBandScale } from '../internals/isBandScale';
3
3
  export function getTicksNumber(params) {
4
4
  const {
5
5
  maxTicks = 999,
@@ -20,23 +20,36 @@ function useTicks(options) {
20
20
  // band scale
21
21
  if (isBandScale(scale)) {
22
22
  const domain = scale.domain();
23
- return [...domain.map(value => {
24
- var _valueFormatter, _scale;
23
+ if (scale.bandwidth() > 0) {
24
+ // scale type = 'band'
25
+ return [...domain.map((value, index) => {
26
+ var _valueFormatter;
27
+ return {
28
+ formattedValue: (_valueFormatter = valueFormatter == null ? void 0 : valueFormatter(value)) != null ? _valueFormatter : value,
29
+ offset: index === 0 ? scale.range()[0] : scale(value) - (scale.step() - scale.bandwidth()) / 2,
30
+ labelOffset: scale.step() / 2
31
+ };
32
+ }), {
33
+ formattedValue: undefined,
34
+ offset: scale.range()[1],
35
+ labelOffset: 0
36
+ }];
37
+ }
38
+
39
+ // scale type = 'point'
40
+ return domain.map(value => {
41
+ var _valueFormatter2;
25
42
  return {
26
- formattedValue: (_valueFormatter = valueFormatter == null ? void 0 : valueFormatter(value)) != null ? _valueFormatter : value,
27
- offset: (_scale = scale(value)) != null ? _scale : 0,
28
- labelOffset: scale.bandwidth() / 2
43
+ formattedValue: (_valueFormatter2 = valueFormatter == null ? void 0 : valueFormatter(value)) != null ? _valueFormatter2 : value,
44
+ offset: scale(value),
45
+ labelOffset: 0
29
46
  };
30
- }), ...(scale.bandwidth() > 0 ? [{
31
- formattedValue: undefined,
32
- offset: scale.range()[1],
33
- labelOffset: 0
34
- }] : [])];
47
+ });
35
48
  }
36
49
  return scale.ticks(ticksNumber).map(value => {
37
- var _valueFormatter2;
50
+ var _valueFormatter3;
38
51
  return {
39
- formattedValue: (_valueFormatter2 = valueFormatter == null ? void 0 : valueFormatter(value)) != null ? _valueFormatter2 : scale.tickFormat(ticksNumber)(value),
52
+ formattedValue: (_valueFormatter3 = valueFormatter == null ? void 0 : valueFormatter(value)) != null ? _valueFormatter3 : scale.tickFormat(ticksNumber)(value),
40
53
  offset: scale(value),
41
54
  labelOffset: 0
42
55
  };
package/esm/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './constants';
2
2
  export * from './context';
3
+ export * from './hooks';
3
4
  export * from './colorPalettes';
4
5
  export * from './models';
5
6
  export * from './ChartsClipPath';
@@ -10,6 +11,7 @@ export * from './ChartsTooltip';
10
11
  export * from './ChartsAxisHighlight';
11
12
  export * from './BarChart';
12
13
  export * from './LineChart';
14
+ export * from './PieChart';
13
15
  export * from './ScatterChart';
14
16
  export * from './ChartContainer';
15
17
  export * from './ResponsiveChartContainer';
@@ -1,6 +1,13 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  const DEFAULT_COLORS = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf'];
3
3
  export function defaultizeColor(series, seriesIndex, colors = DEFAULT_COLORS) {
4
+ if (series.type === 'pie') {
5
+ return _extends({}, series, {
6
+ data: series.data.map((d, index) => _extends({
7
+ color: colors[index % colors.length]
8
+ }, d))
9
+ });
10
+ }
4
11
  return _extends({
5
12
  color: colors[seriesIndex % colors.length]
6
13
  }, series);
@@ -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
+ }
@@ -0,0 +1,3 @@
1
+ export function isBandScale(scale) {
2
+ return scale.bandwidth !== undefined;
3
+ }
@@ -1 +1,6 @@
1
- export {};
1
+ export function isBandScaleConfig(scaleConfig) {
2
+ return scaleConfig.scaleType === 'band';
3
+ }
4
+ export function isPointScaleConfig(scaleConfig) {
5
+ return scaleConfig.scaleType === 'point';
6
+ }
@@ -1,12 +1,5 @@
1
- // import { PieSeriesType } from './pie';
2
-
3
- // | PieSeriesType;
4
-
5
- // | PieSeriesType;
6
-
7
- // | PieSeriesType
8
-
9
1
  export * from './line';
10
2
  export * from './bar';
11
3
  export * from './scatter';
4
+ export * from './pie';
12
5
  export {};
@@ -0,0 +1,2 @@
1
+ export * from './useDrawingArea';
2
+ export * from './useScale';
package/hooks/index.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _useDrawingArea = require("./useDrawingArea");
7
+ Object.keys(_useDrawingArea).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _useDrawingArea[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _useDrawingArea[key];
14
+ }
15
+ });
16
+ });
17
+ var _useScale = require("./useScale");
18
+ Object.keys(_useScale).forEach(function (key) {
19
+ if (key === "default" || key === "__esModule") return;
20
+ if (key in exports && exports[key] === _useScale[key]) return;
21
+ Object.defineProperty(exports, key, {
22
+ enumerable: true,
23
+ get: function () {
24
+ return _useScale[key];
25
+ }
26
+ });
27
+ });
@@ -0,0 +1,6 @@
1
+ {
2
+ "sideEffects": false,
3
+ "module": "../esm/hooks/index.js",
4
+ "main": "./index.js",
5
+ "types": "./index.d.ts"
6
+ }
@@ -8,7 +8,7 @@ var React = _interopRequireWildcard(require("react"));
8
8
  var _InteractionProvider = require("../context/InteractionProvider");
9
9
  var _CartesianContextProvider = require("../context/CartesianContextProvider");
10
10
  var _DrawingProvider = require("../context/DrawingProvider");
11
- var _useScale = require("./useScale");
11
+ var _isBandScale = require("../internals/isBandScale");
12
12
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
13
13
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
14
14
  const useAxisEvents = disableAxisListener => {
@@ -49,7 +49,7 @@ const useAxisEvents = disableAxisListener => {
49
49
  scale: yScale,
50
50
  data: yAxisData
51
51
  } = yAxis[usedYAxis];
52
- if (!(0, _useScale.isBandScale)(yScale)) {
52
+ if (!(0, _isBandScale.isBandScale)(yScale)) {
53
53
  return {
54
54
  value: yScale.invert(y)
55
55
  };
@@ -71,7 +71,7 @@ const useAxisEvents = disableAxisListener => {
71
71
  scale: xScale,
72
72
  data: xAxisData
73
73
  } = xAxis[usedXAxis];
74
- if (!(0, _useScale.isBandScale)(xScale)) {
74
+ if (!(0, _isBandScale.isBandScale)(xScale)) {
75
75
  const value = xScale.invert(x);
76
76
  const closestIndex = xAxisData?.findIndex((v, index) => {
77
77
  if (v > value) {
@@ -117,12 +117,17 @@ const useAxisEvents = disableAxisListener => {
117
117
  });
118
118
  };
119
119
  const handleMouseMove = event => {
120
+ // Get mouse coordinate in global SVG space
121
+ const pt = svgRef.current.createSVGPoint();
122
+ pt.x = event.clientX;
123
+ pt.y = event.clientY;
124
+ const svgPt = pt.matrixTransform(svgRef.current.getScreenCTM().inverse());
120
125
  mousePosition.current = {
121
- x: event.offsetX,
122
- y: event.offsetY
126
+ x: svgPt.x,
127
+ y: svgPt.y
123
128
  };
124
- const outsideX = event.offsetX < left || event.offsetX > left + width;
125
- const outsideY = event.offsetY < top || event.offsetY > top + height;
129
+ const outsideX = svgPt.x < left || svgPt.x > left + width;
130
+ const outsideY = svgPt.y < top || svgPt.y > top + height;
126
131
  if (outsideX || outsideY) {
127
132
  dispatch({
128
133
  type: 'updateAxis',
@@ -133,8 +138,8 @@ const useAxisEvents = disableAxisListener => {
133
138
  });
134
139
  return;
135
140
  }
136
- const newStateX = getUpdateX(event.offsetX);
137
- const newStateY = getUpdateY(event.offsetY);
141
+ const newStateX = getUpdateX(svgPt.x);
142
+ const newStateY = getUpdateY(svgPt.y);
138
143
  dispatch({
139
144
  type: 'updateAxis',
140
145
  data: {
@@ -0,0 +1,6 @@
1
+ export declare function useDrawingArea(): {
2
+ left: number;
3
+ top: number;
4
+ width: number;
5
+ height: number;
6
+ };
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useDrawingArea = useDrawingArea;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _DrawingProvider = require("../context/DrawingProvider");
9
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
10
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
11
+ function useDrawingArea() {
12
+ const {
13
+ left,
14
+ top,
15
+ width,
16
+ height
17
+ } = React.useContext(_DrawingProvider.DrawingContext);
18
+ return React.useMemo(() => ({
19
+ left,
20
+ top,
21
+ width,
22
+ height
23
+ }), [height, left, top, width]);
24
+ }
@@ -1,9 +1,4 @@
1
- import type { ScaleBand, ScaleLogarithmic, ScalePoint, ScalePower, ScaleTime, ScaleLinear } from 'd3-scale';
2
- import { ContinuouseScaleName } from '../models/axis';
3
- export type D3Scale = ScaleBand<any> | ScaleLogarithmic<any, any> | ScalePoint<any> | ScalePower<any, any> | ScaleTime<any, any> | ScaleLinear<any, any>;
4
- export type D3ContinuouseScale = ScaleLogarithmic<any, any> | ScalePower<any, any> | ScaleTime<any, any> | ScaleLinear<any, any>;
5
- export declare function getScale(scaleType: ContinuouseScaleName, domain: any[], range: any[]): D3ContinuouseScale;
6
- export declare function isBandScale(scale: D3Scale): scale is ScaleBand<any> | ScalePoint<any>;
1
+ import { D3Scale } from '../models/axis';
7
2
  /**
8
3
  * For a given scale return a function that map value to their position.
9
4
  * Usefull when dealing with specific scale such as band.
@@ -11,3 +6,5 @@ export declare function isBandScale(scale: D3Scale): scale is ScaleBand<any> | S
11
6
  * @returns (value: any) => number
12
7
  */
13
8
  export declare function getValueToPositionMapper(scale: D3Scale): (value: any) => number;
9
+ export declare function useXScale(identifier?: number | string): import("d3-scale").ScaleBand<any> | import("d3-scale").ScalePoint<any> | import("d3-scale").ScaleLogarithmic<any, any, never> | import("d3-scale").ScalePower<any, any, never> | import("d3-scale").ScaleTime<any, any, never> | import("d3-scale").ScaleLinear<any, any, never>;
10
+ export declare function useYScale(identifier?: number | string): import("d3-scale").ScaleBand<any> | import("d3-scale").ScalePoint<any> | import("d3-scale").ScaleLogarithmic<any, any, never> | import("d3-scale").ScalePower<any, any, never> | import("d3-scale").ScaleTime<any, any, never> | import("d3-scale").ScaleLinear<any, any, never>;
package/hooks/useScale.js CHANGED
@@ -3,30 +3,14 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getScale = getScale;
7
6
  exports.getValueToPositionMapper = getValueToPositionMapper;
8
- exports.isBandScale = isBandScale;
9
- var _d3Scale = require("d3-scale");
10
- function getScale(scaleType, domain, range) {
11
- switch (scaleType) {
12
- case 'log':
13
- return (0, _d3Scale.scaleLog)(domain, range);
14
- case 'pow':
15
- return (0, _d3Scale.scalePow)(domain, range);
16
- case 'sqrt':
17
- return (0, _d3Scale.scaleSqrt)(domain, range);
18
- case 'time':
19
- return (0, _d3Scale.scaleTime)(domain, range);
20
- case 'utc':
21
- return (0, _d3Scale.scaleUtc)(domain, range);
22
- default:
23
- return (0, _d3Scale.scaleLinear)(domain, range);
24
- }
25
- }
26
- function isBandScale(scale) {
27
- return scale.bandwidth !== undefined;
28
- }
29
-
7
+ exports.useXScale = useXScale;
8
+ exports.useYScale = useYScale;
9
+ var React = _interopRequireWildcard(require("react"));
10
+ var _CartesianContextProvider = require("../context/CartesianContextProvider");
11
+ var _isBandScale = require("../internals/isBandScale");
12
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
13
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
30
14
  /**
31
15
  * For a given scale return a function that map value to their position.
32
16
  * Usefull when dealing with specific scale such as band.
@@ -34,8 +18,24 @@ function isBandScale(scale) {
34
18
  * @returns (value: any) => number
35
19
  */
36
20
  function getValueToPositionMapper(scale) {
37
- if (isBandScale(scale)) {
21
+ if ((0, _isBandScale.isBandScale)(scale)) {
38
22
  return value => scale(value) + scale.bandwidth() / 2;
39
23
  }
40
24
  return value => scale(value);
25
+ }
26
+ function useXScale(identifier) {
27
+ const {
28
+ xAxis,
29
+ xAxisIds
30
+ } = React.useContext(_CartesianContextProvider.CartesianContext);
31
+ const id = typeof identifier === 'string' ? identifier : xAxisIds[identifier ?? 0];
32
+ return xAxis[id].scale;
33
+ }
34
+ function useYScale(identifier) {
35
+ const {
36
+ yAxis,
37
+ yAxisIds
38
+ } = React.useContext(_CartesianContextProvider.CartesianContext);
39
+ const id = typeof identifier === 'string' ? identifier : yAxisIds[identifier ?? 0];
40
+ return yAxis[id].scale;
41
41
  }
@@ -1,4 +1,4 @@
1
- import { D3Scale } from './useScale';
1
+ import { D3Scale } from '../models/axis';
2
2
  export type TickParams = {
3
3
  maxTicks?: number;
4
4
  minTicks?: number;
package/hooks/useTicks.js CHANGED
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  exports.getTicksNumber = getTicksNumber;
8
8
  var React = _interopRequireWildcard(require("react"));
9
- var _useScale = require("./useScale");
9
+ var _isBandScale = require("../internals/isBandScale");
10
10
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
11
11
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
12
12
  function getTicksNumber(params) {
@@ -27,17 +27,27 @@ function useTicks(options) {
27
27
  } = options;
28
28
  return React.useMemo(() => {
29
29
  // band scale
30
- if ((0, _useScale.isBandScale)(scale)) {
30
+ if ((0, _isBandScale.isBandScale)(scale)) {
31
31
  const domain = scale.domain();
32
- return [...domain.map(value => ({
32
+ if (scale.bandwidth() > 0) {
33
+ // scale type = 'band'
34
+ return [...domain.map((value, index) => ({
35
+ formattedValue: valueFormatter?.(value) ?? value,
36
+ offset: index === 0 ? scale.range()[0] : scale(value) - (scale.step() - scale.bandwidth()) / 2,
37
+ labelOffset: scale.step() / 2
38
+ })), {
39
+ formattedValue: undefined,
40
+ offset: scale.range()[1],
41
+ labelOffset: 0
42
+ }];
43
+ }
44
+
45
+ // scale type = 'point'
46
+ return domain.map(value => ({
33
47
  formattedValue: valueFormatter?.(value) ?? value,
34
- offset: scale(value) ?? 0,
35
- labelOffset: scale.bandwidth() / 2
36
- })), ...(scale.bandwidth() > 0 ? [{
37
- formattedValue: undefined,
38
- offset: scale.range()[1],
48
+ offset: scale(value),
39
49
  labelOffset: 0
40
- }] : [])];
50
+ }));
41
51
  }
42
52
  return scale.ticks(ticksNumber).map(value => ({
43
53
  formattedValue: valueFormatter?.(value) ?? scale.tickFormat(ticksNumber)(value),