@@ -417,18 +417,32 @@ function TokenUsageChart({
417417
418418 // ViewBox in nice round units — scales responsively.
419419 const W = 600 ;
420- const H = 140 ;
420+ const H = 160 ;
421421 const padX = 4 ;
422- const padBottom = 14 ;
422+ const padBottom = 22 ;
423423 const padTop = 4 ;
424424 const barW = n > 0 ? ( W - padX * 2 ) / n : 0 ;
425425 const chartH = H - padTop - padBottom ;
426426
427+ const MONTHS = [ "Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" , "Jul" , "Aug" , "Sep" , "Oct" , "Nov" , "Dec" ] ;
428+
427429 const labelFor = ( d : { date ?: string ; week_start ?: string } ) : string => {
428430 const iso = d . date ?? d . week_start ?? "" ;
429431 if ( ! iso ) return "" ;
430- const [ , m , day ] = iso . split ( "-" ) ;
431- return mode === "daily" ? `${ m } /${ day } ` : `${ m } /${ day } ` ;
432+ const [ , mm , dd ] = iso . split ( "-" ) ;
433+ const mIdx = parseInt ( mm , 10 ) - 1 ;
434+ const day = parseInt ( dd , 10 ) ;
435+ return `${ MONTHS [ mIdx ] ?? mm } ${ day } ` ;
436+ } ;
437+
438+ // Daily: label only on Mondays + first/last bar to avoid clutter.
439+ // Weekly: label every other bar, plus the most recent.
440+ const shouldLabel = ( i : number , iso : string ) : boolean => {
441+ if ( i === n - 1 || i === 0 ) return true ;
442+ if ( mode === "weekly" ) return i % 2 === 0 ;
443+ // daily: Monday or 1st of month
444+ const dt = new Date ( `${ iso } T00:00:00` ) ;
445+ return dt . getDay ( ) === 1 || dt . getDate ( ) === 1 ;
432446 } ;
433447
434448 const gridlines = [ 0.25 , 0.5 , 0.75 , 1 ] . map ( ( f ) => padTop + chartH * ( 1 - f ) ) ;
@@ -466,7 +480,7 @@ function TokenUsageChart({
466480
467481 < svg
468482 viewBox = { `0 0 ${ W } ${ H } ` }
469- className = "w-full h-36 "
483+ className = "w-full h-40 "
470484 preserveAspectRatio = "none"
471485 onMouseLeave = { ( ) => setHover ( null ) }
472486 >
@@ -510,21 +524,54 @@ function TokenUsageChart({
510524 </ g >
511525 ) ;
512526 } ) }
527+ { /* Hover guideline */ }
528+ { hover != null && (
529+ < line
530+ x1 = { padX + hover * barW + barW / 2 }
531+ x2 = { padX + hover * barW + barW / 2 }
532+ y1 = { padTop }
533+ y2 = { padTop + chartH }
534+ stroke = "#22d3ee"
535+ strokeWidth = { 0.5 }
536+ strokeDasharray = "2 2"
537+ opacity = { 0.4 }
538+ pointerEvents = "none"
539+ />
540+ ) }
541+ { /* Tick marks */ }
542+ { data . map ( ( _ , i ) => {
543+ if ( i % ( mode === "daily" ? 5 : 1 ) !== 0 && i !== n - 1 ) return null ;
544+ const x = padX + i * barW + barW / 2 ;
545+ return (
546+ < line
547+ key = { `tick-${ i } ` }
548+ x1 = { x }
549+ x2 = { x }
550+ y1 = { padTop + chartH }
551+ y2 = { padTop + chartH + 3 }
552+ stroke = "#334155"
553+ strokeWidth = { 0.5 }
554+ />
555+ ) ;
556+ } ) }
557+ { /* X-axis labels */ }
513558 { data . map ( ( d , i ) => {
514- const showLabel =
515- mode === "daily"
516- ? i % 5 === 0 || i === n - 1
517- : i % 2 === 0 || i === n - 1 ;
518- if ( ! showLabel ) return null ;
559+ const iso = ( d as { date ?: string ; week_start ?: string } ) . date
560+ ?? ( d as { date ?: string ; week_start ?: string } ) . week_start
561+ ?? "" ;
562+ if ( ! shouldLabel ( i , iso ) ) return null ;
519563 const x = padX + i * barW + barW / 2 ;
564+ const isHover = hover === i ;
565+ const isLast = i === n - 1 ;
520566 return (
521567 < text
522568 key = { `t-${ i } ` }
523569 x = { x }
524- y = { H - 3 }
570+ y = { H - 6 }
525571 textAnchor = "middle"
526- fontSize = { 8 }
527- fill = "#475569"
572+ fontSize = { 9 }
573+ fontWeight = { isHover || isLast ? 600 : 400 }
574+ fill = { isHover ? "#22d3ee" : isLast ? "#cbd5e1" : "#64748b" }
528575 >
529576 { labelFor ( d ) }
530577 </ text >
0 commit comments