Want this built into your product? AI agents write the code, an engineer directs them: https://vibecoding.tech/services?utm_source=21st&utm_medium=component Book a call and say promo code 21ST to get a free 3-day development trial. Interactive stacked daily columns with a live legend that doubles as the tooltip; the last, incomplete day is hatched. Answers: "What makes up each day's volume, and how does it breathe day to day?"
Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Stacked Activity Bars to your project and fits it to your theme.
Code
How Stacked Activity Bars is used: the demo's code. The component's own source comes with a free account.
Usage.tsx
'use client'
// --- vizcn palette (lib/palette.ts inlined for 21st.dev; canonical registry: https://vibecoding.tech/vizcn) ---
const CATEGORICAL = [
'#4E79A7', // blue
'#F28E2B', // orange
'#59A14F', // green
'#B07AA1', // purple
'#76B7B2', // teal
'#E15759', // red
'#EDC948', // yellow
'#FF9DA7', // pink
'#9C755F', // brown
'#BAB0AC', // grey
] as const
function seriesColor(i: number): string {
return CATEGORICAL[((i % CATEGORICAL.length) + CATEGORICAL.length) % CATEGORICAL.length]
}
// --- end palette ---
import { StackedActivityBars, type StackSegment } from '@/components/ui/stacked-activity'
/**
* Demo: 28 days of token traffic for the fictional model "Atlas" —
* deterministic waves (no randomness), stacked as prompt / completion /
* reasoning tokens. The last day is partial and hatched.
*/
const N = 28
function isoDays(startIso: string, count: number): string[] {
const d = new Date(`${startIso}T00:00:00Z`)
const out: string[] = []
for (let i = 0; i < count; i++) {
out.push(d.toISOString().slice(0, 10))
d.setUTCDate(d.getUTCDate() + 1)
}
return out
}
const days = isoDays('2025-06-01', N)
const wave = (i: number, base: number, a1: number, a2: number) =>
Math.round((base + a1 * Math.sin(i / 3.1) + a2 * Math.sin(i / 1.4 + 1.7) + i * 0.06) * 100) / 100
const prompt = days.map((_, i) => wave(i, 5.8, 1.6, 0.7))
const completion = days.map((_, i) => wave(i, 2.4, 0.8, 0.4))
const reasoning = days.map((_, i) => wave(i, 1.1, 0.5, 0.25))
// last day is in progress — scale it down to look partial
const partial = (vs: number[]) => vs.map((v, i) => (i === N - 1 ? Math.round(v * 42) / 100 : v))
const segments: StackSegment[] = [
{ key: 'prompt', label: 'Prompt', color: seriesColor(0), values: partial(prompt) },
{ key: 'completion', label: 'Completion', color: seriesColor(1), values: partial(completion) },
{ key: 'reasoning', label: 'Reasoning', color: seriesColor(2), values: partial(reasoning) },
]
export default function StackedActivityDemo() {
return (
<StackedActivityBars
days={days}
segments={segments}
unit="B"
note="Daily token volume for Atlas by request part. Hover a day to pin it in the legend."
partialLast
partialNote="partial day"
/>
)
}








