@gemx-dev/heatmap-react 3.5.41 → 3.5.42
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/VizDom/VizDomRenderer.d.ts.map +1 -1
- package/dist/esm/components/VizElement/HeatmapElements.d.ts.map +1 -1
- package/dist/esm/components/VizLive/VizLiveRenderer.d.ts.map +1 -1
- package/dist/esm/configs/style.d.ts +2 -0
- package/dist/esm/configs/style.d.ts.map +1 -1
- package/dist/esm/hooks/vix-elements/useHeatmapMouseHandler.d.ts +34 -0
- package/dist/esm/hooks/vix-elements/useHeatmapMouseHandler.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 +3 -1
- 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 +3 -1
- 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/{useIframeMessage.d.ts → useVizLiveIframeMsg.d.ts} +2 -5
- package/dist/esm/hooks/viz-live/useVizLiveIframeMsg.d.ts.map +1 -0
- package/dist/esm/hooks/viz-live/useVizLiveRender.d.ts +4 -0
- package/dist/esm/hooks/viz-live/useVizLiveRender.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/useObserveIframeHeight.d.ts +10 -0
- package/dist/esm/hooks/viz-scale/useObserveIframeHeight.d.ts.map +1 -0
- package/dist/esm/index.js +451 -62
- package/dist/esm/index.mjs +451 -62
- package/dist/esm/stores/index.d.ts +1 -0
- 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-single.d.ts +9 -0
- package/dist/esm/stores/mode-single.d.ts.map +1 -0
- package/dist/esm/stores/viz.d.ts +0 -5
- package/dist/esm/stores/viz.d.ts.map +1 -1
- package/dist/umd/components/VizDom/VizDomRenderer.d.ts.map +1 -1
- package/dist/umd/components/VizElement/HeatmapElements.d.ts.map +1 -1
- package/dist/umd/components/VizLive/VizLiveRenderer.d.ts.map +1 -1
- package/dist/umd/configs/style.d.ts +2 -0
- package/dist/umd/configs/style.d.ts.map +1 -1
- package/dist/umd/hooks/vix-elements/useHeatmapMouseHandler.d.ts +34 -0
- package/dist/umd/hooks/vix-elements/useHeatmapMouseHandler.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 +3 -1
- 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 +3 -1
- 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/{useIframeMessage.d.ts → useVizLiveIframeMsg.d.ts} +2 -5
- package/dist/umd/hooks/viz-live/useVizLiveIframeMsg.d.ts.map +1 -0
- package/dist/umd/hooks/viz-live/useVizLiveRender.d.ts +4 -0
- package/dist/umd/hooks/viz-live/useVizLiveRender.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/useObserveIframeHeight.d.ts +10 -0
- package/dist/umd/hooks/viz-scale/useObserveIframeHeight.d.ts.map +1 -0
- package/dist/umd/index.js +2 -2
- package/dist/umd/stores/index.d.ts +1 -0
- 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-single.d.ts +9 -0
- package/dist/umd/stores/mode-single.d.ts.map +1 -0
- package/dist/umd/stores/viz.d.ts +0 -5
- package/dist/umd/stores/viz.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/esm/hooks/viz-live/useIframeMessage.d.ts.map +0 -1
- package/dist/esm/hooks/viz-scale/useIframeHeight.d.ts +0 -10
- package/dist/esm/hooks/viz-scale/useIframeHeight.d.ts.map +0 -1
- package/dist/umd/hooks/viz-live/useIframeMessage.d.ts.map +0 -1
- package/dist/umd/hooks/viz-scale/useIframeHeight.d.ts +0 -10
- package/dist/umd/hooks/viz-scale/useIframeHeight.d.ts.map +0 -1
package/dist/esm/index.mjs
CHANGED
|
@@ -61,6 +61,8 @@ const HEATMAP_STYLE = {
|
|
|
61
61
|
},
|
|
62
62
|
wrapper: {
|
|
63
63
|
padding: `${HEATMAP_CONFIG.padding}px 0`,
|
|
64
|
+
paddingBlock: `${HEATMAP_CONFIG.padding}px`,
|
|
65
|
+
paddingInline: `${HEATMAP_CONFIG.padding}px`,
|
|
64
66
|
},
|
|
65
67
|
};
|
|
66
68
|
const DEFAULT_SIDEBAR_WIDTH = 260;
|
|
@@ -139,11 +141,7 @@ const useHeatmapVizStore = create()((set, get) => {
|
|
|
139
141
|
isRenderViz: false,
|
|
140
142
|
setIsRenderViz: (isRenderViz) => set({ isRenderViz }),
|
|
141
143
|
scale: 1,
|
|
142
|
-
vizRef: null,
|
|
143
|
-
iframeHeight: 0,
|
|
144
144
|
setScale: (scale) => set({ scale }),
|
|
145
|
-
setVizRef: (vizRef) => set({ vizRef }),
|
|
146
|
-
setIframeHeight: (iframeHeight) => set({ iframeHeight }),
|
|
147
145
|
};
|
|
148
146
|
});
|
|
149
147
|
|
|
@@ -165,6 +163,15 @@ const useHeatmapLiveStore = create()((set, get) => {
|
|
|
165
163
|
};
|
|
166
164
|
});
|
|
167
165
|
|
|
166
|
+
const useHeatmapSingleStore = create()((set, get) => {
|
|
167
|
+
return {
|
|
168
|
+
vizRef: null,
|
|
169
|
+
iframeHeight: 0,
|
|
170
|
+
setVizRef: (vizRef) => set({ vizRef }),
|
|
171
|
+
setIframeHeight: (iframeHeight) => set({ iframeHeight }),
|
|
172
|
+
};
|
|
173
|
+
});
|
|
174
|
+
|
|
168
175
|
const useRegisterConfig = () => {
|
|
169
176
|
const mode = useHeatmapConfigStore((state) => state.mode);
|
|
170
177
|
const width = useHeatmapConfigStore((state) => state.width);
|
|
@@ -872,7 +879,7 @@ const useHeatmapEffects = ({ isVisible, isElementSidebarOpen, setShouldShowCallo
|
|
|
872
879
|
|
|
873
880
|
const useHeatmapElementPosition = ({ iframeRef, wrapperRef, visualizer }) => {
|
|
874
881
|
const widthScale = useHeatmapVizStore((state) => state.scale);
|
|
875
|
-
const iframeHeight =
|
|
882
|
+
const iframeHeight = useHeatmapSingleStore((state) => state.iframeHeight);
|
|
876
883
|
const heatmapWidth = useHeatmapConfigStore((state) => state.width);
|
|
877
884
|
return useCallback((element) => {
|
|
878
885
|
const hash = element?.hash;
|
|
@@ -920,6 +927,179 @@ const debounce = (fn, delay) => {
|
|
|
920
927
|
};
|
|
921
928
|
};
|
|
922
929
|
|
|
930
|
+
// ===================== CONSTANTS =====================
|
|
931
|
+
const HEATMAP_ELEMENT_ATTRIBUTE = 'data-clarity-hashalpha'; // Hoặc attribute bạn đang dùng
|
|
932
|
+
// ===================== UTILITY FUNCTIONS =====================
|
|
933
|
+
/**
|
|
934
|
+
* Lấy bounding box tuyệt đối của element (relative to document)
|
|
935
|
+
*/
|
|
936
|
+
function getBoundingBox(element) {
|
|
937
|
+
if (typeof element.getBoundingClientRect !== 'function') {
|
|
938
|
+
return null;
|
|
939
|
+
}
|
|
940
|
+
const rect = element.getBoundingClientRect();
|
|
941
|
+
// Lấy scroll offset (hỗ trợ cả cách cũ và mới)
|
|
942
|
+
const scrollLeft = 'pageXOffset' in window ? window.pageXOffset : document.documentElement.scrollLeft;
|
|
943
|
+
const scrollTop = 'pageYOffset' in window ? window.pageYOffset : document.documentElement.scrollTop;
|
|
944
|
+
// Kiểm tra element có kích thước hợp lệ
|
|
945
|
+
if (!rect || (rect.height === 0 && rect.width === 0)) {
|
|
946
|
+
return null;
|
|
947
|
+
}
|
|
948
|
+
// Trả về vị trí tuyệt đối
|
|
949
|
+
return {
|
|
950
|
+
left: Math.floor(rect.left + scrollLeft),
|
|
951
|
+
top: Math.floor(rect.top + scrollTop),
|
|
952
|
+
width: Math.floor(rect.width),
|
|
953
|
+
height: Math.floor(rect.height),
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* Lấy tất cả elements tại tọa độ (x, y), hỗ trợ Shadow DOM
|
|
958
|
+
*/
|
|
959
|
+
function getElementsAtPoint(documentOrShadowRoot, x, y, filterFunction, visitedShadowRoots = new Set()) {
|
|
960
|
+
// Lấy tất cả elements tại vị trí
|
|
961
|
+
const elementsAtPoint = documentOrShadowRoot.elementsFromPoint(x, y);
|
|
962
|
+
if (!filterFunction) {
|
|
963
|
+
return elementsAtPoint;
|
|
964
|
+
}
|
|
965
|
+
// Tìm element đầu tiên match với filter
|
|
966
|
+
const matchedElement = elementsAtPoint.find(filterFunction);
|
|
967
|
+
// Nếu element có Shadow DOM và chưa visit -> đệ quy vào
|
|
968
|
+
if (matchedElement?.shadowRoot && !visitedShadowRoots.has(matchedElement.shadowRoot)) {
|
|
969
|
+
visitedShadowRoots.add(matchedElement.shadowRoot);
|
|
970
|
+
return getElementsAtPoint(matchedElement.shadowRoot, x, y, filterFunction, visitedShadowRoots);
|
|
971
|
+
}
|
|
972
|
+
return elementsAtPoint;
|
|
973
|
+
}
|
|
974
|
+
// ===================== MAIN HOOK =====================
|
|
975
|
+
function useHeatmapMouseHandler(props) {
|
|
976
|
+
const { heatmapWrapperRef, iframeRef, parentRef, heatmapInfo, scaleRatio, onElementHover } = props;
|
|
977
|
+
const handleMouseMove = useCallback((event) => {
|
|
978
|
+
// Kiểm tra tất cả refs và data cần thiết
|
|
979
|
+
if (!heatmapWrapperRef?.current ||
|
|
980
|
+
!iframeRef?.current ||
|
|
981
|
+
!iframeRef.current.contentDocument ||
|
|
982
|
+
!heatmapInfo?.elementMapInfo ||
|
|
983
|
+
!parentRef?.current) {
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
986
|
+
try {
|
|
987
|
+
// Tính toán scroll position (đã scale)
|
|
988
|
+
const scrollTop = parentRef.current.scrollTop / scaleRatio;
|
|
989
|
+
console.log(`🚀 🐥 ~ useHeatmapMouseHandler ~ scrollTop:`, scrollTop);
|
|
990
|
+
// Lấy vị trí của heatmap wrapper
|
|
991
|
+
const wrapperRect = heatmapWrapperRef.current.getBoundingClientRect();
|
|
992
|
+
// Tính toán tọa độ chuột trong iframe (đã scale)
|
|
993
|
+
const mouseX = (event.clientX - wrapperRect.left) / scaleRatio;
|
|
994
|
+
const mouseY = (event.clientY - wrapperRect.top) / scaleRatio - scrollTop;
|
|
995
|
+
// Tìm elements tại vị trí chuột
|
|
996
|
+
const elementsAtPoint = getElementsAtPoint(iframeRef.current.contentDocument, Math.round(mouseX), Math.round(mouseY),
|
|
997
|
+
// Filter: chỉ lấy elements có heatmap attribute
|
|
998
|
+
(element) => element.hasAttribute(HEATMAP_ELEMENT_ATTRIBUTE));
|
|
999
|
+
if (!elementsAtPoint || elementsAtPoint.length === 0) {
|
|
1000
|
+
return;
|
|
1001
|
+
}
|
|
1002
|
+
// Duyệt qua các elements tìm được
|
|
1003
|
+
for (let i = 0; i < elementsAtPoint.length; i++) {
|
|
1004
|
+
const element = elementsAtPoint[i];
|
|
1005
|
+
// Lấy hash/id của element
|
|
1006
|
+
const elementHash = element.getAttribute(HEATMAP_ELEMENT_ATTRIBUTE);
|
|
1007
|
+
// Kiểm tra element có data trong heatmapInfo không
|
|
1008
|
+
if (elementHash && heatmapInfo.elementMapInfo[elementHash]) {
|
|
1009
|
+
const elementData = heatmapInfo.elementMapInfo[elementHash];
|
|
1010
|
+
// Lấy bounding box của element
|
|
1011
|
+
const boundingBox = getBoundingBox(element);
|
|
1012
|
+
if (boundingBox) {
|
|
1013
|
+
// Tính rank của element
|
|
1014
|
+
const rank = Array.isArray(heatmapInfo.sortedElements) && elementData
|
|
1015
|
+
? heatmapInfo.sortedElements.indexOf(elementData) + 1
|
|
1016
|
+
: NaN;
|
|
1017
|
+
// Callback với thông tin element
|
|
1018
|
+
onElementHover({
|
|
1019
|
+
...boundingBox,
|
|
1020
|
+
// Giới hạn width không vượt quá width của heatmap
|
|
1021
|
+
width: Math.min(boundingBox.width, heatmapInfo.width || 0),
|
|
1022
|
+
// Adjust top position với scroll
|
|
1023
|
+
top: boundingBox.top + scrollTop,
|
|
1024
|
+
// Metadata
|
|
1025
|
+
hash: elementHash,
|
|
1026
|
+
clicks: elementData.totalclicks,
|
|
1027
|
+
rank: rank,
|
|
1028
|
+
selector: elementData.selector || '',
|
|
1029
|
+
});
|
|
1030
|
+
// Dừng loop khi tìm thấy element hợp lệ đầu tiên
|
|
1031
|
+
break;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
catch (error) {
|
|
1037
|
+
console.warn('Error handling mouse move on heatmap:', error);
|
|
1038
|
+
}
|
|
1039
|
+
}, [heatmapWrapperRef, iframeRef, parentRef, heatmapInfo, scaleRatio, onElementHover]);
|
|
1040
|
+
return { handleMouseMove };
|
|
1041
|
+
}
|
|
1042
|
+
// ===================== EXAMPLE USAGE =====================
|
|
1043
|
+
/*
|
|
1044
|
+
import { useRef, useState } from 'react';
|
|
1045
|
+
|
|
1046
|
+
function HeatmapComponent() {
|
|
1047
|
+
const heatmapWrapperRef = useRef<HTMLDivElement>(null);
|
|
1048
|
+
const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
1049
|
+
const parentRef = useRef<HTMLDivElement>(null);
|
|
1050
|
+
|
|
1051
|
+
const [hoveredElement, setHoveredElement] = useState<HoveredElementInfo | null>(null);
|
|
1052
|
+
|
|
1053
|
+
const heatmapInfo = {
|
|
1054
|
+
width: 1920,
|
|
1055
|
+
elementMapInfo: {
|
|
1056
|
+
'hash123': {
|
|
1057
|
+
totalclicks: 45,
|
|
1058
|
+
selector: 'button.submit'
|
|
1059
|
+
}
|
|
1060
|
+
},
|
|
1061
|
+
sortedElements: [...]
|
|
1062
|
+
};
|
|
1063
|
+
|
|
1064
|
+
const { handleMouseMove } = useHeatmapMouseHandler({
|
|
1065
|
+
heatmapWrapperRef,
|
|
1066
|
+
iframeRef,
|
|
1067
|
+
parentRef,
|
|
1068
|
+
heatmapInfo,
|
|
1069
|
+
scaleRatio: 0.8, // 80% zoom
|
|
1070
|
+
onElementHover: (info) => {
|
|
1071
|
+
setHoveredElement(info);
|
|
1072
|
+
console.log('Hovered element:', info);
|
|
1073
|
+
}
|
|
1074
|
+
});
|
|
1075
|
+
|
|
1076
|
+
return (
|
|
1077
|
+
<div ref={parentRef}>
|
|
1078
|
+
<div
|
|
1079
|
+
ref={heatmapWrapperRef}
|
|
1080
|
+
onMouseMove={handleMouseMove}
|
|
1081
|
+
>
|
|
1082
|
+
<iframe ref={iframeRef} />
|
|
1083
|
+
|
|
1084
|
+
{hoveredElement && (
|
|
1085
|
+
<div className="tooltip" style={{
|
|
1086
|
+
position: 'absolute',
|
|
1087
|
+
left: hoveredElement.left,
|
|
1088
|
+
top: hoveredElement.top
|
|
1089
|
+
}}>
|
|
1090
|
+
Clicks: {hoveredElement.clicks}
|
|
1091
|
+
<br />
|
|
1092
|
+
Rank: #{hoveredElement.rank}
|
|
1093
|
+
<br />
|
|
1094
|
+
Selector: {hoveredElement.selector}
|
|
1095
|
+
</div>
|
|
1096
|
+
)}
|
|
1097
|
+
</div>
|
|
1098
|
+
</div>
|
|
1099
|
+
);
|
|
1100
|
+
}
|
|
1101
|
+
*/
|
|
1102
|
+
|
|
923
1103
|
const useHoveredElement = ({ iframeRef, getRect }) => {
|
|
924
1104
|
const hoveredElement = useHeatmapInteractionStore((state) => state.hoveredElement);
|
|
925
1105
|
const setHoveredElement = useHeatmapInteractionStore((state) => state.setHoveredElement);
|
|
@@ -941,7 +1121,7 @@ const useHoveredElement = ({ iframeRef, getRect }) => {
|
|
|
941
1121
|
const doc = iframe.contentDocument;
|
|
942
1122
|
const iframeRect = iframe.getBoundingClientRect();
|
|
943
1123
|
const { x, y } = convertViewportToIframeCoords(event.clientX, event.clientY, iframeRect, widthScale);
|
|
944
|
-
const targetElement = findTargetElement(doc, x, y);
|
|
1124
|
+
const targetElement = findTargetElement(doc, x, y, heatmapInfo);
|
|
945
1125
|
if (!targetElement || !isValidElement(targetElement, heatmapInfo)) {
|
|
946
1126
|
reset();
|
|
947
1127
|
return;
|
|
@@ -992,7 +1172,25 @@ const convertViewportToIframeCoords = (clientX, clientY, iframeRect, scale) => {
|
|
|
992
1172
|
}
|
|
993
1173
|
return { x, y };
|
|
994
1174
|
};
|
|
995
|
-
const findTargetElement = (doc, x, y) => {
|
|
1175
|
+
const findTargetElement = (doc, x, y, heatmapInfo) => {
|
|
1176
|
+
const HEATMAP_ELEMENT_ATTRIBUTE = 'data-clarity-hashalpha';
|
|
1177
|
+
const elementsAtPoint = getElementsAtPoint(doc, Math.round(x), Math.round(y), (element) => element.hasAttribute(HEATMAP_ELEMENT_ATTRIBUTE));
|
|
1178
|
+
let dataElement = null;
|
|
1179
|
+
for (let i = 0; i < elementsAtPoint.length; i++) {
|
|
1180
|
+
const element = elementsAtPoint[i];
|
|
1181
|
+
const elementHash = element.getAttribute(HEATMAP_ELEMENT_ATTRIBUTE);
|
|
1182
|
+
if (elementHash && heatmapInfo.elementMapInfo?.[elementHash]) {
|
|
1183
|
+
heatmapInfo.elementMapInfo[elementHash];
|
|
1184
|
+
const boundingBox = getBoundingBox(element);
|
|
1185
|
+
if (boundingBox) {
|
|
1186
|
+
dataElement = element;
|
|
1187
|
+
break;
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
if (!!dataElement) {
|
|
1192
|
+
return dataElement;
|
|
1193
|
+
}
|
|
996
1194
|
let targetElement = getElementAtPoint(doc, x, y);
|
|
997
1195
|
if (!targetElement) {
|
|
998
1196
|
targetElement = doc.elementFromPoint(x, y);
|
|
@@ -1016,7 +1214,7 @@ var MessageType;
|
|
|
1016
1214
|
MessageType["GX_DOM_TRACKING_PAYLOAD"] = "GX_DOM_TRACKING_PAYLOAD";
|
|
1017
1215
|
MessageType["CLARITY_READY"] = "CLARITY_READY";
|
|
1018
1216
|
})(MessageType || (MessageType = {}));
|
|
1019
|
-
function
|
|
1217
|
+
function useVizLiveIframeMsg(options = {}) {
|
|
1020
1218
|
const { trustedOrigins = [], onMessage } = options;
|
|
1021
1219
|
const addPayload = useHeatmapLiveStore((state) => state.addPayload);
|
|
1022
1220
|
const [isReady, setIsReady] = useState(false);
|
|
@@ -1066,13 +1264,14 @@ function useIframeMessage(options = {}) {
|
|
|
1066
1264
|
isReady,
|
|
1067
1265
|
};
|
|
1068
1266
|
}
|
|
1069
|
-
|
|
1267
|
+
|
|
1268
|
+
function useVizLiveRender() {
|
|
1070
1269
|
const wrapperHeight = useHeatmapLiveStore((state) => state.wrapperHeight);
|
|
1270
|
+
const setIframeHeight = useHeatmapLiveStore((state) => state.setIframeHeight);
|
|
1071
1271
|
const contentWidth = useHeatmapConfigStore((state) => state.width);
|
|
1072
|
-
const setIframeHeight = useHeatmapVizStore((state) => state.setIframeHeight);
|
|
1073
1272
|
const htmlContent = useHeatmapLiveStore((state) => state.htmlContent);
|
|
1074
1273
|
const setIsRenderViz = useHeatmapVizStore((state) => state.setIsRenderViz);
|
|
1075
|
-
const { iframeRef, isReady } =
|
|
1274
|
+
const { iframeRef, isReady } = useVizLiveIframeMsg();
|
|
1076
1275
|
useEffect(() => {
|
|
1077
1276
|
if (!htmlContent || !iframeRef.current)
|
|
1078
1277
|
return;
|
|
@@ -1119,9 +1318,9 @@ function reset$1(iframe, rect, onSuccess) {
|
|
|
1119
1318
|
let visualizer = new Visualizer();
|
|
1120
1319
|
const useHeatmapRender = () => {
|
|
1121
1320
|
const data = useHeatmapDataStore((state) => state.data);
|
|
1122
|
-
const setVizRef =
|
|
1321
|
+
const setVizRef = useHeatmapSingleStore((state) => state.setVizRef);
|
|
1123
1322
|
const setIsRenderViz = useHeatmapVizStore((state) => state.setIsRenderViz);
|
|
1124
|
-
const setIframeHeight =
|
|
1323
|
+
const setIframeHeight = useHeatmapSingleStore((state) => state.setIframeHeight);
|
|
1125
1324
|
const iframeRef = useRef(null);
|
|
1126
1325
|
const renderHeatmap = useCallback(async (payloads) => {
|
|
1127
1326
|
if (!payloads || payloads.length === 0)
|
|
@@ -1131,8 +1330,6 @@ const useHeatmapRender = () => {
|
|
|
1131
1330
|
if (!iframe?.contentWindow)
|
|
1132
1331
|
return;
|
|
1133
1332
|
await visualizer.html(payloads, iframe.contentWindow);
|
|
1134
|
-
const element = visualizer.get('3w0uppvjw');
|
|
1135
|
-
console.log(`🚀 🐥 ~ useHeatmapRender ~ element:`, element);
|
|
1136
1333
|
reset(iframe, payloads, (height) => {
|
|
1137
1334
|
height && setIframeHeight(height);
|
|
1138
1335
|
setIsRenderViz(true);
|
|
@@ -1160,8 +1357,8 @@ function reset(iframe, payloads, onSuccess) {
|
|
|
1160
1357
|
targetHeight: docHeight,
|
|
1161
1358
|
iframe: iframe,
|
|
1162
1359
|
onSuccess: (data) => {
|
|
1163
|
-
onSuccess(data.height);
|
|
1164
1360
|
iframe.height = `${data.height}px`;
|
|
1361
|
+
onSuccess(data.height);
|
|
1165
1362
|
},
|
|
1166
1363
|
});
|
|
1167
1364
|
viewportFixer.recalculate();
|
|
@@ -1350,30 +1547,64 @@ const useContentDimensions = ({ iframeRef, }) => {
|
|
|
1350
1547
|
return { contentWidth };
|
|
1351
1548
|
};
|
|
1352
1549
|
|
|
1353
|
-
const
|
|
1550
|
+
const useObserveIframeHeight = (props) => {
|
|
1354
1551
|
const { iframeRef, setIframeHeight } = props;
|
|
1355
1552
|
const isRenderViz = useHeatmapVizStore((state) => state.isRenderViz);
|
|
1356
1553
|
const resizeObserverRef = useRef(null);
|
|
1357
1554
|
const mutationObserverRef = useRef(null);
|
|
1555
|
+
const debounceTimerRef = useRef(null);
|
|
1556
|
+
const lastHeightRef = useRef(0);
|
|
1557
|
+
const animationFrameRef = useRef(null);
|
|
1358
1558
|
const updateIframeHeight = useCallback(() => {
|
|
1359
1559
|
const iframe = iframeRef.current;
|
|
1360
|
-
if (!iframe)
|
|
1560
|
+
if (!iframe || !setIframeHeight)
|
|
1361
1561
|
return;
|
|
1362
1562
|
try {
|
|
1363
1563
|
const iframeDocument = iframe.contentDocument;
|
|
1364
1564
|
const iframeBody = iframeDocument?.body;
|
|
1365
|
-
|
|
1565
|
+
const iframeDocumentElement = iframeDocument?.documentElement;
|
|
1566
|
+
if (!iframeBody || !iframeDocumentElement)
|
|
1366
1567
|
return;
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1568
|
+
iframe.style.height = 'auto';
|
|
1569
|
+
requestAnimationFrame(() => {
|
|
1570
|
+
const bodyHeight = Math.max(iframeBody.scrollHeight, iframeBody.offsetHeight, iframeBody.clientHeight);
|
|
1571
|
+
const documentHeight = Math.max(iframeDocumentElement.scrollHeight, iframeDocumentElement.offsetHeight, iframeDocumentElement.clientHeight);
|
|
1572
|
+
const actualHeight = Math.max(bodyHeight, documentHeight);
|
|
1573
|
+
if (actualHeight > 0) {
|
|
1574
|
+
lastHeightRef.current = actualHeight;
|
|
1575
|
+
iframe.height = `${actualHeight}px`;
|
|
1576
|
+
iframe.style.height = `${actualHeight}px`;
|
|
1577
|
+
setIframeHeight(actualHeight);
|
|
1578
|
+
}
|
|
1579
|
+
});
|
|
1372
1580
|
}
|
|
1373
1581
|
catch (error) {
|
|
1374
1582
|
console.warn('Cannot measure iframe content:', error);
|
|
1375
1583
|
}
|
|
1376
1584
|
}, [iframeRef, setIframeHeight]);
|
|
1585
|
+
const debouncedUpdate = useCallback(() => {
|
|
1586
|
+
// Cancel pending updates
|
|
1587
|
+
if (debounceTimerRef.current) {
|
|
1588
|
+
clearTimeout(debounceTimerRef.current);
|
|
1589
|
+
}
|
|
1590
|
+
if (animationFrameRef.current) {
|
|
1591
|
+
cancelAnimationFrame(animationFrameRef.current);
|
|
1592
|
+
}
|
|
1593
|
+
debounceTimerRef.current = setTimeout(() => {
|
|
1594
|
+
animationFrameRef.current = requestAnimationFrame(() => {
|
|
1595
|
+
updateIframeHeight();
|
|
1596
|
+
});
|
|
1597
|
+
}, 50);
|
|
1598
|
+
}, [updateIframeHeight]);
|
|
1599
|
+
// Immediate update không debounce (cho ResizeObserver)
|
|
1600
|
+
const immediateUpdate = useCallback(() => {
|
|
1601
|
+
if (animationFrameRef.current) {
|
|
1602
|
+
cancelAnimationFrame(animationFrameRef.current);
|
|
1603
|
+
}
|
|
1604
|
+
animationFrameRef.current = requestAnimationFrame(() => {
|
|
1605
|
+
updateIframeHeight();
|
|
1606
|
+
});
|
|
1607
|
+
}, [updateIframeHeight]);
|
|
1377
1608
|
useEffect(() => {
|
|
1378
1609
|
const iframe = iframeRef.current;
|
|
1379
1610
|
if (!iframe || !isRenderViz)
|
|
@@ -1391,22 +1622,24 @@ const useIframeHeight = (props) => {
|
|
|
1391
1622
|
if (mutationObserverRef.current) {
|
|
1392
1623
|
mutationObserverRef.current.disconnect();
|
|
1393
1624
|
}
|
|
1394
|
-
// ResizeObserver for size changes
|
|
1395
1625
|
if (typeof window.ResizeObserver !== 'undefined') {
|
|
1396
|
-
resizeObserverRef.current = new ResizeObserver(
|
|
1626
|
+
resizeObserverRef.current = new ResizeObserver(immediateUpdate);
|
|
1397
1627
|
resizeObserverRef.current.observe(iframeBody);
|
|
1628
|
+
const iframeDocumentElement = iframeDocument?.documentElement;
|
|
1629
|
+
if (iframeDocumentElement) {
|
|
1630
|
+
resizeObserverRef.current.observe(iframeDocumentElement);
|
|
1631
|
+
}
|
|
1398
1632
|
}
|
|
1399
|
-
// MutationObserver for DOM changes
|
|
1400
1633
|
if (typeof window.MutationObserver !== 'undefined') {
|
|
1401
|
-
mutationObserverRef.current = new MutationObserver(
|
|
1634
|
+
mutationObserverRef.current = new MutationObserver(immediateUpdate);
|
|
1402
1635
|
mutationObserverRef.current.observe(iframeBody, {
|
|
1403
1636
|
childList: true,
|
|
1404
1637
|
subtree: true,
|
|
1405
1638
|
attributes: true,
|
|
1406
|
-
|
|
1639
|
+
attributeFilter: ['style', 'class'],
|
|
1640
|
+
characterData: false,
|
|
1407
1641
|
});
|
|
1408
1642
|
}
|
|
1409
|
-
// Initial measurement
|
|
1410
1643
|
updateIframeHeight();
|
|
1411
1644
|
}
|
|
1412
1645
|
catch (error) {
|
|
@@ -1420,15 +1653,23 @@ const useIframeHeight = (props) => {
|
|
|
1420
1653
|
iframe.addEventListener('load', setupObservers, { once: true });
|
|
1421
1654
|
}
|
|
1422
1655
|
return () => {
|
|
1656
|
+
// Cleanup observers
|
|
1423
1657
|
if (resizeObserverRef.current) {
|
|
1424
1658
|
resizeObserverRef.current.disconnect();
|
|
1425
1659
|
}
|
|
1426
1660
|
if (mutationObserverRef.current) {
|
|
1427
1661
|
mutationObserverRef.current.disconnect();
|
|
1428
1662
|
}
|
|
1663
|
+
// Cleanup timers
|
|
1664
|
+
if (debounceTimerRef.current) {
|
|
1665
|
+
clearTimeout(debounceTimerRef.current);
|
|
1666
|
+
}
|
|
1667
|
+
if (animationFrameRef.current) {
|
|
1668
|
+
cancelAnimationFrame(animationFrameRef.current);
|
|
1669
|
+
}
|
|
1429
1670
|
iframe.removeEventListener('load', setupObservers);
|
|
1430
1671
|
};
|
|
1431
|
-
}, [iframeRef, isRenderViz, updateIframeHeight]);
|
|
1672
|
+
}, [iframeRef, isRenderViz, updateIframeHeight, debouncedUpdate, immediateUpdate]);
|
|
1432
1673
|
return {};
|
|
1433
1674
|
};
|
|
1434
1675
|
|
|
@@ -1474,7 +1715,7 @@ const useHeatmapScale = (props) => {
|
|
|
1474
1715
|
// 2. Get content dimensions from config
|
|
1475
1716
|
const { contentWidth } = useContentDimensions({ iframeRef });
|
|
1476
1717
|
// 3. Observe iframe height (now reacts to width changes)
|
|
1477
|
-
|
|
1718
|
+
useObserveIframeHeight({ iframeRef, setIframeHeight });
|
|
1478
1719
|
// 4. Calculate scale
|
|
1479
1720
|
const { scale } = useScaleCalculation({ containerWidth, contentWidth });
|
|
1480
1721
|
// 5. Setup scroll sync
|
|
@@ -1645,37 +1886,159 @@ const VizContainer = ({ children, setWrapperHeight }) => {
|
|
|
1645
1886
|
const useClickmap = () => {
|
|
1646
1887
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
1647
1888
|
const clickmap = useHeatmapDataStore((state) => state.clickmap);
|
|
1648
|
-
const vizRef =
|
|
1649
|
-
|
|
1889
|
+
const vizRef = useHeatmapSingleStore((state) => state.vizRef);
|
|
1890
|
+
const start = useCallback(() => {
|
|
1650
1891
|
if (isInitialized)
|
|
1651
1892
|
return;
|
|
1652
1893
|
if (!vizRef || !clickmap || clickmap.length === 0)
|
|
1653
1894
|
return;
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1895
|
+
try {
|
|
1896
|
+
vizRef?.clearmap?.();
|
|
1897
|
+
vizRef?.clickmap?.(clickmap);
|
|
1898
|
+
setIsInitialized(true);
|
|
1899
|
+
}
|
|
1900
|
+
catch (error) {
|
|
1901
|
+
console.error(`🚀 🐥 ~ useClickmap ~ error:`, error);
|
|
1902
|
+
}
|
|
1659
1903
|
}, [vizRef, clickmap]);
|
|
1660
|
-
return {};
|
|
1904
|
+
return { start };
|
|
1661
1905
|
};
|
|
1662
1906
|
|
|
1907
|
+
const DATA_SCROLLMAP = [
|
|
1908
|
+
{
|
|
1909
|
+
scrollReachY: 5,
|
|
1910
|
+
cumulativeSum: 0,
|
|
1911
|
+
percUsers: 0,
|
|
1912
|
+
},
|
|
1913
|
+
{
|
|
1914
|
+
scrollReachY: 10,
|
|
1915
|
+
cumulativeSum: 0,
|
|
1916
|
+
percUsers: 0,
|
|
1917
|
+
},
|
|
1918
|
+
{
|
|
1919
|
+
scrollReachY: 15,
|
|
1920
|
+
cumulativeSum: 0,
|
|
1921
|
+
percUsers: 0,
|
|
1922
|
+
},
|
|
1923
|
+
{
|
|
1924
|
+
scrollReachY: 20,
|
|
1925
|
+
cumulativeSum: 0,
|
|
1926
|
+
percUsers: 0,
|
|
1927
|
+
},
|
|
1928
|
+
{
|
|
1929
|
+
scrollReachY: 25,
|
|
1930
|
+
cumulativeSum: 0,
|
|
1931
|
+
percUsers: 0,
|
|
1932
|
+
},
|
|
1933
|
+
{
|
|
1934
|
+
scrollReachY: 30,
|
|
1935
|
+
cumulativeSum: 0,
|
|
1936
|
+
percUsers: 0,
|
|
1937
|
+
},
|
|
1938
|
+
{
|
|
1939
|
+
scrollReachY: 35,
|
|
1940
|
+
cumulativeSum: 0,
|
|
1941
|
+
percUsers: 0,
|
|
1942
|
+
},
|
|
1943
|
+
{
|
|
1944
|
+
scrollReachY: 40,
|
|
1945
|
+
cumulativeSum: 0,
|
|
1946
|
+
percUsers: 0,
|
|
1947
|
+
},
|
|
1948
|
+
{
|
|
1949
|
+
scrollReachY: 45,
|
|
1950
|
+
cumulativeSum: 0,
|
|
1951
|
+
percUsers: 0,
|
|
1952
|
+
},
|
|
1953
|
+
{
|
|
1954
|
+
scrollReachY: 50,
|
|
1955
|
+
cumulativeSum: 0,
|
|
1956
|
+
percUsers: 0,
|
|
1957
|
+
},
|
|
1958
|
+
{
|
|
1959
|
+
scrollReachY: 55,
|
|
1960
|
+
cumulativeSum: 0,
|
|
1961
|
+
percUsers: 0,
|
|
1962
|
+
},
|
|
1963
|
+
{
|
|
1964
|
+
scrollReachY: 60,
|
|
1965
|
+
cumulativeSum: 0,
|
|
1966
|
+
percUsers: 0,
|
|
1967
|
+
},
|
|
1968
|
+
{
|
|
1969
|
+
scrollReachY: 65,
|
|
1970
|
+
cumulativeSum: 0,
|
|
1971
|
+
percUsers: 0,
|
|
1972
|
+
},
|
|
1973
|
+
{
|
|
1974
|
+
scrollReachY: 70,
|
|
1975
|
+
cumulativeSum: 0,
|
|
1976
|
+
percUsers: 0,
|
|
1977
|
+
},
|
|
1978
|
+
{
|
|
1979
|
+
scrollReachY: 75,
|
|
1980
|
+
cumulativeSum: 0,
|
|
1981
|
+
percUsers: 0,
|
|
1982
|
+
},
|
|
1983
|
+
{
|
|
1984
|
+
scrollReachY: 80,
|
|
1985
|
+
cumulativeSum: 0,
|
|
1986
|
+
percUsers: 0,
|
|
1987
|
+
},
|
|
1988
|
+
{
|
|
1989
|
+
scrollReachY: 85,
|
|
1990
|
+
cumulativeSum: 0,
|
|
1991
|
+
percUsers: 0,
|
|
1992
|
+
},
|
|
1993
|
+
{
|
|
1994
|
+
scrollReachY: 90,
|
|
1995
|
+
cumulativeSum: 0,
|
|
1996
|
+
percUsers: 0,
|
|
1997
|
+
},
|
|
1998
|
+
{
|
|
1999
|
+
scrollReachY: 95,
|
|
2000
|
+
cumulativeSum: 0,
|
|
2001
|
+
percUsers: 0,
|
|
2002
|
+
},
|
|
2003
|
+
{
|
|
2004
|
+
scrollReachY: 100,
|
|
2005
|
+
cumulativeSum: 0,
|
|
2006
|
+
percUsers: 0,
|
|
2007
|
+
},
|
|
2008
|
+
];
|
|
1663
2009
|
const useScrollmap = () => {
|
|
1664
|
-
|
|
1665
|
-
|
|
2010
|
+
const vizRef = useHeatmapSingleStore((state) => state.vizRef);
|
|
2011
|
+
const start = useCallback(() => {
|
|
2012
|
+
// if (isInitialized) return;
|
|
2013
|
+
const scrollmap = DATA_SCROLLMAP;
|
|
2014
|
+
if (!vizRef || !scrollmap || scrollmap.length === 0)
|
|
2015
|
+
return;
|
|
2016
|
+
try {
|
|
2017
|
+
vizRef?.clearmap?.();
|
|
2018
|
+
vizRef?.scrollmap?.(scrollmap);
|
|
2019
|
+
// setIsInitialized(true);
|
|
2020
|
+
}
|
|
2021
|
+
catch (error) {
|
|
2022
|
+
console.error(`🚀 🐥 ~ useScrollmap ~ error:`, error);
|
|
2023
|
+
}
|
|
2024
|
+
}, [vizRef]);
|
|
2025
|
+
return { start };
|
|
1666
2026
|
};
|
|
1667
2027
|
|
|
1668
2028
|
const useHeatmapVizCanvas = () => {
|
|
1669
2029
|
const heatmapType = useHeatmapConfigStore((state) => state.heatmapType);
|
|
1670
|
-
const
|
|
2030
|
+
const { start: startClickmap } = useClickmap();
|
|
2031
|
+
const { start: startScrollmap } = useScrollmap();
|
|
2032
|
+
useEffect(() => {
|
|
1671
2033
|
switch (heatmapType) {
|
|
1672
2034
|
case IHeatmapType.Click:
|
|
1673
|
-
|
|
2035
|
+
startClickmap();
|
|
2036
|
+
break;
|
|
1674
2037
|
case IHeatmapType.Scroll:
|
|
1675
|
-
|
|
2038
|
+
startClickmap();
|
|
2039
|
+
break;
|
|
1676
2040
|
}
|
|
1677
|
-
}, [heatmapType]);
|
|
1678
|
-
return heatmapRender?.();
|
|
2041
|
+
}, [heatmapType, startClickmap, startScrollmap]);
|
|
1679
2042
|
};
|
|
1680
2043
|
|
|
1681
2044
|
const CLICKED_ELEMENT_ID = 'gx-hm-clicked-element';
|
|
@@ -1738,7 +2101,7 @@ const ElementCallout = (props) => {
|
|
|
1738
2101
|
window.removeEventListener('resize', handleUpdate);
|
|
1739
2102
|
visualRef?.current?.removeEventListener('scroll', handleUpdate);
|
|
1740
2103
|
};
|
|
1741
|
-
}, [target, visualRef, hozOffset, alignment]);
|
|
2104
|
+
}, [element, target, visualRef, hozOffset, alignment]);
|
|
1742
2105
|
const calloutContent = (jsx("div", { ref: calloutRef, className: `clarity-callout clarity-callout--${position.placement} clarity-callout--align-${position.horizontalAlign}`, style: {
|
|
1743
2106
|
position: 'fixed',
|
|
1744
2107
|
top: position.top,
|
|
@@ -1803,7 +2166,8 @@ const ELEMENT_CALLOUT = {
|
|
|
1803
2166
|
alignment: 'left',
|
|
1804
2167
|
};
|
|
1805
2168
|
const HeatmapElements = (props) => {
|
|
1806
|
-
const
|
|
2169
|
+
const iframeHeight = useHeatmapSingleStore((state) => state.iframeHeight);
|
|
2170
|
+
const setHoveredElement = useHeatmapInteractionStore((state) => state.setHoveredElement);
|
|
1807
2171
|
const { iframeRef, wrapperRef, visualRef, visualizer, iframeDimensions, isElementSidebarOpen, isVisible = true, areDefaultRanksHidden, isSecondary, ...rest } = props;
|
|
1808
2172
|
const getRect = useHeatmapElementPosition({
|
|
1809
2173
|
iframeRef,
|
|
@@ -1818,6 +2182,27 @@ const HeatmapElements = (props) => {
|
|
|
1818
2182
|
iframeRef,
|
|
1819
2183
|
getRect,
|
|
1820
2184
|
});
|
|
2185
|
+
const heatmapInfo = useHeatmapDataStore((state) => state.dataInfo);
|
|
2186
|
+
useHeatmapMouseHandler({
|
|
2187
|
+
heatmapWrapperRef: wrapperRef,
|
|
2188
|
+
iframeRef,
|
|
2189
|
+
parentRef: visualRef,
|
|
2190
|
+
heatmapInfo: heatmapInfo || {},
|
|
2191
|
+
scaleRatio: 0.8, // 80% zoom
|
|
2192
|
+
onElementHover: (info) => {
|
|
2193
|
+
setHoveredElement({
|
|
2194
|
+
hash: info.hash,
|
|
2195
|
+
clicks: info.clicks,
|
|
2196
|
+
rank: info.rank,
|
|
2197
|
+
selector: info.selector,
|
|
2198
|
+
top: info.top,
|
|
2199
|
+
left: info.left,
|
|
2200
|
+
width: info.width,
|
|
2201
|
+
height: info.height,
|
|
2202
|
+
});
|
|
2203
|
+
console.log(`🚀 🐥 ~ HeatmapElements ~ info:`, info);
|
|
2204
|
+
},
|
|
2205
|
+
});
|
|
1821
2206
|
useElementCalloutVisible({
|
|
1822
2207
|
visualRef,
|
|
1823
2208
|
getRect,
|
|
@@ -1833,13 +2218,16 @@ const HeatmapElements = (props) => {
|
|
|
1833
2218
|
});
|
|
1834
2219
|
if (!isVisible)
|
|
1835
2220
|
return null;
|
|
1836
|
-
return (jsxs("div", { onMouseMove:
|
|
2221
|
+
return (jsxs("div", { onMouseMove: (event) => {
|
|
2222
|
+
handleMouseMove(event);
|
|
2223
|
+
// handleMouseMove2(event as any);
|
|
2224
|
+
}, onMouseLeave: handleMouseLeave, className: "gx-hm-elements", style: { ...iframeDimensions, height: `${iframeHeight}px` }, children: [jsx(ElementMissing, { show: showMissingElement }), jsx(DefaultRankBadges, { getRect: getRect, hidden: areDefaultRanksHidden }), jsx(ElementOverlay, { type: "clicked", element: clickedElement, isSecondary: isSecondary }), jsx(ElementOverlay, { type: "hovered", element: hoveredElement, isSecondary: isSecondary, onClick: handleClick }), hoveredElement?.hash !== clickedElement?.hash && hoveredElement && (jsx(ElementCallout, { element: hoveredElement, target: `#${HOVERED_ELEMENT_ID}`, visualRef: visualRef, ...ELEMENT_CALLOUT })), shouldShowCallout && clickedElement && (jsx(ElementCallout, { element: clickedElement, target: `#${CLICKED_ELEMENT_ID}`, visualRef: visualRef, ...ELEMENT_CALLOUT }))] }));
|
|
1837
2225
|
};
|
|
1838
2226
|
|
|
1839
2227
|
const VizElements = ({ iframeRef, visualRef, wrapperRef }) => {
|
|
1840
2228
|
const heatmapInfo = useHeatmapDataStore((state) => state.dataInfo);
|
|
1841
2229
|
const contentWidth = useHeatmapConfigStore((state) => state.width);
|
|
1842
|
-
const vizRef =
|
|
2230
|
+
const vizRef = useHeatmapSingleStore((state) => state.vizRef);
|
|
1843
2231
|
const visualizer = {
|
|
1844
2232
|
get: (hash) => {
|
|
1845
2233
|
if (vizRef) {
|
|
@@ -1904,8 +2292,8 @@ const WrapperVisual = ({ children, visualRef, wrapperRef, scaledHeight, iframeHe
|
|
|
1904
2292
|
|
|
1905
2293
|
const VizDomRenderer = ({ mode = 'heatmap' }) => {
|
|
1906
2294
|
const width = useHeatmapConfigStore((state) => state.width);
|
|
1907
|
-
const iframeHeight =
|
|
1908
|
-
const setIframeHeight =
|
|
2295
|
+
const iframeHeight = useHeatmapSingleStore((state) => state.iframeHeight);
|
|
2296
|
+
const setIframeHeight = useHeatmapSingleStore((state) => state.setIframeHeight);
|
|
1909
2297
|
const setSelectedElement = useHeatmapInteractionStore((state) => state.setSelectedElement);
|
|
1910
2298
|
const wrapperRef = useRef(null);
|
|
1911
2299
|
const visualRef = useRef(null);
|
|
@@ -1915,7 +2303,6 @@ const VizDomRenderer = ({ mode = 'heatmap' }) => {
|
|
|
1915
2303
|
iframeRef,
|
|
1916
2304
|
visualRef,
|
|
1917
2305
|
iframeHeight,
|
|
1918
|
-
setIframeHeight,
|
|
1919
2306
|
});
|
|
1920
2307
|
const contentWidth = width ?? 0;
|
|
1921
2308
|
const onScroll = (e) => {
|
|
@@ -1930,7 +2317,7 @@ const VizDomRenderer = ({ mode = 'heatmap' }) => {
|
|
|
1930
2317
|
useEffect(() => {
|
|
1931
2318
|
return cleanUp;
|
|
1932
2319
|
}, []);
|
|
1933
|
-
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,
|
|
2320
|
+
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" })] }));
|
|
1934
2321
|
};
|
|
1935
2322
|
|
|
1936
2323
|
const VizLoading = () => {
|
|
@@ -1940,12 +2327,12 @@ const VizLoading = () => {
|
|
|
1940
2327
|
const VizDomHeatmap = () => {
|
|
1941
2328
|
const controls = useHeatmapControlStore((state) => state.controls);
|
|
1942
2329
|
const isRendering = useHeatmapDataStore((state) => state.isRendering);
|
|
1943
|
-
const iframeHeight =
|
|
1944
|
-
const setIframeHeight =
|
|
1945
|
-
const setVizRef =
|
|
2330
|
+
const iframeHeight = useHeatmapSingleStore((state) => state.iframeHeight);
|
|
2331
|
+
const setIframeHeight = useHeatmapSingleStore((state) => state.setIframeHeight);
|
|
2332
|
+
const setVizRef = useHeatmapSingleStore((state) => state.setVizRef);
|
|
1946
2333
|
useEffect(() => {
|
|
1947
2334
|
return () => {
|
|
1948
|
-
setVizRef(
|
|
2335
|
+
setVizRef(null);
|
|
1949
2336
|
setIframeHeight(0);
|
|
1950
2337
|
};
|
|
1951
2338
|
}, []);
|
|
@@ -1960,7 +2347,7 @@ const VizLiveRenderer = () => {
|
|
|
1960
2347
|
const setIframeHeight = useHeatmapLiveStore((state) => state.setIframeHeight);
|
|
1961
2348
|
const visualRef = useRef(null);
|
|
1962
2349
|
const wrapperRef = useRef(null);
|
|
1963
|
-
const { iframeRef } =
|
|
2350
|
+
const { iframeRef } = useVizLiveRender();
|
|
1964
2351
|
const { scaledHeight, handleScroll } = useHeatmapScale({
|
|
1965
2352
|
wrapperRef,
|
|
1966
2353
|
iframeRef,
|
|
@@ -1972,13 +2359,15 @@ const VizLiveRenderer = () => {
|
|
|
1972
2359
|
const scrollTop = e.currentTarget.scrollTop;
|
|
1973
2360
|
handleScroll(scrollTop);
|
|
1974
2361
|
};
|
|
1975
|
-
return (jsx(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, iframeHeight: iframeHeight, onScroll: onScroll, children: jsx("iframe", { ref: iframeRef, ...HEATMAP_IFRAME, width: contentWidth,
|
|
2362
|
+
return (jsx(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, iframeHeight: iframeHeight, onScroll: onScroll, children: jsx("iframe", { ref: iframeRef, ...HEATMAP_IFRAME, width: contentWidth,
|
|
2363
|
+
// height={iframeHeight}
|
|
2364
|
+
scrolling: "no", sandbox: "allow-scripts allow-same-origin" }) }));
|
|
1976
2365
|
};
|
|
1977
2366
|
|
|
1978
2367
|
const VizLiveHeatmap = () => {
|
|
1979
2368
|
const controls = useHeatmapControlStore((state) => state.controls);
|
|
1980
2369
|
const isRendering = useHeatmapDataStore((state) => state.isRendering);
|
|
1981
|
-
const iframeHeight =
|
|
2370
|
+
const iframeHeight = useHeatmapSingleStore((state) => state.iframeHeight);
|
|
1982
2371
|
const wrapperHeight = useHeatmapLiveStore((state) => state.wrapperHeight);
|
|
1983
2372
|
const setWrapperHeight = useHeatmapLiveStore((state) => state.setWrapperHeight);
|
|
1984
2373
|
const reset = useHeatmapLiveStore((state) => state.reset);
|