@mui/x-charts-premium 8.26.0 → 9.0.0-alpha.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 (134) hide show
  1. package/BarChartPremium/BarChartPremium.d.ts +14 -2
  2. package/BarChartPremium/BarChartPremium.js +11 -5
  3. package/BarChartPremium/RangeBar/AnimatedRangeBarElement.js +1 -1
  4. package/BarChartPremium/RangeBar/FocusedRangeBar.d.ts +2 -0
  5. package/BarChartPremium/RangeBar/FocusedRangeBar.js +70 -0
  6. package/BarChartPremium/RangeBar/RangeBarPlot.js +1 -1
  7. package/BarChartPremium/RangeBar/createGetRangeBarDimensions.d.ts +13 -0
  8. package/BarChartPremium/RangeBar/createGetRangeBarDimensions.js +42 -0
  9. package/BarChartPremium/RangeBar/seriesConfig/getSeriesWithDefaultValues.d.ts +2 -2
  10. package/BarChartPremium/RangeBar/seriesConfig/index.js +4 -1
  11. package/BarChartPremium/RangeBar/seriesConfig/keyboardFocusHandler.d.ts +3 -0
  12. package/BarChartPremium/RangeBar/seriesConfig/keyboardFocusHandler.js +22 -0
  13. package/BarChartPremium/RangeBar/seriesConfig/legend.js +0 -1
  14. package/BarChartPremium/RangeBar/seriesConfig/tooltipPosition.js +8 -2
  15. package/BarChartPremium/RangeBar/useRangeBarPlotData.d.ts +2 -9
  16. package/BarChartPremium/RangeBar/useRangeBarPlotData.js +16 -51
  17. package/BarChartPremium/index.d.ts +1 -0
  18. package/BarChartPremium/index.js +12 -0
  19. package/CHANGELOG.md +355 -3
  20. package/ChartContainerPremium/ChartContainerPremium.d.ts +17 -31
  21. package/ChartContainerPremium/ChartContainerPremium.js +15 -43
  22. package/ChartContainerPremium/useChartContainerPremiumProps.d.ts +10 -9
  23. package/ChartContainerPremium/useChartContainerPremiumProps.js +10 -27
  24. package/ChartDataProviderPremium/ChartDataProviderPremium.d.ts +7 -5
  25. package/ChartDataProviderPremium/ChartDataProviderPremium.js +6 -6
  26. package/ChartDataProviderPremium/index.d.ts +1 -1
  27. package/ChartDataProviderPremium/useChartDataProviderPremiumProps.d.ts +3 -3
  28. package/ChartZoomSlider/internals/previews/RangeBarPreviewPlot.js +1 -1
  29. package/ChartsContainer/index.d.ts +1 -0
  30. package/ChartsContainer/index.js +16 -0
  31. package/ChartsContainerPremium/ChartsContainerPremium.d.ts +37 -0
  32. package/ChartsContainerPremium/ChartsContainerPremium.js +52 -0
  33. package/ChartsContainerPremium/index.d.ts +2 -0
  34. package/ChartsContainerPremium/index.js +17 -0
  35. package/ChartsContainerPremium/useChartsContainerPremiumProps.d.ts +9 -0
  36. package/ChartsContainerPremium/useChartsContainerPremiumProps.js +33 -0
  37. package/ChartsContainerPro/index.d.ts +1 -0
  38. package/ChartsContainerPro/index.js +16 -0
  39. package/HeatmapPremium/HeatmapPlotPremium.d.ts +9 -0
  40. package/HeatmapPremium/HeatmapPlotPremium.js +29 -0
  41. package/HeatmapPremium/HeatmapPremium.d.ts +15 -0
  42. package/HeatmapPremium/HeatmapPremium.js +478 -0
  43. package/HeatmapPremium/HeatmapPremium.plugins.d.ts +4 -0
  44. package/HeatmapPremium/HeatmapPremium.plugins.js +9 -0
  45. package/HeatmapPremium/index.d.ts +1 -0
  46. package/HeatmapPremium/index.js +16 -0
  47. package/HeatmapPremium/useHeatmapPremiumProps.d.ts +16 -0
  48. package/HeatmapPremium/useHeatmapPremiumProps.js +26 -0
  49. package/HeatmapPremium/webgl/HeatmapWebGLPlot.d.ts +6 -0
  50. package/HeatmapPremium/webgl/HeatmapWebGLPlot.js +185 -0
  51. package/HeatmapPremium/webgl/HeatmapWebGLRenderer.d.ts +4 -0
  52. package/HeatmapPremium/webgl/HeatmapWebGLRenderer.js +23 -0
  53. package/HeatmapPremium/webgl/shaders.d.ts +3 -0
  54. package/HeatmapPremium/webgl/shaders.js +77 -0
  55. package/HeatmapPremium/webgl/useHeatmapPlotData.d.ts +12 -0
  56. package/HeatmapPremium/webgl/useHeatmapPlotData.js +58 -0
  57. package/HeatmapPremium/webgl/utils.d.ts +8 -0
  58. package/HeatmapPremium/webgl/utils.js +51 -0
  59. package/esm/BarChartPremium/BarChartPremium.d.ts +14 -2
  60. package/esm/BarChartPremium/BarChartPremium.js +12 -6
  61. package/esm/BarChartPremium/RangeBar/AnimatedRangeBarElement.js +1 -1
  62. package/esm/BarChartPremium/RangeBar/FocusedRangeBar.d.ts +2 -0
  63. package/esm/BarChartPremium/RangeBar/FocusedRangeBar.js +63 -0
  64. package/esm/BarChartPremium/RangeBar/RangeBarPlot.js +1 -1
  65. package/esm/BarChartPremium/RangeBar/createGetRangeBarDimensions.d.ts +13 -0
  66. package/esm/BarChartPremium/RangeBar/createGetRangeBarDimensions.js +36 -0
  67. package/esm/BarChartPremium/RangeBar/seriesConfig/getSeriesWithDefaultValues.d.ts +2 -2
  68. package/esm/BarChartPremium/RangeBar/seriesConfig/index.js +5 -2
  69. package/esm/BarChartPremium/RangeBar/seriesConfig/keyboardFocusHandler.d.ts +3 -0
  70. package/esm/BarChartPremium/RangeBar/seriesConfig/keyboardFocusHandler.js +16 -0
  71. package/esm/BarChartPremium/RangeBar/seriesConfig/legend.js +0 -1
  72. package/esm/BarChartPremium/RangeBar/seriesConfig/tooltipPosition.js +8 -2
  73. package/esm/BarChartPremium/RangeBar/useRangeBarPlotData.d.ts +2 -9
  74. package/esm/BarChartPremium/RangeBar/useRangeBarPlotData.js +16 -51
  75. package/esm/BarChartPremium/index.d.ts +1 -0
  76. package/esm/BarChartPremium/index.js +1 -0
  77. package/esm/ChartContainerPremium/ChartContainerPremium.d.ts +17 -31
  78. package/esm/ChartContainerPremium/ChartContainerPremium.js +16 -42
  79. package/esm/ChartContainerPremium/useChartContainerPremiumProps.d.ts +10 -9
  80. package/esm/ChartContainerPremium/useChartContainerPremiumProps.js +10 -25
  81. package/esm/ChartDataProviderPremium/ChartDataProviderPremium.d.ts +7 -5
  82. package/esm/ChartDataProviderPremium/ChartDataProviderPremium.js +6 -5
  83. package/esm/ChartDataProviderPremium/index.d.ts +1 -1
  84. package/esm/ChartDataProviderPremium/useChartDataProviderPremiumProps.d.ts +3 -3
  85. package/esm/ChartZoomSlider/internals/previews/RangeBarPreviewPlot.js +1 -1
  86. package/esm/ChartsContainer/index.d.ts +1 -0
  87. package/esm/ChartsContainer/index.js +2 -0
  88. package/esm/ChartsContainerPremium/ChartsContainerPremium.d.ts +37 -0
  89. package/esm/ChartsContainerPremium/ChartsContainerPremium.js +46 -0
  90. package/esm/ChartsContainerPremium/index.d.ts +2 -0
  91. package/esm/ChartsContainerPremium/index.js +2 -0
  92. package/esm/ChartsContainerPremium/useChartsContainerPremiumProps.d.ts +9 -0
  93. package/esm/ChartsContainerPremium/useChartsContainerPremiumProps.js +27 -0
  94. package/esm/ChartsContainerPro/index.d.ts +1 -0
  95. package/esm/ChartsContainerPro/index.js +2 -0
  96. package/esm/HeatmapPremium/HeatmapPlotPremium.d.ts +9 -0
  97. package/esm/HeatmapPremium/HeatmapPlotPremium.js +23 -0
  98. package/esm/HeatmapPremium/HeatmapPremium.d.ts +15 -0
  99. package/esm/HeatmapPremium/HeatmapPremium.js +472 -0
  100. package/esm/HeatmapPremium/HeatmapPremium.plugins.d.ts +4 -0
  101. package/esm/HeatmapPremium/HeatmapPremium.plugins.js +3 -0
  102. package/esm/HeatmapPremium/index.d.ts +1 -0
  103. package/esm/HeatmapPremium/index.js +1 -0
  104. package/esm/HeatmapPremium/useHeatmapPremiumProps.d.ts +16 -0
  105. package/esm/HeatmapPremium/useHeatmapPremiumProps.js +19 -0
  106. package/esm/HeatmapPremium/webgl/HeatmapWebGLPlot.d.ts +6 -0
  107. package/esm/HeatmapPremium/webgl/HeatmapWebGLPlot.js +178 -0
  108. package/esm/HeatmapPremium/webgl/HeatmapWebGLRenderer.d.ts +4 -0
  109. package/esm/HeatmapPremium/webgl/HeatmapWebGLRenderer.js +17 -0
  110. package/esm/HeatmapPremium/webgl/shaders.d.ts +3 -0
  111. package/esm/HeatmapPremium/webgl/shaders.js +71 -0
  112. package/esm/HeatmapPremium/webgl/useHeatmapPlotData.d.ts +12 -0
  113. package/esm/HeatmapPremium/webgl/useHeatmapPlotData.js +51 -0
  114. package/esm/HeatmapPremium/webgl/utils.d.ts +8 -0
  115. package/esm/HeatmapPremium/webgl/utils.js +41 -0
  116. package/esm/index.d.ts +5 -1
  117. package/esm/index.js +5 -2
  118. package/esm/internals/plugins/allPlugins.d.ts +1 -1
  119. package/esm/models/seriesType/rangeBar.d.ts +1 -1
  120. package/esm/typeOverloads/modules.d.ts +2 -1
  121. package/esm/utils/webgl/parseColor.d.ts +5 -0
  122. package/esm/utils/webgl/parseColor.js +78 -0
  123. package/esm/utils/webgl/useWebGLResizeObserver.d.ts +7 -0
  124. package/esm/utils/webgl/useWebGLResizeObserver.js +64 -0
  125. package/index.d.ts +5 -1
  126. package/index.js +33 -1
  127. package/internals/plugins/allPlugins.d.ts +1 -1
  128. package/models/seriesType/rangeBar.d.ts +1 -1
  129. package/package.json +9 -9
  130. package/typeOverloads/modules.d.ts +2 -1
  131. package/utils/webgl/parseColor.d.ts +5 -0
  132. package/utils/webgl/parseColor.js +84 -0
  133. package/utils/webgl/useWebGLResizeObserver.d.ts +7 -0
  134. package/utils/webgl/useWebGLResizeObserver.js +70 -0
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ 'use client';
3
+
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
6
+ Object.defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ exports.HeatmapWebGLPlot = HeatmapWebGLPlot;
10
+ var React = _interopRequireWildcard(require("react"));
11
+ var _hooks = require("@mui/x-charts/hooks");
12
+ var _internals = require("@mui/x-charts/internals");
13
+ var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
14
+ var _hooks2 = require("../../hooks");
15
+ var _shaders = require("./shaders");
16
+ var _useWebGLResizeObserver = require("../../utils/webgl/useWebGLResizeObserver");
17
+ var _utils = require("./utils");
18
+ var _useHeatmapPlotData = require("./useHeatmapPlotData");
19
+ var _jsxRuntime = require("react/jsx-runtime");
20
+ function HeatmapWebGLPlot({
21
+ borderRadius
22
+ }) {
23
+ const gl = (0, _internals.useWebGLContext)();
24
+ const series = (0, _hooks2.useHeatmapSeriesContext)();
25
+ const seriesToDisplay = series?.series[series.seriesOrder[0]];
26
+ if (!gl || !seriesToDisplay) {
27
+ return null;
28
+ }
29
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(HeatmapWebGLPlotImpl, {
30
+ gl: gl,
31
+ borderRadius: borderRadius ?? 0,
32
+ series: seriesToDisplay
33
+ });
34
+ }
35
+ function HeatmapWebGLPlotImpl(props) {
36
+ const {
37
+ gl,
38
+ borderRadius,
39
+ series
40
+ } = props;
41
+ const drawingArea = (0, _hooks.useDrawingArea)();
42
+ const xScale = (0, _hooks.useXScale)();
43
+ const yScale = (0, _hooks.useYScale)();
44
+ const [vertexShader] = React.useState(() => (0, _utils.compileShader)(gl, _shaders.heatmapVertexShaderSource, gl.VERTEX_SHADER));
45
+ const [program] = React.useState(() => {
46
+ const p = gl.createProgram();
47
+ gl.attachShader(p, vertexShader);
48
+ return p;
49
+ });
50
+ const [quadBuffer] = React.useState(() => (0, _utils.uploadQuadBuffer)(gl));
51
+ const dataLength = series.data.length;
52
+ const renderScheduledRef = React.useRef(false);
53
+ const render = React.useCallback(() => {
54
+ renderScheduledRef.current = false;
55
+
56
+ // Clear and draw
57
+ gl.clearColor(0, 0, 0, 0.0);
58
+ gl.clear(gl.COLOR_BUFFER_BIT);
59
+ gl.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, dataLength);
60
+ }, [dataLength, gl]);
61
+ const scheduleRender = React.useCallback(() => {
62
+ renderScheduledRef.current = true;
63
+ }, []);
64
+
65
+ // On resize render directly to avoid a frame where the canvas is blank
66
+ (0, _useWebGLResizeObserver.useWebGLResizeObserver)(render);
67
+ React.useEffect(() => {
68
+ /* Enable blending for transparency
69
+ * These are global to the WebGL context and need to be set only once */
70
+ gl.enable(gl.BLEND);
71
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
72
+ }, [gl]);
73
+ const width = xScale.bandwidth();
74
+ const height = yScale.bandwidth();
75
+
76
+ // A border radius cannot be larger than half the width or height of the rectangle
77
+ const seriesBorderRadius = Math.min(borderRadius ?? 0, width / 2, height / 2);
78
+ const lastSeriesBorderRadiusRef = React.useRef(seriesBorderRadius > 0 ? 0 : 1);
79
+ const setupResolutionUniform = React.useCallback(() => {
80
+ gl.uniform2f(gl.getUniformLocation(program, 'u_resolution'), drawingArea.width, drawingArea.height);
81
+ }, [drawingArea.height, drawingArea.width, gl, program]);
82
+ const setupBorderRadiusUniform = React.useCallback(() => {
83
+ gl.uniform1f(gl.getUniformLocation(program, 'u_borderRadius'), seriesBorderRadius);
84
+ }, [gl, program, seriesBorderRadius]);
85
+ const setupRectDimensionsUniform = React.useCallback(() => {
86
+ gl.uniform2f(gl.getUniformLocation(program, 'u_dimensions'), width, height);
87
+ }, [gl, height, program, width]);
88
+ const setupUniformsEvent = (0, _useEventCallback.default)(() => {
89
+ (0, _utils.bindQuadBuffer)(gl, program, quadBuffer);
90
+ setupBorderRadiusUniform();
91
+ setupResolutionUniform();
92
+ setupRectDimensionsUniform();
93
+ });
94
+ const plotData = (0, _useHeatmapPlotData.useHeatmapPlotData)(drawingArea, series, xScale, yScale);
95
+ const setupAttributes = React.useCallback(() => {
96
+ const {
97
+ centers,
98
+ colors,
99
+ saturations
100
+ } = plotData;
101
+
102
+ // Upload rectangle centers
103
+ const centerBuffer = gl.createBuffer();
104
+ gl.bindBuffer(gl.ARRAY_BUFFER, centerBuffer);
105
+ gl.bufferData(gl.ARRAY_BUFFER, centers, gl.STATIC_DRAW);
106
+ const aCenter = gl.getAttribLocation(program, 'a_center');
107
+ gl.enableVertexAttribArray(aCenter);
108
+ gl.vertexAttribPointer(aCenter, 2, gl.FLOAT, false, 0, 0);
109
+
110
+ // This makes the attribute instanced (one value per rectangle, not per vertex)
111
+ gl.vertexAttribDivisor(aCenter, 1);
112
+
113
+ // Upload colors
114
+ const colorBuffer = gl.createBuffer();
115
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
116
+ gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
117
+ const aColor = gl.getAttribLocation(program, 'a_color');
118
+ gl.enableVertexAttribArray(aColor);
119
+ gl.vertexAttribPointer(aColor, 4, gl.FLOAT, false, 0, 0);
120
+ gl.vertexAttribDivisor(aColor, 1);
121
+
122
+ // Upload saturations
123
+ const saturationBuffer = gl.createBuffer();
124
+ gl.bindBuffer(gl.ARRAY_BUFFER, saturationBuffer);
125
+ gl.bufferData(gl.ARRAY_BUFFER, saturations, gl.STATIC_DRAW);
126
+ const aSaturation = gl.getAttribLocation(program, 'a_saturation');
127
+ gl.enableVertexAttribArray(aSaturation);
128
+ gl.vertexAttribPointer(aSaturation, 1, gl.FLOAT, false, 0, 0);
129
+ gl.vertexAttribDivisor(aSaturation, 1);
130
+ }, [gl, plotData, program]);
131
+ const setupAttributesEvent = (0, _useEventCallback.default)(() => setupAttributes());
132
+ React.useEffect(() => {
133
+ const shouldAttachNewShader = lastSeriesBorderRadiusRef.current > 0 !== seriesBorderRadius > 0;
134
+ lastSeriesBorderRadiusRef.current = seriesBorderRadius;
135
+ if (shouldAttachNewShader) {
136
+ const shaderSource = seriesBorderRadius > 0 ? _shaders.heatmapFragmentShaderSourceWithBorderRadius : _shaders.heatmapFragmentShaderSourceNoBorderRadius;
137
+ gl.getAttachedShaders(program)?.forEach(shader => {
138
+ const shaderType = gl.getShaderParameter(shader, gl.SHADER_TYPE);
139
+ if (shaderType === gl.FRAGMENT_SHADER) {
140
+ gl.detachShader(program, shader);
141
+ gl.deleteShader(shader);
142
+ }
143
+ });
144
+ const fragmentShader = (0, _utils.attachShader)(gl, program, shaderSource, gl.FRAGMENT_SHADER);
145
+ gl.linkProgram(program);
146
+
147
+ // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#dont_check_shader_compile_status_unless_linking_fails
148
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
149
+ console.error(`Program linking failed: ${gl.getProgramInfoLog(program)}`);
150
+ console.error(`Vertex shader info-log: ${gl.getShaderInfoLog(vertexShader)}`);
151
+ console.error(`Fragment shader info-log: ${gl.getShaderInfoLog(fragmentShader)}`);
152
+ }
153
+
154
+ // Not a hook
155
+ // eslint-disable-next-line react-compiler/react-compiler
156
+ gl.useProgram(program);
157
+ (0, _utils.logWebGLErrors)(gl);
158
+ setupUniformsEvent();
159
+ setupAttributesEvent();
160
+ } else {
161
+ setupBorderRadiusUniform();
162
+ }
163
+ scheduleRender();
164
+ }, [gl, program, scheduleRender, seriesBorderRadius, setupBorderRadiusUniform,
165
+ // We use the event callback versions here because we only want this effect to trigger when the border radius changes
166
+ setupAttributesEvent, setupUniformsEvent, vertexShader]);
167
+ React.useEffect(() => {
168
+ setupResolutionUniform();
169
+ scheduleRender();
170
+ }, [setupResolutionUniform, scheduleRender]);
171
+ React.useEffect(() => {
172
+ setupRectDimensionsUniform();
173
+ scheduleRender();
174
+ }, [setupRectDimensionsUniform, scheduleRender]);
175
+ React.useEffect(() => {
176
+ setupAttributes();
177
+ scheduleRender();
178
+ }, [scheduleRender, setupAttributes]);
179
+ React.useEffect(() => {
180
+ if (renderScheduledRef.current) {
181
+ render();
182
+ }
183
+ });
184
+ return null;
185
+ }
@@ -0,0 +1,4 @@
1
+ import { type HeatmapRendererPlotProps } from '@mui/x-charts-pro/internals';
2
+ export declare function HeatmapWebGLRenderer({
3
+ borderRadius
4
+ }: HeatmapRendererPlotProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ 'use client';
3
+
4
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.HeatmapWebGLRenderer = HeatmapWebGLRenderer;
9
+ var React = _interopRequireWildcard(require("react"));
10
+ var _internals = require("@mui/x-charts/internals");
11
+ var _internals2 = require("@mui/x-charts-pro/internals");
12
+ var _HeatmapWebGLPlot = require("./HeatmapWebGLPlot");
13
+ var _jsxRuntime = require("react/jsx-runtime");
14
+ function HeatmapWebGLRenderer({
15
+ borderRadius
16
+ }) {
17
+ (0, _internals.useRegisterPointerInteractions)(_internals2.selectorHeatmapItemAtPosition);
18
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_internals.WebGLProvider, {
19
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_HeatmapWebGLPlot.HeatmapWebGLPlot, {
20
+ borderRadius: borderRadius
21
+ })
22
+ });
23
+ }
@@ -0,0 +1,3 @@
1
+ export declare const heatmapVertexShaderSource = "\n precision mediump float;\n \n attribute vec2 a_position;\n attribute vec2 a_center;\n attribute vec4 a_color;\n attribute float a_saturation;\n \n varying vec4 v_color;\n varying vec2 v_pos;\n \n uniform vec2 u_dimensions;\n uniform vec2 u_resolution;\n \n // https://tsev.dev/posts/2020-06-19-colour-correction-with-webgl/\n vec3 adjust_saturation(vec3 color, float value) {\n // https://www.w3.org/TR/WCAG21/#dfn-relative-luminance\n const vec3 luminosityFactor = vec3(0.2126, 0.7152, 0.0722);\n vec3 grayscale = vec3(dot(color, luminosityFactor));\n \n return mix(grayscale, color, 1.0 + value);\n }\n \n void main() {\n // Convert from pixels to clip space (-1 to 1)\n vec2 position = a_center + a_position * u_dimensions / 2.0;\n vec2 clipSpace = (position / u_resolution) * 2.0 - 1.0;\n gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n \n v_color = vec4(adjust_saturation(a_color.rgb, a_saturation), 1.0);\n v_pos = a_position * u_dimensions / 2.0;\n }\n ";
2
+ export declare const heatmapFragmentShaderSourceNoBorderRadius = "\n precision mediump float;\n \n varying vec4 v_color;\n \n void main() {\n gl_FragColor = v_color;\n }\n ";
3
+ export declare const heatmapFragmentShaderSourceWithBorderRadius = "\n precision mediump float;\n\n varying vec4 v_color;\n varying vec2 v_pos;\n\n uniform vec2 u_dimensions;\n uniform float u_borderRadius;\n\n float roundedBoxSDF(vec2 pos, vec2 half_size, float radius) {\n vec2 q = abs(pos) - half_size + radius;\n return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - radius;\n }\n\n void main() {\n // Calculate distance from rounded rectangle edge\n float dist = roundedBoxSDF(v_pos, u_dimensions / 2.0, u_borderRadius);\n \n // Create smooth alpha based on distance\n float alpha = 1.0 - smoothstep(-0.5, 0.5, dist);\n \n gl_FragColor = vec4(v_color.rgb, v_color.a * alpha);\n }\n ";
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.heatmapVertexShaderSource = exports.heatmapFragmentShaderSourceWithBorderRadius = exports.heatmapFragmentShaderSourceNoBorderRadius = void 0;
7
+ // language=Glsl
8
+ const heatmapVertexShaderSource = exports.heatmapVertexShaderSource = /* glsl */`
9
+ precision mediump float;
10
+
11
+ attribute vec2 a_position;
12
+ attribute vec2 a_center;
13
+ attribute vec4 a_color;
14
+ attribute float a_saturation;
15
+
16
+ varying vec4 v_color;
17
+ varying vec2 v_pos;
18
+
19
+ uniform vec2 u_dimensions;
20
+ uniform vec2 u_resolution;
21
+
22
+ // https://tsev.dev/posts/2020-06-19-colour-correction-with-webgl/
23
+ vec3 adjust_saturation(vec3 color, float value) {
24
+ // https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
25
+ const vec3 luminosityFactor = vec3(0.2126, 0.7152, 0.0722);
26
+ vec3 grayscale = vec3(dot(color, luminosityFactor));
27
+
28
+ return mix(grayscale, color, 1.0 + value);
29
+ }
30
+
31
+ void main() {
32
+ // Convert from pixels to clip space (-1 to 1)
33
+ vec2 position = a_center + a_position * u_dimensions / 2.0;
34
+ vec2 clipSpace = (position / u_resolution) * 2.0 - 1.0;
35
+ gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
36
+
37
+ v_color = vec4(adjust_saturation(a_color.rgb, a_saturation), 1.0);
38
+ v_pos = a_position * u_dimensions / 2.0;
39
+ }
40
+ `;
41
+
42
+ // language=Glsl
43
+ const heatmapFragmentShaderSourceNoBorderRadius = exports.heatmapFragmentShaderSourceNoBorderRadius = /* glsl */`
44
+ precision mediump float;
45
+
46
+ varying vec4 v_color;
47
+
48
+ void main() {
49
+ gl_FragColor = v_color;
50
+ }
51
+ `;
52
+
53
+ // language=Glsl
54
+ const heatmapFragmentShaderSourceWithBorderRadius = exports.heatmapFragmentShaderSourceWithBorderRadius = /* glsl */`
55
+ precision mediump float;
56
+
57
+ varying vec4 v_color;
58
+ varying vec2 v_pos;
59
+
60
+ uniform vec2 u_dimensions;
61
+ uniform float u_borderRadius;
62
+
63
+ float roundedBoxSDF(vec2 pos, vec2 half_size, float radius) {
64
+ vec2 q = abs(pos) - half_size + radius;
65
+ return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - radius;
66
+ }
67
+
68
+ void main() {
69
+ // Calculate distance from rounded rectangle edge
70
+ float dist = roundedBoxSDF(v_pos, u_dimensions / 2.0, u_borderRadius);
71
+
72
+ // Create smooth alpha based on distance
73
+ float alpha = 1.0 - smoothstep(-0.5, 0.5, dist);
74
+
75
+ gl_FragColor = vec4(v_color.rgb, v_color.a * alpha);
76
+ }
77
+ `;
@@ -0,0 +1,12 @@
1
+ import { type ScaleBand } from '@mui/x-charts-vendor/d3-scale';
2
+ import { type DefaultizedHeatmapSeriesType } from '@mui/x-charts-pro/models';
3
+ import { type ChartDrawingArea } from '@mui/x-charts/hooks';
4
+ export declare function useHeatmapPlotData(drawingArea: ChartDrawingArea, series: DefaultizedHeatmapSeriesType, xScale: ScaleBand<{
5
+ toString(): string;
6
+ }>, yScale: ScaleBand<{
7
+ toString(): string;
8
+ }>): {
9
+ centers: Float32Array<ArrayBuffer>;
10
+ colors: Float32Array<ArrayBuffer>;
11
+ saturations: Float32Array<ArrayBuffer>;
12
+ };
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.useHeatmapPlotData = useHeatmapPlotData;
8
+ var React = _interopRequireWildcard(require("react"));
9
+ var _hooks = require("@mui/x-charts/hooks");
10
+ var _internals = require("@mui/x-charts/internals");
11
+ var _parseColor = require("../../utils/webgl/parseColor");
12
+ function useHeatmapPlotData(drawingArea, series, xScale, yScale) {
13
+ const width = xScale.bandwidth();
14
+ const height = yScale.bandwidth();
15
+ const colorScale = (0, _hooks.useZColorScale)();
16
+ const store = (0, _internals.useStore)();
17
+ const isHighlighted = store.use(_internals.selectorChartsIsHighlightedCallback);
18
+ const isFaded = store.use(_internals.selectorChartsIsFadedCallback);
19
+ return React.useMemo(() => {
20
+ const centers = new Float32Array(series.data.length * 2);
21
+ const colors = new Float32Array(series.data.length * 4);
22
+ const saturations = new Float32Array(series.data.length);
23
+ const xDomain = xScale.domain();
24
+ const yDomain = yScale.domain();
25
+ for (let dataIndex = 0; dataIndex < series.data.length; dataIndex += 1) {
26
+ const [xIndex, yIndex, value] = series.data[dataIndex];
27
+ const x = xScale(xDomain[xIndex]);
28
+ const y = yScale(yDomain[yIndex]);
29
+ const color = colorScale?.(value);
30
+ if (x === undefined || y === undefined || !color) {
31
+ continue;
32
+ }
33
+ centers[dataIndex * 2] = x + width / 2 - drawingArea.left;
34
+ centers[dataIndex * 2 + 1] = y + height / 2 - drawingArea.top;
35
+ const rgbColor = (0, _parseColor.parseColor)(color);
36
+ colors[dataIndex * 4] = rgbColor[0];
37
+ colors[dataIndex * 4 + 1] = rgbColor[1];
38
+ colors[dataIndex * 4 + 2] = rgbColor[2];
39
+ colors[dataIndex * 4 + 3] = 1.0;
40
+ if (isHighlighted({
41
+ seriesId: series.id,
42
+ dataIndex
43
+ })) {
44
+ saturations[dataIndex] = 0.2;
45
+ } else if (isFaded({
46
+ seriesId: series.id,
47
+ dataIndex
48
+ })) {
49
+ saturations[dataIndex] = -0.2;
50
+ }
51
+ }
52
+ return {
53
+ centers,
54
+ colors,
55
+ saturations
56
+ };
57
+ }, [colorScale, drawingArea.left, drawingArea.top, height, isFaded, isHighlighted, series.data, series.id, width, xScale, yScale]);
58
+ }
@@ -0,0 +1,8 @@
1
+ export declare function compileShader(gl: WebGL2RenderingContext, shaderSource: string, shaderType: WebGL2RenderingContext['FRAGMENT_SHADER'] | WebGL2RenderingContext['VERTEX_SHADER']): WebGLShader;
2
+ export declare function uploadQuadBuffer(gl: WebGL2RenderingContext): WebGLBuffer;
3
+ export declare function bindQuadBuffer(gl: WebGL2RenderingContext, program: WebGLProgram, quadBuffer: WebGLBuffer): void;
4
+ export declare function attachShader(gl: WebGL2RenderingContext, program: WebGLProgram, shaderSource: string, shaderType: WebGL2RenderingContext['FRAGMENT_SHADER'] | WebGL2RenderingContext['VERTEX_SHADER']): WebGLShader;
5
+ /**
6
+ * Logs WebGL errors to the console in development mode.
7
+ */
8
+ export declare function logWebGLErrors(gl: WebGL2RenderingContext): void;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.attachShader = attachShader;
7
+ exports.bindQuadBuffer = bindQuadBuffer;
8
+ exports.compileShader = compileShader;
9
+ exports.logWebGLErrors = logWebGLErrors;
10
+ exports.uploadQuadBuffer = uploadQuadBuffer;
11
+ function compileShader(gl, shaderSource, shaderType) {
12
+ const shader = gl.createShader(shaderType);
13
+ gl.shaderSource(shader, shaderSource);
14
+ gl.compileShader(shader);
15
+ return shader;
16
+ }
17
+ function uploadQuadBuffer(gl) {
18
+ const quadVertices = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
19
+ const buffer = gl.createBuffer();
20
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
21
+ gl.bufferData(gl.ARRAY_BUFFER, quadVertices, gl.STATIC_DRAW);
22
+ return buffer;
23
+ }
24
+ function bindQuadBuffer(gl, program, quadBuffer) {
25
+ gl.bindBuffer(gl.ARRAY_BUFFER, quadBuffer);
26
+ const aPosition = gl.getAttribLocation(program, 'a_position');
27
+ gl.enableVertexAttribArray(aPosition);
28
+ gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);
29
+ }
30
+ function attachShader(gl, program, shaderSource, shaderType) {
31
+ const shader = gl.createShader(shaderType);
32
+ gl.shaderSource(shader, shaderSource);
33
+ gl.compileShader(shader);
34
+ gl.attachShader(program, shader);
35
+ return shader;
36
+ }
37
+
38
+ /**
39
+ * Logs WebGL errors to the console in development mode.
40
+ */
41
+ function logWebGLErrors(gl) {
42
+ /* Only log errors in dev because it has a performance cost:
43
+ * https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#avoid_blocking_api_calls_in_production */
44
+ if (process.env.NODE_ENV !== 'production') {
45
+ let error = gl.getError();
46
+ while (error !== gl.NO_ERROR) {
47
+ console.error('WebGL error:', error);
48
+ error = gl.getError();
49
+ }
50
+ }
51
+ }
@@ -1,9 +1,21 @@
1
1
  import * as React from 'react';
