@gemx-dev/heatmap-react 3.5.44 → 3.5.45

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 (224) hide show
  1. package/dist/esm/components/Layout/HeatmapLayout.d.ts +3 -2
  2. package/dist/esm/components/Layout/HeatmapLayout.d.ts.map +1 -1
  3. package/dist/esm/components/VizDom/VizDomRenderer.d.ts.map +1 -1
  4. package/dist/esm/components/VizElement/HeatmapElements.d.ts +2 -2
  5. package/dist/esm/components/VizElement/HeatmapElements.d.ts.map +1 -1
  6. package/dist/esm/components/VizElement/HeatmapExample.d.ts +2 -0
  7. package/dist/esm/components/VizElement/HeatmapExample.d.ts.map +1 -0
  8. package/dist/esm/components/VizScrollmap/AverageFoldLine.d.ts +8 -0
  9. package/dist/esm/components/VizScrollmap/AverageFoldLine.d.ts.map +1 -0
  10. package/dist/esm/components/VizScrollmap/HoverZones.d.ts +10 -0
  11. package/dist/esm/components/VizScrollmap/HoverZones.d.ts.map +1 -0
  12. package/dist/esm/components/VizScrollmap/MetricRow.d.ts +1 -0
  13. package/dist/esm/components/VizScrollmap/MetricRow.d.ts.map +1 -0
  14. package/dist/esm/components/VizScrollmap/ScrollMapMinimap.d.ts +8 -0
  15. package/dist/esm/components/VizScrollmap/ScrollMapMinimap.d.ts.map +1 -0
  16. package/dist/esm/components/VizScrollmap/ScrollMapOverlay.d.ts +7 -0
  17. package/dist/esm/components/VizScrollmap/ScrollMapOverlay.d.ts.map +1 -0
  18. package/dist/esm/components/VizScrollmap/ScrollZoneHoverArea.d.ts +14 -0
  19. package/dist/esm/components/VizScrollmap/ScrollZoneHoverArea.d.ts.map +1 -0
  20. package/dist/esm/components/VizScrollmap/ScrollZoneTooltip.d.ts +10 -0
  21. package/dist/esm/components/VizScrollmap/ScrollZoneTooltip.d.ts.map +1 -0
  22. package/dist/esm/components/VizScrollmap/ScrollmapMarker.d.ts +7 -0
  23. package/dist/esm/components/VizScrollmap/ScrollmapMarker.d.ts.map +1 -0
  24. package/dist/esm/components/VizScrollmap/VizScrollMap.d.ts +7 -0
  25. package/dist/esm/components/VizScrollmap/VizScrollMap.d.ts.map +1 -0
  26. package/dist/esm/components/VizScrollmap/index.d.ts +2 -0
  27. package/dist/esm/components/VizScrollmap/index.d.ts.map +1 -0
  28. package/dist/esm/components/VizScrollmapV2/ScrollmapOverlayV2.d.ts +5 -0
  29. package/dist/esm/components/VizScrollmapV2/ScrollmapOverlayV2.d.ts.map +1 -0
  30. package/dist/esm/components/VizScrollmapV2/index.d.ts +2 -0
  31. package/dist/esm/components/VizScrollmapV2/index.d.ts.map +1 -0
  32. package/dist/esm/components/VizScrollmapV2/scrollmap.types.d.ts +18 -0
  33. package/dist/esm/components/VizScrollmapV2/scrollmap.types.d.ts.map +1 -0
  34. package/dist/esm/components/VizScrollmapV2/useScrollmapOverlay.d.ts +16 -0
  35. package/dist/esm/components/VizScrollmapV2/useScrollmapOverlay.d.ts.map +1 -0
  36. package/dist/esm/helpers/elm-getter.d.ts +2 -2
  37. package/dist/esm/helpers/elm-getter.d.ts.map +1 -1
  38. package/dist/esm/helpers/index.d.ts +1 -0
  39. package/dist/esm/helpers/index.d.ts.map +1 -1
  40. package/dist/esm/helpers/viz-canvas/area-clustering.d.ts +44 -0
  41. package/dist/esm/helpers/viz-canvas/area-clustering.d.ts.map +1 -0
  42. package/dist/esm/helpers/viz-canvas/area-overlay-manager-v2.d.ts +17 -0
  43. package/dist/esm/helpers/viz-canvas/area-overlay-manager-v2.d.ts.map +1 -0
  44. package/dist/esm/helpers/viz-canvas/area-overlay-manager.d.ts +51 -0
  45. package/dist/esm/helpers/viz-canvas/area-overlay-manager.d.ts.map +1 -0
  46. package/dist/esm/helpers/viz-canvas/hierarchical-area-clustering.d.ts +73 -0
  47. package/dist/esm/helpers/viz-canvas/hierarchical-area-clustering.d.ts.map +1 -0
  48. package/dist/esm/helpers/viz-canvas/index.d.ts +3 -0
  49. package/dist/esm/helpers/viz-canvas/index.d.ts.map +1 -0
  50. package/dist/esm/hooks/index.d.ts +2 -1
  51. package/dist/esm/hooks/index.d.ts.map +1 -1
  52. package/dist/esm/hooks/register/useRegisterData.d.ts +2 -2
  53. package/dist/esm/hooks/register/useRegisterData.d.ts.map +1 -1
  54. package/dist/esm/hooks/register/useRegisterHeatmap.d.ts +7 -2
  55. package/dist/esm/hooks/register/useRegisterHeatmap.d.ts.map +1 -1
  56. package/dist/esm/hooks/viz-area/useAreaHeatmap.d.ts +59 -0
  57. package/dist/esm/hooks/viz-area/useAreaHeatmap.d.ts.map +1 -0
  58. package/dist/esm/hooks/viz-area/useAreaHeatmapManager.d.ts +77 -0
  59. package/dist/esm/hooks/viz-area/useAreaHeatmapManager.d.ts.map +1 -0
  60. package/dist/esm/hooks/viz-canvas/index.d.ts +1 -1
  61. package/dist/esm/hooks/viz-canvas/index.d.ts.map +1 -1
  62. package/dist/esm/hooks/viz-canvas/useAreamap.d.ts +14 -0
  63. package/dist/esm/hooks/viz-canvas/useAreamap.d.ts.map +1 -0
  64. package/dist/esm/hooks/viz-canvas/useHeatmapCanvas.d.ts +4 -0
  65. package/dist/esm/hooks/viz-canvas/useHeatmapCanvas.d.ts.map +1 -0
  66. package/dist/esm/hooks/viz-canvas/useScrollmap.d.ts.map +1 -1
  67. package/dist/{umd/hooks/vix-elements → esm/hooks/viz-elements}/index.d.ts.map +1 -1
  68. package/dist/{umd/hooks/vix-elements → esm/hooks/viz-elements}/useClickedElement.d.ts.map +1 -1
  69. package/dist/esm/hooks/{vix-elements → viz-elements}/useElementCalloutVisible.d.ts.map +1 -1
  70. package/dist/esm/hooks/{vix-elements → viz-elements}/useHeatmapEffects.d.ts.map +1 -1
  71. package/dist/esm/hooks/{vix-elements → viz-elements}/useHeatmapElementPosition.d.ts.map +1 -1
  72. package/dist/esm/hooks/{vix-elements → viz-elements}/useHeatmapMouseHandler.d.ts +2 -2
  73. package/dist/esm/hooks/{vix-elements → viz-elements}/useHeatmapMouseHandler.d.ts.map +1 -1
  74. package/dist/{umd/hooks/vix-elements → esm/hooks/viz-elements}/useHoveredElement.d.ts +4 -0
  75. package/dist/esm/hooks/{vix-elements → viz-elements}/useHoveredElement.d.ts.map +1 -1
  76. package/dist/esm/hooks/viz-scrollmap/index.d.ts +3 -0
  77. package/dist/esm/hooks/viz-scrollmap/index.d.ts.map +1 -0
  78. package/dist/esm/hooks/viz-scrollmap/useScrollmapZones.d.ts +29 -0
  79. package/dist/esm/hooks/viz-scrollmap/useScrollmapZones.d.ts.map +1 -0
  80. package/dist/esm/hooks/viz-scrollmap/useZonePositions.d.ts +12 -0
  81. package/dist/esm/hooks/viz-scrollmap/useZonePositions.d.ts.map +1 -0
  82. package/dist/esm/index.js +470 -206
  83. package/dist/esm/index.mjs +470 -206
  84. package/dist/esm/stores/config.d.ts +5 -1
  85. package/dist/esm/stores/config.d.ts.map +1 -1
  86. package/dist/esm/stores/data.d.ts +5 -3
  87. package/dist/esm/stores/data.d.ts.map +1 -1
  88. package/dist/esm/stores/index.d.ts +1 -0
  89. package/dist/esm/stores/index.d.ts.map +1 -1
  90. package/dist/esm/stores/viz-scrollmap.d.ts +11 -0
  91. package/dist/esm/stores/viz-scrollmap.d.ts.map +1 -0
  92. package/dist/esm/types/clarity.d.ts +5 -0
  93. package/dist/esm/types/clarity.d.ts.map +1 -1
  94. package/dist/esm/types/heatmap-info.d.ts +11 -0
  95. package/dist/esm/types/heatmap-info.d.ts.map +1 -0
  96. package/dist/esm/types/heatmap.d.ts +13 -0
  97. package/dist/esm/types/heatmap.d.ts.map +1 -1
  98. package/dist/esm/types/index.d.ts +3 -0
  99. package/dist/esm/types/index.d.ts.map +1 -1
  100. package/dist/esm/types/viz-canvas.d.ts +23 -0
  101. package/dist/esm/types/viz-canvas.d.ts.map +1 -0
  102. package/dist/esm/types/viz-element.d.ts +0 -6
  103. package/dist/esm/types/viz-element.d.ts.map +1 -1
  104. package/dist/esm/types/viz-scrollmap.d.ts +27 -0
  105. package/dist/esm/types/viz-scrollmap.d.ts.map +1 -0
  106. package/dist/umd/components/Layout/HeatmapLayout.d.ts +3 -2
  107. package/dist/umd/components/Layout/HeatmapLayout.d.ts.map +1 -1
  108. package/dist/umd/components/VizDom/VizDomRenderer.d.ts.map +1 -1
  109. package/dist/umd/components/VizElement/HeatmapElements.d.ts +2 -2
  110. package/dist/umd/components/VizElement/HeatmapElements.d.ts.map +1 -1
  111. package/dist/umd/components/VizElement/HeatmapExample.d.ts +2 -0
  112. package/dist/umd/components/VizElement/HeatmapExample.d.ts.map +1 -0
  113. package/dist/umd/components/VizScrollmap/AverageFoldLine.d.ts +8 -0
  114. package/dist/umd/components/VizScrollmap/AverageFoldLine.d.ts.map +1 -0
  115. package/dist/umd/components/VizScrollmap/HoverZones.d.ts +10 -0
  116. package/dist/umd/components/VizScrollmap/HoverZones.d.ts.map +1 -0
  117. package/dist/umd/components/VizScrollmap/MetricRow.d.ts +1 -0
  118. package/dist/umd/components/VizScrollmap/MetricRow.d.ts.map +1 -0
  119. package/dist/umd/components/VizScrollmap/ScrollMapMinimap.d.ts +8 -0
  120. package/dist/umd/components/VizScrollmap/ScrollMapMinimap.d.ts.map +1 -0
  121. package/dist/umd/components/VizScrollmap/ScrollMapOverlay.d.ts +7 -0
  122. package/dist/umd/components/VizScrollmap/ScrollMapOverlay.d.ts.map +1 -0
  123. package/dist/umd/components/VizScrollmap/ScrollZoneHoverArea.d.ts +14 -0
  124. package/dist/umd/components/VizScrollmap/ScrollZoneHoverArea.d.ts.map +1 -0
  125. package/dist/umd/components/VizScrollmap/ScrollZoneTooltip.d.ts +10 -0
  126. package/dist/umd/components/VizScrollmap/ScrollZoneTooltip.d.ts.map +1 -0
  127. package/dist/umd/components/VizScrollmap/ScrollmapMarker.d.ts +7 -0
  128. package/dist/umd/components/VizScrollmap/ScrollmapMarker.d.ts.map +1 -0
  129. package/dist/umd/components/VizScrollmap/VizScrollMap.d.ts +7 -0
  130. package/dist/umd/components/VizScrollmap/VizScrollMap.d.ts.map +1 -0
  131. package/dist/umd/components/VizScrollmap/index.d.ts +2 -0
  132. package/dist/umd/components/VizScrollmap/index.d.ts.map +1 -0
  133. package/dist/umd/components/VizScrollmapV2/ScrollmapOverlayV2.d.ts +5 -0
  134. package/dist/umd/components/VizScrollmapV2/ScrollmapOverlayV2.d.ts.map +1 -0
  135. package/dist/umd/components/VizScrollmapV2/index.d.ts +2 -0
  136. package/dist/umd/components/VizScrollmapV2/index.d.ts.map +1 -0
  137. package/dist/umd/components/VizScrollmapV2/scrollmap.types.d.ts +18 -0
  138. package/dist/umd/components/VizScrollmapV2/scrollmap.types.d.ts.map +1 -0
  139. package/dist/umd/components/VizScrollmapV2/useScrollmapOverlay.d.ts +16 -0
  140. package/dist/umd/components/VizScrollmapV2/useScrollmapOverlay.d.ts.map +1 -0
  141. package/dist/umd/helpers/elm-getter.d.ts +2 -2
  142. package/dist/umd/helpers/elm-getter.d.ts.map +1 -1
  143. package/dist/umd/helpers/index.d.ts +1 -0
  144. package/dist/umd/helpers/index.d.ts.map +1 -1
  145. package/dist/umd/helpers/viz-canvas/area-clustering.d.ts +44 -0
  146. package/dist/umd/helpers/viz-canvas/area-clustering.d.ts.map +1 -0
  147. package/dist/umd/helpers/viz-canvas/area-overlay-manager-v2.d.ts +17 -0
  148. package/dist/umd/helpers/viz-canvas/area-overlay-manager-v2.d.ts.map +1 -0
  149. package/dist/umd/helpers/viz-canvas/area-overlay-manager.d.ts +51 -0
  150. package/dist/umd/helpers/viz-canvas/area-overlay-manager.d.ts.map +1 -0
  151. package/dist/umd/helpers/viz-canvas/hierarchical-area-clustering.d.ts +73 -0
  152. package/dist/umd/helpers/viz-canvas/hierarchical-area-clustering.d.ts.map +1 -0
  153. package/dist/umd/helpers/viz-canvas/index.d.ts +3 -0
  154. package/dist/umd/helpers/viz-canvas/index.d.ts.map +1 -0
  155. package/dist/umd/hooks/index.d.ts +2 -1
  156. package/dist/umd/hooks/index.d.ts.map +1 -1
  157. package/dist/umd/hooks/register/useRegisterData.d.ts +2 -2
  158. package/dist/umd/hooks/register/useRegisterData.d.ts.map +1 -1
  159. package/dist/umd/hooks/register/useRegisterHeatmap.d.ts +7 -2
  160. package/dist/umd/hooks/register/useRegisterHeatmap.d.ts.map +1 -1
  161. package/dist/umd/hooks/viz-area/useAreaHeatmap.d.ts +59 -0
  162. package/dist/umd/hooks/viz-area/useAreaHeatmap.d.ts.map +1 -0
  163. package/dist/umd/hooks/viz-area/useAreaHeatmapManager.d.ts +77 -0
  164. package/dist/umd/hooks/viz-area/useAreaHeatmapManager.d.ts.map +1 -0
  165. package/dist/umd/hooks/viz-canvas/index.d.ts +1 -1
  166. package/dist/umd/hooks/viz-canvas/index.d.ts.map +1 -1
  167. package/dist/umd/hooks/viz-canvas/useAreamap.d.ts +14 -0
  168. package/dist/umd/hooks/viz-canvas/useAreamap.d.ts.map +1 -0
  169. package/dist/umd/hooks/viz-canvas/useHeatmapCanvas.d.ts +4 -0
  170. package/dist/umd/hooks/viz-canvas/useHeatmapCanvas.d.ts.map +1 -0
  171. package/dist/umd/hooks/viz-canvas/useScrollmap.d.ts.map +1 -1
  172. package/dist/{esm/hooks/vix-elements → umd/hooks/viz-elements}/index.d.ts.map +1 -1
  173. package/dist/{esm/hooks/vix-elements → umd/hooks/viz-elements}/useClickedElement.d.ts.map +1 -1
  174. package/dist/umd/hooks/{vix-elements → viz-elements}/useElementCalloutVisible.d.ts.map +1 -1
  175. package/dist/umd/hooks/{vix-elements → viz-elements}/useHeatmapEffects.d.ts.map +1 -1
  176. package/dist/umd/hooks/{vix-elements → viz-elements}/useHeatmapElementPosition.d.ts.map +1 -1
  177. package/dist/umd/hooks/{vix-elements → viz-elements}/useHeatmapMouseHandler.d.ts +2 -2
  178. package/dist/umd/hooks/{vix-elements → viz-elements}/useHeatmapMouseHandler.d.ts.map +1 -1
  179. package/dist/{esm/hooks/vix-elements → umd/hooks/viz-elements}/useHoveredElement.d.ts +4 -0
  180. package/dist/umd/hooks/{vix-elements → viz-elements}/useHoveredElement.d.ts.map +1 -1
  181. package/dist/umd/hooks/viz-scrollmap/index.d.ts +3 -0
  182. package/dist/umd/hooks/viz-scrollmap/index.d.ts.map +1 -0
  183. package/dist/umd/hooks/viz-scrollmap/useScrollmapZones.d.ts +29 -0
  184. package/dist/umd/hooks/viz-scrollmap/useScrollmapZones.d.ts.map +1 -0
  185. package/dist/umd/hooks/viz-scrollmap/useZonePositions.d.ts +12 -0
  186. package/dist/umd/hooks/viz-scrollmap/useZonePositions.d.ts.map +1 -0
  187. package/dist/umd/index.js +2 -2
  188. package/dist/umd/stores/config.d.ts +5 -1
  189. package/dist/umd/stores/config.d.ts.map +1 -1
  190. package/dist/umd/stores/data.d.ts +5 -3
  191. package/dist/umd/stores/data.d.ts.map +1 -1
  192. package/dist/umd/stores/index.d.ts +1 -0
  193. package/dist/umd/stores/index.d.ts.map +1 -1
  194. package/dist/umd/stores/viz-scrollmap.d.ts +11 -0
  195. package/dist/umd/stores/viz-scrollmap.d.ts.map +1 -0
  196. package/dist/umd/types/clarity.d.ts +5 -0
  197. package/dist/umd/types/clarity.d.ts.map +1 -1
  198. package/dist/umd/types/heatmap-info.d.ts +11 -0
  199. package/dist/umd/types/heatmap-info.d.ts.map +1 -0
  200. package/dist/umd/types/heatmap.d.ts +13 -0
  201. package/dist/umd/types/heatmap.d.ts.map +1 -1
  202. package/dist/umd/types/index.d.ts +3 -0
  203. package/dist/umd/types/index.d.ts.map +1 -1
  204. package/dist/umd/types/viz-canvas.d.ts +23 -0
  205. package/dist/umd/types/viz-canvas.d.ts.map +1 -0
  206. package/dist/umd/types/viz-element.d.ts +0 -6
  207. package/dist/umd/types/viz-element.d.ts.map +1 -1
  208. package/dist/umd/types/viz-scrollmap.d.ts +27 -0
  209. package/dist/umd/types/viz-scrollmap.d.ts.map +1 -0
  210. package/package.json +1 -1
  211. package/dist/esm/hooks/viz-canvas/useHeatmapVizCanvas.d.ts +0 -2
  212. package/dist/esm/hooks/viz-canvas/useHeatmapVizCanvas.d.ts.map +0 -1
  213. package/dist/umd/hooks/viz-canvas/useHeatmapVizCanvas.d.ts +0 -2
  214. package/dist/umd/hooks/viz-canvas/useHeatmapVizCanvas.d.ts.map +0 -1
  215. /package/dist/esm/hooks/{vix-elements → viz-elements}/index.d.ts +0 -0
  216. /package/dist/esm/hooks/{vix-elements → viz-elements}/useClickedElement.d.ts +0 -0
  217. /package/dist/esm/hooks/{vix-elements → viz-elements}/useElementCalloutVisible.d.ts +0 -0
  218. /package/dist/esm/hooks/{vix-elements → viz-elements}/useHeatmapEffects.d.ts +0 -0
  219. /package/dist/esm/hooks/{vix-elements → viz-elements}/useHeatmapElementPosition.d.ts +0 -0
  220. /package/dist/umd/hooks/{vix-elements → viz-elements}/index.d.ts +0 -0
  221. /package/dist/umd/hooks/{vix-elements → viz-elements}/useClickedElement.d.ts +0 -0
  222. /package/dist/umd/hooks/{vix-elements → viz-elements}/useElementCalloutVisible.d.ts +0 -0
  223. /package/dist/umd/hooks/{vix-elements → viz-elements}/useHeatmapEffects.d.ts +0 -0
  224. /package/dist/umd/hooks/{vix-elements → viz-elements}/useHeatmapElementPosition.d.ts +0 -0
