@gemx-dev/heatmap-react 3.5.32 → 3.5.34
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/ContentToolbar.d.ts.map +1 -1
- package/dist/esm/components/Layout/HeatmapLayout.d.ts.map +1 -1
- package/dist/esm/components/VizDom/VizDomRenderer.d.ts.map +1 -1
- package/dist/esm/components/VizElement/ClickedElementOverlay.d.ts +0 -7
- package/dist/esm/components/VizElement/ClickedElementOverlay.d.ts.map +1 -1
- package/dist/esm/components/VizElement/DefaultRankBadges.d.ts +0 -3
- package/dist/esm/components/VizElement/DefaultRankBadges.d.ts.map +1 -1
- package/dist/esm/components/VizElement/ElementCallout.d.ts +1 -7
- package/dist/esm/components/VizElement/ElementCallout.d.ts.map +1 -1
- package/dist/esm/components/VizElement/HeatmapElements.d.ts +2 -7
- package/dist/esm/components/VizElement/HeatmapElements.d.ts.map +1 -1
- package/dist/esm/components/VizElement/HoveredElementOverlay.d.ts +0 -2
- package/dist/esm/components/VizElement/HoveredElementOverlay.d.ts.map +1 -1
- package/dist/esm/components/VizElement/MissingElementMessage.d.ts +0 -1
- package/dist/esm/components/VizElement/MissingElementMessage.d.ts.map +1 -1
- package/dist/esm/components/VizElement/VizElements.d.ts +1 -2
- package/dist/esm/components/VizElement/VizElements.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/useClickedElement.d.ts +5 -3
- package/dist/esm/hooks/vix-elements/useClickedElement.d.ts.map +1 -1
- package/dist/esm/hooks/vix-elements/useHeatmapElementPosition.d.ts +2 -5
- package/dist/esm/hooks/vix-elements/useHeatmapElementPosition.d.ts.map +1 -1
- package/dist/esm/hooks/vix-elements/useHoveredElement.d.ts +2 -5
- package/dist/esm/hooks/vix-elements/useHoveredElement.d.ts.map +1 -1
- package/dist/esm/hooks/viz-render/useHeatmapRender.d.ts.map +1 -1
- package/dist/esm/hooks/viz-scale/useContentDimensions.d.ts +0 -2
- package/dist/esm/hooks/viz-scale/useContentDimensions.d.ts.map +1 -1
- package/dist/esm/hooks/viz-scale/useHeatmapScale.d.ts +1 -4
- package/dist/esm/hooks/viz-scale/useHeatmapScale.d.ts.map +1 -1
- package/dist/esm/hooks/viz-scale/useScrollSync.d.ts +1 -2
- package/dist/esm/hooks/viz-scale/useScrollSync.d.ts.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +171 -225
- package/dist/esm/index.mjs +171 -225
- package/dist/esm/types/viz-element.d.ts +1 -0
- package/dist/esm/types/viz-element.d.ts.map +1 -1
- package/dist/style.css +149 -4
- package/dist/umd/components/Layout/ContentToolbar.d.ts.map +1 -1
- package/dist/umd/components/Layout/HeatmapLayout.d.ts.map +1 -1
- package/dist/umd/components/VizDom/VizDomRenderer.d.ts.map +1 -1
- package/dist/umd/components/VizElement/ClickedElementOverlay.d.ts +0 -7
- package/dist/umd/components/VizElement/ClickedElementOverlay.d.ts.map +1 -1
- package/dist/umd/components/VizElement/DefaultRankBadges.d.ts +0 -3
- package/dist/umd/components/VizElement/DefaultRankBadges.d.ts.map +1 -1
- package/dist/umd/components/VizElement/ElementCallout.d.ts +1 -7
- package/dist/umd/components/VizElement/ElementCallout.d.ts.map +1 -1
- package/dist/umd/components/VizElement/HeatmapElements.d.ts +2 -7
- package/dist/umd/components/VizElement/HeatmapElements.d.ts.map +1 -1
- package/dist/umd/components/VizElement/HoveredElementOverlay.d.ts +0 -2
- package/dist/umd/components/VizElement/HoveredElementOverlay.d.ts.map +1 -1
- package/dist/umd/components/VizElement/MissingElementMessage.d.ts +0 -1
- package/dist/umd/components/VizElement/MissingElementMessage.d.ts.map +1 -1
- package/dist/umd/components/VizElement/VizElements.d.ts +1 -2
- package/dist/umd/components/VizElement/VizElements.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/useClickedElement.d.ts +5 -3
- package/dist/umd/hooks/vix-elements/useClickedElement.d.ts.map +1 -1
- package/dist/umd/hooks/vix-elements/useHeatmapElementPosition.d.ts +2 -5
- package/dist/umd/hooks/vix-elements/useHeatmapElementPosition.d.ts.map +1 -1
- package/dist/umd/hooks/vix-elements/useHoveredElement.d.ts +2 -5
- package/dist/umd/hooks/vix-elements/useHoveredElement.d.ts.map +1 -1
- package/dist/umd/hooks/viz-render/useHeatmapRender.d.ts.map +1 -1
- package/dist/umd/hooks/viz-scale/useContentDimensions.d.ts +0 -2
- package/dist/umd/hooks/viz-scale/useContentDimensions.d.ts.map +1 -1
- package/dist/umd/hooks/viz-scale/useHeatmapScale.d.ts +1 -4
- package/dist/umd/hooks/viz-scale/useHeatmapScale.d.ts.map +1 -1
- package/dist/umd/hooks/viz-scale/useScrollSync.d.ts +1 -2
- package/dist/umd/hooks/viz-scale/useScrollSync.d.ts.map +1 -1
- 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/types/viz-element.d.ts +1 -0
- package/dist/umd/types/viz-element.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -49,7 +49,9 @@ const HEATMAP_IFRAME = {
|
|
|
49
49
|
const HEATMAP_CONFIG = {
|
|
50
50
|
padding: 8,
|
|
51
51
|
borderWidth: 1,
|
|
52
|
+
borderWidthIframe: 2,
|
|
52
53
|
borderColor: '#E3E3E3',
|
|
54
|
+
heightToolbar: 60, // height of the toolbar
|
|
53
55
|
};
|
|
54
56
|
const HEATMAP_STYLE = {
|
|
55
57
|
viz: {
|
|
@@ -187,17 +189,77 @@ const useRegisterHeatmap = (clickmap) => {
|
|
|
187
189
|
}, [clickmap]);
|
|
188
190
|
};
|
|
189
191
|
|
|
190
|
-
const
|
|
192
|
+
const isElementInViewport = (elementRect, visualRef, scale) => {
|
|
193
|
+
const visualRect = visualRef.current?.getBoundingClientRect();
|
|
194
|
+
if (!visualRect)
|
|
195
|
+
return false;
|
|
196
|
+
// Absolute position of element so visual container (not scaled)
|
|
197
|
+
const elementTopRaw = elementRect.top - visualRect.top;
|
|
198
|
+
const elementBottomRaw = elementTopRaw + elementRect.height;
|
|
199
|
+
// Apply scale because wrapper is scaled
|
|
200
|
+
const elementTop = elementTopRaw * scale;
|
|
201
|
+
const elementBottom = elementBottomRaw * scale;
|
|
202
|
+
const scrollTop = visualRef.current?.scrollTop || 0;
|
|
203
|
+
const viewportHeight = visualRect.height;
|
|
204
|
+
const viewportTop = scrollTop;
|
|
205
|
+
const viewportBottom = scrollTop + viewportHeight;
|
|
206
|
+
return elementTop >= viewportTop && elementBottom <= viewportBottom;
|
|
207
|
+
};
|
|
208
|
+
const calculateElementRank = (selectedElement, sortedElements) => {
|
|
209
|
+
if (!sortedElements)
|
|
210
|
+
return 0;
|
|
211
|
+
return sortedElements.findIndex((e) => e.hash === selectedElement) + 1;
|
|
212
|
+
};
|
|
213
|
+
const buildElementInfo = (selectedElement, info, rect, rank) => {
|
|
214
|
+
const baseInfo = {
|
|
215
|
+
hash: selectedElement,
|
|
216
|
+
clicks: info.totalclicks ?? 0,
|
|
217
|
+
rank,
|
|
218
|
+
selector: info.selector ?? '',
|
|
219
|
+
};
|
|
220
|
+
if (rect) {
|
|
221
|
+
return { ...baseInfo, ...rect };
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
...baseInfo,
|
|
225
|
+
left: 0,
|
|
226
|
+
top: 0,
|
|
227
|
+
width: 0,
|
|
228
|
+
height: 0,
|
|
229
|
+
};
|
|
230
|
+
};
|
|
231
|
+
const scrollToElementIfNeeded = (visualRef, wrapperRef, rect, scale) => {
|
|
232
|
+
if (!visualRef.current || !wrapperRef.current)
|
|
233
|
+
return;
|
|
234
|
+
const visualRect = visualRef.current.getBoundingClientRect();
|
|
235
|
+
if (isElementInViewport(rect, visualRef, scale)) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const topRaw = rect.top; // - visualRect.top
|
|
239
|
+
const topScaled = topRaw * scale;
|
|
240
|
+
const viewportHeight = visualRect.height;
|
|
241
|
+
const elementHeightScaled = rect.height * scale;
|
|
242
|
+
const scrollTop = topScaled - (viewportHeight - elementHeightScaled) / 2;
|
|
243
|
+
visualRef.current.scrollTo({
|
|
244
|
+
top: Math.max(0, scrollTop),
|
|
245
|
+
behavior: 'smooth',
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
const useClickedElement = ({ visualRef, wrapperRef, getRect }) => {
|
|
249
|
+
const heatmapInfo = useHeatmapDataStore((state) => state.dataInfo);
|
|
191
250
|
const selectedElement = useHeatmapInteractionStore((state) => state.selectedElement);
|
|
251
|
+
const scale = useHeatmapVizStore((state) => state.scale);
|
|
192
252
|
const [clickedElement, setClickedElement] = useState(null);
|
|
193
253
|
const [showMissingElement, setShowMissingElement] = useState(false);
|
|
194
254
|
const [shouldShowCallout, setShouldShowCallout] = useState(false);
|
|
255
|
+
const reset = () => {
|
|
256
|
+
setClickedElement(null);
|
|
257
|
+
setShowMissingElement(false);
|
|
258
|
+
setShouldShowCallout(false);
|
|
259
|
+
};
|
|
195
260
|
useEffect(() => {
|
|
196
|
-
console.log(`🚀 🐥 ~ useClickedElement ~ heatmapInfo?.elementMapInfo:`, heatmapInfo?.elementMapInfo);
|
|
197
261
|
if (!selectedElement || !heatmapInfo?.elementMapInfo) {
|
|
198
|
-
|
|
199
|
-
setShowMissingElement(false);
|
|
200
|
-
setShouldShowCallout(false);
|
|
262
|
+
reset();
|
|
201
263
|
return;
|
|
202
264
|
}
|
|
203
265
|
const info = heatmapInfo.elementMapInfo[selectedElement];
|
|
@@ -206,34 +268,22 @@ const useClickedElement = ({ heatmapInfo, getRect }) => {
|
|
|
206
268
|
return;
|
|
207
269
|
}
|
|
208
270
|
const rect = getRect({ hash: selectedElement, selector: info.selector });
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
...rect,
|
|
213
|
-
hash: selectedElement,
|
|
214
|
-
clicks: info.totalclicks ?? 0,
|
|
215
|
-
rank,
|
|
216
|
-
selector: info.selector ?? '',
|
|
217
|
-
});
|
|
271
|
+
const rank = calculateElementRank(selectedElement, heatmapInfo.sortedElements);
|
|
272
|
+
const elementInfo = buildElementInfo(selectedElement, info, rect, rank);
|
|
273
|
+
if (rect) {
|
|
218
274
|
setShowMissingElement(false);
|
|
275
|
+
scrollToElementIfNeeded(visualRef, wrapperRef, rect, scale);
|
|
219
276
|
setShouldShowCallout(true);
|
|
277
|
+
requestAnimationFrame(() => {
|
|
278
|
+
setClickedElement(elementInfo);
|
|
279
|
+
});
|
|
220
280
|
}
|
|
221
281
|
else {
|
|
222
|
-
|
|
223
|
-
setClickedElement({
|
|
224
|
-
hash: selectedElement,
|
|
225
|
-
clicks: info.totalclicks ?? 0,
|
|
226
|
-
rank,
|
|
227
|
-
selector: info.selector ?? '',
|
|
228
|
-
left: 0,
|
|
229
|
-
top: 0,
|
|
230
|
-
width: 0,
|
|
231
|
-
height: 0,
|
|
232
|
-
});
|
|
282
|
+
setClickedElement(elementInfo);
|
|
233
283
|
setShowMissingElement(true);
|
|
234
284
|
setShouldShowCallout(false);
|
|
235
285
|
}
|
|
236
|
-
}, [selectedElement, heatmapInfo, getRect]);
|
|
286
|
+
}, [selectedElement, heatmapInfo, getRect, visualRef, wrapperRef, scale]);
|
|
237
287
|
return { clickedElement, showMissingElement, shouldShowCallout, setShouldShowCallout };
|
|
238
288
|
};
|
|
239
289
|
|
|
@@ -281,8 +331,10 @@ function calculateRankPosition(rect, widthScale) {
|
|
|
281
331
|
};
|
|
282
332
|
}
|
|
283
333
|
|
|
284
|
-
const useHeatmapElementPosition = ({ iframeRef,
|
|
334
|
+
const useHeatmapElementPosition = ({ iframeRef, wrapperRef, visualizer }) => {
|
|
335
|
+
const widthScale = useHeatmapVizStore((state) => state.scale);
|
|
285
336
|
const iframeHeight = useHeatmapVizStore((state) => state.iframeHeight);
|
|
337
|
+
const heatmapWidth = useHeatmapDataStore((state) => state.config?.width);
|
|
286
338
|
return useCallback((element) => {
|
|
287
339
|
const hash = element?.hash;
|
|
288
340
|
if (!iframeRef.current?.contentDocument || !hash || !visualizer)
|
|
@@ -292,7 +344,7 @@ const useHeatmapElementPosition = ({ iframeRef, parentRef, visualizer, heatmapWi
|
|
|
292
344
|
domElement = visualizer.get(hash);
|
|
293
345
|
}
|
|
294
346
|
catch (error) {
|
|
295
|
-
console.error('Visualizer error:', {
|
|
347
|
+
console.error('Visualizer error:', { hash, error });
|
|
296
348
|
return null;
|
|
297
349
|
}
|
|
298
350
|
if (!domElement)
|
|
@@ -300,7 +352,7 @@ const useHeatmapElementPosition = ({ iframeRef, parentRef, visualizer, heatmapWi
|
|
|
300
352
|
const layout = getElementLayout(domElement);
|
|
301
353
|
if (!layout)
|
|
302
354
|
return null;
|
|
303
|
-
const parentEl =
|
|
355
|
+
const parentEl = wrapperRef.current;
|
|
304
356
|
if (!parentEl)
|
|
305
357
|
return null;
|
|
306
358
|
const scrollOffset = parentEl.scrollTop / widthScale;
|
|
@@ -316,8 +368,9 @@ const useHeatmapElementPosition = ({ iframeRef, parentRef, visualizer, heatmapWi
|
|
|
316
368
|
top: adjustedTop,
|
|
317
369
|
width: Math.min(layout.width, heatmapWidth || layout.width),
|
|
318
370
|
height: layout.height,
|
|
371
|
+
outOfBounds,
|
|
319
372
|
};
|
|
320
|
-
}, [iframeRef,
|
|
373
|
+
}, [iframeRef, wrapperRef, visualizer, heatmapWidth, iframeHeight, widthScale]);
|
|
321
374
|
};
|
|
322
375
|
|
|
323
376
|
const debounce = (fn, delay) => {
|
|
@@ -327,10 +380,12 @@ const debounce = (fn, delay) => {
|
|
|
327
380
|
timeout = setTimeout(() => fn(...args), delay);
|
|
328
381
|
};
|
|
329
382
|
};
|
|
330
|
-
const useHoveredElement = ({ iframeRef,
|
|
383
|
+
const useHoveredElement = ({ iframeRef, getRect }) => {
|
|
331
384
|
const hoveredElement = useHeatmapInteractionStore((state) => state.hoveredElement);
|
|
332
385
|
const setHoveredElement = useHeatmapInteractionStore((state) => state.setHoveredElement);
|
|
333
386
|
const onSelect = useHeatmapInteractionStore((state) => state.setSelectedElement);
|
|
387
|
+
const widthScale = useHeatmapVizStore((state) => state.scale);
|
|
388
|
+
const heatmapInfo = useHeatmapDataStore((state) => state.dataInfo);
|
|
334
389
|
const handleMouseMove = useCallback(debounce((event) => {
|
|
335
390
|
if (!iframeRef.current?.contentDocument || !heatmapInfo?.elementMapInfo) {
|
|
336
391
|
setHoveredElement(null);
|
|
@@ -422,6 +477,15 @@ const useHeatmapRender = () => {
|
|
|
422
477
|
if (!iframe?.contentWindow)
|
|
423
478
|
return;
|
|
424
479
|
await visualizer.html(payloads, iframe.contentWindow);
|
|
480
|
+
// iframe.contentDocument?.body.querySelectorAll('body>*').forEach((element) => {
|
|
481
|
+
// console.log(`🚀 🐥 ~ useHeatmapRender ~ element:`, element);
|
|
482
|
+
// const isClosedEcomsendWidget = element.closest('#ecomsend-widget');
|
|
483
|
+
// const isEcomsendWidget = element.querySelector('#ecomsend-widget');
|
|
484
|
+
// const isRemove = !(isClosedEcomsendWidget || isEcomsendWidget);
|
|
485
|
+
// if (isRemove) {
|
|
486
|
+
// element.remove();
|
|
487
|
+
// }
|
|
488
|
+
// });
|
|
425
489
|
setVizRef(visualizer);
|
|
426
490
|
}, []);
|
|
427
491
|
useEffect(() => {
|
|
@@ -608,15 +672,16 @@ const useContainerDimensions = (props) => {
|
|
|
608
672
|
};
|
|
609
673
|
|
|
610
674
|
const useContentDimensions = (props) => {
|
|
611
|
-
const
|
|
675
|
+
const contentWidth = useHeatmapDataStore((state) => state.config?.width ?? 0);
|
|
676
|
+
const { iframeRef } = props;
|
|
612
677
|
useEffect(() => {
|
|
613
|
-
if (!
|
|
678
|
+
if (!contentWidth)
|
|
614
679
|
return;
|
|
615
680
|
if (!iframeRef.current)
|
|
616
681
|
return;
|
|
617
|
-
iframeRef.current.width = `${
|
|
618
|
-
}, [
|
|
619
|
-
return { contentWidth
|
|
682
|
+
iframeRef.current.width = `${contentWidth}px`;
|
|
683
|
+
}, [contentWidth, iframeRef]);
|
|
684
|
+
return { contentWidth };
|
|
620
685
|
};
|
|
621
686
|
|
|
622
687
|
// Hook 3: Iframe Height Observer
|
|
@@ -725,45 +790,44 @@ const useScaleCalculation = (props) => {
|
|
|
725
790
|
return { scale };
|
|
726
791
|
};
|
|
727
792
|
|
|
728
|
-
const useScrollSync = (
|
|
729
|
-
const
|
|
793
|
+
const useScrollSync = ({ iframeRef }) => {
|
|
794
|
+
const widthScale = useHeatmapVizStore((state) => state.scale);
|
|
730
795
|
const handleScroll = useCallback((scrollTop) => {
|
|
731
796
|
const iframe = iframeRef.current;
|
|
732
|
-
if (!iframe ||
|
|
797
|
+
if (!iframe || widthScale <= 0)
|
|
733
798
|
return;
|
|
734
799
|
try {
|
|
735
800
|
const iframeWindow = iframe.contentWindow;
|
|
736
801
|
const iframeDocument = iframe.contentDocument;
|
|
737
802
|
if (iframeWindow && iframeDocument) {
|
|
738
|
-
const iframeScrollTop = scrollTop /
|
|
803
|
+
const iframeScrollTop = scrollTop / widthScale;
|
|
739
804
|
iframe.style.top = `${iframeScrollTop}px`;
|
|
805
|
+
// iframeWindow.scrollTo({ top: iframeScrollTop, behavior: 'smooth' });
|
|
740
806
|
}
|
|
741
807
|
}
|
|
742
808
|
catch (error) {
|
|
743
809
|
console.warn('Cannot sync scroll to iframe:', error);
|
|
744
810
|
}
|
|
745
|
-
}, [iframeRef,
|
|
811
|
+
}, [iframeRef, widthScale]);
|
|
746
812
|
return { handleScroll };
|
|
747
813
|
};
|
|
748
814
|
|
|
749
815
|
const useHeatmapScale = (props) => {
|
|
750
|
-
const { wrapperRef, iframeRef,
|
|
816
|
+
const { wrapperRef, iframeRef, visualRef } = props;
|
|
751
817
|
// 1. Observe container dimensions
|
|
752
818
|
const { containerWidth, containerHeight } = useContainerDimensions({ wrapperRef });
|
|
753
819
|
// 2. Get content dimensions from config
|
|
754
|
-
const { contentWidth } = useContentDimensions({ iframeRef
|
|
820
|
+
const { contentWidth } = useContentDimensions({ iframeRef });
|
|
755
821
|
// 3. Observe iframe height (now reacts to width changes)
|
|
756
822
|
const { iframeHeight } = useIframeHeight({ iframeRef, contentWidth });
|
|
757
823
|
// 4. Calculate scale
|
|
758
824
|
const { scale } = useScaleCalculation({ containerWidth, contentWidth });
|
|
759
825
|
// 5. Setup scroll sync
|
|
760
|
-
const { handleScroll } = useScrollSync({ iframeRef
|
|
826
|
+
const { handleScroll } = useScrollSync({ iframeRef });
|
|
761
827
|
return {
|
|
762
828
|
containerWidth,
|
|
763
829
|
containerHeight,
|
|
764
|
-
contentWidth,
|
|
765
830
|
iframeHeight,
|
|
766
|
-
scale,
|
|
767
831
|
scaledWidth: contentWidth * scale,
|
|
768
832
|
scaledHeight: iframeHeight * scale,
|
|
769
833
|
handleScroll,
|
|
@@ -853,13 +917,16 @@ const SECONDARY_CLICKED_ELEMENT_ID = 'secondaryClickedElementID';
|
|
|
853
917
|
const HOVERED_ELEMENT_ID = 'hoveredElement';
|
|
854
918
|
const SECONDARY_HOVERED_ELEMENT_ID = 'secondaryhoveredElementID';
|
|
855
919
|
|
|
856
|
-
const ElementCallout = (
|
|
920
|
+
const ElementCallout = (props) => {
|
|
921
|
+
const { element, target, isSecondary, language, wrapperRef } = props;
|
|
922
|
+
const heatmapInfo = useHeatmapDataStore((state) => state.dataInfo);
|
|
857
923
|
const calloutRef = useRef(null);
|
|
858
924
|
const [position, setPosition] = useState({
|
|
859
925
|
top: 0,
|
|
860
926
|
left: 0,
|
|
861
927
|
placement: 'top',
|
|
862
928
|
});
|
|
929
|
+
const totalClicks = heatmapInfo?.totalClicks ?? 1;
|
|
863
930
|
const percentage = formatPercentage(((element.clicks ?? 0) / totalClicks) * 100, 2);
|
|
864
931
|
useEffect(() => {
|
|
865
932
|
const targetElement = document.querySelector(target);
|
|
@@ -918,163 +985,20 @@ const ElementCallout = ({ element, target, totalClicks, isSecondary, isRecording
|
|
|
918
985
|
};
|
|
919
986
|
window.addEventListener('scroll', handleUpdate, true);
|
|
920
987
|
window.addEventListener('resize', handleUpdate);
|
|
921
|
-
|
|
988
|
+
wrapperRef?.current?.addEventListener('scroll', handleUpdate);
|
|
922
989
|
return () => {
|
|
923
990
|
window.removeEventListener('scroll', handleUpdate, true);
|
|
924
991
|
window.removeEventListener('resize', handleUpdate);
|
|
925
|
-
|
|
992
|
+
wrapperRef?.current?.removeEventListener('scroll', handleUpdate);
|
|
926
993
|
};
|
|
927
|
-
}, [target,
|
|
994
|
+
}, [target, wrapperRef]);
|
|
928
995
|
const calloutContent = (jsxs("div", { ref: calloutRef, className: `clarity-callout clarity-callout--${position.placement} ${isSecondary ? 'clarity-callout--secondary' : ''}`, style: {
|
|
929
996
|
position: 'fixed',
|
|
930
997
|
top: position.top,
|
|
931
998
|
left: position.left,
|
|
932
999
|
zIndex: 2147483647,
|
|
933
|
-
}, "aria-live": "assertive", role: "tooltip", children: [jsx("div", { className: "clarity-callout__arrow" }), jsx("div", { className: "clarity-callout__content", children: jsxs("div", { className: "clarity-callout__stats", children: [jsx("div", { className: "clarity-callout__label", children: "Clicks" }), jsxs("div", { className: "clarity-callout__value", children: [jsx("span", { className: "clarity-callout__count", children: element.clicks?.toLocaleString(language) }), jsxs("span", { className: "clarity-callout__percentage", children: ["(", percentage, "%)"] })] })] }) })
|
|
934
|
-
|
|
935
|
-
background: white;
|
|
936
|
-
border-radius: 8px;
|
|
937
|
-
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
|
938
|
-
padding: 16px;
|
|
939
|
-
min-width: 200px;
|
|
940
|
-
max-width: 280px;
|
|
941
|
-
animation: clarity-callout-fade-in 0.2s ease-out;
|
|
942
|
-
pointer-events: auto;
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
@keyframes clarity-callout-fade-in {
|
|
946
|
-
from {
|
|
947
|
-
opacity: 0;
|
|
948
|
-
transform: scale(0.95);
|
|
949
|
-
}
|
|
950
|
-
to {
|
|
951
|
-
opacity: 1;
|
|
952
|
-
transform: scale(1);
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
.clarity-callout__arrow {
|
|
957
|
-
position: absolute;
|
|
958
|
-
width: 16px;
|
|
959
|
-
height: 16px;
|
|
960
|
-
background: white;
|
|
961
|
-
transform: rotate(45deg);
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
/* Arrow positions */
|
|
965
|
-
.clarity-callout--top .clarity-callout__arrow {
|
|
966
|
-
bottom: -8px;
|
|
967
|
-
left: 50%;
|
|
968
|
-
margin-left: -8px;
|
|
969
|
-
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
.clarity-callout--bottom .clarity-callout__arrow {
|
|
973
|
-
top: -8px;
|
|
974
|
-
left: 50%;
|
|
975
|
-
margin-left: -8px;
|
|
976
|
-
box-shadow: -2px -2px 4px rgba(0, 0, 0, 0.1);
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
.clarity-callout--left .clarity-callout__arrow {
|
|
980
|
-
right: -8px;
|
|
981
|
-
top: 50%;
|
|
982
|
-
margin-top: -8px;
|
|
983
|
-
box-shadow: 2px -2px 4px rgba(0, 0, 0, 0.1);
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
.clarity-callout--right .clarity-callout__arrow {
|
|
987
|
-
left: -8px;
|
|
988
|
-
top: 50%;
|
|
989
|
-
margin-top: -8px;
|
|
990
|
-
box-shadow: -2px 2px 4px rgba(0, 0, 0, 0.1);
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
.clarity-callout__content {
|
|
994
|
-
position: relative;
|
|
995
|
-
z-index: 1;
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
.clarity-callout__rank {
|
|
999
|
-
display: inline-flex;
|
|
1000
|
-
align-items: center;
|
|
1001
|
-
justify-content: center;
|
|
1002
|
-
width: 32px;
|
|
1003
|
-
height: 32px;
|
|
1004
|
-
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
1005
|
-
color: white;
|
|
1006
|
-
border-radius: 8px;
|
|
1007
|
-
font-weight: 600;
|
|
1008
|
-
font-size: 16px;
|
|
1009
|
-
margin-bottom: 12px;
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
.clarity-callout--secondary .clarity-callout__rank {
|
|
1013
|
-
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
.clarity-callout__stats {
|
|
1017
|
-
margin-bottom: 12px;
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
.clarity-callout__label {
|
|
1021
|
-
font-size: 12px;
|
|
1022
|
-
color: #6b7280;
|
|
1023
|
-
margin-bottom: 4px;
|
|
1024
|
-
font-weight: 500;
|
|
1025
|
-
}
|
|
1026
|
-
|
|
1027
|
-
.clarity-callout__value {
|
|
1028
|
-
display: flex;
|
|
1029
|
-
align-items: baseline;
|
|
1030
|
-
gap: 6px;
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
.clarity-callout__count {
|
|
1034
|
-
font-size: 20px;
|
|
1035
|
-
font-weight: 700;
|
|
1036
|
-
color: #111827;
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
.clarity-callout__percentage {
|
|
1040
|
-
font-size: 14px;
|
|
1041
|
-
color: #6b7280;
|
|
1042
|
-
font-weight: 500;
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
.clarity-callout__button {
|
|
1046
|
-
display: flex;
|
|
1047
|
-
align-items: center;
|
|
1048
|
-
justify-content: center;
|
|
1049
|
-
gap: 6px;
|
|
1050
|
-
width: 100%;
|
|
1051
|
-
padding: 8px 12px;
|
|
1052
|
-
background: #667eea;
|
|
1053
|
-
color: white;
|
|
1054
|
-
border: none;
|
|
1055
|
-
border-radius: 6px;
|
|
1056
|
-
font-size: 13px;
|
|
1057
|
-
font-weight: 600;
|
|
1058
|
-
cursor: pointer;
|
|
1059
|
-
transition: all 0.2s;
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
|
-
.clarity-callout__button:hover {
|
|
1063
|
-
background: #5568d3;
|
|
1064
|
-
transform: translateY(-1px);
|
|
1065
|
-
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.4);
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
.clarity-callout__button:active {
|
|
1069
|
-
transform: translateY(0);
|
|
1070
|
-
}
|
|
1071
|
-
|
|
1072
|
-
.clarity-callout__button svg {
|
|
1073
|
-
width: 14px;
|
|
1074
|
-
height: 14px;
|
|
1075
|
-
}
|
|
1076
|
-
` })] }));
|
|
1077
|
-
return createPortal(calloutContent, document.body);
|
|
1000
|
+
}, "aria-live": "assertive", role: "tooltip", children: [jsx("div", { className: "clarity-callout__arrow" }), jsx("div", { className: "clarity-callout__content", children: jsxs("div", { className: "clarity-callout__stats", children: [jsx("div", { className: "clarity-callout__label", children: "Clicks" }), jsxs("div", { className: "clarity-callout__value", children: [jsx("span", { className: "clarity-callout__count", children: element.clicks?.toLocaleString(language) }), jsxs("span", { className: "clarity-callout__percentage", children: ["(", percentage, "%)"] })] })] }) })] }));
|
|
1001
|
+
return createPortal(calloutContent, document.getElementById('gx-hm-viz-container'));
|
|
1078
1002
|
};
|
|
1079
1003
|
|
|
1080
1004
|
const RankBadge = ({ index, elementRect, widthScale, clickOnElement, }) => {
|
|
@@ -1082,7 +1006,8 @@ const RankBadge = ({ index, elementRect, widthScale, clickOnElement, }) => {
|
|
|
1082
1006
|
return (jsx("div", { className: "rankBadge", style: style, onClick: clickOnElement, "data-testid": "elementRank", children: index }));
|
|
1083
1007
|
};
|
|
1084
1008
|
|
|
1085
|
-
const ClickedElementOverlay = ({ element, shouldShowCallout, isSecondary, targetId,
|
|
1009
|
+
const ClickedElementOverlay = ({ element, shouldShowCallout, isSecondary, targetId, }) => {
|
|
1010
|
+
const widthScale = useHeatmapVizStore((state) => state.scale);
|
|
1086
1011
|
if (!element || (element.width === 0 && element.height === 0))
|
|
1087
1012
|
return null;
|
|
1088
1013
|
return (jsxs(Fragment$1, { children: [jsx("div", { className: "heatmapElement", id: targetId, style: {
|
|
@@ -1090,10 +1015,14 @@ const ClickedElementOverlay = ({ element, shouldShowCallout, isSecondary, target
|
|
|
1090
1015
|
left: element.left,
|
|
1091
1016
|
width: element.width,
|
|
1092
1017
|
height: element.height,
|
|
1093
|
-
} }), jsx(RankBadge, { index: element.rank, elementRect: element, widthScale: widthScale }), shouldShowCallout && (jsx(ElementCallout, { element: element, target: `#${targetId}`,
|
|
1018
|
+
} }), jsx(RankBadge, { index: element.rank, elementRect: element, widthScale: widthScale }), shouldShowCallout && (jsx(ElementCallout, { element: element, target: `#${targetId}`, isSecondary: isSecondary }))] }));
|
|
1094
1019
|
};
|
|
1095
1020
|
|
|
1096
|
-
const
|
|
1021
|
+
const NUMBER_OF_TOP_ELEMENTS = 10;
|
|
1022
|
+
const DefaultRankBadges = ({ getRect, hidden }) => {
|
|
1023
|
+
const heatmapInfo = useHeatmapDataStore((state) => state.dataInfo);
|
|
1024
|
+
const widthScale = useHeatmapVizStore((state) => state.scale);
|
|
1025
|
+
const elements = heatmapInfo?.sortedElements?.slice(0, NUMBER_OF_TOP_ELEMENTS) ?? [];
|
|
1097
1026
|
if (hidden || elements.length === 0)
|
|
1098
1027
|
return null;
|
|
1099
1028
|
return (jsx(Fragment, { children: elements.map((element, index) => {
|
|
@@ -1104,19 +1033,25 @@ const DefaultRankBadges = ({ elements, getRect, widthScale, hidden }) => {
|
|
|
1104
1033
|
}) }));
|
|
1105
1034
|
};
|
|
1106
1035
|
|
|
1107
|
-
const HoveredElementOverlay = ({ element, onClick, isSecondary, targetId,
|
|
1036
|
+
const HoveredElementOverlay = ({ element, onClick, isSecondary, targetId, }) => {
|
|
1108
1037
|
if (!element)
|
|
1109
1038
|
return null;
|
|
1039
|
+
// Iframe has border, so we need to add it to the top position
|
|
1040
|
+
const top = element.top + HEATMAP_CONFIG['borderWidthIframe'];
|
|
1041
|
+
const left = element.left + HEATMAP_CONFIG['borderWidthIframe'];
|
|
1042
|
+
const width = element.width;
|
|
1043
|
+
const height = element.height;
|
|
1110
1044
|
return (jsxs(Fragment$1, { children: [jsx("div", { onClick: onClick, className: "heatmapElement hovered", id: targetId, style: {
|
|
1111
|
-
top
|
|
1112
|
-
left
|
|
1113
|
-
width
|
|
1114
|
-
height
|
|
1045
|
+
top,
|
|
1046
|
+
left,
|
|
1047
|
+
width,
|
|
1048
|
+
height,
|
|
1115
1049
|
cursor: 'pointer',
|
|
1116
1050
|
} }), jsx(RankBadge, { index: element.rank, elementRect: element, widthScale: 1, clickOnElement: onClick })] }));
|
|
1117
1051
|
};
|
|
1118
1052
|
|
|
1119
|
-
const MissingElementMessage = (
|
|
1053
|
+
const MissingElementMessage = () => {
|
|
1054
|
+
const widthScale = useHeatmapVizStore((state) => state.scale);
|
|
1120
1055
|
return (jsx("div", { className: "missingElement", style: {
|
|
1121
1056
|
position: 'absolute',
|
|
1122
1057
|
top: '50%',
|
|
@@ -1136,25 +1071,21 @@ const MissingElementMessage = ({ widthScale }) => {
|
|
|
1136
1071
|
|
|
1137
1072
|
const HeatmapElements = (props) => {
|
|
1138
1073
|
const height = useHeatmapVizStore((state) => state.iframeHeight);
|
|
1139
|
-
const {
|
|
1074
|
+
const { iframeRef, wrapperRef, visualRef, visualizer, iframeDimensions, isElementSidebarOpen, isVisible = true, areDefaultRanksHidden, isSecondary, ...rest } = props;
|
|
1140
1075
|
const getRect = useHeatmapElementPosition({
|
|
1141
1076
|
iframeRef,
|
|
1142
|
-
|
|
1077
|
+
wrapperRef,
|
|
1143
1078
|
visualizer,
|
|
1144
|
-
heatmapWidth: heatmapInfo?.width,
|
|
1145
|
-
widthScale,
|
|
1146
|
-
projectId: props.projectId,
|
|
1147
1079
|
});
|
|
1148
1080
|
const { clickedElement, showMissingElement, shouldShowCallout, setShouldShowCallout } = useClickedElement({
|
|
1149
|
-
|
|
1081
|
+
iframeRef,
|
|
1082
|
+
visualRef,
|
|
1083
|
+
wrapperRef,
|
|
1150
1084
|
getRect,
|
|
1151
1085
|
});
|
|
1152
|
-
console.log(`🚀 🐥 ~ HeatmapElements ~ clickedElement:`, clickedElement);
|
|
1153
1086
|
const { hoveredElement, handleMouseMove, handleMouseLeave, handleClick } = useHoveredElement({
|
|
1154
1087
|
iframeRef,
|
|
1155
|
-
heatmapInfo,
|
|
1156
1088
|
getRect,
|
|
1157
|
-
widthScale,
|
|
1158
1089
|
});
|
|
1159
1090
|
const resetAll = () => {
|
|
1160
1091
|
// setShouldShowCallout(false);
|
|
@@ -1167,12 +1098,12 @@ const HeatmapElements = (props) => {
|
|
|
1167
1098
|
});
|
|
1168
1099
|
if (!isVisible)
|
|
1169
1100
|
return null;
|
|
1170
|
-
|
|
1171
|
-
return (jsxs("div", { onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, className: "heatmapElements gx-hm-elements", style: { ...iframeDimensions, height }, children: [jsx(DefaultRankBadges, { elements: top10, getRect: getRect, widthScale: widthScale, hidden: areDefaultRanksHidden }), jsx(ClickedElementOverlay, { widthScale: widthScale, element: clickedElement, shouldShowCallout: shouldShowCallout, isSecondary: isSecondary, targetId: isSecondary ? SECONDARY_CLICKED_ELEMENT_ID : CLICKED_ELEMENT_ID, ...rest }), showMissingElement && jsx(MissingElementMessage, { widthScale: widthScale }), jsx(HoveredElementOverlay, { element: hoveredElement, onClick: handleClick, isSecondary: isSecondary, targetId: isSecondary ? SECONDARY_HOVERED_ELEMENT_ID : HOVERED_ELEMENT_ID, totalClicks: heatmapInfo?.totalClicks ?? 1 }), hoveredElement?.hash !== clickedElement?.hash && hoveredElement && (jsx(ElementCallout, { element: hoveredElement, target: `#${props.isSecondary ? SECONDARY_HOVERED_ELEMENT_ID : HOVERED_ELEMENT_ID}`, totalClicks: props.heatmapInfo?.totalClicks ?? 1, isSecondary: props.isSecondary, parentRef: props.parentRef }))] }));
|
|
1101
|
+
return (jsxs("div", { onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave, className: "heatmapElements gx-hm-elements", style: { ...iframeDimensions, height }, children: [jsx(DefaultRankBadges, { getRect: getRect, hidden: areDefaultRanksHidden }), jsx(ClickedElementOverlay, { element: clickedElement, shouldShowCallout: shouldShowCallout, isSecondary: isSecondary, targetId: isSecondary ? SECONDARY_CLICKED_ELEMENT_ID : CLICKED_ELEMENT_ID, ...rest }), showMissingElement && jsx(MissingElementMessage, {}), jsx(HoveredElementOverlay, { element: hoveredElement, onClick: handleClick, isSecondary: isSecondary, targetId: isSecondary ? SECONDARY_HOVERED_ELEMENT_ID : HOVERED_ELEMENT_ID }), hoveredElement?.hash !== clickedElement?.hash && hoveredElement && (jsx(ElementCallout, { element: hoveredElement, target: `#${props.isSecondary ? SECONDARY_HOVERED_ELEMENT_ID : HOVERED_ELEMENT_ID}`, isSecondary: props.isSecondary, wrapperRef: props.wrapperRef }))] }));
|
|
1172
1102
|
};
|
|
1173
1103
|
|
|
1174
|
-
const VizElements = ({
|
|
1104
|
+
const VizElements = ({ iframeRef, visualRef, wrapperRef }) => {
|
|
1175
1105
|
const heatmapInfo = useHeatmapDataStore((state) => state.dataInfo);
|
|
1106
|
+
const contentWidth = useHeatmapDataStore((state) => state.config?.width ?? 0);
|
|
1176
1107
|
const visualizer = {
|
|
1177
1108
|
get: (hash) => {
|
|
1178
1109
|
const doc = iframeRef.current?.contentDocument;
|
|
@@ -1191,8 +1122,8 @@ const VizElements = ({ width, iframeRef, wrapperRef, widthScale, }) => {
|
|
|
1191
1122
|
};
|
|
1192
1123
|
if (!iframeRef.current)
|
|
1193
1124
|
return null;
|
|
1194
|
-
return (jsx(HeatmapElements, { visualizer: visualizer,
|
|
1195
|
-
width,
|
|
1125
|
+
return (jsx(HeatmapElements, { visualizer: visualizer, visualRef: visualRef, iframeRef: iframeRef, wrapperRef: wrapperRef, heatmapInfo: heatmapInfo, isVisible: true, iframeDimensions: {
|
|
1126
|
+
width: contentWidth,
|
|
1196
1127
|
position: 'absolute',
|
|
1197
1128
|
top: 0,
|
|
1198
1129
|
left: 0,
|
|
@@ -1232,14 +1163,20 @@ const ReplayControls = () => {
|
|
|
1232
1163
|
const VizDomRenderer = ({ mode = 'heatmap' }) => {
|
|
1233
1164
|
const config = useHeatmapDataStore((state) => state.config);
|
|
1234
1165
|
const setIframeHeight = useHeatmapVizStore((state) => state.setIframeHeight);
|
|
1166
|
+
const widthScale = useHeatmapVizStore((state) => state.scale);
|
|
1167
|
+
const setSelectedElement = useHeatmapInteractionStore((state) => state.setSelectedElement);
|
|
1235
1168
|
const wrapperRef = useRef(null);
|
|
1236
1169
|
const visualRef = useRef(null);
|
|
1237
1170
|
const { iframeRef } = useHeatmapVizRender(mode);
|
|
1238
|
-
const {
|
|
1171
|
+
const { iframeHeight, scaledHeight, handleScroll } = useHeatmapScale({
|
|
1239
1172
|
wrapperRef,
|
|
1240
1173
|
iframeRef,
|
|
1241
|
-
|
|
1174
|
+
visualRef,
|
|
1242
1175
|
});
|
|
1176
|
+
const contentWidth = config?.width ?? 0;
|
|
1177
|
+
const contentHeight = scaledHeight > 0
|
|
1178
|
+
? `${scaledHeight + HEATMAP_CONFIG['heightToolbar'] + HEATMAP_CONFIG['padding'] * 2}px`
|
|
1179
|
+
: 'auto';
|
|
1243
1180
|
const onScroll = (e) => {
|
|
1244
1181
|
const scrollTop = e.currentTarget.scrollTop;
|
|
1245
1182
|
handleScroll(scrollTop);
|
|
@@ -1247,6 +1184,7 @@ const VizDomRenderer = ({ mode = 'heatmap' }) => {
|
|
|
1247
1184
|
useHeatmapVizCanvas({ type: config?.heatmapType });
|
|
1248
1185
|
const cleanUp = () => {
|
|
1249
1186
|
setIframeHeight(0);
|
|
1187
|
+
setSelectedElement(null);
|
|
1250
1188
|
};
|
|
1251
1189
|
useEffect(() => {
|
|
1252
1190
|
return cleanUp;
|
|
@@ -1264,17 +1202,17 @@ const VizDomRenderer = ({ mode = 'heatmap' }) => {
|
|
|
1264
1202
|
display: 'flex',
|
|
1265
1203
|
justifyContent: 'center',
|
|
1266
1204
|
alignItems: 'flex-start',
|
|
1267
|
-
height:
|
|
1205
|
+
height: contentHeight,
|
|
1268
1206
|
padding: HEATMAP_STYLE['wrapper']['padding'],
|
|
1269
1207
|
paddingBottom: HEATMAP_STYLE['viz']['paddingBottom'],
|
|
1270
1208
|
background: HEATMAP_STYLE['viz']['background'],
|
|
1271
1209
|
}, children: jsxs("div", { className: "gx-hm-wrapper", ref: wrapperRef, style: {
|
|
1272
1210
|
width: contentWidth,
|
|
1273
1211
|
height: iframeHeight,
|
|
1274
|
-
transform: `scale(${
|
|
1212
|
+
transform: `scale(${widthScale})`,
|
|
1275
1213
|
transformOrigin: 'top center',
|
|
1276
1214
|
paddingBlockEnd: '0',
|
|
1277
|
-
}, children: [jsx(VizElements, {
|
|
1215
|
+
}, children: [jsx(VizElements, { iframeRef: iframeRef, visualRef: visualRef, wrapperRef: wrapperRef }), jsx("iframe", { ref: iframeRef, ...HEATMAP_IFRAME, width: contentWidth, height: iframeHeight, scrolling: "no" })] }) }), mode === 'replay' && jsx(ReplayControls, {})] }));
|
|
1278
1216
|
};
|
|
1279
1217
|
|
|
1280
1218
|
const VizDomContainer = () => {
|
|
@@ -1296,7 +1234,14 @@ const ContentMetricBar = () => {
|
|
|
1296
1234
|
|
|
1297
1235
|
const ContentToolbar = () => {
|
|
1298
1236
|
const controls = useHeatmapControlStore((state) => state.controls);
|
|
1299
|
-
return (jsx("div", { id: "gx-hm-content-toolbar", style: {
|
|
1237
|
+
return (jsx("div", { id: "gx-hm-content-toolbar", style: {
|
|
1238
|
+
position: 'absolute',
|
|
1239
|
+
bottom: 0,
|
|
1240
|
+
left: '8px',
|
|
1241
|
+
right: '24px',
|
|
1242
|
+
padding: '8px',
|
|
1243
|
+
paddingBlock: '16px',
|
|
1244
|
+
}, children: controls.Toolbar ?? null }));
|
|
1300
1245
|
};
|
|
1301
1246
|
|
|
1302
1247
|
const LeftSidebar = () => {
|
|
@@ -1344,6 +1289,7 @@ const HeatmapLayout = ({ data, clickmap, controls, dataInfo, }) => {
|
|
|
1344
1289
|
function getVariableStyle() {
|
|
1345
1290
|
return {
|
|
1346
1291
|
'--gx-hm-border-width': `${HEATMAP_CONFIG.borderWidth}px`,
|
|
1292
|
+
'--gx-hm-border-width-iframe': `${HEATMAP_CONFIG.borderWidthIframe}px`,
|
|
1347
1293
|
'--gx-hm-border-color': `${HEATMAP_CONFIG.borderColor}`,
|
|
1348
1294
|
};
|
|
1349
1295
|
}
|
|
@@ -1367,4 +1313,4 @@ var ErrorType;
|
|
|
1367
1313
|
ErrorType["DataError"] = "DataError";
|
|
1368
1314
|
})(ErrorType || (ErrorType = {}));
|
|
1369
1315
|
|
|
1370
|
-
export { GraphView, HeatmapLayout, IHeatmapType, useHeatmapDataStore };
|
|
1316
|
+
export { GraphView, HeatmapLayout, IHeatmapType, useHeatmapDataStore, useHeatmapInteractionStore };
|