@smartnet360/svelte-components 0.0.32 → 0.0.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.
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
// Chart container div and state
|
|
38
38
|
let chartDiv: HTMLElement;
|
|
39
39
|
let containerSize = $state<ContainerSize>({ width: 0, height: 0 });
|
|
40
|
+
let chartInitialized = $state(false); // Track if chart has been created
|
|
40
41
|
|
|
41
42
|
function handleContextMenu(event: MouseEvent) {
|
|
42
43
|
event.preventDefault();
|
|
@@ -229,7 +230,15 @@
|
|
|
229
230
|
displaylogo: false
|
|
230
231
|
};
|
|
231
232
|
|
|
232
|
-
Plotly.
|
|
233
|
+
// Use Plotly.react() for updates (preserves zoom/pan) or newPlot for initial render
|
|
234
|
+
if (chartInitialized) {
|
|
235
|
+
// Update existing chart - much faster, preserves user interactions
|
|
236
|
+
Plotly.react(chartDiv, traces, finalLayout, config);
|
|
237
|
+
} else {
|
|
238
|
+
// Initial chart creation
|
|
239
|
+
Plotly.newPlot(chartDiv, traces, finalLayout, config);
|
|
240
|
+
chartInitialized = true;
|
|
241
|
+
}
|
|
233
242
|
|
|
234
243
|
// Resize immediately after creation to ensure proper sizing
|
|
235
244
|
setTimeout(() => {
|
|
@@ -291,6 +300,12 @@
|
|
|
291
300
|
clearTimeout(resizeTimeout);
|
|
292
301
|
}
|
|
293
302
|
resizeObserver.disconnect();
|
|
303
|
+
|
|
304
|
+
// Clean up Plotly chart
|
|
305
|
+
if (chartDiv && chartInitialized) {
|
|
306
|
+
Plotly.purge(chartDiv);
|
|
307
|
+
chartInitialized = false;
|
|
308
|
+
}
|
|
294
309
|
};
|
|
295
310
|
}
|
|
296
311
|
});
|
|
@@ -334,6 +349,7 @@
|
|
|
334
349
|
transition: box-shadow 0.2s ease;
|
|
335
350
|
overflow: hidden; /* Prevent content overflow */
|
|
336
351
|
box-sizing: border-box; /* Include padding in size calculations */
|
|
352
|
+
contain: layout style paint; /* Browser optimization: isolate rendering from rest of page */
|
|
337
353
|
}
|
|
338
354
|
|
|
339
355
|
.chart-card:hover {
|
|
@@ -2,6 +2,56 @@
|
|
|
2
2
|
* Chart-specific adaptation utilities for Plotly layouts
|
|
3
3
|
* Handles size-based adaptations while preserving external styling/theming
|
|
4
4
|
*/
|
|
5
|
+
/**
|
|
6
|
+
* Adapts hover behavior based on container size and series count
|
|
7
|
+
* Optimizes tooltip display and performance for different chart sizes
|
|
8
|
+
*/
|
|
9
|
+
function adaptHoverBehavior(layout, containerSize, chartInfo) {
|
|
10
|
+
const { width, height } = containerSize;
|
|
11
|
+
const isTiny = width < 250 || height < 200;
|
|
12
|
+
const isSmall = width < 400 || height < 300;
|
|
13
|
+
const isMedium = width < 600 || height < 400;
|
|
14
|
+
const totalSeries = chartInfo.leftSeriesCount + chartInfo.rightSeriesCount;
|
|
15
|
+
// Priority 1: Disable hover in tiny charts (performance + UX)
|
|
16
|
+
if (isTiny) {
|
|
17
|
+
layout.hovermode = 'closest'; // Single point instead of unified
|
|
18
|
+
if (layout.hoverlabel) {
|
|
19
|
+
layout.hoverlabel.font = layout.hoverlabel.font || {};
|
|
20
|
+
layout.hoverlabel.font.size = 9; // Smaller font
|
|
21
|
+
}
|
|
22
|
+
return layout;
|
|
23
|
+
}
|
|
24
|
+
// Priority 2: Simplify hover in small charts
|
|
25
|
+
if (isSmall) {
|
|
26
|
+
layout.hovermode = 'x'; // Single point instead of unified
|
|
27
|
+
if (layout.hoverlabel) {
|
|
28
|
+
layout.hoverlabel.font = layout.hoverlabel.font || {};
|
|
29
|
+
layout.hoverlabel.font.size = 9; // Smaller font
|
|
30
|
+
}
|
|
31
|
+
return layout;
|
|
32
|
+
}
|
|
33
|
+
// Priority 3: Adaptive hover mode based on series count
|
|
34
|
+
if (totalSeries > 4 && isMedium) {
|
|
35
|
+
// Too many series in medium chart - switch to closest
|
|
36
|
+
layout.hovermode = 'x';
|
|
37
|
+
}
|
|
38
|
+
else if (totalSeries > 8) {
|
|
39
|
+
// Very many series - even in large charts, use x
|
|
40
|
+
layout.hovermode = 'x';
|
|
41
|
+
}
|
|
42
|
+
// Otherwise keep default 'x unified' from base layout
|
|
43
|
+
// Priority 4: Adaptive hover label font size
|
|
44
|
+
if (layout.hoverlabel) {
|
|
45
|
+
layout.hoverlabel.font = layout.hoverlabel.font || {};
|
|
46
|
+
if (isMedium) {
|
|
47
|
+
layout.hoverlabel.font.size = 10;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
layout.hoverlabel.font.size = 11; // Default for large
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return layout;
|
|
54
|
+
}
|
|
5
55
|
/**
|
|
6
56
|
* Adapts a Plotly layout based on container size
|
|
7
57
|
* Preserves external styling while optimizing functional properties
|
|
@@ -96,6 +146,8 @@ export function adaptPlotlyLayout(baseLayout, containerSize, chartInfo, config =
|
|
|
96
146
|
adaptedLayout.legend.font.size = 11;
|
|
97
147
|
}
|
|
98
148
|
}
|
|
149
|
+
// Apply adaptive hover behavior (disable in tiny, simplify in small, optimize for series count)
|
|
150
|
+
adaptHoverBehavior(adaptedLayout, containerSize, chartInfo);
|
|
99
151
|
return adaptedLayout;
|
|
100
152
|
}
|
|
101
153
|
/**
|
|
@@ -201,7 +201,7 @@ export function createDefaultPlotlyLayout(title) {
|
|
|
201
201
|
paper_bgcolor: 'rgba(0,0,0,0)',
|
|
202
202
|
plot_bgcolor: 'rgba(0,0,0,0)',
|
|
203
203
|
font: { family: 'Inter, -apple-system, BlinkMacSystemFont, sans-serif' },
|
|
204
|
-
hovermode: 'x
|
|
204
|
+
hovermode: 'x',
|
|
205
205
|
hoverlabel: {
|
|
206
206
|
font: {
|
|
207
207
|
family: 'Inter, Segoe UI, Tahoma, Geneva, Verdana, sans-serif',
|