package/dist/esm/index.js CHANGED
@@ -93,18 +93,37 @@ var IHeatmapType;
93
93
  IHeatmapType["Click"] = "click";
94
94
  IHeatmapType["Scroll"] = "scroll";
95
95
  })(IHeatmapType || (IHeatmapType = {}));
96
+ var IClickType;
97
+ (function (IClickType) {
98
+ IClickType["Total"] = "total-clicks";
99
+ IClickType["Rage"] = "rage-clicks";
100
+ IClickType["Dead"] = "dead-clicks";
101
+ IClickType["Error"] = "error-clicks";
102
+ IClickType["First"] = "first-clicks";
103
+ IClickType["Last"] = "last-clicks";
104
+ })(IClickType || (IClickType = {}));
105
+ var IScrollType;
106
+ (function (IScrollType) {
107
+ IScrollType["Depth"] = "scroll-depth";
108
+ IScrollType["Attention"] = "attention-scroll";
109
+ IScrollType["Revenue"] = "revenue-scroll";
110
+ })(IScrollType || (IScrollType = {}));
96
111
 
97
112
  const useHeatmapConfigStore = create()((set, get) => {
98
113
  return {
99
114
  mode: 'single',
100
115
  width: 1440,
101
116
  sidebarWidth: DEFAULT_SIDEBAR_WIDTH,
102
- heatmapType: IHeatmapType.Click,
117
+ heatmapType: IHeatmapType.Scroll,
118
+ clickType: IClickType.Total,
119
+ scrollType: IScrollType.Depth,
103
120
  setMode: (mode) => set({ mode }),
104
121
  resetMode: () => set({ mode: 'single' }),
105
122
  setWidth: (width) => set({ width }),
106
123
  setSidebarWidth: (sidebarWidth) => set({ sidebarWidth }),
107
124
  setHeatmapType: (heatmapType) => set({ heatmapType }),
125
+ setClickType: (clickType) => set({ clickType }),
126
+ setScrollType: (scrollType) => set({ scrollType }),
108
127
  };
109
128
  });
