@gemx-dev/heatmap-react 3.5.45 → 3.5.46

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 (493) hide show
  1. package/dist/esm/components/Layout/ContentHeader.d.ts +4 -0
  2. package/dist/esm/components/Layout/ContentHeader.d.ts.map +1 -0
  3. package/dist/esm/components/Layout/HeatmapLayout.d.ts +2 -3
  4. package/dist/esm/components/Layout/HeatmapLayout.d.ts.map +1 -1
  5. package/dist/esm/components/Layout/VizMode.d.ts +2 -0
  6. package/dist/esm/components/Layout/VizMode.d.ts.map +1 -0
  7. package/dist/esm/components/Test.d.ts +121 -0
  8. package/dist/esm/components/Test.d.ts.map +1 -0
  9. package/dist/esm/components/VizDom/VizDomContainer.d.ts +6 -0
  10. package/dist/esm/components/VizDom/VizDomContainer.d.ts.map +1 -0
  11. package/dist/esm/components/VizDom/VizDomRenderer.d.ts.map +1 -1
  12. package/dist/esm/components/VizElement/ClickedElementOverlay.d.ts +17 -0
  13. package/dist/esm/components/VizElement/ClickedElementOverlay.d.ts.map +1 -0
  14. package/dist/esm/components/VizElement/HeatmapElements.d.ts +2 -2
  15. package/dist/esm/components/VizElement/HeatmapElements.d.ts.map +1 -1
  16. package/dist/esm/components/VizElement/HoveredElementOverlay.d.ts +12 -0
  17. package/dist/esm/components/VizElement/HoveredElementOverlay.d.ts.map +1 -0
  18. package/dist/esm/components/VizElement/MissingElementMessage.d.ts +7 -0
  19. package/dist/esm/components/VizElement/MissingElementMessage.d.ts.map +1 -0
  20. package/dist/esm/components/VizElement/VizElements.d.ts.map +1 -1
  21. package/dist/esm/components/VizElement/temp/ClarityVisualizer.d.ts +150 -0
  22. package/dist/esm/components/VizElement/temp/ClarityVisualizer.d.ts.map +1 -0
  23. package/dist/esm/components/VizElement/temp/VizElementRank.d.ts +74 -0
  24. package/dist/esm/components/VizElement/temp/VizElementRank.d.ts.map +1 -0
  25. package/dist/esm/components/VizLive/VizLive.d.ts +2 -0
  26. package/dist/esm/components/VizLive/VizLive.d.ts.map +1 -0
  27. package/dist/esm/components/VizLive/VizLiveHeatmap.d.ts.map +1 -1
  28. package/dist/esm/components/VizLive/VizLiveRenderer.d.ts.map +1 -1
  29. package/dist/esm/configs/style.d.ts +0 -2
  30. package/dist/esm/configs/style.d.ts.map +1 -1
  31. package/dist/esm/helpers/elm-getter.d.ts +2 -2
  32. package/dist/esm/helpers/elm-getter.d.ts.map +1 -1
  33. package/dist/esm/helpers/index.d.ts +2 -2
  34. package/dist/esm/helpers/index.d.ts.map +1 -1
  35. package/dist/esm/helpers/viewport-fixer.d.ts +13 -0
  36. package/dist/esm/helpers/viewport-fixer.d.ts.map +1 -0
  37. package/dist/esm/helpers/viewport-replacer.d.ts +26 -0
  38. package/dist/esm/helpers/viewport-replacer.d.ts.map +1 -0
  39. package/dist/esm/hooks/index.d.ts +1 -2
  40. package/dist/esm/hooks/index.d.ts.map +1 -1
  41. package/dist/esm/hooks/register/useRegisterData.d.ts +2 -2
  42. package/dist/esm/hooks/register/useRegisterData.d.ts.map +1 -1
  43. package/dist/esm/hooks/register/useRegisterHeatmap.d.ts +2 -7
  44. package/dist/esm/hooks/register/useRegisterHeatmap.d.ts.map +1 -1
  45. package/dist/esm/hooks/{viz-elements → vix-elements}/index.d.ts.map +1 -1
  46. package/dist/esm/hooks/{viz-elements → vix-elements}/useClickedElement.d.ts.map +1 -1
  47. package/dist/esm/hooks/{viz-elements → vix-elements}/useElementCalloutVisible.d.ts.map +1 -1
  48. package/dist/esm/hooks/{viz-elements → vix-elements}/useHeatmapEffects.d.ts.map +1 -1
  49. package/dist/esm/hooks/{viz-elements → vix-elements}/useHeatmapElementPosition.d.ts.map +1 -1
  50. package/dist/esm/hooks/{viz-elements → vix-elements}/useHoveredElement.d.ts +0 -4
  51. package/dist/esm/hooks/vix-elements/useHoveredElement.d.ts.map +1 -0
  52. package/dist/esm/hooks/viz-canvas/index.d.ts +1 -1
  53. package/dist/esm/hooks/viz-canvas/index.d.ts.map +1 -1
  54. package/dist/esm/hooks/viz-canvas/useClickmap.d.ts +1 -3
  55. package/dist/esm/hooks/viz-canvas/useClickmap.d.ts.map +1 -1
  56. package/dist/esm/hooks/viz-canvas/useHeatmapVizCanvas.d.ts +2 -0
  57. package/dist/esm/hooks/viz-canvas/useHeatmapVizCanvas.d.ts.map +1 -0
  58. package/dist/esm/hooks/viz-canvas/useScrollmap.d.ts +1 -3
  59. package/dist/esm/hooks/viz-canvas/useScrollmap.d.ts.map +1 -1
  60. package/dist/esm/hooks/viz-live/index.d.ts +1 -1
  61. package/dist/{umd/hooks/viz-live/useVizLiveIframeMsg.d.ts → esm/hooks/viz-live/useIframeMessage.d.ts} +10 -2
  62. package/dist/esm/hooks/viz-live/useIframeMessage.d.ts.map +1 -0
  63. package/dist/esm/hooks/viz-render/useHeatmapRender.d.ts.map +1 -1
  64. package/dist/esm/hooks/viz-scale/useContainerDimensions.d.ts.map +1 -1
  65. package/dist/esm/hooks/viz-scale/useHeatmapScale.d.ts +1 -1
  66. package/dist/esm/hooks/viz-scale/useHeatmapScale.d.ts.map +1 -1
  67. package/dist/esm/hooks/viz-scale/useIframeHeight.d.ts +10 -0
  68. package/dist/esm/hooks/viz-scale/useIframeHeight.d.ts.map +1 -0
  69. package/dist/esm/index.d.ts +1 -1
  70. package/dist/esm/index.d.ts.map +1 -1
  71. package/dist/esm/index.js +210 -1181
  72. package/dist/esm/index.mjs +210 -1181
  73. package/dist/esm/stores/config.d.ts +1 -5
  74. package/dist/esm/stores/config.d.ts.map +1 -1
  75. package/dist/esm/stores/data.d.ts +3 -5
  76. package/dist/esm/stores/data.d.ts.map +1 -1
  77. package/dist/esm/stores/index.d.ts +0 -2
  78. package/dist/esm/stores/index.d.ts.map +1 -1
  79. package/dist/esm/stores/interaction.d.ts.map +1 -1
  80. package/dist/esm/stores/mode-live.d.ts +0 -4
  81. package/dist/esm/stores/mode-live.d.ts.map +1 -1
  82. package/dist/esm/stores/viz.d.ts +4 -0
  83. package/dist/esm/stores/viz.d.ts.map +1 -1
  84. package/dist/esm/types/clarity.d.ts +0 -5
  85. package/dist/esm/types/clarity.d.ts.map +1 -1
  86. package/dist/esm/types/heatmap.d.ts +0 -13
  87. package/dist/esm/types/heatmap.d.ts.map +1 -1
  88. package/dist/esm/types/index.d.ts +1 -4
  89. package/dist/esm/types/index.d.ts.map +1 -1
  90. package/dist/esm/types/viewport-fixer.d.ts +31 -0
  91. package/dist/esm/types/viewport-fixer.d.ts.map +1 -0
  92. package/dist/esm/types/viz-element.d.ts +6 -0
  93. package/dist/esm/types/viz-element.d.ts.map +1 -1
  94. package/dist/umd/components/Layout/ContentHeader.d.ts +4 -0
  95. package/dist/umd/components/Layout/ContentHeader.d.ts.map +1 -0
  96. package/dist/umd/components/Layout/HeatmapLayout.d.ts +2 -3
  97. package/dist/umd/components/Layout/HeatmapLayout.d.ts.map +1 -1
  98. package/dist/umd/components/Test.d.ts +121 -0
  99. package/dist/umd/components/Test.d.ts.map +1 -0
  100. package/dist/umd/components/VizDom/VizDomContainer.d.ts +2 -0
  101. package/dist/umd/components/VizDom/VizDomContainer.d.ts.map +1 -0
  102. package/dist/umd/components/VizDom/VizDomRenderer.d.ts.map +1 -1
  103. package/dist/umd/components/VizElement/ClickedElementOverlay.d.ts +17 -0
  104. package/dist/umd/components/VizElement/ClickedElementOverlay.d.ts.map +1 -0
  105. package/dist/umd/components/VizElement/HeatmapElements.d.ts +2 -2
  106. package/dist/umd/components/VizElement/HeatmapElements.d.ts.map +1 -1
  107. package/dist/umd/components/VizElement/HoveredElementOverlay.d.ts +12 -0
  108. package/dist/umd/components/VizElement/HoveredElementOverlay.d.ts.map +1 -0
  109. package/dist/umd/components/VizElement/MissingElementMessage.d.ts +7 -0
  110. package/dist/umd/components/VizElement/MissingElementMessage.d.ts.map +1 -0
  111. package/dist/umd/components/VizElement/VizElements.d.ts.map +1 -1
  112. package/dist/umd/components/VizElement/temp/ClarityVisualizer.d.ts +150 -0
  113. package/dist/umd/components/VizElement/temp/ClarityVisualizer.d.ts.map +1 -0
  114. package/dist/umd/components/VizElement/temp/VizElementRank.d.ts +74 -0
  115. package/dist/umd/components/VizElement/temp/VizElementRank.d.ts.map +1 -0
  116. package/dist/umd/components/VizLive/VizLiveHeatmap.d.ts.map +1 -1
  117. package/dist/umd/components/VizLive/VizLiveRenderer.d.ts.map +1 -1
  118. package/dist/umd/configs/style.d.ts +0 -2
  119. package/dist/umd/configs/style.d.ts.map +1 -1
  120. package/dist/umd/helpers/elm-getter.d.ts +2 -2
  121. package/dist/umd/helpers/elm-getter.d.ts.map +1 -1
  122. package/dist/umd/helpers/index.d.ts +2 -2
  123. package/dist/umd/helpers/index.d.ts.map +1 -1
  124. package/dist/umd/helpers/viewport-fixer.d.ts +13 -0
  125. package/dist/umd/helpers/viewport-fixer.d.ts.map +1 -0
  126. package/dist/umd/helpers/viewport-replacer.d.ts +26 -0
  127. package/dist/umd/helpers/viewport-replacer.d.ts.map +1 -0
  128. package/dist/umd/hooks/index.d.ts +1 -2
  129. package/dist/umd/hooks/index.d.ts.map +1 -1
  130. package/dist/umd/hooks/register/useRegisterData.d.ts +2 -2
  131. package/dist/umd/hooks/register/useRegisterData.d.ts.map +1 -1
  132. package/dist/umd/hooks/register/useRegisterHeatmap.d.ts +2 -7
  133. package/dist/umd/hooks/register/useRegisterHeatmap.d.ts.map +1 -1
  134. package/dist/umd/hooks/{viz-elements → vix-elements}/index.d.ts.map +1 -1
  135. package/dist/umd/hooks/{viz-elements → vix-elements}/useClickedElement.d.ts.map +1 -1
  136. package/dist/umd/hooks/{viz-elements → vix-elements}/useElementCalloutVisible.d.ts.map +1 -1
  137. package/dist/umd/hooks/{viz-elements → vix-elements}/useHeatmapEffects.d.ts.map +1 -1
  138. package/dist/umd/hooks/{viz-elements → vix-elements}/useHeatmapElementPosition.d.ts.map +1 -1
  139. package/dist/umd/hooks/{viz-elements → vix-elements}/useHoveredElement.d.ts +0 -4
  140. package/dist/umd/hooks/vix-elements/useHoveredElement.d.ts.map +1 -0
  141. package/dist/umd/hooks/viz-canvas/index.d.ts +1 -1
  142. package/dist/umd/hooks/viz-canvas/index.d.ts.map +1 -1
  143. package/dist/umd/hooks/viz-canvas/useClickmap.d.ts +1 -3
  144. package/dist/umd/hooks/viz-canvas/useClickmap.d.ts.map +1 -1
  145. package/dist/umd/hooks/viz-canvas/useHeatmapVizCanvas.d.ts +2 -0
  146. package/dist/umd/hooks/viz-canvas/useHeatmapVizCanvas.d.ts.map +1 -0
  147. package/dist/umd/hooks/viz-canvas/useScrollmap.d.ts +1 -3
  148. package/dist/umd/hooks/viz-canvas/useScrollmap.d.ts.map +1 -1
  149. package/dist/umd/hooks/viz-live/index.d.ts +1 -1
  150. package/dist/{esm/hooks/viz-live/useVizLiveIframeMsg.d.ts → umd/hooks/viz-live/useIframeMessage.d.ts} +10 -2
  151. package/dist/umd/hooks/viz-live/useIframeMessage.d.ts.map +1 -0
  152. package/dist/umd/hooks/viz-render/useHeatmapRender.d.ts.map +1 -1
  153. package/dist/umd/hooks/viz-scale/useContainerDimensions.d.ts.map +1 -1
  154. package/dist/umd/hooks/viz-scale/useHeatmapScale.d.ts +1 -1
  155. package/dist/umd/hooks/viz-scale/useHeatmapScale.d.ts.map +1 -1
  156. package/dist/umd/hooks/viz-scale/useIframeHeight.d.ts +10 -0
  157. package/dist/umd/hooks/viz-scale/useIframeHeight.d.ts.map +1 -0
  158. package/dist/umd/index.d.ts +1 -1
  159. package/dist/umd/index.d.ts.map +1 -1
  160. package/dist/umd/index.js +2 -2
  161. package/dist/umd/stores/config.d.ts +1 -5
  162. package/dist/umd/stores/config.d.ts.map +1 -1
  163. package/dist/umd/stores/data.d.ts +3 -5
  164. package/dist/umd/stores/data.d.ts.map +1 -1
  165. package/dist/umd/stores/index.d.ts +0 -2
  166. package/dist/umd/stores/index.d.ts.map +1 -1
  167. package/dist/umd/stores/interaction.d.ts.map +1 -1
  168. package/dist/umd/stores/mode-live.d.ts +0 -4
  169. package/dist/umd/stores/mode-live.d.ts.map +1 -1
  170. package/dist/umd/stores/viz.d.ts +4 -0
  171. package/dist/umd/stores/viz.d.ts.map +1 -1
  172. package/dist/umd/types/clarity.d.ts +0 -5
  173. package/dist/umd/types/clarity.d.ts.map +1 -1
  174. package/dist/umd/types/heatmap.d.ts +0 -13
  175. package/dist/umd/types/heatmap.d.ts.map +1 -1
  176. package/dist/umd/types/index.d.ts +1 -4
  177. package/dist/umd/types/index.d.ts.map +1 -1
  178. package/dist/umd/types/viewport-fixer.d.ts +31 -0
  179. package/dist/umd/types/viewport-fixer.d.ts.map +1 -0
  180. package/dist/umd/types/viz-element.d.ts +6 -0
  181. package/dist/umd/types/viz-element.d.ts.map +1 -1
  182. package/package.json +13 -15
  183. package/src/components/GraphView.tsx +58 -0
  184. package/src/components/Layout/ContentMetricBar.tsx +23 -0
  185. package/src/components/Layout/ContentToolbar.tsx +22 -0
  186. package/src/components/Layout/ContentTopBar.tsx +24 -0
  187. package/src/components/Layout/ContentVizByMode.tsx +14 -0
  188. package/src/components/Layout/HeatmapLayout.tsx +60 -0
  189. package/src/components/Layout/LeftSidebar.tsx +44 -0
  190. package/src/components/Layout/WrapperLayout.tsx +12 -0
  191. package/src/components/Layout/WrapperPreview.tsx +24 -0
  192. package/src/components/Layout/index.ts +1 -0
  193. package/src/components/VizDom/ReplayControls.tsx +48 -0
  194. package/src/components/VizDom/VizContainer.tsx +40 -0
  195. package/src/components/VizDom/VizDomHeatmap.tsx +28 -0
  196. package/src/components/VizDom/VizDomRenderer.tsx +82 -0
  197. package/src/components/VizDom/VizLoading.tsx +8 -0
  198. package/src/components/VizDom/WrapperVisual.tsx +73 -0
  199. package/src/components/VizDom/index.ts +5 -0
  200. package/src/components/VizElement/DefaultRankBadges.tsx +36 -0
  201. package/src/components/VizElement/ElementCallout.tsx +82 -0
  202. package/src/components/VizElement/ElementMissing.tsx +35 -0
  203. package/src/components/VizElement/ElementOverlay.tsx +66 -0
  204. package/src/components/VizElement/HeatmapElements.tsx +127 -0
  205. package/src/components/VizElement/HeatmapExample.tsx +70 -0
  206. package/src/components/VizElement/RankBadge.tsx +25 -0
  207. package/src/components/VizElement/VizElements.tsx +57 -0
  208. package/src/components/VizElement/index.ts +1 -0
  209. package/src/components/VizLive/VizLiveHeatmap.tsx +27 -0
  210. package/src/components/VizLive/VizLiveRenderer.tsx +47 -0
  211. package/src/components/VizLive/index.ts +1 -0
  212. package/src/components/VizScrollmap/AverageFoldLine.tsx +57 -0
  213. package/src/components/VizScrollmap/HoverZones.tsx +58 -0
  214. package/src/components/VizScrollmap/MetricRow.tsx +0 -0
  215. package/src/components/VizScrollmap/ScrollMapMinimap.tsx +64 -0
  216. package/src/components/VizScrollmap/ScrollMapOverlay.tsx +79 -0
  217. package/src/components/VizScrollmap/ScrollZoneHoverArea.tsx +35 -0
  218. package/src/components/VizScrollmap/ScrollZoneTooltip.tsx +146 -0
  219. package/src/components/VizScrollmap/ScrollmapMarker.tsx +106 -0
  220. package/src/components/VizScrollmap/VizScrollMap.tsx +36 -0
  221. package/{dist/esm/components/VizScrollmap/index.d.ts → src/components/VizScrollmap/index.ts} +0 -1
  222. package/src/components/VizScrollmapV2/ScrollmapOverlay.css +94 -0
  223. package/src/components/VizScrollmapV2/ScrollmapOverlayV2.tsx +130 -0
  224. package/{dist/esm/components/VizScrollmapV2/index.d.ts → src/components/VizScrollmapV2/index.ts} +0 -1
  225. package/src/components/VizScrollmapV2/scrollmap.types.ts +21 -0
  226. package/src/components/VizScrollmapV2/useScrollmapOverlay.ts +187 -0
  227. package/src/components/index.tsx +2 -0
  228. package/src/configs/iframe.ts +15 -0
  229. package/src/configs/index.ts +2 -0
  230. package/src/configs/style.ts +21 -0
  231. package/src/constants/index.ts +4 -0
  232. package/src/global.d.ts +5 -0
  233. package/src/helpers/elm-callout.ts +347 -0
  234. package/src/helpers/elm-getter.ts +70 -0
  235. package/src/helpers/iframe-helper/fixer.ts +100 -0
  236. package/src/helpers/iframe-helper/index.ts +1 -0
  237. package/src/helpers/iframe-helper/init.ts +56 -0
  238. package/src/helpers/iframe-helper/navigation-blocker-v2.ts +371 -0
  239. package/src/helpers/iframe-helper/navigation-blocker.ts +367 -0
  240. package/src/helpers/iframe-helper/style-replacer.ts +231 -0
  241. package/src/helpers/iframe.ts +42 -0
  242. package/src/helpers/index.ts +8 -0
  243. package/src/helpers/viz-canvas/area-clustering.ts +234 -0
  244. package/src/helpers/viz-canvas/area-overlay-manager-v2.ts +176 -0
  245. package/src/helpers/viz-canvas/area-overlay-manager.ts +273 -0
  246. package/src/helpers/viz-canvas/hierarchical-area-clustering.ts +420 -0
  247. package/{dist/esm/helpers/viz-canvas/index.d.ts → src/helpers/viz-canvas/index.ts} +0 -1
  248. package/src/helpers/viz-elements.ts +43 -0
  249. package/src/hooks/index.ts +8 -0
  250. package/src/hooks/register/index.ts +4 -0
  251. package/src/hooks/register/useRegisterConfig.ts +17 -0
  252. package/src/hooks/register/useRegisterControl.ts +13 -0
  253. package/src/hooks/register/useRegisterData.ts +36 -0
  254. package/src/hooks/register/useRegisterHeatmap.ts +38 -0
  255. package/src/hooks/viz-area/useAreaHeatmap.ts +336 -0
  256. package/src/hooks/viz-area/useAreaHeatmapManager.ts +692 -0
  257. package/src/hooks/viz-canvas/index.ts +1 -0
  258. package/src/hooks/viz-canvas/useAreamap.ts +162 -0
  259. package/src/hooks/viz-canvas/useClickmap.ts +24 -0
  260. package/src/hooks/viz-canvas/useHeatmapCanvas.ts +27 -0
  261. package/src/hooks/viz-canvas/useScrollmap.ts +22 -0
  262. package/src/hooks/viz-elements/index.ts +5 -0
  263. package/src/hooks/viz-elements/useClickedElement.ts +86 -0
  264. package/src/hooks/viz-elements/useElementCalloutVisible.ts +45 -0
  265. package/src/hooks/viz-elements/useHeatmapEffects.ts +30 -0
  266. package/src/hooks/viz-elements/useHeatmapElementPosition.ts +60 -0
  267. package/src/hooks/viz-elements/useHeatmapMouseHandler.ts +255 -0
  268. package/src/hooks/viz-elements/useHoveredElement.ts +170 -0
  269. package/src/hooks/viz-live/index.ts +1 -0
  270. package/src/hooks/viz-live/useVizLiveIframeMsg.ts +88 -0
  271. package/src/hooks/viz-live/useVizLiveRender.ts +67 -0
  272. package/src/hooks/viz-render/index.ts +1 -0
  273. package/src/hooks/viz-render/useHeatmapRender.ts +71 -0
  274. package/src/hooks/viz-render/useHeatmapVizRender.ts +20 -0
  275. package/src/hooks/viz-render/useReplayRender.ts +160 -0
  276. package/src/hooks/viz-scale/index.ts +2 -0
  277. package/src/hooks/viz-scale/useContainerDimensions.ts +48 -0
  278. package/src/hooks/viz-scale/useContentDimensions.ts +25 -0
  279. package/src/hooks/viz-scale/useHeatmapScale.ts +52 -0
  280. package/src/hooks/viz-scale/useObserveIframeHeight.ts +162 -0
  281. package/src/hooks/viz-scale/useScaleCalculation.ts +31 -0
  282. package/src/hooks/viz-scale/useScrollSync.ts +36 -0
  283. package/src/hooks/viz-scale/useWrapperRefHeight.ts +91 -0
  284. package/{dist/esm/hooks/viz-scrollmap/index.d.ts → src/hooks/viz-scrollmap/index.ts} +0 -1
  285. package/src/hooks/viz-scrollmap/useScrollmapZones.ts +165 -0
  286. package/src/hooks/viz-scrollmap/useZonePositions.ts +38 -0
  287. package/src/index.ts +10 -0
  288. package/src/stores/comp.ts +31 -0
  289. package/src/stores/config.ts +37 -0
  290. package/src/stores/data.ts +30 -0
  291. package/src/stores/index.ts +10 -0
  292. package/src/stores/interaction.ts +32 -0
  293. package/src/stores/mode-live.ts +38 -0
  294. package/src/stores/mode-single.ts +18 -0
  295. package/src/stores/viz-scrollmap.ts +22 -0
  296. package/src/stores/viz.ts +17 -0
  297. package/src/styles/base.css +1 -0
  298. package/src/styles/style.css +137 -0
  299. package/src/types/clarity.ts +45 -0
  300. package/src/types/control.ts +10 -0
  301. package/src/types/elm-callout.ts +9 -0
  302. package/src/types/heatmap-info.ts +11 -0
  303. package/src/types/heatmap.ts +25 -0
  304. package/src/types/iframe-helper.ts +18 -0
  305. package/src/types/index.ts +12 -0
  306. package/src/types/viz-canvas.ts +20 -0
  307. package/src/types/viz-element.ts +34 -0
  308. package/src/types/viz-scrollmap.ts +28 -0
  309. package/src/ui/BoxStack/BoxStack.tsx +136 -0
  310. package/src/ui/BoxStack/index.ts +1 -0
  311. package/src/ui/index.ts +1 -0
  312. package/src/utils/debounce.ts +10 -0
  313. package/src/utils/device.ts +7 -0
  314. package/src/utils/retry.ts +20 -0
  315. package/src/utils/sort.ts +5 -0
  316. package/dist/esm/components/VizElement/HeatmapExample.d.ts +0 -2
  317. package/dist/esm/components/VizElement/HeatmapExample.d.ts.map +0 -1
  318. package/dist/esm/components/VizScrollmap/AverageFoldLine.d.ts +0 -8
  319. package/dist/esm/components/VizScrollmap/AverageFoldLine.d.ts.map +0 -1
  320. package/dist/esm/components/VizScrollmap/HoverZones.d.ts +0 -10
  321. package/dist/esm/components/VizScrollmap/HoverZones.d.ts.map +0 -1
  322. package/dist/esm/components/VizScrollmap/MetricRow.d.ts +0 -1
  323. package/dist/esm/components/VizScrollmap/MetricRow.d.ts.map +0 -1
  324. package/dist/esm/components/VizScrollmap/ScrollMapMinimap.d.ts +0 -8
  325. package/dist/esm/components/VizScrollmap/ScrollMapMinimap.d.ts.map +0 -1
  326. package/dist/esm/components/VizScrollmap/ScrollMapOverlay.d.ts +0 -7
  327. package/dist/esm/components/VizScrollmap/ScrollMapOverlay.d.ts.map +0 -1
  328. package/dist/esm/components/VizScrollmap/ScrollZoneHoverArea.d.ts +0 -14
  329. package/dist/esm/components/VizScrollmap/ScrollZoneHoverArea.d.ts.map +0 -1
  330. package/dist/esm/components/VizScrollmap/ScrollZoneTooltip.d.ts +0 -10
  331. package/dist/esm/components/VizScrollmap/ScrollZoneTooltip.d.ts.map +0 -1
  332. package/dist/esm/components/VizScrollmap/ScrollmapMarker.d.ts +0 -7
  333. package/dist/esm/components/VizScrollmap/ScrollmapMarker.d.ts.map +0 -1
  334. package/dist/esm/components/VizScrollmap/VizScrollMap.d.ts +0 -7
  335. package/dist/esm/components/VizScrollmap/VizScrollMap.d.ts.map +0 -1
  336. package/dist/esm/components/VizScrollmap/index.d.ts.map +0 -1
  337. package/dist/esm/components/VizScrollmapV2/ScrollmapOverlayV2.d.ts +0 -5
  338. package/dist/esm/components/VizScrollmapV2/ScrollmapOverlayV2.d.ts.map +0 -1
  339. package/dist/esm/components/VizScrollmapV2/index.d.ts.map +0 -1
  340. package/dist/esm/components/VizScrollmapV2/scrollmap.types.d.ts +0 -18
  341. package/dist/esm/components/VizScrollmapV2/scrollmap.types.d.ts.map +0 -1
  342. package/dist/esm/components/VizScrollmapV2/useScrollmapOverlay.d.ts +0 -16
  343. package/dist/esm/components/VizScrollmapV2/useScrollmapOverlay.d.ts.map +0 -1
  344. package/dist/esm/helpers/iframe-helper/fixer.d.ts +0 -18
  345. package/dist/esm/helpers/iframe-helper/fixer.d.ts.map +0 -1
  346. package/dist/esm/helpers/iframe-helper/index.d.ts +0 -2
  347. package/dist/esm/helpers/iframe-helper/index.d.ts.map +0 -1
  348. package/dist/esm/helpers/iframe-helper/init.d.ts +0 -5
  349. package/dist/esm/helpers/iframe-helper/init.d.ts.map +0 -1
  350. package/dist/esm/helpers/iframe-helper/navigation-blocker-v2.d.ts +0 -28
  351. package/dist/esm/helpers/iframe-helper/navigation-blocker-v2.d.ts.map +0 -1
  352. package/dist/esm/helpers/iframe-helper/navigation-blocker.d.ts +0 -20
  353. package/dist/esm/helpers/iframe-helper/navigation-blocker.d.ts.map +0 -1
  354. package/dist/esm/helpers/iframe-helper/style-replacer.d.ts +0 -25
  355. package/dist/esm/helpers/iframe-helper/style-replacer.d.ts.map +0 -1
  356. package/dist/esm/helpers/viz-canvas/area-clustering.d.ts +0 -44
  357. package/dist/esm/helpers/viz-canvas/area-clustering.d.ts.map +0 -1
  358. package/dist/esm/helpers/viz-canvas/area-overlay-manager-v2.d.ts +0 -17
  359. package/dist/esm/helpers/viz-canvas/area-overlay-manager-v2.d.ts.map +0 -1
  360. package/dist/esm/helpers/viz-canvas/area-overlay-manager.d.ts +0 -51
  361. package/dist/esm/helpers/viz-canvas/area-overlay-manager.d.ts.map +0 -1
  362. package/dist/esm/helpers/viz-canvas/hierarchical-area-clustering.d.ts +0 -73
  363. package/dist/esm/helpers/viz-canvas/hierarchical-area-clustering.d.ts.map +0 -1
  364. package/dist/esm/helpers/viz-canvas/index.d.ts.map +0 -1
  365. package/dist/esm/hooks/viz-area/useAreaHeatmap.d.ts +0 -59
  366. package/dist/esm/hooks/viz-area/useAreaHeatmap.d.ts.map +0 -1
  367. package/dist/esm/hooks/viz-area/useAreaHeatmapManager.d.ts +0 -77
  368. package/dist/esm/hooks/viz-area/useAreaHeatmapManager.d.ts.map +0 -1
  369. package/dist/esm/hooks/viz-canvas/useAreamap.d.ts +0 -14
  370. package/dist/esm/hooks/viz-canvas/useAreamap.d.ts.map +0 -1
  371. package/dist/esm/hooks/viz-canvas/useHeatmapCanvas.d.ts +0 -4
  372. package/dist/esm/hooks/viz-canvas/useHeatmapCanvas.d.ts.map +0 -1
  373. package/dist/esm/hooks/viz-elements/useHeatmapMouseHandler.d.ts +0 -34
  374. package/dist/esm/hooks/viz-elements/useHeatmapMouseHandler.d.ts.map +0 -1
  375. package/dist/esm/hooks/viz-elements/useHoveredElement.d.ts.map +0 -1
  376. package/dist/esm/hooks/viz-live/useVizLiveIframeMsg.d.ts.map +0 -1
  377. package/dist/esm/hooks/viz-live/useVizLiveRender.d.ts +0 -4
  378. package/dist/esm/hooks/viz-live/useVizLiveRender.d.ts.map +0 -1
  379. package/dist/esm/hooks/viz-scale/useObserveIframeHeight.d.ts +0 -10
  380. package/dist/esm/hooks/viz-scale/useObserveIframeHeight.d.ts.map +0 -1
  381. package/dist/esm/hooks/viz-scrollmap/index.d.ts.map +0 -1
  382. package/dist/esm/hooks/viz-scrollmap/useScrollmapZones.d.ts +0 -29
  383. package/dist/esm/hooks/viz-scrollmap/useScrollmapZones.d.ts.map +0 -1
  384. package/dist/esm/hooks/viz-scrollmap/useZonePositions.d.ts +0 -12
  385. package/dist/esm/hooks/viz-scrollmap/useZonePositions.d.ts.map +0 -1
  386. package/dist/esm/stores/mode-single.d.ts +0 -9
  387. package/dist/esm/stores/mode-single.d.ts.map +0 -1
  388. package/dist/esm/stores/viz-scrollmap.d.ts +0 -11
  389. package/dist/esm/stores/viz-scrollmap.d.ts.map +0 -1
  390. package/dist/esm/types/heatmap-info.d.ts +0 -11
  391. package/dist/esm/types/heatmap-info.d.ts.map +0 -1
  392. package/dist/esm/types/iframe-helper.d.ts +0 -20
  393. package/dist/esm/types/iframe-helper.d.ts.map +0 -1
  394. package/dist/esm/types/viz-canvas.d.ts +0 -23
  395. package/dist/esm/types/viz-canvas.d.ts.map +0 -1
  396. package/dist/esm/types/viz-scrollmap.d.ts +0 -27
  397. package/dist/esm/types/viz-scrollmap.d.ts.map +0 -1
  398. package/dist/umd/components/VizElement/HeatmapExample.d.ts +0 -2
  399. package/dist/umd/components/VizElement/HeatmapExample.d.ts.map +0 -1
  400. package/dist/umd/components/VizScrollmap/AverageFoldLine.d.ts +0 -8
  401. package/dist/umd/components/VizScrollmap/AverageFoldLine.d.ts.map +0 -1
  402. package/dist/umd/components/VizScrollmap/HoverZones.d.ts +0 -10
  403. package/dist/umd/components/VizScrollmap/HoverZones.d.ts.map +0 -1
  404. package/dist/umd/components/VizScrollmap/MetricRow.d.ts +0 -1
  405. package/dist/umd/components/VizScrollmap/MetricRow.d.ts.map +0 -1
  406. package/dist/umd/components/VizScrollmap/ScrollMapMinimap.d.ts +0 -8
  407. package/dist/umd/components/VizScrollmap/ScrollMapMinimap.d.ts.map +0 -1
  408. package/dist/umd/components/VizScrollmap/ScrollMapOverlay.d.ts +0 -7
  409. package/dist/umd/components/VizScrollmap/ScrollMapOverlay.d.ts.map +0 -1
  410. package/dist/umd/components/VizScrollmap/ScrollZoneHoverArea.d.ts +0 -14
  411. package/dist/umd/components/VizScrollmap/ScrollZoneHoverArea.d.ts.map +0 -1
  412. package/dist/umd/components/VizScrollmap/ScrollZoneTooltip.d.ts +0 -10
  413. package/dist/umd/components/VizScrollmap/ScrollZoneTooltip.d.ts.map +0 -1
  414. package/dist/umd/components/VizScrollmap/ScrollmapMarker.d.ts +0 -7
  415. package/dist/umd/components/VizScrollmap/ScrollmapMarker.d.ts.map +0 -1
  416. package/dist/umd/components/VizScrollmap/VizScrollMap.d.ts +0 -7
  417. package/dist/umd/components/VizScrollmap/VizScrollMap.d.ts.map +0 -1
  418. package/dist/umd/components/VizScrollmap/index.d.ts +0 -2
  419. package/dist/umd/components/VizScrollmap/index.d.ts.map +0 -1
  420. package/dist/umd/components/VizScrollmapV2/ScrollmapOverlayV2.d.ts +0 -5
  421. package/dist/umd/components/VizScrollmapV2/ScrollmapOverlayV2.d.ts.map +0 -1
  422. package/dist/umd/components/VizScrollmapV2/index.d.ts +0 -2
  423. package/dist/umd/components/VizScrollmapV2/index.d.ts.map +0 -1
  424. package/dist/umd/components/VizScrollmapV2/scrollmap.types.d.ts +0 -18
  425. package/dist/umd/components/VizScrollmapV2/scrollmap.types.d.ts.map +0 -1
  426. package/dist/umd/components/VizScrollmapV2/useScrollmapOverlay.d.ts +0 -16
  427. package/dist/umd/components/VizScrollmapV2/useScrollmapOverlay.d.ts.map +0 -1
  428. package/dist/umd/helpers/iframe-helper/fixer.d.ts +0 -18
  429. package/dist/umd/helpers/iframe-helper/fixer.d.ts.map +0 -1
  430. package/dist/umd/helpers/iframe-helper/index.d.ts +0 -2
  431. package/dist/umd/helpers/iframe-helper/index.d.ts.map +0 -1
  432. package/dist/umd/helpers/iframe-helper/init.d.ts +0 -5
  433. package/dist/umd/helpers/iframe-helper/init.d.ts.map +0 -1
  434. package/dist/umd/helpers/iframe-helper/navigation-blocker-v2.d.ts +0 -28
  435. package/dist/umd/helpers/iframe-helper/navigation-blocker-v2.d.ts.map +0 -1
  436. package/dist/umd/helpers/iframe-helper/navigation-blocker.d.ts +0 -20
  437. package/dist/umd/helpers/iframe-helper/navigation-blocker.d.ts.map +0 -1
  438. package/dist/umd/helpers/iframe-helper/style-replacer.d.ts +0 -25
  439. package/dist/umd/helpers/iframe-helper/style-replacer.d.ts.map +0 -1
  440. package/dist/umd/helpers/viz-canvas/area-clustering.d.ts +0 -44
  441. package/dist/umd/helpers/viz-canvas/area-clustering.d.ts.map +0 -1
  442. package/dist/umd/helpers/viz-canvas/area-overlay-manager-v2.d.ts +0 -17
  443. package/dist/umd/helpers/viz-canvas/area-overlay-manager-v2.d.ts.map +0 -1
  444. package/dist/umd/helpers/viz-canvas/area-overlay-manager.d.ts +0 -51
  445. package/dist/umd/helpers/viz-canvas/area-overlay-manager.d.ts.map +0 -1
  446. package/dist/umd/helpers/viz-canvas/hierarchical-area-clustering.d.ts +0 -73
  447. package/dist/umd/helpers/viz-canvas/hierarchical-area-clustering.d.ts.map +0 -1
  448. package/dist/umd/helpers/viz-canvas/index.d.ts +0 -3
  449. package/dist/umd/helpers/viz-canvas/index.d.ts.map +0 -1
  450. package/dist/umd/hooks/viz-area/useAreaHeatmap.d.ts +0 -59
  451. package/dist/umd/hooks/viz-area/useAreaHeatmap.d.ts.map +0 -1
  452. package/dist/umd/hooks/viz-area/useAreaHeatmapManager.d.ts +0 -77
  453. package/dist/umd/hooks/viz-area/useAreaHeatmapManager.d.ts.map +0 -1
  454. package/dist/umd/hooks/viz-canvas/useAreamap.d.ts +0 -14
  455. package/dist/umd/hooks/viz-canvas/useAreamap.d.ts.map +0 -1
  456. package/dist/umd/hooks/viz-canvas/useHeatmapCanvas.d.ts +0 -4
  457. package/dist/umd/hooks/viz-canvas/useHeatmapCanvas.d.ts.map +0 -1
  458. package/dist/umd/hooks/viz-elements/useHeatmapMouseHandler.d.ts +0 -34
  459. package/dist/umd/hooks/viz-elements/useHeatmapMouseHandler.d.ts.map +0 -1
  460. package/dist/umd/hooks/viz-elements/useHoveredElement.d.ts.map +0 -1
  461. package/dist/umd/hooks/viz-live/useVizLiveIframeMsg.d.ts.map +0 -1
  462. package/dist/umd/hooks/viz-live/useVizLiveRender.d.ts +0 -4
  463. package/dist/umd/hooks/viz-live/useVizLiveRender.d.ts.map +0 -1
  464. package/dist/umd/hooks/viz-scale/useObserveIframeHeight.d.ts +0 -10
  465. package/dist/umd/hooks/viz-scale/useObserveIframeHeight.d.ts.map +0 -1
  466. package/dist/umd/hooks/viz-scrollmap/index.d.ts +0 -3
  467. package/dist/umd/hooks/viz-scrollmap/index.d.ts.map +0 -1
  468. package/dist/umd/hooks/viz-scrollmap/useScrollmapZones.d.ts +0 -29
  469. package/dist/umd/hooks/viz-scrollmap/useScrollmapZones.d.ts.map +0 -1
  470. package/dist/umd/hooks/viz-scrollmap/useZonePositions.d.ts +0 -12
  471. package/dist/umd/hooks/viz-scrollmap/useZonePositions.d.ts.map +0 -1
  472. package/dist/umd/stores/mode-single.d.ts +0 -9
  473. package/dist/umd/stores/mode-single.d.ts.map +0 -1
  474. package/dist/umd/stores/viz-scrollmap.d.ts +0 -11
  475. package/dist/umd/stores/viz-scrollmap.d.ts.map +0 -1
  476. package/dist/umd/types/heatmap-info.d.ts +0 -11
  477. package/dist/umd/types/heatmap-info.d.ts.map +0 -1
  478. package/dist/umd/types/iframe-helper.d.ts +0 -20
  479. package/dist/umd/types/iframe-helper.d.ts.map +0 -1
  480. package/dist/umd/types/viz-canvas.d.ts +0 -23
  481. package/dist/umd/types/viz-canvas.d.ts.map +0 -1
  482. package/dist/umd/types/viz-scrollmap.d.ts +0 -27
  483. package/dist/umd/types/viz-scrollmap.d.ts.map +0 -1
  484. /package/dist/esm/hooks/{viz-elements → vix-elements}/index.d.ts +0 -0
  485. /package/dist/esm/hooks/{viz-elements → vix-elements}/useClickedElement.d.ts +0 -0
  486. /package/dist/esm/hooks/{viz-elements → vix-elements}/useElementCalloutVisible.d.ts +0 -0
  487. /package/dist/esm/hooks/{viz-elements → vix-elements}/useHeatmapEffects.d.ts +0 -0
  488. /package/dist/esm/hooks/{viz-elements → vix-elements}/useHeatmapElementPosition.d.ts +0 -0
  489. /package/dist/umd/hooks/{viz-elements → vix-elements}/index.d.ts +0 -0
  490. /package/dist/umd/hooks/{viz-elements → vix-elements}/useClickedElement.d.ts +0 -0
  491. /package/dist/umd/hooks/{viz-elements → vix-elements}/useElementCalloutVisible.d.ts +0 -0
  492. /package/dist/umd/hooks/{viz-elements → vix-elements}/useHeatmapEffects.d.ts +0 -0
  493. /package/dist/umd/hooks/{viz-elements → vix-elements}/useHeatmapElementPosition.d.ts +0 -0