2
- import { type BarChartProProps } from '@mui/x-charts-pro/BarChartPro';
2
+ import { type BarChartProProps, type BarChartProSlotProps, type BarChartProSlots } from '@mui/x-charts-pro/BarChartPro';
3
3
  import { type BarSeries } from '@mui/x-charts/BarChart';
4
4
  import { type BarItemIdentifier, type RangeBarItemIdentifier, type RangeBarSeriesType } from "../models/index.js";
5
5
  export type RangeBarSeries = RangeBarSeriesType;
6
- export interface BarChartPremiumProps extends Omit<BarChartProProps, 'series' | 'onItemClick'> {
6
+ export interface BarChartPremiumSlots extends BarChartProSlots {}
7
+ export interface BarChartPremiumSlotProps extends BarChartProSlotProps {}
8
+ export interface BarChartPremiumProps extends Omit<BarChartProProps, 'series' | 'onItemClick' | 'slots' | 'slotProps'> {
9
+ /**
10
+ * Overridable component slots.
11
+ * @default {}
12
+ */
13
+ slots?: BarChartPremiumSlots;
14
+ /**
15
+ * The props used for each component slot.
16
+ * @default {}
17
+ */
18
+ slotProps?: BarChartPremiumSlotProps;
7
19
  /**
8
20
  * Callback fired when a bar or range bar item is clicked.
9
21
  * @param {React.MouseEvent<SVGElement, MouseEvent>} event The event source of the callback.
@@ -12,7 +12,7 @@ import { ChartsTooltip } from '@mui/x-charts/ChartsTooltip';
12
12
  import { ChartsWrapper } from '@mui/x-charts/ChartsWrapper';
13
13
  import { ChartsSurface } from '@mui/x-charts/ChartsSurface';
14
14
  import { ChartsGrid } from '@mui/x-charts/ChartsGrid';
15
- import { BarPlot } from '@mui/x-charts/BarChart';
15
+ import { BarPlot, FocusedBar } from '@mui/x-charts/BarChart';
16
16
  import { ChartsOverlay } from '@mui/x-charts/ChartsOverlay';
17
17
  import { ChartsAxisHighlight } from '@mui/x-charts/ChartsAxisHighlight';
18
18
  import { ChartsAxis } from '@mui/x-charts/ChartsAxis';
@@ -24,6 +24,7 @@ import { useBarChartPremiumProps } from "./useBarChartPremiumProps.js";
24
24
  import { BAR_CHART_PREMIUM_PLUGINS } from "./BarChartPremium.plugins.js";
25
25
  import { ChartDataProviderPremium } from "../ChartDataProviderPremium/index.js";
26
26
  import { RangeBarPlot } from "./RangeBar/RangeBarPlot.js";
27
+ import { FocusedRangeBar } from "./RangeBar/FocusedRangeBar.js";
27
28
  import { RangeBarPreviewPlot } from "../ChartZoomSlider/internals/previews/RangeBarPreviewPlot.js";
28
29
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
29
30
  seriesPreviewPlotMap.set('rangeBar', RangeBarPreviewPlot);
@@ -81,7 +82,7 @@ const BarChartPremium = /*#__PURE__*/React.forwardRef(function BarChartPremium(i
81
82
  children: /*#__PURE__*/_jsxs(ChartsWrapper, _extends({}, chartsWrapperProps, {
82
83
  children: [showToolbar ? /*#__PURE__*/_jsx(Toolbar, _extends({}, props.slotProps?.toolbar)) : null, !props.hideLegend && /*#__PURE__*/_jsx(ChartsLegend, _extends({}, legendProps)), /*#__PURE__*/_jsxs(ChartsSurface, _extends({}, chartsSurfaceProps, {
83
84
  children: [/*#__PURE__*/_jsx(ChartsGrid, _extends({}, gridProps)), /*#__PURE__*/_jsxs("g", _extends({}, clipPathGroupProps, {
84
- children: [/*#__PURE__*/_jsx(BarPlot, _extends({}, barPlotProps)), /*#__PURE__*/_jsx(RangeBarPlot, _extends({}, rangeBarPlotProps)), /*#__PURE__*/_jsx(ChartsOverlay, _extends({}, overlayProps)), /*#__PURE__*/_jsx(ChartsAxisHighlight, _extends({}, axisHighlightProps))]
85
+ children: [/*#__PURE__*/_jsx(BarPlot, _extends({}, barPlotProps)), /*#__PURE__*/_jsx(RangeBarPlot, _extends({}, rangeBarPlotProps)), /*#__PURE__*/_jsx(ChartsOverlay, _extends({}, overlayProps)), /*#__PURE__*/_jsx(ChartsAxisHighlight, _extends({}, axisHighlightProps)), /*#__PURE__*/_jsx(FocusedBar, {}), /*#__PURE__*/_jsx(FocusedRangeBar, {})]
85
86
  })), /*#__PURE__*/_jsx(ChartsAxis, _extends({}, chartsAxisProps)), /*#__PURE__*/_jsx(ChartZoomSlider, {}), /*#__PURE__*/_jsx(ChartsBrushOverlay, {}), /*#__PURE__*/_jsx(ChartsClipPath, _extends({}, clipPathProps)), children]
86
87
  })), !props.loading && /*#__PURE__*/_jsx(Tooltip, _extends({}, props.slotProps?.tooltip))]
87
88
  }))
@@ -101,6 +102,11 @@ process.env.NODE_ENV !== "production" ? BarChartPremium.propTypes = {
101
102
  setZoomData: PropTypes.func.isRequired
102
103
  })
103
104
  }),
105
+ /**
106
+ * A gap added between axes when multiple axes are rendered on the same side of the chart.
107
+ * @default 0
108
+ */
109
+ axesGap: PropTypes.number,
104
110
  /**
105
111
  * The configuration of axes highlight.
106
112
  * Default is set to 'band' in the bar direction.
@@ -184,7 +190,7 @@ process.env.NODE_ENV !== "production" ? BarChartPremium.propTypes = {
184
190
  */
185
191
  hiddenItems: PropTypes.arrayOf(PropTypes.shape({
186
192
  dataIndex: PropTypes.number,
187
- seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
193
+ seriesId: PropTypes.string,
188
194
  type: PropTypes.oneOf(['bar']).isRequired
189
195
  })),
190
196
  /**
@@ -205,7 +211,7 @@ process.env.NODE_ENV !== "production" ? BarChartPremium.propTypes = {
205
211
  */
206
212
  highlightedItem: PropTypes.shape({
207
213
  dataIndex: PropTypes.number,
208
- seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired
214
+ seriesId: PropTypes.string.isRequired
209
215
  }),
210
216
  /**
211
217
  * This prop is used to help implement the accessibility logic.
@@ -235,7 +241,7 @@ process.env.NODE_ENV !== "production" ? BarChartPremium.propTypes = {
235
241
  */
236
242
  initialHiddenItems: PropTypes.arrayOf(PropTypes.shape({
237
243
  dataIndex: PropTypes.number,
238
- seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
244
+ seriesId: PropTypes.string,
239
245
  type: PropTypes.oneOf(['bar']).isRequired
240
246
  })),
241
247
  /**
@@ -360,7 +366,7 @@ process.env.NODE_ENV !== "production" ? BarChartPremium.propTypes = {
360
366
  */
361
367
  tooltipItem: PropTypes.shape({
362
368
  dataIndex: PropTypes.number.isRequired,
363
- seriesId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
369
+ seriesId: PropTypes.string.isRequired,
364
370
  type: PropTypes.oneOf(['bar']).isRequired
365
371
  }),
366
372
  /**
@@ -2,7 +2,7 @@
2
2
 
3
3
  import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
5
- const _excluded = ["ownerState", "skipAnimation", "id", "dataIndex", "xOrigin", "yOrigin", "hidden"];
5
+ const _excluded = ["ownerState", "skipAnimation", "seriesId", "dataIndex", "xOrigin", "yOrigin", "hidden"];
6
6
  import * as React from 'react';
7
7
  import { useAnimateRangeBar } from "../../hooks/animation/useAnimateRangeBar.js";
8
8
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -0,0 +1,2 @@
1
+ import * as React from 'react';
2
+ export declare function FocusedRangeBar(props: React.SVGAttributes<SVGRectElement>): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,63 @@
1
+ 'use client';
2
+
3
+ import _extends from "@babel/runtime/helpers/esm/extends";
4
+ import * as React from 'react';
5
+ import { useTheme } from '@mui/material/styles';
6
+ import { useFocusedItem, useXAxes, useYAxes } from '@mui/x-charts/hooks';
7
+ import { createGetRangeBarDimensions } from "./createGetRangeBarDimensions.js";
8
+ import { useRangeBarSeriesContext } from "../../hooks/useRangeBarSeries.js";
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ export function FocusedRangeBar(props) {
11
+ const theme = useTheme();
12
+ const focusedItem = useFocusedItem();
13
+ const rangeBarSeries = useRangeBarSeriesContext();
14
+ const {
15
+ xAxis,
16
+ xAxisIds
17
+ } = useXAxes();
18
+ const {
19
+ yAxis,
20
+ yAxisIds
21
+ } = useYAxes();
22
+ if (focusedItem === null || focusedItem.type !== 'rangeBar' || !rangeBarSeries) {
23
+ return null;
24
+ }
25
+ const series = rangeBarSeries.series[focusedItem.seriesId];
26
+ if (series.data[focusedItem.dataIndex] == null) {
27
+ // Handle missing data
28
+ return null;
29
+ }
30
+ const xAxisId = series.xAxisId ?? xAxisIds[0];
31
+ const yAxisId = series.yAxisId ?? yAxisIds[0];
32
+ const xAxisConfig = xAxis[xAxisId];
33
+ const yAxisConfig = yAxis[yAxisId];
34
+ const verticalLayout = rangeBarSeries.series[focusedItem.seriesId].layout === 'vertical';
35
+ const groupIndex = rangeBarSeries.seriesOrder.findIndex(seriesId => seriesId === focusedItem.seriesId);
36
+ const barDimensions = createGetRangeBarDimensions({
37
+ verticalLayout,
38
+ xAxisConfig,
39
+ yAxisConfig,
40
+ series,
41
+ numberOfGroups: rangeBarSeries.seriesOrder.length
42
+ })(focusedItem.dataIndex, groupIndex);
43
+ if (barDimensions === null) {
44
+ return null;
45
+ }
46
+ const {
47
+ x,
48
+ y,
49
+ height,
50
+ width
51
+ } = barDimensions;
52
+ return /*#__PURE__*/_jsx("rect", _extends({
53
+ fill: "none",
54
+ stroke: (theme.vars ?? theme).palette.text.primary,
55
+ strokeWidth: 2,
56
+ x: x - 3,
57
+ y: y - 3,
58
+ width: width + 6,
59
+ height: height + 6,
60
+ rx: 3,
61
+ ry: 3
62
+ }, props));
63
+ }
@@ -74,7 +74,7 @@ function RangeBarPlot(props) {
74
74
  hidden
75
75
  }) => {
76
76
  return /*#__PURE__*/_jsx(BarElement, _extends({
77
- id: seriesId,
77
+ seriesId: seriesId,
78
78
  dataIndex: dataIndex,
79
79
  color: color,
80
80
  skipAnimation: skipAnimation ?? false,
@@ -0,0 +1,13 @@
1
+ import { type ChartSeriesDefaultized, type ChartsXAxisProps, type ChartsYAxisProps, type ComputedAxis, type ScaleName } from '@mui/x-charts/internals';
2
+ export declare function createGetRangeBarDimensions(params: {
3
+ verticalLayout: boolean;
4
+ xAxisConfig: ComputedAxis<ScaleName, any, ChartsXAxisProps>;
5
+ yAxisConfig: ComputedAxis<ScaleName, any, ChartsYAxisProps>;
6
+ series: ChartSeriesDefaultized<'rangeBar'>;
7
+ numberOfGroups: number;
8
+ }): (dataIndex: number, groupIndex: number) => {
9
+ x: number;
10
+ y: number;
11
+ height: number;
12
+ width: number;
13
+ } | null;