333 lines · 3 files · 9.2 kB
cases/118-token-usage-calendar/example.tsx140 lines · entry
cases/118-token-usage-calendar/example.tsx
import { cell, defineChart } from '@tanstack/charts'
import { Chart } from '@tanstack/charts/react/tooltip'
import { tooltip } from '@tanstack/charts/tooltip'
import { portal } from '@tanstack/charts/tooltip/portal'
import { scaleBand, scaleOrdinal } from 'd3-scale'
import {
calendarMonthTicks,
calendarWeekCount,
formatTokenUsage,
tokenUsageCalendar,
usageColors,
usageLevels,
weekdays,
} from './model'
import {
calendarBandPaddingInner,
calendarBandPaddingOuter,
calendarBottomMargin,
calendarMargin,
} from './layout'
export interface ChartOptions {
width: number
height: number
revision: number
preview?: boolean
}
const weekDomain = Array.from(
{ length: calendarWeekCount },
(_value, index) => index,
)
export const exampleAriaLabel =
'Token activity from August 2025 through July 2026. Weeks are columns and Sunday through Saturday are rows. Pale gray means no usage; blue intensity ranges from up to 25 million through over 150 million tokens.'
export const exampleTooltip = {
anchor: 'point' as const,
className: 'token-activity-tooltip',
format: ({
datum,
}: {
datum: ReturnType<typeof tokenUsageCalendar>[number]
}) => formatTokenUsage(datum),
offset: 5,
portal,
}
export function createExampleChart(input: ChartOptions) {
const days = tokenUsageCalendar(input.revision)
const monthTicks = calendarMonthTicks()
return defineChart(
{
marks: [
cell(days, {
x: 'week',
y: 'weekday',
color: 'level',
key: 'dateKey',
inset: 0,
radius: 3,
}),
],
scales: {
x: {
scale: scaleBand<number>()
.domain(weekDomain)
.paddingInner(calendarBandPaddingInner)
.paddingOuter(calendarBandPaddingOuter),
axis: {
line: false,
ticks: {
values: monthTicks.values,
size: 0,
padding: input.preview ? 3 : 7,
format: (week: number) => monthTicks.labels.get(week) ?? '',
},
tickLabels: {
fontSize: input.preview ? 8 : 13,
opacity: 0.62,
anchor: ({ index }) => (index === 0 ? 'start' : undefined),
dx: ({ index, bandwidth }) =>
index === 0 ? -bandwidth / 2 : undefined,
thin: { minGap: input.preview ? 2 : 8, priority: 'ends' },
},
},
},
y: {
scale: scaleBand<string>()
.domain(weekdays)
.paddingInner(calendarBandPaddingInner)
.paddingOuter(calendarBandPaddingOuter),
axis: false,
},
},
color: {
scale: scaleOrdinal<string, string>()
.domain(usageLevels)
.range(usageColors),
},
margin: input.preview
? { top: 0, right: 0, bottom: 16, left: 0 }
: {
...calendarMargin,
bottom: calendarBottomMargin(input.width, input.height),
},
},
{
keyboard: true,
tooltip: { use: tooltip, ...exampleTooltip },
},
)
}
export const chart = createExampleChart({
width: 720,
height: 300,
revision: 0,
})
export default function Example() {
return (
<div style={{ height: 300 }}>
<style>{`
.ts-chart-tooltip.token-activity-tooltip {
padding: 6px 9px !important;
border: 1px solid #e5e7eb !important;
border-radius: 9px !important;
background: #fff !important;
color: #202124 !important;
box-shadow: none !important;
white-space: nowrap !important;
}
`}</style>
<Chart definition={chart} ariaLabel={exampleAriaLabel} height={300} />
</div>
)
}cases/118-token-usage-calendar/layout.ts36 lines · dependency
cases/118-token-usage-calendar/layout.ts
import { calendarWeekCount } from './model'
export const calendarBandPaddingInner = 0.08
export const calendarBandPaddingOuter = 0
export const calendarMargin = {
top: 4,
right: 0,
bottom: 30,
left: 0,
} as const
export function calendarGridHeight(width: number): number {
const plotWidth = Math.max(
1,
width - calendarMargin.left - calendarMargin.right,
)
const xStep =
plotWidth /
(calendarWeekCount -
calendarBandPaddingInner +
calendarBandPaddingOuter * 2)
return xStep * (7 - calendarBandPaddingInner + calendarBandPaddingOuter * 2)
}
export function calendarChartHeight(width: number): number {
return Math.ceil(
calendarMargin.top + calendarGridHeight(width) + calendarMargin.bottom,
)
}
export function calendarBottomMargin(width: number, height: number): number {
return Math.max(
calendarMargin.bottom,
height - calendarMargin.top - calendarGridHeight(width),
)
}cases/118-token-usage-calendar/model.ts157 lines · dependency
cases/118-token-usage-calendar/model.ts
import { binTimeX } from '@tanstack/charts'
import { utcDay, utcMonth, utcSunday } from 'd3-time'
export interface TokenUsageEvent {
readonly at: Date
readonly tokens: number
}
export const weekdays = [
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
] as const
export const usageLevels = [
'No usage',
'Up to 25M',
'25M–75M',
'75M–150M',
'Over 150M',
] as const
export type UsageLevel = (typeof usageLevels)[number]
export const usageColors = [
'#f3f4f6',
'#dbeafe',
'#bfdbfe',
'#93c5fd',
'#3b82f6',
] as const
export interface TokenUsageDay {
readonly date: Date
readonly dateKey: string
readonly week: number
readonly weekday: (typeof weekdays)[number]
readonly tokens: number
readonly sessions: number
readonly level: UsageLevel
readonly source: readonly TokenUsageEvent[]
readonly sourceIndexes: readonly number[]
}
export const calendarStart = new Date('2025-08-03T00:00:00Z')
export const calendarEnd = new Date('2026-08-01T00:00:00Z')
export const calendarWeekCount = utcSunday.count(calendarStart, calendarEnd) + 1
const dateFormat = new Intl.DateTimeFormat('en-US', {
month: 'short',
day: 'numeric',
timeZone: 'UTC',
})
const monthFormat = new Intl.DateTimeFormat('en-US', {
month: 'short',
timeZone: 'UTC',
})
const tokenFormat = new Intl.NumberFormat('en-US', {
notation: 'compact',
maximumFractionDigits: 1,
})
export function tokenUsageCalendar(revision: number): TokenUsageDay[] {
const events = tokenUsageEvents(revision)
const daily = binTimeX(events, {
value: 'at',
interval: utcDay,
domain: [calendarStart, calendarEnd],
outputs: {
tokens: { value: 'tokens', reduce: 'sum' },
sessions: { reduce: 'count' },
},
})
return daily.map((day) => {
const date = day.x1
const dateKey = isoDate(date)
return {
date,
dateKey,
week: utcSunday.count(calendarStart, date),
weekday: weekdays[date.getUTCDay()] ?? 'Sun',
tokens: day.tokens,
sessions: day.sessions,
level: usageLevel(day.tokens),
source: day.source,
sourceIndexes: day.sourceIndexes,
}
})
}
export function tokenUsageEvents(revision: number): TokenUsageEvent[] {
const dates = utcDay.range(calendarStart, utcDay.offset(calendarEnd, 1))
return dates.flatMap((date, dayIndex) => {
const weekday = date.getUTCDay()
const weekend = weekday === 0 || weekday === 6
const progress = dayIndex / Math.max(1, dates.length - 1)
const activityRamp = Math.min(1, Math.max(0, (progress - 0.46) / 0.08))
const activity = (dayIndex * 37 + weekday * 17 + revision * 11) % 100
const quietThreshold = Math.round(99 - activityRamp * (weekend ? 67 : 81))
if (activity < quietThreshold) return []
const intensityRamp = Math.min(1, Math.max(0, (progress - 0.5) / 0.5))
const surge =
intensityRamp > 0.8 && (dayIndex * 11 + weekday * 7 + revision) % 13 === 0
? 90_000_000
: 0
const total =
4_000_000 +
((dayIndex * 7_919_000 + weekday * 13_337_000 + revision * 9_973_000) %
28_000_000) +
Math.round(intensityRamp * 78_000_000) +
surge
const sessions = 1 + ((dayIndex + revision + weekday) % 3)
return Array.from({ length: sessions }, (_value, sessionIndex) => ({
at: new Date(date.getTime() + (8 + sessionIndex * 4) * 3_600_000),
tokens:
Math.floor(total / sessions) +
(sessionIndex < total % sessions ? 1 : 0),
}))
})
}
export function calendarMonthTicks(): {
readonly values: readonly number[]
readonly labels: ReadonlyMap<number, string>
} {
const dates = [calendarStart, ...utcMonth.range(calendarStart, calendarEnd)]
const labels = new Map<number, string>()
for (const date of dates) {
const week = utcSunday.count(calendarStart, date)
if (!labels.has(week)) labels.set(week, monthFormat.format(date))
}
return { values: [...labels.keys()], labels }
}
export function formatTokenUsage(day: TokenUsageDay): string {
return `${tokenFormat.format(day.tokens)} tokens on ${dateFormat.format(day.date)}`
}
function usageLevel(tokens: number): UsageLevel {
if (tokens === 0) return 'No usage'
if (tokens <= 25_000_000) return 'Up to 25M'
if (tokens <= 75_000_000) return '25M–75M'
if (tokens <= 150_000_000) return '75M–150M'
return 'Over 150M'
}
function isoDate(date: Date): string {
return date.toISOString().slice(0, 10)
}