diff --git a/index.html b/index.html
index f6c94ed..c07c92a 100644
--- a/index.html
+++ b/index.html
@@ -1172,6 +1172,24 @@ function renderChartRanges(){
document.querySelectorAll(".rangebtn").forEach(btn=>btn.onclick=()=>{localStorage.setItem(CHART_RANGE_KEY,btn.dataset.range);renderAll();});
}
const snapTime=(s)=>new Date(s.timestamp||`${s.date}T12:00:00Z`).getTime();
+function chartDateLabel(t,compact=false){
+ const d=new Date(t);
+ if(isNaN(d))return "";
+ const sameYear=d.getUTCFullYear()===new Date().getUTCFullYear();
+ return d.toLocaleDateString("en-US",compact
+ ? {month:"short",day:"numeric"}
+ : (sameYear?{month:"short",day:"numeric"}:{month:"short",day:"numeric",year:"2-digit"}));
+}
+function chartTicks(times,maxTicks=5){
+ if(!times.length)return [];
+ if(times.length===1)return [{i:0,t:times[0]}];
+ const count=Math.min(maxTicks,times.length),seen=new Set(),ticks=[];
+ for(let n=0;nr.id===chartRange())||CHART_RANGES[0];
if(!range.days)return times;
@@ -1188,7 +1206,7 @@ function drawCombo(svgId,legendId){
const allTimes=rangeFilteredTimes([...new Set(series.flatMap(s=>s.snaps.map(snapTime)))].sort((a,b)=>a-b));
const svg=$(svgId); if(!svg)return;
if(!allTimes.length){svg.innerHTML="";if($(legendId))$(legendId).innerHTML=`No history yet — click "Run cycle".`;return;}
- const W=600,H=240,pad=14; const vals=[0];
+ const W=600,H=240,padL=42,padR=18,padT=18,padB=38; const vals=[0];
const lines=series.map(s=>{
let last=0,idx=0;
const pts=allTimes.map(t=>{
@@ -1203,10 +1221,27 @@ function drawCombo(svgId,legendId){
const avgPts=allTimes.map((_,i)=>+(lines.reduce((sum,l)=>sum+l.pts[i],0)/Math.max(1,lines.length)).toFixed(2));
vals.push(...avgPts);
const min=Math.min(...vals,0),max=Math.max(...vals,0),span=(max-min)||1;
- const x=i=>allTimes.length===1?W/2:pad+(i/(allTimes.length-1))*(W-2*pad);
- const y=v=>H-pad-((v-min)/span)*(H-2*pad);
+ const x=i=>allTimes.length===1?(padL+(W-padR))/2:padL+(i/(allTimes.length-1))*(W-padL-padR);
+ const y=v=>H-padB-((v-min)/span)*(H-padT-padB);
+ const yTicks=[...new Set([min,(min+max)/2,max].map(v=>+v.toFixed(1)))];
const zeroY=y(0).toFixed(1);
- let inner=``;
+ let inner=`
+
+
+
+ `;
+ inner+=``;
+ for(const v of yTicks){
+ const yy=y(v).toFixed(1);
+ inner+=``;
+ inner+=`${fmtPct(v)}`;
+ }
+ inner+=``;
+ for(const tick of chartTicks(allTimes,5)){
+ const xx=x(tick.i).toFixed(1);
+ inner+=``;
+ inner+=`${chartDateLabel(tick.t,true)}`;
+ }
for(const ln of lines){
const d=ln.pts.map((v,i)=>`${i===0?"M":"L"}${x(i).toFixed(1)},${y(v).toFixed(1)}`).join(" ");
const dot=allTimes.length===1?``:"";
@@ -1214,6 +1249,8 @@ function drawCombo(svgId,legendId){
}
const avgD=avgPts.map((v,i)=>`${i===0?"M":"L"}${x(i).toFixed(1)},${y(v).toFixed(1)}`).join(" ");
inner+=``;
+ inner+=`${chartDateLabel(allTimes[0])}`;
+ inner+=`${chartDateLabel(allTimes[allTimes.length-1])}`;
svg.innerHTML=inner;
if($(legendId)){
const b=board();const avg=b.reduce((s,r)=>s+r.ret,0)/b.length;