@mui/x-charts-premium 9.7.0 → 9.9.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 (230) hide show
  1. package/BarChartPremium/BarChartPremium.d.mts +1 -1
  2. package/BarChartPremium/BarChartPremium.d.ts +1 -1
  3. package/BarChartPremium/BarChartPremium.js +14 -3
  4. package/BarChartPremium/BarChartPremium.mjs +14 -3
  5. package/BarChartPremium/RangeBar/AnimatedRangeBarElement.d.mts +2 -1
  6. package/BarChartPremium/RangeBar/AnimatedRangeBarElement.d.ts +2 -1
  7. package/BarChartPremium/RangeBar/FocusedRangeBar.d.mts +1 -1
  8. package/BarChartPremium/RangeBar/FocusedRangeBar.d.ts +1 -1
  9. package/BarChartPremium/RangeBar/seriesConfig/index.js +2 -2
  10. package/BarChartPremium/RangeBar/seriesConfig/index.mjs +2 -2
  11. package/BarChartPremium/RangeBar/seriesConfig/tooltipPosition.d.mts +2 -3
  12. package/BarChartPremium/RangeBar/seriesConfig/tooltipPosition.d.ts +2 -3
  13. package/BarChartPremium/RangeBar/seriesConfig/tooltipPosition.js +12 -15
  14. package/BarChartPremium/RangeBar/seriesConfig/tooltipPosition.mjs +11 -14
  15. package/BarChartPremium/webgl/BarWebGLProgram.d.mts +4 -5
  16. package/BarChartPremium/webgl/BarWebGLProgram.d.ts +4 -5
  17. package/BarChartPremium/webgl/BarWebGLProgram.js +24 -65
  18. package/BarChartPremium/webgl/BarWebGLProgram.mjs +24 -65
  19. package/BarChartPremium/webgl/shaders.d.mts +1 -1
  20. package/BarChartPremium/webgl/shaders.d.ts +1 -1
  21. package/BarChartPremium/webgl/shaders.js +2 -15
  22. package/BarChartPremium/webgl/shaders.mjs +3 -15
  23. package/CHANGELOG.md +249 -1
  24. package/CandlestickChart/CandlestickPlot.d.mts +2 -1
  25. package/CandlestickChart/CandlestickPlot.d.ts +2 -1
  26. package/CandlestickChart/seriesConfig/OHLCTooltipContent.d.mts +2 -1
  27. package/CandlestickChart/seriesConfig/OHLCTooltipContent.d.ts +2 -1
  28. package/CandlestickChart/seriesConfig/index.js +2 -2
  29. package/CandlestickChart/seriesConfig/index.mjs +2 -2
  30. package/CandlestickChart/seriesConfig/tooltipPosition.d.mts +2 -3
  31. package/CandlestickChart/seriesConfig/tooltipPosition.d.ts +2 -3
  32. package/CandlestickChart/seriesConfig/tooltipPosition.js +10 -14
  33. package/CandlestickChart/seriesConfig/tooltipPosition.mjs +10 -14
  34. package/ChartsDataProviderPremium/ChartsDataProviderPremium.d.mts +1 -1
  35. package/ChartsDataProviderPremium/ChartsDataProviderPremium.d.ts +1 -1
  36. package/ChartsDataProviderPremium/ChartsDataProviderPremium.js +2 -2
  37. package/ChartsDataProviderPremium/ChartsDataProviderPremium.mjs +2 -2
  38. package/ChartsGeoDataProviderPremium/ChartsGeoDataProviderPremium.d.mts +1 -1
  39. package/ChartsGeoDataProviderPremium/ChartsGeoDataProviderPremium.d.ts +1 -1
  40. package/ChartsGeoDataProviderPremium/ChartsGeoDataProviderPremium.js +2 -2
  41. package/ChartsGeoDataProviderPremium/ChartsGeoDataProviderPremium.mjs +2 -2
  42. package/ChartsGeoDataProviderPremium/ChartsGeoDataProviderPremium.plugins.d.mts +4 -3
  43. package/ChartsGeoDataProviderPremium/ChartsGeoDataProviderPremium.plugins.d.ts +4 -3
  44. package/ChartsGeoDataProviderPremium/ChartsGeoDataProviderPremium.plugins.js +2 -1
  45. package/ChartsGeoDataProviderPremium/ChartsGeoDataProviderPremium.plugins.mjs +2 -1
  46. package/ChartsGeoDataProviderPremium/index.d.mts +2 -1
  47. package/ChartsGeoDataProviderPremium/index.d.ts +2 -1
  48. package/ChartsRadialDataProviderPremium/ChartsRadialDataProviderPremium.d.mts +2 -1
  49. package/ChartsRadialDataProviderPremium/ChartsRadialDataProviderPremium.d.ts +2 -1
  50. package/ChartsRadialDataProviderPremium/ChartsRadialDataProviderPremium.js +2 -2
  51. package/ChartsRadialDataProviderPremium/ChartsRadialDataProviderPremium.mjs +2 -2
  52. package/ChartsRenderer/components/PaletteOption.d.mts +1 -1
  53. package/ChartsRenderer/components/PaletteOption.d.ts +1 -1
  54. package/ChartsZoomSlider/internals/previews/CandlestickPreviewPlot.d.mts +2 -1
  55. package/ChartsZoomSlider/internals/previews/CandlestickPreviewPlot.d.ts +2 -1
  56. package/ChartsZoomSlider/internals/previews/RangeBarPreviewPlot.d.mts +1 -1
  57. package/ChartsZoomSlider/internals/previews/RangeBarPreviewPlot.d.ts +1 -1
  58. package/HeatmapPremium/HeatmapPlotPremium.d.mts +1 -1
  59. package/HeatmapPremium/HeatmapPlotPremium.d.ts +1 -1
  60. package/HeatmapPremium/webgl/HeatmapWebGLProgram.js +12 -37
  61. package/HeatmapPremium/webgl/HeatmapWebGLProgram.mjs +12 -37
  62. package/HeatmapPremium/webgl/shaders.d.mts +3 -3
  63. package/HeatmapPremium/webgl/shaders.d.ts +3 -3
  64. package/HeatmapPremium/webgl/shaders.js +12 -15
  65. package/HeatmapPremium/webgl/shaders.mjs +13 -15
  66. package/HeatmapPremium/webgl/useHeatmapPlotData.js +3 -8
  67. package/HeatmapPremium/webgl/useHeatmapPlotData.mjs +3 -8
  68. package/Map/FocusedMapShape.d.mts +2 -1
  69. package/Map/FocusedMapShape.d.ts +2 -1
  70. package/Map/FocusedMapShape.js +5 -1
  71. package/Map/FocusedMapShape.mjs +5 -1
  72. package/Map/GeoDataPlot.d.mts +1 -1
  73. package/Map/GeoDataPlot.d.ts +1 -1
  74. package/Map/Graticule.d.mts +1 -1
  75. package/Map/Graticule.d.ts +1 -1
  76. package/Map/MapImagePlot.d.mts +39 -0
  77. package/Map/MapImagePlot.d.ts +39 -0
  78. package/Map/MapImagePlot.js +138 -0
  79. package/Map/MapImagePlot.mjs +132 -0
  80. package/Map/MapShape.d.mts +2 -2
  81. package/Map/MapShape.d.ts +2 -2
  82. package/Map/MapShape.js +6 -6
  83. package/Map/MapShape.mjs +6 -6
  84. package/Map/MapShapePlot.d.mts +9 -1
  85. package/Map/MapShapePlot.d.ts +9 -1
  86. package/Map/MapShapePlot.js +17 -5
  87. package/Map/MapShapePlot.mjs +17 -5
  88. package/Map/index.d.mts +2 -3
  89. package/Map/index.d.ts +2 -3
  90. package/Map/index.js +11 -0
  91. package/Map/index.mjs +1 -0
  92. package/Map/reprojectEquirectangularImage.d.mts +60 -0
  93. package/Map/reprojectEquirectangularImage.d.ts +60 -0
  94. package/Map/reprojectEquirectangularImage.js +116 -0
  95. package/Map/reprojectEquirectangularImage.mjs +110 -0
  96. package/Map/seriesConfig/descriptionGetter.js +5 -1
  97. package/Map/seriesConfig/descriptionGetter.mjs +5 -1
  98. package/Map/seriesConfig/getColor.js +18 -6
  99. package/Map/seriesConfig/getColor.mjs +18 -6
  100. package/Map/seriesConfig/highlight.d.mts +10 -0
  101. package/Map/seriesConfig/highlight.d.ts +10 -0
  102. package/Map/seriesConfig/highlight.js +52 -0
  103. package/Map/seriesConfig/highlight.mjs +45 -0
  104. package/Map/seriesConfig/identifierCleaner.d.mts +3 -0
  105. package/Map/seriesConfig/identifierCleaner.d.ts +3 -0
  106. package/Map/seriesConfig/identifierCleaner.js +14 -0
  107. package/Map/seriesConfig/identifierCleaner.mjs +8 -0
  108. package/Map/seriesConfig/identifierSerializer.d.mts +3 -0
  109. package/Map/seriesConfig/identifierSerializer.d.ts +3 -0
  110. package/Map/seriesConfig/identifierSerializer.js +12 -0
  111. package/Map/seriesConfig/identifierSerializer.mjs +6 -0
  112. package/Map/seriesConfig/index.js +8 -6
  113. package/Map/seriesConfig/index.mjs +7 -5
  114. package/Map/seriesConfig/keyboardFocusHandler.d.mts +0 -6
  115. package/Map/seriesConfig/keyboardFocusHandler.d.ts +0 -6
  116. package/Map/seriesConfig/keyboardFocusHandler.js +40 -7
  117. package/Map/seriesConfig/keyboardFocusHandler.mjs +41 -8
  118. package/Map/seriesConfig/seriesProcessor.js +11 -2
  119. package/Map/seriesConfig/seriesProcessor.mjs +11 -2
  120. package/Map/seriesConfig/tooltip.js +8 -4
  121. package/Map/seriesConfig/tooltip.mjs +8 -4
  122. package/Map/seriesConfig/tooltipPosition.d.mts +8 -3
  123. package/Map/seriesConfig/tooltipPosition.d.ts +8 -3
  124. package/Map/seriesConfig/tooltipPosition.js +15 -27
  125. package/Map/seriesConfig/tooltipPosition.mjs +16 -27
  126. package/RadialBarChart/RadialBarElement.d.mts +1 -1
  127. package/RadialBarChart/RadialBarElement.d.ts +1 -1
  128. package/RadialBarChart/seriesConfig/index.js +2 -2
  129. package/RadialBarChart/seriesConfig/index.mjs +2 -2
  130. package/RadialBarChart/seriesConfig/tooltipPosition.d.mts +2 -3
  131. package/RadialBarChart/seriesConfig/tooltipPosition.d.ts +2 -3
  132. package/RadialBarChart/seriesConfig/tooltipPosition.js +4 -6
  133. package/RadialBarChart/seriesConfig/tooltipPosition.mjs +2 -5
  134. package/RadialLineChart/RadialArea.d.mts +2 -1
  135. package/RadialLineChart/RadialArea.d.ts +2 -1
  136. package/RadialLineChart/RadialAreaPlot.d.mts +1 -1
  137. package/RadialLineChart/RadialAreaPlot.d.ts +1 -1
  138. package/RadialLineChart/RadialLine.d.mts +1 -1
  139. package/RadialLineChart/RadialLine.d.ts +1 -1
  140. package/RadialLineChart/RadialLineHighlightElement.d.mts +1 -1
  141. package/RadialLineChart/RadialLineHighlightElement.d.ts +1 -1
  142. package/RadialLineChart/RadialLineHighlightPlot.d.mts +1 -1
  143. package/RadialLineChart/RadialLineHighlightPlot.d.ts +1 -1
  144. package/RadialLineChart/RadialLinePlot.d.mts +1 -1
  145. package/RadialLineChart/RadialLinePlot.d.ts +1 -1
  146. package/RadialLineChart/RadialMarkPlot.d.mts +1 -1
  147. package/RadialLineChart/RadialMarkPlot.d.ts +1 -1
  148. package/RadialLineChart/seriesConfig/index.js +2 -2
  149. package/RadialLineChart/seriesConfig/index.mjs +2 -2
  150. package/RadialLineChart/seriesConfig/tooltipPosition.d.mts +2 -3
  151. package/RadialLineChart/seriesConfig/tooltipPosition.d.ts +2 -3
  152. package/RadialLineChart/seriesConfig/tooltipPosition.js +4 -6
  153. package/RadialLineChart/seriesConfig/tooltipPosition.mjs +2 -5
  154. package/ScatterChartPremium/ScatterPlotPremium.d.mts +2 -1
  155. package/ScatterChartPremium/ScatterPlotPremium.d.ts +2 -1
  156. package/ScatterChartPremium/webgl/ScatterWebGLPlot.d.mts +2 -1
  157. package/ScatterChartPremium/webgl/ScatterWebGLPlot.d.ts +2 -1
  158. package/ScatterChartPremium/webgl/ScatterWebGLProgram.d.mts +0 -2
  159. package/ScatterChartPremium/webgl/ScatterWebGLProgram.d.ts +0 -2
  160. package/ScatterChartPremium/webgl/ScatterWebGLProgram.js +23 -81
  161. package/ScatterChartPremium/webgl/ScatterWebGLProgram.mjs +23 -81
  162. package/index.js +1 -1
  163. package/index.mjs +1 -1
  164. package/internals/createGetVisibleCoordinate.d.mts +14 -0
  165. package/internals/createGetVisibleCoordinate.d.ts +14 -0
  166. package/internals/createGetVisibleCoordinate.js +66 -0
  167. package/internals/createGetVisibleCoordinate.mjs +60 -0
  168. package/internals/plugins/useGeoProjection/factories.d.mts +3 -0
  169. package/internals/plugins/useGeoProjection/factories.d.ts +3 -0
  170. package/internals/plugins/useGeoProjection/factories.js +29 -0
  171. package/internals/plugins/useGeoProjection/factories.mjs +23 -0
  172. package/internals/plugins/useGeoProjection/projection.utils.d.mts +17 -0
  173. package/internals/plugins/useGeoProjection/projection.utils.d.ts +17 -0
  174. package/internals/plugins/useGeoProjection/projection.utils.js +67 -0
  175. package/internals/plugins/useGeoProjection/projection.utils.mjs +59 -0
  176. package/internals/plugins/useGeoProjection/useGeoProjection.js +7 -40
  177. package/internals/plugins/useGeoProjection/useGeoProjection.mjs +7 -40
  178. package/internals/plugins/useGeoProjection/useGeoProjection.selectors.d.mts +47 -11
  179. package/internals/plugins/useGeoProjection/useGeoProjection.selectors.d.ts +47 -11
  180. package/internals/plugins/useGeoProjection/useGeoProjection.selectors.js +118 -8
  181. package/internals/plugins/useGeoProjection/useGeoProjection.selectors.mjs +117 -8
  182. package/internals/plugins/useGeoProjection/useGeoProjection.types.d.mts +63 -2
  183. package/internals/plugins/useGeoProjection/useGeoProjection.types.d.ts +63 -2
  184. package/internals/plugins/useGeoProjectionZoom/gestureHooks/usePanOnDrag.d.mts +11 -0
  185. package/internals/plugins/useGeoProjectionZoom/gestureHooks/usePanOnDrag.d.ts +11 -0
  186. package/internals/plugins/useGeoProjectionZoom/gestureHooks/usePanOnDrag.js +65 -0
  187. package/internals/plugins/useGeoProjectionZoom/gestureHooks/usePanOnDrag.mjs +58 -0
  188. package/internals/plugins/useGeoProjectionZoom/gestureHooks/useZoomOnPinch.d.mts +13 -0
  189. package/internals/plugins/useGeoProjectionZoom/gestureHooks/useZoomOnPinch.d.ts +13 -0
  190. package/internals/plugins/useGeoProjectionZoom/gestureHooks/useZoomOnPinch.js +62 -0
  191. package/internals/plugins/useGeoProjectionZoom/gestureHooks/useZoomOnPinch.mjs +56 -0
  192. package/internals/plugins/useGeoProjectionZoom/gestureHooks/useZoomOnWheel.d.mts +13 -0
  193. package/internals/plugins/useGeoProjectionZoom/gestureHooks/useZoomOnWheel.d.ts +13 -0
  194. package/internals/plugins/useGeoProjectionZoom/gestureHooks/useZoomOnWheel.js +64 -0
  195. package/internals/plugins/useGeoProjectionZoom/gestureHooks/useZoomOnWheel.mjs +58 -0
  196. package/internals/plugins/useGeoProjectionZoom/index.d.mts +2 -0
  197. package/internals/plugins/useGeoProjectionZoom/index.d.ts +2 -0
  198. package/internals/plugins/useGeoProjectionZoom/index.js +12 -0
  199. package/internals/plugins/useGeoProjectionZoom/index.mjs +1 -0
  200. package/internals/plugins/useGeoProjectionZoom/mapZoom.utils.d.mts +31 -0
  201. package/internals/plugins/useGeoProjectionZoom/mapZoom.utils.d.ts +31 -0
  202. package/internals/plugins/useGeoProjectionZoom/mapZoom.utils.js +187 -0
  203. package/internals/plugins/useGeoProjectionZoom/mapZoom.utils.mjs +177 -0
  204. package/internals/plugins/useGeoProjectionZoom/rotationMath.d.mts +23 -0
  205. package/internals/plugins/useGeoProjectionZoom/rotationMath.d.ts +23 -0
  206. package/internals/plugins/useGeoProjectionZoom/rotationMath.js +190 -0
  207. package/internals/plugins/useGeoProjectionZoom/rotationMath.mjs +182 -0
  208. package/internals/plugins/useGeoProjectionZoom/useGeoProjectionZoom.d.mts +3 -0
  209. package/internals/plugins/useGeoProjectionZoom/useGeoProjectionZoom.d.ts +3 -0
  210. package/internals/plugins/useGeoProjectionZoom/useGeoProjectionZoom.js +174 -0
  211. package/internals/plugins/useGeoProjectionZoom/useGeoProjectionZoom.mjs +166 -0
  212. package/internals/plugins/useGeoProjectionZoom/useGeoProjectionZoom.types.d.mts +152 -0
  213. package/internals/plugins/useGeoProjectionZoom/useGeoProjectionZoom.types.d.ts +152 -0
  214. package/internals/plugins/useGeoProjectionZoom/useGeoProjectionZoom.types.js +5 -0
  215. package/internals/plugins/useGeoProjectionZoom/useGeoProjectionZoom.types.mjs +1 -0
  216. package/models/seriesType/mapShape.d.mts +2 -1
  217. package/models/seriesType/mapShape.d.ts +2 -1
  218. package/package.json +6 -6
  219. package/utils/webgl/glsl.d.mts +15 -0
  220. package/utils/webgl/glsl.d.ts +15 -0
  221. package/utils/webgl/glsl.js +34 -0
  222. package/utils/webgl/glsl.mjs +28 -0
  223. package/utils/webgl/instancedAttribute.d.mts +28 -0
  224. package/utils/webgl/instancedAttribute.d.ts +28 -0
  225. package/utils/webgl/instancedAttribute.js +57 -0
  226. package/utils/webgl/instancedAttribute.mjs +50 -0
  227. package/utils/webgl/utils.d.mts +21 -2
  228. package/utils/webgl/utils.d.ts +21 -2
  229. package/utils/webgl/utils.js +44 -8
  230. package/utils/webgl/utils.mjs +41 -7
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Given the current d3 `rotate` `[lambda, phi, gamma]` (degrees), returns the new
3
+ * `[longitude, latitude, roll]` (the view `center` plus `roll`) that drags `geoPoint` onto the
4
+ * identity-frame screen coordinate `q` using the shortest-arc rotation composed with the current
5
+ * orientation. Because the delta is the minimal rotation moving the grabbed point to the target, the
6
+ * roll only changes as much as strictly required.
7
+ */
8
+ export declare function getMinimalRollRotation(rotate: [number, number, number], geoPoint: [number, number], targetGeoPoint: [number, number]): [number, number, number];
9
+ /**
10
+ * Given the current d3 `rotate` `[lambda, phi, gamma]` (degrees), returns the
11
+ * `[longitude, latitude, roll]` that drags `geoPoint` onto the identity-frame screen coordinate
12
+ * `targetGeoPoint` while keeping the roll (`gamma`) unchanged: only the longitude and latitude move.
13
+ * When the target is out of reach for a roll-preserving rotation, the closest reachable orientation
14
+ * is returned.
15
+ */
16
+ export declare function getNoRollRotation(rotate: [number, number, number], geoPoint: [number, number], targetGeoPoint: [number, number]): [number, number, number];
17
+ /**
18
+ * Given the current d3 `rotate` `[lambda, phi, gamma]` (degrees), returns the
19
+ * `[longitude, latitude, roll]` that pans `geoPoint` toward the identity-frame screen coordinate
20
+ * `targetGeoPoint` along the longitude axis only: the latitude and roll are left untouched and just
21
+ * the longitude is solved so `geoPoint` reaches the target's longitude.
22
+ */
23
+ export declare function getLongitudeRotation(rotate: [number, number, number], geoPoint: [number, number], targetGeoPoint: [number, number]): [number, number, number];
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Given the current d3 `rotate` `[lambda, phi, gamma]` (degrees), returns the new
3
+ * `[longitude, latitude, roll]` (the view `center` plus `roll`) that drags `geoPoint` onto the
4
+ * identity-frame screen coordinate `q` using the shortest-arc rotation composed with the current
5
+ * orientation. Because the delta is the minimal rotation moving the grabbed point to the target, the
6
+ * roll only changes as much as strictly required.
7
+ */
8
+ export declare function getMinimalRollRotation(rotate: [number, number, number], geoPoint: [number, number], targetGeoPoint: [number, number]): [number, number, number];
9
+ /**
10
+ * Given the current d3 `rotate` `[lambda, phi, gamma]` (degrees), returns the
11
+ * `[longitude, latitude, roll]` that drags `geoPoint` onto the identity-frame screen coordinate
12
+ * `targetGeoPoint` while keeping the roll (`gamma`) unchanged: only the longitude and latitude move.
13
+ * When the target is out of reach for a roll-preserving rotation, the closest reachable orientation
14
+ * is returned.
15
+ */
16
+ export declare function getNoRollRotation(rotate: [number, number, number], geoPoint: [number, number], targetGeoPoint: [number, number]): [number, number, number];
17
+ /**
18
+ * Given the current d3 `rotate` `[lambda, phi, gamma]` (degrees), returns the
19
+ * `[longitude, latitude, roll]` that pans `geoPoint` toward the identity-frame screen coordinate
20
+ * `targetGeoPoint` along the longitude axis only: the latitude and roll are left untouched and just
21
+ * the longitude is solved so `geoPoint` reaches the target's longitude.
22
+ */
23
+ export declare function getLongitudeRotation(rotate: [number, number, number], geoPoint: [number, number], targetGeoPoint: [number, number]): [number, number, number];
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getLongitudeRotation = getLongitudeRotation;
7
+ exports.getMinimalRollRotation = getMinimalRollRotation;
8
+ exports.getNoRollRotation = getNoRollRotation;
9
+ const DEG = Math.PI / 180;
10
+ const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
11
+
12
+ /**
13
+ * Rotate a `[longitude, latitude]` coordinate around the projection's center axis (the x-axis
14
+ * pointing to `[0, 0]`) by `gamma` degrees.
15
+ *
16
+ * This is the roll component of a d3 rotation `[lambda, phi, gamma]`, isolated so it can be undone
17
+ * on the target coordinate before solving the longitude/latitude rotation. A d3 rotation composes as
18
+ * `rollGamma ∘ geoRotation([lambda, phi])`, so pre-applying `rollGamma(-gamma)` to the target keeps
19
+ * the roll fixed while the yaw/pitch solver stays a two-angle problem.
20
+ */
21
+ function rollCoordinate(coord, gamma) {
22
+ if (!gamma) {
23
+ return coord;
24
+ }
25
+ const g = gamma * DEG;
26
+ const cosG = Math.cos(g);
27
+ const sinG = Math.sin(g);
28
+ const lon = coord[0] * DEG;
29
+ const lat = coord[1] * DEG;
30
+ const x = Math.cos(lon) * Math.cos(lat);
31
+ const y = Math.sin(lon) * Math.cos(lat);
32
+ const z = Math.sin(lat);
33
+ // Rotation about the x-axis by `g`.
34
+ const yRolled = y * cosG - z * sinG;
35
+ const zRolled = y * sinG + z * cosG;
36
+ return [Math.atan2(yRolled, x) / DEG, Math.asin(clamp(zRolled, -1, 1)) / DEG];
37
+ }
38
+ const cross = (a, b) => [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
39
+
40
+ /**
41
+ * Unit vector on the sphere for a `[longitude, latitude]` coordinate (degrees).
42
+ */
43
+ function unitVector([lonDeg, latDeg]) {
44
+ const lon = lonDeg * DEG;
45
+ const lat = latDeg * DEG;
46
+ const cosLat = Math.cos(lat);
47
+ return [Math.cos(lon) * cosLat, Math.sin(lon) * cosLat, Math.sin(lat)];
48
+ }
49
+
50
+ /**
51
+ * Rotate vector `v` around the unit axis `k` by `angle` radians (Rodrigues' rotation formula).
52
+ */
53
+ function rotateAroundAxis(k, angle, v) {
54
+ const cos = Math.cos(angle);
55
+ const sin = Math.sin(angle);
56
+ const dot = (k[0] * v[0] + k[1] * v[1] + k[2] * v[2]) * (1 - cos);
57
+ const kv = cross(k, v);
58
+ return [v[0] * cos + kv[0] * sin + k[0] * dot, v[1] * cos + kv[1] * sin + k[1] * dot, v[2] * cos + kv[2] * sin + k[2] * dot];
59
+ }
60
+
61
+ /**
62
+ * Given the current d3 `rotate` `[lambda, phi, gamma]` (degrees), returns the new
63
+ * `[longitude, latitude, roll]` (the view `center` plus `roll`) that drags `geoPoint` onto the
64
+ * identity-frame screen coordinate `q` using the shortest-arc rotation composed with the current
65
+ * orientation. Because the delta is the minimal rotation moving the grabbed point to the target, the
66
+ * roll only changes as much as strictly required.
67
+ */
68
+ function getMinimalRollRotation(rotate, geoPoint, targetGeoPoint) {
69
+ const l = rotate[0] * DEG;
70
+ const p = rotate[1] * DEG;
71
+ const g = (rotate[2] ?? 0) * DEG;
72
+ const cl = Math.cos(l);
73
+ const sl = Math.sin(l);
74
+ const cp = Math.cos(p);
75
+ const sp = Math.sin(p);
76
+ const cg = Math.cos(g);
77
+ const sg = Math.sin(g);
78
+
79
+ // Columns of the current rotation matrix `M = Rx(g)·Ry(-p)·Rz(l)`, which is exactly
80
+ // d3's `geoRotation([lambda, phi, gamma])` expressed on cartesian unit vectors.
81
+ const col0 = [cp * cl, cg * sl - sg * sp * cl, sg * sl + cg * sp * cl];
82
+ const col1 = [-cp * sl, cg * cl + sg * sp * sl, sg * cl - cg * sp * sl];
83
+ const col2 = [-sp, -sg * cp, cg * cp];
84
+ const point = unitVector(geoPoint);
85
+ // Where the grabbed point currently sits in the identity (screen) frame: `M · point`.
86
+ const current = [col0[0] * point[0] + col1[0] * point[1] + col2[0] * point[2], col0[1] * point[0] + col1[1] * point[1] + col2[1] * point[2], col0[2] * point[0] + col1[2] * point[1] + col2[2] * point[2]];
87
+ const target = unitVector(targetGeoPoint);
88
+
89
+ // Shortest-arc rotation taking `current` onto `target`, applied to `M` column by column
90
+ // (`M_new = delta · M`).
91
+ const axis = cross(current, target);
92
+ const s = Math.hypot(axis[0], axis[1], axis[2]);
93
+ let n0 = col0;
94
+ let n1 = col1;
95
+ let n2 = col2;
96
+ if (s > 1e-12) {
97
+ const dot = clamp(current[0] * target[0] + current[1] * target[1] + current[2] * target[2], -1, 1);
98
+ const angle = Math.atan2(s, dot);
99
+ const k = [axis[0] / s, axis[1] / s, axis[2] / s];
100
+ n0 = rotateAroundAxis(k, angle, col0);
101
+ n1 = rotateAroundAxis(k, angle, col1);
102
+ n2 = rotateAroundAxis(k, angle, col2);
103
+ }
104
+
105
+ // Decompose `M_new = Rx(g')·Ry(-p')·Rz(l')` back into d3 angles.
106
+ const phi = Math.asin(clamp(-n2[0], -1, 1));
107
+ const lambda = Math.atan2(-n1[0], n0[0]);
108
+ const gamma = Math.atan2(-n2[1], n2[2]);
109
+
110
+ // `rotate = [-center[0], -center[1], roll]`, so invert the sign for the view center.
111
+ return [-lambda / DEG, -phi / DEG, gamma / DEG];
112
+ }
113
+
114
+ /**
115
+ * Given the current d3 `rotate` `[lambda, phi, gamma]` (degrees), returns the
116
+ * `[longitude, latitude, roll]` that drags `geoPoint` onto the identity-frame screen coordinate
117
+ * `targetGeoPoint` while keeping the roll (`gamma`) unchanged: only the longitude and latitude move.
118
+ * When the target is out of reach for a roll-preserving rotation, the closest reachable orientation
119
+ * is returned.
120
+ */
121
+ function getNoRollRotation(rotate, geoPoint, targetGeoPoint) {
122
+ const roll = rotate[2] ?? 0;
123
+
124
+ // A d3 rotation composes as `rollGamma ∘ geoRotation([lambda, phi])`, so undo the roll on the
125
+ // target: what remains is a plain (roll-free) `Ry(-phi)·Rz(lambda)` mapping `geoPoint` onto it.
126
+ const [px, py, pz] = unitVector(geoPoint);
127
+ const [tx, ty, tz] = unitVector(rollCoordinate(targetGeoPoint, -roll));
128
+ const lambdaOld = rotate[0] * DEG;
129
+ const phiOld = rotate[1] * DEG;
130
+
131
+ // `Rz(lambda)` spins `geoPoint` on the circle of radius `r` in the xy-plane, keeping its
132
+ // z-component; `Ry(-phi)` then tilts it. So after `Rz` the y-component (`uy`) must already equal
133
+ // the target's, and the xy-radius bounds how far the latitude can reach.
134
+ const r = Math.hypot(px, py);
135
+ if (r < 1e-12) {
136
+ // `geoPoint` sits on a pole where `Rz(lambda)` is a no-op: keep the current longitude and only
137
+ // solve the tilt.
138
+ const phi = Math.atan2(tz, tx) - Math.atan2(pz, 0);
139
+ return [-lambdaOld / DEG, -phi / DEG, roll];
140
+ }
141
+
142
+ // `clamp` keeps the nearest reachable point when the target latitude is out of range (`|ty| > r`).
143
+ const uy = clamp(ty, -r, r);
144
+ const uxMagnitude = Math.sqrt(Math.max(0, r * r - uy * uy));
145
+ const solveFor = ux => ({
146
+ // `Rz(lambda)` rotates `(px, py)` onto `(ux, uy)`.
147
+ lambda: Math.atan2(uy, ux) - Math.atan2(py, px),
148
+ // `Ry(-phi)` rotates `(ux, pz)` onto `(tx, tz)`.
149
+ phi: Math.atan2(tz, tx) - Math.atan2(pz, ux)
150
+ });
151
+
152
+ // Two branches (`±ux`) solve the equation; pick the one closest to the current orientation so the
153
+ // rotation stays continuous while dragging.
154
+ const wrap = angle => Math.atan2(Math.sin(angle), Math.cos(angle));
155
+ const distanceToCurrent = ({
156
+ lambda,
157
+ phi
158
+ }) => Math.abs(wrap(lambda - lambdaOld)) + Math.abs(wrap(phi - phiOld));
159
+ const positive = solveFor(uxMagnitude);
160
+ const negative = solveFor(-uxMagnitude);
161
+ const best = distanceToCurrent(positive) <= distanceToCurrent(negative) ? positive : negative;
162
+ return [-best.lambda / DEG, -best.phi / DEG, roll];
163
+ }
164
+
165
+ /**
166
+ * Given the current d3 `rotate` `[lambda, phi, gamma]` (degrees), returns the
167
+ * `[longitude, latitude, roll]` that pans `geoPoint` toward the identity-frame screen coordinate
168
+ * `targetGeoPoint` along the longitude axis only: the latitude and roll are left untouched and just
169
+ * the longitude is solved so `geoPoint` reaches the target's longitude.
170
+ */
171
+ function getLongitudeRotation(rotate, geoPoint, targetGeoPoint) {
172
+ const roll = rotate[2] ?? 0;
173
+ const latitude = -rotate[1]; // the fixed center latitude (degrees)
174
+
175
+ // Undo the roll on the target, then keep the pitch locked to the current latitude and solve the
176
+ // yaw so `geoPoint` lands on the target's longitude.
177
+ const [tx, ty, tz] = unitVector(rollCoordinate(targetGeoPoint, -roll));
178
+ const lonG = geoPoint[0] * DEG;
179
+ const c1 = latitude * DEG;
180
+ const c0 = lonG - Math.atan2(ty, tx * Math.cos(c1) - tz * Math.sin(c1));
181
+
182
+ // Normalize the longitude into `[-180, 180]`.
183
+ let longitude = c0 / DEG % 360;
184
+ if (longitude > 180) {
185
+ longitude -= 360;
186
+ } else if (longitude < -180) {
187
+ longitude += 360;
188
+ }
189
+ return [longitude, latitude, roll];
190
+ }
@@ -0,0 +1,182 @@
1
+ const DEG = Math.PI / 180;
2
+ const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
3
+
4
+ /**
5
+ * Rotate a `[longitude, latitude]` coordinate around the projection's center axis (the x-axis
6
+ * pointing to `[0, 0]`) by `gamma` degrees.
7
+ *
8
+ * This is the roll component of a d3 rotation `[lambda, phi, gamma]`, isolated so it can be undone
9
+ * on the target coordinate before solving the longitude/latitude rotation. A d3 rotation composes as
10
+ * `rollGamma ∘ geoRotation([lambda, phi])`, so pre-applying `rollGamma(-gamma)` to the target keeps
11
+ * the roll fixed while the yaw/pitch solver stays a two-angle problem.
12
+ */
13
+ function rollCoordinate(coord, gamma) {
14
+ if (!gamma) {
15
+ return coord;
16
+ }
17
+ const g = gamma * DEG;
18
+ const cosG = Math.cos(g);
19
+ const sinG = Math.sin(g);
20
+ const lon = coord[0] * DEG;
21
+ const lat = coord[1] * DEG;
22
+ const x = Math.cos(lon) * Math.cos(lat);
23
+ const y = Math.sin(lon) * Math.cos(lat);
24
+ const z = Math.sin(lat);
25
+ // Rotation about the x-axis by `g`.
26
+ const yRolled = y * cosG - z * sinG;
27
+ const zRolled = y * sinG + z * cosG;
28
+ return [Math.atan2(yRolled, x) / DEG, Math.asin(clamp(zRolled, -1, 1)) / DEG];
29
+ }
30
+ const cross = (a, b) => [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
31
+
32
+ /**
33
+ * Unit vector on the sphere for a `[longitude, latitude]` coordinate (degrees).
34
+ */
35
+ function unitVector([lonDeg, latDeg]) {
36
+ const lon = lonDeg * DEG;
37
+ const lat = latDeg * DEG;
38
+ const cosLat = Math.cos(lat);
39
+ return [Math.cos(lon) * cosLat, Math.sin(lon) * cosLat, Math.sin(lat)];
40
+ }
41
+
42
+ /**
43
+ * Rotate vector `v` around the unit axis `k` by `angle` radians (Rodrigues' rotation formula).
44
+ */
45
+ function rotateAroundAxis(k, angle, v) {
46
+ const cos = Math.cos(angle);
47
+ const sin = Math.sin(angle);
48
+ const dot = (k[0] * v[0] + k[1] * v[1] + k[2] * v[2]) * (1 - cos);
49
+ const kv = cross(k, v);
50
+ return [v[0] * cos + kv[0] * sin + k[0] * dot, v[1] * cos + kv[1] * sin + k[1] * dot, v[2] * cos + kv[2] * sin + k[2] * dot];
51
+ }
52
+
53
+ /**
54
+ * Given the current d3 `rotate` `[lambda, phi, gamma]` (degrees), returns the new
55
+ * `[longitude, latitude, roll]` (the view `center` plus `roll`) that drags `geoPoint` onto the
56
+ * identity-frame screen coordinate `q` using the shortest-arc rotation composed with the current
57
+ * orientation. Because the delta is the minimal rotation moving the grabbed point to the target, the
58
+ * roll only changes as much as strictly required.
59
+ */
60
+ export function getMinimalRollRotation(rotate, geoPoint, targetGeoPoint) {
61
+ const l = rotate[0] * DEG;
62
+ const p = rotate[1] * DEG;
63
+ const g = (rotate[2] ?? 0) * DEG;
64
+ const cl = Math.cos(l);
65
+ const sl = Math.sin(l);
66
+ const cp = Math.cos(p);
67
+ const sp = Math.sin(p);
68
+ const cg = Math.cos(g);
69
+ const sg = Math.sin(g);
70
+
71
+ // Columns of the current rotation matrix `M = Rx(g)·Ry(-p)·Rz(l)`, which is exactly
72
+ // d3's `geoRotation([lambda, phi, gamma])` expressed on cartesian unit vectors.
73
+ const col0 = [cp * cl, cg * sl - sg * sp * cl, sg * sl + cg * sp * cl];
74
+ const col1 = [-cp * sl, cg * cl + sg * sp * sl, sg * cl - cg * sp * sl];
75
+ const col2 = [-sp, -sg * cp, cg * cp];
76
+ const point = unitVector(geoPoint);
77
+ // Where the grabbed point currently sits in the identity (screen) frame: `M · point`.
78
+ const current = [col0[0] * point[0] + col1[0] * point[1] + col2[0] * point[2], col0[1] * point[0] + col1[1] * point[1] + col2[1] * point[2], col0[2] * point[0] + col1[2] * point[1] + col2[2] * point[2]];
79
+ const target = unitVector(targetGeoPoint);
80
+
81
+ // Shortest-arc rotation taking `current` onto `target`, applied to `M` column by column
82
+ // (`M_new = delta · M`).
83
+ const axis = cross(current, target);
84
+ const s = Math.hypot(axis[0], axis[1], axis[2]);
85
+ let n0 = col0;
86
+ let n1 = col1;
87
+ let n2 = col2;
88
+ if (s > 1e-12) {
89
+ const dot = clamp(current[0] * target[0] + current[1] * target[1] + current[2] * target[2], -1, 1);
90
+ const angle = Math.atan2(s, dot);
91
+ const k = [axis[0] / s, axis[1] / s, axis[2] / s];
92
+ n0 = rotateAroundAxis(k, angle, col0);
93
+ n1 = rotateAroundAxis(k, angle, col1);
94
+ n2 = rotateAroundAxis(k, angle, col2);
95
+ }
96
+
97
+ // Decompose `M_new = Rx(g')·Ry(-p')·Rz(l')` back into d3 angles.
98
+ const phi = Math.asin(clamp(-n2[0], -1, 1));
99
+ const lambda = Math.atan2(-n1[0], n0[0]);
100
+ const gamma = Math.atan2(-n2[1], n2[2]);
101
+
102
+ // `rotate = [-center[0], -center[1], roll]`, so invert the sign for the view center.
103
+ return [-lambda / DEG, -phi / DEG, gamma / DEG];
104
+ }
105
+
106
+ /**
107
+ * Given the current d3 `rotate` `[lambda, phi, gamma]` (degrees), returns the
108
+ * `[longitude, latitude, roll]` that drags `geoPoint` onto the identity-frame screen coordinate
109
+ * `targetGeoPoint` while keeping the roll (`gamma`) unchanged: only the longitude and latitude move.
110
+ * When the target is out of reach for a roll-preserving rotation, the closest reachable orientation
111
+ * is returned.
112
+ */
113
+ export function getNoRollRotation(rotate, geoPoint, targetGeoPoint) {
114
+ const roll = rotate[2] ?? 0;
115
+
116
+ // A d3 rotation composes as `rollGamma ∘ geoRotation([lambda, phi])`, so undo the roll on the
117
+ // target: what remains is a plain (roll-free) `Ry(-phi)·Rz(lambda)` mapping `geoPoint` onto it.
118
+ const [px, py, pz] = unitVector(geoPoint);
119
+ const [tx, ty, tz] = unitVector(rollCoordinate(targetGeoPoint, -roll));
120
+ const lambdaOld = rotate[0] * DEG;
121
+ const phiOld = rotate[1] * DEG;
122
+
123
+ // `Rz(lambda)` spins `geoPoint` on the circle of radius `r` in the xy-plane, keeping its
124
+ // z-component; `Ry(-phi)` then tilts it. So after `Rz` the y-component (`uy`) must already equal
125
+ // the target's, and the xy-radius bounds how far the latitude can reach.
126
+ const r = Math.hypot(px, py);
127
+ if (r < 1e-12) {
128
+ // `geoPoint` sits on a pole where `Rz(lambda)` is a no-op: keep the current longitude and only
129
+ // solve the tilt.
130
+ const phi = Math.atan2(tz, tx) - Math.atan2(pz, 0);
131
+ return [-lambdaOld / DEG, -phi / DEG, roll];
132
+ }
133
+
134
+ // `clamp` keeps the nearest reachable point when the target latitude is out of range (`|ty| > r`).
135
+ const uy = clamp(ty, -r, r);
136
+ const uxMagnitude = Math.sqrt(Math.max(0, r * r - uy * uy));
137
+ const solveFor = ux => ({
138
+ // `Rz(lambda)` rotates `(px, py)` onto `(ux, uy)`.
139
+ lambda: Math.atan2(uy, ux) - Math.atan2(py, px),
140
+ // `Ry(-phi)` rotates `(ux, pz)` onto `(tx, tz)`.
141
+ phi: Math.atan2(tz, tx) - Math.atan2(pz, ux)
142
+ });
143
+
144
+ // Two branches (`±ux`) solve the equation; pick the one closest to the current orientation so the
145
+ // rotation stays continuous while dragging.
146
+ const wrap = angle => Math.atan2(Math.sin(angle), Math.cos(angle));
147
+ const distanceToCurrent = ({
148
+ lambda,
149
+ phi
150
+ }) => Math.abs(wrap(lambda - lambdaOld)) + Math.abs(wrap(phi - phiOld));
151
+ const positive = solveFor(uxMagnitude);
152
+ const negative = solveFor(-uxMagnitude);
153
+ const best = distanceToCurrent(positive) <= distanceToCurrent(negative) ? positive : negative;
154
+ return [-best.lambda / DEG, -best.phi / DEG, roll];
155
+ }
156
+
157
+ /**
158
+ * Given the current d3 `rotate` `[lambda, phi, gamma]` (degrees), returns the
159
+ * `[longitude, latitude, roll]` that pans `geoPoint` toward the identity-frame screen coordinate
160
+ * `targetGeoPoint` along the longitude axis only: the latitude and roll are left untouched and just
161
+ * the longitude is solved so `geoPoint` reaches the target's longitude.
162
+ */
163
+ export function getLongitudeRotation(rotate, geoPoint, targetGeoPoint) {
164
+ const roll = rotate[2] ?? 0;
165
+ const latitude = -rotate[1]; // the fixed center latitude (degrees)
166
+
167
+ // Undo the roll on the target, then keep the pitch locked to the current latitude and solve the
168
+ // yaw so `geoPoint` lands on the target's longitude.
169
+ const [tx, ty, tz] = unitVector(rollCoordinate(targetGeoPoint, -roll));
170
+ const lonG = geoPoint[0] * DEG;
171
+ const c1 = latitude * DEG;
172
+ const c0 = lonG - Math.atan2(ty, tx * Math.cos(c1) - tz * Math.sin(c1));
173
+
174
+ // Normalize the longitude into `[-180, 180]`.
175
+ let longitude = c0 / DEG % 360;
176
+ if (longitude > 180) {
177
+ longitude -= 360;
178
+ } else if (longitude < -180) {
179
+ longitude += 360;
180
+ }
181
+ return [longitude, latitude, roll];
182
+ }
@@ -0,0 +1,3 @@
1
+ import type { ChartPlugin } from '@mui/x-charts/internals';
2
+ import type { UseGeoProjectionZoomSignature } from "./useGeoProjectionZoom.types.mjs";
3
+ export declare const useGeoProjectionZoom: ChartPlugin<UseGeoProjectionZoomSignature>;
@@ -0,0 +1,3 @@
1
+ import type { ChartPlugin } from '@mui/x-charts/internals';
2
+ import type { UseGeoProjectionZoomSignature } from "./useGeoProjectionZoom.types.js";
3
+ export declare const useGeoProjectionZoom: ChartPlugin<UseGeoProjectionZoomSignature>;
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ 'use client';
3
+
4
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
5
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
6
+ Object.defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ exports.useGeoProjectionZoom = void 0;
10
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
+ var React = _interopRequireWildcard(require("react"));
12
+ var _useEffectAfterFirstRender = require("@mui/x-internals/useEffectAfterFirstRender");
13
+ var _internals = require("@mui/x-charts-pro/internals");
14
+ var _useGeoProjection = require("../useGeoProjection/useGeoProjection.selectors");
15
+ var _mapZoom = require("./mapZoom.utils");
16
+ var _usePanOnDrag = require("./gestureHooks/usePanOnDrag");
17
+ var _useZoomOnWheel = require("./gestureHooks/useZoomOnWheel");
18
+ var _useZoomOnPinch = require("./gestureHooks/useZoomOnPinch");
19
+ var _projection = require("../useGeoProjection/projection.utils");
20
+ const useGeoProjectionZoom = ({
21
+ store,
22
+ instance,
23
+ params
24
+ }) => {
25
+ const {
26
+ zoom,
27
+ onViewChange,
28
+ view
29
+ } = params;
30
+ const interactionDefaults = (0, _mapZoom.getDefaultMapInteraction)((0, _useGeoProjection.selectorChartRawProjection)(store.state));
31
+ const {
32
+ minZoomLevel = 0.5,
33
+ maxZoomLevel = 8,
34
+ maxEmptySpace = 0,
35
+ rotationAllowed = interactionDefaults.rotationAllowed,
36
+ translationAllowed = interactionDefaults.translationAllowed
37
+ } = typeof zoom === 'object' ? zoom : {};
38
+
39
+ // `zoom` is either a boolean or a config object; an object always enables the interaction.
40
+ const enabled = zoom !== false;
41
+ const isControlled = view !== undefined;
42
+ const clampZoomLevel = React.useCallback(zoomLevel => Math.max(minZoomLevel, Math.min(maxZoomLevel, zoomLevel)), [minZoomLevel, maxZoomLevel]);
43
+
44
+ // The view is the source of truth, stored directly: no pixel <-> view conversion on write/read.
45
+ // Callers are responsible for clamping `zoomLevel`.
46
+ const applyView = React.useCallback(newView => {
47
+ if (!isControlled) {
48
+ store.set('geoProjectionZoom', (0, _extends2.default)({}, store.state.geoProjectionZoom, {
49
+ zoomLevel: newView.zoomLevel,
50
+ center: newView.center,
51
+ translation: newView.translation,
52
+ roll: newView.roll
53
+ }));
54
+ }
55
+ onViewChange?.(newView);
56
+ }, [store, isControlled, onViewChange]);
57
+
58
+ // In controlled mode, keep the store in sync with the `view` prop. The initial view is seeded in
59
+ // `getInitialState`, so this only reacts to subsequent updates.
60
+ (0, _useEffectAfterFirstRender.useEffectAfterFirstRender)(() => {
61
+ if (!view) {
62
+ return;
63
+ }
64
+ store.set('geoProjectionZoom', (0, _extends2.default)({}, store.state.geoProjectionZoom, {
65
+ zoomLevel: view.zoomLevel,
66
+ center: view.center,
67
+ translation: view.translation,
68
+ roll: view.roll
69
+ }));
70
+ }, [store, view]);
71
+ (0, _internals.useRegisterZoomGestures)({
72
+ instance
73
+ });
74
+
75
+ // --- gestures: reuse the generic primitives from x-charts-pro -------------
76
+ (0, _usePanOnDrag.usePanOnDrag)({
77
+ store,
78
+ instance
79
+ }, applyView, {
80
+ enabled,
81
+ rotationAllowed,
82
+ translationAllowed,
83
+ maxEmptySpace
84
+ });
85
+ (0, _useZoomOnWheel.useZoomOnWheel)({
86
+ store,
87
+ instance
88
+ }, applyView, {
89
+ enabled,
90
+ rotationAllowed,
91
+ translationAllowed,
92
+ maxEmptySpace,
93
+ minZoomLevel,
94
+ maxZoomLevel
95
+ });
96
+ (0, _useZoomOnPinch.useZoomOnPinch)({
97
+ store,
98
+ instance
99
+ }, applyView, {
100
+ enabled,
101
+ rotationAllowed,
102
+ translationAllowed,
103
+ maxEmptySpace,
104
+ minZoomLevel,
105
+ maxZoomLevel
106
+ });
107
+
108
+ // Shared by both buttons: clamp through `applyView` (which also handles controlled mode and
109
+ // `onViewChange`), keeping the current center/translation. Bail out when already at a bound so a
110
+ // click at the limit stays a no-op.
111
+ const zoomBy = React.useCallback(factor => {
112
+ const current = store.state.geoProjectionZoom;
113
+ const currentZoom = current.zoomLevel ?? 1;
114
+ const nextZoom = clampZoomLevel(currentZoom * factor);
115
+ if (nextZoom === currentZoom) {
116
+ return;
117
+ }
118
+ applyView({
119
+ zoomLevel: nextZoom,
120
+ center: current.center ?? [0, 0],
121
+ translation: current.translation ?? [0, 0],
122
+ roll: current.roll ?? 0
123
+ });
124
+ }, [store, clampZoomLevel, applyView]);
125
+ const zoomIn = React.useCallback(() => zoomBy(_mapZoom.BUTTON_ZOOM_STEP), [zoomBy]);
126
+ const zoomOut = React.useCallback(() => zoomBy(1 / _mapZoom.BUTTON_ZOOM_STEP), [zoomBy]);
127
+ const resetZoom = React.useCallback(() => {
128
+ applyView({
129
+ zoomLevel: store.state.geoProjectionZoom.initialZoomLevel,
130
+ center: store.state.geoProjectionZoom.initialCenter,
131
+ translation: store.state.geoProjectionZoom.initialTranslation,
132
+ roll: store.state.geoProjectionZoom.initialRoll
133
+ });
134
+ }, [applyView, store]);
135
+ const publicAPI = {
136
+ zoomIn,
137
+ zoomOut,
138
+ resetZoom
139
+ };
140
+ return {
141
+ publicAPI,
142
+ instance: publicAPI
143
+ };
144
+ };
145
+ exports.useGeoProjectionZoom = useGeoProjectionZoom;
146
+ useGeoProjectionZoom.params = {
147
+ zoom: true,
148
+ initialView: true,
149
+ view: true,
150
+ onViewChange: true
151
+ };
152
+ useGeoProjectionZoom.getDefaultizedParams = ({
153
+ params
154
+ }) => (0, _extends2.default)({}, params, {
155
+ zoom: params.zoom ?? false
156
+ });
157
+ useGeoProjectionZoom.getInitialState = params => {
158
+ const zoomLevel = params.view?.zoomLevel ?? params.initialView?.zoomLevel ?? 1;
159
+ const center = params.view?.center ?? params.initialView?.center ?? [0, 0];
160
+ const roll = params.view?.roll ?? params.initialView?.roll ?? 0;
161
+ const translation = params.view?.translation ?? params.initialView?.translation ?? (0, _projection.getDefaultTranslation)(params.projection, params.geoData, params.parallels, center) ?? [0, 0];
162
+ return {
163
+ geoProjectionZoom: {
164
+ zoomLevel,
165
+ center,
166
+ translation,
167
+ roll,
168
+ initialZoomLevel: zoomLevel,
169
+ initialCenter: center,
170
+ initialTranslation: translation,
171
+ initialRoll: roll
172
+ }
173
+ };
174
+ };