CoolFace
Apppublic

lerobot/robot-learning-tutorial

sourceHugging Faceupdated 1y agoView on Hugging Face
508likes
TrackioWrapper.astro438 linesDownload Raw Back to components
1---2// TrackioWrapper.astro3import Trackio from './trackio/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<link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;600;700&display=swap" rel="stylesheet">10 11<div class="trackio-wrapper">12  <div class="trackio-controls">13    <div class="controls-left">14      <div class="theme-selector">15        <label for="theme-select">Theme</label>16        <select id="theme-select" class="theme-select">17          <option value="classic">Classic</option>18          <option value="oblivion">Oblivion</option>19        </select>20      </div>21      <div class="scale-controls">22        <label>23          <input type="checkbox" id="log-scale-x" checked>24          Log Scale X25        </label>26        <label>27          <input type="checkbox" id="smooth-data" checked>28          Smooth29        </label>30      </div>31    </div>32    <div class="controls-right">33      <button class="button button--ghost" type="button" id="randomize-btn">34        Randomize Data35      </button>36      <button class="button button--primary" type="button" id="start-simulation-btn">37        Live Run38      </button>39      <button class="button button--danger" type="button" id="stop-simulation-btn" style="display: none;">40        Stop41      </button>42    </div>43  </div>44  45  <div class="trackio-container">46    <Trackio client:load variant="classic" logScaleX={true} smoothing={true} />47  </div>48</div>49 50<script>51  // @ts-nocheck52  document.addEventListener('DOMContentLoaded', async () => {53    const themeSelect = document.getElementById('theme-select');54    const randomizeBtn = document.getElementById('randomize-btn');55    const startSimulationBtn = document.getElementById('start-simulation-btn');56    const stopSimulationBtn = document.getElementById('stop-simulation-btn');57    const logScaleXCheckbox = document.getElementById('log-scale-x');58    const smoothDataCheckbox = document.getElementById('smooth-data');59    const trackioContainer = document.querySelector('.trackio-container');60    61    if (!themeSelect || !randomizeBtn || !startSimulationBtn || !stopSimulationBtn || 62        !logScaleXCheckbox || !smoothDataCheckbox || !trackioContainer) return;63        64    // Variables pour la simulation65    let simulationInterval = null;66    let currentSimulationRun = null;67    let currentStep = 0;68    69    // Import the store function70    const { triggerJitter } = await import('./trackio/core/store.js');71    72    // Theme change handler73    themeSelect.addEventListener('change', (e) => {74      const target = e.target;75      if (!target || !('value' in target)) return;76      77      const newVariant = target.value;78      console.log(`Theme changed to: ${newVariant}`); // Debug log79      80      // Find the trackio element and call setTheme on the Svelte instance81      const trackioEl = debugTrackioState();82      if (trackioEl && trackioEl.__trackioInstance) {83        console.log('✅ Calling setTheme on Trackio instance');84        trackioEl.__trackioInstance.setTheme(newVariant);85      } else {86        console.warn('❌ No Trackio instance found for theme change');87      }88    });89 90    // Log scale X change handler91    logScaleXCheckbox.addEventListener('change', (e) => {92      const target = e.target;93      if (!target || !('checked' in target)) return;94      95      const isLogScale = target.checked;96      console.log(`Log scale X changed to: ${isLogScale}`); // Debug log97      98      // Find the trackio element and call setLogScaleX on the Svelte instance99      const trackioEl = debugTrackioState();100      if (trackioEl && trackioEl.__trackioInstance) {101        console.log('✅ Calling setLogScaleX on Trackio instance');102        trackioEl.__trackioInstance.setLogScaleX(isLogScale);103      } else {104        console.warn('❌ Trackio instance not found for log scale change');105      }106    });107 108    // Smooth data change handler109    smoothDataCheckbox.addEventListener('change', (e) => {110      const target = e.target;111      if (!target || !('checked' in target)) return;112      113      const isSmooth = target.checked;114      console.log(`Smooth data changed to: ${isSmooth}`); // Debug log115      116      // Find the trackio element and call setSmoothing on the Svelte instance117      const trackioEl = debugTrackioState();118      if (trackioEl && trackioEl.__trackioInstance) {119        console.log('✅ Calling setSmoothing on Trackio instance');120        trackioEl.__trackioInstance.setSmoothing(isSmooth);121      } else {122        console.warn('❌ Trackio instance not found for smooth change');123      }124    });125    126    // Debug function to check trackio state127    function debugTrackioState() {128      const trackioEl = trackioContainer.querySelector('.trackio');129      console.log('🔍 Debug Trackio state:', {130        container: !!trackioContainer,131        trackioEl: !!trackioEl,132        hasInstance: !!(trackioEl && trackioEl.__trackioInstance),133        availableMethods: trackioEl && trackioEl.__trackioInstance ? Object.keys(trackioEl.__trackioInstance) : 'none',134        windowInstance: !!window.trackioInstance135      });136      return trackioEl;137    }138    139    // Initialize with default checked states - increased delay and retry logic140    function initializeTrackio(attempt = 1) {141      console.log(`🚀 Initializing Trackio (attempt ${attempt})`);142      143      const trackioEl = debugTrackioState();144      145      if (trackioEl && trackioEl.__trackioInstance) {146        console.log('✅ Trackio instance found, applying initial settings');147        148        if (logScaleXCheckbox.checked) {149          console.log('Initializing with log scale X enabled');150          trackioEl.__trackioInstance.setLogScaleX(true);151        }152        153        if (smoothDataCheckbox.checked) {154          console.log('Initializing with smoothing enabled');155          trackioEl.__trackioInstance.setSmoothing(true);156        }157      } else {158        console.log('❌ Trackio instance not ready yet');159        if (attempt < 10) {160          setTimeout(() => initializeTrackio(attempt + 1), 200 * attempt);161        } else {162          console.error('Failed to initialize Trackio after 10 attempts');163        }164      }165    }166    167    // Start initialization168    setTimeout(() => initializeTrackio(), 100);169    170    // Fonction pour générer une nouvelle valeur de métrique simulée171    function generateSimulatedValue(step, metric) {172      const baseProgress = Math.min(1, step / 100); // Normalise sur 100 steps173      174      if (metric === 'loss') {175        // Loss qui décroit avec du bruit176        const baseLoss = 2.0 * Math.exp(-0.05 * step);177        const noise = (Math.random() - 0.5) * 0.2;178        return Math.max(0.01, baseLoss + noise);179      } else if (metric === 'accuracy') {180        // Accuracy qui augmente avec du bruit181        const baseAcc = 0.1 + 0.8 * (1 - Math.exp(-0.04 * step));182        const noise = (Math.random() - 0.5) * 0.05;183        return Math.max(0, Math.min(1, baseAcc + noise));184      }185      return Math.random();186    }187    188    // Gestionnaire pour démarrer la simulation189    function startSimulation() {190      if (simulationInterval) {191        clearInterval(simulationInterval);192      }193      194      // Générer un nouveau nom de run195      const adjectives = ['live', 'real-time', 'streaming', 'dynamic', 'active', 'running'];196      const nouns = ['experiment', 'trial', 'session', 'training', 'run', 'test'];197      const randomAdj = adjectives[Math.floor(Math.random() * adjectives.length)];198      const randomNoun = nouns[Math.floor(Math.random() * nouns.length)];199      currentSimulationRun = `${randomAdj}-${randomNoun}-${Date.now().toString().slice(-4)}`;200      currentStep = 1; // Commencer à step 1201      202      console.log(`Starting simulation for run: ${currentSimulationRun}`);203      204      // Interface UI205      startSimulationBtn.style.display = 'none';206      stopSimulationBtn.style.display = 'inline-flex';207      startSimulationBtn.disabled = true;208      209      // Ajouter le premier point210      addSimulationStep();211      212      // Continuer chaque seconde213      simulationInterval = setInterval(() => {214        currentStep++;215        addSimulationStep();216        217        // Arrêter après 200 steps pour éviter l'infini218        if (currentStep > 200) {219          stopSimulation();220        }221      }, 1000); // Chaque seconde222    }223    224    // Fonction pour ajouter un nouveau point de données225    function addSimulationStep() {226      const trackioEl = trackioContainer.querySelector('.trackio');227      if (trackioEl && trackioEl.__trackioInstance) {228        const newDataPoint = {229          step: currentStep,230          loss: generateSimulatedValue(currentStep, 'loss'),231          accuracy: generateSimulatedValue(currentStep, 'accuracy')232        };233        234        console.log(`Adding simulation step ${currentStep} for run ${currentSimulationRun}:`, newDataPoint);235        236        // Ajouter le point via l'instance Trackio237        if (typeof trackioEl.__trackioInstance.addLiveDataPoint === 'function') {238          trackioEl.__trackioInstance.addLiveDataPoint(currentSimulationRun, newDataPoint);239        } else {240          console.warn('addLiveDataPoint method not found on Trackio instance');241        }242      }243    }244    245    // Gestionnaire pour arrêter la simulation  246    function stopSimulation() {247      if (simulationInterval) {248        clearInterval(simulationInterval);249        simulationInterval = null;250      }251      252      console.log(`Stopping simulation for run: ${currentSimulationRun}`);253      254      // Interface UI255      startSimulationBtn.style.display = 'inline-flex';256      stopSimulationBtn.style.display = 'none';257      startSimulationBtn.disabled = false;258      259      currentSimulationRun = null;260      currentStep = 0;261    }262    263    // Event listeners pour les boutons de simulation264    startSimulationBtn.addEventListener('click', startSimulation);265    stopSimulationBtn.addEventListener('click', stopSimulation);266    267    // Arrêter la simulation si l'utilisateur quitte la page268    window.addEventListener('beforeunload', stopSimulation);269    270    // Randomize data handler - now uses the store271    randomizeBtn.addEventListener('click', () => {272      console.log('Randomize button clicked - triggering jitter via store'); // Debug log273      274      // Arrêter la simulation en cours si elle tourne275      if (simulationInterval) {276        stopSimulation();277      }278      279      // Add vibration animation280      randomizeBtn.classList.add('vibrating');281      setTimeout(() => {282        randomizeBtn.classList.remove('vibrating');283      }, 600);284      285      // Test direct window approach as well286      if (window.trackioInstance && typeof window.trackioInstance.jitterData === 'function') {287        console.log('Found window.trackioInstance, calling jitterData directly'); // Debug log288        window.trackioInstance.jitterData();289      } else {290        console.log('No window.trackioInstance found, using store trigger'); // Debug log291        triggerJitter();292      }293    });294  });295</script>296 297<style>298  .trackio-wrapper {299    width: 100%;300    margin: 0px 0 20px 0;301  }302  303  .trackio-controls {304    display: flex;305    justify-content: space-between;306    align-items: center;307    margin-bottom: 16px;308    padding: 12px 0px;309    /* border-bottom: 1px solid var(--border-color); */310    gap: 16px;311    flex-wrap: nowrap;312  }313  314  .controls-left {315    display: flex;316    align-items: center;317    gap: 24px;318    flex-wrap: wrap;319  }320  321  .controls-right {322    display: flex;323    align-items: center;324    gap: 12px;325    flex-wrap: wrap;326  }327  328  .btn-randomize {329    display: inline-flex;330    align-items: center;331    gap: 6px;332    padding: 8px 16px;333    background: var(--accent-color, #007acc);334    color: white;335    border: none;336    border-radius: 6px;337    font-size: 14px;338    font-weight: 500;339    cursor: pointer;340    transition: all 0.15s ease;341  }342  343  .btn-randomize:hover {344    background: var(--accent-hover, #005a9e);345    transform: translateY(-1px);346  }347  348  .btn-randomize:active {349    transform: translateY(0);350  }351  352  .theme-selector {353    display: flex;354    align-items: center;355    gap: 8px;356    font-size: 14px;357    flex-shrink: 0;358    white-space: nowrap;359  }360  361  .theme-selector label {362    font-weight: 500;363    color: var(--text-color);364  }365  366  .theme-select {367    padding: 6px 12px;368    border: 1px solid var(--border-color);369    border-radius: 4px;370    background: var(--input-bg, var(--surface-bg));371    color: var(--text-color);372    font-size: 14px;373    cursor: pointer;374    transition: border-color 0.15s ease;375  }376  377  .theme-select:focus {378    outline: none;379    border-color: var(--accent-color, #007acc);380  }381  382  .scale-controls {383    display: flex;384    align-items: center;385    gap: 16px;386    flex-shrink: 0;387    white-space: nowrap;388  }389  390  /* Animation de vibration pour le bouton */391  @keyframes vibrate {392    0% { transform: translateX(0); }393    10% { transform: translateX(-2px) rotate(-1deg); }394    20% { transform: translateX(2px) rotate(1deg); }395    30% { transform: translateX(-2px) rotate(-1deg); }396    40% { transform: translateX(2px) rotate(1deg); }397    50% { transform: translateX(-1px) rotate(-0.5deg); }398    60% { transform: translateX(1px) rotate(0.5deg); }399    70% { transform: translateX(-1px) rotate(-0.5deg); }400    80% { transform: translateX(1px) rotate(0.5deg); }401    90% { transform: translateX(-0.5px) rotate(-0.25deg); }402    100% { transform: translateX(0) rotate(0); }403  }404  405  .button.vibrating {406    animation: vibrate 0.6s ease-in-out;407  }408  409  .trackio-container {410    width: 100%;411    margin-top: 10px;412    border: 1px solid var(--border-color);413    padding: 24px 12px;414 415  }416  417  @media (max-width: 768px) {418    .trackio-controls {419      flex-direction: column;420      align-items: stretch;421      gap: 12px;422    }423    424    .controls-left {425      flex-direction: column;426      align-items: stretch;427      gap: 12px;428    }429    430    .theme-selector {431      justify-content: space-between;432    }433    434    .scale-controls {435      justify-content: space-between;436    }437  }438</style>