110
129
 
@@ -113,11 +132,13 @@ const useHeatmapDataStore = create()((set, get) => {
113
132
  data: undefined,
114
133
  clickmap: undefined,
115
134
  dataInfo: undefined,
135
+ scrollmap: undefined,
116
136
  isRendering: true,
117
137
  setIsRendering: (isRendering) => set({ isRendering }),
118
138
  setDataInfo: (dataInfo) => set({ dataInfo }),
119
139
  setData: (data) => set({ data }),
120
140
  setClickmap: (clickmap) => set({ clickmap }),
141
+ setScrollmap: (scrollmap) => set({ scrollmap }),
121
142
  };
122
143
  });
123
144
 
@@ -145,6 +166,17 @@ const useHeatmapVizStore = create()((set, get) => {
145
166
  };
146
167
  });
147
168
 
169
+ const useHeatmapVizScrollmapStore = create()((set, get) => {
170
+ return {
171
+ zones: [],
172
+ hoveredZone: null,
173
+ showMinimap: true,
174
+ setZones: (zones) => set({ zones }),
175
+ setHoveredZone: (hoveredZone) => set({ hoveredZone }),
176
+ setShowMinimap: (showMinimap) => set({ showMinimap }),
177
+ };
178
+ });
179
+
148
180
  const initialState = {
149
181
  payloads: [],
150
182
  htmlContent: '',
@@ -219,16 +251,25 @@ const useRegisterData = (data, dataInfo) => {
219
251
  }, [dataInfo]);
