ztxtech commited on
Commit
63808a2
·
verified ·
1 Parent(s): 123e888

Fix per-series forecast controls

Browse files

Move horizons into series cards, connect forecast lines, and use one-based time indexes.

README.md CHANGED
@@ -14,7 +14,7 @@ A private browser interface for Fracast-0.
14
 
15
  The page automatically downloads the 113 KB W8 checkpoint and records the loading time. It starts with an empty series workspace. A preset selector loads synthetic Traffic, Sensor, Load, or two-channel Demo data; the source note states that these are deterministic synthetic examples rather than public dataset extracts. Each channel receives its own compact forecast chart.
16
 
17
- The browser runtime uses the checkpoint's native 48-step head. The horizon slider selects 8 to 48 steps and trims the native forecast; it does not perform recursive long-horizon rollout. Synthetic presets reserve the selected number of final observations as held-out ground truth. Hand-edited inputs have no held-out truth. The activity log records checkpoint loading, input series count, input lengths, forecast time, throughput, and selected horizon.
18
 
19
  Forecasting runs locally in page memory for up to six channel-independent series. Chart.js renders each median forecast with a 0.1-0.9 quantile band. No service worker or persistent Cache API is used, so closing the page releases the model.
20
 
 
14
 
15
  The page automatically downloads the 113 KB W8 checkpoint and records the loading time. It starts with an empty series workspace. A preset selector loads synthetic Traffic, Sensor, Load, or two-channel Demo data; the source note states that these are deterministic synthetic examples rather than public dataset extracts. Each channel receives its own compact forecast chart.
16
 
17
+ The browser runtime uses the checkpoint's native 48-step head. Each series card has its own 8-48 step horizon slider and trims the native forecast; it does not perform recursive long-horizon rollout. Synthetic presets reserve that series' selected number of final observations as held-out ground truth. Hand-edited inputs have no held-out truth. The activity log records checkpoint loading, input series count, input lengths, forecast time, throughput, and selected horizons.
18
 
19
  Forecasting runs locally in page memory for up to six channel-independent series. Chart.js renders each median forecast with a 0.1-0.9 quantile band. No service worker or persistent Cache API is used, so closing the page releases the model.
20
 
