@mui/x-charts-premium 9.0.3 → 9.1.0

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/BarChartPremium/BarChartPremium.js +2 -1183
  2. package/BarChartPremium/BarChartPremium.mjs +2 -1183
  3. package/BarChartPremium/RangeBar/FocusedRangeBar.js +3 -0
  4. package/BarChartPremium/RangeBar/FocusedRangeBar.mjs +3 -0
  5. package/BarChartPremium/RangeBar/seriesConfig/seriesProcessor.js +2 -0
  6. package/BarChartPremium/RangeBar/seriesConfig/seriesProcessor.mjs +2 -0
  7. package/CHANGELOG.md +220 -0
  8. package/CandlestickChart/CandlestickChart.d.mts +2 -2
  9. package/CandlestickChart/CandlestickChart.d.ts +2 -2
  10. package/CandlestickChart/CandlestickChart.js +2 -1183
  11. package/CandlestickChart/CandlestickChart.mjs +2 -1183
  12. package/CandlestickChart/CandlestickWebGLProgram.d.mts +6 -11
  13. package/CandlestickChart/CandlestickWebGLProgram.d.ts +6 -11
  14. package/CandlestickChart/CandlestickWebGLProgram.js +136 -121
  15. package/CandlestickChart/CandlestickWebGLProgram.mjs +137 -122
  16. package/CandlestickChart/useCandlestickPlotData.d.mts +2 -2
  17. package/CandlestickChart/useCandlestickPlotData.d.ts +2 -2
  18. package/CandlestickChart/useCandlestickPlotData.js +121 -61
  19. package/CandlestickChart/useCandlestickPlotData.mjs +122 -61
  20. package/ChartsAxisHighlightValue/index.d.mts +1 -0
  21. package/ChartsAxisHighlightValue/index.d.ts +1 -0
  22. package/ChartsAxisHighlightValue/index.js +16 -0
  23. package/ChartsAxisHighlightValue/index.mjs +2 -0
  24. package/ChartsDataProviderPremium/ChartsDataProviderPremium.js +2 -2
  25. package/ChartsDataProviderPremium/ChartsDataProviderPremium.mjs +2 -2
  26. package/ChartsRadialAxisHighlight/index.d.mts +1 -0
  27. package/ChartsRadialAxisHighlight/index.d.ts +1 -0
  28. package/ChartsRadialAxisHighlight/index.js +16 -0
  29. package/ChartsRadialAxisHighlight/index.mjs +2 -0
  30. package/ChartsRadialDataProviderPremium/ChartsRadialDataProviderPremium.js +2 -2
  31. package/ChartsRadialDataProviderPremium/ChartsRadialDataProviderPremium.mjs +2 -2
  32. package/HeatmapPremium/HeatmapPremium.js +2 -155
  33. package/HeatmapPremium/HeatmapPremium.mjs +2 -155
  34. package/HeatmapPremium/webgl/HeatmapWebGLPlot.js +19 -112
  35. package/HeatmapPremium/webgl/HeatmapWebGLPlot.mjs +19 -111
  36. package/HeatmapPremium/webgl/HeatmapWebGLProgram.d.mts +24 -0
  37. package/HeatmapPremium/webgl/HeatmapWebGLProgram.d.ts +24 -0
  38. package/HeatmapPremium/webgl/HeatmapWebGLProgram.js +132 -0
  39. package/HeatmapPremium/webgl/HeatmapWebGLProgram.mjs +125 -0
  40. package/HeatmapPremium/webgl/shaders.d.mts +1 -1
  41. package/HeatmapPremium/webgl/shaders.d.ts +1 -1
  42. package/HeatmapPremium/webgl/shaders.js +1 -1
  43. package/HeatmapPremium/webgl/shaders.mjs +1 -1
  44. package/HeatmapPremium/webgl/useHeatmapPlotData.d.mts +3 -3
  45. package/HeatmapPremium/webgl/useHeatmapPlotData.d.ts +3 -3
  46. package/HeatmapPremium/webgl/useHeatmapPlotData.js +78 -26
  47. package/HeatmapPremium/webgl/useHeatmapPlotData.mjs +80 -26
  48. package/LICENSE +3 -1
  49. package/RadialBarChart/RadialBarChart.d.mts +60 -0
  50. package/RadialBarChart/RadialBarChart.d.ts +60 -0
  51. package/RadialBarChart/RadialBarChart.js +298 -0
  52. package/RadialBarChart/RadialBarChart.mjs +292 -0
  53. package/RadialBarChart/RadialBarChart.plugins.d.mts +4 -0
  54. package/RadialBarChart/RadialBarChart.plugins.d.ts +4 -0
  55. package/RadialBarChart/RadialBarChart.plugins.js +9 -0
  56. package/RadialBarChart/RadialBarChart.plugins.mjs +3 -0
  57. package/RadialBarChart/RadialBarElement.d.mts +16 -0
  58. package/RadialBarChart/RadialBarElement.d.ts +16 -0
  59. package/RadialBarChart/RadialBarElement.js +54 -0
  60. package/RadialBarChart/RadialBarElement.mjs +48 -0
  61. package/RadialBarChart/RadialBarPlot.d.mts +21 -0
  62. package/RadialBarChart/RadialBarPlot.d.ts +21 -0
  63. package/RadialBarChart/RadialBarPlot.js +85 -0
  64. package/RadialBarChart/RadialBarPlot.mjs +79 -0
  65. package/RadialBarChart/index.d.mts +3 -0
  66. package/RadialBarChart/index.d.ts +3 -0
  67. package/RadialBarChart/index.js +39 -0
  68. package/RadialBarChart/index.mjs +3 -0
  69. package/RadialBarChart/radialBarClasses.d.mts +15 -0
  70. package/RadialBarChart/radialBarClasses.d.ts +15 -0
  71. package/RadialBarChart/radialBarClasses.js +26 -0
  72. package/RadialBarChart/radialBarClasses.mjs +18 -0
  73. package/RadialBarChart/seriesConfig/seriesProcessor.js +4 -0
  74. package/RadialBarChart/seriesConfig/seriesProcessor.mjs +4 -0
  75. package/RadialBarChart/useRadialBarChartProps.d.mts +28 -0
  76. package/RadialBarChart/useRadialBarChartProps.d.ts +28 -0
  77. package/RadialBarChart/useRadialBarChartProps.js +100 -0
  78. package/RadialBarChart/useRadialBarChartProps.mjs +93 -0
  79. package/RadialBarChart/useRadialBarPlotData.d.mts +23 -0
  80. package/RadialBarChart/useRadialBarPlotData.d.ts +23 -0
  81. package/RadialBarChart/useRadialBarPlotData.js +94 -0
  82. package/RadialBarChart/useRadialBarPlotData.mjs +87 -0
  83. package/RadialLineChart/RadialArea.js +13 -1
  84. package/RadialLineChart/RadialArea.mjs +13 -1
  85. package/RadialLineChart/RadialLine.js +13 -1
  86. package/RadialLineChart/RadialLine.mjs +13 -1
  87. package/RadialLineChart/RadialLineChart.d.mts +11 -3
  88. package/RadialLineChart/RadialLineChart.d.ts +11 -3
  89. package/RadialLineChart/RadialLineChart.js +24 -673
  90. package/RadialLineChart/RadialLineChart.mjs +24 -673
  91. package/RadialLineChart/RadialLineHighlightElement.d.mts +15 -0
  92. package/RadialLineChart/RadialLineHighlightElement.d.ts +15 -0
  93. package/RadialLineChart/RadialLineHighlightElement.js +46 -0
  94. package/RadialLineChart/RadialLineHighlightElement.mjs +39 -0
  95. package/RadialLineChart/RadialLineHighlightPlot.d.mts +23 -0
  96. package/RadialLineChart/RadialLineHighlightPlot.d.ts +23 -0
  97. package/RadialLineChart/RadialLineHighlightPlot.js +92 -0
  98. package/RadialLineChart/RadialLineHighlightPlot.mjs +86 -0
  99. package/RadialLineChart/RadialMarkPlot.js +32 -3
  100. package/RadialLineChart/RadialMarkPlot.mjs +32 -3
  101. package/RadialLineChart/index.d.mts +3 -1
  102. package/RadialLineChart/index.d.ts +3 -1
  103. package/RadialLineChart/index.js +22 -0
  104. package/RadialLineChart/index.mjs +3 -1
  105. package/RadialLineChart/radialLineClasses.d.mts +3 -1
  106. package/RadialLineChart/radialLineClasses.d.ts +3 -1
  107. package/RadialLineChart/radialLineClasses.js +2 -1
  108. package/RadialLineChart/radialLineClasses.mjs +2 -1
  109. package/RadialLineChart/seriesConfig/getItemAtPosition.d.mts +6 -0
  110. package/RadialLineChart/seriesConfig/getItemAtPosition.d.ts +6 -0
  111. package/RadialLineChart/seriesConfig/getItemAtPosition.js +353 -0
  112. package/RadialLineChart/seriesConfig/getItemAtPosition.mjs +348 -0
  113. package/RadialLineChart/seriesConfig/getSeriesWithDefaultValues.js +2 -1
  114. package/RadialLineChart/seriesConfig/getSeriesWithDefaultValues.mjs +2 -1
  115. package/RadialLineChart/seriesConfig/index.js +2 -1
  116. package/RadialLineChart/seriesConfig/index.mjs +2 -1
  117. package/RadialLineChart/seriesConfig/seriesProcessor.js +4 -0
  118. package/RadialLineChart/seriesConfig/seriesProcessor.mjs +4 -0
  119. package/RadialLineChart/useRadialLineChartProps.d.mts +2 -0
  120. package/RadialLineChart/useRadialLineChartProps.d.ts +2 -0
  121. package/RadialLineChart/useRadialLineChartProps.js +16 -8
  122. package/RadialLineChart/useRadialLineChartProps.mjs +16 -8
  123. package/RadialLineChart/useRadialLinePlotData.d.mts +3 -1
  124. package/RadialLineChart/useRadialLinePlotData.d.ts +3 -1
  125. package/RadialLineChart/useRadialLinePlotData.js +5 -1
  126. package/RadialLineChart/useRadialLinePlotData.mjs +6 -2
  127. package/ScatterChartPremium/ScatterChartPremium.d.mts +25 -0
  128. package/ScatterChartPremium/ScatterChartPremium.d.ts +25 -0
  129. package/ScatterChartPremium/ScatterChartPremium.js +507 -0
  130. package/ScatterChartPremium/ScatterChartPremium.mjs +501 -0
  131. package/ScatterChartPremium/ScatterChartPremium.plugins.d.mts +3 -0
  132. package/ScatterChartPremium/ScatterChartPremium.plugins.d.ts +3 -0
  133. package/ScatterChartPremium/ScatterChartPremium.plugins.js +8 -0
  134. package/ScatterChartPremium/ScatterChartPremium.plugins.mjs +2 -0
  135. package/ScatterChartPremium/ScatterPlotPremium.d.mts +14 -0
  136. package/ScatterChartPremium/ScatterPlotPremium.d.ts +14 -0
  137. package/ScatterChartPremium/ScatterPlotPremium.js +28 -0
  138. package/ScatterChartPremium/ScatterPlotPremium.mjs +21 -0
  139. package/ScatterChartPremium/index.d.mts +3 -0
  140. package/ScatterChartPremium/index.d.ts +3 -0
  141. package/ScatterChartPremium/index.js +26 -0
  142. package/ScatterChartPremium/index.mjs +3 -0
  143. package/ScatterChartPremium/webgl/ScatterWebGLPlot.d.mts +4 -0
  144. package/ScatterChartPremium/webgl/ScatterWebGLPlot.d.ts +4 -0
  145. package/ScatterChartPremium/webgl/ScatterWebGLPlot.js +70 -0
  146. package/ScatterChartPremium/webgl/ScatterWebGLPlot.mjs +65 -0
  147. package/ScatterChartPremium/webgl/ScatterWebGLProgram.d.mts +18 -0
  148. package/ScatterChartPremium/webgl/ScatterWebGLProgram.d.ts +18 -0
  149. package/ScatterChartPremium/webgl/ScatterWebGLProgram.js +129 -0
  150. package/ScatterChartPremium/webgl/ScatterWebGLProgram.mjs +122 -0
  151. package/ScatterChartPremium/webgl/shaders.d.mts +2 -0
  152. package/ScatterChartPremium/webgl/shaders.d.ts +2 -0
  153. package/ScatterChartPremium/webgl/shaders.js +57 -0
  154. package/ScatterChartPremium/webgl/shaders.mjs +51 -0
  155. package/ScatterChartPremium/webgl/useScatterWebGLPlotData.d.mts +7 -0
  156. package/ScatterChartPremium/webgl/useScatterWebGLPlotData.d.ts +7 -0
  157. package/ScatterChartPremium/webgl/useScatterWebGLPlotData.js +140 -0
  158. package/ScatterChartPremium/webgl/useScatterWebGLPlotData.mjs +134 -0
  159. package/index.d.mts +3 -1
  160. package/index.d.ts +3 -1
  161. package/index.js +25 -1
  162. package/index.mjs +4 -2
  163. package/internals/index.d.mts +1 -0
  164. package/internals/index.d.ts +1 -0
  165. package/internals/index.js +13 -0
  166. package/internals/index.mjs +1 -0
  167. package/models/seriesType/radialLine.d.mts +7 -1
  168. package/models/seriesType/radialLine.d.ts +7 -1
  169. package/package.json +185 -115
  170. package/plugins/selectors/useChartCandlestickPosition.selectors.d.mts +1 -1
  171. package/plugins/selectors/useChartCandlestickPosition.selectors.d.ts +1 -1
  172. package/utils/webgl/parseColor.d.mts +2 -1
  173. package/utils/webgl/parseColor.d.ts +2 -1
  174. package/utils/webgl/parseColor.js +8 -7
  175. package/utils/webgl/parseColor.mjs +8 -7
  176. package/utils/webgl/utils.d.mts +13 -0
  177. package/utils/webgl/utils.d.ts +13 -0
  178. package/utils/webgl/utils.js +29 -0
  179. package/utils/webgl/utils.mjs +27 -0
