CoolFace
Apppublic

lerobot/robot-learning-tutorial

sourceHugging Faceupdated 1y agoView on Hugging Face
508likes
TrackioWrapper.astro511 linesDownload Raw Back to trackio
1---2// TrackioWrapper.astro3import Trackio from "./Trackio.svelte";4---5 6<!-- Ensure Roboto Mono is loaded for Oblivion theme -->7<link rel="preconnect" href="https://fonts.googleapis.com" />8<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />9<link10  href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;600;700&display=swap"11  rel="stylesheet"12/>13 14<div class="trackio-wrapper">15  <div class="trackio-controls">16    <div class="controls-left">17      <div class="theme-selector">18        <label for="theme-select">Theme</label>19        <select id="theme-select" class="theme-select">20          <option value="classic">Classic</option>21          <option value="oblivion">Oblivion</option>22        </select>23      </div>24      <div class="scale-controls">25        <label>26          <input type="checkbox" id="log-scale-x" checked />27          Log Scale X28        </label>29        <label>30          <input type="checkbox" id="smooth-data" checked />31          Smooth32        </label>33      </div>34    </div>35    <div class="controls-right">36      <button class="button button--ghost" type="button" id="randomize-btn">37        Randomize Data38      </button>39      <button40        class="button button--primary"41        type="button"42        id="start-simulation-btn"43      >44        Live Run45      </button>46      <button47        class="button button--danger"48        type="button"49        id="stop-simulation-btn"50        style="display: none;"51      >52        Stop53      </button>54    </div>55  </div>56 57  <div class="trackio-container">58    <Trackio client:load variant="classic" logScaleX={true} smoothing={true} />59  </div>60</div>61 62<script>63  // @ts-nocheck64  document.addEventListener("DOMContentLoaded", async () => {65    const themeSelect = document.getElementById("theme-select");66    const randomizeBtn = document.getElementById("randomize-btn");67    const startSimulationBtn = document.getElementById("start-simulation-btn");68    const stopSimulationBtn = document.getElementById("stop-simulation-btn");69    const logScaleXCheckbox = document.getElementById("log-scale-x");70    const smoothDataCheckbox = document.getElementById("smooth-data");71    const trackioContainer = document.querySelector(".trackio-container");72 73    if (74      !themeSelect ||75      !randomizeBtn ||76      !startSimulationBtn ||77      !stopSimulationBtn ||78      !logScaleXCheckbox ||79      !smoothDataCheckbox ||80      !trackioContainer81    )82      return;83 84    // Variables for simulation85    let simulationInterval = null;86    let currentSimulationRun = null;87    let currentStep = 0;88 89    // Import the store function90    const { triggerJitter } = await import("./core/store.js");91 92    // Theme change handler93    themeSelect.addEventListener("change", (e) => {94      const target = e.target;95      if (!target || !("value" in target)) return;96 97      const newVariant = target.value;98      console.log(`Theme changed to: ${newVariant}`); // Debug log99 100      // Find the trackio element and call setTheme on the Svelte instance101      const trackioEl = debugTrackioState();102      if (trackioEl && trackioEl.__trackioInstance) {103        console.log("✅ Calling setTheme on Trackio instance");104        trackioEl.__trackioInstance.setTheme(newVariant);105      } else {106        console.warn("❌ No Trackio instance found for theme change");107      }108    });109 110    // Log scale X change handler111    logScaleXCheckbox.addEventListener("change", (e) => {112      const target = e.target;113      if (!target || !("checked" in target)) return;114 115      const isLogScale = target.checked;116      console.log(`Log scale X changed to: ${isLogScale}`); // Debug log117 118      // Find the trackio element and call setLogScaleX on the Svelte instance119      const trackioEl = debugTrackioState();120      if (trackioEl && trackioEl.__trackioInstance) {121        console.log("✅ Calling setLogScaleX on Trackio instance");122        trackioEl.__trackioInstance.setLogScaleX(isLogScale);123      } else {124        console.warn("❌ Trackio instance not found for log scale change");125      }126    });127 128    // Smooth data change handler129    smoothDataCheckbox.addEventListener("change", (e) => {130      const target = e.target;131      if (!target || !("checked" in target)) return;132 133      const isSmooth = target.checked;134      console.log(`Smooth data changed to: ${isSmooth}`); // Debug log135 136      // Find the trackio element and call setSmoothing on the Svelte instance137      const trackioEl = debugTrackioState();138      if (trackioEl && trackioEl.__trackioInstance) {139        console.log("✅ Calling setSmoothing on Trackio instance");140        trackioEl.__trackioInstance.setSmoothing(isSmooth);141      } else {142        console.warn("❌ Trackio instance not found for smooth change");143      }144    });145 146    // Debug function to check trackio state147    function debugTrackioState() {148      const trackioEl = trackioContainer.querySelector(".trackio");149      console.log("🔍 Debug Trackio state:", {150        container: !!trackioContainer,151        trackioEl: !!trackioEl,152        hasInstance: !!(trackioEl && trackioEl.__trackioInstance),153        availableMethods:154          trackioEl && trackioEl.__trackioInstance155            ? Object.keys(trackioEl.__trackioInstance)156            : "none",157        windowInstance: !!window.trackioInstance,158      });159      return trackioEl;160    }161 162    // Initialize with default checked states - increased delay and retry logic163    function initializeTrackio(attempt = 1) {164      console.log(`🚀 Initializing Trackio (attempt ${attempt})`);165 166      const trackioEl = debugTrackioState();167 168      if (trackioEl && trackioEl.__trackioInstance) {169        console.log("✅ Trackio instance found, applying initial settings");170 171        if (logScaleXCheckbox.checked) {172          console.log("Initializing with log scale X enabled");173          trackioEl.__trackioInstance.setLogScaleX(true);174        }175 176        if (smoothDataCheckbox.checked) {177          console.log("Initializing with smoothing enabled");178          trackioEl.__trackioInstance.setSmoothing(true);179        }180      } else {181        console.log("❌ Trackio instance not ready yet");182        if (attempt < 10) {183          setTimeout(() => initializeTrackio(attempt + 1), 200 * attempt);184        } else {185          console.error("Failed to initialize Trackio after 10 attempts");186        }187      }188    }189 190    // Start initialization191    setTimeout(() => initializeTrackio(), 100);192 193    // Function to generate a new simulated metric value194    function generateSimulatedValue(step, metric) {195      const baseProgress = Math.min(1, step / 100); // Normalise sur 100 steps196 197      if (metric === "loss") {198        // Loss that decreases with noise199        const baseLoss = 2.0 * Math.exp(-0.05 * step);200        const noise = (Math.random() - 0.5) * 0.2;201        return Math.max(0.01, baseLoss + noise);202      } else if (metric === "accuracy") {203        // Accuracy that increases with noise204        const baseAcc = 0.1 + 0.8 * (1 - Math.exp(-0.04 * step));205        const noise = (Math.random() - 0.5) * 0.05;206        return Math.max(0, Math.min(1, baseAcc + noise));207      }208      return Math.random();209    }210 211    // Handler to start simulation212    function startSimulation() {213      if (simulationInterval) {214        clearInterval(simulationInterval);215      }216 217      // Générer un nouveau nom de run218      const adjectives = [219        "live",220        "real-time",221        "streaming",222        "dynamic",223        "active",224        "running",225      ];226      const nouns = [227        "experiment",228        "trial",229        "session",230        "training",231        "run",232        "test",233      ];234      const randomAdj =235        adjectives[Math.floor(Math.random() * adjectives.length)];236      const randomNoun = nouns[Math.floor(Math.random() * nouns.length)];237      currentSimulationRun = `${randomAdj}-${randomNoun}-${Date.now().toString().slice(-4)}`;238      currentStep = 1; // Commencer à step 1239 240      console.log(`Starting simulation for run: ${currentSimulationRun}`);241 242      // Interface UI243      startSimulationBtn.style.display = "none";244      stopSimulationBtn.style.display = "inline-flex";245      startSimulationBtn.disabled = true;246 247      // Ajouter le premier point248      addSimulationStep();249 250      // Continuer chaque seconde251      simulationInterval = setInterval(() => {252        currentStep++;253        addSimulationStep();254 255        // Stop after 200 steps to avoid infinity256        if (currentStep > 200) {257          stopSimulation();258        }259      }, 1000); // Chaque seconde260    }261 262    // Function to add a new data point263    function addSimulationStep() {264      const trackioEl = trackioContainer.querySelector(".trackio");265      if (trackioEl && trackioEl.__trackioInstance) {266        const newDataPoint = {267          step: currentStep,268          loss: generateSimulatedValue(currentStep, "loss"),269          accuracy: generateSimulatedValue(currentStep, "accuracy"),270        };271 272        console.log(273          `Adding simulation step ${currentStep} for run ${currentSimulationRun}:`,274          newDataPoint,275        );276 277        // Ajouter le point via l'instance Trackio278        if (279          typeof trackioEl.__trackioInstance.addLiveDataPoint === "function"280        ) {281          trackioEl.__trackioInstance.addLiveDataPoint(282            currentSimulationRun,283            newDataPoint,284          );285        } else {286          console.warn("addLiveDataPoint method not found on Trackio instance");287        }288      }289    }290 291    // Handler to stop simulation292    function stopSimulation() {293      if (simulationInterval) {294        clearInterval(simulationInterval);295        simulationInterval = null;296      }297 298      console.log(`Stopping simulation for run: ${currentSimulationRun}`);299 300      // Interface UI301      startSimulationBtn.style.display = "inline-flex";302      stopSimulationBtn.style.display = "none";303      startSimulationBtn.disabled = false;304 305      currentSimulationRun = null;306      currentStep = 0;307    }308 309    // Event listeners for simulation buttons310    startSimulationBtn.addEventListener("click", startSimulation);311    stopSimulationBtn.addEventListener("click", stopSimulation);312 313    // Arrêter la simulation si l'utilisateur quitte la page314    window.addEventListener("beforeunload", stopSimulation);315 316    // Randomize data handler - now uses the store317    randomizeBtn.addEventListener("click", () => {318      console.log("Randomize button clicked - triggering jitter via store"); // Debug log319 320      // Arrêter la simulation en cours si elle tourne321      if (simulationInterval) {322        stopSimulation();323      }324 325      // Add vibration animation326      randomizeBtn.classList.add("vibrating");327      setTimeout(() => {328        randomizeBtn.classList.remove("vibrating");329      }, 600);330 331      // Test direct window approach as well332      if (333        window.trackioInstance &&334        typeof window.trackioInstance.jitterData === "function"335      ) {336        console.log(337          "Found window.trackioInstance, calling jitterData directly",338        ); // Debug log339        window.trackioInstance.jitterData();340      } else {341        console.log("No window.trackioInstance found, using store trigger"); // Debug log342        triggerJitter();343      }344    });345  });346</script>347 348<style>349  .trackio-wrapper {350    width: 100%;351    margin: 0px 0 20px 0;352  }353 354  .trackio-controls {355    display: flex;356    justify-content: space-between;357    align-items: center;358    margin-bottom: 16px;359    padding: 12px 0px;360    /* border-bottom: 1px solid var(--border-color); */361    gap: 16px;362    flex-wrap: nowrap;363  }364 365  .controls-left {366    display: flex;367    align-items: center;368    gap: 24px;369    flex-wrap: wrap;370  }371 372  .controls-right {373    display: flex;374    align-items: center;375    gap: 12px;376    flex-wrap: wrap;377  }378 379  .btn-randomize {380    display: inline-flex;381    align-items: center;382    gap: 6px;383    padding: 8px 16px;384    background: var(--accent-color, #007acc);385    color: white;386    border: none;387    border-radius: 6px;388    font-size: 14px;389    font-weight: 500;390    cursor: pointer;391    transition: all 0.15s ease;392  }393 394  .btn-randomize:hover {395    background: var(--accent-hover, #005a9e);396    transform: translateY(-1px);397  }398 399  .btn-randomize:active {400    transform: translateY(0);401  }402 403  .theme-selector {404    display: flex;405    align-items: center;406    gap: 8px;407    font-size: 14px;408    flex-shrink: 0;409    white-space: nowrap;410  }411 412  .theme-selector label {413    font-weight: 500;414    color: var(--text-color);415  }416 417  .theme-select {418    padding: 6px 12px;419    border: 1px solid var(--border-color);420    border-radius: 4px;421    background: var(--input-bg, var(--surface-bg));422    color: var(--text-color);423    font-size: 14px;424    cursor: pointer;425    transition: border-color 0.15s ease;426  }427 428  .theme-select:focus {429    outline: none;430    border-color: var(--accent-color, #007acc);431  }432 433  .scale-controls {434    display: flex;435    align-items: center;436    gap: 16px;437    flex-shrink: 0;438    white-space: nowrap;439  }440 441  /* Vibration animation for button */442  @keyframes vibrate {443    0% {444      transform: translateX(0);445    }446    10% {447      transform: translateX(-2px) rotate(-1deg);448    }449    20% {450      transform: translateX(2px) rotate(1deg);451    }452    30% {453      transform: translateX(-2px) rotate(-1deg);454    }455    40% {456      transform: translateX(2px) rotate(1deg);457    }458    50% {459      transform: translateX(-1px) rotate(-0.5deg);460    }461    60% {462      transform: translateX(1px) rotate(0.5deg);463    }464    70% {465      transform: translateX(-1px) rotate(-0.5deg);466    }467    80% {468      transform: translateX(1px) rotate(0.5deg);469    }470    90% {471      transform: translateX(-0.5px) rotate(-0.25deg);472    }473    100% {474      transform: translateX(0) rotate(0);475    }476  }477 478  .button.vibrating {479    animation: vibrate 0.6s ease-in-out;480  }481 482  .trackio-container {483    width: 100%;484    margin-top: 10px;485    border: 1px solid var(--border-color);486    padding: 24px 12px;487  }488 489  @media (max-width: 768px) {490    .trackio-controls {491      flex-direction: column;492      align-items: stretch;493      gap: 12px;494    }495 496    .controls-left {497      flex-direction: column;498      align-items: stretch;499      gap: 12px;500    }501 502    .theme-selector {503      justify-content: space-between;504    }505 506    .scale-controls {507      justify-content: space-between;508    }509  }510</style>511