@gemx-dev/heatmap-react 3.5.44 → 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.
- package/dist/esm/components/Layout/ContentHeader.d.ts +4 -0
- package/dist/esm/components/Layout/ContentHeader.d.ts.map +1 -0
- package/dist/esm/components/Layout/VizMode.d.ts +2 -0
- package/dist/esm/components/Layout/VizMode.d.ts.map +1 -0
- package/dist/esm/components/Test.d.ts +121 -0
- package/dist/esm/components/Test.d.ts.map +1 -0
- package/dist/esm/components/VizDom/VizDomContainer.d.ts +6 -0
- package/dist/esm/components/VizDom/VizDomContainer.d.ts.map +1 -0
- package/dist/esm/components/VizDom/VizDomRenderer.d.ts.map +1 -1
- package/dist/esm/components/VizElement/ClickedElementOverlay.d.ts +17 -0
- package/dist/esm/components/VizElement/ClickedElementOverlay.d.ts.map +1 -0
- package/dist/esm/components/VizElement/HeatmapElements.d.ts.map +1 -1
- package/dist/esm/components/VizElement/HoveredElementOverlay.d.ts +12 -0
- package/dist/esm/components/VizElement/HoveredElementOverlay.d.ts.map +1 -0
- package/dist/esm/components/VizElement/MissingElementMessage.d.ts +7 -0
- package/dist/esm/components/VizElement/MissingElementMessage.d.ts.map +1 -0
- package/dist/esm/components/VizElement/VizElements.d.ts.map +1 -1
- package/dist/esm/components/VizElement/temp/ClarityVisualizer.d.ts +150 -0
- package/dist/esm/components/VizElement/temp/ClarityVisualizer.d.ts.map +1 -0
- package/dist/esm/components/VizElement/temp/VizElementRank.d.ts +74 -0
- package/dist/esm/components/VizElement/temp/VizElementRank.d.ts.map +1 -0
- package/dist/esm/components/VizLive/VizLive.d.ts +2 -0
- package/dist/esm/components/VizLive/VizLive.d.ts.map +1 -0
- package/dist/esm/components/VizLive/VizLiveHeatmap.d.ts.map +1 -1
- package/dist/esm/components/VizLive/VizLiveRenderer.d.ts.map +1 -1
- package/dist/esm/configs/style.d.ts +0 -2
- package/dist/esm/configs/style.d.ts.map +1 -1
- package/dist/esm/helpers/index.d.ts +2 -1
- package/dist/esm/helpers/index.d.ts.map +1 -1
- package/dist/esm/helpers/viewport-fixer.d.ts +13 -0
- package/dist/esm/helpers/viewport-fixer.d.ts.map +1 -0
- package/dist/esm/helpers/viewport-replacer.d.ts +26 -0
- package/dist/esm/helpers/viewport-replacer.d.ts.map +1 -0
- package/dist/esm/hooks/vix-elements/useHoveredElement.d.ts.map +1 -1
- package/dist/esm/hooks/viz-canvas/useClickmap.d.ts +1 -3
- package/dist/esm/hooks/viz-canvas/useClickmap.d.ts.map +1 -1
- package/dist/esm/hooks/viz-canvas/useHeatmapVizCanvas.d.ts +1 -1
- package/dist/esm/hooks/viz-canvas/useHeatmapVizCanvas.d.ts.map +1 -1
- package/dist/esm/hooks/viz-canvas/useScrollmap.d.ts +1 -3
- package/dist/esm/hooks/viz-canvas/useScrollmap.d.ts.map +1 -1
- package/dist/esm/hooks/viz-live/index.d.ts +1 -1
- package/dist/esm/hooks/viz-live/{useVizLiveIframeMsg.d.ts → useIframeMessage.d.ts} +10 -2
- package/dist/esm/hooks/viz-live/useIframeMessage.d.ts.map +1 -0
- package/dist/esm/hooks/viz-render/useHeatmapRender.d.ts.map +1 -1
- package/dist/esm/hooks/viz-scale/useContainerDimensions.d.ts.map +1 -1
- package/dist/esm/hooks/viz-scale/useHeatmapScale.d.ts +1 -1
- package/dist/esm/hooks/viz-scale/useHeatmapScale.d.ts.map +1 -1
- package/dist/esm/hooks/viz-scale/useIframeHeight.d.ts +10 -0
- package/dist/esm/hooks/viz-scale/useIframeHeight.d.ts.map +1 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +203 -910
- package/dist/esm/index.mjs +203 -910
- package/dist/esm/stores/index.d.ts +0 -1
- package/dist/esm/stores/index.d.ts.map +1 -1
- package/dist/esm/stores/interaction.d.ts.map +1 -1
- package/dist/esm/stores/mode-live.d.ts +0 -4
- package/dist/esm/stores/mode-live.d.ts.map +1 -1
- package/dist/esm/stores/viz.d.ts +4 -0
- package/dist/esm/stores/viz.d.ts.map +1 -1
- package/dist/esm/types/index.d.ts +1 -1
- package/dist/esm/types/index.d.ts.map +1 -1
- package/dist/esm/types/viewport-fixer.d.ts +31 -0
- package/dist/esm/types/viewport-fixer.d.ts.map +1 -0
- package/dist/umd/components/Layout/ContentHeader.d.ts +4 -0
- package/dist/umd/components/Layout/ContentHeader.d.ts.map +1 -0
- package/dist/umd/components/Test.d.ts +121 -0
- package/dist/umd/components/Test.d.ts.map +1 -0
- package/dist/umd/components/VizDom/VizDomContainer.d.ts +2 -0
- package/dist/umd/components/VizDom/VizDomContainer.d.ts.map +1 -0
- package/dist/umd/components/VizDom/VizDomRenderer.d.ts.map +1 -1
- package/dist/umd/components/VizElement/ClickedElementOverlay.d.ts +17 -0
- package/dist/umd/components/VizElement/ClickedElementOverlay.d.ts.map +1 -0
- package/dist/umd/components/VizElement/HeatmapElements.d.ts.map +1 -1
- package/dist/umd/components/VizElement/HoveredElementOverlay.d.ts +12 -0
- package/dist/umd/components/VizElement/HoveredElementOverlay.d.ts.map +1 -0
- package/dist/umd/components/VizElement/MissingElementMessage.d.ts +7 -0
- package/dist/umd/components/VizElement/MissingElementMessage.d.ts.map +1 -0
- package/dist/umd/components/VizElement/VizElements.d.ts.map +1 -1
- package/dist/umd/components/VizElement/temp/ClarityVisualizer.d.ts +150 -0
- package/dist/umd/components/VizElement/temp/ClarityVisualizer.d.ts.map +1 -0
- package/dist/umd/components/VizElement/temp/VizElementRank.d.ts +74 -0
- package/dist/umd/components/VizElement/temp/VizElementRank.d.ts.map +1 -0
- package/dist/umd/components/VizLive/VizLiveHeatmap.d.ts.map +1 -1
- package/dist/umd/components/VizLive/VizLiveRenderer.d.ts.map +1 -1
- package/dist/umd/configs/style.d.ts +0 -2
- package/dist/umd/configs/style.d.ts.map +1 -1
- package/dist/umd/helpers/index.d.ts +2 -1
- package/dist/umd/helpers/index.d.ts.map +1 -1
- package/dist/umd/helpers/viewport-fixer.d.ts +13 -0
- package/dist/umd/helpers/viewport-fixer.d.ts.map +1 -0
- package/dist/umd/helpers/viewport-replacer.d.ts +26 -0
- package/dist/umd/helpers/viewport-replacer.d.ts.map +1 -0
- package/dist/umd/hooks/vix-elements/useHoveredElement.d.ts.map +1 -1
- package/dist/umd/hooks/viz-canvas/useClickmap.d.ts +1 -3
- package/dist/umd/hooks/viz-canvas/useClickmap.d.ts.map +1 -1
- package/dist/umd/hooks/viz-canvas/useHeatmapVizCanvas.d.ts +1 -1
- package/dist/umd/hooks/viz-canvas/useHeatmapVizCanvas.d.ts.map +1 -1
- package/dist/umd/hooks/viz-canvas/useScrollmap.d.ts +1 -3
- package/dist/umd/hooks/viz-canvas/useScrollmap.d.ts.map +1 -1
- package/dist/umd/hooks/viz-live/index.d.ts +1 -1
- package/dist/umd/hooks/viz-live/{useVizLiveIframeMsg.d.ts → useIframeMessage.d.ts} +10 -2
- package/dist/umd/hooks/viz-live/useIframeMessage.d.ts.map +1 -0
- package/dist/umd/hooks/viz-render/useHeatmapRender.d.ts.map +1 -1
- package/dist/umd/hooks/viz-scale/useContainerDimensions.d.ts.map +1 -1
- package/dist/umd/hooks/viz-scale/useHeatmapScale.d.ts +1 -1
- package/dist/umd/hooks/viz-scale/useHeatmapScale.d.ts.map +1 -1
- package/dist/umd/hooks/viz-scale/useIframeHeight.d.ts +10 -0
- package/dist/umd/hooks/viz-scale/useIframeHeight.d.ts.map +1 -0
- package/dist/umd/index.d.ts +1 -1
- package/dist/umd/index.d.ts.map +1 -1
- package/dist/umd/index.js +2 -2
- package/dist/umd/stores/index.d.ts +0 -1
- package/dist/umd/stores/index.d.ts.map +1 -1
- package/dist/umd/stores/interaction.d.ts.map +1 -1
- package/dist/umd/stores/mode-live.d.ts +0 -4
- package/dist/umd/stores/mode-live.d.ts.map +1 -1
- package/dist/umd/stores/viz.d.ts +4 -0
- package/dist/umd/stores/viz.d.ts.map +1 -1
- package/dist/umd/types/index.d.ts +1 -1
- package/dist/umd/types/index.d.ts.map +1 -1
- package/dist/umd/types/viewport-fixer.d.ts +31 -0
- package/dist/umd/types/viewport-fixer.d.ts.map +1 -0
- package/package.json +13 -15
- package/src/components/GraphView.tsx +58 -0
- package/src/components/Layout/ContentMetricBar.tsx +23 -0
- package/src/components/Layout/ContentToolbar.tsx +22 -0
- package/src/components/Layout/ContentTopBar.tsx +24 -0
- package/src/components/Layout/ContentVizByMode.tsx +14 -0
- package/src/components/Layout/HeatmapLayout.tsx +60 -0
- package/src/components/Layout/LeftSidebar.tsx +44 -0
- package/src/components/Layout/WrapperLayout.tsx +12 -0
- package/src/components/Layout/WrapperPreview.tsx +24 -0
- package/src/components/Layout/index.ts +1 -0
- package/src/components/VizDom/ReplayControls.tsx +48 -0
- package/src/components/VizDom/VizContainer.tsx +40 -0
- package/src/components/VizDom/VizDomHeatmap.tsx +28 -0
- package/src/components/VizDom/VizDomRenderer.tsx +82 -0
- package/src/components/VizDom/VizLoading.tsx +8 -0
- package/src/components/VizDom/WrapperVisual.tsx +73 -0
- package/src/components/VizDom/index.ts +5 -0
- package/src/components/VizElement/DefaultRankBadges.tsx +36 -0
- package/src/components/VizElement/ElementCallout.tsx +82 -0
- package/src/components/VizElement/ElementMissing.tsx +35 -0
- package/src/components/VizElement/ElementOverlay.tsx +66 -0
- package/src/components/VizElement/HeatmapElements.tsx +127 -0
- package/src/components/VizElement/HeatmapExample.tsx +70 -0
- package/src/components/VizElement/RankBadge.tsx +25 -0
- package/src/components/VizElement/VizElements.tsx +57 -0
- package/src/components/VizElement/index.ts +1 -0
- package/src/components/VizLive/VizLiveHeatmap.tsx +27 -0
- package/src/components/VizLive/VizLiveRenderer.tsx +47 -0
- package/src/components/VizLive/index.ts +1 -0
- package/src/components/VizScrollmap/AverageFoldLine.tsx +57 -0
- package/src/components/VizScrollmap/HoverZones.tsx +58 -0
- package/src/components/VizScrollmap/MetricRow.tsx +0 -0
- package/src/components/VizScrollmap/ScrollMapMinimap.tsx +64 -0
- package/src/components/VizScrollmap/ScrollMapOverlay.tsx +79 -0
- package/src/components/VizScrollmap/ScrollZoneHoverArea.tsx +35 -0
- package/src/components/VizScrollmap/ScrollZoneTooltip.tsx +146 -0
- package/src/components/VizScrollmap/ScrollmapMarker.tsx +106 -0
- package/src/components/VizScrollmap/VizScrollMap.tsx +36 -0
- package/src/components/VizScrollmap/index.ts +1 -0
- package/src/components/VizScrollmapV2/ScrollmapOverlay.css +94 -0
- package/src/components/VizScrollmapV2/ScrollmapOverlayV2.tsx +130 -0
- package/src/components/VizScrollmapV2/index.ts +1 -0
- package/src/components/VizScrollmapV2/scrollmap.types.ts +21 -0
- package/src/components/VizScrollmapV2/useScrollmapOverlay.ts +187 -0
- package/src/components/index.tsx +2 -0
- package/src/configs/iframe.ts +15 -0
- package/src/configs/index.ts +2 -0
- package/src/configs/style.ts +21 -0
- package/src/constants/index.ts +4 -0
- package/src/global.d.ts +5 -0
- package/src/helpers/elm-callout.ts +347 -0
- package/src/helpers/elm-getter.ts +70 -0
- package/src/helpers/iframe-helper/fixer.ts +100 -0
- package/src/helpers/iframe-helper/index.ts +1 -0
- package/src/helpers/iframe-helper/init.ts +56 -0
- package/src/helpers/iframe-helper/navigation-blocker-v2.ts +371 -0
- package/src/helpers/iframe-helper/navigation-blocker.ts +367 -0
- package/src/helpers/iframe-helper/style-replacer.ts +231 -0
- package/src/helpers/iframe.ts +42 -0
- package/src/helpers/index.ts +8 -0
- package/src/helpers/viz-canvas/area-clustering.ts +234 -0
- package/src/helpers/viz-canvas/area-overlay-manager-v2.ts +176 -0
- package/src/helpers/viz-canvas/area-overlay-manager.ts +273 -0
- package/src/helpers/viz-canvas/hierarchical-area-clustering.ts +420 -0
- package/src/helpers/viz-canvas/index.ts +2 -0
- package/src/helpers/viz-elements.ts +43 -0
- package/src/hooks/index.ts +8 -0
- package/src/hooks/register/index.ts +4 -0
- package/src/hooks/register/useRegisterConfig.ts +17 -0
- package/src/hooks/register/useRegisterControl.ts +13 -0
- package/src/hooks/register/useRegisterData.ts +36 -0
- package/src/hooks/register/useRegisterHeatmap.ts +38 -0
- package/src/hooks/viz-area/useAreaHeatmap.ts +336 -0
- package/src/hooks/viz-area/useAreaHeatmapManager.ts +692 -0
- package/src/hooks/viz-canvas/index.ts +1 -0
- package/src/hooks/viz-canvas/useAreamap.ts +162 -0
- package/src/hooks/viz-canvas/useClickmap.ts +24 -0
- package/src/hooks/viz-canvas/useHeatmapCanvas.ts +27 -0
- package/src/hooks/viz-canvas/useScrollmap.ts +22 -0
- package/src/hooks/viz-elements/index.ts +5 -0
- package/src/hooks/viz-elements/useClickedElement.ts +86 -0
- package/src/hooks/viz-elements/useElementCalloutVisible.ts +45 -0
- package/src/hooks/viz-elements/useHeatmapEffects.ts +30 -0
- package/src/hooks/viz-elements/useHeatmapElementPosition.ts +60 -0
- package/src/hooks/viz-elements/useHeatmapMouseHandler.ts +255 -0
- package/src/hooks/viz-elements/useHoveredElement.ts +170 -0
- package/src/hooks/viz-live/index.ts +1 -0
- package/src/hooks/viz-live/useVizLiveIframeMsg.ts +88 -0
- package/src/hooks/viz-live/useVizLiveRender.ts +67 -0
- package/src/hooks/viz-render/index.ts +1 -0
- package/src/hooks/viz-render/useHeatmapRender.ts +71 -0
- package/src/hooks/viz-render/useHeatmapVizRender.ts +20 -0
- package/src/hooks/viz-render/useReplayRender.ts +160 -0
- package/src/hooks/viz-scale/index.ts +2 -0
- package/src/hooks/viz-scale/useContainerDimensions.ts +48 -0
- package/src/hooks/viz-scale/useContentDimensions.ts +25 -0
- package/src/hooks/viz-scale/useHeatmapScale.ts +52 -0
- package/src/hooks/viz-scale/useObserveIframeHeight.ts +162 -0
- package/src/hooks/viz-scale/useScaleCalculation.ts +31 -0
- package/src/hooks/viz-scale/useScrollSync.ts +36 -0
- package/src/hooks/viz-scale/useWrapperRefHeight.ts +91 -0
- package/src/hooks/viz-scrollmap/index.ts +2 -0
- package/src/hooks/viz-scrollmap/useScrollmapZones.ts +165 -0
- package/src/hooks/viz-scrollmap/useZonePositions.ts +38 -0
- package/src/index.ts +10 -0
- package/src/stores/comp.ts +31 -0
- package/src/stores/config.ts +37 -0
- package/src/stores/data.ts +30 -0
- package/src/stores/index.ts +10 -0
- package/src/stores/interaction.ts +32 -0
- package/src/stores/mode-live.ts +38 -0
- package/src/stores/mode-single.ts +18 -0
- package/src/stores/viz-scrollmap.ts +22 -0
- package/src/stores/viz.ts +17 -0
- package/src/styles/base.css +1 -0
- package/src/styles/style.css +137 -0
- package/src/types/clarity.ts +45 -0
- package/src/types/control.ts +10 -0
- package/src/types/elm-callout.ts +9 -0
- package/src/types/heatmap-info.ts +11 -0
- package/src/types/heatmap.ts +25 -0
- package/src/types/iframe-helper.ts +18 -0
- package/src/types/index.ts +12 -0
- package/src/types/viz-canvas.ts +20 -0
- package/src/types/viz-element.ts +34 -0
- package/src/types/viz-scrollmap.ts +28 -0
- package/src/ui/BoxStack/BoxStack.tsx +136 -0
- package/src/ui/BoxStack/index.ts +1 -0
- package/src/ui/index.ts +1 -0
- package/src/utils/debounce.ts +10 -0
- package/src/utils/device.ts +7 -0
- package/src/utils/retry.ts +20 -0
- package/src/utils/sort.ts +5 -0
- package/dist/esm/helpers/iframe-helper/fixer.d.ts +0 -18
- package/dist/esm/helpers/iframe-helper/fixer.d.ts.map +0 -1
- package/dist/esm/helpers/iframe-helper/index.d.ts +0 -2
- package/dist/esm/helpers/iframe-helper/index.d.ts.map +0 -1
- package/dist/esm/helpers/iframe-helper/init.d.ts +0 -5
- package/dist/esm/helpers/iframe-helper/init.d.ts.map +0 -1
- package/dist/esm/helpers/iframe-helper/navigation-blocker-v2.d.ts +0 -28
- package/dist/esm/helpers/iframe-helper/navigation-blocker-v2.d.ts.map +0 -1
- package/dist/esm/helpers/iframe-helper/navigation-blocker.d.ts +0 -20
- package/dist/esm/helpers/iframe-helper/navigation-blocker.d.ts.map +0 -1
- package/dist/esm/helpers/iframe-helper/style-replacer.d.ts +0 -25
- package/dist/esm/helpers/iframe-helper/style-replacer.d.ts.map +0 -1
- package/dist/esm/hooks/vix-elements/useHeatmapMouseHandler.d.ts +0 -34
- package/dist/esm/hooks/vix-elements/useHeatmapMouseHandler.d.ts.map +0 -1
- package/dist/esm/hooks/viz-live/useVizLiveIframeMsg.d.ts.map +0 -1
- package/dist/esm/hooks/viz-live/useVizLiveRender.d.ts +0 -4
- package/dist/esm/hooks/viz-live/useVizLiveRender.d.ts.map +0 -1
- package/dist/esm/hooks/viz-scale/useObserveIframeHeight.d.ts +0 -10
- package/dist/esm/hooks/viz-scale/useObserveIframeHeight.d.ts.map +0 -1
- package/dist/esm/stores/mode-single.d.ts +0 -9
- package/dist/esm/stores/mode-single.d.ts.map +0 -1
- package/dist/esm/types/iframe-helper.d.ts +0 -20
- package/dist/esm/types/iframe-helper.d.ts.map +0 -1
- package/dist/umd/helpers/iframe-helper/fixer.d.ts +0 -18
- package/dist/umd/helpers/iframe-helper/fixer.d.ts.map +0 -1
- package/dist/umd/helpers/iframe-helper/index.d.ts +0 -2
- package/dist/umd/helpers/iframe-helper/index.d.ts.map +0 -1
- package/dist/umd/helpers/iframe-helper/init.d.ts +0 -5
- package/dist/umd/helpers/iframe-helper/init.d.ts.map +0 -1
- package/dist/umd/helpers/iframe-helper/navigation-blocker-v2.d.ts +0 -28
- package/dist/umd/helpers/iframe-helper/navigation-blocker-v2.d.ts.map +0 -1
- package/dist/umd/helpers/iframe-helper/navigation-blocker.d.ts +0 -20
- package/dist/umd/helpers/iframe-helper/navigation-blocker.d.ts.map +0 -1
- package/dist/umd/helpers/iframe-helper/style-replacer.d.ts +0 -25
- package/dist/umd/helpers/iframe-helper/style-replacer.d.ts.map +0 -1
- package/dist/umd/hooks/vix-elements/useHeatmapMouseHandler.d.ts +0 -34
- package/dist/umd/hooks/vix-elements/useHeatmapMouseHandler.d.ts.map +0 -1
- package/dist/umd/hooks/viz-live/useVizLiveIframeMsg.d.ts.map +0 -1
- package/dist/umd/hooks/viz-live/useVizLiveRender.d.ts +0 -4
- package/dist/umd/hooks/viz-live/useVizLiveRender.d.ts.map +0 -1
- package/dist/umd/hooks/viz-scale/useObserveIframeHeight.d.ts +0 -10
- package/dist/umd/hooks/viz-scale/useObserveIframeHeight.d.ts.map +0 -1
- package/dist/umd/stores/mode-single.d.ts +0 -9
- package/dist/umd/stores/mode-single.d.ts.map +0 -1
- package/dist/umd/types/iframe-helper.d.ts +0 -20
- package/dist/umd/types/iframe-helper.d.ts.map +0 -1
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// ScrollmapOverlay.tsx
|
|
2
|
+
import React, { useCallback, useState } from 'react';
|
|
3
|
+
import { useHeatmapVizStore } from '../../stores';
|
|
4
|
+
import { ScrollMapMarker, ScrollmapOverlayProps } from './scrollmap.types';
|
|
5
|
+
import './ScrollmapOverlay.css';
|
|
6
|
+
import { useScrollmapOverlayV2 } from './useScrollmapOverlay';
|
|
7
|
+
|
|
8
|
+
export const ScrollmapOverlayV2: React.FC<ScrollmapOverlayProps> = ({
|
|
9
|
+
iframeRef,
|
|
10
|
+
wrapperRef,
|
|
11
|
+
enabled = true,
|
|
12
|
+
}) => {
|
|
13
|
+
const [isHovering, setIsHovering] = useState(false);
|
|
14
|
+
const [mouseY, setMouseY] = useState(0);
|
|
15
|
+
|
|
16
|
+
const { isReady, markers, hoveredPercentage, setHoveredMouseY } = useScrollmapOverlayV2({
|
|
17
|
+
enabled,
|
|
18
|
+
iframeRef,
|
|
19
|
+
wrapperRef,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Handle mouse move - track position for hover tooltip
|
|
24
|
+
*/
|
|
25
|
+
const handleMouseMove = useCallback(
|
|
26
|
+
(event: React.MouseEvent<HTMLDivElement>) => {
|
|
27
|
+
const wrapper = wrapperRef.current;
|
|
28
|
+
if (!wrapper) return;
|
|
29
|
+
|
|
30
|
+
const rect = wrapper.getBoundingClientRect();
|
|
31
|
+
const relativeY = event.clientY - rect.top;
|
|
32
|
+
|
|
33
|
+
setIsHovering(true);
|
|
34
|
+
setMouseY(relativeY);
|
|
35
|
+
setHoveredMouseY(relativeY);
|
|
36
|
+
},
|
|
37
|
+
[wrapperRef, setHoveredMouseY],
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Handle mouse leave - hide tooltip
|
|
42
|
+
*/
|
|
43
|
+
const handleMouseLeave = useCallback(() => {
|
|
44
|
+
setIsHovering(false);
|
|
45
|
+
setMouseY(0);
|
|
46
|
+
setHoveredMouseY(null);
|
|
47
|
+
}, [setHoveredMouseY]);
|
|
48
|
+
|
|
49
|
+
if (!enabled || !isReady) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<div
|
|
55
|
+
className="scrollmap-overlay"
|
|
56
|
+
onMouseMove={handleMouseMove}
|
|
57
|
+
onMouseLeave={handleMouseLeave}
|
|
58
|
+
>
|
|
59
|
+
{/* Render markers */}
|
|
60
|
+
{markers.map((marker) => (
|
|
61
|
+
<ScrollmapMarker key={marker.id} marker={marker} />
|
|
62
|
+
))}
|
|
63
|
+
|
|
64
|
+
{/* Hover tooltip */}
|
|
65
|
+
{isHovering && hoveredPercentage !== null && (
|
|
66
|
+
<ScrollmapHoverTooltip mouseY={mouseY} percentage={hoveredPercentage} />
|
|
67
|
+
)}
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Individual marker component
|
|
74
|
+
*/
|
|
75
|
+
interface ScrollmapMarkerProps {
|
|
76
|
+
marker: ScrollMapMarker;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const ScrollmapMarker: React.FC<ScrollmapMarkerProps> = ({ marker }) => {
|
|
80
|
+
const widthScale = useHeatmapVizStore((state) => state.scale);
|
|
81
|
+
|
|
82
|
+
const markerStyle: React.CSSProperties = {
|
|
83
|
+
transform: `scale(${1 / widthScale})`,
|
|
84
|
+
transformOrigin: 'left',
|
|
85
|
+
top: marker.yPosition - 24, // Offset for label height
|
|
86
|
+
left: 0,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const markerClassName = `scrollmap-marker ${
|
|
90
|
+
marker.type === 'avgFold' ? 'scrollmap-marker--avgfold' : 'scrollmap-marker--percentage'
|
|
91
|
+
}`;
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<div className="scrollmap-marker-wrapper" style={markerStyle}>
|
|
95
|
+
<div className="scrollmap-marker-line" />
|
|
96
|
+
<div className={markerClassName}>
|
|
97
|
+
<span className="scrollmap-marker-label">{marker.label}</span>
|
|
98
|
+
</div>
|
|
99
|
+
<div className="scrollmap-marker-line" />
|
|
100
|
+
</div>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Hover tooltip component
|
|
106
|
+
*/
|
|
107
|
+
interface ScrollmapHoverTooltipProps {
|
|
108
|
+
mouseY: number;
|
|
109
|
+
percentage: number;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const ScrollmapHoverTooltip: React.FC<ScrollmapHoverTooltipProps> = ({ mouseY, percentage }) => {
|
|
113
|
+
const widthScale = useHeatmapVizStore((state) => state.scale);
|
|
114
|
+
|
|
115
|
+
const tooltipStyle: React.CSSProperties = {
|
|
116
|
+
transform: `scale(${1 / widthScale})`,
|
|
117
|
+
transformOrigin: 'left',
|
|
118
|
+
top: mouseY / widthScale - 24,
|
|
119
|
+
left: 0,
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<div className="scrollmap-hover-tooltip" style={tooltipStyle}>
|
|
124
|
+
<div className="scrollmap-hover-tooltip-content">
|
|
125
|
+
<span className="scrollmap-hover-tooltip-percentage">{percentage}%</span>
|
|
126
|
+
<span className="scrollmap-hover-tooltip-label">of users</span>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
);
|
|
130
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ScrollmapOverlayV2';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// scrollmap.types.ts
|
|
2
|
+
|
|
3
|
+
export interface ScrollMapDataPoint {
|
|
4
|
+
scrollReachY: number; // 0-100 (vị trí % trên trang)
|
|
5
|
+
cumulativeSum: number; // Tổng số users đến điểm này
|
|
6
|
+
percUsers: number; // % users đạt được (100 -> 0, giảm dần)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface ScrollMapMarker {
|
|
10
|
+
id: string;
|
|
11
|
+
type: 'avgFold' | 'percentage';
|
|
12
|
+
yPosition: number; // Vị trí pixel
|
|
13
|
+
label: string;
|
|
14
|
+
percentage?: number; // Chỉ có với type 'percentage'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ScrollmapOverlayProps {
|
|
18
|
+
iframeRef: React.RefObject<HTMLIFrameElement>;
|
|
19
|
+
wrapperRef: React.RefObject<HTMLElement>;
|
|
20
|
+
enabled?: boolean;
|
|
21
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
// useScrollmapOverlay.ts
|
|
2
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { useHeatmapDataStore, useHeatmapSingleStore, useHeatmapVizStore } from '../../stores';
|
|
4
|
+
import { ScrollMapDataPoint, ScrollMapMarker } from './scrollmap.types';
|
|
5
|
+
|
|
6
|
+
interface UseScrollmapOverlayOptions {
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
iframeRef: React.RefObject<HTMLIFrameElement>;
|
|
9
|
+
wrapperRef: React.RefObject<HTMLElement>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface UseScrollmapOverlayReturn {
|
|
13
|
+
isReady: boolean;
|
|
14
|
+
markers: ScrollMapMarker[];
|
|
15
|
+
averageFold: number;
|
|
16
|
+
hoveredPercentage: number | null;
|
|
17
|
+
setHoveredMouseY: (y: number | null) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const useScrollmapOverlayV2 = (
|
|
21
|
+
options: UseScrollmapOverlayOptions,
|
|
22
|
+
): UseScrollmapOverlayReturn => {
|
|
23
|
+
const { enabled = true, iframeRef, wrapperRef } = options;
|
|
24
|
+
|
|
25
|
+
const [isReady, setIsReady] = useState(false);
|
|
26
|
+
const [hoveredMouseY, setHoveredMouseY] = useState<number | null>(null);
|
|
27
|
+
|
|
28
|
+
// Zustand stores
|
|
29
|
+
const scrollMapInfo = useHeatmapDataStore((state) => state.scrollmap);
|
|
30
|
+
const iframeHeight = useHeatmapSingleStore((state) => state.iframeHeight);
|
|
31
|
+
const widthScale = useHeatmapVizStore((state) => state.scale);
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Tính Average Fold (vị trí mà 50% users scroll đến)
|
|
35
|
+
* Returns: pixel position
|
|
36
|
+
*/
|
|
37
|
+
const averageFold = useMemo(() => {
|
|
38
|
+
if (!scrollMapInfo || scrollMapInfo.length === 0 || !iframeHeight) {
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Total users = điểm đầu tiên (100% users)
|
|
43
|
+
const totalUsers = scrollMapInfo[0]?.percUsers || 100;
|
|
44
|
+
const halfUsers = totalUsers / 2;
|
|
45
|
+
|
|
46
|
+
// Tìm điểm đầu tiên có percUsers <= 50%
|
|
47
|
+
for (const point of scrollMapInfo) {
|
|
48
|
+
if (point.percUsers <= halfUsers) {
|
|
49
|
+
// Convert % sang pixel
|
|
50
|
+
return (point.scrollReachY / 100) * iframeHeight;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Fallback: 50% chiều cao
|
|
55
|
+
return iframeHeight / 2;
|
|
56
|
+
}, [scrollMapInfo, iframeHeight]);
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Tính Percentage Markers (75%, 50%, 25%)
|
|
60
|
+
* Tìm điểm gần nhất với mỗi target, trong khoảng ±5%
|
|
61
|
+
*/
|
|
62
|
+
const percentageMarkers = useMemo(() => {
|
|
63
|
+
if (!scrollMapInfo || scrollMapInfo.length === 0 || !iframeHeight) {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const markers: ScrollMapMarker[] = [];
|
|
68
|
+
const targetPercentages = [75, 50, 25];
|
|
69
|
+
|
|
70
|
+
for (const targetPerc of targetPercentages) {
|
|
71
|
+
// Tìm điểm GẦN NHẤT với target percentage
|
|
72
|
+
const closestPoint = scrollMapInfo.reduce<ScrollMapDataPoint | null>((prev, curr) => {
|
|
73
|
+
if (prev === null) return curr;
|
|
74
|
+
|
|
75
|
+
const prevDiff = Math.abs(prev.percUsers - targetPerc);
|
|
76
|
+
const currDiff = Math.abs(curr.percUsers - targetPerc);
|
|
77
|
+
|
|
78
|
+
return currDiff < prevDiff ? curr : prev;
|
|
79
|
+
}, null);
|
|
80
|
+
|
|
81
|
+
// Chỉ thêm marker nếu điểm gần nhất nằm trong khoảng ±5%
|
|
82
|
+
if (
|
|
83
|
+
closestPoint &&
|
|
84
|
+
closestPoint.percUsers >= targetPerc - 5 &&
|
|
85
|
+
closestPoint.percUsers <= targetPerc + 5
|
|
86
|
+
) {
|
|
87
|
+
const yPosition = (closestPoint.scrollReachY / 100) * iframeHeight;
|
|
88
|
+
|
|
89
|
+
markers.push({
|
|
90
|
+
id: `percentage_${targetPerc}`,
|
|
91
|
+
type: 'percentage',
|
|
92
|
+
yPosition,
|
|
93
|
+
label: `${targetPerc}%`,
|
|
94
|
+
percentage: targetPerc,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return markers;
|
|
100
|
+
}, [scrollMapInfo, iframeHeight]);
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Combine tất cả markers (Average Fold + Percentage Markers)
|
|
104
|
+
*/
|
|
105
|
+
const markers = useMemo(() => {
|
|
106
|
+
const allMarkers: ScrollMapMarker[] = [];
|
|
107
|
+
|
|
108
|
+
// Average Fold marker
|
|
109
|
+
if (averageFold > 0) {
|
|
110
|
+
allMarkers.push({
|
|
111
|
+
id: 'avgFold',
|
|
112
|
+
type: 'avgFold',
|
|
113
|
+
yPosition: averageFold,
|
|
114
|
+
label: 'Average Fold',
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Percentage markers
|
|
119
|
+
allMarkers.push(...percentageMarkers);
|
|
120
|
+
|
|
121
|
+
return allMarkers;
|
|
122
|
+
}, [averageFold, percentageMarkers]);
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Tính % users tại vị trí hover
|
|
126
|
+
* Input: mouseY (pixel position from wrapper top)
|
|
127
|
+
* Output: percentage of users reached this position
|
|
128
|
+
*/
|
|
129
|
+
const hoveredPercentage = useMemo(() => {
|
|
130
|
+
if (
|
|
131
|
+
hoveredMouseY === null ||
|
|
132
|
+
!scrollMapInfo ||
|
|
133
|
+
scrollMapInfo.length === 0 ||
|
|
134
|
+
!iframeHeight ||
|
|
135
|
+
!widthScale
|
|
136
|
+
) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Tính % scroll position từ mouseY
|
|
141
|
+
const scrollPercent = (hoveredMouseY / widthScale / iframeHeight) * 100;
|
|
142
|
+
|
|
143
|
+
// Tìm điểm đầu tiên có scrollReachY >= scrollPercent
|
|
144
|
+
for (const point of scrollMapInfo) {
|
|
145
|
+
if (point.scrollReachY >= scrollPercent) {
|
|
146
|
+
// Tính % cumulative users
|
|
147
|
+
const percentage = (point.cumulativeSum / scrollMapInfo[0].cumulativeSum) * 100;
|
|
148
|
+
return Math.round(percentage * 10) / 10; // 1 decimal place
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Fallback: lấy điểm cuối cùng
|
|
153
|
+
const lastPoint = scrollMapInfo[scrollMapInfo.length - 1];
|
|
154
|
+
const percentage = (lastPoint.cumulativeSum / scrollMapInfo[0].cumulativeSum) * 100;
|
|
155
|
+
return Math.round(percentage * 10) / 10;
|
|
156
|
+
}, [hoveredMouseY, scrollMapInfo, iframeHeight, widthScale]);
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Check if data is ready
|
|
160
|
+
*/
|
|
161
|
+
useEffect(() => {
|
|
162
|
+
if (!enabled) {
|
|
163
|
+
setIsReady(false);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (scrollMapInfo && scrollMapInfo.length > 0 && iframeHeight) {
|
|
168
|
+
setIsReady(true);
|
|
169
|
+
console.log('[useScrollmapOverlay] Ready:', {
|
|
170
|
+
dataPoints: scrollMapInfo.length,
|
|
171
|
+
iframeHeight,
|
|
172
|
+
averageFold,
|
|
173
|
+
markers: markers.length,
|
|
174
|
+
});
|
|
175
|
+
} else {
|
|
176
|
+
setIsReady(false);
|
|
177
|
+
}
|
|
178
|
+
}, [enabled, scrollMapInfo, iframeHeight, averageFold, markers.length]);
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
isReady,
|
|
182
|
+
markers,
|
|
183
|
+
averageFold,
|
|
184
|
+
hoveredPercentage,
|
|
185
|
+
setHoveredMouseY,
|
|
186
|
+
};
|
|
187
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
interface IFrameAttrs {
|
|
2
|
+
id: string;
|
|
3
|
+
title: string;
|
|
4
|
+
sandbox: string;
|
|
5
|
+
scrolling: string;
|
|
6
|
+
height?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const HEATMAP_IFRAME: IFrameAttrs = {
|
|
10
|
+
id: 'clarity-iframe',
|
|
11
|
+
title: 'Clarity Session Replay',
|
|
12
|
+
sandbox: 'allow-same-origin allow-scripts',
|
|
13
|
+
scrolling: 'no',
|
|
14
|
+
height: '100%',
|
|
15
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const HEATMAP_CONFIG = {
|
|
2
|
+
padding: 8,
|
|
3
|
+
borderWidth: 1,
|
|
4
|
+
borderWidthIframe: 2,
|
|
5
|
+
borderColor: '#E3E3E3',
|
|
6
|
+
heightToolbar: 60, // height of the toolbar
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const HEATMAP_STYLE = {
|
|
10
|
+
viz: {
|
|
11
|
+
background: '#f3f3f3',
|
|
12
|
+
paddingBottom: `${HEATMAP_CONFIG.padding}px`,
|
|
13
|
+
},
|
|
14
|
+
wrapper: {
|
|
15
|
+
padding: `${HEATMAP_CONFIG.padding}px 0`,
|
|
16
|
+
paddingBlock: `${HEATMAP_CONFIG.padding}px`,
|
|
17
|
+
paddingInline: `${HEATMAP_CONFIG.padding}px`,
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const DEFAULT_SIDEBAR_WIDTH = 260;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export const CLICKED_ELEMENT_ID = 'gx-hm-clicked-element';
|
|
2
|
+
export const SECONDARY_CLICKED_ELEMENT_ID = 'gx-hm-secondary-clicked-element';
|
|
3
|
+
export const HOVERED_ELEMENT_ID = 'gx-hm-hovered-element';
|
|
4
|
+
export const SECONDARY_HOVERED_ELEMENT_ID = 'gx-hm-secondary-hovered-element';
|