diff --git a/training/dashboard/static/dashboard.js b/training/dashboard/static/dashboard.js
index 51c4131..fb29ff6 100644
--- a/training/dashboard/static/dashboard.js
+++ b/training/dashboard/static/dashboard.js
@@ -2102,8 +2102,29 @@ def train_nn(*, model, X_train, y_train, X_val, y_val,
rebuildLegend();
}
- on('demo_start', loadSynthetic);
- on('demo_stop', () => { points.length = 0; resetStats(); rebuildLegend(); });
+ // Exclusive: demo on → only synthetic clusters; demo off → only
+ // real embedding events. cachedReal accumulates real points
+ // even while demo is on, so demo_stop restores them.
+ let demoActive = false;
+ const cachedReal = [];
+ const REAL_CACHE_CAP = 5000;
+ function repaintFromReal() {
+ points.length = 0;
+ resetStats();
+ for (const pt of cachedReal) {
+ points.push(pt);
+ addStat(pt);
+ }
+ rebuildLegend();
+ }
+ on('demo_start', () => {
+ demoActive = true;
+ loadSynthetic();
+ });
+ on('demo_stop', () => {
+ demoActive = false;
+ repaintFromReal();
+ });
on('embedding', m => {
if (typeof m.x !== 'number' || typeof m.y !== 'number') return;
const pt = {
@@ -2113,9 +2134,13 @@ def train_nn(*, model, X_train, y_train, X_val, y_val,
predicted: m.predicted,
cluster: typeof m.cluster === 'number' ? m.cluster : undefined,
};
- points.push(pt);
- addStat(pt);
- rebuildLegend();
+ cachedReal.push(pt);
+ if (cachedReal.length > REAL_CACHE_CAP) cachedReal.shift();
+ if (!demoActive) {
+ points.push(pt);
+ addStat(pt);
+ rebuildLegend();
+ }
});
rebuildLegend();
diff --git a/training/dashboard/static/index.html b/training/dashboard/static/index.html
index a347f5e..b85b8c1 100644
--- a/training/dashboard/static/index.html
+++ b/training/dashboard/static/index.html
@@ -1314,6 +1314,6 @@
-
+