lerobot/robot-learning-tutorial
508
1<script>2 import { onMount } from 'svelte';3 4 // Props5 export let visible = false;6 export let x = -9999;7 export let y = -9999;8 export let title = '';9 export let subtitle = '';10 export let entries = []; // Array of { color, name, valueText }11 export let parentElement = null; // Element to append tooltip to12 export let zIndex = 1000; // Default z-index13 14 let tooltipElement;15 let tipHost;16 17 onMount(() => {18 // Find trackio parent for positioning context19 console.log('ChartTooltip onMount - parentElement:', parentElement);20 console.log('ChartTooltip onMount - parentElement classes:', parentElement?.className);21 22 const trackioEl = parentElement?.closest?.('.trackio') || (parentElement?.classList?.contains('trackio') ? parentElement : null);23 24 console.log('ChartTooltip onMount - trackioEl found:', trackioEl);25 26 if (trackioEl) {27 // Create tooltip host positioned relative to trackio container28 tipHost = document.createElement('div');29 tipHost.className = 'tip-host';30 tipHost.style.position = 'absolute';31 tipHost.style.top = '0';32 tipHost.style.left = '0';33 tipHost.style.width = '100%';34 tipHost.style.height = '100%';35 tipHost.style.pointerEvents = 'none';36 tipHost.style.zIndex = String(zIndex);37 tipHost.style.overflow = 'visible';38 trackioEl.appendChild(tipHost);39 40 // Move tooltip element to host41 if (tooltipElement && tipHost) {42 tipHost.appendChild(tooltipElement);43 }44 }45 46 return () => {47 if (tipHost && tipHost.parentNode) {48 tipHost.parentNode.removeChild(tipHost);49 }50 };51 });52 53 $: tooltipStyle = `54 transform: translate(${x}px, ${y}px);55 pointer-events: none;56 z-index: ${zIndex};57 `;58 59 $: tooltipClass = `d3-tooltip ${visible ? 'is-visible' : ''}`;60</script>61 62<div 63 bind:this={tooltipElement}64 class={tooltipClass}65 style={tooltipStyle}66>67 <div class="d3-tooltip__inner">68 {#if title}69 <div class="d3-tooltip__title">{@html title}</div>70 {/if}71 72 {#if subtitle}73 <div class="d3-tooltip__subtitle">{subtitle}</div>74 {/if}75 76 {#each entries as entry}77 <div class="d3-tooltip__entry">78 <span class="d3-tooltip__color-dot" style="background:{entry.color}"></span>79 <strong class="d3-tooltip__entry-name">{entry.name}</strong>80 <span class="d3-tooltip__entry-value">{entry.valueText}</span>81 </div>82 {/each}83 </div>84</div>85 86<style>87 /* Classic tooltip styling - based on original d3-trackio.html */88 .d3-tooltip {89 position: absolute;90 top: 0;91 left: 0;92 transform: translate(-9999px, -9999px);93 pointer-events: none;94 padding: 10px 12px;95 border-radius: 12px;96 font-size: 12px;97 line-height: 1.35;98 border: 1px solid var(--border-color);99 background: var(--surface-bg);100 color: var(--text-color);101 box-shadow: 0 8px 32px rgba(0,0,0,.12), 0 2px 8px rgba(0,0,0,.06);102 opacity: 0;103 transition: none;104 z-index: var(--z-tooltip, 50);105 backdrop-filter: saturate(1.12) blur(8px);106 }107 108 .d3-tooltip.is-visible {109 opacity: 1;110 }111 112 .d3-tooltip__inner {113 display: flex;114 flex-direction: column;115 gap: 6px;116 min-width: 220px;117 }118 119 .d3-tooltip__title {120 font-weight: 800;121 letter-spacing: 0.1px;122 margin-bottom: 0;123 color: var(--text-color);124 }125 126 .d3-tooltip__subtitle {127 font-size: 11px;128 color: var(--muted-color);129 display: block;130 margin-top: -4px;131 margin-bottom: 2px;132 letter-spacing: 0.1px;133 }134 135 .d3-tooltip__entry {136 padding-top: 6px;137 border-top: 1px solid var(--border-color);138 display: flex;139 align-items: center;140 gap: 8px;141 white-space: nowrap;142 }143 144 .d3-tooltip__entry-name {145 flex: 1;146 font-weight: 500;147 }148 149 .d3-tooltip__entry-value {150 margin-left: auto;151 text-align: right;152 font-weight: 900;153 }154 155 .d3-tooltip__color-dot {156 display: inline-block;157 width: 12px;158 height: 12px;159 border-radius: 3px;160 border: 1px solid var(--border-color);161 flex-shrink: 0;162 }163 164 /* Oblivion tooltip styling - based on original d3-trackio-oblivion.html */165 :global(.trackio.theme--oblivion) .d3-tooltip {166 border-radius: 8px;167 border: none;168 background: 169 radial-gradient(1200px 200px at 20% -10%, rgba(0,0,0,.05), transparent 80%),170 radial-gradient(900px 200px at 80% 110%, rgba(0,0,0,.05), transparent 80%);171 color: var(--trackio-text-primary);172 box-shadow: 0 8px 32px rgba(127,241,255,.05), 0 2px 8px rgba(0,0,0,.10);173 opacity: 0;174 backdrop-filter: saturate(1.1) blur(10px);175 }176 177 :global(.trackio.theme--oblivion) .d3-tooltip.is-visible {178 opacity: 1;179 }180 181 /* Dark mode oblivion tooltip */182 :global([data-theme="dark"]) :global(.trackio.theme--oblivion) .d3-tooltip {183 background:184 radial-gradient(1400px 260px at 20% -10%, color-mix(in srgb, #ffffff 6.5%, transparent), transparent 80%),185 radial-gradient(1100px 240px at 80% 110%, color-mix(in srgb, #ffffff 6%, transparent), transparent 80%),186 linear-gradient(180deg, color-mix(in srgb, #ffffff 3.5%, transparent), transparent 45%);187 color: var(--trackio-text-primary);188 box-shadow: 0 8px 32px color-mix(in srgb, #ffffff 5%, transparent), 0 2px 8px color-mix(in srgb, black 10%, transparent);189 }190 191 :global(.trackio.theme--oblivion) .d3-tooltip__title {192 font-weight: 900;193 letter-spacing: 0.18em;194 text-transform: uppercase;195 color: var(--trackio-oblivion-primary);196 }197 198 :global(.trackio.theme--oblivion) .d3-tooltip__subtitle {199 color: var(--trackio-oblivion-primary);200 opacity: 0.4;201 letter-spacing: 0.06em;202 }203 204 :global(.trackio.theme--oblivion) .d3-tooltip__entry {205 position: relative;206 padding-top: 10px;207 margin-top: 6px;208 border-top: none;209 }210 211 :global(.trackio.theme--oblivion) .d3-tooltip__entry::before {212 content: "";213 position: absolute;214 left: 0;215 right: 0;216 top: 0;217 height: 1px;218 background: color-mix(in srgb, #000000 10%, transparent);219 }220 221 :global(.trackio.theme--oblivion) .d3-tooltip__entry::after {222 content: "";223 position: absolute;224 left: 0;225 right: 0;226 top: 1px;227 height: 1px;228 background: color-mix(in srgb, #ffffff 15%, transparent);229 }230 231 /* Dark mode separator adjustments */232 :global([data-theme="dark"]) :global(.trackio.theme--oblivion) .d3-tooltip__entry::before {233 background: color-mix(in srgb, #ffffff 5%, transparent);234 }235 236 :global([data-theme="dark"]) :global(.trackio.theme--oblivion) .d3-tooltip__entry::after {237 background: color-mix(in srgb, #000000 10%, transparent);238 }239 240 :global(.trackio.theme--oblivion) .d3-tooltip__color-dot {241 border-radius: 2px;242 border: 1px solid var(--obl-border, rgba(50, 50, 50, 0.22));243 box-shadow: 0 0 10px color-mix(in srgb, var(--obl-base, #323232) 20%, transparent) inset;244 }245</style>246 