@@ -5,10 +5,10 @@ import type { DefaultizedOHLCSeriesType } from "../models/index.mjs";
5
5
  export interface CandlestickPlotData {
6
6
  candleCenters: Float32Array;
7
7
  candleHeights: Float32Array;
8
- candleColors: Float32Array;
8
+ candleColors: Uint8ClampedArray;
9
9
  wickCenters: Float32Array;
10
10
  wickHeights: Float32Array;
11
- wickColors: Float32Array;
11
+ wickColors: Uint8ClampedArray;
12
12
  }
13
13
  export declare function useCandlestickPlotData(drawingArea: ChartDrawingArea, series: DefaultizedOHLCSeriesType, xScale: ScaleBand<{
14
14
  toString(): string;
@@ -5,10 +5,10 @@ import type { DefaultizedOHLCSeriesType } from "../models/index.js";
5
5
  export interface CandlestickPlotData {
6
6
  candleCenters: Float32Array;
7
7
  candleHeights: Float32Array;
8
- candleColors: Float32Array;
8
+ candleColors: Uint8ClampedArray;
9
9
  wickCenters: Float32Array;
10
10
  wickHeights: Float32Array;
11
- wickColors: Float32Array;
11
+ wickColors: Uint8ClampedArray;
12
12
  }
13
13
  export declare function useCandlestickPlotData(drawingArea: ChartDrawingArea, series: DefaultizedOHLCSeriesType, xScale: ScaleBand<{
14
14
  toString(): string;
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ 'use client';
2
3
 
3
4
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
5
  var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
@@ -13,54 +14,37 @@ var _parseColor = require("../utils/webgl/parseColor");
13
14
  var _getColor = _interopRequireDefault(require("./seriesConfig/getColor"));
14
15
  const FADE_OPACITY = 0.3;
15
16
  const HIGHLIGHT_BRIGHTNESS = 1.2;
17
+ function ensurePoolFloat32(pool, n) {
18
+ if (pool && pool.length >= n) {
19
+ return pool;
20
+ }
21
+ return new Float32Array(n);
22
+ }
16
23
  function useCandlestickPlotData(drawingArea, series, xScale, yScale) {
17
24
  const theme = (0, _styles.useTheme)();
18
25
  const store = (0, _internals.useStore)();
19
26
  const getHighlightState = store.use(_internals.selectorChartsHighlightStateCallback);
20
27
  const wickColor = React.useMemo(() => (0, _parseColor.parseColor)(theme.palette.text.primary), [theme.palette.text.primary]);
21
28
  const colorGetter = React.useMemo(() => (0, _getColor.default)(series, undefined), [series]);
22
- return React.useMemo(() => {
23
- const candleCenters = new Float32Array(series.data.length * 2);
24
- const candleHeights = new Float32Array(series.data.length);
25
- // Two wicks per candle: upper (candle top → high) and lower (candle bottom → low)
26
- const wickCenters = new Float32Array(series.data.length * 2 * 2);
27
- const wickHeights = new Float32Array(series.data.length * 2);
28
- const candleColors = new Float32Array(series.data.length * 4);
29
- const wickColors = new Float32Array(series.data.length * 2 * 4);
30
- const xDomain = xScale.domain();
29
+
30
+ /* Colors only change when the series, color getter, or highlight state changes.
31
+ * Cache them so zoom-only renders return the same Uint8ClampedArray refs and the
32
+ * GL upload short-circuit can skip re-uploading colors.
33
+ * `parseColor` returns bytes in [0, 255]. Uint8Clamped rounds + clamps automatically,
34
+ * so brightness multiplications can't overflow. */
35
+ const colors = React.useMemo(() => {
36
+ const candleColors = new Uint8ClampedArray(series.data.length * 4);
37
+ const wickColors = new Uint8ClampedArray(series.data.length * 2 * 4);
38
+ const [wickR, wickG, wickB, wickA] = wickColor;
31
39
  for (let dataIndex = 0; dataIndex < series.data.length; dataIndex += 1) {
32
40
  const datum = series.data[dataIndex];
33
41
  if (datum === null) {
34
- // Set alpha to 0 to hide the candle and both wicks
35
- candleColors[dataIndex * 4 + 3] = 0.0;
36
- wickColors[dataIndex * 2 * 4 + 3] = 0.0;
37
- wickColors[(dataIndex * 2 + 1) * 4 + 3] = 0.0;
42
+ /* Alpha 0 hides the candle and both wicks; src-alpha blending makes RGB irrelevant. */
43
+ candleColors[dataIndex * 4 + 3] = 0;
44
+ wickColors[dataIndex * 2 * 4 + 3] = 0;
45
+ wickColors[(dataIndex * 2 + 1) * 4 + 3] = 0;
38
46
  continue;
39
47
  }
40
-
41
- // Can't return undefined because we're calling it with a value from the domain
42
- const scaledX = xScale(xDomain[dataIndex]);
43
- const [open, high, low, close] = datum;
44
- const x = scaledX - drawingArea.left;
45
- const scaledOpen = yScale(open);
46
- const scaledClose = yScale(close);
47
- const candleBottom = Math.min(scaledOpen, scaledClose) - drawingArea.top;
48
- const candleTop = Math.max(scaledOpen, scaledClose) - drawingArea.top;
49
- const wickBottom = yScale(low) - drawingArea.top;
50
- const wickTop = yScale(high) - drawingArea.top;
51
- candleCenters[dataIndex * 2] = x;
52
- candleCenters[dataIndex * 2 + 1] = (candleTop + candleBottom) / 2;
53
- candleHeights[dataIndex] = candleTop - candleBottom;
54
-
55
- // We have two wicks per candle so that when a candle is faded the wick isn't visible behind the candle body.
56
- const upperWickIndex = dataIndex * 2;
57
- wickCenters[upperWickIndex * 2] = x;
58
- wickCenters[upperWickIndex * 2 + 1] = (wickTop + candleBottom) / 2;
59
- wickHeights[upperWickIndex] = wickTop - candleBottom;
60
- const lowerWickIndex = dataIndex * 2 + 1;
61
- wickCenters[lowerWickIndex * 2] = x;
62
- wickCenters[lowerWickIndex * 2 + 1] = (candleTop + wickBottom) / 2;
63
- wickHeights[lowerWickIndex] = candleTop - wickBottom;
64
48
  const candleColor = (0, _parseColor.parseColor)(colorGetter(dataIndex));
65
49
  candleColors[dataIndex * 4] = candleColor[0];
66
50
  candleColors[dataIndex * 4 + 1] = candleColor[1];
@@ -68,44 +52,120 @@ function useCandlestickPlotData(drawingArea, series, xScale, yScale) {
68
52
  candleColors[dataIndex * 4 + 3] = candleColor[3];
69
53
  for (let w = 0; w < 2; w += 1) {
70
54
  const wickIdx = (dataIndex * 2 + w) * 4;
71
- wickColors[wickIdx] = wickColor[0];
72
- wickColors[wickIdx + 1] = wickColor[1];
73
- wickColors[wickIdx + 2] = wickColor[2];
74
- wickColors[wickIdx + 3] = wickColor[3];
55
+ wickColors[wickIdx] = wickR;
56
+ wickColors[wickIdx + 1] = wickG;
57
+ wickColors[wickIdx + 2] = wickB;
58
+ wickColors[wickIdx + 3] = wickA;
75
59
  }
76
- const identifier = {
60
+ const highlightState = getHighlightState({
77
61
  type: 'ohlc',
78
62
  seriesId: series.id,
79
63
  dataIndex
80
- };
81
- const highlightState = getHighlightState(identifier);
82
- const highlighted = highlightState === 'highlighted';
83
- const faded = highlightState === 'faded';
84
- if (highlighted) {
85
- // Mimics CSS's filter: brightness(1.2), which multiplies the RGB values by 1.2, without affecting the alpha channel
86
- candleColors[dataIndex * 4] *= HIGHLIGHT_BRIGHTNESS;
87
- candleColors[dataIndex * 4 + 1] *= HIGHLIGHT_BRIGHTNESS;
88
- candleColors[dataIndex * 4 + 2] *= HIGHLIGHT_BRIGHTNESS;
64
+ });
65
+ if (highlightState === 'highlighted') {
66
+ /* Mimics CSS's filter: brightness(1.2): multiplies RGB by 1.2 without touching alpha. */
67
+ candleColors[dataIndex * 4] = candleColors[dataIndex * 4] * HIGHLIGHT_BRIGHTNESS;
68
+ candleColors[dataIndex * 4 + 1] = candleColors[dataIndex * 4 + 1] * HIGHLIGHT_BRIGHTNESS;
69
+ candleColors[dataIndex * 4 + 2] = candleColors[dataIndex * 4 + 2] * HIGHLIGHT_BRIGHTNESS;
89
70
  for (let w = 0; w < 2; w += 1) {
90
71
  const wickIdx = (dataIndex * 2 + w) * 4;
91
- wickColors[wickIdx] *= HIGHLIGHT_BRIGHTNESS;
92
- wickColors[wickIdx + 1] *= HIGHLIGHT_BRIGHTNESS;
93
- wickColors[wickIdx + 2] *= HIGHLIGHT_BRIGHTNESS;
72
+ wickColors[wickIdx] = wickColors[wickIdx] * HIGHLIGHT_BRIGHTNESS;
73
+ wickColors[wickIdx + 1] = wickColors[wickIdx + 1] * HIGHLIGHT_BRIGHTNESS;
74
+ wickColors[wickIdx + 2] = wickColors[wickIdx + 2] * HIGHLIGHT_BRIGHTNESS;
94
75
  }
95
- } else if (faded) {
96
- candleColors[dataIndex * 4 + 3] *= FADE_OPACITY;
76
+ } else if (highlightState === 'faded') {
77
+ candleColors[dataIndex * 4 + 3] = candleColors[dataIndex * 4 + 3] * FADE_OPACITY;
97
78
  for (let w = 0; w < 2; w += 1) {
98
- wickColors[(dataIndex * 2 + w) * 4 + 3] *= FADE_OPACITY;
79
+ const aIdx = (dataIndex * 2 + w) * 4 + 3;
80
+ wickColors[aIdx] = wickColors[aIdx] * FADE_OPACITY;
99
81
  }
100
82
  }
101
83
  }
102
84
  return {
85
+ candleColors,
86
+ wickColors
87
+ };
88
+ }, [colorGetter, wickColor, getHighlightState, series.data, series.id]);
89
+
90
+ /* Positions change every zoom/drag. Pool the typed arrays in a ref so we don't
91
+ * allocate ~1.5 MB per frame at large series sizes; hand out fresh subarray views
92
+ * so the upload short-circuit still fires. */
93
+ const positionsPoolRef = React.useRef(null);
94
+ const positions = React.useMemo(() => {
95
+ const n = series.data.length;
96
+ const pool = positionsPoolRef.current;
97
+ const candleCenters = ensurePoolFloat32(pool?.candleCenters, n * 2);
98
+ const candleHeights = ensurePoolFloat32(pool?.candleHeights, n);
99
+ const wickCenters = ensurePoolFloat32(pool?.wickCenters, n * 2 * 2);
100
+ const wickHeights = ensurePoolFloat32(pool?.wickHeights, n * 2);
101
+ positionsPoolRef.current = {
103
102
  candleCenters,
104
103
  candleHeights,
105
- candleColors,
106
104
  wickCenters,
107
- wickHeights,
108
- wickColors
105
+ wickHeights
106
+ };
107
+
108
+ /* Hoist drawing-area offsets into scalars so the loop body doesn't re-read them. */
109
+ const left = drawingArea.left;
110
+ const top = drawingArea.top;
111
+ const xDomain = xScale.domain();
112
+ for (let dataIndex = 0; dataIndex < n; dataIndex += 1) {
113
+ const datum = series.data[dataIndex];
114
+ if (datum === null) {
115
+ /* Pool is reused, so zero out stale values from previous frames. */
116
+ candleHeights[dataIndex] = 0;
117
+ candleCenters[dataIndex * 2] = 0;
118
+ candleCenters[dataIndex * 2 + 1] = 0;
119
+ wickHeights[dataIndex * 2] = 0;
120
+ wickHeights[dataIndex * 2 + 1] = 0;
121
+ wickCenters[dataIndex * 2 * 2] = 0;
122
+ wickCenters[dataIndex * 2 * 2 + 1] = 0;
123
+ wickCenters[(dataIndex * 2 + 1) * 2] = 0;
124
+ wickCenters[(dataIndex * 2 + 1) * 2 + 1] = 0;
125
+ continue;
126
+ }
127
+ const scaledX = xScale(xDomain[dataIndex]);
128
+ const open = datum[0];
129
+ const high = datum[1];
130
+ const low = datum[2];
131
+ const close = datum[3];
132
+ const x = scaledX - left;
133
+ const scaledOpen = yScale(open);
134
+ const scaledClose = yScale(close);
135
+ const candleBottom = Math.min(scaledOpen, scaledClose) - top;
136
+ const candleTop = Math.max(scaledOpen, scaledClose) - top;
137
+ const wickBottom = yScale(low) - top;
138
+ const wickTop = yScale(high) - top;
139
+ candleCenters[dataIndex * 2] = x;
140
+ candleCenters[dataIndex * 2 + 1] = (candleTop + candleBottom) / 2;
141
+ candleHeights[dataIndex] = candleTop - candleBottom;
142
+
143
+ /* Two wicks per candle so a faded candle body doesn't have a wick poking through it. */
144
+ const upperWickIndex = dataIndex * 2;
145
+ wickCenters[upperWickIndex * 2] = x;
146
+ wickCenters[upperWickIndex * 2 + 1] = (wickTop + candleBottom) / 2;
147
+ wickHeights[upperWickIndex] = wickTop - candleBottom;
148
+ const lowerWickIndex = dataIndex * 2 + 1;
149
+ wickCenters[lowerWickIndex * 2] = x;
150
+ wickCenters[lowerWickIndex * 2 + 1] = (candleTop + wickBottom) / 2;
151
+ wickHeights[lowerWickIndex] = candleTop - wickBottom;
152
+ }
153
+
154
+ /* Subarrays share the pool's ArrayBuffer but have new identity, which lets the GL
155
+ * upload short-circuit detect that the data has actually changed this frame. */
156
+ return {
157
+ candleCenters: candleCenters.subarray(0, n * 2),
158
+ candleHeights: candleHeights.subarray(0, n),
159
+ wickCenters: wickCenters.subarray(0, n * 2 * 2),
160
+ wickHeights: wickHeights.subarray(0, n * 2)
109
161
  };
110
- }, [colorGetter, drawingArea.left, drawingArea.top, getHighlightState, wickColor, series.data, series.id, xScale, yScale]);
162
+ }, [drawingArea.left, drawingArea.top, series.data, xScale, yScale]);
163
+ return React.useMemo(() => ({
164
+ candleCenters: positions.candleCenters,
165
+ candleHeights: positions.candleHeights,
166
+ candleColors: colors.candleColors,
167
+ wickCenters: positions.wickCenters,
168
+ wickHeights: positions.wickHeights,
169
+ wickColors: colors.wickColors
170
+ }), [positions, colors]);
111
171
  }
@@ -1,3 +1,5 @@
1
+ 'use client';
2
+
1
3
  import * as React from 'react';
2
4
  import { selectorChartsHighlightStateCallback, useStore } from '@mui/x-charts/internals';
3
5
  import { useTheme } from '@mui/material/styles';
@@ -5,54 +7,37 @@ import { parseColor } from "../utils/webgl/parseColor.mjs";
5
7
  import getColor from "./seriesConfig/getColor.mjs";
6
8
  const FADE_OPACITY = 0.3;
7
9
  const HIGHLIGHT_BRIGHTNESS = 1.2;
10
+ function ensurePoolFloat32(pool, n) {
11
+ if (pool && pool.length >= n) {
12
+ return pool;
13
+ }
14
+ return new Float32Array(n);
15
+ }
8
16
  export function useCandlestickPlotData(drawingArea, series, xScale, yScale) {
9
17
  const theme = useTheme();
10
18
  const store = useStore();
11
19
  const getHighlightState = store.use(selectorChartsHighlightStateCallback);
12
20
  const wickColor = React.useMemo(() => parseColor(theme.palette.text.primary), [theme.palette.text.primary]);
13
21
  const colorGetter = React.useMemo(() => getColor(series, undefined), [series]);
14
- return React.useMemo(() => {
15
- const candleCenters = new Float32Array(series.data.length * 2);
16
- const candleHeights = new Float32Array(series.data.length);
17
- // Two wicks per candle: upper (candle top → high) and lower (candle bottom → low)
18
- const wickCenters = new Float32Array(series.data.length * 2 * 2);
19
- const wickHeights = new Float32Array(series.data.length * 2);
20
- const candleColors = new Float32Array(series.data.length * 4);
21
- const wickColors = new Float32Array(series.data.length * 2 * 4);
22
- const xDomain = xScale.domain();
22
+
23
+ /* Colors only change when the series, color getter, or highlight state changes.
24
+ * Cache them so zoom-only renders return the same Uint8ClampedArray refs and the
25
+ * GL upload short-circuit can skip re-uploading colors.
26
+ * `parseColor` returns bytes in [0, 255]. Uint8Clamped rounds + clamps automatically,
27
+ * so brightness multiplications can't overflow. */
28
+ const colors = React.useMemo(() => {
29
+ const candleColors = new Uint8ClampedArray(series.data.length * 4);
30
+ const wickColors = new Uint8ClampedArray(series.data.length * 2 * 4);
31
+ const [wickR, wickG, wickB, wickA] = wickColor;
23
32
  for (let dataIndex = 0; dataIndex < series.data.length; dataIndex += 1) {
24
33
  const datum = series.data[dataIndex];
25
34
  if (datum === null) {
26
- // Set alpha to 0 to hide the candle and both wicks
27
- candleColors[dataIndex * 4 + 3] = 0.0;
28
- wickColors[dataIndex * 2 * 4 + 3] = 0.0;
29
- wickColors[(dataIndex * 2 + 1) * 4 + 3] = 0.0;
35
+ /* Alpha 0 hides the candle and both wicks; src-alpha blending makes RGB irrelevant. */
36
+ candleColors[dataIndex * 4 + 3] = 0;
37
+ wickColors[dataIndex * 2 * 4 + 3] = 0;
38
+ wickColors[(dataIndex * 2 + 1) * 4 + 3] = 0;
30
39
  continue;
31
40
  }
32
-
33
- // Can't return undefined because we're calling it with a value from the domain
34
- const scaledX = xScale(xDomain[dataIndex]);
35
- const [open, high, low, close] = datum;
36
- const x = scaledX - drawingArea.left;
37
- const scaledOpen = yScale(open);
38
- const scaledClose = yScale(close);
39
- const candleBottom = Math.min(scaledOpen, scaledClose) - drawingArea.top;
40
- const candleTop = Math.max(scaledOpen, scaledClose) - drawingArea.top;
41
- const wickBottom = yScale(low) - drawingArea.top;
42
- const wickTop = yScale(high) - drawingArea.top;
43
- candleCenters[dataIndex * 2] = x;
44
- candleCenters[dataIndex * 2 + 1] = (candleTop + candleBottom) / 2;
45
- candleHeights[dataIndex] = candleTop - candleBottom;
46
-
47
- // We have two wicks per candle so that when a candle is faded the wick isn't visible behind the candle body.
48
- const upperWickIndex = dataIndex * 2;
49
- wickCenters[upperWickIndex * 2] = x;
50
- wickCenters[upperWickIndex * 2 + 1] = (wickTop + candleBottom) / 2;
51
- wickHeights[upperWickIndex] = wickTop - candleBottom;
52
- const lowerWickIndex = dataIndex * 2 + 1;
53
- wickCenters[lowerWickIndex * 2] = x;
54
- wickCenters[lowerWickIndex * 2 + 1] = (candleTop + wickBottom) / 2;
55
- wickHeights[lowerWickIndex] = candleTop - wickBottom;
56
41
  const candleColor = parseColor(colorGetter(dataIndex));
57
42
  candleColors[dataIndex * 4] = candleColor[0];
58
43
  candleColors[dataIndex * 4 + 1] = candleColor[1];
@@ -60,44 +45,120 @@ export function useCandlestickPlotData(drawingArea, series, xScale, yScale) {
60
45
  candleColors[dataIndex * 4 + 3] = candleColor[3];
61
46
  for (let w = 0; w < 2; w += 1) {
62
47
  const wickIdx = (dataIndex * 2 + w) * 4;
63
- wickColors[wickIdx] = wickColor[0];
64
- wickColors[wickIdx + 1] = wickColor[1];
65
- wickColors[wickIdx + 2] = wickColor[2];
66
- wickColors[wickIdx + 3] = wickColor[3];
48
+ wickColors[wickIdx] = wickR;
49
+ wickColors[wickIdx + 1] = wickG;
50
+ wickColors[wickIdx + 2] = wickB;
51
+ wickColors[wickIdx + 3] = wickA;
67
52
  }
68
- const identifier = {
53
+ const highlightState = getHighlightState({
69
54
  type: 'ohlc',
70
55
  seriesId: series.id,
71
56
  dataIndex
72
- };
73
- const highlightState = getHighlightState(identifier);
74
- const highlighted = highlightState === 'highlighted';
75
- const faded = highlightState === 'faded';
76
- if (highlighted) {
77
- // Mimics CSS's filter: brightness(1.2), which multiplies the RGB values by 1.2, without affecting the alpha channel
78
- candleColors[dataIndex * 4] *= HIGHLIGHT_BRIGHTNESS;
79
- candleColors[dataIndex * 4 + 1] *= HIGHLIGHT_BRIGHTNESS;
80
- candleColors[dataIndex * 4 + 2] *= HIGHLIGHT_BRIGHTNESS;
57
+ });
58
+ if (highlightState === 'highlighted') {
59
+ /* Mimics CSS's filter: brightness(1.2): multiplies RGB by 1.2 without touching alpha. */
60
+ candleColors[dataIndex * 4] = candleColors[dataIndex * 4] * HIGHLIGHT_BRIGHTNESS;
61
+ candleColors[dataIndex * 4 + 1] = candleColors[dataIndex * 4 + 1] * HIGHLIGHT_BRIGHTNESS;
62
+ candleColors[dataIndex * 4 + 2] = candleColors[dataIndex * 4 + 2] * HIGHLIGHT_BRIGHTNESS;
81
63
  for (let w = 0; w < 2; w += 1) {
82
64
  const wickIdx = (dataIndex * 2 + w) * 4;
83
- wickColors[wickIdx] *= HIGHLIGHT_BRIGHTNESS;
84
- wickColors[wickIdx + 1] *= HIGHLIGHT_BRIGHTNESS;
85
- wickColors[wickIdx + 2] *= HIGHLIGHT_BRIGHTNESS;
65
+ wickColors[wickIdx] = wickColors[wickIdx] * HIGHLIGHT_BRIGHTNESS;
66
+ wickColors[wickIdx + 1] = wickColors[wickIdx + 1] * HIGHLIGHT_BRIGHTNESS;
67
+ wickColors[wickIdx + 2] = wickColors[wickIdx + 2] * HIGHLIGHT_BRIGHTNESS;
86
68
  }
87
- } else if (faded) {
88
- candleColors[dataIndex * 4 + 3] *= FADE_OPACITY;
69
+ } else if (highlightState === 'faded') {
70
+ candleColors[dataIndex * 4 + 3] = candleColors[dataIndex * 4 + 3] * FADE_OPACITY;
89
71
  for (let w = 0; w < 2; w += 1) {
90
- wickColors[(dataIndex * 2 + w) * 4 + 3] *= FADE_OPACITY;
72
+ const aIdx = (dataIndex * 2 + w) * 4 + 3;
73
+ wickColors[aIdx] = wickColors[aIdx] * FADE_OPACITY;
91
74
  }
92
75
  }
93
76
  }
94
77
  return {
78
+ candleColors,
79
+ wickColors
80
+ };
81
+ }, [colorGetter, wickColor, getHighlightState, series.data, series.id]);
82
+
83
+ /* Positions change every zoom/drag. Pool the typed arrays in a ref so we don't
84
+ * allocate ~1.5 MB per frame at large series sizes; hand out fresh subarray views
85
+ * so the upload short-circuit still fires. */
86
+ const positionsPoolRef = React.useRef(null);
87
+ const positions = React.useMemo(() => {
88
+ const n = series.data.length;
89
+ const pool = positionsPoolRef.current;
90
+ const candleCenters = ensurePoolFloat32(pool?.candleCenters, n * 2);
91
+ const candleHeights = ensurePoolFloat32(pool?.candleHeights, n);
92
+ const wickCenters = ensurePoolFloat32(pool?.wickCenters, n * 2 * 2);
93
+ const wickHeights = ensurePoolFloat32(pool?.wickHeights, n * 2);
94
+ positionsPoolRef.current = {
95
95
  candleCenters,
96
96
  candleHeights,
97
- candleColors,
98
97
  wickCenters,
99
- wickHeights,
100
- wickColors
98
+ wickHeights
99
+ };
100
+
101
+ /* Hoist drawing-area offsets into scalars so the loop body doesn't re-read them. */
102
+ const left = drawingArea.left;
103
+ const top = drawingArea.top;
104
+ const xDomain = xScale.domain();
105
+ for (let dataIndex = 0; dataIndex < n; dataIndex += 1) {
106
+ const datum = series.data[dataIndex];
107
+ if (datum === null) {
108
+ /* Pool is reused, so zero out stale values from previous frames. */
109
+ candleHeights[dataIndex] = 0;
110
+ candleCenters[dataIndex * 2] = 0;
111
+ candleCenters[dataIndex * 2 + 1] = 0;
112
+ wickHeights[dataIndex * 2] = 0;
113
+ wickHeights[dataIndex * 2 + 1] = 0;
114
+ wickCenters[dataIndex * 2 * 2] = 0;
115
+ wickCenters[dataIndex * 2 * 2 + 1] = 0;
116
+ wickCenters[(dataIndex * 2 + 1) * 2] = 0;
117
+ wickCenters[(dataIndex * 2 + 1) * 2 + 1] = 0;
118
+ continue;
119
+ }
120
+ const scaledX = xScale(xDomain[dataIndex]);
121
+ const open = datum[0];
122
+ const high = datum[1];
123
+ const low = datum[2];
124
+ const close = datum[3];
125
+ const x = scaledX - left;
126
+ const scaledOpen = yScale(open);
127
+ const scaledClose = yScale(close);
128
+ const candleBottom = Math.min(scaledOpen, scaledClose) - top;
129
+ const candleTop = Math.max(scaledOpen, scaledClose) - top;
130
+ const wickBottom = yScale(low) - top;
131
+ const wickTop = yScale(high) - top;
132
+ candleCenters[dataIndex * 2] = x;
133
+ candleCenters[dataIndex * 2 + 1] = (candleTop + candleBottom) / 2;
134
+ candleHeights[dataIndex] = candleTop - candleBottom;
135
+
136
+ /* Two wicks per candle so a faded candle body doesn't have a wick poking through it. */
137
+ const upperWickIndex = dataIndex * 2;
138
+ wickCenters[upperWickIndex * 2] = x;
139
+ wickCenters[upperWickIndex * 2 + 1] = (wickTop + candleBottom) / 2;
140
+ wickHeights[upperWickIndex] = wickTop - candleBottom;
141
+ const lowerWickIndex = dataIndex * 2 + 1;
142
+ wickCenters[lowerWickIndex * 2] = x;
143
+ wickCenters[lowerWickIndex * 2 + 1] = (candleTop + wickBottom) / 2;
144
+ wickHeights[lowerWickIndex] = candleTop - wickBottom;
145
+ }
146
+
147
+ /* Subarrays share the pool's ArrayBuffer but have new identity, which lets the GL
148
+ * upload short-circuit detect that the data has actually changed this frame. */
149
+ return {
150
+ candleCenters: candleCenters.subarray(0, n * 2),
151
+ candleHeights: candleHeights.subarray(0, n),
152
+ wickCenters: wickCenters.subarray(0, n * 2 * 2),
153
+ wickHeights: wickHeights.subarray(0, n * 2)
101
154
  };
102
- }, [colorGetter, drawingArea.left, drawingArea.top, getHighlightState, wickColor, series.data, series.id, xScale, yScale]);
155
+ }, [drawingArea.left, drawingArea.top, series.data, xScale, yScale]);
156
+ return React.useMemo(() => ({
157
+ candleCenters: positions.candleCenters,
158
+ candleHeights: positions.candleHeights,
159
+ candleColors: colors.candleColors,
160
+ wickCenters: positions.wickCenters,
161
+ wickHeights: positions.wickHeights,
162
+ wickColors: colors.wickColors
163
+ }), [positions, colors]);
103
164
  }
@@ -0,0 +1 @@
1
+ export * from '@mui/x-charts/ChartsAxisHighlightValue';
@@ -0,0 +1 @@
1
+ export * from '@mui/x-charts/ChartsAxisHighlightValue';
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _ChartsAxisHighlightValue = require("@mui/x-charts/ChartsAxisHighlightValue");
7
+ Object.keys(_ChartsAxisHighlightValue).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _ChartsAxisHighlightValue[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _ChartsAxisHighlightValue[key];
14
+ }
15
+ });
16
+ });
@@ -0,0 +1,2 @@
1
+ // Re-export automatically generated, to customize, simply remove this line.
2
+ export * from '@mui/x-charts/ChartsAxisHighlightValue';
@@ -19,8 +19,8 @@ var _useChartsDataProviderPremiumProps = require("./useChartsDataProviderPremium
19
19
  var _seriesConfig2 = require("../CandlestickChart/seriesConfig");
20
20
  var _jsxRuntime = require("react/jsx-runtime");
21
21
  const packageInfo = {
22
- releaseDate: "MTc3NzI0ODAwMDAwMA==",
23
- version: "9.0.3",
22
+ releaseDate: "MTc3ODE5ODQwMDAwMA==",
23
+ version: "9.1.0",
24
24
  name: 'x-charts-premium'
25
25
  };
26
26
  const defaultSeriesConfigPremium = exports.defaultSeriesConfigPremium = (0, _extends2.default)({}, _internals2.defaultSeriesConfigPro, {
@@ -13,8 +13,8 @@ import { useChartsDataProviderPremiumProps } from "./useChartsDataProviderPremiu
13
13
  import { ohlcSeriesConfig } from "../CandlestickChart/seriesConfig/index.mjs";
14
14
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
15
  const packageInfo = {
16
- releaseDate: "MTc3NzI0ODAwMDAwMA==",
17
- version: "9.0.3",
16
+ releaseDate: "MTc3ODE5ODQwMDAwMA==",
17
+ version: "9.1.0",
18
18
  name: 'x-charts-premium'
19
19
  };
20
20
  export const defaultSeriesConfigPremium = _extends({}, defaultSeriesConfigPro, {
@@ -0,0 +1 @@
1
+ export * from '@mui/x-charts/ChartsRadialAxisHighlight';
@@ -0,0 +1 @@
1
+ export * from '@mui/x-charts/ChartsRadialAxisHighlight';
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _ChartsRadialAxisHighlight = require("@mui/x-charts/ChartsRadialAxisHighlight");
7
+ Object.keys(_ChartsRadialAxisHighlight).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _ChartsRadialAxisHighlight[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _ChartsRadialAxisHighlight[key];
14
+ }
15
+ });
16
+ });
@@ -0,0 +1,2 @@
1
+ // Re-export automatically generated, to customize, simply remove this line.
2
+ export * from '@mui/x-charts/ChartsRadialAxisHighlight';
@@ -18,8 +18,8 @@ var _useChartsRadialDataProviderPremiumProps = require("./useChartsRadialDataPro
18
18
  var _ChartsRadialDataProviderPremium = require("./ChartsRadialDataProviderPremium.plugins");
19
19
  var _jsxRuntime = require("react/jsx-runtime");
20
20
  const packageInfo = {
21
- releaseDate: "MTc3NzI0ODAwMDAwMA==",
22
- version: "9.0.3",
21
+ releaseDate: "MTc3ODE5ODQwMDAwMA==",
22
+ version: "9.1.0",
23
23
  name: 'x-charts-premium'
24
24
  };
25
25
  /**
@@ -11,8 +11,8 @@ import { useChartsRadialDataProviderPremiumProps } from "./useChartsRadialDataPr
11
11
  import { RADIAL_PREMIUM_PLUGINS } from "./ChartsRadialDataProviderPremium.plugins.mjs";
12
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
13
  const packageInfo = {
14
- releaseDate: "MTc3NzI0ODAwMDAwMA==",
15
- version: "9.0.3",
14
+ releaseDate: "MTc3ODE5ODQwMDAwMA==",
15
+ version: "9.1.0",
16
16
  name: 'x-charts-premium'
17
17
  };
18
18
  /**