# Analytics charts

> A dashboard pair — an area chart of audience growth beside a bar chart of weekly sales, each on its own card.

A shadcn/ui block from the [@quill](https://www.quilldesignsystem.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/quill/analytics-charts).

- Page, with a live preview: https://shadcn.exchange/r/quill/analytics-charts
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/quill/analytics-charts-light-94bd676c65ff263c.png
- Registry item: https://www.quilldesignsystem.com/r/analytics-charts.json
- Categories: data-viz, data-display
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://www.quilldesignsystem.com/r/analytics-charts.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `recharts`
- Registry items: `card`, `chart`, `badge`

## Notes from the registry

A dashboard pair — an area chart of audience growth beside a bar chart of weekly sales, each on its own card. Do: Color each series from the chart token set (--chart-1…--chart-5), assigned in a fixed order. Don't: Hardcode a raw accent pigment (--terracotta, --moss, --indigo…) for a series — some pairs are documented as failing colorblind-distinguishability. Do: Pair a multi-series chart with a ChartLegend, as the Audience chart does — color is tied to a series name in text, never left for the reader to infer. Don't: Ship a multi-series chart with no legend — color becomes the only signal distinguishing readers from subscribers. Use stat-cards when you need at-a-glance numbers, not a trend shape — a single KPI reads faster as a number than a chart. Use data-table when the audience needs to inspect exact values per row, not the shape of change over time.

## Files

### `registry/blocks/analytics-charts.tsx`

```tsx
'use client'
import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
} from '@/components/ui/card'
import {
  ChartContainer,
  ChartLegend,
  ChartLegendContent,
  ChartTooltip,
  ChartTooltipContent,
} from '@/components/ui/chart'
import { Badge } from '@/components/ui/badge'
import { Area, AreaChart, Bar, BarChart, XAxis, YAxis } from 'recharts'

const traffic = [
  { month: 'Jan', readers: 820, subscribers: 310 },
  { month: 'Feb', readers: 932, subscribers: 340 },
  { month: 'Mar', readers: 1105, subscribers: 415 },
  { month: 'Apr', readers: 1043, subscribers: 462 },
  { month: 'May', readers: 1290, subscribers: 550 },
  { month: 'Jun', readers: 1481, subscribers: 618 },
]
const trafficConfig = {
  readers: { label: 'Readers', color: 'var(--chart-1)' },
  subscribers: { label: 'Subscribers', color: 'var(--chart-2)' },
}

const sales = [
  { week: 'W1', prints: 12 },
  { week: 'W2', prints: 19 },
  { week: 'W3', prints: 14 },
  { week: 'W4', prints: 26 },
]
const salesConfig = {
  prints: { label: 'Print sales', color: 'var(--chart-3)' },
}

/** A dashboard pair — an area chart of audience growth beside a bar chart of weekly sales, each on its own card. */
export function AnalyticsCharts() {
  return (
    <div className="mx-auto grid w-full max-w-[880px] grid-cols-[1.4fr_1fr] items-start gap-6 max-md:grid-cols-1">
      <Card>
        <CardHeader>
          <div className="flex items-center justify-between gap-2">
            <CardTitle>Audience</CardTitle>
            <Badge variant="secondary">Last 6 months</Badge>
          </div>
          <CardDescription>Monthly readers and new subscribers.</CardDescription>
        </CardHeader>
        <CardContent>
          <ChartContainer config={trafficConfig} className="h-56 w-full">
            <AreaChart data={traffic}>
              <XAxis dataKey="month" />
              <YAxis width={36} />
              <ChartTooltip content={<ChartTooltipContent />} />
              <ChartLegend content={<ChartLegendContent />} />
              <Area
                dataKey="readers"
                fill="var(--color-readers)"
                fillOpacity={0.2}
                stroke="var(--color-readers)"
                strokeWidth={2}
                type="monotone"
              />
              <Area
                dataKey="subscribers"
                fill="var(--color-subscribers)"
                fillOpacity={0.2}
                stroke="var(--color-subscribers)"
                strokeWidth={2}
                type="monotone"
              />
            </AreaChart>
          </ChartContainer>
        </CardContent>
      </Card>
      <Card>
        <CardHeader>
          <CardTitle>Engagements</CardTitle>
          <CardDescription>Weekly engagements this month.</CardDescription>
        </CardHeader>
        <CardContent>
          <ChartContainer config={salesConfig} className="h-56 w-full">
            <BarChart data={sales}>
              <XAxis dataKey="week" />
              <YAxis width={28} />
              <ChartTooltip content={<ChartTooltipContent />} />
              <Bar dataKey="prints" fill="var(--color-prints)" radius={4} />
            </BarChart>
          </ChartContainer>
        </CardContent>
      </Card>
    </div>
  )
}
```
