@gemx-dev/heatmap-react 3.5.37 → 3.5.39
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/ContentTopBar.d.ts.map +1 -1
- package/dist/esm/components/Layout/ContentVizByMode.d.ts +2 -0
- package/dist/esm/components/Layout/ContentVizByMode.d.ts.map +1 -0
- package/dist/esm/components/Layout/LeftSidebar.d.ts.map +1 -1
- package/dist/esm/components/VizDom/VizContainer.d.ts +7 -0
- package/dist/esm/components/VizDom/VizContainer.d.ts.map +1 -0
- package/dist/esm/components/VizDom/VizDomHeatmap.d.ts +2 -0
- package/dist/esm/components/VizDom/VizDomHeatmap.d.ts.map +1 -0
- package/dist/esm/components/VizDom/VizDomRenderer.d.ts.map +1 -1
- package/dist/esm/components/VizDom/VizLoading.d.ts +2 -0
- package/dist/esm/components/VizDom/VizLoading.d.ts.map +1 -0
- package/dist/esm/components/VizDom/WrapperVisual.d.ts +11 -0
- package/dist/esm/components/VizDom/WrapperVisual.d.ts.map +1 -0
- package/dist/esm/components/VizDom/index.d.ts +4 -1
- package/dist/esm/components/VizDom/index.d.ts.map +1 -1
- package/dist/esm/components/VizLive/VizLiveHeatmap.d.ts +2 -0
- package/dist/esm/components/VizLive/VizLiveHeatmap.d.ts.map +1 -0
- package/dist/esm/components/VizLive/VizLiveRenderer.d.ts +2 -0
- package/dist/esm/components/VizLive/VizLiveRenderer.d.ts.map +1 -0
- package/dist/esm/components/VizLive/index.d.ts +2 -0
- package/dist/esm/components/VizLive/index.d.ts.map +1 -0
- package/dist/esm/components/index.d.ts +0 -1
- package/dist/esm/components/index.d.ts.map +1 -1
- package/dist/esm/helpers/iframe.d.ts +16 -2
- package/dist/esm/helpers/iframe.d.ts.map +1 -1
- package/dist/esm/helpers/viewport-fixer.d.ts.map +1 -1
- package/dist/esm/helpers/viewport-replacer.d.ts +5 -5
- package/dist/esm/helpers/viewport-replacer.d.ts.map +1 -1
- package/dist/esm/hooks/index.d.ts +1 -0
- package/dist/esm/hooks/index.d.ts.map +1 -1
- package/dist/esm/hooks/register/useRegisterConfig.d.ts.map +1 -1
- package/dist/esm/hooks/viz-canvas/useHeatmapVizCanvas.d.ts +1 -4
- package/dist/esm/hooks/viz-canvas/useHeatmapVizCanvas.d.ts.map +1 -1
- package/dist/esm/hooks/viz-live/index.d.ts +2 -0
- package/dist/esm/hooks/viz-live/index.d.ts.map +1 -0
- package/dist/esm/hooks/viz-live/useIframeMessage.d.ts +27 -0
- 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/index.d.ts +1 -0
- package/dist/esm/hooks/viz-scale/index.d.ts.map +1 -1
- package/dist/esm/hooks/viz-scale/useContentDimensions.d.ts.map +1 -1
- package/dist/esm/hooks/viz-scale/useHeatmapScale.d.ts +2 -1
- package/dist/esm/hooks/viz-scale/useHeatmapScale.d.ts.map +1 -1
- package/dist/esm/hooks/viz-scale/useIframeHeight.d.ts +2 -1
- package/dist/esm/hooks/viz-scale/useIframeHeight.d.ts.map +1 -1
- package/dist/esm/hooks/viz-scale/useWrapperRefHeight.d.ts +11 -0
- package/dist/esm/hooks/viz-scale/useWrapperRefHeight.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 +451 -195
- package/dist/esm/index.mjs +451 -195
- package/dist/esm/stores/config.d.ts +14 -0
- package/dist/esm/stores/config.d.ts.map +1 -0
- package/dist/esm/stores/data.d.ts +1 -4
- package/dist/esm/stores/data.d.ts.map +1 -1
- package/dist/esm/stores/index.d.ts +2 -0
- package/dist/esm/stores/index.d.ts.map +1 -1
- package/dist/esm/stores/mode-live.d.ts +16 -0
- package/dist/esm/stores/mode-live.d.ts.map +1 -0
- package/dist/esm/types/control.d.ts +1 -1
- package/dist/esm/types/control.d.ts.map +1 -1
- package/dist/esm/types/viewport-fixer.d.ts +4 -2
- package/dist/esm/types/viewport-fixer.d.ts.map +1 -1
- package/dist/umd/components/Layout/ContentTopBar.d.ts.map +1 -1
- package/dist/umd/components/Layout/ContentVizByMode.d.ts +2 -0
- package/dist/umd/components/Layout/ContentVizByMode.d.ts.map +1 -0
- package/dist/umd/components/Layout/LeftSidebar.d.ts.map +1 -1
- package/dist/umd/components/VizDom/VizContainer.d.ts +7 -0
- package/dist/umd/components/VizDom/VizContainer.d.ts.map +1 -0
- package/dist/umd/components/VizDom/VizDomHeatmap.d.ts +2 -0
- package/dist/umd/components/VizDom/VizDomHeatmap.d.ts.map +1 -0
- package/dist/umd/components/VizDom/VizDomRenderer.d.ts.map +1 -1
- package/dist/umd/components/VizDom/VizLoading.d.ts +2 -0
- package/dist/umd/components/VizDom/VizLoading.d.ts.map +1 -0
- package/dist/umd/components/VizDom/WrapperVisual.d.ts +11 -0
- package/dist/umd/components/VizDom/WrapperVisual.d.ts.map +1 -0
- package/dist/umd/components/VizDom/index.d.ts +4 -1
- package/dist/umd/components/VizDom/index.d.ts.map +1 -1
- package/dist/umd/components/VizLive/VizLiveHeatmap.d.ts +2 -0
- package/dist/umd/components/VizLive/VizLiveHeatmap.d.ts.map +1 -0
- package/dist/umd/components/VizLive/VizLiveRenderer.d.ts +2 -0
- package/dist/umd/components/VizLive/VizLiveRenderer.d.ts.map +1 -0
- package/dist/umd/components/VizLive/index.d.ts +2 -0
- package/dist/umd/components/VizLive/index.d.ts.map +1 -0
- package/dist/umd/components/index.d.ts +0 -1
- package/dist/umd/components/index.d.ts.map +1 -1
- package/dist/umd/helpers/iframe.d.ts +16 -2
- package/dist/umd/helpers/iframe.d.ts.map +1 -1
- package/dist/umd/helpers/viewport-fixer.d.ts.map +1 -1
- package/dist/umd/helpers/viewport-replacer.d.ts +5 -5
- package/dist/umd/helpers/viewport-replacer.d.ts.map +1 -1
- package/dist/umd/hooks/index.d.ts +1 -0
- package/dist/umd/hooks/index.d.ts.map +1 -1
- package/dist/umd/hooks/register/useRegisterConfig.d.ts.map +1 -1
- package/dist/umd/hooks/viz-canvas/useHeatmapVizCanvas.d.ts +1 -4
- package/dist/umd/hooks/viz-canvas/useHeatmapVizCanvas.d.ts.map +1 -1
- package/dist/umd/hooks/viz-live/index.d.ts +2 -0
- package/dist/umd/hooks/viz-live/index.d.ts.map +1 -0
- package/dist/umd/hooks/viz-live/useIframeMessage.d.ts +27 -0
- 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/index.d.ts +1 -0
- package/dist/umd/hooks/viz-scale/index.d.ts.map +1 -1
- package/dist/umd/hooks/viz-scale/useContentDimensions.d.ts.map +1 -1
- package/dist/umd/hooks/viz-scale/useHeatmapScale.d.ts +2 -1
- package/dist/umd/hooks/viz-scale/useHeatmapScale.d.ts.map +1 -1
- package/dist/umd/hooks/viz-scale/useIframeHeight.d.ts +2 -1
- package/dist/umd/hooks/viz-scale/useIframeHeight.d.ts.map +1 -1
- package/dist/umd/hooks/viz-scale/useWrapperRefHeight.d.ts +11 -0
- package/dist/umd/hooks/viz-scale/useWrapperRefHeight.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/config.d.ts +14 -0
- package/dist/umd/stores/config.d.ts.map +1 -0
- package/dist/umd/stores/data.d.ts +1 -4
- package/dist/umd/stores/data.d.ts.map +1 -1
- package/dist/umd/stores/index.d.ts +2 -0
- package/dist/umd/stores/index.d.ts.map +1 -1
- package/dist/umd/stores/mode-live.d.ts +16 -0
- package/dist/umd/stores/mode-live.d.ts.map +1 -0
- package/dist/umd/types/control.d.ts +1 -1
- package/dist/umd/types/control.d.ts.map +1 -1
- package/dist/umd/types/viewport-fixer.d.ts +4 -2
- package/dist/umd/types/viewport-fixer.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/esm/components/Test.d.ts +0 -121
- package/dist/esm/components/Test.d.ts.map +0 -1
- package/dist/esm/components/VizDom/VizDomContainer.d.ts +0 -2
- package/dist/esm/components/VizDom/VizDomContainer.d.ts.map +0 -1
- package/dist/esm/components/VizElement/temp/ClarityVisualizer.d.ts +0 -150
- package/dist/esm/components/VizElement/temp/ClarityVisualizer.d.ts.map +0 -1
- package/dist/esm/components/VizElement/temp/VizElementRank.d.ts +0 -74
- package/dist/esm/components/VizElement/temp/VizElementRank.d.ts.map +0 -1
- package/dist/umd/components/Test.d.ts +0 -121
- package/dist/umd/components/Test.d.ts.map +0 -1
- package/dist/umd/components/VizDom/VizDomContainer.d.ts +0 -2
- package/dist/umd/components/VizDom/VizDomContainer.d.ts.map +0 -1
- package/dist/umd/components/VizElement/temp/ClarityVisualizer.d.ts +0 -150
- package/dist/umd/components/VizElement/temp/ClarityVisualizer.d.ts.map +0 -1
- package/dist/umd/components/VizElement/temp/VizElementRank.d.ts +0 -74
- package/dist/umd/components/VizElement/temp/VizElementRank.d.ts.map +0 -1
package/dist/esm/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
|
3
3
|
import { useNodesState, ReactFlow, Controls, Background } from '@xyflow/react';
|
|
4
4
|
import { useEffect, useCallback, useState, useRef, useMemo, forwardRef, Fragment as Fragment$1 } from 'react';
|
|
5
5
|
import { create } from 'zustand';
|
|
6
|
+
import { decode } from '@gemx-dev/clarity-decode';
|
|
6
7
|
import { Visualizer } from '@gemx-dev/clarity-visualize';
|
|
7
8
|
import { createPortal } from 'react-dom';
|
|
8
9
|
|
|
@@ -91,23 +92,30 @@ var IHeatmapType;
|
|
|
91
92
|
IHeatmapType["Scroll"] = "scroll";
|
|
92
93
|
})(IHeatmapType || (IHeatmapType = {}));
|
|
93
94
|
|
|
95
|
+
const useHeatmapConfigStore = create()((set, get) => {
|
|
96
|
+
return {
|
|
97
|
+
mode: 'single',
|
|
98
|
+
width: 1440,
|
|
99
|
+
sidebarWidth: DEFAULT_SIDEBAR_WIDTH,
|
|
100
|
+
heatmapType: IHeatmapType.Click,
|
|
101
|
+
setMode: (mode) => set({ mode }),
|
|
102
|
+
resetMode: () => set({ mode: 'single' }),
|
|
103
|
+
setWidth: (width) => set({ width }),
|
|
104
|
+
setSidebarWidth: (sidebarWidth) => set({ sidebarWidth }),
|
|
105
|
+
setHeatmapType: (heatmapType) => set({ heatmapType }),
|
|
106
|
+
};
|
|
107
|
+
});
|
|
108
|
+
|
|
94
109
|
const useHeatmapDataStore = create()((set, get) => {
|
|
95
110
|
return {
|
|
96
111
|
data: undefined,
|
|
97
112
|
clickmap: undefined,
|
|
98
|
-
config: {
|
|
99
|
-
sidebarWidth: DEFAULT_SIDEBAR_WIDTH,
|
|
100
|
-
width: 1440,
|
|
101
|
-
heatmapType: IHeatmapType.Click,
|
|
102
|
-
},
|
|
103
113
|
dataInfo: undefined,
|
|
104
114
|
isRendering: true,
|
|
105
115
|
setIsRendering: (isRendering) => set({ isRendering }),
|
|
106
116
|
setDataInfo: (dataInfo) => set({ dataInfo }),
|
|
107
117
|
setData: (data) => set({ data }),
|
|
108
118
|
setClickmap: (clickmap) => set({ clickmap }),
|
|
109
|
-
setConfig: (value) => set({ config: { ...get().config, ...value } }),
|
|
110
|
-
setConfigBy: (key, value) => set({ config: { ...get().config, [key]: value } }),
|
|
111
119
|
};
|
|
112
120
|
});
|
|
113
121
|
|
|
@@ -139,15 +147,33 @@ const useHeatmapVizStore = create()((set, get) => {
|
|
|
139
147
|
};
|
|
140
148
|
});
|
|
141
149
|
|
|
150
|
+
const initialState = {
|
|
151
|
+
htmlContent: '',
|
|
152
|
+
wrapperHeight: 0,
|
|
153
|
+
iframeHeight: 0,
|
|
154
|
+
};
|
|
155
|
+
const useHeatmapLiveStore = create()((set, get) => {
|
|
156
|
+
return {
|
|
157
|
+
...initialState,
|
|
158
|
+
reset: () => set(initialState),
|
|
159
|
+
setHtmlContent: (htmlContent) => set({ htmlContent }),
|
|
160
|
+
setWrapperHeight: (wrapperHeight) => set({ wrapperHeight }),
|
|
161
|
+
setIframeHeight: (iframeHeight) => set({ iframeHeight }),
|
|
162
|
+
};
|
|
163
|
+
});
|
|
164
|
+
|
|
142
165
|
const useRegisterConfig = () => {
|
|
143
|
-
const
|
|
166
|
+
const mode = useHeatmapConfigStore((state) => state.mode);
|
|
167
|
+
const width = useHeatmapConfigStore((state) => state.width);
|
|
168
|
+
const sidebarWidth = useHeatmapConfigStore((state) => state.sidebarWidth);
|
|
169
|
+
const heatmapType = useHeatmapConfigStore((state) => state.heatmapType);
|
|
144
170
|
const setIsRendering = useHeatmapDataStore((state) => state.setIsRendering);
|
|
145
171
|
useEffect(() => {
|
|
146
172
|
setIsRendering(true);
|
|
147
173
|
setTimeout(() => {
|
|
148
174
|
setIsRendering(false);
|
|
149
175
|
}, 1000);
|
|
150
|
-
}, [
|
|
176
|
+
}, [mode, width, sidebarWidth, heatmapType]);
|
|
151
177
|
};
|
|
152
178
|
|
|
153
179
|
const useRegisterControl = (control) => {
|
|
@@ -409,6 +435,43 @@ const buildElementInfo = (hash, rect, heatmapInfo) => {
|
|
|
409
435
|
};
|
|
410
436
|
};
|
|
411
437
|
|
|
438
|
+
function findLastSizeOfDom(data) {
|
|
439
|
+
const firstDoc = data.find((item) => item.envelope.sequence === 1)?.doc;
|
|
440
|
+
const docSorted = firstDoc?.sort(sort);
|
|
441
|
+
const firstEvent = docSorted?.[0];
|
|
442
|
+
const docSize = {
|
|
443
|
+
width: firstEvent?.data.width,
|
|
444
|
+
height: firstEvent?.data.height,
|
|
445
|
+
};
|
|
446
|
+
const newData = JSON.parse(JSON.stringify(data));
|
|
447
|
+
const reversedData = newData.reverse();
|
|
448
|
+
const lastResizeEvent = reversedData.find((item) => !!item.resize);
|
|
449
|
+
const firstEventResize = lastResizeEvent?.resize?.[0];
|
|
450
|
+
const resize = {
|
|
451
|
+
width: firstEventResize?.data.width,
|
|
452
|
+
height: firstEventResize?.data.height,
|
|
453
|
+
};
|
|
454
|
+
return {
|
|
455
|
+
doc: docSize,
|
|
456
|
+
resize: resize,
|
|
457
|
+
size: {
|
|
458
|
+
width: resize.width ?? docSize.width,
|
|
459
|
+
height: resize.height ?? docSize.height,
|
|
460
|
+
},
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
function sort(a, b) {
|
|
464
|
+
return a.time - b.time;
|
|
465
|
+
}
|
|
466
|
+
function decodePayloads(payload) {
|
|
467
|
+
try {
|
|
468
|
+
return decode(payload);
|
|
469
|
+
}
|
|
470
|
+
catch (error) {
|
|
471
|
+
return null;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
412
475
|
function calculateRankPosition(rect, widthScale) {
|
|
413
476
|
const top = rect.top <= 18 ? rect.top + 3 : rect.top - 18;
|
|
414
477
|
const left = rect.left <= 18 ? rect.left + 3 : rect.left - 18;
|
|
@@ -438,6 +501,21 @@ function isElementInViewport(elementRect, visualRef, scale) {
|
|
|
438
501
|
return elementBottom > viewportTop && elementTop < viewportBottom;
|
|
439
502
|
}
|
|
440
503
|
|
|
504
|
+
const getScriptInjectCode = async () => {
|
|
505
|
+
const moduleResult = (await Promise.resolve().then(function () { return viewportReplacer; }));
|
|
506
|
+
const ActualClass = moduleResult.default;
|
|
507
|
+
const classCode = ActualClass.toString();
|
|
508
|
+
const classInstantiateCode = ActualClass.name;
|
|
509
|
+
const scriptCode = `
|
|
510
|
+
(function() {
|
|
511
|
+
'use strict';
|
|
512
|
+
${classCode}
|
|
513
|
+
const replacer = new ${classInstantiateCode}();
|
|
514
|
+
replacer.init();
|
|
515
|
+
})();
|
|
516
|
+
`;
|
|
517
|
+
return scriptCode;
|
|
518
|
+
};
|
|
441
519
|
class ViewportUnitsFixer {
|
|
442
520
|
iframe = null;
|
|
443
521
|
config;
|
|
@@ -463,22 +541,21 @@ class ViewportUnitsFixer {
|
|
|
463
541
|
async injectScript() {
|
|
464
542
|
if (!this.iframe?.contentWindow || !this.iframe.contentDocument)
|
|
465
543
|
return;
|
|
466
|
-
const win = this.iframe.contentWindow;
|
|
467
544
|
const doc = this.iframe.contentDocument;
|
|
468
|
-
win
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
545
|
+
const win = this.iframe.contentWindow;
|
|
546
|
+
try {
|
|
547
|
+
win.__viewportConfig = this.config;
|
|
548
|
+
const script = doc.createElement('script');
|
|
549
|
+
console.log(`🚀 🐥 ~ ViewportUnitsFixer ~ injectScript ~ script:`, script);
|
|
550
|
+
const scriptCode = await getScriptInjectCode();
|
|
551
|
+
console.log(`🚀 🐥 ~ ViewportUnitsFixer ~ injectScript ~ scriptCode:`, scriptCode);
|
|
552
|
+
script.textContent = scriptCode;
|
|
553
|
+
doc.head.appendChild(script);
|
|
554
|
+
console.log(`🚀 🐥 ~ ViewportUnitsFixer ~ injectScript ~ doc:`, doc);
|
|
555
|
+
}
|
|
556
|
+
catch (error) {
|
|
557
|
+
console.error('[Parent] Failed to inject script', error);
|
|
558
|
+
}
|
|
482
559
|
}
|
|
483
560
|
handleMessage(event) {
|
|
484
561
|
const data = event.data;
|
|
@@ -501,15 +578,11 @@ function initViewportFixer(config) {
|
|
|
501
578
|
}
|
|
502
579
|
|
|
503
580
|
class ViewportUnitsReplacer {
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
}
|
|
510
|
-
this.config = window.__viewportConfig;
|
|
511
|
-
console.log('[Iframe] ViewportUnitsReplacer started with config:', this.config);
|
|
512
|
-
this.init();
|
|
581
|
+
regex() {
|
|
582
|
+
return /([-.\d]+)(vh|svh|lvh|dvh|vw|svw|lvw|dvw)/gi;
|
|
583
|
+
}
|
|
584
|
+
config() {
|
|
585
|
+
return window.__viewportConfig;
|
|
513
586
|
}
|
|
514
587
|
px(value) {
|
|
515
588
|
return `${value.toFixed(2)}px`;
|
|
@@ -519,25 +592,25 @@ class ViewportUnitsReplacer {
|
|
|
519
592
|
if (isNaN(num))
|
|
520
593
|
return value;
|
|
521
594
|
const map = {
|
|
522
|
-
vh: this.config.targetHeight,
|
|
523
|
-
svh: this.config.targetHeight,
|
|
524
|
-
lvh: this.config.targetHeight,
|
|
525
|
-
dvh: this.config.targetHeight,
|
|
526
|
-
vw: this.config.targetWidth,
|
|
527
|
-
svw: this.config.targetWidth,
|
|
528
|
-
lvw: this.config.targetWidth,
|
|
529
|
-
dvw: this.config.targetWidth,
|
|
595
|
+
vh: this.config().targetHeight,
|
|
596
|
+
svh: this.config().targetHeight,
|
|
597
|
+
lvh: this.config().targetHeight,
|
|
598
|
+
dvh: this.config().targetHeight,
|
|
599
|
+
vw: this.config().targetWidth,
|
|
600
|
+
svw: this.config().targetWidth,
|
|
601
|
+
lvw: this.config().targetWidth,
|
|
602
|
+
dvw: this.config().targetWidth,
|
|
530
603
|
};
|
|
531
604
|
return this.px((num / 100) * (map[unit.toLowerCase()] || 0));
|
|
532
605
|
}
|
|
533
606
|
replaceInText(cssText) {
|
|
534
|
-
return cssText.replace(this.regex, (_, value, unit) => this.convert(value, unit));
|
|
607
|
+
return cssText.replace(this.regex(), (_, value, unit) => this.convert(value, unit));
|
|
535
608
|
}
|
|
536
609
|
processInlineStyles() {
|
|
537
610
|
let count = 0;
|
|
538
611
|
document.querySelectorAll('[style]').forEach((el) => {
|
|
539
612
|
const style = el.getAttribute('style');
|
|
540
|
-
if (style && this.regex.test(style)) {
|
|
613
|
+
if (style && this.regex().test(style)) {
|
|
541
614
|
el.setAttribute('style', this.replaceInText(style));
|
|
542
615
|
count++;
|
|
543
616
|
}
|
|
@@ -549,7 +622,7 @@ class ViewportUnitsReplacer {
|
|
|
549
622
|
let count = 0;
|
|
550
623
|
document.querySelectorAll('style').forEach((tag) => {
|
|
551
624
|
const css = tag.textContent || '';
|
|
552
|
-
if (this.regex.test(css)) {
|
|
625
|
+
if (this.regex().test(css)) {
|
|
553
626
|
tag.textContent = this.replaceInText(css);
|
|
554
627
|
count++;
|
|
555
628
|
}
|
|
@@ -564,7 +637,7 @@ class ViewportUnitsReplacer {
|
|
|
564
637
|
for (let i = 0; i < style.length; i++) {
|
|
565
638
|
const prop = style[i];
|
|
566
639
|
const value = style.getPropertyValue(prop);
|
|
567
|
-
if (value && this.regex.test(value)) {
|
|
640
|
+
if (value && this.regex().test(value)) {
|
|
568
641
|
style.setProperty(prop, this.replaceInText(value), style.getPropertyPriority(prop));
|
|
569
642
|
count++;
|
|
570
643
|
}
|
|
@@ -612,7 +685,7 @@ class ViewportUnitsReplacer {
|
|
|
612
685
|
try {
|
|
613
686
|
const res = await fetch(link.href);
|
|
614
687
|
let css = await res.text();
|
|
615
|
-
if (this.regex.test(css)) {
|
|
688
|
+
if (this.regex().test(css)) {
|
|
616
689
|
css = this.replaceInText(css);
|
|
617
690
|
const style = document.createElement('style');
|
|
618
691
|
style.textContent = css;
|
|
@@ -671,6 +744,8 @@ class ViewportUnitsReplacer {
|
|
|
671
744
|
}
|
|
672
745
|
}
|
|
673
746
|
init() {
|
|
747
|
+
if (!window.__viewportConfig)
|
|
748
|
+
return;
|
|
674
749
|
if (document.readyState === 'loading') {
|
|
675
750
|
document.addEventListener('DOMContentLoaded', () => this.run());
|
|
676
751
|
}
|
|
@@ -798,7 +873,7 @@ const useHeatmapEffects = ({ isVisible, isElementSidebarOpen, setShouldShowCallo
|
|
|
798
873
|
const useHeatmapElementPosition = ({ iframeRef, wrapperRef, visualizer }) => {
|
|
799
874
|
const widthScale = useHeatmapVizStore((state) => state.scale);
|
|
800
875
|
const iframeHeight = useHeatmapVizStore((state) => state.iframeHeight);
|
|
801
|
-
const heatmapWidth =
|
|
876
|
+
const heatmapWidth = useHeatmapConfigStore((state) => state.width);
|
|
802
877
|
return useCallback((element) => {
|
|
803
878
|
const hash = element?.hash;
|
|
804
879
|
if (!iframeRef.current?.contentDocument || !hash || !visualizer)
|
|
@@ -936,9 +1011,122 @@ const isValidElement = (element, heatmapInfo) => {
|
|
|
936
1011
|
return !!heatmapInfo?.elementMapInfo?.[hash];
|
|
937
1012
|
};
|
|
938
1013
|
|
|
1014
|
+
var MessageType;
|
|
1015
|
+
(function (MessageType) {
|
|
1016
|
+
MessageType["GX_DOM_TRACKING_PAYLOAD"] = "GX_DOM_TRACKING_PAYLOAD";
|
|
1017
|
+
MessageType["CLARITY_READY"] = "CLARITY_READY";
|
|
1018
|
+
})(MessageType || (MessageType = {}));
|
|
1019
|
+
function useIframeMessage(options = {}) {
|
|
1020
|
+
const { trustedOrigins = [], onMessage } = options;
|
|
1021
|
+
const [payloads, setPayloads] = useState([]);
|
|
1022
|
+
const [isReady, setIsReady] = useState(false);
|
|
1023
|
+
const iframeRef = useRef(null);
|
|
1024
|
+
const isValidOrigin = useCallback((origin) => {
|
|
1025
|
+
if (trustedOrigins.length === 0)
|
|
1026
|
+
return true;
|
|
1027
|
+
return trustedOrigins.includes(origin);
|
|
1028
|
+
}, [trustedOrigins]);
|
|
1029
|
+
const handleMessage = useCallback((event) => {
|
|
1030
|
+
if (!isValidOrigin(event.origin)) {
|
|
1031
|
+
console.warn('Message from untrusted origin:', event.origin);
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
1034
|
+
if (!event.data || typeof event.data !== 'object' || !event.data.type) {
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
const message = event.data;
|
|
1038
|
+
if (!Object.values(MessageType).includes(message.type)) {
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
if (onMessage) {
|
|
1042
|
+
onMessage(message);
|
|
1043
|
+
}
|
|
1044
|
+
switch (message.type) {
|
|
1045
|
+
case MessageType.GX_DOM_TRACKING_PAYLOAD:
|
|
1046
|
+
if (message.payload) {
|
|
1047
|
+
const decodedPayloads = decodePayloads(message.payload);
|
|
1048
|
+
if (decodedPayloads) {
|
|
1049
|
+
setPayloads((prev) => [...prev, decodedPayloads]);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
break;
|
|
1053
|
+
case MessageType.CLARITY_READY:
|
|
1054
|
+
setIsReady(true);
|
|
1055
|
+
break;
|
|
1056
|
+
}
|
|
1057
|
+
}, [isValidOrigin, onMessage]);
|
|
1058
|
+
useEffect(() => {
|
|
1059
|
+
window.addEventListener('message', handleMessage);
|
|
1060
|
+
return () => {
|
|
1061
|
+
window.removeEventListener('message', handleMessage);
|
|
1062
|
+
};
|
|
1063
|
+
}, [handleMessage]);
|
|
1064
|
+
const clearPayloads = useCallback(() => {
|
|
1065
|
+
setPayloads([]);
|
|
1066
|
+
}, []);
|
|
1067
|
+
const reset = useCallback(() => {
|
|
1068
|
+
setPayloads([]);
|
|
1069
|
+
setIsReady(false);
|
|
1070
|
+
}, []);
|
|
1071
|
+
return {
|
|
1072
|
+
iframeRef,
|
|
1073
|
+
payloads,
|
|
1074
|
+
isReady,
|
|
1075
|
+
clearPayloads,
|
|
1076
|
+
reset,
|
|
1077
|
+
};
|
|
1078
|
+
}
|
|
1079
|
+
function useIframeRender() {
|
|
1080
|
+
const wrapperHeight = useHeatmapLiveStore((state) => state.wrapperHeight);
|
|
1081
|
+
const contentWidth = useHeatmapConfigStore((state) => state.width);
|
|
1082
|
+
const setIframeHeight = useHeatmapVizStore((state) => state.setIframeHeight);
|
|
1083
|
+
const htmlContent = useHeatmapLiveStore((state) => state.htmlContent);
|
|
1084
|
+
const { iframeRef, payloads, isReady } = useIframeMessage();
|
|
1085
|
+
useEffect(() => {
|
|
1086
|
+
if (!htmlContent || !iframeRef.current)
|
|
1087
|
+
return;
|
|
1088
|
+
const iframe = iframeRef.current;
|
|
1089
|
+
const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;
|
|
1090
|
+
if (iframeDoc) {
|
|
1091
|
+
iframeDoc.open();
|
|
1092
|
+
iframeDoc.writeln(htmlContent);
|
|
1093
|
+
iframeDoc.close();
|
|
1094
|
+
}
|
|
1095
|
+
}, [htmlContent]);
|
|
1096
|
+
useEffect(() => {
|
|
1097
|
+
if (!isReady)
|
|
1098
|
+
return;
|
|
1099
|
+
if (!iframeRef.current)
|
|
1100
|
+
return;
|
|
1101
|
+
const iframe = iframeRef.current;
|
|
1102
|
+
if (!iframe || !htmlContent)
|
|
1103
|
+
return;
|
|
1104
|
+
reset$1(iframe, { width: contentWidth, height: wrapperHeight }, (height) => {
|
|
1105
|
+
setIframeHeight(height);
|
|
1106
|
+
});
|
|
1107
|
+
}, [isReady, contentWidth, wrapperHeight]);
|
|
1108
|
+
return {
|
|
1109
|
+
iframeRef,
|
|
1110
|
+
payloads,
|
|
1111
|
+
isReady,
|
|
1112
|
+
};
|
|
1113
|
+
}
|
|
1114
|
+
function reset$1(iframe, payloads, onSuccess) {
|
|
1115
|
+
const viewportFixer = initViewportFixer({
|
|
1116
|
+
targetWidth: payloads.width,
|
|
1117
|
+
targetHeight: payloads.height,
|
|
1118
|
+
iframe: iframe,
|
|
1119
|
+
onSuccess: (data) => {
|
|
1120
|
+
onSuccess(data.height);
|
|
1121
|
+
iframe.height = `${data.height}px`;
|
|
1122
|
+
},
|
|
1123
|
+
});
|
|
1124
|
+
viewportFixer.recalculate();
|
|
1125
|
+
return iframe;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
939
1128
|
const useHeatmapRender = () => {
|
|
940
1129
|
const data = useHeatmapDataStore((state) => state.data);
|
|
941
|
-
const config = useHeatmapDataStore((state) => state.config);
|
|
942
1130
|
const setVizRef = useHeatmapVizStore((state) => state.setVizRef);
|
|
943
1131
|
const setIsRenderViz = useHeatmapVizStore((state) => state.setIsRenderViz);
|
|
944
1132
|
const setIframeHeight = useHeatmapVizStore((state) => state.setIframeHeight);
|
|
@@ -965,39 +1153,11 @@ const useHeatmapRender = () => {
|
|
|
965
1153
|
return () => {
|
|
966
1154
|
setVizRef(null);
|
|
967
1155
|
};
|
|
968
|
-
}, [
|
|
1156
|
+
}, [data]);
|
|
969
1157
|
return {
|
|
970
1158
|
iframeRef,
|
|
971
1159
|
};
|
|
972
1160
|
};
|
|
973
|
-
function sort(a, b) {
|
|
974
|
-
return a.time - b.time;
|
|
975
|
-
}
|
|
976
|
-
function findLastSizeOfDom(data) {
|
|
977
|
-
const firstDoc = data.find((item) => item.envelope.sequence === 1)?.doc;
|
|
978
|
-
const docSorted = firstDoc?.sort(sort);
|
|
979
|
-
const firstEvent = docSorted?.[0];
|
|
980
|
-
const docSize = {
|
|
981
|
-
width: firstEvent?.data.width,
|
|
982
|
-
height: firstEvent?.data.height,
|
|
983
|
-
};
|
|
984
|
-
const newData = JSON.parse(JSON.stringify(data));
|
|
985
|
-
const reversedData = newData.reverse();
|
|
986
|
-
const lastResizeEvent = reversedData.find((item) => !!item.resize);
|
|
987
|
-
const firstEventResize = lastResizeEvent?.resize?.[0];
|
|
988
|
-
const resize = {
|
|
989
|
-
width: firstEventResize?.data.width,
|
|
990
|
-
height: firstEventResize?.data.height,
|
|
991
|
-
};
|
|
992
|
-
return {
|
|
993
|
-
doc: docSize,
|
|
994
|
-
resize: resize,
|
|
995
|
-
size: {
|
|
996
|
-
width: resize.width ?? docSize.width,
|
|
997
|
-
height: resize.height ?? docSize.height,
|
|
998
|
-
},
|
|
999
|
-
};
|
|
1000
|
-
}
|
|
1001
1161
|
function reset(iframe, payloads, onSuccess) {
|
|
1002
1162
|
const { size } = findLastSizeOfDom(payloads);
|
|
1003
1163
|
const docWidth = size.width ?? 0;
|
|
@@ -1027,7 +1187,7 @@ function sortEvents(a, b) {
|
|
|
1027
1187
|
|
|
1028
1188
|
const useReplayRender = () => {
|
|
1029
1189
|
const data = useHeatmapDataStore((state) => state.data);
|
|
1030
|
-
const
|
|
1190
|
+
const setWidth = useHeatmapConfigStore((state) => state.setWidth);
|
|
1031
1191
|
const visualizerRef = useRef(null);
|
|
1032
1192
|
const iframeRef = useRef(null);
|
|
1033
1193
|
const eventsRef = useRef([]);
|
|
@@ -1045,14 +1205,14 @@ const useReplayRender = () => {
|
|
|
1045
1205
|
visualizer.setup(iframe.contentWindow, {
|
|
1046
1206
|
version: envelope.version,
|
|
1047
1207
|
onresize: (width) => {
|
|
1048
|
-
|
|
1208
|
+
setWidth(width);
|
|
1049
1209
|
},
|
|
1050
1210
|
mobile,
|
|
1051
1211
|
vNext: true,
|
|
1052
1212
|
locale: 'en-us',
|
|
1053
1213
|
});
|
|
1054
1214
|
return visualizer;
|
|
1055
|
-
}, [
|
|
1215
|
+
}, [setWidth]);
|
|
1056
1216
|
// Animation loop for replay
|
|
1057
1217
|
const replayLoop = useCallback(() => {
|
|
1058
1218
|
if (!isPlayingRef.current)
|
|
@@ -1186,8 +1346,7 @@ const useContainerDimensions = (props) => {
|
|
|
1186
1346
|
};
|
|
1187
1347
|
|
|
1188
1348
|
const useContentDimensions = ({ iframeRef, }) => {
|
|
1189
|
-
const
|
|
1190
|
-
const contentWidth = config?.width ?? 0;
|
|
1349
|
+
const contentWidth = useHeatmapConfigStore((state) => state.width);
|
|
1191
1350
|
useEffect(() => {
|
|
1192
1351
|
if (!contentWidth)
|
|
1193
1352
|
return;
|
|
@@ -1199,9 +1358,7 @@ const useContentDimensions = ({ iframeRef, }) => {
|
|
|
1199
1358
|
};
|
|
1200
1359
|
|
|
1201
1360
|
const useIframeHeight = (props) => {
|
|
1202
|
-
const { iframeRef } = props;
|
|
1203
|
-
const iframeHeight = useHeatmapVizStore((state) => state.iframeHeight);
|
|
1204
|
-
const setIframeHeight = useHeatmapVizStore((state) => state.setIframeHeight);
|
|
1361
|
+
const { iframeRef, setIframeHeight } = props;
|
|
1205
1362
|
const isRenderViz = useHeatmapVizStore((state) => state.isRenderViz);
|
|
1206
1363
|
const resizeObserverRef = useRef(null);
|
|
1207
1364
|
const mutationObserverRef = useRef(null);
|
|
@@ -1279,7 +1436,7 @@ const useIframeHeight = (props) => {
|
|
|
1279
1436
|
iframe.removeEventListener('load', setupObservers);
|
|
1280
1437
|
};
|
|
1281
1438
|
}, [iframeRef, isRenderViz, updateIframeHeight]);
|
|
1282
|
-
return {
|
|
1439
|
+
return {};
|
|
1283
1440
|
};
|
|
1284
1441
|
|
|
1285
1442
|
const useScaleCalculation = (props) => {
|
|
@@ -1318,14 +1475,13 @@ const useScrollSync = ({ iframeRef }) => {
|
|
|
1318
1475
|
};
|
|
1319
1476
|
|
|
1320
1477
|
const useHeatmapScale = (props) => {
|
|
1321
|
-
|
|
1322
|
-
const { wrapperRef, iframeRef, visualRef } = props;
|
|
1478
|
+
const { wrapperRef, iframeRef, iframeHeight, setIframeHeight } = props;
|
|
1323
1479
|
// 1. Observe container dimensions
|
|
1324
1480
|
const { containerWidth, containerHeight } = useContainerDimensions({ wrapperRef });
|
|
1325
1481
|
// 2. Get content dimensions from config
|
|
1326
1482
|
const { contentWidth } = useContentDimensions({ iframeRef });
|
|
1327
1483
|
// 3. Observe iframe height (now reacts to width changes)
|
|
1328
|
-
|
|
1484
|
+
useIframeHeight({ iframeRef, setIframeHeight });
|
|
1329
1485
|
// 4. Calculate scale
|
|
1330
1486
|
const { scale } = useScaleCalculation({ containerWidth, contentWidth });
|
|
1331
1487
|
// 5. Setup scroll sync
|
|
@@ -1333,13 +1489,81 @@ const useHeatmapScale = (props) => {
|
|
|
1333
1489
|
return {
|
|
1334
1490
|
containerWidth,
|
|
1335
1491
|
containerHeight,
|
|
1336
|
-
iframeHeight,
|
|
1337
1492
|
scaledWidth: contentWidth * scale,
|
|
1338
1493
|
scaledHeight: iframeHeight * scale,
|
|
1339
1494
|
handleScroll,
|
|
1340
1495
|
};
|
|
1341
1496
|
};
|
|
1342
1497
|
|
|
1498
|
+
const useWrapperRefHeight = (props) => {
|
|
1499
|
+
const { isActive, wrapperRef, setWrapperHeight } = props;
|
|
1500
|
+
const isRenderViz = useHeatmapVizStore((state) => state.isRenderViz);
|
|
1501
|
+
const resizeObserverRef = useRef(null);
|
|
1502
|
+
const mutationObserverRef = useRef(null);
|
|
1503
|
+
const updateWrapperHeight = useCallback(() => {
|
|
1504
|
+
const wrapper = wrapperRef.current;
|
|
1505
|
+
if (!wrapper)
|
|
1506
|
+
return;
|
|
1507
|
+
try {
|
|
1508
|
+
const wrapperHeight = wrapper.offsetHeight;
|
|
1509
|
+
if (wrapperHeight > 0) {
|
|
1510
|
+
setWrapperHeight?.(wrapperHeight);
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
catch (error) {
|
|
1514
|
+
console.warn('Cannot measure iframe content:', error);
|
|
1515
|
+
}
|
|
1516
|
+
}, [wrapperRef, setWrapperHeight]);
|
|
1517
|
+
useEffect(() => {
|
|
1518
|
+
const wrapper = wrapperRef.current;
|
|
1519
|
+
if (!wrapper || !isRenderViz)
|
|
1520
|
+
return;
|
|
1521
|
+
const setupObservers = () => {
|
|
1522
|
+
try {
|
|
1523
|
+
// Cleanup existing observers
|
|
1524
|
+
if (resizeObserverRef.current) {
|
|
1525
|
+
resizeObserverRef.current.disconnect();
|
|
1526
|
+
}
|
|
1527
|
+
if (mutationObserverRef.current) {
|
|
1528
|
+
mutationObserverRef.current.disconnect();
|
|
1529
|
+
}
|
|
1530
|
+
// ResizeObserver for size changes
|
|
1531
|
+
if (typeof window.ResizeObserver !== 'undefined') {
|
|
1532
|
+
resizeObserverRef.current = new ResizeObserver(updateWrapperHeight);
|
|
1533
|
+
resizeObserverRef.current.observe(wrapper);
|
|
1534
|
+
}
|
|
1535
|
+
// MutationObserver for DOM changes
|
|
1536
|
+
if (typeof window.MutationObserver !== 'undefined') {
|
|
1537
|
+
mutationObserverRef.current = new MutationObserver(updateWrapperHeight);
|
|
1538
|
+
mutationObserverRef.current.observe(wrapper, {
|
|
1539
|
+
childList: true,
|
|
1540
|
+
subtree: true,
|
|
1541
|
+
attributes: true,
|
|
1542
|
+
characterData: true,
|
|
1543
|
+
});
|
|
1544
|
+
}
|
|
1545
|
+
// Initial measurement
|
|
1546
|
+
updateWrapperHeight();
|
|
1547
|
+
}
|
|
1548
|
+
catch (error) {
|
|
1549
|
+
console.warn('Cannot access wrapper content:', error);
|
|
1550
|
+
}
|
|
1551
|
+
};
|
|
1552
|
+
if (isActive) {
|
|
1553
|
+
setupObservers();
|
|
1554
|
+
}
|
|
1555
|
+
return () => {
|
|
1556
|
+
if (resizeObserverRef.current) {
|
|
1557
|
+
resizeObserverRef.current.disconnect();
|
|
1558
|
+
}
|
|
1559
|
+
if (mutationObserverRef.current) {
|
|
1560
|
+
mutationObserverRef.current.disconnect();
|
|
1561
|
+
}
|
|
1562
|
+
};
|
|
1563
|
+
}, [wrapperRef, isRenderViz, updateWrapperHeight, isActive]);
|
|
1564
|
+
return {};
|
|
1565
|
+
};
|
|
1566
|
+
|
|
1343
1567
|
const BoxStack = forwardRef(({ children, ...props }, ref) => {
|
|
1344
1568
|
const id = props.id;
|
|
1345
1569
|
const flexDirection = props.flexDirection;
|
|
@@ -1385,9 +1609,42 @@ const BoxStack = forwardRef(({ children, ...props }, ref) => {
|
|
|
1385
1609
|
|
|
1386
1610
|
const ContentTopBar = () => {
|
|
1387
1611
|
const controls = useHeatmapControlStore((state) => state.controls);
|
|
1612
|
+
const TopBar = controls.TopBar;
|
|
1388
1613
|
return (jsx(BoxStack, { id: "gx-hm-content-header", flexDirection: "row", alignItems: "center", overflow: "auto", zIndex: 1, backgroundColor: "white", style: {
|
|
1389
1614
|
borderBottom: `${HEATMAP_CONFIG.borderWidth}px solid ${HEATMAP_CONFIG.borderColor}`,
|
|
1390
|
-
}, children:
|
|
1615
|
+
}, children: TopBar && jsx(TopBar, {}) }));
|
|
1616
|
+
};
|
|
1617
|
+
|
|
1618
|
+
const ContentMetricBar = () => {
|
|
1619
|
+
const controls = useHeatmapControlStore((state) => state.controls);
|
|
1620
|
+
return (jsx(BoxStack, { id: "gx-hm-content-metric-bar", flexDirection: "row", alignItems: "center", overflow: "auto", zIndex: 1, backgroundColor: "white", style: {
|
|
1621
|
+
borderBottom: `${HEATMAP_CONFIG.borderWidth}px solid ${HEATMAP_CONFIG.borderColor}`,
|
|
1622
|
+
}, children: controls.MetricBar ?? null }));
|
|
1623
|
+
};
|
|
1624
|
+
|
|
1625
|
+
const ContentToolbar = () => {
|
|
1626
|
+
const controls = useHeatmapControlStore((state) => state.controls);
|
|
1627
|
+
return (jsx("div", { id: "gx-hm-content-toolbar", style: {
|
|
1628
|
+
zIndex: 2,
|
|
1629
|
+
position: 'absolute',
|
|
1630
|
+
bottom: 0,
|
|
1631
|
+
left: '8px',
|
|
1632
|
+
right: '24px',
|
|
1633
|
+
padding: '8px',
|
|
1634
|
+
paddingBlock: '16px',
|
|
1635
|
+
}, children: controls.Toolbar ?? null }));
|
|
1636
|
+
};
|
|
1637
|
+
|
|
1638
|
+
const VizContainer = ({ children, setWrapperHeight }) => {
|
|
1639
|
+
const wrapperRef = useRef(null);
|
|
1640
|
+
useWrapperRefHeight({
|
|
1641
|
+
isActive: !!setWrapperHeight,
|
|
1642
|
+
wrapperRef,
|
|
1643
|
+
setWrapperHeight,
|
|
1644
|
+
});
|
|
1645
|
+
return (jsx(BoxStack, { ref: wrapperRef, id: "gx-hm-viz-container", flexDirection: "column", flex: "1 1 auto", overflow: "auto", zIndex: 1, children: jsx(BoxStack, { id: "gx-hm-content", flexDirection: "column", flex: "1 1 auto", overflow: "hidden", style: {
|
|
1646
|
+
minWidth: '394px',
|
|
1647
|
+
}, children: children }) }));
|
|
1391
1648
|
};
|
|
1392
1649
|
|
|
1393
1650
|
const useClickmap = () => {
|
|
@@ -1411,15 +1668,16 @@ const useScrollmap = () => {
|
|
|
1411
1668
|
return {};
|
|
1412
1669
|
};
|
|
1413
1670
|
|
|
1414
|
-
const useHeatmapVizCanvas = (
|
|
1671
|
+
const useHeatmapVizCanvas = () => {
|
|
1672
|
+
const heatmapType = useHeatmapConfigStore((state) => state.heatmapType);
|
|
1415
1673
|
const heatmapRender = useMemo(() => {
|
|
1416
|
-
switch (
|
|
1674
|
+
switch (heatmapType) {
|
|
1417
1675
|
case IHeatmapType.Click:
|
|
1418
1676
|
return useClickmap;
|
|
1419
1677
|
case IHeatmapType.Scroll:
|
|
1420
1678
|
return useScrollmap;
|
|
1421
1679
|
}
|
|
1422
|
-
}, [
|
|
1680
|
+
}, [heatmapType]);
|
|
1423
1681
|
return heatmapRender?.();
|
|
1424
1682
|
};
|
|
1425
1683
|
|
|
@@ -1611,57 +1869,59 @@ const VizElements = ({ iframeRef, visualRef, wrapperRef }) => {
|
|
|
1611
1869
|
} }));
|
|
1612
1870
|
};
|
|
1613
1871
|
|
|
1614
|
-
const
|
|
1615
|
-
const
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1872
|
+
const WrapperVisual = ({ children, visualRef, wrapperRef, scaledHeight, iframeHeight, onScroll, }) => {
|
|
1873
|
+
const contentWidth = useHeatmapConfigStore((state) => state.width);
|
|
1874
|
+
const widthScale = useHeatmapVizStore((state) => state.scale);
|
|
1875
|
+
const contentHeight = scaledHeight > 0
|
|
1876
|
+
? `${scaledHeight + HEATMAP_CONFIG['heightToolbar'] + HEATMAP_CONFIG['padding'] * 2}px`
|
|
1877
|
+
: 'auto';
|
|
1878
|
+
return (jsx("div", { ref: visualRef, className: "gx-hm-visual", onScroll: onScroll, style: {
|
|
1879
|
+
overflow: 'hidden auto',
|
|
1621
1880
|
display: 'flex',
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1881
|
+
position: 'relative',
|
|
1882
|
+
justifyContent: 'center',
|
|
1883
|
+
flex: 1,
|
|
1884
|
+
// paddingBottom: HEATMAP_STYLE['viz']['paddingBottom'],
|
|
1885
|
+
background: '#fff',
|
|
1886
|
+
}, children: jsx("div", { className: "gx-hm-visual-unscaled", style: {
|
|
1887
|
+
width: '100%',
|
|
1888
|
+
display: 'flex',
|
|
1889
|
+
justifyContent: 'center',
|
|
1890
|
+
alignItems: 'flex-start',
|
|
1891
|
+
height: contentHeight,
|
|
1892
|
+
padding: HEATMAP_STYLE['wrapper']['padding'],
|
|
1893
|
+
paddingBottom: HEATMAP_STYLE['viz']['paddingBottom'],
|
|
1894
|
+
background: HEATMAP_STYLE['viz']['background'],
|
|
1895
|
+
}, children: jsx("div", { className: "gx-hm-wrapper", ref: wrapperRef, style: {
|
|
1896
|
+
width: contentWidth,
|
|
1897
|
+
height: iframeHeight,
|
|
1898
|
+
transform: `scale(${widthScale})`,
|
|
1899
|
+
transformOrigin: 'top center',
|
|
1900
|
+
paddingBlockEnd: '0',
|
|
1901
|
+
}, children: children }) }) }));
|
|
1641
1902
|
};
|
|
1642
1903
|
|
|
1643
1904
|
const VizDomRenderer = ({ mode = 'heatmap' }) => {
|
|
1644
|
-
const
|
|
1905
|
+
const width = useHeatmapConfigStore((state) => state.width);
|
|
1906
|
+
const iframeHeight = useHeatmapVizStore((state) => state.iframeHeight);
|
|
1645
1907
|
const setIframeHeight = useHeatmapVizStore((state) => state.setIframeHeight);
|
|
1646
|
-
const widthScale = useHeatmapVizStore((state) => state.scale);
|
|
1647
1908
|
const setSelectedElement = useHeatmapInteractionStore((state) => state.setSelectedElement);
|
|
1648
1909
|
const wrapperRef = useRef(null);
|
|
1649
1910
|
const visualRef = useRef(null);
|
|
1650
1911
|
const { iframeRef } = useHeatmapVizRender(mode);
|
|
1651
|
-
const {
|
|
1912
|
+
const { scaledHeight, handleScroll } = useHeatmapScale({
|
|
1652
1913
|
wrapperRef,
|
|
1653
1914
|
iframeRef,
|
|
1654
1915
|
visualRef,
|
|
1916
|
+
iframeHeight,
|
|
1917
|
+
setIframeHeight,
|
|
1655
1918
|
});
|
|
1656
|
-
const contentWidth =
|
|
1657
|
-
const contentHeight = scaledHeight > 0
|
|
1658
|
-
? `${scaledHeight + HEATMAP_CONFIG['heightToolbar'] + HEATMAP_CONFIG['padding'] * 2}px`
|
|
1659
|
-
: 'auto';
|
|
1919
|
+
const contentWidth = width ?? 0;
|
|
1660
1920
|
const onScroll = (e) => {
|
|
1661
1921
|
const scrollTop = e.currentTarget.scrollTop;
|
|
1662
1922
|
handleScroll(scrollTop);
|
|
1663
1923
|
};
|
|
1664
|
-
useHeatmapVizCanvas(
|
|
1924
|
+
useHeatmapVizCanvas();
|
|
1665
1925
|
const cleanUp = () => {
|
|
1666
1926
|
setIframeHeight(0);
|
|
1667
1927
|
setSelectedElement(null);
|
|
@@ -1669,68 +1929,82 @@ const VizDomRenderer = ({ mode = 'heatmap' }) => {
|
|
|
1669
1929
|
useEffect(() => {
|
|
1670
1930
|
return cleanUp;
|
|
1671
1931
|
}, []);
|
|
1672
|
-
return (jsxs(
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
}, children: [jsx("div", { className: "gx-hm-visual-unscaled", style: {
|
|
1681
|
-
width: '100%',
|
|
1682
|
-
display: 'flex',
|
|
1683
|
-
justifyContent: 'center',
|
|
1684
|
-
alignItems: 'flex-start',
|
|
1685
|
-
height: contentHeight,
|
|
1686
|
-
padding: HEATMAP_STYLE['wrapper']['padding'],
|
|
1687
|
-
paddingBottom: HEATMAP_STYLE['viz']['paddingBottom'],
|
|
1688
|
-
background: HEATMAP_STYLE['viz']['background'],
|
|
1689
|
-
}, children: jsxs("div", { className: "gx-hm-wrapper", ref: wrapperRef, style: {
|
|
1690
|
-
width: contentWidth,
|
|
1691
|
-
height: iframeHeight,
|
|
1692
|
-
transform: `scale(${widthScale})`,
|
|
1693
|
-
transformOrigin: 'top center',
|
|
1694
|
-
paddingBlockEnd: '0',
|
|
1695
|
-
}, 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, {})] }));
|
|
1696
|
-
};
|
|
1697
|
-
|
|
1698
|
-
const VizDomContainer = () => {
|
|
1932
|
+
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, height: iframeHeight, scrolling: "no" })] }));
|
|
1933
|
+
};
|
|
1934
|
+
|
|
1935
|
+
const VizLoading = () => {
|
|
1936
|
+
return (jsxs("div", { className: "gx-hm-loading", children: [jsx("div", { className: "gx-hm-loading--spinner" }), jsx("p", { className: "gx-hm-loading--text", children: "Loading visualization..." })] }));
|
|
1937
|
+
};
|
|
1938
|
+
|
|
1939
|
+
const VizDomHeatmap = () => {
|
|
1699
1940
|
const controls = useHeatmapControlStore((state) => state.controls);
|
|
1700
1941
|
const isRendering = useHeatmapDataStore((state) => state.isRendering);
|
|
1701
1942
|
const iframeHeight = useHeatmapVizStore((state) => state.iframeHeight);
|
|
1943
|
+
const setIframeHeight = useHeatmapVizStore((state) => state.setIframeHeight);
|
|
1944
|
+
const setVizRef = useHeatmapVizStore((state) => state.setVizRef);
|
|
1945
|
+
useEffect(() => {
|
|
1946
|
+
return () => {
|
|
1947
|
+
setVizRef(undefined);
|
|
1948
|
+
setIframeHeight(0);
|
|
1949
|
+
};
|
|
1950
|
+
}, []);
|
|
1702
1951
|
if (isRendering)
|
|
1703
1952
|
return controls.VizLoading ?? null;
|
|
1704
|
-
return (
|
|
1705
|
-
minWidth: '394px',
|
|
1706
|
-
}, children: [jsx(VizDomRenderer, {}), iframeHeight === 0 && (jsxs("div", { className: "gx-hm-loading", children: [jsx("div", { className: "gx-hm-loading--spinner" }), jsx("p", { className: "gx-hm-loading--text", children: "Loading visualization..." })] }))] }) }));
|
|
1953
|
+
return (jsxs(VizContainer, { children: [jsx(VizDomRenderer, {}), iframeHeight === 0 && jsx(VizLoading, {})] }));
|
|
1707
1954
|
};
|
|
1708
1955
|
|
|
1709
|
-
const
|
|
1710
|
-
const
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1956
|
+
const VizLiveRenderer = () => {
|
|
1957
|
+
const contentWidth = useHeatmapConfigStore((state) => state.width);
|
|
1958
|
+
const iframeHeight = useHeatmapLiveStore((state) => state.iframeHeight);
|
|
1959
|
+
const setIframeHeight = useHeatmapLiveStore((state) => state.setIframeHeight);
|
|
1960
|
+
const visualRef = useRef(null);
|
|
1961
|
+
const wrapperRef = useRef(null);
|
|
1962
|
+
const { iframeRef } = useIframeRender();
|
|
1963
|
+
const { scaledHeight, handleScroll } = useHeatmapScale({
|
|
1964
|
+
wrapperRef,
|
|
1965
|
+
iframeRef,
|
|
1966
|
+
visualRef,
|
|
1967
|
+
iframeHeight,
|
|
1968
|
+
setIframeHeight,
|
|
1969
|
+
});
|
|
1970
|
+
const onScroll = (e) => {
|
|
1971
|
+
const scrollTop = e.currentTarget.scrollTop;
|
|
1972
|
+
handleScroll(scrollTop);
|
|
1973
|
+
};
|
|
1974
|
+
return (jsx(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, iframeHeight: iframeHeight, onScroll: onScroll, children: jsx("iframe", { ref: iframeRef, ...HEATMAP_IFRAME, width: contentWidth, height: iframeHeight, scrolling: "no", sandbox: "allow-scripts allow-same-origin" }) }));
|
|
1714
1975
|
};
|
|
1715
1976
|
|
|
1716
|
-
const
|
|
1977
|
+
const VizLiveHeatmap = () => {
|
|
1717
1978
|
const controls = useHeatmapControlStore((state) => state.controls);
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
}
|
|
1979
|
+
const isRendering = useHeatmapDataStore((state) => state.isRendering);
|
|
1980
|
+
const iframeHeight = useHeatmapVizStore((state) => state.iframeHeight);
|
|
1981
|
+
const wrapperHeight = useHeatmapLiveStore((state) => state.wrapperHeight);
|
|
1982
|
+
const setWrapperHeight = useHeatmapLiveStore((state) => state.setWrapperHeight);
|
|
1983
|
+
const reset = useHeatmapLiveStore((state) => state.reset);
|
|
1984
|
+
useEffect(() => {
|
|
1985
|
+
return () => {
|
|
1986
|
+
reset();
|
|
1987
|
+
};
|
|
1988
|
+
}, [reset]);
|
|
1989
|
+
if (isRendering)
|
|
1990
|
+
return controls.VizLoading ?? null;
|
|
1991
|
+
return (jsxs(VizContainer, { setWrapperHeight: setWrapperHeight, children: [jsx(VizLiveRenderer, {}), (!iframeHeight || !wrapperHeight) && jsx(VizLoading, {})] }));
|
|
1992
|
+
};
|
|
1993
|
+
|
|
1994
|
+
const ContentVizByMode = () => {
|
|
1995
|
+
const mode = useHeatmapConfigStore((state) => state.mode);
|
|
1996
|
+
switch (mode) {
|
|
1997
|
+
case 'live':
|
|
1998
|
+
return jsx(VizLiveHeatmap, {});
|
|
1999
|
+
default:
|
|
2000
|
+
return jsx(VizDomHeatmap, {});
|
|
2001
|
+
}
|
|
1727
2002
|
};
|
|
1728
2003
|
|
|
1729
2004
|
const LeftSidebar = () => {
|
|
1730
2005
|
const controls = useHeatmapControlStore((state) => state.controls);
|
|
1731
2006
|
const isHideSidebar = useHeatmapInteractionStore((state) => state.state.hideSidebar);
|
|
1732
|
-
const
|
|
1733
|
-
const sidebarWidth = config?.sidebarWidth || DEFAULT_SIDEBAR_WIDTH;
|
|
2007
|
+
const sidebarWidth = useHeatmapConfigStore((state) => state.sidebarWidth);
|
|
1734
2008
|
if (isHideSidebar) {
|
|
1735
2009
|
return null;
|
|
1736
2010
|
}
|
|
@@ -1753,7 +2027,7 @@ const LeftSidebar = () => {
|
|
|
1753
2027
|
};
|
|
1754
2028
|
|
|
1755
2029
|
const WrapperPreview = () => {
|
|
1756
|
-
return (jsxs(BoxStack, { id: "gx-hm-container", flexDirection: "row", overflow: "hidden", flex: "1", position: "relative", children: [jsx(LeftSidebar, {}), jsxs(BoxStack, { flexDirection: "column", flex: "1", children: [jsx(ContentMetricBar, {}), jsx(
|
|
2030
|
+
return (jsxs(BoxStack, { id: "gx-hm-container", flexDirection: "row", overflow: "hidden", flex: "1", position: "relative", children: [jsx(LeftSidebar, {}), jsxs(BoxStack, { flexDirection: "column", flex: "1", children: [jsx(ContentMetricBar, {}), jsx(ContentVizByMode, {}), jsx(ContentToolbar, {})] })] }));
|
|
1757
2031
|
};
|
|
1758
2032
|
|
|
1759
2033
|
const WrapperLayout = () => {
|
|
@@ -1778,22 +2052,4 @@ const HeatmapLayout = ({ data, clickmap, controls, dataInfo, }) => {
|
|
|
1778
2052
|
}
|
|
1779
2053
|
};
|
|
1780
2054
|
|
|
1781
|
-
|
|
1782
|
-
(function (PanelContent) {
|
|
1783
|
-
PanelContent["Sessions"] = "Sessions";
|
|
1784
|
-
PanelContent["Timeline"] = "Timeline";
|
|
1785
|
-
PanelContent["Area"] = "Area";
|
|
1786
|
-
PanelContent["Click"] = "Click";
|
|
1787
|
-
PanelContent["Scroll"] = "Scroll";
|
|
1788
|
-
PanelContent["Attention"] = "Attention";
|
|
1789
|
-
})(PanelContent || (PanelContent = {}));
|
|
1790
|
-
var ErrorType;
|
|
1791
|
-
(function (ErrorType) {
|
|
1792
|
-
ErrorType["NoResults"] = "NoResults";
|
|
1793
|
-
ErrorType["NoClicks"] = "NoClicks";
|
|
1794
|
-
ErrorType["NoScroll"] = "NoScroll";
|
|
1795
|
-
ErrorType["ServerError"] = "ServerError";
|
|
1796
|
-
ErrorType["DataError"] = "DataError";
|
|
1797
|
-
})(ErrorType || (ErrorType = {}));
|
|
1798
|
-
|
|
1799
|
-
export { GraphView, HeatmapLayout, IHeatmapType, useHeatmapDataStore, useHeatmapInteractionStore };
|
|
2055
|
+
export { GraphView, HeatmapLayout, IHeatmapType, useHeatmapConfigStore, useHeatmapDataStore, useHeatmapInteractionStore, useHeatmapLiveStore };
|