assets/{index.gyeZP3tu.css → index.DRUfRDea.css} RENAMED
@@ -1 +1 @@
1
- :root{color-scheme:light;font-family:Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,sans-serif;color:#1c252b;background:#eef0ed}*{box-sizing:border-box}[hidden]{display:none!important}body{margin:0}.shell{width:min(1320px,calc(100% - 40px));margin:0 auto;padding:34px 0 42px}.top{display:flex;align-items:end;justify-content:space-between;gap:20px;margin-bottom:18px}h1{margin:0;font-size:30px;letter-spacing:0}.top p{margin:4px 0 0;color:#5c686f;font-size:14px}.status-group{display:grid;justify-items:end;gap:6px;min-width:min(390px,100%)}#status{min-height:22px;color:#5c686f;font-size:13px;text-align:right}.progress-track{width:min(320px,100%);height:4px;overflow:hidden;border-radius:999px;background:#d9dfda;opacity:0;transition:opacity .16s ease}.progress-track.visible{opacity:1}.progress-bar{width:0;height:100%;border-radius:inherit;background:#17786f;transition:width .12s linear}.workspace{min-width:0;display:grid;grid-template-columns:minmax(330px,390px) minmax(0,1fr);gap:16px;align-items:start}.input-pane,.activity-pane{background:#fff;border:1px solid #d9dfda;border-radius:8px;box-shadow:0 8px 22px #1c252b0a}.input-pane{padding:16px}.pane-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}h2{margin:0;font-size:16px}button{height:32px;border:1px solid #ccd4cf;border-radius:6px;padding:0 11px;background:#fff;color:#2b353b;font-size:13px;font-weight:600}button:hover:not(:disabled){background:#f2f5f1}button.primary{width:100%;margin-top:12px;border-color:#17786f;background:#17786f;color:#fff}button.primary:hover:not(:disabled){background:#116059}button:disabled{border-color:#ccd4cf;background:#eef0ed;color:#8b9499;cursor:not-allowed}.empty-text{margin:0 0 12px;padding:18px 10px;border:1px dashed #ccd4cf;border-radius:6px;color:#69757b;font-size:13px;text-align:center}.series-card{margin-bottom:10px;padding:10px;border:1px solid #dfe4df;border-radius:6px;background:#fbfcfa}.series-head{display:grid;grid-template-columns:54px minmax(0,1fr) auto;gap:7px;align-items:center;margin-bottom:7px}label{font-size:12px;font-weight:650;color:#59646a}.name{height:30px;min-width:0;border:1px solid #ccd4cf;border-radius:5px;padding:0 8px;font:13px Inter,sans-serif;color:inherit}.remove{height:28px;padding:0 8px;font-size:12px}textarea{width:100%;min-height:92px;resize:vertical;border:1px solid #ccd4cf;border-radius:5px;padding:8px;font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;color:inherit;background:#fff}.name:focus,textarea:focus{outline:2px solid #17786f;outline-offset:1px}.control-block{margin-bottom:14px}select{width:100%;height:32px;border:1px solid #ccd4cf;border-radius:5px;background:#fff;padding:0 8px;font:13px Inter,sans-serif;color:inherit}.source-note{margin:6px 0 0;color:#69757b;font-size:12px;line-height:1.45}.horizon-head{display:flex;align-items:center;justify-content:space-between;gap:10px}.horizon-head output{color:#17786f;font-size:12px;font-weight:700;font-variant-numeric:tabular-nums}input[type=range]{width:100%;margin:10px 0 2px;accent-color:#17786f}.plot-pane{min-width:0;display:grid;gap:12px;align-content:start;max-height:720px;overflow-y:auto;padding-right:2px}.chart-card{background:#fff;border:1px solid #d9dfda;border-radius:8px;box-shadow:0 8px 22px #1c252b0a;padding:12px}.chart-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:8px}.chart-title{flex:none;margin:0;font-size:14px}.chart-source{min-width:0;flex:1;overflow-wrap:anywhere;color:#69757b;font-size:11px;text-align:right}.chart-body{position:relative;height:270px}canvas{display:block;max-width:100%;width:100%;height:100%}.plot-empty{display:grid;place-items:center;min-height:270px;border:1px dashed #ccd4cf;border-radius:8px;background:#fff;padding:20px;color:#69757b;font-size:14px;text-align:center}.activity-pane{margin-top:16px;padding:14px 16px}.activity-state{color:#69757b;font-size:12px}.activity-list{display:grid;gap:7px;max-height:178px;margin:0;padding:0;overflow-y:auto;list-style:none}.activity-item{display:grid;grid-template-columns:66px minmax(0,1fr);gap:10px;padding:7px 9px;border:1px solid #e0e5e0;border-radius:6px;background:#fbfcfa;color:#364248;font-size:12px;line-height:1.45}.activity-item.error{border-color:#e2b8b8;background:#fdf5f4;color:#8d3332}.activity-time{color:#758086;font-variant-numeric:tabular-nums}@media(max-width:920px){.shell{width:min(100% - 24px,1320px);padding-top:24px}.workspace{grid-template-columns:1fr}.top{align-items:start;flex-direction:column}.status-group{justify-items:start;min-width:100%}#status,.progress-track{text-align:left}.plot-pane{max-height:none;overflow:visible;padding-right:0}.chart-body{height:230px}.activity-item{grid-template-columns:58px minmax(0,1fr)}}.workspace>*{min-width:0}
 
1
+ :root{color-scheme:light;font-family:Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,sans-serif;color:#1c252b;background:#eef0ed}*{box-sizing:border-box}[hidden]{display:none!important}body{margin:0}.shell{width:min(1320px,calc(100% - 40px));margin:0 auto;padding:34px 0 42px}.top{display:flex;align-items:end;justify-content:space-between;gap:20px;margin-bottom:18px}h1{margin:0;font-size:30px;letter-spacing:0}.top p{margin:4px 0 0;color:#5c686f;font-size:14px}.status-group{display:grid;justify-items:end;gap:6px;min-width:min(390px,100%)}#status{min-height:22px;color:#5c686f;font-size:13px;text-align:right}.progress-track{width:min(320px,100%);height:4px;overflow:hidden;border-radius:999px;background:#d9dfda;opacity:0;transition:opacity .16s ease}.progress-track.visible{opacity:1}.progress-bar{width:0;height:100%;border-radius:inherit;background:#17786f;transition:width .12s linear}.workspace{min-width:0;display:grid;grid-template-columns:minmax(330px,390px) minmax(0,1fr);gap:16px;align-items:start}.input-pane,.activity-pane{background:#fff;border:1px solid #d9dfda;border-radius:8px;box-shadow:0 8px 22px #1c252b0a}.input-pane{padding:16px}.pane-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}h2{margin:0;font-size:16px}button{height:32px;border:1px solid #ccd4cf;border-radius:6px;padding:0 11px;background:#fff;color:#2b353b;font-size:13px;font-weight:600}button:hover:not(:disabled){background:#f2f5f1}button.primary{width:100%;margin-top:12px;border-color:#17786f;background:#17786f;color:#fff}button.primary:hover:not(:disabled){background:#116059}button:disabled{border-color:#ccd4cf;background:#eef0ed;color:#8b9499;cursor:not-allowed}.empty-text{margin:0 0 12px;padding:18px 10px;border:1px dashed #ccd4cf;border-radius:6px;color:#69757b;font-size:13px;text-align:center}.series-card{margin-bottom:10px;padding:10px;border:1px solid #dfe4df;border-radius:6px;background:#fbfcfa}.series-head{display:grid;grid-template-columns:54px minmax(0,1fr) auto;gap:7px;align-items:center;margin-bottom:7px}label{font-size:12px;font-weight:650;color:#59646a}.name{height:30px;min-width:0;border:1px solid #ccd4cf;border-radius:5px;padding:0 8px;font:13px Inter,sans-serif;color:inherit}.remove{height:28px;padding:0 8px;font-size:12px}textarea{width:100%;min-height:92px;resize:vertical;border:1px solid #ccd4cf;border-radius:5px;padding:8px;font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;color:inherit;background:#fff}.name:focus,textarea:focus{outline:2px solid #17786f;outline-offset:1px}.control-block{margin-bottom:14px}select{width:100%;height:32px;border:1px solid #ccd4cf;border-radius:5px;background:#fff;padding:0 8px;font:13px Inter,sans-serif;color:inherit}.source-note{margin:6px 0 0;color:#69757b;font-size:12px;line-height:1.45}.series-horizon{margin-top:8px;padding-top:8px;border-top:1px solid #e4e9e4}.series-horizon-head{display:flex;align-items:center;justify-content:space-between;gap:10px}.series-horizon-value{display:inline-grid;place-items:center;min-width:28px;height:22px;padding:0 6px;border-radius:5px;background:#e7f2ee;color:#116059;font-size:12px;font-weight:700;font-variant-numeric:tabular-nums}input[type=range]{width:100%;margin:10px 0 2px;accent-color:#17786f}.plot-pane{min-width:0;display:grid;gap:12px;align-content:start;max-height:720px;overflow-y:auto;padding-right:2px}.chart-card{background:#fff;border:1px solid #d9dfda;border-radius:8px;box-shadow:0 8px 22px #1c252b0a;padding:12px}.chart-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:8px}.chart-title{flex:none;margin:0;font-size:14px}.chart-source{min-width:0;flex:1;overflow-wrap:anywhere;color:#69757b;font-size:11px;text-align:right}.chart-body{position:relative;height:270px}canvas{display:block;max-width:100%;width:100%;height:100%}.plot-empty{display:grid;place-items:center;min-height:270px;border:1px dashed #ccd4cf;border-radius:8px;background:#fff;padding:20px;color:#69757b;font-size:14px;text-align:center}.activity-pane{margin-top:16px;padding:14px 16px}.activity-state{color:#69757b;font-size:12px}.activity-list{display:grid;gap:7px;max-height:178px;margin:0;padding:0;overflow-y:auto;list-style:none}.activity-item{display:grid;grid-template-columns:66px minmax(0,1fr);gap:10px;padding:7px 9px;border:1px solid #e0e5e0;border-radius:6px;background:#fbfcfa;color:#364248;font-size:12px;line-height:1.45}.activity-item.error{border-color:#e2b8b8;background:#fdf5f4;color:#8d3332}.activity-time{color:#758086;font-variant-numeric:tabular-nums}@media(max-width:920px){.shell{width:min(100% - 24px,1320px);padding-top:24px}.workspace{grid-template-columns:1fr}.top{align-items:start;flex-direction:column}.status-group{justify-items:start;min-width:100%}#status,.progress-track{text-align:left}.plot-pane{max-height:none;overflow:visible;padding-right:0}.chart-body{height:230px}.activity-item{grid-template-columns:58px minmax(0,1fr)}}.workspace>*{min-width:0}
fraccast.BmQmAFoF.js → fraccast.Chrzp_2K.js RENAMED
The diff for this file is too large to render. See raw diff
 
index.html CHANGED
@@ -6,8 +6,8 @@
6
  <meta name="color-scheme" content="light">
7
  <link rel="icon" href="data:,">
8
  <title>Fracast-0 Playground</title>
9
- <script type="module" crossorigin src="./fraccast.BmQmAFoF.js"></script>
10
- <link rel="stylesheet" crossorigin href="./assets/index.gyeZP3tu.css">
11
  </head>
12
  <body>
13
  <main class="shell">
@@ -35,14 +35,6 @@
35
  <select id="preset"></select>
36
  <p id="preset-source" class="source-note">Synthetic: deterministic traffic and sensor waveforms</p>
37
  </div>
38
- <div class="control-block">
39
- <div class="horizon-head">
40
- <label for="horizon">Forecast horizon</label>
41
- <output id="horizon-value" for="horizon">48</output>
42
- </div>
43
- <input id="horizon" type="range" min="8" max="48" step="1" value="48">
44
- <p class="source-note">Native browser head: 8-48 steps</p>
45
- </div>
46
  <div id="series"></div>
47
  <p id="empty-series" class="empty-text">No series loaded yet.</p>
48
  <button id="run" type="button" class="primary" disabled>Load preset</button>
 
6
  <meta name="color-scheme" content="light">
7
  <link rel="icon" href="data:,">
8
  <title>Fracast-0 Playground</title>
9
+ <script type="module" crossorigin src="./fraccast.Chrzp_2K.js"></script>
10
+ <link rel="stylesheet" crossorigin href="./assets/index.DRUfRDea.css">
11
  </head>
12
  <body>
13
  <main class="shell">
 
35
  <select id="preset"></select>
36
  <p id="preset-source" class="source-note">Synthetic: deterministic traffic and sensor waveforms</p>
37
  </div>
 
 
 
 
 
 
 
 
38
  <div id="series"></div>
39
  <p id="empty-series" class="empty-text">No series loaded yet.</p>
40
  <button id="run" type="button" class="primary" disabled>Load preset</button>