220
252
  };
221
253
 
222
- const useRegisterHeatmap = (clickmap) => {
254
+ const useRegisterHeatmap = ({ clickmap, scrollmap }) => {
223
255
  const setClickmap = useHeatmapDataStore((state) => state.setClickmap);
256
+ const setScrollmap = useHeatmapDataStore((state) => state.setScrollmap);
224
257
  const handleSetClickmap = useCallback((clickmap) => {
225
258
  if (!clickmap)
226
259
  return;
227
260
  setClickmap(clickmap);
228
261
  }, [clickmap]);
262
+ const handleSetScrollmap = useCallback((scrollmap) => {
263
+ if (!scrollmap)
264
+ return;
265
+ setScrollmap(scrollmap);
266
+ }, [scrollmap]);
229
267
  useEffect(() => {
230
268
  handleSetClickmap(clickmap);
231
269
  }, [clickmap]);
270
+ useEffect(() => {
271
+ handleSetScrollmap(scrollmap);
272
+ }, [scrollmap]);
232
273
  };
233
274
 
234
275
  const PADDING = 0;
@@ -1246,8 +1287,6 @@ const debounce = (fn, delay) => {
1246
1287
  };
1247
1288
  };
1248
1289
 
1249
- // ===================== CONSTANTS =====================
1250
- const HEATMAP_ELEMENT_ATTRIBUTE = 'data-clarity-hashalpha'; // Hoặc attribute bạn đang dùng
1251
1290
  // ===================== UTILITY FUNCTIONS =====================