@@ -0,0 +1,234 @@
1
+ import { ClickMapPoint, IClusterArea, IClusterAreaRect } from '../../types';
2
+
3
+ interface ClickElement {
4
+ hash: string;
5
+ element: HTMLElement;
6
+ rect: IClusterAreaRect;
7
+ clicks: number;
8
+ }
9
+
10
+ const HEATMAP_GRADIENT_COLORS: [number, number, number][] = [
11
+ [0, 0, 255], // Blue (cold)
12
+ [0, 255, 255], // Cyan
13
+ [0, 255, 0], // Green
14
+ [255, 255, 0], // Yellow
15
+ [255, 0, 0], // Red (hot)
16
+ ];
17
+
18
+ const GRADIENT_COLOR_COUNT = HEATMAP_GRADIENT_COLORS.length - 1;
19
+
20
+ // Configuration
21
+ const CLUSTERING_CONFIG = {
22
+ maxDistance: 1, // Khoảng cách tối đa để gom nhóm (px)
23
+ minElements: 1, // Số elements tối thiểu trong 1 cluster
24
+ mergePadding: 0, // Padding khi merge các rects
25
+ };
26
+
27
+ export class AreaClusteringEngine {
28
+ /**
29
+ * Cluster click elements thành các vùng
30
+ */
31
+ public clusterAreas(
32
+ clickData: ClickMapPoint[],
33
+ iframeDoc: Document,
34
+ totalClicks: number,
35
+ ): IClusterArea[] {
36
+ // 1. Get all click elements với rect
37
+ const clickElements = this.getClickElements(clickData, iframeDoc);
38
+ if (clickElements.length === 0) return [];
39
+
40
+ // 2. Clustering based on proximity
41
+ const clusters = this.performClustering(clickElements);
42
+
43
+ // 3. Create area objects từ clusters
44
+ const areas = this.createAreasFromClusters(clusters, totalClicks);
45
+
46
+ // 4. Sort by click percentage (descending)
47
+ areas.sort((a, b) => b.clickPercentage - a.clickPercentage);
48
+
49
+ console.log(
50
+ `[AreaClustering] Created ${areas.length} areas from ${clickElements.length} elements`,
51
+ );
52
+
53
+ return areas;
54
+ }
55
+
56
+ /**
57
+ * Get click elements with their rects
58
+ */
59
+ private getClickElements(clickData: ClickMapPoint[], iframeDoc: Document): ClickElement[] {
60
+ const elements: ClickElement[] = [];
61
+
62
+ clickData.forEach((item) => {
63
+ const element = iframeDoc.querySelector(
64
+ `[data-clarity-hashalpha="${item.hash}"]`,
65
+ ) as HTMLElement;
66
+
67
+ if (!element || item.clicks.length === 0) return;
68
+ if (element.tagName === 'BODY') return;
69
+
70
+ const rect = this.getElementRect(element);
71
+
72
+ // Lọc elements quá nhỏ hoặc không visible
73
+ if (rect.width < 10 || rect.height < 10) return;
74
+
75
+ elements.push({
76
+ hash: item.hash,
77
+ element,
78
+ rect,
79
+ clicks: item.clicks.reduce((sum, click) => sum + click, 0),
80
+ });
81
+ });
82
+
83
+ return elements;
84
+ }
85
+
86
+ /**
87
+ * Get element rect
88
+ */
89
+ private getElementRect(element: HTMLElement): IClusterAreaRect {
90
+ const domRect = element.getBoundingClientRect();
91
+ return {
92
+ top: domRect.top,
93
+ left: domRect.left,
94
+ width: domRect.width,
95
+ height: domRect.height,
96
+ right: domRect.right,
97
+ bottom: domRect.bottom,
98
+ };
99
+ }
100
+
101
+ /**
102
+ * Perform clustering using distance-based algorithm
103
+ */
104
+ private performClustering(clickElements: ClickElement[]): ClickElement[][] {
105
+ const clusters: ClickElement[][] = [];
106
+ const used = new Set<number>();
107
+
108
+ // Sort by clicks descending để ưu tiên elements có nhiều clicks
109
+ const sorted = [...clickElements].sort((a, b) => b.clicks - a.clicks);
110
+
111
+ sorted.forEach((element, index) => {
112
+ if (used.has(index)) return;
113
+
114
+ // Tạo cluster mới với element này làm seed
115
+ const cluster: ClickElement[] = [element];
116
+ used.add(index);
117
+
118
+ // Tìm các elements gần với cluster này
119
+ sorted.forEach((other, otherIndex) => {
120
+ if (used.has(otherIndex)) return;
121
+
122
+ // Check khoảng cách với bất kỳ element nào trong cluster
123
+ const isNear = cluster.some((clusterEl) => {
124
+ return this.getDistance(clusterEl.rect, other.rect) <= CLUSTERING_CONFIG.maxDistance;
125
+ });
126
+
127
+ if (isNear) {
128
+ cluster.push(other);
129
+ used.add(otherIndex);
130
+ }
131
+ });
132
+
133
+ // Chỉ thêm cluster nếu đủ elements
134
+ if (cluster.length >= CLUSTERING_CONFIG.minElements) {
135
+ clusters.push(cluster);
136
+ }
137
+ });
138
+
139
+ return clusters;
140
+ }
141
+
142
+ /**
143
+ * Calculate distance between two rects (edge-to-edge)
144
+ */
145
+ private getDistance(rect1: IClusterAreaRect, rect2: IClusterAreaRect): number {
146
+ // Tính khoảng cách edge-to-edge thay vì center-to-center
147
+ const horizontalDistance = Math.max(0, rect1.left - rect2.right, rect2.left - rect1.right);
148
+
149
+ const verticalDistance = Math.max(0, rect1.top - rect2.bottom, rect2.top - rect1.bottom);
150
+
151
+ // Euclidean distance
152
+ return Math.sqrt(horizontalDistance ** 2 + verticalDistance ** 2);
153
+ }
154
+
155
+ /**
156
+ * Create area objects from clusters
157
+ */
158
+ private createAreasFromClusters(clusters: ClickElement[][], totalClicks: number): IClusterArea[] {
159
+ return clusters.map((cluster, index) => {
160
+ const totalClusterClicks = cluster.reduce((sum, el) => sum + el.clicks, 0);
161
+ const clickPercentage = (totalClusterClicks / totalClicks) * 100;
162
+
163
+ // Calculate bounding rect cho cluster
164
+ const boundingRect = this.calculateBoundingRect(cluster.map((c) => c.rect));
165
+
166
+ // Calculate centroid
167
+ const centroid = this.calculateCentroid(cluster.map((c) => c.rect));
168
+
169
+ return {
170
+ id: `area_${index}`,
171
+ elements: cluster.map((c) => c.element),
172
+ hashes: cluster.map((c) => c.hash),
173
+ boundingRect,
174
+ totalClicks: totalClusterClicks,
175
+ clickPercentage,
176
+ color: this.getHeatmapColor(clickPercentage / 100),
177
+ hoverColor: this.getHoverColor(clickPercentage / 100),
178
+ centroid,
179
+ };
180
+ });
181
+ }
182
+
183
+ /**
184
+ * Calculate bounding rect for multiple rects
185
+ */
186
+ private calculateBoundingRect(rects: IClusterAreaRect[]): IClusterAreaRect {
187
+ const padding = CLUSTERING_CONFIG.mergePadding;
188
+
189
+ const minLeft = Math.min(...rects.map((r) => r.left)) - padding;
190
+ const minTop = Math.min(...rects.map((r) => r.top)) - padding;
191
+ const maxRight = Math.max(...rects.map((r) => r.right)) + padding;
192
+ const maxBottom = Math.max(...rects.map((r) => r.bottom)) + padding;
193
+
194
+ return {
195
+ left: minLeft,
196
+ top: minTop,
197
+ width: maxRight - minLeft,
198
+ height: maxBottom - minTop,
199
+ right: maxRight,
200
+ bottom: maxBottom,
201
+ };
202
+ }
203
+
204
+ /**
205
+ * Calculate centroid (center point) of cluster
206
+ */
207
+ private calculateCentroid(rects: IClusterAreaRect[]): { x: number; y: number } {
208
+ const sumX = rects.reduce((sum, r) => sum + (r.left + r.width / 2), 0);
209
+ const sumY = rects.reduce((sum, r) => sum + (r.top + r.height / 2), 0);
210
+
211
+ return {
212
+ x: sumX / rects.length,
213
+ y: sumY / rects.length,
214
+ };
215
+ }
216
+
217
+ /**
218
+ * Get heatmap color based on percentage (0-1)
219
+ */
220
+ private getHeatmapColor(percentage: number): string {
221
+ const index = Math.min(Math.floor(percentage * GRADIENT_COLOR_COUNT), GRADIENT_COLOR_COUNT - 1);
222
+ const [r, g, b] = HEATMAP_GRADIENT_COLORS[index];
223
+ return `rgba(${r}, ${g}, ${b}, 0.5)`;
224
+ }
225
+
226
+ /**
227
+ * Get hover color
228
+ */
229
+ private getHoverColor(percentage: number): string {
230
+ const index = Math.min(Math.floor(percentage * GRADIENT_COLOR_COUNT), GRADIENT_COLOR_COUNT - 1);
231
+ const [r, g, b] = HEATMAP_GRADIENT_COLORS[index];
232
+ return `rgba(${r}, ${g}, ${b}, 0.8)`;
233
+ }
234
+ }
@@ -0,0 +1,176 @@
1
+ import { AreaMapData } from './area-overlay-manager';
2
+ import {
3
+ HierarchicalAreaClusteringEngine,
4
+ HierarchicalCluster,
5
+ } from './hierarchical-area-clustering';
6
+
7
+ const MIN_LABEL_WIDTH = 67;
8
+ const MIN_LABEL_HEIGHT = 30;
9
+
10
+ export class AreaOverlayManagerV2 {
11
+ private iframe: HTMLIFrameElement;
12
+ private overlayContainer: HTMLDivElement | null = null;
13
+ private areas = new Map<string, HierarchicalCluster>();
14
+ private clusteringEngine = new HierarchicalAreaClusteringEngine();
15
+ private overlayElements = new Map<string, HTMLDivElement>();
16
+
17
+ constructor(iframe: HTMLIFrameElement) {
18
+ this.iframe = iframe;
19
+ }
20
+
21
+ public init(): void {
22
+ if (this.overlayContainer) {
23
+ this.clear();
24
+ }
25
+
26
+ const container = document.createElement('div');
27
+ container.id = 'area-overlay-container';
28
+
29
+ Object.assign(container.style, {
30
+ position: 'absolute',
31
+ top: '0',
32
+ left: '0',
33
+ width: '100%',
34
+ height: '100%',
35
+ pointerEvents: 'none',
36
+ zIndex: '9998',
37
+ overflow: 'hidden',
38
+ });
39
+
40
+ const iframeStyle = window.getComputedStyle(this.iframe);
41
+ // if (iframeStyle.position === 'static') {
42
+ // this.iframe.style.position = 'relative';
43
+ // }
44
+
45
+ this.iframe.parentElement?.insertBefore(container, this.iframe.nextSibling);
46
+ this.overlayContainer = container;
47
+
48
+ console.log('[AreaOverlayManager] Initialized');
49
+ }
50
+
51
+ public render(data: AreaMapData): void {
52
+ if (!this.overlayContainer || !this.iframe.contentDocument) {
53
+ console.warn('[AreaOverlayManager] Not ready');
54
+ return;
55
+ }
56
+
57
+ this.clear();
58
+
59
+ // Use hierarchical clustering
60
+ const clusters = this.clusteringEngine.clusterAreas(
61
+ data.clickData,
62
+ this.iframe.contentDocument,
63
+ data.totalClicks,
64
+ );
65
+ console.log(`🚀 🐥 ~ AreaOverlayManagerV2 ~ render ~ clusters:`, clusters);
66
+
67
+ // Render each cluster
68
+ clusters.forEach((cluster) => {
69
+ this.createOverlay(cluster);
70
+ this.areas.set(cluster.id, cluster);
71
+ });
72
+
73
+ console.log(`[AreaOverlayManager] Rendered ${clusters.length} hierarchical clusters`);
74
+ }
75
+
76
+ private createOverlay(cluster: HierarchicalCluster): void {
77
+ if (!this.overlayContainer) return;
78
+
79
+ const overlay = document.createElement('div');
80
+ const rect = cluster.boundingRect;
81
+
82
+ Object.assign(overlay.style, {
83
+ position: 'absolute',
84
+ top: `${rect.top}px`,
85
+ left: `${rect.left}px`,
86
+ width: `${rect.width}px`,
87
+ height: `${rect.height}px`,
88
+ backgroundColor: cluster.color,
89
+ boxShadow: '0 0 0 2px white inset',
90
+ display: 'flex',
91
+ alignItems: 'center',
92
+ justifyContent: 'center',
93
+ pointerEvents: 'auto',
94
+ cursor: 'pointer',
95
+ transition: 'background-color 0.2s ease, box-shadow 0.2s ease',
96
+ zIndex: '9999',
97
+ boxSizing: 'border-box',
98
+ borderRadius: '4px',
99
+ });
100
+
101
+ overlay.setAttribute('data-area-id', cluster.id);
102
+ overlay.setAttribute('data-area-level', cluster.level.toString());
103
+ overlay.setAttribute('data-area-clicks', cluster.totalClicks.toString());
104
+
105
+ if (rect.width >= MIN_LABEL_WIDTH && rect.height >= MIN_LABEL_HEIGHT) {
106
+ const label = document.createElement('div');
107
+ label.textContent = `${cluster.clickPercentage.toFixed(2)}%`;
108
+
109
+ Object.assign(label.style, {
110
+ color: '#161514',
111
+ backgroundColor: 'rgba(255, 255, 255, 0.9)',
112
+ padding: '8px 12px',
113
+ borderRadius: '4px',
114
+ fontSize: '14px',
115
+ lineHeight: '20px',
116
+ fontWeight: '600',
117
+ fontFamily: '"Segoe UI", system-ui, -apple-system, sans-serif',
118
+ pointerEvents: 'none',
119
+ userSelect: 'none',
120
+ boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
121
+ });
122
+
123
+ overlay.appendChild(label);
124
+ }
125
+
126
+ // Events
127
+ overlay.addEventListener('mouseenter', () => {
128
+ overlay.style.backgroundColor = cluster.hoverColor;
129
+ overlay.style.boxShadow = '0 0 0 1px #0078D4, 0 0 0 1px #0078D4 inset, 0 0 0 2px white inset';
130
+ });
131
+
132
+ overlay.addEventListener('mouseleave', () => {
133
+ overlay.style.backgroundColor = cluster.color;
134
+ overlay.style.boxShadow = '0 0 0 2px white inset';
135
+ });
136
+
137
+ overlay.addEventListener('click', () => {
138
+ console.log('[AreaOverlayManager] Cluster clicked:', {
139
+ id: cluster.id,
140
+ level: cluster.level,
141
+ parentHash: cluster.parentHash,
142
+ clicks: cluster.totalClicks,
143
+ elements: cluster.elements.length,
144
+ });
145
+
146
+ window.dispatchEvent(new CustomEvent('area-clicked', { detail: cluster }));
147
+
148
+ if (cluster.elements[0]) {
149
+ cluster.elements[0].scrollIntoView({ behavior: 'smooth', block: 'center' });
150
+ }
151
+ });
152
+
153
+ this.overlayContainer.appendChild(overlay);
154
+ this.overlayElements.set(cluster.id, overlay);
155
+ }
156
+
157
+ public clear(): void {
158
+ if (this.overlayContainer) {
159
+ this.overlayContainer.innerHTML = '';
160
+ }
161
+ this.areas.clear();
162
+ this.overlayElements.clear();
163
+ }
164
+
165
+ public destroy(): void {
166
+ this.clear();
167
+ if (this.overlayContainer?.parentElement) {
168
+ this.overlayContainer.parentElement.removeChild(this.overlayContainer);
169
+ }
170
+ this.overlayContainer = null;
171
+ }
172
+
173
+ public getAreas(): HierarchicalCluster[] {
174
+ return Array.from(this.areas.values());
175
+ }
176
+ }
@@ -0,0 +1,273 @@
1
+ import { ClickMapPoint, IClusterArea } from '../../types';
2
+ import { AreaClusteringEngine } from './area-clustering';
3
+
4
+ export interface AreaMapData {
5
+ clickData: ClickMapPoint[];
6
+ totalClicks: number;
7
+ }
8
+
9
+ const MIN_LABEL_WIDTH = 67;
10
+ const MIN_LABEL_HEIGHT = 30;
11
+
12
+ export class AreaOverlayManager {
13
+ private iframe: HTMLIFrameElement;
14
+ private overlayContainer: HTMLDivElement | null = null;
15
+ private areas = new Map<string, IClusterArea>();
16
+ private clusteringEngine = new AreaClusteringEngine();
17
+ private overlayElements = new Map<string, HTMLDivElement>();
18
+
19
+ constructor(iframe: HTMLIFrameElement) {
20
+ this.iframe = iframe;
21
+ }
22
+
23
+ /**
24
+ * Initialize overlay container
25
+ */
26
+ public init(): void {
27
+ if (this.overlayContainer) {
28
+ this.clear();
29
+ }
30
+
31
+ const container = document.createElement('div');
32
+ container.id = 'area-overlay-container';
33
+
34
+ Object.assign(container.style, {
35
+ position: 'absolute',
36
+ top: '0',
37
+ left: '0',
38
+ width: '100%',
39
+ height: '100%',
40
+ pointerEvents: 'none',
41
+ zIndex: '9998',
42
+ overflow: 'hidden',
43
+ });
44
+
45
+ const iframeStyle = window.getComputedStyle(this.iframe);
46
+ // if (iframeStyle.position === 'static') {
47
+ // this.iframe.style.position = 'relative';
48
+ // }
49
+
50
+ this.iframe.parentElement?.insertBefore(container, this.iframe.nextSibling);
51
+ this.overlayContainer = container;
52
+
53
+ console.log('[AreaOverlayManager] Initialized');
54
+ }
55
+
56
+ /**
57
+ * Render clustered areas
58
+ */
59
+ public render(data: AreaMapData): void {
60
+ if (!this.overlayContainer || !this.iframe.contentDocument) {
61
+ console.warn('[AreaOverlayManager] Not ready');
62
+ return;
63
+ }
64
+
65
+ this.clear();
66
+
67
+ // Cluster areas
68
+ const clusterAreas = this.clusteringEngine.clusterAreas(
69
+ data.clickData,
70
+ this.iframe.contentDocument,
71
+ data.totalClicks,
72
+ );
73
+
74
+ // Render each area
75
+ clusterAreas.forEach((area) => {
76
+ this.createOverlay(area);
77
+ this.areas.set(area.id, area);
78
+ });
79
+
80
+ console.log(`[AreaOverlayManager] Rendered ${clusterAreas.length} cluster areas`);
81
+ }
82
+
83
+ /**
84
+ * Create overlay for a cluster area
85
+ */
86
+ private createOverlay(area: IClusterArea): void {
87
+ if (!this.overlayContainer) return;
88
+
89
+ const overlay = document.createElement('div');
90
+ const rect = area.boundingRect;
91
+
92
+ Object.assign(overlay.style, {
93
+ position: 'absolute',
94
+ top: `${rect.top}px`,
95
+ left: `${rect.left}px`,
96
+ width: `${rect.width}px`,
97
+ height: `${rect.height}px`,
98
+ backgroundColor: area.color,
99
+ boxShadow: '0 0 0 2px white inset',
100
+ display: 'flex',
101
+ alignItems: 'center',
102
+ justifyContent: 'center',
103
+ pointerEvents: 'auto',
104
+ cursor: 'pointer',
105
+ transition: 'background-color 0.2s ease, box-shadow 0.2s ease',
106
+ zIndex: '9999',
107
+ boxSizing: 'border-box',
108
+ borderRadius: '4px',
109
+ });
110
+
111
+ overlay.setAttribute('data-area-id', area.id);
112
+ overlay.setAttribute('data-area-clicks', area.totalClicks.toString());
113
+
114
+ // Add label
115
+ if (rect.width >= MIN_LABEL_WIDTH && rect.height >= MIN_LABEL_HEIGHT) {
116
+ const label = this.createLabel(area);
117
+ overlay.appendChild(label);
118
+ }
119
+
120
+ // Event handlers
121
+ overlay.addEventListener('mouseenter', () => {
122
+ overlay.style.backgroundColor = area.hoverColor;
123
+ overlay.style.boxShadow = '0 0 0 1px #0078D4, 0 0 0 1px #0078D4 inset, 0 0 0 2px white inset';
124
+ });
125
+
126
+ overlay.addEventListener('mouseleave', () => {
127
+ overlay.style.backgroundColor = area.color;
128
+ overlay.style.boxShadow = '0 0 0 2px white inset';
129
+ });
130
+
131
+ overlay.addEventListener('click', () => {
132
+ this.handleAreaClick(area);
133
+ });
134
+
135
+ this.overlayContainer.appendChild(overlay);
136
+ this.overlayElements.set(area.id, overlay);
137
+ }
138
+
139
+ /**
140
+ * Create label
141
+ */
142
+ private createLabel(area: IClusterArea): HTMLDivElement {
143
+ const label = document.createElement('div');
144
+
145
+ // Hiển thị % clicks
146
+ label.textContent = `${area.clickPercentage.toFixed(2)}%`;
147
+
148
+ Object.assign(label.style, {
149
+ color: '#161514',
150
+ backgroundColor: 'rgba(255, 255, 255, 0.9)',
151
+ padding: '8px 12px',
152
+ borderRadius: '4px',
153
+ fontSize: '14px',
154
+ lineHeight: '20px',
155
+ fontWeight: '600',
156
+ fontFamily: '"Segoe UI", system-ui, -apple-system, sans-serif',
157
+ pointerEvents: 'none',
158
+ userSelect: 'none',
159
+ boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
160
+ });
161
+
162
+ return label;
163
+ }
164
+
165
+ /**
166
+ * Handle area click
167
+ */
168
+ private handleAreaClick(area: IClusterArea): void {
169
+ console.log('[AreaOverlayManager] Area clicked:', {
170
+ id: area.id,
171
+ clicks: area.totalClicks,
172
+ percentage: area.clickPercentage,
173
+ elements: area.elements.length,
174
+ });
175
+
176
+ // Dispatch event
177
+ window.dispatchEvent(
178
+ new CustomEvent('area-clicked', {
179
+ detail: area,
180
+ }),
181
+ );
182
+
183
+ // Scroll to centroid
184
+ if (area.elements[0]) {
185
+ area.elements[0].scrollIntoView({
186
+ behavior: 'smooth',
187
+ block: 'center',
188
+ });
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Update positions when iframe resizes
194
+ */
195
+ public updatePositions(): void {
196
+ if (!this.iframe.contentDocument) return;
197
+
198
+ this.areas.forEach((area) => {
199
+ const overlay = this.overlayElements.get(area.id);
200
+ if (!overlay) return;
201
+
202
+ // Recalculate bounding rect
203
+ const rects = area.elements.map((el) => {
204
+ const domRect = el.getBoundingClientRect();
205
+ return {
206
+ top: domRect.top,
207
+ left: domRect.left,
208
+ width: domRect.width,
209
+ height: domRect.height,
210
+ right: domRect.right,
211
+ bottom: domRect.bottom,
212
+ };
213
+ });
214
+
215
+ const newBoundingRect = this.calculateBoundingRect(rects);
216
+
217
+ Object.assign(overlay.style, {
218
+ top: `${newBoundingRect.top}px`,
219
+ left: `${newBoundingRect.left}px`,
220
+ width: `${newBoundingRect.width}px`,
221
+ height: `${newBoundingRect.height}px`,
222
+ });
223
+ });
224
+ }
225
+
226
+ private calculateBoundingRect(rects: any[]): any {
227
+ const padding = 0;
228
+ const minLeft = Math.min(...rects.map((r) => r.left)) - padding;
229
+ const minTop = Math.min(...rects.map((r) => r.top)) - padding;
230
+ const maxRight = Math.max(...rects.map((r) => r.right)) + padding;
231
+ const maxBottom = Math.max(...rects.map((r) => r.bottom)) + padding;
232
+
233
+ return {
234
+ left: minLeft,
235
+ top: minTop,
236
+ width: maxRight - minLeft,
237
+ height: maxBottom - minTop,
238
+ right: maxRight,
239
+ bottom: maxBottom,
240
+ };
241
+ }
242
+
243
+ /**
244
+ * Clear all overlays
245
+ */
246
+ public clear(): void {
247
+ if (this.overlayContainer) {
248
+ this.overlayContainer.innerHTML = '';
249
+ }
250
+ this.areas.clear();
251
+ this.overlayElements.clear();
252
+ }
253
+
254
+ /**
255
+ * Destroy
256
+ */
257
+ public destroy(): void {
258
+ this.clear();
259
+
260
+ if (this.overlayContainer?.parentElement) {
261
+ this.overlayContainer.parentElement.removeChild(this.overlayContainer);
262
+ }
263
+
264
+ this.overlayContainer = null;
265
+ }
266
+
267
+ /**
268
+ * Get all areas
269
+ */
270
+ public getAreas(): IClusterArea[] {
271
+ return Array.from(this.areas.values());
272
+ }
273
+ }