1252
1291
  /**
1253
1292
  * Lấy bounding box tuyệt đối của element (relative to document)
@@ -1290,74 +1329,6 @@ function getElementsAtPoint(documentOrShadowRoot, x, y, filterFunction, visitedS
1290
1329
  }
1291
1330
  return elementsAtPoint;
1292
1331
  }
1293
- // ===================== MAIN HOOK =====================
1294
- function useHeatmapMouseHandler(props) {
1295
- const { heatmapWrapperRef, iframeRef, parentRef, heatmapInfo, scaleRatio, onElementHover } = props;
1296
- const handleMouseMove = useCallback((event) => {
1297
- // Kiểm tra tất cả refs và data cần thiết
1298
- if (!heatmapWrapperRef?.current ||
1299
- !iframeRef?.current ||
1300
- !iframeRef.current.contentDocument ||
1301
- !heatmapInfo?.elementMapInfo ||
1302
- !parentRef?.current) {
1303
- return;
1304
- }
1305
- try {
1306
- // Tính toán scroll position (đã scale)
1307
- const scrollTop = parentRef.current.scrollTop / scaleRatio;
1308
- console.log(`🚀 🐥 ~ useHeatmapMouseHandler ~ scrollTop:`, scrollTop);
1309
- // Lấy vị trí của heatmap wrapper
1310
- const wrapperRect = heatmapWrapperRef.current.getBoundingClientRect();
1311
- // Tính toán tọa độ chuột trong iframe (đã scale)
1312
- const mouseX = (event.clientX - wrapperRect.left) / scaleRatio;
1313
- const mouseY = (event.clientY - wrapperRect.top) / scaleRatio - scrollTop;
1314
- // Tìm elements tại vị trí chuột
1315
- const elementsAtPoint = getElementsAtPoint(iframeRef.current.contentDocument, Math.round(mouseX), Math.round(mouseY),
1316
- // Filter: chỉ lấy elements có heatmap attribute
1317
- (element) => element.hasAttribute(HEATMAP_ELEMENT_ATTRIBUTE));
1318
- if (!elementsAtPoint || elementsAtPoint.length === 0) {
1319
- return;
1320
- }
1321
- // Duyệt qua các elements tìm được
1322
- for (let i = 0; i < elementsAtPoint.length; i++) {
1323
- const element = elementsAtPoint[i];
1324
- // Lấy hash/id của element
1325
- const elementHash = element.getAttribute(HEATMAP_ELEMENT_ATTRIBUTE);
1326
- // Kiểm tra element có data trong heatmapInfo không
1327
- if (elementHash && heatmapInfo.elementMapInfo[elementHash]) {
1328
- const elementData = heatmapInfo.elementMapInfo[elementHash];
1329
- // Lấy bounding box của element
1330
- const boundingBox = getBoundingBox(element);
1331
- if (boundingBox) {
1332
- // Tính rank của element
1333
- const rank = Array.isArray(heatmapInfo.sortedElements) && elementData
1334
- ? heatmapInfo.sortedElements.indexOf(elementData) + 1
1335
- : NaN;
1336
- // Callback với thông tin element
1337
- onElementHover({
1338
- ...boundingBox,
1339
- // Giới hạn width không vượt quá width của heatmap
1340
- width: Math.min(boundingBox.width, heatmapInfo.width || 0),
1341
- // Adjust top position với scroll
1342
- top: boundingBox.top + scrollTop,
1343
- // Metadata
1344
- hash: elementHash,
1345
- clicks: elementData.totalclicks,
1346
- rank: rank,
1347
- selector: elementData.selector || '',
1348
- });
1349
- // Dừng loop khi tìm thấy element hợp lệ đầu tiên
1350
- break;
1351
- }
1352
- }
1353
- }
1354
- }
1355
- catch (error) {
1356
- console.warn('Error handling mouse move on heatmap:', error);
1357
- }
1358
- }, [heatmapWrapperRef, iframeRef, parentRef, heatmapInfo, scaleRatio, onElementHover]);
1359
- return { handleMouseMove };
1360
- }
1361
1332
  // ===================== EXAMPLE USAGE =====================
1362
1333
  /*
1363
1334
  import { useRef, useState } from 'react';
@@ -2118,6 +2089,135 @@ const useWrapperRefHeight = (props) => {
2118
2089
  return {};
2119
2090
  };
2120
2091
 
2092
+ const useZonePositions = (options) => {
2093
+ const iframeHeight = useHeatmapSingleStore((state) => state.iframeHeight);
2094
+ const getZonePosition = useCallback((zone) => {
2095
+ if (!iframeHeight) {
2096
+ return null;
2097
+ }
2098
+ const startYPx = (zone.startY / 100) * iframeHeight;
2099
+ const heightPx = ((zone.endY - zone.startY) / 100) * iframeHeight;
2100
+ return {
2101
+ top: startYPx,
2102
+ height: heightPx,
2103
+ };
2104
+ }, [iframeHeight]);
2105
+ return {
2106
+ getZonePosition,
2107
+ };
2108
+ };
2109
+
2110
+ const SCROLL_GRADIENT_COLORS = [
2111
+ [255, 0, 0], // Red
2112
+ [255, 255, 0], // Yellow
2113
+ [0, 255, 0], // Green
2114
+ ];
2115
+ const useScrollmapZones = (options) => {
2116
+ const { mode = 'basic', enabled = true, iframeRef, wrapperRef } = options;
2117
+ const [isReady, setIsReady] = useState(false);
2118
+ const [zones, setZones] = useState([]);
2119
+ const scrollmap = useHeatmapDataStore((state) => state.scrollmap);
2120
+ const scrollMapInfo = useHeatmapDataStore((state) => state.dataInfo?.scrollMapInfo);
2121
+ const { getZonePosition } = useZonePositions();
2122
+ const maxUsers = useMemo(() => {
2123
+ if (!scrollmap || scrollmap.length === 0)
2124
+ return 100;
2125
+ return Math.max(...scrollmap.map((d) => d.percUsers));
2126
+ }, [scrollmap]);
2127
+ const createZones = useCallback((data) => {
2128
+ if (mode === 'basic') {
2129
+ const breakpoints = [0, 25, 50, 75, 100];
2130
+ const zones = [];
2131
+ for (let i = 0; i < breakpoints.length - 1; i++) {
2132
+ const startY = breakpoints[i];
2133
+ const endY = breakpoints[i + 1];
2134
+ const pointsInRange = data.filter((d) => d.scrollReachY >= startY && d.scrollReachY < endY);
2135
+ const avgUsers = pointsInRange.length > 0
2136
+ ? pointsInRange.reduce((sum, p) => sum + p.percUsers, 0) / pointsInRange.length
2137
+ : 0;
2138
+ zones.push({
2139
+ id: `zone_${startY}_${endY}`,
2140
+ startY,
2141
+ endY,
2142
+ percUsers: avgUsers,
2143
+ label: `${startY}% - ${endY}%`,
2144
+ });
2145
+ }
2146
+ return zones;
2147
+ }
2148
+ else {
2149
+ // Metrics mode: 20 zones (5% intervals)
2150
+ const zones = [];
2151
+ const interval = 5;
2152
+ // Prepare metrics map
2153
+ let metricsMap;
2154
+ if (scrollMapInfo && Object.keys(scrollMapInfo).length > 0) {
2155
+ metricsMap = new Map();
2156
+ Object.entries(scrollMapInfo).forEach(([key, value]) => {
2157
+ metricsMap.set(Number(key), value);
2158
+ });
2159
+ }
2160
+ for (let i = 0; i < 100; i += interval) {
2161
+ const startY = i;
2162
+ const endY = i + interval;
2163
+ const point = data.find((d) => d.scrollReachY === startY) || {
2164
+ scrollReachY: startY,
2165
+ cumulativeSum: 0,
2166
+ percUsers: 0,
2167
+ };
2168
+ const metrics = metricsMap?.get(startY);
2169
+ zones.push({
2170
+ id: `zone_${startY}_${endY}`,
2171
+ startY,
2172
+ endY,
2173
+ percUsers: point.percUsers,
2174
+ metrics,
2175
+ label: `${startY}% - ${endY}%`,
2176
+ });
2177
+ }
2178
+ return zones;
2179
+ }
2180
+ }, [mode, scrollMapInfo]);
2181
+ /**
2182
+ * Initialize zones
2183
+ */
2184
+ useEffect(() => {
2185
+ if (!enabled || !scrollmap || scrollmap.length === 0) {
2186
+ setIsReady(false);
2187
+ return;
2188
+ }
2189
+ try {
2190
+ const newZones = createZones(scrollmap);
2191
+ setZones(newZones);
2192
+ setIsReady(true);
2193
+ console.log(`[useScrollmap] Created ${newZones.length} zones in ${mode} mode`);
2194
+ }
2195
+ catch (error) {
2196
+ console.error('[useScrollmap] Error:', error);
2197
+ setIsReady(false);
2198
+ }
2199
+ }, [enabled, scrollmap, mode, createZones]);
2200
+ return {
2201
+ zones,
2202
+ isReady,
2203
+ maxUsers,
2204
+ getZonePosition,
2205
+ };
2206
+ };
2207
+ /**
2208
+ * Get scroll gradient color for minimap
2209
+ */
2210
+ const getScrollGradientColor = (normalized) => {
2211
+ const idx = Math.min(Math.floor(normalized * 2), 1);
2212
+ const [r1, g1, b1] = SCROLL_GRADIENT_COLORS[idx];
2213
+ const [r2, g2, b2] = SCROLL_GRADIENT_COLORS[idx + 1];
2214
+ const localPercent = (normalized * 2) % 1;
2215
+ const r = Math.round(r1 + (r2 - r1) * localPercent);
2216
+ const g = Math.round(g1 + (g2 - g1) * localPercent);
2217
+ const b = Math.round(b1 + (b2 - b1) * localPercent);
2218
+ return `rgb(${r}, ${g}, ${b})`;
2219
+ };
2220
+
2121
2221
  const BoxStack = forwardRef(({ children, ...props }, ref) => {
2122
2222
  const id = props.id;
2123
2223
  const flexDirection = props.flexDirection;
@@ -2222,113 +2322,11 @@ const useClickmap = () => {
2222
2322
  return { start };
2223
2323
  };
2224
2324
 
2225
- const DATA_SCROLLMAP = [
2226
- {
2227
- scrollReachY: 5,
2228
- cumulativeSum: 0,
2229
- percUsers: 0,
2230
- },
2231
- {
2232
- scrollReachY: 10,
2233
- cumulativeSum: 0,
2234
- percUsers: 0,
2235
- },
2236
- {
2237
- scrollReachY: 15,
2238
- cumulativeSum: 0,
2239
- percUsers: 0,
2240
- },
2241
- {
2242
- scrollReachY: 20,
2243
- cumulativeSum: 0,
2244
- percUsers: 0,
2245
- },
2246
- {
2247
- scrollReachY: 25,
2248
- cumulativeSum: 0,
2249
- percUsers: 0,
2250
- },
2251
- {
2252
- scrollReachY: 30,
2253
- cumulativeSum: 0,
2254
- percUsers: 0,
2255
- },
2256
- {
2257
- scrollReachY: 35,
2258
- cumulativeSum: 0,
2259
- percUsers: 0,
2260
- },
2261
- {
2262
- scrollReachY: 40,
2263
- cumulativeSum: 0,
2264
- percUsers: 0,
2265
- },
2266
- {
2267
- scrollReachY: 45,
2268
- cumulativeSum: 0,
2269
- percUsers: 0,
2270
- },
2271
- {
2272
- scrollReachY: 50,
2273
- cumulativeSum: 0,
2274
- percUsers: 0,
2275
- },
2276
- {
2277
- scrollReachY: 55,
2278
- cumulativeSum: 0,
2279
- percUsers: 0,
2280
- },
2281
- {
2282
- scrollReachY: 60,
2283
- cumulativeSum: 0,
2284
- percUsers: 0,
2285
- },
2286
- {
2287
- scrollReachY: 65,
2288
- cumulativeSum: 0,
2289
- percUsers: 0,
2290
- },
2291
- {
2292
- scrollReachY: 70,
2293
- cumulativeSum: 0,
2294
- percUsers: 0,
2295
- },
2296
- {
2297
- scrollReachY: 75,
2298
- cumulativeSum: 0,
2299
- percUsers: 0,
2300
- },
2301
- {
2302
- scrollReachY: 80,
2303
- cumulativeSum: 0,
2304
- percUsers: 0,
2305
- },
2306
- {
2307
- scrollReachY: 85,
2308
- cumulativeSum: 0,
2309
- percUsers: 0,
2310
- },
2311
- {
2312
- scrollReachY: 90,
2313
- cumulativeSum: 0,
2314
- percUsers: 0,
2315
- },
2316
- {
2317
- scrollReachY: 95,
2318
- cumulativeSum: 0,
2319
- percUsers: 0,
2320
- },
2321
- {
2322
- scrollReachY: 100,
2323
- cumulativeSum: 0,
2324
- percUsers: 0,
2325
- },
2326
- ];
2327
2325
  const useScrollmap = () => {
2328
2326
  const vizRef = useHeatmapSingleStore((state) => state.vizRef);
2327
+ const scrollmap = useHeatmapDataStore((state) => state.scrollmap);
2329
2328
  const start = useCallback(() => {
2330
2329
  // if (isInitialized) return;
2331
- const scrollmap = DATA_SCROLLMAP;
2332
2330
  if (!vizRef || !scrollmap || scrollmap.length === 0)
2333
2331
  return;
2334
2332
  try {
@@ -2339,11 +2337,11 @@ const useScrollmap = () => {
2339
2337
  catch (error) {
2340
2338
  console.error(`🚀 🐥 ~ useScrollmap ~ error:`, error);
2341
2339
  }
2342
- }, [vizRef]);
2340
+ }, [vizRef, scrollmap]);
2343
2341
  return { start };
2344
2342
  };
2345
2343
 
2346
- const useHeatmapVizCanvas = () => {
2344
+ const useHeatmapCanvas = ({ iframeRef, }) => {
2347
2345
  const heatmapType = useHeatmapConfigStore((state) => state.heatmapType);
2348
2346
  const { start: startClickmap } = useClickmap();
2349
2347
  const { start: startScrollmap } = useScrollmap();
@@ -2353,7 +2351,7 @@ const useHeatmapVizCanvas = () => {
2353
2351
  startClickmap();
2354
2352
  break;
2355
2353
  case IHeatmapType.Scroll:
2356
- startClickmap();
2354
+ startScrollmap();
2357
2355
  break;
2358
2356
  }
2359
2357
  }, [heatmapType, startClickmap, startScrollmap]);
@@ -2485,8 +2483,7 @@ const ELEMENT_CALLOUT = {
2485
2483
  };
2486
2484
  const HeatmapElements = (props) => {
2487
2485
  const iframeHeight = useHeatmapSingleStore((state) => state.iframeHeight);
2488
- const setHoveredElement = useHeatmapInteractionStore((state) => state.setHoveredElement);
2489
- const { iframeRef, wrapperRef, visualRef, visualizer, iframeDimensions, isElementSidebarOpen, isVisible = true, areDefaultRanksHidden, isSecondary, ...rest } = props;
2486
+ const { iframeRef, wrapperRef, visualRef, visualizer, iframeDimensions, isElementSidebarOpen, isVisible = true, areDefaultRanksHidden, isSecondary, } = props;
2490
2487
  const getRect = useHeatmapElementPosition({
2491
2488
  iframeRef,
2492
2489
  wrapperRef,
@@ -2500,27 +2497,6 @@ const HeatmapElements = (props) => {
2500
2497
  iframeRef,
2501
2498
  getRect,
2502
2499
  });
2503
- const heatmapInfo = useHeatmapDataStore((state) => state.dataInfo);
2504
- useHeatmapMouseHandler({
2505
- heatmapWrapperRef: wrapperRef,
2506
- iframeRef,
2507
- parentRef: visualRef,
2508
- heatmapInfo: heatmapInfo || {},
2509
- scaleRatio: 0.8, // 80% zoom
2510
- onElementHover: (info) => {
2511
- setHoveredElement({
2512
- hash: info.hash,
2513
- clicks: info.clicks,
2514
- rank: info.rank,
2515
- selector: info.selector,
2516
- top: info.top,
2517
- left: info.left,
2518
- width: info.width,
2519
- height: info.height,
2520
- });
2521
- console.log(`🚀 🐥 ~ HeatmapElements ~ info:`, info);
2522
- },
2523
- });
2524
2500
  useElementCalloutVisible({
2525
2501
  visualRef,
2526
2502
  getRect,
@@ -2576,6 +2552,293 @@ const VizElements = ({ iframeRef, visualRef, wrapperRef }) => {
2576
2552
  } }));
2577
2553
  };
2578
2554
 
2555
+ const AverageFoldLine = ({ iframeRef, wrapperRef }) => {
2556
+ const averageFold = useHeatmapDataStore((state) => state.dataInfo?.averageFold || 50);
2557
+ const { getZonePosition } = useZonePositions();
2558
+ const position = getZonePosition({
2559
+ startY: averageFold,
2560
+ endY: averageFold,
2561
+ });
2562
+ if (!position)
2563
+ return null;
2564
+ return (jsx("div", { style: {
2565
+ position: 'absolute',
2566
+ top: `${position.top}px`,
2567
+ left: 0,
2568
+ width: '100%',
2569
+ height: '2px',
2570
+ backgroundColor: '#0078D4',
2571
+ pointerEvents: 'none',
2572
+ zIndex: 2,
2573
+ boxShadow: '0 0 4px rgba(0,120,212,0.5)',
2574
+ display: 'flex',
2575
+ alignItems: 'center',
2576
+ }, children: jsxs("div", { style: {
2577
+ position: 'absolute',
2578
+ padding: '8px',
2579
+ backgroundColor: 'rgba(0, 120, 212, 0.9)',
2580
+ color: 'white',
2581
+ fontSize: '16px',
2582
+ fontWeight: 600,
2583
+ borderRadius: '4px',
2584
+ whiteSpace: 'nowrap',
2585
+ left: '12px',
2586
+ minWidth: '120px',
2587
+ textAlign: 'center',
2588
+ }, children: ["Average fold - ", averageFold.toFixed(0), "%"] }) }));
2589
+ };
2590
+
2591
+ const ScrollmapMarker = ({ iframeRef, wrapperRef }) => {
2592
+ const scrollmap = useHeatmapDataStore((state) => state.scrollmap);
2593
+ const scrollType = useHeatmapConfigStore((state) => state.scrollType);
2594
+ const { getZonePosition } = useZonePositions();
2595
+ if (!scrollmap || scrollmap.length === 0)
2596
+ return null;
2597
+ const findScrollPositionForUserPercent = (targetPercent) => {
2598
+ for (let i = 0; i < scrollmap.length; i++) {
2599
+ if (scrollmap[i].percUsers <= targetPercent) {
2600
+ if (i > 0) {
2601
+ return scrollmap[i - 1].scrollReachY;
2602
+ }
2603
+ return scrollmap[i].scrollReachY;
2604
+ }
2605
+ }
2606
+ return scrollmap[scrollmap.length - 1]?.scrollReachY || null;
2607
+ };
2608
+ const boundaries = [
2609
+ { percent: 75, label: '75%', color: '#10B981' },
2610
+ { percent: 50, label: '50%', color: '#F59E0B' },
2611
+ { percent: 25, label: '25%', color: '#EF4444' },
2612
+ { percent: 5, label: '5%', color: '#8B5CF6' },
2613
+ ];
2614
+ const isScrollDepth = scrollType === IScrollType.Depth;
2615
+ if (!isScrollDepth)
2616
+ return null;
2617
+ return (jsx(Fragment, { children: boundaries.map((boundary) => {
2618
+ const scrollY = findScrollPositionForUserPercent(boundary.percent);
2619
+ if (scrollY === null)
2620
+ return null;
2621
+ const position = getZonePosition({
2622
+ startY: scrollY,
2623
+ endY: scrollY,
2624
+ });
2625
+ if (!position)
2626
+ return null;
2627
+ return (jsx("div", { className: `marker-boundary-line-${boundary.percent}`, style: {
2628
+ position: 'absolute',
2629
+ top: `${position.top}px`,
2630
+ left: 0,
2631
+ transformOrigin: 'left center',
2632
+ width: '100%',
2633
+ height: '0px',
2634
+ // borderBottom: `2px dashed #323130`,
2635
+ borderBottom: `2px solid ${boundary.color}`,
2636
+ // background: 'repeating-linear-gradient(90deg, #323130, transparent 2px 3px)',
2637
+ zIndex: 1,
2638
+ display: 'flex',
2639
+ alignItems: 'center',
2640
+ }, children: jsx("div", { style: {
2641
+ position: 'absolute',
2642
+ padding: '8px',
2643
+ backgroundColor: boundary.color,
2644
+ color: 'white',
2645
+ fontSize: '16px',
2646
+ fontWeight: 600,
2647
+ borderRadius: '4px',
2648
+ whiteSpace: 'nowrap',
2649
+ left: '12px',
2650
+ minWidth: '120px',
2651
+ textAlign: 'center',
2652
+ // textAlign: 'center',
2653
+ // padding: '8px',
2654
+ // paddingInline: '8px',
2655
+ // fontSize: '16px',
2656
+ // background: '#fff',
2657
+ // width: 'auto',
2658
+ // borderRadius: '4px',
2659
+ // position: 'absolute',
2660
+ // left: '12px',
2661
+ // minWidth: '120px',
2662
+ }, children: boundary.label }) }, boundary.label));
2663
+ }) }));
2664
+ };
2665
+
2666
+ const ScrollMapMinimap = ({ zones, maxUsers }) => {
2667
+ const showMinimap = useHeatmapVizScrollmapStore((state) => state.showMinimap);
2668
+ const scrollType = useHeatmapConfigStore((state) => state.scrollType);
2669
+ const isScrollType = [IScrollType.Attention].includes(scrollType);
2670
+ if (!showMinimap || !isScrollType)
2671
+ return null;
2672
+ return (jsx("div", { style: {
2673
+ position: 'fixed',
2674
+ left: '20px',
2675
+ top: '50%',
2676
+ transform: 'translateY(-50%)',
2677
+ width: '60px',
2678
+ height: '400px',
2679
+ backgroundColor: 'white',
2680
+ borderRadius: '8px',
2681
+ boxShadow: '0 4px 16px rgba(0,0,0,0.15)',
2682
+ zIndex: 10002,
2683
+ padding: '8px',
2684
+ boxSizing: 'border-box',
2685
+ }, children: jsx("div", { style: {
2686
+ width: '100%',
2687
+ height: '100%',
2688
+ borderRadius: '4px',
2689
+ overflow: 'hidden',
2690
+ display: 'flex',
2691
+ flexDirection: 'column',
2692
+ }, children: zones.map((zone) => {
2693
+ const normalized = maxUsers > 0 ? zone.percUsers / maxUsers : 0;
2694
+ const color = getScrollGradientColor(normalized);
2695
+ return (jsx("div", { title: `${zone.label}: ${zone.percUsers.toFixed(2)}%`, style: {
2696
+ width: '100%',
2697
+ flex: `${zone.endY - zone.startY}`,
2698
+ backgroundColor: color,
2699
+ borderBottom: '1px solid rgba(255,255,255,0.2)',
2700
+ } }, zone.id));
2701
+ }) }) }));
2702
+ };
2703
+
2704
+ const ScrollZoneTooltip = ({ zone, position, currentScrollPercent, scrollmap, }) => {
2705
+ const tooltipRef = useRef(null);
2706
+ const currentData = useMemo(() => {
2707
+ if (!scrollmap || scrollmap.length === 0)
2708
+ return null;
2709
+ const roundedPercent = Math.floor(currentScrollPercent);
2710
+ return scrollmap.find((d) => d.scrollReachY === roundedPercent) || null;
2711
+ }, [scrollmap, currentScrollPercent]);
2712
+ return (jsxs("div", { id: "gx-hm-scrollmap-tooltip", ref: tooltipRef, style: {
2713
+ position: 'fixed',
2714
+ top: `${position.y}px`,
2715
+ backgroundColor: 'black',
2716
+ zIndex: 10001,
2717
+ pointerEvents: 'none',
2718
+ width: '100%',
2719
+ height: '2px',
2720
+ }, children: [jsxs("div", { style: {
2721
+ position: 'absolute',
2722
+ left: '50%',
2723
+ top: '-50%',
2724
+ transform: 'translate(-50%, -50%)',
2725
+ padding: '16px',
2726
+ borderRadius: '8px',
2727
+ boxShadow: '0 4px 16px rgba(0,0,0,0.15)',
2728
+ fontSize: '14px',
2729
+ width: 'fit-content',
2730
+ backgroundColor: 'white',
2731
+ minWidth: '230px',
2732
+ display: 'flex',
2733
+ gap: '8px',
2734
+ alignItems: 'center',
2735
+ }, children: [jsxs("p", { style: {
2736
+ fontWeight: 650,
2737
+ fontSize: '20px',
2738
+ lineHeight: '24px',
2739
+ letterSpacing: '-0.2px',
2740
+ verticalAlign: 'middle',
2741
+ fontVariantNumeric: 'tabular-nums',
2742
+ }, children: [currentData?.percUsers?.toFixed(2), "%", ' '] }), jsx("p", { style: { fontWeight: 450 }, children: "user scrolled this far" })] }), jsx(TooltipByZone, { zone: zone })] }));
2743
+ };
2744
+ const TooltipByZone = ({ zone }) => {
2745
+ const scrollType = useHeatmapConfigStore((state) => state.scrollType);
2746
+ if (!zone)
2747
+ return null;
2748
+ const contentMarkup = () => {
2749
+ switch (scrollType) {
2750
+ case IScrollType.Depth:
2751
+ return jsx(BasicTooltipContent, { zone: zone });
2752
+ case IScrollType.Attention:
2753
+ return jsx(MetricsTooltipContent, { zone: zone });
2754
+ default:
2755
+ return jsx(BasicTooltipContent, { zone: zone });
2756
+ }
2757
+ };
2758
+ return (jsx("div", { style: { paddingTop: '12px', borderTop: '1px solid #E5E7EB' }, children: contentMarkup() }));
2759
+ };
2760
+ const BasicTooltipContent = ({ zone }) => {
2761
+ if (!zone)
2762
+ return null;
2763
+ return (jsxs(Fragment, { children: [jsx("div", { style: { fontWeight: 600, marginBottom: '8px' }, children: zone.label }), jsxs("div", { style: { fontSize: '24px', fontWeight: 700, color: '#0078D4' }, children: [zone.percUsers.toFixed(2), "%"] }), jsx("div", { style: { fontSize: '12px', color: '#605E5C', marginTop: '4px' }, children: "of users reached this point" })] }));
2764
+ };
2765
+ const MetricsTooltipContent = ({ zone }) => {
2766
+ if (!zone)
2767
+ return null;
2768
+ return (jsxs(Fragment, { children: [jsx("div", { style: { fontWeight: 600, marginBottom: '8px' }, children: zone.label }), jsxs("div", { style: { fontSize: '20px', fontWeight: 700, marginBottom: '8px' }, children: [zone.percUsers.toFixed(2), "% users"] }), zone.metrics && (jsxs("div", { style: { display: 'grid', gap: '6px', fontSize: '13px' }, children: [zone.metrics.revenue !== undefined && (jsx(MetricRow, { label: "Revenue", value: `$${zone.metrics.revenue.toFixed(2)}` })), zone.metrics.conversionRate !== undefined && (jsx(MetricRow, { label: "Conversion", value: `${zone.metrics.conversionRate.toFixed(2)}%` })), zone.metrics.orders !== undefined && (jsx(MetricRow, { label: "Orders", value: zone.metrics.orders.toString() }))] }))] }));
2769
+ };
2770
+ const MetricRow = ({ label, value }) => (jsxs("div", { style: { display: 'flex', justifyContent: 'space-between' }, children: [jsxs("span", { style: { color: '#605E5C' }, children: [label, ":"] }), jsx("span", { style: { fontWeight: 600 }, children: value })] }));
2771
+
2772
+ const HoverZones = ({ iframeRef, wrapperRef, position, currentScrollPercent, }) => {
2773
+ const scrollmap = useHeatmapDataStore((state) => state.scrollmap);
2774
+ // const hoveredZone = useHeatmapVizScrollmapStore((state) => state.hoveredZone);
2775
+ // const setHoveredZone = useHeatmapVizScrollmapStore((state) => state.setHoveredZone);
2776
+ const { zones, isReady, maxUsers } = useScrollmapZones({
2777
+ iframeRef,
2778
+ wrapperRef,
2779
+ });
2780
+ if (!isReady || !zones.length)
2781
+ return null;
2782
+ if (!position)
2783
+ return null;
2784
+ return (jsxs(Fragment, { children: [jsx(ScrollZoneTooltip, { position: position, currentScrollPercent: currentScrollPercent, scrollmap: scrollmap || [] }), jsx(ScrollMapMinimap, { zones: zones, maxUsers: maxUsers })] }));
2785
+ };
2786
+
2787
+ const ScrollMapOverlay = ({ wrapperRef, iframeRef }) => {
2788
+ const overlayRef = useRef(null);
2789
+ const [position, setPosition] = useState();
2790
+ const [currentScrollPercent, setCurrentScrollPercent] = useState(0);
2791
+ const widthScale = useHeatmapVizStore((state) => state.scale);
2792
+ const iframeHeight = useHeatmapSingleStore((state) => state.iframeHeight);
2793
+ const handleMouseMove = (event) => {
2794
+ if (!iframeRef.current || !wrapperRef.current)
2795
+ return;
2796
+ const iframe = iframeRef.current;
2797
+ const iframeRect = iframe.getBoundingClientRect();
2798
+ const { x, y } = convertViewportToIframeCoords(event.clientX, event.clientY, iframeRect, widthScale);
2799
+ const wrapperEl = wrapperRef.current;
2800
+ const scrollOffset = (wrapperEl?.scrollTop || 0) / widthScale;
2801
+ const actualY = y + scrollOffset;
2802
+ const scrollPercent = Math.min(100, Math.max(0, (actualY / iframeHeight) * 100));
2803
+ setCurrentScrollPercent(scrollPercent);
2804
+ setPosition({ x, y });
2805
+ };
2806
+ const onMouseMove = useCallback((event) => {
2807
+ requestAnimationFrame(() => handleMouseMove(event));
2808
+ }, [handleMouseMove]);
2809
+ const onMouseLeave = () => {
2810
+ requestAnimationFrame(() => {
2811
+ setCurrentScrollPercent(0);
2812
+ setPosition(undefined);
2813
+ });
2814
+ };
2815
+ return (jsx("div", { ref: overlayRef, id: "gx-hm-scrollmap-overlay", onMouseMove: onMouseMove, onMouseLeave: onMouseLeave, style: {
2816
+ position: 'absolute',
2817
+ top: 0,
2818
+ left: 0,
2819
+ width: '100%',
2820
+ height: `${iframeHeight}px`,
2821
+ zIndex: 3,
2822
+ }, children: jsx(HoverZones, { position: position, currentScrollPercent: currentScrollPercent, iframeRef: iframeRef, wrapperRef: wrapperRef }) }));
2823
+ };
2824
+
2825
+ const SCROLL_TYPES = [IHeatmapType.Scroll];
2826
+ const VizScrollMap = ({ iframeRef, wrapperRef }) => {
2827
+ const iframeHeight = useHeatmapSingleStore((state) => state.iframeHeight);
2828
+ const heatmapType = useHeatmapConfigStore((state) => state.heatmapType);
2829
+ const isHeatmapScroll = SCROLL_TYPES.includes(heatmapType);
2830
+ if (!iframeHeight || !isHeatmapScroll)
2831
+ return null;
2832
+ return (jsxs("div", { style: {
2833
+ position: 'absolute',
2834
+ top: 0,
2835
+ left: '2px',
2836
+ width: `calc(100% - 4px)`,
2837
+ height: '100%',
2838
+ transform: 'translateZ(0)',
2839
+ }, children: [jsx(ScrollmapMarker, { iframeRef: iframeRef, wrapperRef: wrapperRef }), jsx(AverageFoldLine, { iframeRef: iframeRef, wrapperRef: wrapperRef }), jsx(ScrollMapOverlay, { wrapperRef: wrapperRef, iframeRef: iframeRef })] }));
2840
+ };
2841
+
2579
2842
  const WrapperVisual = ({ children, visualRef, wrapperRef, scaledHeight, iframeHeight, onScroll, }) => {
2580
2843
  const contentWidth = useHeatmapConfigStore((state) => state.width);
2581
2844
  const widthScale = useHeatmapVizStore((state) => state.scale);
@@ -2610,6 +2873,7 @@ const WrapperVisual = ({ children, visualRef, wrapperRef, scaledHeight, iframeHe
2610
2873
 
2611
2874
  const VizDomRenderer = ({ mode = 'heatmap' }) => {
2612
2875
  const width = useHeatmapConfigStore((state) => state.width);
2876
+ const heatmapType = useHeatmapConfigStore((state) => state.heatmapType);
2613
2877
  const iframeHeight = useHeatmapSingleStore((state) => state.iframeHeight);
2614
2878
  const setIframeHeight = useHeatmapSingleStore((state) => state.setIframeHeight);
2615
2879
  const setSelectedElement = useHeatmapInteractionStore((state) => state.setSelectedElement);
@@ -2627,7 +2891,7 @@ const VizDomRenderer = ({ mode = 'heatmap' }) => {
2627
2891
  const scrollTop = e.currentTarget.scrollTop;
2628
2892
  handleScroll(scrollTop);
2629
2893
  };
2630
- useHeatmapVizCanvas();
2894
+ useHeatmapCanvas({ iframeRef: iframeRef });
2631
2895
  const cleanUp = () => {
2632
2896
  setIframeHeight(0);
2633
2897
  setSelectedElement(null);
@@ -2635,7 +2899,7 @@ const VizDomRenderer = ({ mode = 'heatmap' }) => {
2635
2899
  useEffect(() => {
2636
2900
  return cleanUp;
2637
2901
  }, []);
2638
- return (jsxs(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, onScroll: onScroll, iframeHeight: iframeHeight, children: [jsx(VizElements, { iframeRef: iframeRef, visualRef: visualRef, wrapperRef: wrapperRef }), jsx("iframe", { ref: iframeRef, ...HEATMAP_IFRAME, width: contentWidth, scrolling: "no" })] }));
2902
+ return (jsxs(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, onScroll: onScroll, iframeHeight: iframeHeight, children: [heatmapType === IHeatmapType.Click && (jsx(VizElements, { iframeRef: iframeRef, visualRef: visualRef, wrapperRef: wrapperRef })), jsx("iframe", { ref: iframeRef, ...HEATMAP_IFRAME, width: contentWidth, scrolling: "no" }), jsx(VizScrollMap, { iframeRef: iframeRef, wrapperRef: visualRef })] }));
2639
2903
  };
2640
2904
 
2641
2905
  const VizLoading = () => {
@@ -2742,10 +3006,10 @@ const WrapperLayout = () => {
2742
3006
  return (jsxs(BoxStack, { id: "gx-hm-layout", flexDirection: "column", flex: "1", children: [jsx(ContentTopBar, {}), jsx(WrapperPreview, {})] }));
2743
3007
  };
2744
3008
 
2745
- const HeatmapLayout = ({ data, clickmap, controls, dataInfo, }) => {
3009
+ const HeatmapLayout = ({ data, clickmap, scrollmap, controls, dataInfo, }) => {
2746
3010
  useRegisterControl(controls);
2747
3011
  useRegisterData(data, dataInfo);
2748
- useRegisterHeatmap(clickmap);
3012
+ useRegisterHeatmap({ clickmap, scrollmap });
2749
3013
  useRegisterConfig();
2750
3014
  return (jsx(BoxStack, { id: "gx-hm-project", flexDirection: "column", flex: "1", height: "100%", style: getVariableStyle(), children: jsx(BoxStack, { id: "gx-hm-project-content", flexDirection: "column", flex: "1", children: jsx("div", { style: {
2751
3015
  minHeight: '100%',
@@ -2760,4 +3024,4 @@ const HeatmapLayout = ({ data, clickmap, controls, dataInfo, }) => {
2760
3024
  }
2761
3025
  };
2762
3026
 
2763
- export { GraphView, HeatmapLayout, IHeatmapType, useHeatmapConfigStore, useHeatmapDataStore, useHeatmapInteractionStore, useHeatmapLiveStore, useHeatmapVizStore };
3027
+ export { GraphView, HeatmapLayout, IClickType, IHeatmapType, IScrollType, useHeatmapConfigStore, useHeatmapDataStore, useHeatmapInteractionStore, useHeatmapLiveStore, useHeatmapVizStore };