mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
feat(design-system): charts defrag (#41026)
* feat: remove unused chart files * chore: regenerate registry * fix: logs bar chart positioning * feat: add charts page to ui patterns * chore: alphabetise ui patterns nav * feat: base composable chart components * chore: prettier for charts.mdx * chore: slowly putting example together * feat: add chart header components * feat: add chart content wrapper * feat: add recharts to source * feat: add empty state handling * feat: add loading state for content area as well * feat: starting on actual recharts pieces * feat: add basic api to documentation * feat: add disabled state too * feat: couple of basic chart types * chore: tidy up for now * feat: modify eslint rules for our demo files * fix: recharts logo colour on light mode * feat: absorb metric card into chart * feat: align prop for chart header * feat: refactor chart content * feat: example with table * chore: format for prettier * fix: pkg lock merge conflict * fix: small bits from danny * feat: add link in ui pattern intro to charts * chore: remove charts link from atoms * chore: update metric padding to saxon suggestion * feat: table footer overrides by default * feat: update api props in table * chore: formating
This commit is contained in:
1 parent
3221a38596
commit
ec6f55c00b
147 files changed
+2731
-11273
No files matched your search
@@ -1,91 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'An area chart with axes'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Axes</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: -20,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<YAxis tickLine={false} axisLine={false} tickMargin={8} tickCount={3} />
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
|
||||
<Area
|
||||
dataKey="mobile"
|
||||
type="natural"
|
||||
fill="var(--color-mobile)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-mobile)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
stackId="a"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A simple area chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'An area chart with gradient fill'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Gradient</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
|
||||
<defs>
|
||||
<linearGradient id="fillDesktop" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="5%" stopColor="var(--color-desktop)" stopOpacity={0.8} />
|
||||
<stop offset="95%" stopColor="var(--color-desktop)" stopOpacity={0.1} />
|
||||
</linearGradient>
|
||||
<linearGradient id="fillMobile" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="5%" stopColor="var(--color-mobile)" stopOpacity={0.8} />
|
||||
<stop offset="95%" stopColor="var(--color-mobile)" stopOpacity={0.1} />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<Area
|
||||
dataKey="mobile"
|
||||
type="natural"
|
||||
fill="url(#fillMobile)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-mobile)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="url(#fillDesktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
stackId="a"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingDown, TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import {
|
||||
ChartConfig,
|
||||
ChartContainer,
|
||||
ChartLegend,
|
||||
ChartLegendContent,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
} from 'ui'
|
||||
|
||||
export const description = 'An area chart with icons'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
icon: TrendingDown,
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
icon: TrendingUp,
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Icons</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<Area
|
||||
dataKey="mobile"
|
||||
type="natural"
|
||||
fill="var(--color-mobile)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-mobile)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
stackId="a"
|
||||
/>
|
||||
<ChartLegend content={<ChartLegendContent />} />
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,238 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import * as React from 'react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from 'ui'
|
||||
import {
|
||||
ChartConfig,
|
||||
ChartContainer,
|
||||
ChartLegend,
|
||||
ChartLegendContent,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
} from 'ui'
|
||||
import {
|
||||
Select_Shadcn_,
|
||||
SelectContent_Shadcn_,
|
||||
SelectItem_Shadcn_,
|
||||
SelectTrigger_Shadcn_,
|
||||
SelectValue_Shadcn_,
|
||||
} from 'ui'
|
||||
|
||||
export const description = 'An interactive area chart'
|
||||
|
||||
const chartData = [
|
||||
{ date: '2024-04-01', desktop: 222, mobile: 150 },
|
||||
{ date: '2024-04-02', desktop: 97, mobile: 180 },
|
||||
{ date: '2024-04-03', desktop: 167, mobile: 120 },
|
||||
{ date: '2024-04-04', desktop: 242, mobile: 260 },
|
||||
{ date: '2024-04-05', desktop: 373, mobile: 290 },
|
||||
{ date: '2024-04-06', desktop: 301, mobile: 340 },
|
||||
{ date: '2024-04-07', desktop: 245, mobile: 180 },
|
||||
{ date: '2024-04-08', desktop: 409, mobile: 320 },
|
||||
{ date: '2024-04-09', desktop: 59, mobile: 110 },
|
||||
{ date: '2024-04-10', desktop: 261, mobile: 190 },
|
||||
{ date: '2024-04-11', desktop: 327, mobile: 350 },
|
||||
{ date: '2024-04-12', desktop: 292, mobile: 210 },
|
||||
{ date: '2024-04-13', desktop: 342, mobile: 380 },
|
||||
{ date: '2024-04-14', desktop: 137, mobile: 220 },
|
||||
{ date: '2024-04-15', desktop: 120, mobile: 170 },
|
||||
{ date: '2024-04-16', desktop: 138, mobile: 190 },
|
||||
{ date: '2024-04-17', desktop: 446, mobile: 360 },
|
||||
{ date: '2024-04-18', desktop: 364, mobile: 410 },
|
||||
{ date: '2024-04-19', desktop: 243, mobile: 180 },
|
||||
{ date: '2024-04-20', desktop: 89, mobile: 150 },
|
||||
{ date: '2024-04-21', desktop: 137, mobile: 200 },
|
||||
{ date: '2024-04-22', desktop: 224, mobile: 170 },
|
||||
{ date: '2024-04-23', desktop: 138, mobile: 230 },
|
||||
{ date: '2024-04-24', desktop: 387, mobile: 290 },
|
||||
{ date: '2024-04-25', desktop: 215, mobile: 250 },
|
||||
{ date: '2024-04-26', desktop: 75, mobile: 130 },
|
||||
{ date: '2024-04-27', desktop: 383, mobile: 420 },
|
||||
{ date: '2024-04-28', desktop: 122, mobile: 180 },
|
||||
{ date: '2024-04-29', desktop: 315, mobile: 240 },
|
||||
{ date: '2024-04-30', desktop: 454, mobile: 380 },
|
||||
{ date: '2024-05-01', desktop: 165, mobile: 220 },
|
||||
{ date: '2024-05-02', desktop: 293, mobile: 310 },
|
||||
{ date: '2024-05-03', desktop: 247, mobile: 190 },
|
||||
{ date: '2024-05-04', desktop: 385, mobile: 420 },
|
||||
{ date: '2024-05-05', desktop: 481, mobile: 390 },
|
||||
{ date: '2024-05-06', desktop: 498, mobile: 520 },
|
||||
{ date: '2024-05-07', desktop: 388, mobile: 300 },
|
||||
{ date: '2024-05-08', desktop: 149, mobile: 210 },
|
||||
{ date: '2024-05-09', desktop: 227, mobile: 180 },
|
||||
{ date: '2024-05-10', desktop: 293, mobile: 330 },
|
||||
{ date: '2024-05-11', desktop: 335, mobile: 270 },
|
||||
{ date: '2024-05-12', desktop: 197, mobile: 240 },
|
||||
{ date: '2024-05-13', desktop: 197, mobile: 160 },
|
||||
{ date: '2024-05-14', desktop: 448, mobile: 490 },
|
||||
{ date: '2024-05-15', desktop: 473, mobile: 380 },
|
||||
{ date: '2024-05-16', desktop: 338, mobile: 400 },
|
||||
{ date: '2024-05-17', desktop: 499, mobile: 420 },
|
||||
{ date: '2024-05-18', desktop: 315, mobile: 350 },
|
||||
{ date: '2024-05-19', desktop: 235, mobile: 180 },
|
||||
{ date: '2024-05-20', desktop: 177, mobile: 230 },
|
||||
{ date: '2024-05-21', desktop: 82, mobile: 140 },
|
||||
{ date: '2024-05-22', desktop: 81, mobile: 120 },
|
||||
{ date: '2024-05-23', desktop: 252, mobile: 290 },
|
||||
{ date: '2024-05-24', desktop: 294, mobile: 220 },
|
||||
{ date: '2024-05-25', desktop: 201, mobile: 250 },
|
||||
{ date: '2024-05-26', desktop: 213, mobile: 170 },
|
||||
{ date: '2024-05-27', desktop: 420, mobile: 460 },
|
||||
{ date: '2024-05-28', desktop: 233, mobile: 190 },
|
||||
{ date: '2024-05-29', desktop: 78, mobile: 130 },
|
||||
{ date: '2024-05-30', desktop: 340, mobile: 280 },
|
||||
{ date: '2024-05-31', desktop: 178, mobile: 230 },
|
||||
{ date: '2024-06-01', desktop: 178, mobile: 200 },
|
||||
{ date: '2024-06-02', desktop: 470, mobile: 410 },
|
||||
{ date: '2024-06-03', desktop: 103, mobile: 160 },
|
||||
{ date: '2024-06-04', desktop: 439, mobile: 380 },
|
||||
{ date: '2024-06-05', desktop: 88, mobile: 140 },
|
||||
{ date: '2024-06-06', desktop: 294, mobile: 250 },
|
||||
{ date: '2024-06-07', desktop: 323, mobile: 370 },
|
||||
{ date: '2024-06-08', desktop: 385, mobile: 320 },
|
||||
{ date: '2024-06-09', desktop: 438, mobile: 480 },
|
||||
{ date: '2024-06-10', desktop: 155, mobile: 200 },
|
||||
{ date: '2024-06-11', desktop: 92, mobile: 150 },
|
||||
{ date: '2024-06-12', desktop: 492, mobile: 420 },
|
||||
{ date: '2024-06-13', desktop: 81, mobile: 130 },
|
||||
{ date: '2024-06-14', desktop: 426, mobile: 380 },
|
||||
{ date: '2024-06-15', desktop: 307, mobile: 350 },
|
||||
{ date: '2024-06-16', desktop: 371, mobile: 310 },
|
||||
{ date: '2024-06-17', desktop: 475, mobile: 520 },
|
||||
{ date: '2024-06-18', desktop: 107, mobile: 170 },
|
||||
{ date: '2024-06-19', desktop: 341, mobile: 290 },
|
||||
{ date: '2024-06-20', desktop: 408, mobile: 450 },
|
||||
{ date: '2024-06-21', desktop: 169, mobile: 210 },
|
||||
{ date: '2024-06-22', desktop: 317, mobile: 270 },
|
||||
{ date: '2024-06-23', desktop: 480, mobile: 530 },
|
||||
{ date: '2024-06-24', desktop: 132, mobile: 180 },
|
||||
{ date: '2024-06-25', desktop: 141, mobile: 190 },
|
||||
{ date: '2024-06-26', desktop: 434, mobile: 380 },
|
||||
{ date: '2024-06-27', desktop: 448, mobile: 490 },
|
||||
{ date: '2024-06-28', desktop: 149, mobile: 200 },
|
||||
{ date: '2024-06-29', desktop: 103, mobile: 160 },
|
||||
{ date: '2024-06-30', desktop: 446, mobile: 400 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
const [timeRange, setTimeRange] = React.useState('90d')
|
||||
|
||||
const filteredData = chartData.filter((item) => {
|
||||
const date = new Date(item.date)
|
||||
const now = new Date()
|
||||
let daysToSubtract = 90
|
||||
if (timeRange === '30d') {
|
||||
daysToSubtract = 30
|
||||
} else if (timeRange === '7d') {
|
||||
daysToSubtract = 7
|
||||
}
|
||||
now.setDate(now.getDate() - daysToSubtract)
|
||||
return date >= now
|
||||
})
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="flex items-center gap-2 space-y-0 border-b py-5 sm:flex-row">
|
||||
<div className="grid flex-1 gap-1 text-center sm:text-left">
|
||||
<CardTitle>Area Chart - Interactive</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 3 months</CardDescription>
|
||||
</div>
|
||||
<Select_Shadcn_ value={timeRange} onValueChange={setTimeRange}>
|
||||
<SelectTrigger_Shadcn_
|
||||
className="w-[160px] rounded-lg sm:ml-auto"
|
||||
aria-label="Select a value"
|
||||
>
|
||||
<SelectValue_Shadcn_ placeholder="Last 3 months" />
|
||||
</SelectTrigger_Shadcn_>
|
||||
<SelectContent_Shadcn_ className="rounded-xl">
|
||||
<SelectItem_Shadcn_ value="90d" className="rounded-lg">
|
||||
Last 3 months
|
||||
</SelectItem_Shadcn_>
|
||||
<SelectItem_Shadcn_ value="30d" className="rounded-lg">
|
||||
Last 30 days
|
||||
</SelectItem_Shadcn_>
|
||||
<SelectItem_Shadcn_ value="7d" className="rounded-lg">
|
||||
Last 7 days
|
||||
</SelectItem_Shadcn_>
|
||||
</SelectContent_Shadcn_>
|
||||
</Select_Shadcn_>
|
||||
</CardHeader>
|
||||
<CardContent className="px-2 pt-4 sm:px-6 sm:pt-6">
|
||||
<ChartContainer config={chartConfig} className="aspect-auto h-[250px] w-full">
|
||||
<AreaChart data={filteredData}>
|
||||
<defs>
|
||||
<linearGradient id="fillDesktop" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="5%" stopColor="var(--color-desktop)" stopOpacity={0.8} />
|
||||
<stop offset="95%" stopColor="var(--color-desktop)" stopOpacity={0.1} />
|
||||
</linearGradient>
|
||||
<linearGradient id="fillMobile" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="5%" stopColor="var(--color-mobile)" stopOpacity={0.8} />
|
||||
<stop offset="95%" stopColor="var(--color-mobile)" stopOpacity={0.1} />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="date"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
minTickGap={32}
|
||||
tickFormatter={(value) => {
|
||||
const date = new Date(value)
|
||||
return date.toLocaleDateString('en-US', {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<ChartTooltip
|
||||
cursor={false}
|
||||
content={
|
||||
<ChartTooltipContent
|
||||
labelFormatter={(value) => {
|
||||
return new Date(value).toLocaleDateString('en-US', {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
})
|
||||
}}
|
||||
indicator="dot"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Area
|
||||
dataKey="mobile"
|
||||
type="natural"
|
||||
fill="url(#fillMobile)"
|
||||
stroke="var(--color-mobile)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="url(#fillDesktop)"
|
||||
stroke="var(--color-desktop)"
|
||||
stackId="a"
|
||||
/>
|
||||
<ChartLegend content={<ChartLegendContent />} />
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import {
|
||||
ChartConfig,
|
||||
ChartContainer,
|
||||
ChartLegend,
|
||||
ChartLegendContent,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
} from 'ui'
|
||||
|
||||
export const description = 'An area chart with a legend'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Legend</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<Area
|
||||
dataKey="mobile"
|
||||
type="natural"
|
||||
fill="var(--color-mobile)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-mobile)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
stackId="a"
|
||||
/>
|
||||
<ChartLegend content={<ChartLegendContent />} />
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A linear area chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Linear</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip
|
||||
cursor={false}
|
||||
content={<ChartTooltipContent indicator="dot" hideLabel />}
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="linear"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A stacked area chart with expand stacking'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80, other: 45 },
|
||||
{ month: 'February', desktop: 305, mobile: 200, other: 100 },
|
||||
{ month: 'March', desktop: 237, mobile: 120, other: 150 },
|
||||
{ month: 'April', desktop: 73, mobile: 190, other: 50 },
|
||||
{ month: 'May', desktop: 209, mobile: 130, other: 100 },
|
||||
{ month: 'June', desktop: 214, mobile: 140, other: 160 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Stacked Expanded</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
top: 12,
|
||||
}}
|
||||
stackOffset="expand"
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<Area
|
||||
dataKey="other"
|
||||
type="natural"
|
||||
fill="var(--color-other)"
|
||||
fillOpacity={0.1}
|
||||
stroke="var(--color-other)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="mobile"
|
||||
type="natural"
|
||||
fill="var(--color-mobile)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-mobile)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
stackId="a"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A stacked area chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Stacked</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="dot" />} />
|
||||
<Area
|
||||
dataKey="mobile"
|
||||
type="natural"
|
||||
fill="var(--color-mobile)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-mobile)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
stackId="a"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { Activity, TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A step area chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
icon: Activity,
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Step</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="step"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, CartesianGrid, Rectangle, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A bar chart with an active bar'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 187, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 275, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Active</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart accessibilityLayer data={chartData}>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="browser"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => chartConfig[value as keyof typeof chartConfig]?.label}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Bar
|
||||
dataKey="visitors"
|
||||
strokeWidth={2}
|
||||
radius={8}
|
||||
activeIndex={2}
|
||||
activeBar={({ ...props }) => {
|
||||
return (
|
||||
<Rectangle
|
||||
{...props}
|
||||
fillOpacity={0.8}
|
||||
stroke={props.payload.fill}
|
||||
strokeDasharray={4}
|
||||
strokeDashoffset={4}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A bar chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart accessibilityLayer data={chartData}>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={8} />
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, XAxis, YAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A horizontal bar chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Horizontal</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
layout="vertical"
|
||||
margin={{
|
||||
left: -20,
|
||||
}}
|
||||
>
|
||||
<XAxis type="number" dataKey="desktop" hide />
|
||||
<YAxis
|
||||
dataKey="month"
|
||||
type="category"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={5} />
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, CartesianGrid, LabelList, XAxis, YAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A bar chart with a custom label'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
label: {
|
||||
color: 'hsl(var(--background))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Custom Label</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
layout="vertical"
|
||||
margin={{
|
||||
right: 16,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid horizontal={false} />
|
||||
<YAxis
|
||||
dataKey="month"
|
||||
type="category"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
hide
|
||||
/>
|
||||
<XAxis dataKey="desktop" type="number" hide />
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<Bar dataKey="desktop" layout="vertical" fill="var(--color-desktop)" radius={4}>
|
||||
<LabelList
|
||||
dataKey="month"
|
||||
position="insideLeft"
|
||||
offset={8}
|
||||
className="fill-[--color-label]"
|
||||
fontSize={12}
|
||||
/>
|
||||
<LabelList
|
||||
dataKey="desktop"
|
||||
position="right"
|
||||
offset={8}
|
||||
className="fill-foreground"
|
||||
fontSize={12}
|
||||
/>
|
||||
</Bar>
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, CartesianGrid, LabelList, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A bar chart with a label'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Label</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
top: 20,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={8}>
|
||||
<LabelList position="top" offset={12} className="fill-foreground" fontSize={12} />
|
||||
</Bar>
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, XAxis, YAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A mixed bar chart'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Mixed</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
layout="vertical"
|
||||
margin={{
|
||||
left: 0,
|
||||
}}
|
||||
>
|
||||
<YAxis
|
||||
dataKey="browser"
|
||||
type="category"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => chartConfig[value as keyof typeof chartConfig]?.label}
|
||||
/>
|
||||
<XAxis dataKey="visitors" type="number" hide />
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Bar dataKey="visitors" layout="vertical" radius={5} />
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A multiple bar chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Multiple</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart accessibilityLayer data={chartData}>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="dashed" />} />
|
||||
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
||||
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, CartesianGrid, Cell, LabelList } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A bar chart with negative values'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', visitors: 186 },
|
||||
{ month: 'February', visitors: 205 },
|
||||
{ month: 'March', visitors: -207 },
|
||||
{ month: 'April', visitors: 173 },
|
||||
{ month: 'May', visitors: -209 },
|
||||
{ month: 'June', visitors: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Negative</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart accessibilityLayer data={chartData}>
|
||||
<CartesianGrid vertical={false} />
|
||||
<ChartTooltip
|
||||
cursor={false}
|
||||
content={<ChartTooltipContent hideLabel hideIndicator />}
|
||||
/>
|
||||
<Bar dataKey="visitors">
|
||||
<LabelList position="top" dataKey="month" fillOpacity={1} />
|
||||
{chartData.map((item) => (
|
||||
<Cell
|
||||
key={item.month}
|
||||
fill={item.visitors > 0 ? 'hsl(var(--chart-1))' : 'hsl(var(--chart-2))'}
|
||||
/>
|
||||
))}
|
||||
</Bar>
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import {
|
||||
ChartConfig,
|
||||
ChartContainer,
|
||||
ChartLegend,
|
||||
ChartLegendContent,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
} from 'ui'
|
||||
|
||||
export const description = 'A stacked bar chart with a legend'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Stacked + Legend</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart accessibilityLayer data={chartData}>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip content={<ChartTooltipContent hideLabel />} />
|
||||
<ChartLegend content={<ChartLegendContent />} />
|
||||
<Bar dataKey="desktop" stackId="a" fill="var(--color-desktop)" radius={[0, 0, 4, 4]} />
|
||||
<Bar dataKey="mobile" stackId="a" fill="var(--color-mobile)" radius={[4, 4, 0, 0]} />
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
Chart,
|
||||
ChartActions,
|
||||
ChartCard,
|
||||
ChartContent,
|
||||
ChartHeader,
|
||||
ChartTitle,
|
||||
ChartEmptyState,
|
||||
ChartLoadingState,
|
||||
ChartBar,
|
||||
ChartLine,
|
||||
} from 'ui-patterns/Chart'
|
||||
import { BarChart2, ExternalLink, LineChart } from 'lucide-react'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
export default function ChartComposedActions() {
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const [chartType, setChartType] = useState<'bar' | 'line'>('bar')
|
||||
|
||||
const actions = [
|
||||
{
|
||||
label: 'Open in Logs Explorer',
|
||||
onClick: () => {
|
||||
alert('Opening in Logs Explorer...')
|
||||
},
|
||||
icon: <ExternalLink size={12} />,
|
||||
},
|
||||
{
|
||||
label: 'Toggle Chart Type',
|
||||
onClick: () => {
|
||||
setChartType(chartType === 'bar' ? 'line' : 'bar')
|
||||
},
|
||||
icon: chartType === 'bar' ? <LineChart size={12} /> : <BarChart2 size={12} />,
|
||||
},
|
||||
]
|
||||
|
||||
const data = Array.from({ length: 46 }, (_, i) => {
|
||||
const date = new Date()
|
||||
date.setMinutes(date.getMinutes() - i * 5) // Each point 5 minutes apart
|
||||
|
||||
return {
|
||||
timestamp: date.toISOString(),
|
||||
requests: Math.floor(Math.random() * 100),
|
||||
}
|
||||
}).reverse()
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setIsLoading(false)
|
||||
}, 1000)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-6 w-8/12">
|
||||
<Chart isLoading={isLoading}>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartTitle tooltip="This is a tooltip">Total Requests</ChartTitle>
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
isEmpty={data.length === 0}
|
||||
emptyState={
|
||||
<ChartEmptyState
|
||||
icon={<BarChart2 size={16} />}
|
||||
title="No data to show"
|
||||
description="It may take up to 24 hours for data to refresh"
|
||||
/>
|
||||
}
|
||||
loadingState={<ChartLoadingState />}
|
||||
>
|
||||
<div className="h-40">
|
||||
{chartType === 'bar' ? (
|
||||
<ChartBar
|
||||
data={data}
|
||||
dataKey="requests"
|
||||
showGrid={false}
|
||||
showYAxis={true}
|
||||
YAxisProps={{
|
||||
tickFormatter: (value) => `${value}k`,
|
||||
width: 80,
|
||||
}}
|
||||
isFullHeight={true}
|
||||
/>
|
||||
) : (
|
||||
<ChartLine
|
||||
data={data}
|
||||
dataKey="requests"
|
||||
showGrid={true}
|
||||
showYAxis={true}
|
||||
YAxisProps={{
|
||||
tickFormatter: (value) => `${value}k`,
|
||||
width: 80,
|
||||
}}
|
||||
isFullHeight={true}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
Chart,
|
||||
ChartActions,
|
||||
ChartCard,
|
||||
ChartContent,
|
||||
ChartHeader,
|
||||
ChartTitle,
|
||||
ChartEmptyState,
|
||||
ChartLoadingState,
|
||||
ChartBar,
|
||||
ChartLine,
|
||||
} from 'ui-patterns/Chart'
|
||||
import { BarChart2, ExternalLink } from 'lucide-react'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
export default function ComposedChartBasic() {
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
|
||||
const actions = [
|
||||
{
|
||||
label: 'Open in Logs Explorer',
|
||||
onClick: () => {
|
||||
alert('Ta da! You clicked me! 🎉')
|
||||
},
|
||||
icon: <ExternalLink size={12} />,
|
||||
},
|
||||
]
|
||||
|
||||
const data = Array.from({ length: 46 }, (_, i) => {
|
||||
const date = new Date()
|
||||
date.setMinutes(date.getMinutes() - i * 5) // Each point 5 minutes apart
|
||||
|
||||
return {
|
||||
timestamp: date.toISOString(),
|
||||
standard_score: Math.floor(Math.random() * 100),
|
||||
}
|
||||
}).reverse()
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setIsLoading(false)
|
||||
}, 1000)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-6 w-8/12">
|
||||
<Chart isLoading={isLoading}>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartTitle tooltip="This is a tooltip">Standard Bar Chart</ChartTitle>
|
||||
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
|
||||
<ChartContent
|
||||
isEmpty={data.length === 0}
|
||||
emptyState={
|
||||
<ChartEmptyState
|
||||
icon={<BarChart2 size={16} />}
|
||||
title="No data to show"
|
||||
description="It may take up to 24 hours for data to refresh"
|
||||
/>
|
||||
}
|
||||
loadingState={<ChartLoadingState />}
|
||||
>
|
||||
<div className="h-40">
|
||||
<ChartBar
|
||||
data={data}
|
||||
dataKey="standard_score"
|
||||
showGrid={false}
|
||||
showYAxis={true}
|
||||
YAxisProps={{
|
||||
tickFormatter: (value) => `${value}k`,
|
||||
width: 80,
|
||||
}}
|
||||
isFullHeight={true}
|
||||
/>
|
||||
</div>
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
|
||||
<Chart isLoading={isLoading}>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartTitle tooltip="This is a tooltip">Standard Line Chart</ChartTitle>
|
||||
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
|
||||
<ChartContent
|
||||
isEmpty={data.length === 0}
|
||||
emptyState={
|
||||
<ChartEmptyState
|
||||
icon={<BarChart2 size={16} />}
|
||||
title="No data to show"
|
||||
description="It may take up to 24 hours for data to refresh"
|
||||
/>
|
||||
}
|
||||
loadingState={<ChartLoadingState />}
|
||||
>
|
||||
<div className="h-40">
|
||||
<ChartLine
|
||||
data={data}
|
||||
dataKey="standard_score"
|
||||
showGrid={true}
|
||||
showYAxis={true}
|
||||
YAxisProps={{
|
||||
tickFormatter: (value) => `${value}k`,
|
||||
width: 80,
|
||||
}}
|
||||
isFullHeight={true}
|
||||
/>
|
||||
</div>
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
Chart,
|
||||
ChartCard,
|
||||
ChartContent,
|
||||
ChartHeader,
|
||||
ChartEmptyState,
|
||||
ChartLoadingState,
|
||||
ChartMetric,
|
||||
} from 'ui-patterns/Chart'
|
||||
import { BarChart2 } from 'lucide-react'
|
||||
import { LogsBarChart } from 'ui-patterns/LogsBarChart'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
export default function ComposedChartDemo() {
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
|
||||
const data = Array.from({ length: 60 }, (_, i) => {
|
||||
const date = new Date()
|
||||
date.setMinutes(date.getMinutes() - i * 5) // Each point 5 minutes apart
|
||||
|
||||
return {
|
||||
timestamp: date.toISOString(),
|
||||
ok_count: Math.floor(Math.random() * 100), // Random value 0-99
|
||||
error_count: Math.floor(Math.random() * 50), // Random value 0-50
|
||||
warning_count: Math.floor(Math.random() * 50), // Random value 0-50
|
||||
}
|
||||
}).reverse()
|
||||
|
||||
const totalUsersValue = 4663
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setIsLoading(false)
|
||||
}, 1000)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="w-8/12">
|
||||
<Chart isLoading={isLoading}>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartMetric
|
||||
label="Total Users"
|
||||
value={totalUsersValue.toLocaleString('en-US')}
|
||||
tooltip="This is a tooltip"
|
||||
/>
|
||||
<div className="flex items-center gap-6">
|
||||
<ChartMetric label="Warn" value="1.2k" status="warning" align="end" />
|
||||
<ChartMetric label="Err" value="736" status="negative" align="end" />
|
||||
</div>
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
isEmpty={data.length === 0}
|
||||
emptyState={
|
||||
<ChartEmptyState
|
||||
icon={<BarChart2 size={16} />}
|
||||
title="No data to show"
|
||||
description="It may take up to 24 hours for data to refresh"
|
||||
/>
|
||||
}
|
||||
loadingState={<ChartLoadingState />}
|
||||
>
|
||||
<div className="h-40">
|
||||
<LogsBarChart data={data} isFullHeight={true} />
|
||||
</div>
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
Chart,
|
||||
ChartCard,
|
||||
ChartHeader,
|
||||
ChartActions,
|
||||
ChartContent,
|
||||
ChartMetric,
|
||||
ChartSparkline,
|
||||
} from 'ui-patterns/Chart'
|
||||
import { ExternalLink } from 'lucide-react'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Skeleton } from 'ui'
|
||||
|
||||
export default function ChartComposedMetrics() {
|
||||
const [data, setData] = useState<Array<{ value: number; timestamp: string }>>([])
|
||||
|
||||
const actions = [
|
||||
{
|
||||
label: 'Open in Logs Explorer',
|
||||
onClick: () => {
|
||||
alert('Ta da! You clicked me! 🎉')
|
||||
},
|
||||
icon: <ExternalLink size={12} />,
|
||||
},
|
||||
]
|
||||
|
||||
useEffect(() => {
|
||||
const now = new Date()
|
||||
setData(
|
||||
Array.from({ length: 12 }, (_, i) => ({
|
||||
value: Math.floor(4000 + i * 100 + (Math.random() * 2000 - 800)),
|
||||
timestamp: new Date(now.getTime() - (11 - i) * 60 * 60 * 1000).toISOString(),
|
||||
}))
|
||||
)
|
||||
}, [])
|
||||
|
||||
const averageValue = data.reduce((acc, curr) => acc + curr.value, 0) / data.length
|
||||
|
||||
const diff = data[data.length - 1]?.value - data[0]?.value || 0
|
||||
const diffPercentage = (diff / averageValue) * 100
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-2 gap-6 w-full">
|
||||
<Chart isLoading={!data.length}>
|
||||
<ChartCard>
|
||||
<ChartHeader className="pb-4" align="start">
|
||||
<ChartMetric label="Slow Queries" value={0} />
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
<Chart isLoading={!data.length}>
|
||||
<ChartCard>
|
||||
<ChartHeader className="pb-4" align="start">
|
||||
<ChartMetric label="Sign Ups" value={127} />
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
<Chart isLoading={!data.length}>
|
||||
<ChartCard>
|
||||
<ChartHeader align="start">
|
||||
<ChartMetric
|
||||
label="Active Users"
|
||||
value={averageValue.toLocaleString(undefined, { maximumFractionDigits: 0 })}
|
||||
diffValue={diffPercentage.toFixed(2) + '%'}
|
||||
/>
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
className="p-0"
|
||||
loadingState={<Skeleton className="w-full h-[6rem] rounded-none mt-4" />}
|
||||
>
|
||||
<ChartSparkline data={data} dataKey="value" />
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
<Chart isLoading={!data.length}>
|
||||
<ChartCard>
|
||||
<ChartHeader align="start">
|
||||
<ChartMetric
|
||||
label="Active Users"
|
||||
value={averageValue.toLocaleString(undefined, { maximumFractionDigits: 0 })}
|
||||
diffValue={diffPercentage.toFixed(2) + '%'}
|
||||
/>
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
className="p-0"
|
||||
loadingState={<Skeleton className="w-full h-[6rem] rounded-none mt-4" />}
|
||||
>
|
||||
<ChartSparkline data={data} dataKey="value" />
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
'use client'
|
||||
|
||||
import { BarChart2, ExternalLink } from 'lucide-react'
|
||||
import {
|
||||
Chart,
|
||||
ChartCard,
|
||||
ChartHeader,
|
||||
ChartTitle,
|
||||
ChartActions,
|
||||
ChartContent,
|
||||
ChartEmptyState,
|
||||
ChartLoadingState,
|
||||
ChartDisabledState,
|
||||
} from 'ui-patterns/Chart'
|
||||
import { Badge } from 'ui'
|
||||
|
||||
export default function ChartComposedStates() {
|
||||
const actions = [
|
||||
{
|
||||
label: 'Open in Logs Explorer',
|
||||
onClick: () => {
|
||||
alert('Ta da! You clicked me! 🎉')
|
||||
},
|
||||
icon: <ExternalLink size={12} />,
|
||||
},
|
||||
]
|
||||
|
||||
const disabledActions = [
|
||||
{
|
||||
label: 'Upgrade to Pro',
|
||||
href: '#',
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-6 w-8/12">
|
||||
<Chart isLoading={true}>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartTitle tooltip="This is a tooltip">Response Errors</ChartTitle>
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
<ChartContent loadingState={<ChartLoadingState />}>My chart here...</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
|
||||
<Chart>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartTitle tooltip="This is a tooltip">Response Errors</ChartTitle>
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
isEmpty={true}
|
||||
emptyState={
|
||||
<ChartEmptyState
|
||||
icon={<BarChart2 size={20} />}
|
||||
title="No data to show"
|
||||
description="It may take up to 24 hours for data to refresh"
|
||||
/>
|
||||
}
|
||||
loadingState={<ChartLoadingState />}
|
||||
>
|
||||
My chart here...
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
|
||||
<Chart isDisabled={true}>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartTitle tooltip="This is a tooltip">Response Errors</ChartTitle>
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
loadingState={<ChartLoadingState />}
|
||||
disabledState={
|
||||
<ChartDisabledState
|
||||
icon={<Badge variant="success">Pro</Badge>}
|
||||
label="API Processing Time"
|
||||
description="This chart is available on the Pro plan and above"
|
||||
actions={disabledActions}
|
||||
/>
|
||||
}
|
||||
>
|
||||
My chart here...
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
Chart,
|
||||
ChartActions,
|
||||
ChartCard,
|
||||
ChartContent,
|
||||
ChartHeader,
|
||||
ChartTitle,
|
||||
ChartEmptyState,
|
||||
ChartLoadingState,
|
||||
ChartBar,
|
||||
ChartFooter,
|
||||
} from 'ui-patterns/Chart'
|
||||
import { BarChart2, ExternalLink } from 'lucide-react'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Table, TableHead, TableBody, TableRow, TableCell, TableHeader } from 'ui'
|
||||
import { format } from 'date-fns'
|
||||
|
||||
export default function ChartComposedTable() {
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
|
||||
const actions = [
|
||||
{
|
||||
label: 'Open in Logs Explorer',
|
||||
onClick: () => {
|
||||
alert('Opening in Logs Explorer...')
|
||||
},
|
||||
icon: <ExternalLink size={12} />,
|
||||
},
|
||||
]
|
||||
|
||||
const data = Array.from({ length: 46 }, (_, i) => {
|
||||
const date = new Date()
|
||||
date.setMinutes(date.getMinutes() - i * 5) // Each point 5 minutes apart
|
||||
|
||||
return {
|
||||
timestamp: date.toISOString(),
|
||||
standard_score: Math.floor(Math.random() * 100),
|
||||
}
|
||||
}).reverse()
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setIsLoading(false)
|
||||
}, 1000)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-6 w-8/12">
|
||||
<Chart isLoading={isLoading}>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartTitle tooltip="This is a tooltip">Standard Bar Chart</ChartTitle>
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
isEmpty={data.length === 0}
|
||||
emptyState={
|
||||
<ChartEmptyState
|
||||
icon={<BarChart2 size={16} />}
|
||||
title="No data to show"
|
||||
description="It may take up to 24 hours for data to refresh"
|
||||
/>
|
||||
}
|
||||
loadingState={<ChartLoadingState />}
|
||||
>
|
||||
<div className="h-40">
|
||||
<ChartBar
|
||||
data={data}
|
||||
dataKey="standard_score"
|
||||
showGrid={false}
|
||||
showYAxis={true}
|
||||
YAxisProps={{
|
||||
tickFormatter: (value) => `${value}k`,
|
||||
width: 80,
|
||||
}}
|
||||
isFullHeight={true}
|
||||
/>
|
||||
</div>
|
||||
</ChartContent>
|
||||
<ChartFooter>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Timestamp</TableHead>
|
||||
<TableHead className="text-right">Standard Score</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{data.slice(0, 3).map((item) => (
|
||||
<TableRow key={item.timestamp}>
|
||||
<TableCell className="text-foreground-light">
|
||||
{format(new Date(item.timestamp), 'MMM d, yyyy h:mm a')}
|
||||
</TableCell>
|
||||
<TableCell className="text-right tabular-nums">{item.standard_score}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</ChartFooter>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { CartesianGrid, Line, LineChart, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A line chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Line Chart</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<LineChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Line
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
stroke="var(--color-desktop)"
|
||||
strokeWidth={2}
|
||||
dot={false}
|
||||
/>
|
||||
</LineChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { CartesianGrid, Dot, Line, LineChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A line chart with dots and colors'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Line Chart - Dots Colors</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<LineChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
top: 24,
|
||||
left: 24,
|
||||
right: 24,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<ChartTooltip
|
||||
cursor={false}
|
||||
content={<ChartTooltipContent indicator="line" nameKey="visitors" hideLabel />}
|
||||
/>
|
||||
<Line
|
||||
dataKey="visitors"
|
||||
type="natural"
|
||||
stroke="var(--color-visitors)"
|
||||
strokeWidth={2}
|
||||
dot={({ payload, ...props }) => {
|
||||
return (
|
||||
<Dot
|
||||
key={payload.browser}
|
||||
r={5}
|
||||
cx={props.cx}
|
||||
cy={props.cy}
|
||||
fill={payload.fill}
|
||||
stroke={payload.fill}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</LineChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { GitCommitVertical, TrendingUp } from 'lucide-react'
|
||||
import { CartesianGrid, Line, LineChart, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A line chart with custom dots'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Line Chart - Custom Dots</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<LineChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Line
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
stroke="var(--color-desktop)"
|
||||
strokeWidth={2}
|
||||
dot={({ cx, cy, payload }) => {
|
||||
const r = 24
|
||||
return (
|
||||
<GitCommitVertical
|
||||
key={payload.month}
|
||||
x={cx - r / 2}
|
||||
y={cy - r / 2}
|
||||
width={r}
|
||||
height={r}
|
||||
fill="hsl(var(--background))"
|
||||
stroke="var(--color-desktop)"
|
||||
/>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</LineChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { CartesianGrid, Line, LineChart, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A line chart with dots'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Line Chart - Dots</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<LineChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Line
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
stroke="var(--color-desktop)"
|
||||
strokeWidth={2}
|
||||
dot={{
|
||||
fill: 'var(--color-desktop)',
|
||||
}}
|
||||
activeDot={{
|
||||
r: 6,
|
||||
}}
|
||||
/>
|
||||
</LineChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,208 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import * as React from 'react'
|
||||
import { CartesianGrid, Line, LineChart, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'An interactive line chart'
|
||||
|
||||
const chartData = [
|
||||
{ date: '2024-04-01', desktop: 222, mobile: 150 },
|
||||
{ date: '2024-04-02', desktop: 97, mobile: 180 },
|
||||
{ date: '2024-04-03', desktop: 167, mobile: 120 },
|
||||
{ date: '2024-04-04', desktop: 242, mobile: 260 },
|
||||
{ date: '2024-04-05', desktop: 373, mobile: 290 },
|
||||
{ date: '2024-04-06', desktop: 301, mobile: 340 },
|
||||
{ date: '2024-04-07', desktop: 245, mobile: 180 },
|
||||
{ date: '2024-04-08', desktop: 409, mobile: 320 },
|
||||
{ date: '2024-04-09', desktop: 59, mobile: 110 },
|
||||
{ date: '2024-04-10', desktop: 261, mobile: 190 },
|
||||
{ date: '2024-04-11', desktop: 327, mobile: 350 },
|
||||
{ date: '2024-04-12', desktop: 292, mobile: 210 },
|
||||
{ date: '2024-04-13', desktop: 342, mobile: 380 },
|
||||
{ date: '2024-04-14', desktop: 137, mobile: 220 },
|
||||
{ date: '2024-04-15', desktop: 120, mobile: 170 },
|
||||
{ date: '2024-04-16', desktop: 138, mobile: 190 },
|
||||
{ date: '2024-04-17', desktop: 446, mobile: 360 },
|
||||
{ date: '2024-04-18', desktop: 364, mobile: 410 },
|
||||
{ date: '2024-04-19', desktop: 243, mobile: 180 },
|
||||
{ date: '2024-04-20', desktop: 89, mobile: 150 },
|
||||
{ date: '2024-04-21', desktop: 137, mobile: 200 },
|
||||
{ date: '2024-04-22', desktop: 224, mobile: 170 },
|
||||
{ date: '2024-04-23', desktop: 138, mobile: 230 },
|
||||
{ date: '2024-04-24', desktop: 387, mobile: 290 },
|
||||
{ date: '2024-04-25', desktop: 215, mobile: 250 },
|
||||
{ date: '2024-04-26', desktop: 75, mobile: 130 },
|
||||
{ date: '2024-04-27', desktop: 383, mobile: 420 },
|
||||
{ date: '2024-04-28', desktop: 122, mobile: 180 },
|
||||
{ date: '2024-04-29', desktop: 315, mobile: 240 },
|
||||
{ date: '2024-04-30', desktop: 454, mobile: 380 },
|
||||
{ date: '2024-05-01', desktop: 165, mobile: 220 },
|
||||
{ date: '2024-05-02', desktop: 293, mobile: 310 },
|
||||
{ date: '2024-05-03', desktop: 247, mobile: 190 },
|
||||
{ date: '2024-05-04', desktop: 385, mobile: 420 },
|
||||
{ date: '2024-05-05', desktop: 481, mobile: 390 },
|
||||
{ date: '2024-05-06', desktop: 498, mobile: 520 },
|
||||
{ date: '2024-05-07', desktop: 388, mobile: 300 },
|
||||
{ date: '2024-05-08', desktop: 149, mobile: 210 },
|
||||
{ date: '2024-05-09', desktop: 227, mobile: 180 },
|
||||
{ date: '2024-05-10', desktop: 293, mobile: 330 },
|
||||
{ date: '2024-05-11', desktop: 335, mobile: 270 },
|
||||
{ date: '2024-05-12', desktop: 197, mobile: 240 },
|
||||
{ date: '2024-05-13', desktop: 197, mobile: 160 },
|
||||
{ date: '2024-05-14', desktop: 448, mobile: 490 },
|
||||
{ date: '2024-05-15', desktop: 473, mobile: 380 },
|
||||
{ date: '2024-05-16', desktop: 338, mobile: 400 },
|
||||
{ date: '2024-05-17', desktop: 499, mobile: 420 },
|
||||
{ date: '2024-05-18', desktop: 315, mobile: 350 },
|
||||
{ date: '2024-05-19', desktop: 235, mobile: 180 },
|
||||
{ date: '2024-05-20', desktop: 177, mobile: 230 },
|
||||
{ date: '2024-05-21', desktop: 82, mobile: 140 },
|
||||
{ date: '2024-05-22', desktop: 81, mobile: 120 },
|
||||
{ date: '2024-05-23', desktop: 252, mobile: 290 },
|
||||
{ date: '2024-05-24', desktop: 294, mobile: 220 },
|
||||
{ date: '2024-05-25', desktop: 201, mobile: 250 },
|
||||
{ date: '2024-05-26', desktop: 213, mobile: 170 },
|
||||
{ date: '2024-05-27', desktop: 420, mobile: 460 },
|
||||
{ date: '2024-05-28', desktop: 233, mobile: 190 },
|
||||
{ date: '2024-05-29', desktop: 78, mobile: 130 },
|
||||
{ date: '2024-05-30', desktop: 340, mobile: 280 },
|
||||
{ date: '2024-05-31', desktop: 178, mobile: 230 },
|
||||
{ date: '2024-06-01', desktop: 178, mobile: 200 },
|
||||
{ date: '2024-06-02', desktop: 470, mobile: 410 },
|
||||
{ date: '2024-06-03', desktop: 103, mobile: 160 },
|
||||
{ date: '2024-06-04', desktop: 439, mobile: 380 },
|
||||
{ date: '2024-06-05', desktop: 88, mobile: 140 },
|
||||
{ date: '2024-06-06', desktop: 294, mobile: 250 },
|
||||
{ date: '2024-06-07', desktop: 323, mobile: 370 },
|
||||
{ date: '2024-06-08', desktop: 385, mobile: 320 },
|
||||
{ date: '2024-06-09', desktop: 438, mobile: 480 },
|
||||
{ date: '2024-06-10', desktop: 155, mobile: 200 },
|
||||
{ date: '2024-06-11', desktop: 92, mobile: 150 },
|
||||
{ date: '2024-06-12', desktop: 492, mobile: 420 },
|
||||
{ date: '2024-06-13', desktop: 81, mobile: 130 },
|
||||
{ date: '2024-06-14', desktop: 426, mobile: 380 },
|
||||
{ date: '2024-06-15', desktop: 307, mobile: 350 },
|
||||
{ date: '2024-06-16', desktop: 371, mobile: 310 },
|
||||
{ date: '2024-06-17', desktop: 475, mobile: 520 },
|
||||
{ date: '2024-06-18', desktop: 107, mobile: 170 },
|
||||
{ date: '2024-06-19', desktop: 341, mobile: 290 },
|
||||
{ date: '2024-06-20', desktop: 408, mobile: 450 },
|
||||
{ date: '2024-06-21', desktop: 169, mobile: 210 },
|
||||
{ date: '2024-06-22', desktop: 317, mobile: 270 },
|
||||
{ date: '2024-06-23', desktop: 480, mobile: 530 },
|
||||
{ date: '2024-06-24', desktop: 132, mobile: 180 },
|
||||
{ date: '2024-06-25', desktop: 141, mobile: 190 },
|
||||
{ date: '2024-06-26', desktop: 434, mobile: 380 },
|
||||
{ date: '2024-06-27', desktop: 448, mobile: 490 },
|
||||
{ date: '2024-06-28', desktop: 149, mobile: 200 },
|
||||
{ date: '2024-06-29', desktop: 103, mobile: 160 },
|
||||
{ date: '2024-06-30', desktop: 446, mobile: 400 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
views: {
|
||||
label: 'Page Views',
|
||||
},
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
const [activeChart, setActiveChart] = React.useState<keyof typeof chartConfig>('desktop')
|
||||
|
||||
const total = React.useMemo(
|
||||
() => ({
|
||||
desktop: chartData.reduce((acc, curr) => acc + curr.desktop, 0),
|
||||
mobile: chartData.reduce((acc, curr) => acc + curr.mobile, 0),
|
||||
}),
|
||||
[]
|
||||
)
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="flex flex-col items-stretch space-y-0 border-b p-0 sm:flex-row">
|
||||
<div className="flex flex-1 flex-col justify-center gap-1 px-6 py-5 sm:py-6">
|
||||
<CardTitle>Line Chart - Interactive</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 3 months</CardDescription>
|
||||
</div>
|
||||
<div className="flex">
|
||||
{['desktop', 'mobile'].map((key) => {
|
||||
const chart = key as keyof typeof chartConfig
|
||||
return (
|
||||
<button
|
||||
key={chart}
|
||||
data-active={activeChart === chart}
|
||||
className="flex flex-1 flex-col justify-center gap-1 border-t px-6 py-4 text-left even:border-l data-[active=true]:bg-muted/50 sm:border-l sm:border-t-0 sm:px-8 sm:py-6"
|
||||
onClick={() => setActiveChart(chart)}
|
||||
>
|
||||
<span className="text-xs text-muted-foreground">{chartConfig[chart].label}</span>
|
||||
<span className="text-lg font-bold leading-none sm:text-3xl">
|
||||
{total[key as keyof typeof total].toLocaleString()}
|
||||
</span>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="px-2 sm:p-6">
|
||||
<ChartContainer config={chartConfig} className="aspect-auto h-[250px] w-full">
|
||||
<LineChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="date"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
minTickGap={32}
|
||||
tickFormatter={(value) => {
|
||||
const date = new Date(value)
|
||||
return date.toLocaleDateString('en-US', {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<ChartTooltip
|
||||
content={
|
||||
<ChartTooltipContent
|
||||
className="w-[150px]"
|
||||
nameKey="views"
|
||||
labelFormatter={(value) => {
|
||||
return new Date(value).toLocaleDateString('en-US', {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
year: 'numeric',
|
||||
})
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Line
|
||||
dataKey={activeChart}
|
||||
type="monotone"
|
||||
stroke={`var(--color-${activeChart})`}
|
||||
strokeWidth={2}
|
||||
dot={false}
|
||||
/>
|
||||
</LineChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { CartesianGrid, LabelList, Line, LineChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A line chart with a custom label'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Line Chart - Custom Label</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<LineChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
top: 24,
|
||||
left: 24,
|
||||
right: 24,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<ChartTooltip
|
||||
cursor={false}
|
||||
content={<ChartTooltipContent indicator="line" nameKey="visitors" hideLabel />}
|
||||
/>
|
||||
<Line
|
||||
dataKey="visitors"
|
||||
type="natural"
|
||||
stroke="var(--color-visitors)"
|
||||
strokeWidth={2}
|
||||
dot={{
|
||||
fill: 'var(--color-visitors)',
|
||||
}}
|
||||
activeDot={{
|
||||
r: 6,
|
||||
}}
|
||||
>
|
||||
<LabelList
|
||||
position="top"
|
||||
offset={12}
|
||||
className="fill-foreground"
|
||||
fontSize={12}
|
||||
dataKey="browser"
|
||||
formatter={(value: keyof typeof chartConfig) => chartConfig[value]?.label}
|
||||
/>
|
||||
</Line>
|
||||
</LineChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { CartesianGrid, LabelList, Line, LineChart, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A line chart with a label'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Line Chart - Label</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<LineChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
top: 20,
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<Line
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
stroke="var(--color-desktop)"
|
||||
strokeWidth={2}
|
||||
dot={{
|
||||
fill: 'var(--color-desktop)',
|
||||
}}
|
||||
activeDot={{
|
||||
r: 6,
|
||||
}}
|
||||
>
|
||||
<LabelList position="top" offset={12} className="fill-foreground" fontSize={12} />
|
||||
</Line>
|
||||
</LineChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { CartesianGrid, Line, LineChart, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A linear line chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Line Chart - Linear</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<LineChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Line
|
||||
dataKey="desktop"
|
||||
type="linear"
|
||||
stroke="var(--color-desktop)"
|
||||
strokeWidth={2}
|
||||
dot={false}
|
||||
/>
|
||||
</LineChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { CartesianGrid, Line, LineChart, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A multiple line chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Line Chart - Multiple</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<LineChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
|
||||
<Line
|
||||
dataKey="desktop"
|
||||
type="monotone"
|
||||
stroke="var(--color-desktop)"
|
||||
strokeWidth={2}
|
||||
dot={false}
|
||||
/>
|
||||
<Line
|
||||
dataKey="mobile"
|
||||
type="monotone"
|
||||
stroke="var(--color-mobile)"
|
||||
strokeWidth={2}
|
||||
dot={false}
|
||||
/>
|
||||
</LineChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { CartesianGrid, Line, LineChart, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A line chart with step'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Line Chart - Step</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<LineChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Line
|
||||
dataKey="desktop"
|
||||
type="step"
|
||||
stroke="var(--color-desktop)"
|
||||
strokeWidth={2}
|
||||
dot={false}
|
||||
/>
|
||||
</LineChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Label, Pie, PieChart, Sector } from 'recharts'
|
||||
import { PieSectorDataItem } from 'recharts/types/polar/Pie'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A donut chart with an active sector'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Pie Chart - Donut Active</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<PieChart>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Pie
|
||||
data={chartData}
|
||||
dataKey="visitors"
|
||||
nameKey="browser"
|
||||
innerRadius={60}
|
||||
strokeWidth={5}
|
||||
activeIndex={0}
|
||||
activeShape={({ outerRadius = 0, ...props }: PieSectorDataItem) => (
|
||||
<Sector {...props} outerRadius={outerRadius + 10} />
|
||||
)}
|
||||
/>
|
||||
</PieChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import * as React from 'react'
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Label, Pie, PieChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A donut chart with text'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 287, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 190, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
const totalVisitors = React.useMemo(() => {
|
||||
return chartData.reduce((acc, curr) => acc + curr.visitors, 0)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Pie Chart - Donut with Text</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<PieChart>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Pie
|
||||
data={chartData}
|
||||
dataKey="visitors"
|
||||
nameKey="browser"
|
||||
innerRadius={60}
|
||||
strokeWidth={5}
|
||||
>
|
||||
<Label
|
||||
content={({ viewBox }) => {
|
||||
if (viewBox && 'cx' in viewBox && 'cy' in viewBox) {
|
||||
return (
|
||||
<text
|
||||
x={viewBox.cx}
|
||||
y={viewBox.cy}
|
||||
textAnchor="middle"
|
||||
dominantBaseline="middle"
|
||||
>
|
||||
<tspan
|
||||
x={viewBox.cx}
|
||||
y={viewBox.cy}
|
||||
className="fill-foreground text-3xl font-bold"
|
||||
>
|
||||
{totalVisitors.toLocaleString()}
|
||||
</tspan>
|
||||
<tspan
|
||||
x={viewBox.cx}
|
||||
y={(viewBox.cy || 0) + 24}
|
||||
className="fill-muted-foreground"
|
||||
>
|
||||
Visitors
|
||||
</tspan>
|
||||
</text>
|
||||
)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Pie, PieChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A donut chart'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Pie Chart - Donut</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<PieChart>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Pie data={chartData} dataKey="visitors" nameKey="browser" innerRadius={60} />
|
||||
</PieChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import * as React from 'react'
|
||||
import { Label, Pie, PieChart, Sector } from 'recharts'
|
||||
import { PieSectorDataItem } from 'recharts/types/polar/Pie'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartStyle, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
import {
|
||||
Select_Shadcn_,
|
||||
SelectContent_Shadcn_,
|
||||
SelectItem_Shadcn_,
|
||||
SelectTrigger_Shadcn_,
|
||||
SelectValue_Shadcn_,
|
||||
} from 'ui'
|
||||
|
||||
export const description = 'An interactive pie chart'
|
||||
|
||||
const desktopData = [
|
||||
{ month: 'january', desktop: 186, fill: 'var(--color-january)' },
|
||||
{ month: 'february', desktop: 305, fill: 'var(--color-february)' },
|
||||
{ month: 'march', desktop: 237, fill: 'var(--color-march)' },
|
||||
{ month: 'april', desktop: 173, fill: 'var(--color-april)' },
|
||||
{ month: 'may', desktop: 209, fill: 'var(--color-may)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
},
|
||||
january: {
|
||||
label: 'January',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
february: {
|
||||
label: 'February',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
march: {
|
||||
label: 'March',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
april: {
|
||||
label: 'April',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
may: {
|
||||
label: 'May',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
const id = 'pie-interactive'
|
||||
const [activeMonth, setActiveMonth] = React.useState(desktopData[0].month)
|
||||
|
||||
const activeIndex = React.useMemo(
|
||||
() => desktopData.findIndex((item) => item.month === activeMonth),
|
||||
[activeMonth]
|
||||
)
|
||||
const months = React.useMemo(() => desktopData.map((item) => item.month), [])
|
||||
|
||||
return (
|
||||
<Card data-chart={id} className="flex flex-col">
|
||||
<ChartStyle id={id} config={chartConfig} />
|
||||
<CardHeader className="flex-row items-start space-y-0 pb-0">
|
||||
<div className="grid gap-1">
|
||||
<CardTitle>Pie Chart - Interactive</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</div>
|
||||
<Select_Shadcn_ value={activeMonth} onValueChange={setActiveMonth}>
|
||||
<SelectTrigger_Shadcn_
|
||||
className="ml-auto h-7 w-[130px] rounded-lg pl-2.5"
|
||||
aria-label="Select a value"
|
||||
>
|
||||
<SelectValue_Shadcn_ placeholder="Select month" />
|
||||
</SelectTrigger_Shadcn_>
|
||||
<SelectContent_Shadcn_ align="end" className="rounded-xl">
|
||||
{months.map((key) => {
|
||||
const config = chartConfig[key as keyof typeof chartConfig]
|
||||
|
||||
if (!config) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<SelectItem_Shadcn_ key={key} value={key} className="rounded-lg [&_span]:flex">
|
||||
<div className="flex items-center gap-2 text-xs">
|
||||
<span
|
||||
className="flex h-3 w-3 shrink-0 rounded-sm"
|
||||
style={{
|
||||
backgroundColor: `var(--color-${key})`,
|
||||
}}
|
||||
/>
|
||||
{config?.label}
|
||||
</div>
|
||||
</SelectItem_Shadcn_>
|
||||
)
|
||||
})}
|
||||
</SelectContent_Shadcn_>
|
||||
</Select_Shadcn_>
|
||||
</CardHeader>
|
||||
<CardContent className="flex flex-1 justify-center pb-0">
|
||||
<ChartContainer
|
||||
id={id}
|
||||
config={chartConfig}
|
||||
className="mx-auto aspect-square w-full max-w-[300px]"
|
||||
>
|
||||
<PieChart>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Pie
|
||||
data={desktopData}
|
||||
dataKey="desktop"
|
||||
nameKey="month"
|
||||
innerRadius={60}
|
||||
strokeWidth={5}
|
||||
activeIndex={activeIndex}
|
||||
activeShape={({ outerRadius = 0, ...props }: PieSectorDataItem) => (
|
||||
<g>
|
||||
<Sector {...props} outerRadius={outerRadius + 10} />
|
||||
<Sector
|
||||
{...props}
|
||||
outerRadius={outerRadius + 25}
|
||||
innerRadius={outerRadius + 12}
|
||||
/>
|
||||
</g>
|
||||
)}
|
||||
>
|
||||
<Label
|
||||
content={({ viewBox }) => {
|
||||
if (viewBox && 'cx' in viewBox && 'cy' in viewBox) {
|
||||
return (
|
||||
<text
|
||||
x={viewBox.cx}
|
||||
y={viewBox.cy}
|
||||
textAnchor="middle"
|
||||
dominantBaseline="middle"
|
||||
>
|
||||
<tspan
|
||||
x={viewBox.cx}
|
||||
y={viewBox.cy}
|
||||
className="fill-foreground text-3xl font-bold"
|
||||
>
|
||||
{desktopData[activeIndex].desktop.toLocaleString()}
|
||||
</tspan>
|
||||
<tspan
|
||||
x={viewBox.cx}
|
||||
y={(viewBox.cy || 0) + 24}
|
||||
className="fill-muted-foreground"
|
||||
>
|
||||
Visitors
|
||||
</tspan>
|
||||
</text>
|
||||
)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Pie, PieChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A pie chart with a custom label'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Pie Chart - Custom Label</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<PieChart>
|
||||
<ChartTooltip content={<ChartTooltipContent nameKey="visitors" hideLabel />} />
|
||||
<Pie
|
||||
data={chartData}
|
||||
dataKey="visitors"
|
||||
labelLine={false}
|
||||
label={({ payload, ...props }) => {
|
||||
return (
|
||||
<text
|
||||
cx={props.cx}
|
||||
cy={props.cy}
|
||||
x={props.x}
|
||||
y={props.y}
|
||||
textAnchor={props.textAnchor}
|
||||
dominantBaseline={props.dominantBaseline}
|
||||
fill="hsla(var(--foreground))"
|
||||
>
|
||||
{`${
|
||||
chartConfig[payload.browser as keyof typeof chartConfig]?.label
|
||||
} (${payload.visitors})`}
|
||||
</text>
|
||||
)
|
||||
}}
|
||||
nameKey="browser"
|
||||
/>
|
||||
</PieChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { LabelList, Pie, PieChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A pie chart with a label list'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Pie Chart - Label List</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<PieChart>
|
||||
<ChartTooltip content={<ChartTooltipContent nameKey="visitors" hideLabel />} />
|
||||
<Pie data={chartData} dataKey="visitors">
|
||||
<LabelList
|
||||
dataKey="browser"
|
||||
className="fill-background"
|
||||
stroke="none"
|
||||
fontSize={12}
|
||||
formatter={(value: keyof typeof chartConfig) => chartConfig[value]?.label}
|
||||
/>
|
||||
</Pie>
|
||||
</PieChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Pie, PieChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A pie chart with a label'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Pie Chart - Label</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer
|
||||
config={chartConfig}
|
||||
className="mx-auto aspect-square max-h-[250px] pb-0 [&_.recharts-pie-label-text]:fill-foreground"
|
||||
>
|
||||
<PieChart>
|
||||
<ChartTooltip content={<ChartTooltipContent hideLabel />} />
|
||||
<Pie data={chartData} dataKey="visitors" label nameKey="browser" />
|
||||
</PieChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { Pie, PieChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartLegend, ChartLegendContent } from 'ui'
|
||||
|
||||
export const description = 'A pie chart with a legend'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Pie Chart - Legend</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[300px]">
|
||||
<PieChart>
|
||||
<Pie data={chartData} dataKey="visitors" />
|
||||
<ChartLegend
|
||||
content={<ChartLegendContent nameKey="browser" />}
|
||||
className="-translate-y-2 flex-wrap gap-2 [&>*]:basis-1/4 [&>*]:justify-center"
|
||||
/>
|
||||
</PieChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Pie, PieChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A pie chart with no separator'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Pie Chart - Separator None</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<PieChart>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Pie data={chartData} dataKey="visitors" nameKey="browser" stroke="0" />
|
||||
</PieChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Pie, PieChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A simple pie chart'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Pie Chart</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<PieChart>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Pie data={chartData} dataKey="visitors" nameKey="browser" />
|
||||
</PieChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import * as React from 'react'
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Label, Pie, PieChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A pie chart with stacked sections'
|
||||
|
||||
const desktopData = [
|
||||
{ month: 'january', desktop: 186, fill: 'var(--color-january)' },
|
||||
{ month: 'february', desktop: 305, fill: 'var(--color-february)' },
|
||||
{ month: 'march', desktop: 237, fill: 'var(--color-march)' },
|
||||
{ month: 'april', desktop: 173, fill: 'var(--color-april)' },
|
||||
{ month: 'may', desktop: 209, fill: 'var(--color-may)' },
|
||||
]
|
||||
|
||||
const mobileData = [
|
||||
{ month: 'january', mobile: 80, fill: 'var(--color-january)' },
|
||||
{ month: 'february', mobile: 200, fill: 'var(--color-february)' },
|
||||
{ month: 'march', mobile: 120, fill: 'var(--color-march)' },
|
||||
{ month: 'april', mobile: 190, fill: 'var(--color-april)' },
|
||||
{ month: 'may', mobile: 130, fill: 'var(--color-may)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
},
|
||||
january: {
|
||||
label: 'January',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
february: {
|
||||
label: 'February',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
march: {
|
||||
label: 'March',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
april: {
|
||||
label: 'April',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
may: {
|
||||
label: 'May',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Pie Chart - Stacked</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<PieChart>
|
||||
<ChartTooltip
|
||||
content={
|
||||
<ChartTooltipContent
|
||||
labelKey="visitors"
|
||||
nameKey="month"
|
||||
indicator="line"
|
||||
labelFormatter={(_, payload) => {
|
||||
return chartConfig[payload?.[0].dataKey as keyof typeof chartConfig].label
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Pie data={desktopData} dataKey="desktop" outerRadius={60} />
|
||||
<Pie data={mobileData} dataKey="mobile" innerRadius={70} outerRadius={90} />
|
||||
</PieChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radar chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 273 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="items-center pb-4">
|
||||
<CardTitle>Radar Chart</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadarChart data={chartData}>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
|
||||
<PolarAngleAxis dataKey="month" />
|
||||
<PolarGrid />
|
||||
<Radar dataKey="desktop" fill="var(--color-desktop)" fillOpacity={0.6} />
|
||||
</RadarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radar chart with dots'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 273 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="items-center">
|
||||
<CardTitle>Radar Chart - Dots</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadarChart data={chartData}>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
|
||||
<PolarAngleAxis dataKey="month" />
|
||||
<PolarGrid />
|
||||
<Radar
|
||||
dataKey="desktop"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.6}
|
||||
dot={{
|
||||
r: 4,
|
||||
fillOpacity: 1,
|
||||
}}
|
||||
/>
|
||||
</RadarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radar chart with a grid and circle fill'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 285 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 203 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 264 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="items-center pb-4">
|
||||
<CardTitle>Radar Chart - Grid Circle Filled</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadarChart data={chartData}>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
|
||||
<PolarGrid className="fill-[--color-desktop] opacity-20" gridType="circle" />
|
||||
<PolarAngleAxis dataKey="month" />
|
||||
<Radar dataKey="desktop" fill="var(--color-desktop)" fillOpacity={0.5} />
|
||||
</RadarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radar chart with a grid and circle fill'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 203 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="items-center pb-4">
|
||||
<CardTitle>Radar Chart - Grid Circle - No lines</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadarChart data={chartData}>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<PolarGrid gridType="circle" radialLines={false} />
|
||||
<PolarAngleAxis dataKey="month" />
|
||||
<Radar
|
||||
dataKey="desktop"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.6}
|
||||
dot={{
|
||||
r: 4,
|
||||
fillOpacity: 1,
|
||||
}}
|
||||
/>
|
||||
</RadarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radar chart with a grid and circle'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 273 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="items-center pb-4">
|
||||
<CardTitle>Radar Chart - Grid Circle</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadarChart data={chartData}>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<PolarGrid gridType="circle" />
|
||||
<PolarAngleAxis dataKey="month" />
|
||||
<Radar
|
||||
dataKey="desktop"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.6}
|
||||
dot={{
|
||||
r: 4,
|
||||
fillOpacity: 1,
|
||||
}}
|
||||
/>
|
||||
</RadarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radar chart with a custom grid'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 273 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="items-center pb-4">
|
||||
<CardTitle>Radar Chart - Grid Custom</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadarChart data={chartData}>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<PolarGrid radialLines={false} polarRadius={[90]} strokeWidth={1} />
|
||||
<PolarAngleAxis dataKey="month" />
|
||||
<Radar dataKey="desktop" fill="var(--color-desktop)" fillOpacity={0.6} />
|
||||
</RadarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radar chart with a grid filled'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 285 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 203 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 264 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="items-center pb-4">
|
||||
<CardTitle>Radar Chart - Grid Filled</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadarChart data={chartData}>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<PolarGrid className="fill-[--color-desktop] opacity-20" />
|
||||
<PolarAngleAxis dataKey="month" />
|
||||
<Radar dataKey="desktop" fill="var(--color-desktop)" fillOpacity={0.5} />
|
||||
</RadarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { PolarAngleAxis, Radar, RadarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radar chart with no grid'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 273 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="items-center pb-4">
|
||||
<CardTitle>Radar Chart - Grid None</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadarChart data={chartData}>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<PolarAngleAxis dataKey="month" />
|
||||
<Radar
|
||||
dataKey="desktop"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.6}
|
||||
dot={{
|
||||
r: 4,
|
||||
fillOpacity: 1,
|
||||
}}
|
||||
/>
|
||||
</RadarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { ArrowDownFromLine, ArrowUpFromLine, TrendingUp } from 'lucide-react'
|
||||
import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import {
|
||||
ChartConfig,
|
||||
ChartContainer,
|
||||
ChartLegend,
|
||||
ChartLegendContent,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
} from 'ui'
|
||||
|
||||
export const description = 'A radar chart with icons'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
icon: ArrowDownFromLine,
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
icon: ArrowUpFromLine,
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="items-center pb-4">
|
||||
<CardTitle>Radar Chart - Icons</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadarChart
|
||||
data={chartData}
|
||||
margin={{
|
||||
top: -40,
|
||||
bottom: -10,
|
||||
}}
|
||||
>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<PolarAngleAxis dataKey="month" />
|
||||
<PolarGrid />
|
||||
<Radar dataKey="desktop" fill="var(--color-desktop)" fillOpacity={0.6} />
|
||||
<Radar dataKey="mobile" fill="var(--color-mobile)" />
|
||||
<ChartLegend className="mt-8" content={<ChartLegendContent />} />
|
||||
</RadarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 pt-4 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radar chart with a custom label'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="items-center pb-4">
|
||||
<CardTitle>Radar Chart - Custom Label</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadarChart
|
||||
data={chartData}
|
||||
margin={{
|
||||
top: 10,
|
||||
right: 10,
|
||||
bottom: 10,
|
||||
left: 10,
|
||||
}}
|
||||
>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<PolarAngleAxis
|
||||
dataKey="month"
|
||||
tick={({ x, y, textAnchor, value, index, ...props }) => {
|
||||
const data = chartData[index]
|
||||
|
||||
return (
|
||||
<text
|
||||
x={x}
|
||||
y={index === 0 ? y - 10 : y}
|
||||
textAnchor={textAnchor}
|
||||
fontSize={13}
|
||||
fontWeight={500}
|
||||
{...props}
|
||||
>
|
||||
<tspan>{data.desktop}</tspan>
|
||||
<tspan className="fill-muted-foreground">/</tspan>
|
||||
<tspan>{data.mobile}</tspan>
|
||||
<tspan x={x} dy={'1rem'} fontSize={12} className="fill-muted-foreground">
|
||||
{data.month}
|
||||
</tspan>
|
||||
</text>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
|
||||
<PolarGrid />
|
||||
<Radar dataKey="desktop" fill="var(--color-desktop)" fillOpacity={0.6} />
|
||||
<Radar dataKey="mobile" fill="var(--color-mobile)" />
|
||||
</RadarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import {
|
||||
ChartConfig,
|
||||
ChartContainer,
|
||||
ChartLegend,
|
||||
ChartLegendContent,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
} from 'ui'
|
||||
|
||||
export const description = 'A radar chart with a legend'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="items-center pb-4">
|
||||
<CardTitle>Radar Chart - Legend</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadarChart
|
||||
data={chartData}
|
||||
margin={{
|
||||
top: -40,
|
||||
bottom: -10,
|
||||
}}
|
||||
>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<PolarAngleAxis dataKey="month" />
|
||||
<PolarGrid />
|
||||
<Radar dataKey="desktop" fill="var(--color-desktop)" fillOpacity={0.6} />
|
||||
<Radar dataKey="mobile" fill="var(--color-mobile)" />
|
||||
<ChartLegend className="mt-8" content={<ChartLegendContent />} />
|
||||
</RadarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 pt-4 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radar chart with lines only'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 160 },
|
||||
{ month: 'February', desktop: 185, mobile: 170 },
|
||||
{ month: 'March', desktop: 207, mobile: 180 },
|
||||
{ month: 'April', desktop: 173, mobile: 160 },
|
||||
{ month: 'May', desktop: 160, mobile: 190 },
|
||||
{ month: 'June', desktop: 174, mobile: 204 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="items-center pb-4">
|
||||
<CardTitle>Radar Chart - Lines Only</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadarChart data={chartData}>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<PolarAngleAxis dataKey="month" />
|
||||
<PolarGrid radialLines={false} />
|
||||
<Radar
|
||||
dataKey="desktop"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0}
|
||||
stroke="var(--color-desktop)"
|
||||
strokeWidth={2}
|
||||
/>
|
||||
<Radar
|
||||
dataKey="mobile"
|
||||
fill="var(--color-mobile)"
|
||||
fillOpacity={0}
|
||||
stroke="var(--color-mobile)"
|
||||
strokeWidth={2}
|
||||
/>
|
||||
</RadarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radar chart with multiple data'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="items-center pb-4">
|
||||
<CardTitle>Radar Chart - Multiple</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadarChart data={chartData}>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<PolarAngleAxis dataKey="month" />
|
||||
<PolarGrid />
|
||||
<Radar dataKey="desktop" fill="var(--color-desktop)" fillOpacity={0.6} />
|
||||
<Radar dataKey="mobile" fill="var(--color-mobile)" />
|
||||
</RadarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { PolarAngleAxis, PolarGrid, PolarRadiusAxis, Radar, RadarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radar chart with a radius axis'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="items-center pb-4">
|
||||
<CardTitle>Radar Chart - Radius Axis</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadarChart data={chartData}>
|
||||
<ChartTooltip
|
||||
cursor={false}
|
||||
content={<ChartTooltipContent indicator="line" labelKey="month" />}
|
||||
/>
|
||||
<PolarGrid />
|
||||
<Radar dataKey="desktop" fill="var(--color-desktop)" fillOpacity={0.6} />
|
||||
<Radar dataKey="mobile" fill="var(--color-mobile)" />
|
||||
<PolarRadiusAxis
|
||||
angle={60}
|
||||
stroke="hsla(var(--foreground))"
|
||||
orientation="middle"
|
||||
axisLine={false}
|
||||
/>
|
||||
</RadarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { PolarGrid, RadialBar, RadialBarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radial chart with a grid'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Radial Chart - Grid</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadialBarChart data={chartData} innerRadius={30} outerRadius={100}>
|
||||
<ChartTooltip
|
||||
cursor={false}
|
||||
content={<ChartTooltipContent hideLabel nameKey="browser" />}
|
||||
/>
|
||||
<PolarGrid gridType="circle" />
|
||||
<RadialBar dataKey="visitors" />
|
||||
</RadialBarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { LabelList, RadialBar, RadialBarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radial chart with a label'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Radial Chart - Label</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadialBarChart
|
||||
data={chartData}
|
||||
startAngle={-90}
|
||||
endAngle={380}
|
||||
innerRadius={30}
|
||||
outerRadius={110}
|
||||
>
|
||||
<ChartTooltip
|
||||
cursor={false}
|
||||
content={<ChartTooltipContent hideLabel nameKey="browser" />}
|
||||
/>
|
||||
<RadialBar dataKey="visitors" background>
|
||||
<LabelList
|
||||
position="insideStart"
|
||||
dataKey="browser"
|
||||
className="fill-white capitalize mix-blend-luminosity"
|
||||
fontSize={11}
|
||||
/>
|
||||
</RadialBar>
|
||||
</RadialBarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Label, PolarGrid, PolarRadiusAxis, RadialBar, RadialBarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer } from 'ui'
|
||||
|
||||
export const description = 'A radial chart with a custom shape'
|
||||
|
||||
const chartData = [{ browser: 'safari', visitors: 1260, fill: 'var(--color-safari)' }]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Radial Chart - Shape</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadialBarChart data={chartData} endAngle={100} innerRadius={80} outerRadius={140}>
|
||||
<PolarGrid
|
||||
gridType="circle"
|
||||
radialLines={false}
|
||||
stroke="none"
|
||||
className="first:fill-muted last:fill-background"
|
||||
polarRadius={[86, 74]}
|
||||
/>
|
||||
<RadialBar dataKey="visitors" background />
|
||||
<PolarRadiusAxis tick={false} tickLine={false} axisLine={false}>
|
||||
<Label
|
||||
content={({ viewBox }) => {
|
||||
if (viewBox && 'cx' in viewBox && 'cy' in viewBox) {
|
||||
return (
|
||||
<text
|
||||
x={viewBox.cx}
|
||||
y={viewBox.cy}
|
||||
textAnchor="middle"
|
||||
dominantBaseline="middle"
|
||||
>
|
||||
<tspan
|
||||
x={viewBox.cx}
|
||||
y={viewBox.cy}
|
||||
className="fill-foreground text-4xl font-bold"
|
||||
>
|
||||
{chartData[0].visitors.toLocaleString()}
|
||||
</tspan>
|
||||
<tspan
|
||||
x={viewBox.cx}
|
||||
y={(viewBox.cy || 0) + 24}
|
||||
className="fill-muted-foreground"
|
||||
>
|
||||
Visitors
|
||||
</tspan>
|
||||
</text>
|
||||
)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</PolarRadiusAxis>
|
||||
</RadialBarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { RadialBar, RadialBarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radial chart'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Radial Chart</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadialBarChart data={chartData} innerRadius={30} outerRadius={110}>
|
||||
<ChartTooltip
|
||||
cursor={false}
|
||||
content={<ChartTooltipContent hideLabel nameKey="browser" />}
|
||||
/>
|
||||
<RadialBar dataKey="visitors" background />
|
||||
</RadialBarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Label, PolarRadiusAxis, RadialBar, RadialBarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A radial chart with stacked sections'
|
||||
|
||||
const chartData = [{ month: 'january', desktop: 1260, mobile: 570 }]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
const totalVisitors = chartData[0].desktop + chartData[0].mobile
|
||||
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Radial Chart - Stacked</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex flex-1 items-center pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square w-full max-w-[250px]">
|
||||
<RadialBarChart data={chartData} endAngle={180} innerRadius={80} outerRadius={130}>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<PolarRadiusAxis tick={false} tickLine={false} axisLine={false}>
|
||||
<Label
|
||||
content={({ viewBox }) => {
|
||||
if (viewBox && 'cx' in viewBox && 'cy' in viewBox) {
|
||||
return (
|
||||
<text x={viewBox.cx} y={viewBox.cy} textAnchor="middle">
|
||||
<tspan
|
||||
x={viewBox.cx}
|
||||
y={(viewBox.cy || 0) - 16}
|
||||
className="fill-foreground text-2xl font-bold"
|
||||
>
|
||||
{totalVisitors.toLocaleString()}
|
||||
</tspan>
|
||||
<tspan
|
||||
x={viewBox.cx}
|
||||
y={(viewBox.cy || 0) + 4}
|
||||
className="fill-muted-foreground"
|
||||
>
|
||||
Visitors
|
||||
</tspan>
|
||||
</text>
|
||||
)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</PolarRadiusAxis>
|
||||
<RadialBar
|
||||
dataKey="desktop"
|
||||
stackId="a"
|
||||
cornerRadius={5}
|
||||
fill="var(--color-desktop)"
|
||||
className="stroke-transparent stroke-2"
|
||||
/>
|
||||
<RadialBar
|
||||
dataKey="mobile"
|
||||
fill="var(--color-mobile)"
|
||||
stackId="a"
|
||||
cornerRadius={5}
|
||||
className="stroke-transparent stroke-2"
|
||||
/>
|
||||
</RadialBarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Label, PolarGrid, PolarRadiusAxis, RadialBar, RadialBarChart } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer } from 'ui'
|
||||
|
||||
export const description = 'A radial chart with text'
|
||||
|
||||
const chartData = [{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardHeader className="items-center pb-0">
|
||||
<CardTitle>Radial Chart - Text</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex-1 pb-0">
|
||||
<ChartContainer config={chartConfig} className="mx-auto aspect-square max-h-[250px]">
|
||||
<RadialBarChart
|
||||
data={chartData}
|
||||
startAngle={0}
|
||||
endAngle={250}
|
||||
innerRadius={80}
|
||||
outerRadius={110}
|
||||
>
|
||||
<PolarGrid
|
||||
gridType="circle"
|
||||
radialLines={false}
|
||||
stroke="none"
|
||||
className="first:fill-muted last:fill-background"
|
||||
polarRadius={[86, 74]}
|
||||
/>
|
||||
<RadialBar dataKey="visitors" background cornerRadius={10} />
|
||||
<PolarRadiusAxis tick={false} tickLine={false} axisLine={false}>
|
||||
<Label
|
||||
content={({ viewBox }) => {
|
||||
if (viewBox && 'cx' in viewBox && 'cy' in viewBox) {
|
||||
return (
|
||||
<text
|
||||
x={viewBox.cx}
|
||||
y={viewBox.cy}
|
||||
textAnchor="middle"
|
||||
dominantBaseline="middle"
|
||||
>
|
||||
<tspan
|
||||
x={viewBox.cx}
|
||||
y={viewBox.cy}
|
||||
className="fill-foreground text-4xl font-bold"
|
||||
>
|
||||
{chartData[0].visitors.toLocaleString()}
|
||||
</tspan>
|
||||
<tspan
|
||||
x={viewBox.cx}
|
||||
y={(viewBox.cy || 0) + 24}
|
||||
className="fill-muted-foreground"
|
||||
>
|
||||
Visitors
|
||||
</tspan>
|
||||
</text>
|
||||
)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</PolarRadiusAxis>
|
||||
</RadialBarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col gap-2 text-sm">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -2821,149 +2821,6 @@ export const Index: Record<string, any> = {
|
||||
subcategory: "undefined",
|
||||
chunks: []
|
||||
},
|
||||
"chart-area-axes": {
|
||||
name: "chart-area-axes",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-area-axes")),
|
||||
source: "__registry__/default/block/chart-area-axes.tsx",
|
||||
files: ["registry/default/block/chart-area-axes.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Area",
|
||||
chunks: []
|
||||
},
|
||||
"chart-area-default": {
|
||||
name: "chart-area-default",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-area-default")),
|
||||
source: "__registry__/default/block/chart-area-default.tsx",
|
||||
files: ["registry/default/block/chart-area-default.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Area",
|
||||
chunks: []
|
||||
},
|
||||
"chart-area-gradient": {
|
||||
name: "chart-area-gradient",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-area-gradient")),
|
||||
source: "__registry__/default/block/chart-area-gradient.tsx",
|
||||
files: ["registry/default/block/chart-area-gradient.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Area",
|
||||
chunks: []
|
||||
},
|
||||
"chart-area-icons": {
|
||||
name: "chart-area-icons",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-area-icons")),
|
||||
source: "__registry__/default/block/chart-area-icons.tsx",
|
||||
files: ["registry/default/block/chart-area-icons.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Area",
|
||||
chunks: []
|
||||
},
|
||||
"chart-area-interactive": {
|
||||
name: "chart-area-interactive",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-area-interactive")),
|
||||
source: "__registry__/default/block/chart-area-interactive.tsx",
|
||||
files: ["registry/default/block/chart-area-interactive.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Area",
|
||||
chunks: []
|
||||
},
|
||||
"chart-area-legend": {
|
||||
name: "chart-area-legend",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-area-legend")),
|
||||
source: "__registry__/default/block/chart-area-legend.tsx",
|
||||
files: ["registry/default/block/chart-area-legend.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Area",
|
||||
chunks: []
|
||||
},
|
||||
"chart-area-linear": {
|
||||
name: "chart-area-linear",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-area-linear")),
|
||||
source: "__registry__/default/block/chart-area-linear.tsx",
|
||||
files: ["registry/default/block/chart-area-linear.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Area",
|
||||
chunks: []
|
||||
},
|
||||
"chart-area-stacked-expand": {
|
||||
name: "chart-area-stacked-expand",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-area-stacked-expand")),
|
||||
source: "__registry__/default/block/chart-area-stacked-expand.tsx",
|
||||
files: ["registry/default/block/chart-area-stacked-expand.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Area",
|
||||
chunks: []
|
||||
},
|
||||
"chart-area-stacked": {
|
||||
name: "chart-area-stacked",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-area-stacked")),
|
||||
source: "__registry__/default/block/chart-area-stacked.tsx",
|
||||
files: ["registry/default/block/chart-area-stacked.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Area",
|
||||
chunks: []
|
||||
},
|
||||
"chart-area-step": {
|
||||
name: "chart-area-step",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-area-step")),
|
||||
source: "__registry__/default/block/chart-area-step.tsx",
|
||||
files: ["registry/default/block/chart-area-step.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Area",
|
||||
chunks: []
|
||||
},
|
||||
"chart-bar-active": {
|
||||
name: "chart-bar-active",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-bar-active")),
|
||||
source: "__registry__/default/block/chart-bar-active.tsx",
|
||||
files: ["registry/default/block/chart-bar-active.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Bar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-bar-default": {
|
||||
name: "chart-bar-default",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-bar-default")),
|
||||
source: "__registry__/default/block/chart-bar-default.tsx",
|
||||
files: ["registry/default/block/chart-bar-default.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Bar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-bar-horizontal": {
|
||||
name: "chart-bar-horizontal",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-bar-horizontal")),
|
||||
source: "__registry__/default/block/chart-bar-horizontal.tsx",
|
||||
files: ["registry/default/block/chart-bar-horizontal.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Bar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-bar-interactive": {
|
||||
name: "chart-bar-interactive",
|
||||
type: "components:block",
|
||||
@@ -2975,521 +2832,70 @@ export const Index: Record<string, any> = {
|
||||
subcategory: "Bar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-bar-label-custom": {
|
||||
name: "chart-bar-label-custom",
|
||||
"chart-composed-demo": {
|
||||
name: "chart-composed-demo",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-bar-label-custom")),
|
||||
source: "__registry__/default/block/chart-bar-label-custom.tsx",
|
||||
files: ["registry/default/block/chart-bar-label-custom.tsx"],
|
||||
registryDependencies: ["chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-composed-demo")),
|
||||
source: "__registry__/default/block/chart-composed-demo.tsx",
|
||||
files: ["registry/default/block/chart-composed-demo.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Bar",
|
||||
subcategory: "Composed",
|
||||
chunks: []
|
||||
},
|
||||
"chart-bar-label": {
|
||||
name: "chart-bar-label",
|
||||
"chart-composed-basic": {
|
||||
name: "chart-composed-basic",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-bar-label")),
|
||||
source: "__registry__/default/block/chart-bar-label.tsx",
|
||||
files: ["registry/default/block/chart-bar-label.tsx"],
|
||||
registryDependencies: ["chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-composed-basic")),
|
||||
source: "__registry__/default/block/chart-composed-basic.tsx",
|
||||
files: ["registry/default/block/chart-composed-basic.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Bar",
|
||||
subcategory: "Composed",
|
||||
chunks: []
|
||||
},
|
||||
"chart-bar-mixed": {
|
||||
name: "chart-bar-mixed",
|
||||
"chart-composed-states": {
|
||||
name: "chart-composed-states",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-bar-mixed")),
|
||||
source: "__registry__/default/block/chart-bar-mixed.tsx",
|
||||
files: ["registry/default/block/chart-bar-mixed.tsx"],
|
||||
registryDependencies: ["chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-composed-states")),
|
||||
source: "__registry__/default/block/chart-composed-states.tsx",
|
||||
files: ["registry/default/block/chart-composed-states.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Bar",
|
||||
subcategory: "Composed",
|
||||
chunks: []
|
||||
},
|
||||
"chart-bar-multiple": {
|
||||
name: "chart-bar-multiple",
|
||||
"chart-composed-table": {
|
||||
name: "chart-composed-table",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-bar-multiple")),
|
||||
source: "__registry__/default/block/chart-bar-multiple.tsx",
|
||||
files: ["registry/default/block/chart-bar-multiple.tsx"],
|
||||
registryDependencies: ["chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-composed-table")),
|
||||
source: "__registry__/default/block/chart-composed-table.tsx",
|
||||
files: ["registry/default/block/chart-composed-table.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Bar",
|
||||
subcategory: "Composed",
|
||||
chunks: []
|
||||
},
|
||||
"chart-bar-negative": {
|
||||
name: "chart-bar-negative",
|
||||
"chart-composed-metrics": {
|
||||
name: "chart-composed-metrics",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-bar-negative")),
|
||||
source: "__registry__/default/block/chart-bar-negative.tsx",
|
||||
files: ["registry/default/block/chart-bar-negative.tsx"],
|
||||
registryDependencies: ["chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-composed-metrics")),
|
||||
source: "__registry__/default/block/chart-composed-metrics.tsx",
|
||||
files: ["registry/default/block/chart-composed-metrics.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Bar",
|
||||
subcategory: "Composed",
|
||||
chunks: []
|
||||
},
|
||||
"chart-bar-stacked": {
|
||||
name: "chart-bar-stacked",
|
||||
"chart-composed-actions": {
|
||||
name: "chart-composed-actions",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-bar-stacked")),
|
||||
source: "__registry__/default/block/chart-bar-stacked.tsx",
|
||||
files: ["registry/default/block/chart-bar-stacked.tsx"],
|
||||
registryDependencies: ["chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-composed-actions")),
|
||||
source: "__registry__/default/block/chart-composed-actions.tsx",
|
||||
files: ["registry/default/block/chart-composed-actions.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Bar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-line-default": {
|
||||
name: "chart-line-default",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-line-default")),
|
||||
source: "__registry__/default/block/chart-line-default.tsx",
|
||||
files: ["registry/default/block/chart-line-default.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Line",
|
||||
chunks: []
|
||||
},
|
||||
"chart-line-dots-colors": {
|
||||
name: "chart-line-dots-colors",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-line-dots-colors")),
|
||||
source: "__registry__/default/block/chart-line-dots-colors.tsx",
|
||||
files: ["registry/default/block/chart-line-dots-colors.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Line",
|
||||
chunks: []
|
||||
},
|
||||
"chart-line-dots-custom": {
|
||||
name: "chart-line-dots-custom",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-line-dots-custom")),
|
||||
source: "__registry__/default/block/chart-line-dots-custom.tsx",
|
||||
files: ["registry/default/block/chart-line-dots-custom.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Line",
|
||||
chunks: []
|
||||
},
|
||||
"chart-line-dots": {
|
||||
name: "chart-line-dots",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-line-dots")),
|
||||
source: "__registry__/default/block/chart-line-dots.tsx",
|
||||
files: ["registry/default/block/chart-line-dots.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Line",
|
||||
chunks: []
|
||||
},
|
||||
"chart-line-interactive": {
|
||||
name: "chart-line-interactive",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-line-interactive")),
|
||||
source: "__registry__/default/block/chart-line-interactive.tsx",
|
||||
files: ["registry/default/block/chart-line-interactive.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Line",
|
||||
chunks: []
|
||||
},
|
||||
"chart-line-label-custom": {
|
||||
name: "chart-line-label-custom",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-line-label-custom")),
|
||||
source: "__registry__/default/block/chart-line-label-custom.tsx",
|
||||
files: ["registry/default/block/chart-line-label-custom.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Line",
|
||||
chunks: []
|
||||
},
|
||||
"chart-line-label": {
|
||||
name: "chart-line-label",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-line-label")),
|
||||
source: "__registry__/default/block/chart-line-label.tsx",
|
||||
files: ["registry/default/block/chart-line-label.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Line",
|
||||
chunks: []
|
||||
},
|
||||
"chart-line-linear": {
|
||||
name: "chart-line-linear",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-line-linear")),
|
||||
source: "__registry__/default/block/chart-line-linear.tsx",
|
||||
files: ["registry/default/block/chart-line-linear.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Line",
|
||||
chunks: []
|
||||
},
|
||||
"chart-line-multiple": {
|
||||
name: "chart-line-multiple",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-line-multiple")),
|
||||
source: "__registry__/default/block/chart-line-multiple.tsx",
|
||||
files: ["registry/default/block/chart-line-multiple.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Line",
|
||||
chunks: []
|
||||
},
|
||||
"chart-line-step": {
|
||||
name: "chart-line-step",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-line-step")),
|
||||
source: "__registry__/default/block/chart-line-step.tsx",
|
||||
files: ["registry/default/block/chart-line-step.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Line",
|
||||
chunks: []
|
||||
},
|
||||
"chart-pie-donut-active": {
|
||||
name: "chart-pie-donut-active",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-pie-donut-active")),
|
||||
source: "__registry__/default/block/chart-pie-donut-active.tsx",
|
||||
files: ["registry/default/block/chart-pie-donut-active.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Pie",
|
||||
chunks: []
|
||||
},
|
||||
"chart-pie-donut-text": {
|
||||
name: "chart-pie-donut-text",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-pie-donut-text")),
|
||||
source: "__registry__/default/block/chart-pie-donut-text.tsx",
|
||||
files: ["registry/default/block/chart-pie-donut-text.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Pie",
|
||||
chunks: []
|
||||
},
|
||||
"chart-pie-donut": {
|
||||
name: "chart-pie-donut",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-pie-donut")),
|
||||
source: "__registry__/default/block/chart-pie-donut.tsx",
|
||||
files: ["registry/default/block/chart-pie-donut.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Pie",
|
||||
chunks: []
|
||||
},
|
||||
"chart-pie-interactive": {
|
||||
name: "chart-pie-interactive",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-pie-interactive")),
|
||||
source: "__registry__/default/block/chart-pie-interactive.tsx",
|
||||
files: ["registry/default/block/chart-pie-interactive.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Pie",
|
||||
chunks: []
|
||||
},
|
||||
"chart-pie-label-custom": {
|
||||
name: "chart-pie-label-custom",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-pie-label-custom")),
|
||||
source: "__registry__/default/block/chart-pie-label-custom.tsx",
|
||||
files: ["registry/default/block/chart-pie-label-custom.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Pie",
|
||||
chunks: []
|
||||
},
|
||||
"chart-pie-label-list": {
|
||||
name: "chart-pie-label-list",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-pie-label-list")),
|
||||
source: "__registry__/default/block/chart-pie-label-list.tsx",
|
||||
files: ["registry/default/block/chart-pie-label-list.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Pie",
|
||||
chunks: []
|
||||
},
|
||||
"chart-pie-label": {
|
||||
name: "chart-pie-label",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-pie-label")),
|
||||
source: "__registry__/default/block/chart-pie-label.tsx",
|
||||
files: ["registry/default/block/chart-pie-label.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Pie",
|
||||
chunks: []
|
||||
},
|
||||
"chart-pie-legend": {
|
||||
name: "chart-pie-legend",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-pie-legend")),
|
||||
source: "__registry__/default/block/chart-pie-legend.tsx",
|
||||
files: ["registry/default/block/chart-pie-legend.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Pie",
|
||||
chunks: []
|
||||
},
|
||||
"chart-pie-separator-none": {
|
||||
name: "chart-pie-separator-none",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-pie-separator-none")),
|
||||
source: "__registry__/default/block/chart-pie-separator-none.tsx",
|
||||
files: ["registry/default/block/chart-pie-separator-none.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Pie",
|
||||
chunks: []
|
||||
},
|
||||
"chart-pie-simple": {
|
||||
name: "chart-pie-simple",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-pie-simple")),
|
||||
source: "__registry__/default/block/chart-pie-simple.tsx",
|
||||
files: ["registry/default/block/chart-pie-simple.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Pie",
|
||||
chunks: []
|
||||
},
|
||||
"chart-pie-stacked": {
|
||||
name: "chart-pie-stacked",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-pie-stacked")),
|
||||
source: "__registry__/default/block/chart-pie-stacked.tsx",
|
||||
files: ["registry/default/block/chart-pie-stacked.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Pie",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radar-default": {
|
||||
name: "chart-radar-default",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radar-default")),
|
||||
source: "__registry__/default/block/chart-radar-default.tsx",
|
||||
files: ["registry/default/block/chart-radar-default.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radar-dots": {
|
||||
name: "chart-radar-dots",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radar-dots")),
|
||||
source: "__registry__/default/block/chart-radar-dots.tsx",
|
||||
files: ["registry/default/block/chart-radar-dots.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radar-grid-circle-fill": {
|
||||
name: "chart-radar-grid-circle-fill",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radar-grid-circle-fill")),
|
||||
source: "__registry__/default/block/chart-radar-grid-circle-fill.tsx",
|
||||
files: ["registry/default/block/chart-radar-grid-circle-fill.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radar-grid-circle-no-lines": {
|
||||
name: "chart-radar-grid-circle-no-lines",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radar-grid-circle-no-lines")),
|
||||
source: "__registry__/default/block/chart-radar-grid-circle-no-lines.tsx",
|
||||
files: ["registry/default/block/chart-radar-grid-circle-no-lines.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radar-grid-circle": {
|
||||
name: "chart-radar-grid-circle",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radar-grid-circle")),
|
||||
source: "__registry__/default/block/chart-radar-grid-circle.tsx",
|
||||
files: ["registry/default/block/chart-radar-grid-circle.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radar-grid-custom": {
|
||||
name: "chart-radar-grid-custom",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radar-grid-custom")),
|
||||
source: "__registry__/default/block/chart-radar-grid-custom.tsx",
|
||||
files: ["registry/default/block/chart-radar-grid-custom.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radar-grid-fill": {
|
||||
name: "chart-radar-grid-fill",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radar-grid-fill")),
|
||||
source: "__registry__/default/block/chart-radar-grid-fill.tsx",
|
||||
files: ["registry/default/block/chart-radar-grid-fill.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radar-grid-none": {
|
||||
name: "chart-radar-grid-none",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radar-grid-none")),
|
||||
source: "__registry__/default/block/chart-radar-grid-none.tsx",
|
||||
files: ["registry/default/block/chart-radar-grid-none.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radar-icons": {
|
||||
name: "chart-radar-icons",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radar-icons")),
|
||||
source: "__registry__/default/block/chart-radar-icons.tsx",
|
||||
files: ["registry/default/block/chart-radar-icons.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radar-label-custom": {
|
||||
name: "chart-radar-label-custom",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radar-label-custom")),
|
||||
source: "__registry__/default/block/chart-radar-label-custom.tsx",
|
||||
files: ["registry/default/block/chart-radar-label-custom.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radar-legend": {
|
||||
name: "chart-radar-legend",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radar-legend")),
|
||||
source: "__registry__/default/block/chart-radar-legend.tsx",
|
||||
files: ["registry/default/block/chart-radar-legend.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radar-lines-only": {
|
||||
name: "chart-radar-lines-only",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radar-lines-only")),
|
||||
source: "__registry__/default/block/chart-radar-lines-only.tsx",
|
||||
files: ["registry/default/block/chart-radar-lines-only.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radar-multiple": {
|
||||
name: "chart-radar-multiple",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radar-multiple")),
|
||||
source: "__registry__/default/block/chart-radar-multiple.tsx",
|
||||
files: ["registry/default/block/chart-radar-multiple.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radar-radius": {
|
||||
name: "chart-radar-radius",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radar-radius")),
|
||||
source: "__registry__/default/block/chart-radar-radius.tsx",
|
||||
files: ["registry/default/block/chart-radar-radius.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radar",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radial-grid": {
|
||||
name: "chart-radial-grid",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radial-grid")),
|
||||
source: "__registry__/default/block/chart-radial-grid.tsx",
|
||||
files: ["registry/default/block/chart-radial-grid.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radial",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radial-label": {
|
||||
name: "chart-radial-label",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radial-label")),
|
||||
source: "__registry__/default/block/chart-radial-label.tsx",
|
||||
files: ["registry/default/block/chart-radial-label.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radial",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radial-shape": {
|
||||
name: "chart-radial-shape",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radial-shape")),
|
||||
source: "__registry__/default/block/chart-radial-shape.tsx",
|
||||
files: ["registry/default/block/chart-radial-shape.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radial",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radial-simple": {
|
||||
name: "chart-radial-simple",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radial-simple")),
|
||||
source: "__registry__/default/block/chart-radial-simple.tsx",
|
||||
files: ["registry/default/block/chart-radial-simple.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radial",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radial-stacked": {
|
||||
name: "chart-radial-stacked",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radial-stacked")),
|
||||
source: "__registry__/default/block/chart-radial-stacked.tsx",
|
||||
files: ["registry/default/block/chart-radial-stacked.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radial",
|
||||
chunks: []
|
||||
},
|
||||
"chart-radial-text": {
|
||||
name: "chart-radial-text",
|
||||
type: "components:block",
|
||||
registryDependencies: ["card","chart"],
|
||||
component: React.lazy(() => import("@/registry/default/block/chart-radial-text")),
|
||||
source: "__registry__/default/block/chart-radial-text.tsx",
|
||||
files: ["registry/default/block/chart-radial-text.tsx"],
|
||||
category: "Charts",
|
||||
subcategory: "Radial",
|
||||
subcategory: "Composed",
|
||||
chunks: []
|
||||
},
|
||||
},
|
||||
|
||||
@@ -240,12 +240,70 @@ const SourcePanel = forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement> &
|
||||
}
|
||||
}
|
||||
|
||||
const RechartsPanel = () => {
|
||||
if (doc.source?.recharts) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'bg-surface-75/50 border flex items-center p-3 px-5 gap-6 first:rounded-t-md last:rounded-b-md',
|
||||
props.className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<svg
|
||||
width="146"
|
||||
height="24"
|
||||
viewBox="0 0 146 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M124.123 1.21484L109.695 23.9951L108.737 23.3887L107.779 22.7812L122.207 0L124.123 1.21484ZM15.4844 5.4082L2.96387 11.998L15.4844 18.5879L14.4277 20.5957L0 13.002L0.52832 11.998L0 10.9941L14.4277 3.40039L15.4844 5.4082ZM145.335 10.9941L144.807 11.998L145.335 13.002L130.907 20.5957L129.851 18.5879L142.37 11.998L129.851 5.4082L130.907 3.40039L145.335 10.9941ZM68.5801 8.39746C68.8994 8.39746 69.2665 8.43699 69.6807 8.51465C70.0991 8.58798 70.5024 8.74074 70.8906 8.97363C71.2832 9.20658 71.6093 9.55816 71.8682 10.0283C72.127 10.4985 72.2568 11.1286 72.2568 11.918V18.4678H70.7285V17.1221H70.6514C70.6409 17.1439 70.6271 17.1644 70.6152 17.1865C70.598 17.2186 70.5818 17.2524 70.5615 17.2852L70.4443 17.457C70.3581 17.5724 70.2545 17.6916 70.1338 17.8145C70.1245 17.8239 70.1141 17.8324 70.1045 17.8418C70.0734 17.8722 70.0414 17.9023 70.0078 17.9316C69.7839 18.1272 69.5044 18.2981 69.1689 18.4424C68.7678 18.6148 68.2781 18.7012 67.7002 18.7012C67.0703 18.7012 66.4988 18.582 65.9854 18.3447C65.6861 18.2039 65.4237 18.0261 65.1963 17.8135C65.0335 17.6615 64.8876 17.4915 64.7617 17.3027C64.5935 17.0479 64.4739 16.763 64.3994 16.4492C64.3724 16.3357 64.3497 16.2188 64.335 16.0977C64.3344 16.0928 64.3346 16.0879 64.334 16.083C64.3175 15.9423 64.3086 15.7965 64.3086 15.6455C64.3087 15.0766 64.4215 14.6153 64.6455 14.2617C64.7017 14.172 64.7624 14.0869 64.8281 14.0068C64.8444 13.987 64.862 13.9684 64.8789 13.9492C65.0657 13.7362 65.287 13.5583 65.5449 13.4189C65.736 13.3157 65.938 13.2267 66.1494 13.1504C66.3529 13.0768 66.5659 13.0155 66.7881 12.9668C66.9022 12.941 67.0165 12.9167 67.1309 12.8936C67.2457 12.8703 67.3605 12.8477 67.4756 12.8271C67.5904 12.8067 67.7053 12.7873 67.8203 12.7695C67.9354 12.7517 68.0507 12.7358 68.166 12.7207C68.77 12.6431 69.2604 12.5847 69.6357 12.5459C70.0151 12.5027 70.2914 12.4312 70.4639 12.332C70.53 12.2949 70.5836 12.2471 70.625 12.1895C70.6389 12.1701 70.651 12.1496 70.6621 12.1279C70.7063 12.0417 70.7285 11.9374 70.7285 11.8145V11.7627C70.7285 11.4437 70.6849 11.1601 70.5977 10.9121C70.554 10.7881 70.5001 10.6726 70.4346 10.5664C70.3692 10.4603 70.2923 10.3628 70.2051 10.2744C70.0325 10.0977 69.8149 9.9654 69.5527 9.87695C69.4871 9.85481 69.4189 9.83496 69.3477 9.81836C69.1342 9.76858 68.8955 9.74415 68.6318 9.74414C67.9029 9.7442 67.3311 9.90344 66.917 10.2227C66.7617 10.3424 66.6236 10.4651 66.5029 10.5908C66.3458 10.7544 66.2187 10.9237 66.1201 11.0977C66.1177 11.102 66.1147 11.106 66.1123 11.1104L66.0439 11.2451L64.5928 10.7275C64.6561 10.5797 64.7251 10.4395 64.7988 10.3076C64.8087 10.29 64.82 10.2732 64.8301 10.2559C64.8959 10.1423 64.9653 10.0349 65.0391 9.93359C65.0466 9.9232 65.0539 9.91261 65.0615 9.90234C65.0956 9.85658 65.1312 9.81272 65.167 9.76953C65.1741 9.76094 65.1803 9.75165 65.1875 9.74316C65.2256 9.69808 65.2647 9.65451 65.3047 9.6123C65.312 9.6046 65.3188 9.59647 65.3262 9.58887C65.3732 9.54019 65.4221 9.49397 65.4717 9.44922L65.5156 9.41211C65.5531 9.37961 65.59 9.34673 65.6289 9.31641C66.0646 8.97561 66.5394 8.73826 67.0527 8.60449C67.5703 8.46646 68.0797 8.3975 68.5801 8.39746ZM37.4268 8.40137C37.491 8.40408 37.5551 8.40769 37.6191 8.41309C38.0052 8.44542 38.3878 8.52676 38.7666 8.65625C38.8269 8.67688 38.8863 8.69992 38.9453 8.72363C39.0099 8.74954 39.0737 8.77707 39.1367 8.80664C39.4982 8.97651 39.835 9.20692 40.1455 9.49805C40.5595 9.88199 40.8889 10.3914 41.1348 11.0254C41.3807 11.6596 41.5039 12.4405 41.5039 13.3682V14.0156H34.2861C34.2975 14.3591 34.3374 14.677 34.4062 14.9697C34.4355 15.0944 34.4691 15.2146 34.5088 15.3301C34.5156 15.3499 34.5241 15.3691 34.5312 15.3887C34.5726 15.5024 34.6181 15.6123 34.6699 15.7168C34.7686 15.9108 34.8817 16.0874 35.0088 16.2471C35.2209 16.5132 35.4723 16.7314 35.7637 16.9014C35.7835 16.9128 35.8041 16.9227 35.8242 16.9336C35.9066 16.9783 35.9911 17.0191 36.0781 17.0557C36.4686 17.2196 36.9047 17.3027 37.3877 17.3027C37.7888 17.3027 38.1511 17.2468 38.4746 17.1348C38.7205 17.0474 38.9408 16.9278 39.1357 16.7773C39.2006 16.7273 39.263 16.6742 39.3223 16.6172C39.5596 16.3842 39.7426 16.0942 39.8721 15.749L41.3486 16.1641C41.2641 16.4361 41.147 16.6903 41 16.9268C40.8797 17.1202 40.7393 17.3022 40.5771 17.4717C40.5732 17.4758 40.5694 17.4802 40.5654 17.4844C40.4739 17.578 40.3767 17.6666 40.2744 17.75C40.1718 17.8337 40.0636 17.9119 39.9502 17.9854C39.7239 18.1318 39.4764 18.2586 39.207 18.3643C39.1943 18.3692 39.1808 18.3731 39.168 18.3779C39.0606 18.418 38.9505 18.4534 38.8379 18.4854C38.7505 18.5102 38.6618 18.5338 38.5713 18.5537C38.2032 18.6345 37.809 18.6757 37.3887 18.6758C36.9098 18.6758 36.4631 18.6224 36.0498 18.5166C35.6367 18.4109 35.2556 18.2524 34.9082 18.041C34.2182 17.6139 33.6858 17.0182 33.3105 16.2549C33.0626 15.7416 32.8996 15.1719 32.8174 14.5469C32.7764 14.2366 32.7539 13.9129 32.7539 13.5752C32.7539 13.0662 32.8006 12.5872 32.8936 12.1387C32.9168 12.0264 32.9427 11.9161 32.9717 11.8076C33.005 11.6833 33.043 11.5618 33.084 11.4424C33.15 11.2496 33.2246 11.0627 33.3105 10.8828C33.53Line truncated
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<div className="flex flex-row items-center justify-between text-sm w-full">
|
||||
<span className="text-foreground-light text-xs">This component uses Recharts</span>
|
||||
{doc.links ? (
|
||||
<div className="flex items-center gap-2 justify-end">
|
||||
{doc.links?.doc && (
|
||||
<Button
|
||||
type="outline"
|
||||
className="rounded-full"
|
||||
icon={<ExternalLink className="text-foreground-muted" strokeWidth={1} />}
|
||||
>
|
||||
<Link href={doc.links.doc} target="_blank" rel="noreferrer">
|
||||
Docs
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
{doc.links?.api && (
|
||||
<Button
|
||||
type="outline"
|
||||
className="rounded-full"
|
||||
icon={<ExternalLink className="text-foreground-muted" strokeWidth={1} />}
|
||||
>
|
||||
<Link href={doc.links.api} target="_blank" rel="noreferrer">
|
||||
API Reference
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col -space-y-px">
|
||||
<RadixPanel />
|
||||
<VaulPanel />
|
||||
<InputOtp />
|
||||
<ReactAccesibleTreeViewPanel />
|
||||
<RechartsPanel />
|
||||
{/* <ShadcnPanel /> */}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -59,13 +59,8 @@ export const docsConfig: DocsConfig = {
|
||||
priority: true,
|
||||
},
|
||||
{
|
||||
title: 'Navigation',
|
||||
href: '/docs/ui-patterns/navigation',
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: 'Layout',
|
||||
href: '/docs/ui-patterns/layout',
|
||||
title: 'Charts',
|
||||
href: '/docs/ui-patterns/charts',
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
@@ -78,6 +73,16 @@ export const docsConfig: DocsConfig = {
|
||||
href: '/docs/ui-patterns/forms',
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: 'Layout',
|
||||
href: '/docs/ui-patterns/layout',
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: 'Navigation',
|
||||
href: '/docs/ui-patterns/navigation',
|
||||
items: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -243,11 +248,6 @@ export const docsConfig: DocsConfig = {
|
||||
href: '/docs/components/carousel',
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: 'Chart',
|
||||
href: '/docs/components/chart',
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: 'Checkbox',
|
||||
href: '/docs/components/checkbox',
|
||||
|
||||
@@ -0,0 +1,281 @@
|
||||
---
|
||||
title: Charts
|
||||
description: Composable charts for Reports, Dashboards and other visualizations.
|
||||
links:
|
||||
doc: https://recharts.github.io/en-US/
|
||||
source:
|
||||
recharts: true
|
||||
---
|
||||
|
||||
<ComponentPreview name="chart-composed-demo" peekCode wide />
|
||||
|
||||
## About
|
||||
|
||||
Charts are an integral part of Observability at Supabase. Charts aim to be composable and reusable for frictionless setup.
|
||||
|
||||
Our charts use a combination of our own presentational components and [Recharts](https://recharts.github.io/en-US/) for extensibility.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use provided chart types first**: Always try to use the default provided charts first, otherwise passing Recharts compoennts to `<ChartContent>` is possible but not recommended to avoid complexity.
|
||||
|
||||
2. **Use the `useChart` context to show loading and disabled states**: The `useChart` context provides boolean flags for child components to show `isLoading` and `isDisabled` states.
|
||||
|
||||
3. **Keep it simple**: Try to avoid abstracting the chart content too much. These components should cover most of your presentational needs.
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Chart Types
|
||||
|
||||
<ComponentPreview name="chart-composed-basic" wide />
|
||||
|
||||
### Chart States
|
||||
|
||||
<ComponentPreview name="chart-composed-states" wide />
|
||||
|
||||
### Charts as Standalone Metrics
|
||||
|
||||
<ComponentPreview name="chart-composed-metrics" wide />
|
||||
|
||||
### Charts with Actions
|
||||
|
||||
<ComponentPreview name="chart-composed-actions" wide />
|
||||
|
||||
### Chart with Table
|
||||
|
||||
<ComponentPreview name="chart-composed-table" wide />
|
||||
|
||||
You can pass through our [Table](/docs/components/table) component to the `ChartFooter` and expect it to be styled correctly. There is no additional need to style the table, `ChartFooter` will handle the styling for you.
|
||||
|
||||
## API
|
||||
|
||||
### Chart
|
||||
|
||||
The root container component that provides chart context to all child components.
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| ------------ | -------------------------------------- | ------- | ------------------------------------------------------------------ |
|
||||
| `children` | `React.ReactNode` | - | Chart child components |
|
||||
| `isLoading` | `boolean` | `false` | Shows loading state in child components via the `useChart` context |
|
||||
| `isDisabled` | `boolean` | `false` | Disables chart interactions via the `useChart` context |
|
||||
| `className` | `string` | - | Additional CSS classes |
|
||||
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
||||
|
||||
### ChartCard
|
||||
|
||||
A card wrapper for the chart. Can be used as a Card component or as a slot.
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| ----------- | -------------------------------------- | ------- | ----------------------------------------------------------------------------- |
|
||||
| `children` | `React.ReactNode` | - | Chart content |
|
||||
| `asChild` | `boolean` | - | Render as child component (uses Slot) - ideal for removing the `Card` wrapper |
|
||||
| `className` | `string` | - | Additional CSS classes |
|
||||
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
||||
|
||||
### ChartHeader
|
||||
|
||||
Container for chart header content like title and actions.
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| ----------- | -------------------------------------- | ---------- | ------------------------------------------------------------------- |
|
||||
| `children` | `React.ReactNode` | - | Header content (typically ChartTitle, ChartActions, or ChartMetric) |
|
||||
| `align` | `'start' \| 'center'` | `'center'` | Alignment of header content |
|
||||
| `className` | `string` | - | Additional CSS classes |
|
||||
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
||||
|
||||
### ChartTitle
|
||||
|
||||
Displays the chart title with optional tooltip.
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| ----------- | -------------------------------------- | ------- | ------------------------------------- |
|
||||
| `children` | `React.ReactNode` | - | Title text |
|
||||
| `tooltip` | `string` | - | Tooltip text shown on help icon hover |
|
||||
| `className` | `string` | - | Additional CSS classes |
|
||||
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
||||
|
||||
### ChartActions
|
||||
|
||||
Renders action buttons or links in the chart header.
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| ----------- | -------------------------------------- | ------- | ---------------------------------------------------------- |
|
||||
| `actions` | `ChartAction[]` | - | Array of action objects (see ChartAction type below) |
|
||||
| `children` | `React.ReactNode` | - | Custom action content (takes precedence over actions prop) |
|
||||
| `className` | `string` | - | Additional CSS classes |
|
||||
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
||||
|
||||
#### ChartAction Type
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------- | -------------------- | ----------------------------------------------- |
|
||||
| `label` | `string` | Accessible label for the action |
|
||||
| `icon` | `React.ReactNode` | Icon component to display |
|
||||
| `onClick` | `() => void` | Click handler for button actions |
|
||||
| `href` | `string` | URL for link actions |
|
||||
| `type` | `'button' \| 'link'` | Action type (auto-detected if href is provided) |
|
||||
| `className` | `string` | Additional CSS classes |
|
||||
|
||||
### ChartMetric
|
||||
|
||||
Displays a metric value with optional status indicator.
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| ----------- | ---------------------------------------------------- | --------- | --------------------------------------------------- |
|
||||
| `label` | `string` | - | Metric label text |
|
||||
| `value` | `string \| number \| null \| undefined` | - | Metric value to display |
|
||||
| `diffValue` | `string \| number \| null \| undefined` | - | Differential value to display (shown as +/- change) |
|
||||
| `status` | `'positive' \| 'negative' \| 'warning' \| 'default'` | - | Status indicator color |
|
||||
| `align` | `'start' \| 'end'` | `'start'` | Alignment of the metric |
|
||||
| `tooltip` | `string` | - | Tooltip text shown on help icon hover |
|
||||
| `className` | `string` | - | Additional CSS classes |
|
||||
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
||||
|
||||
### ChartContent
|
||||
|
||||
Container for the main chart visualization. Handles loading and empty states.
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| ----------------- | -------------------------------------- | ------- | -------------------------------------- |
|
||||
| `children` | `React.ReactNode` | - | Chart visualization content |
|
||||
| `isEmpty` | `boolean` | `false` | Whether to show empty state |
|
||||
| `emptyState` | `React.ReactNode` | - | Custom empty state component |
|
||||
| `loadingState` | `React.ReactNode` | - | Custom loading state component |
|
||||
| `disabledState` | `React.ReactNode` | - | Custom disabled state component |
|
||||
| `disabledActions` | `ChartAction[]` | - | Actions to show when chart is disabled |
|
||||
| `className` | `string` | - | Additional CSS classes |
|
||||
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
||||
|
||||
### ChartEmptyState
|
||||
|
||||
Pre-built empty state component for charts.
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| ------------- | -------------------------------------- | ------- | ------------------------ |
|
||||
| `title` | `string` | - | Empty state title |
|
||||
| `description` | `string` | - | Empty state description |
|
||||
| `icon` | `React.ReactNode` | - | Optional icon to display |
|
||||
| `className` | `string` | - | Additional CSS classes |
|
||||
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
||||
|
||||
### ChartLoadingState
|
||||
|
||||
Pre-built loading state component. Takes no props.
|
||||
|
||||
### ChartFooter
|
||||
|
||||
Container for footer content below the chart.
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| ----------- | -------------------------------------- | ------- | ---------------------- |
|
||||
| `children` | `React.ReactNode` | - | Footer content |
|
||||
| `className` | `string` | - | Additional CSS classes |
|
||||
| `...props` | `React.HTMLAttributes<HTMLDivElement>` | - | All standard div props |
|
||||
|
||||
### ChartConfig
|
||||
|
||||
Type definition for chart configuration used with Recharts components.
|
||||
|
||||
```tsx
|
||||
type ChartConfig = {
|
||||
[key: string]: {
|
||||
label?: React.ReactNode
|
||||
icon?: React.ComponentType
|
||||
} & (
|
||||
| { color?: string; theme?: never }
|
||||
| { color?: never; theme: Record<'light' | 'dark', string> }
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
| Property | Type | Description |
|
||||
| -------- | ----------------------------------- | -------------------------------------------------------- |
|
||||
| `label` | `React.ReactNode` | Label for the data series |
|
||||
| `icon` | `React.ComponentType` | Icon component for the data series |
|
||||
| `color` | `string` | Single color value (mutually exclusive with theme) |
|
||||
| `theme` | `Record<'light' \| 'dark', string>` | Theme-aware color values (mutually exclusive with color) |
|
||||
|
||||
### ChartLine
|
||||
|
||||
Line chart component for displaying time-series data.
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| ------------------- | --------------------------------------------------------------------- | ----------------------------- | ----------------------------------------------------------------- |
|
||||
| `data` | `ChartLineTick[]` | - | Array of data points with timestamp |
|
||||
| `dataKey` | `string` | - | Key in data object to plot |
|
||||
| `config` | `ChartConfig?` | - | Chart configuration for styling |
|
||||
| `onLineClick` | `(datum: ChartLineTick, tooltipData?: CategoricalChartState) => void` | - | Click handler for line points |
|
||||
| `DateTimeFormat` | `string` | `'MMM D, YYYY, hh:mma'` | Date format for tooltips and labels |
|
||||
| `isFullHeight` | `boolean` | `false` | Whether chart should take full height |
|
||||
| `className` | `string` | - | Additional CSS classes |
|
||||
| `color` | `string` | `'hsl(var(--brand-default))'` | Line color |
|
||||
| `hoverColor` | `string` | `'hsl(var(--brand-500))'` | Line color on hover |
|
||||
| `chartHighlight` | `ChartHighlight` | - | Highlight selection configuration |
|
||||
| `updateDateRange` | `(from: string, to: string) => void` | - | Callback when date range is updated via highlight |
|
||||
| `highlightActions` | `ChartHighlightAction[]` | - | Actions to show when area is highlighted |
|
||||
| `syncId` | `string` | - | ID to sync multiple charts |
|
||||
| `showHighlightArea` | `boolean` | `true` | Whether to show highlight area |
|
||||
| `cursor` | `string` | - | Cursor style (defaults to 'crosshair' if chartHighlight provided) |
|
||||
| `showGrid` | `boolean` | `false` | Whether to show grid lines |
|
||||
| `showYAxis` | `boolean` | `false` | Whether to show Y-axis |
|
||||
| `YAxisProps` | `object` | - | Additional Y-axis props (tick, tickFormatter, width, etc.) |
|
||||
| `strokeWidth` | `number` | `1.5` | Line stroke width |
|
||||
|
||||
#### ChartLineTick Type
|
||||
|
||||
| Property | Type | Description |
|
||||
| --------------- | ------------------ | ---------------------------- |
|
||||
| `timestamp` | `string` | Timestamp for the data point |
|
||||
| `[key: string]` | `string \| number` | Additional data fields |
|
||||
|
||||
#### ChartHighlight Type
|
||||
|
||||
| Property | Type | Description |
|
||||
| ----------------- | ------------------------------------------------------------- | ------------------------------------ |
|
||||
| `handleMouseDown` | `(e: { activeLabel?: string; coordinates?: string }) => void` | Mouse down handler |
|
||||
| `handleMouseMove` | `(e: { activeLabel?: string; coordinates?: string }) => void` | Mouse move handler |
|
||||
| `handleMouseUp` | `(e: { chartX?: number; chartY?: number }) => void` | Mouse up handler |
|
||||
| `coordinates` | `{ left?: string; right?: string }` | Highlight area coordinates |
|
||||
| `clearHighlight` | `() => void?` | Optional function to clear highlight |
|
||||
|
||||
#### ChartHighlightAction Type
|
||||
|
||||
| Property | Type | Description |
|
||||
| ------------ | -------------------------------------------------------------------------------- | ---------------------------------------------------- |
|
||||
| `id` | `string` | Unique identifier for the action |
|
||||
| `label` | `string \| ((ctx: { start: string; end: string; clear: () => void }) => string)` | Action label or function that returns label |
|
||||
| `icon` | `ReactNode?` | Optional icon component |
|
||||
| `isDisabled` | `(ctx: { start: string; end: string; clear: () => void }) => boolean?` | Optional function to determine if action is disabled |
|
||||
| `onSelect` | `(ctx: { start: string; end: string; clear: () => void }) => void` | Action selection handler |
|
||||
|
||||
### ChartBar
|
||||
|
||||
Bar chart component for displaying time-series data.
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
| ------------------- | -------------------------------------------------------------------- | ----------------------------- | ----------------------------------------------------------------- |
|
||||
| `data` | `ChartBarTick[]` | - | Array of data points with timestamp |
|
||||
| `dataKey` | `string` | - | Key in data object to plot |
|
||||
| `config` | `ChartConfig?` | - | Chart configuration for styling |
|
||||
| `onBarClick` | `(datum: ChartBarTick, tooltipData?: CategoricalChartState) => void` | - | Click handler for bars |
|
||||
| `DateTimeFormat` | `string` | `'MMM D, YYYY, hh:mma'` | Date format for tooltips and labels |
|
||||
| `isFullHeight` | `boolean` | `false` | Whether chart should take full height |
|
||||
| `className` | `string` | - | Additional CSS classes |
|
||||
| `color` | `string` | `'hsl(var(--brand-default))'` | Bar color |
|
||||
| `hoverColor` | `string` | `'hsl(var(--brand-500))'` | Bar color on hover |
|
||||
| `chartHighlight` | `ChartHighlight` | - | Highlight selection configuration |
|
||||
| `updateDateRange` | `(from: string, to: string) => void` | - | Callback when date range is updated via highlight |
|
||||
| `highlightActions` | `ChartHighlightAction[]` | - | Actions to show when area is highlighted |
|
||||
| `syncId` | `string` | - | ID to sync multiple charts |
|
||||
| `showHighlightArea` | `boolean` | `true` | Whether to show highlight area |
|
||||
| `cursor` | `string` | - | Cursor style (defaults to 'crosshair' if chartHighlight provided) |
|
||||
| `showGrid` | `boolean` | `false` | Whether to show grid lines |
|
||||
| `showYAxis` | `boolean` | `false` | Whether to show Y-axis |
|
||||
| `YAxisProps` | `object` | - | Additional Y-axis props (tick, tickFormatter, width, etc.) |
|
||||
|
||||
#### ChartBarTick Type
|
||||
|
||||
| Property | Type | Description |
|
||||
| --------------- | ------------------ | ---------------------------- |
|
||||
| `timestamp` | `string` | Timestamp for the data point |
|
||||
| `[key: string]` | `string \| number` | Additional data fields |
|
||||
@@ -7,7 +7,7 @@ UI patterns are reusable design solutions that combine multiple components from
|
||||
|
||||
These patterns help ensure consistency across Supabase products by establishing standard approaches for:
|
||||
|
||||
- **Charts**: Visualizing data consistently using standardized chart types and styling.
|
||||
- **[Charts](/docs/ui-patterns/charts)**: Visualizing data consistently using standardized chart types and styling.
|
||||
- **[Empty States](/docs/ui-patterns/empty-states)**: Communicating the absence of data and guiding users toward meaningful actions.
|
||||
- **[Forms](/docs/ui-patterns/forms)**: Building cohesive form experiences in both page layouts and side panels.
|
||||
- **[Layout](/docs/ui-patterns/layout)**: Creating consistent page structures with proper spacing, max-widths, and content organization.
|
||||
|
||||
@@ -53,6 +53,9 @@ const NestedProperties = defineNestedType(() => ({
|
||||
reactAccessibleTreeview: {
|
||||
type: 'boolean',
|
||||
},
|
||||
recharts: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
const { defineConfig } = require('eslint/config')
|
||||
const supabaseConfig = require('eslint-config-supabase/next')
|
||||
|
||||
module.exports = defineConfig([supabaseConfig])
|
||||
module.exports = defineConfig([
|
||||
supabaseConfig,
|
||||
{
|
||||
files: ['registry/**/*.tsx', '__registry__/**/*.tsx'],
|
||||
rules: {
|
||||
'no-restricted-exports': 'off',
|
||||
},
|
||||
},
|
||||
])
|
||||
@@ -19,8 +19,8 @@
|
||||
"dependencies": {
|
||||
"@hookform/resolvers": "^3.1.1",
|
||||
"contentlayer2": "0.4.6",
|
||||
"dayjs": "1.11.13",
|
||||
"date-fns": "^2.30.0",
|
||||
"dayjs": "1.11.13",
|
||||
"eslint-config-supabase": "workspace:*",
|
||||
"icons": "workspace:*",
|
||||
"jotai": "^2.8.0",
|
||||
|
||||
@@ -1,113 +1,6 @@
|
||||
import { Registry } from './schema'
|
||||
|
||||
export const charts: Registry = [
|
||||
// Area Charts
|
||||
{
|
||||
name: 'chart-area-axes',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-area-axes.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Area',
|
||||
},
|
||||
{
|
||||
name: 'chart-area-default',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-area-default.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Area',
|
||||
},
|
||||
{
|
||||
name: 'chart-area-gradient',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-area-gradient.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Area',
|
||||
},
|
||||
{
|
||||
name: 'chart-area-icons',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-area-icons.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Area',
|
||||
},
|
||||
{
|
||||
name: 'chart-area-interactive',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-area-interactive.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Area',
|
||||
},
|
||||
{
|
||||
name: 'chart-area-legend',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-area-legend.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Area',
|
||||
},
|
||||
{
|
||||
name: 'chart-area-linear',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-area-linear.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Area',
|
||||
},
|
||||
{
|
||||
name: 'chart-area-stacked-expand',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-area-stacked-expand.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Area',
|
||||
},
|
||||
{
|
||||
name: 'chart-area-stacked',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-area-stacked.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Area',
|
||||
},
|
||||
{
|
||||
name: 'chart-area-step',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-area-step.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Area',
|
||||
},
|
||||
|
||||
// Bar Charts
|
||||
{
|
||||
name: 'chart-bar-active',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-bar-active.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Bar',
|
||||
},
|
||||
{
|
||||
name: 'chart-bar-default',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-bar-default.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Bar',
|
||||
},
|
||||
{
|
||||
name: 'chart-bar-horizontal',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-bar-horizontal.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Bar',
|
||||
},
|
||||
{
|
||||
name: 'chart-bar-interactive',
|
||||
type: 'components:block',
|
||||
@@ -117,387 +10,51 @@ export const charts: Registry = [
|
||||
subcategory: 'Bar',
|
||||
},
|
||||
{
|
||||
name: 'chart-bar-label-custom',
|
||||
name: 'chart-composed-demo',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-bar-label-custom.tsx'],
|
||||
registryDependencies: ['chart'],
|
||||
files: ['block/chart-composed-demo.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Bar',
|
||||
subcategory: 'Composed',
|
||||
},
|
||||
{
|
||||
name: 'chart-bar-label',
|
||||
name: 'chart-composed-basic',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-bar-label.tsx'],
|
||||
registryDependencies: ['chart'],
|
||||
files: ['block/chart-composed-basic.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Bar',
|
||||
subcategory: 'Composed',
|
||||
},
|
||||
{
|
||||
name: 'chart-bar-mixed',
|
||||
name: 'chart-composed-states',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-bar-mixed.tsx'],
|
||||
registryDependencies: ['chart'],
|
||||
files: ['block/chart-composed-states.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Bar',
|
||||
subcategory: 'Composed',
|
||||
},
|
||||
{
|
||||
name: 'chart-bar-multiple',
|
||||
name: 'chart-composed-table',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-bar-multiple.tsx'],
|
||||
registryDependencies: ['chart'],
|
||||
files: ['block/chart-composed-table.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Bar',
|
||||
subcategory: 'Composed',
|
||||
},
|
||||
{
|
||||
name: 'chart-bar-negative',
|
||||
name: 'chart-composed-metrics',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-bar-negative.tsx'],
|
||||
registryDependencies: ['chart'],
|
||||
files: ['block/chart-composed-metrics.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Bar',
|
||||
subcategory: 'Composed',
|
||||
},
|
||||
{
|
||||
name: 'chart-bar-stacked',
|
||||
name: 'chart-composed-actions',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-bar-stacked.tsx'],
|
||||
registryDependencies: ['chart'],
|
||||
files: ['block/chart-composed-actions.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Bar',
|
||||
},
|
||||
|
||||
// Line Charts
|
||||
{
|
||||
name: 'chart-line-default',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-line-default.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Line',
|
||||
},
|
||||
{
|
||||
name: 'chart-line-dots-colors',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-line-dots-colors.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Line',
|
||||
},
|
||||
{
|
||||
name: 'chart-line-dots-custom',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-line-dots-custom.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Line',
|
||||
},
|
||||
{
|
||||
name: 'chart-line-dots',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-line-dots.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Line',
|
||||
},
|
||||
{
|
||||
name: 'chart-line-interactive',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-line-interactive.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Line',
|
||||
},
|
||||
{
|
||||
name: 'chart-line-label-custom',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-line-label-custom.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Line',
|
||||
},
|
||||
{
|
||||
name: 'chart-line-label',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-line-label.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Line',
|
||||
},
|
||||
{
|
||||
name: 'chart-line-linear',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-line-linear.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Line',
|
||||
},
|
||||
{
|
||||
name: 'chart-line-multiple',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-line-multiple.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Line',
|
||||
},
|
||||
{
|
||||
name: 'chart-line-step',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-line-step.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Line',
|
||||
},
|
||||
|
||||
// Pie Charts
|
||||
{
|
||||
name: 'chart-pie-donut-active',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-pie-donut-active.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Pie',
|
||||
},
|
||||
{
|
||||
name: 'chart-pie-donut-text',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-pie-donut-text.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Pie',
|
||||
},
|
||||
{
|
||||
name: 'chart-pie-donut',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-pie-donut.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Pie',
|
||||
},
|
||||
{
|
||||
name: 'chart-pie-interactive',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-pie-interactive.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Pie',
|
||||
},
|
||||
{
|
||||
name: 'chart-pie-label-custom',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-pie-label-custom.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Pie',
|
||||
},
|
||||
{
|
||||
name: 'chart-pie-label-list',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-pie-label-list.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Pie',
|
||||
},
|
||||
{
|
||||
name: 'chart-pie-label',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-pie-label.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Pie',
|
||||
},
|
||||
{
|
||||
name: 'chart-pie-legend',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-pie-legend.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Pie',
|
||||
},
|
||||
{
|
||||
name: 'chart-pie-separator-none',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-pie-separator-none.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Pie',
|
||||
},
|
||||
{
|
||||
name: 'chart-pie-simple',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-pie-simple.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Pie',
|
||||
},
|
||||
{
|
||||
name: 'chart-pie-stacked',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-pie-stacked.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Pie',
|
||||
},
|
||||
|
||||
// Radar Charts
|
||||
{
|
||||
name: 'chart-radar-default',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radar-default.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radar',
|
||||
},
|
||||
{
|
||||
name: 'chart-radar-dots',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radar-dots.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radar',
|
||||
},
|
||||
{
|
||||
name: 'chart-radar-grid-circle-fill',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radar-grid-circle-fill.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radar',
|
||||
},
|
||||
{
|
||||
name: 'chart-radar-grid-circle-no-lines',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radar-grid-circle-no-lines.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radar',
|
||||
},
|
||||
{
|
||||
name: 'chart-radar-grid-circle',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radar-grid-circle.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radar',
|
||||
},
|
||||
{
|
||||
name: 'chart-radar-grid-custom',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radar-grid-custom.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radar',
|
||||
},
|
||||
{
|
||||
name: 'chart-radar-grid-fill',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radar-grid-fill.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radar',
|
||||
},
|
||||
{
|
||||
name: 'chart-radar-grid-none',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radar-grid-none.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radar',
|
||||
},
|
||||
{
|
||||
name: 'chart-radar-icons',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radar-icons.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radar',
|
||||
},
|
||||
{
|
||||
name: 'chart-radar-label-custom',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radar-label-custom.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radar',
|
||||
},
|
||||
{
|
||||
name: 'chart-radar-legend',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radar-legend.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radar',
|
||||
},
|
||||
{
|
||||
name: 'chart-radar-lines-only',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radar-lines-only.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radar',
|
||||
},
|
||||
{
|
||||
name: 'chart-radar-multiple',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radar-multiple.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radar',
|
||||
},
|
||||
{
|
||||
name: 'chart-radar-radius',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radar-radius.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radar',
|
||||
},
|
||||
|
||||
// Radial Charts
|
||||
{
|
||||
name: 'chart-radial-grid',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radial-grid.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radial',
|
||||
},
|
||||
{
|
||||
name: 'chart-radial-label',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radial-label.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radial',
|
||||
},
|
||||
{
|
||||
name: 'chart-radial-shape',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radial-shape.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radial',
|
||||
},
|
||||
{
|
||||
name: 'chart-radial-simple',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radial-simple.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radial',
|
||||
},
|
||||
{
|
||||
name: 'chart-radial-stacked',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radial-stacked.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radial',
|
||||
},
|
||||
{
|
||||
name: 'chart-radial-text',
|
||||
type: 'components:block',
|
||||
registryDependencies: ['card', 'chart'],
|
||||
files: ['block/chart-radial-text.tsx'],
|
||||
category: 'Charts',
|
||||
subcategory: 'Radial',
|
||||
subcategory: 'Composed',
|
||||
},
|
||||
]
|
||||
@@ -1,91 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'An area chart with axes'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Axes</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: -20,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<YAxis tickLine={false} axisLine={false} tickMargin={8} tickCount={3} />
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
|
||||
<Area
|
||||
dataKey="mobile"
|
||||
type="natural"
|
||||
fill="var(--color-mobile)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-mobile)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
stackId="a"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A simple area chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'An area chart with gradient fill'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Gradient</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
|
||||
<defs>
|
||||
<linearGradient id="fillDesktop" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="5%" stopColor="var(--color-desktop)" stopOpacity={0.8} />
|
||||
<stop offset="95%" stopColor="var(--color-desktop)" stopOpacity={0.1} />
|
||||
</linearGradient>
|
||||
<linearGradient id="fillMobile" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="5%" stopColor="var(--color-mobile)" stopOpacity={0.8} />
|
||||
<stop offset="95%" stopColor="var(--color-mobile)" stopOpacity={0.1} />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<Area
|
||||
dataKey="mobile"
|
||||
type="natural"
|
||||
fill="url(#fillMobile)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-mobile)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="url(#fillDesktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
stackId="a"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingDown, TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import {
|
||||
ChartConfig,
|
||||
ChartContainer,
|
||||
ChartLegend,
|
||||
ChartLegendContent,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
} from 'ui'
|
||||
|
||||
export const description = 'An area chart with icons'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
icon: TrendingDown,
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
icon: TrendingUp,
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Icons</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<Area
|
||||
dataKey="mobile"
|
||||
type="natural"
|
||||
fill="var(--color-mobile)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-mobile)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
stackId="a"
|
||||
/>
|
||||
<ChartLegend content={<ChartLegendContent />} />
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,238 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import * as React from 'react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from 'ui'
|
||||
import {
|
||||
ChartConfig,
|
||||
ChartContainer,
|
||||
ChartLegend,
|
||||
ChartLegendContent,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
} from 'ui'
|
||||
import {
|
||||
Select_Shadcn_,
|
||||
SelectContent_Shadcn_,
|
||||
SelectItem_Shadcn_,
|
||||
SelectTrigger_Shadcn_,
|
||||
SelectValue_Shadcn_,
|
||||
} from 'ui'
|
||||
|
||||
export const description = 'An interactive area chart'
|
||||
|
||||
const chartData = [
|
||||
{ date: '2024-04-01', desktop: 222, mobile: 150 },
|
||||
{ date: '2024-04-02', desktop: 97, mobile: 180 },
|
||||
{ date: '2024-04-03', desktop: 167, mobile: 120 },
|
||||
{ date: '2024-04-04', desktop: 242, mobile: 260 },
|
||||
{ date: '2024-04-05', desktop: 373, mobile: 290 },
|
||||
{ date: '2024-04-06', desktop: 301, mobile: 340 },
|
||||
{ date: '2024-04-07', desktop: 245, mobile: 180 },
|
||||
{ date: '2024-04-08', desktop: 409, mobile: 320 },
|
||||
{ date: '2024-04-09', desktop: 59, mobile: 110 },
|
||||
{ date: '2024-04-10', desktop: 261, mobile: 190 },
|
||||
{ date: '2024-04-11', desktop: 327, mobile: 350 },
|
||||
{ date: '2024-04-12', desktop: 292, mobile: 210 },
|
||||
{ date: '2024-04-13', desktop: 342, mobile: 380 },
|
||||
{ date: '2024-04-14', desktop: 137, mobile: 220 },
|
||||
{ date: '2024-04-15', desktop: 120, mobile: 170 },
|
||||
{ date: '2024-04-16', desktop: 138, mobile: 190 },
|
||||
{ date: '2024-04-17', desktop: 446, mobile: 360 },
|
||||
{ date: '2024-04-18', desktop: 364, mobile: 410 },
|
||||
{ date: '2024-04-19', desktop: 243, mobile: 180 },
|
||||
{ date: '2024-04-20', desktop: 89, mobile: 150 },
|
||||
{ date: '2024-04-21', desktop: 137, mobile: 200 },
|
||||
{ date: '2024-04-22', desktop: 224, mobile: 170 },
|
||||
{ date: '2024-04-23', desktop: 138, mobile: 230 },
|
||||
{ date: '2024-04-24', desktop: 387, mobile: 290 },
|
||||
{ date: '2024-04-25', desktop: 215, mobile: 250 },
|
||||
{ date: '2024-04-26', desktop: 75, mobile: 130 },
|
||||
{ date: '2024-04-27', desktop: 383, mobile: 420 },
|
||||
{ date: '2024-04-28', desktop: 122, mobile: 180 },
|
||||
{ date: '2024-04-29', desktop: 315, mobile: 240 },
|
||||
{ date: '2024-04-30', desktop: 454, mobile: 380 },
|
||||
{ date: '2024-05-01', desktop: 165, mobile: 220 },
|
||||
{ date: '2024-05-02', desktop: 293, mobile: 310 },
|
||||
{ date: '2024-05-03', desktop: 247, mobile: 190 },
|
||||
{ date: '2024-05-04', desktop: 385, mobile: 420 },
|
||||
{ date: '2024-05-05', desktop: 481, mobile: 390 },
|
||||
{ date: '2024-05-06', desktop: 498, mobile: 520 },
|
||||
{ date: '2024-05-07', desktop: 388, mobile: 300 },
|
||||
{ date: '2024-05-08', desktop: 149, mobile: 210 },
|
||||
{ date: '2024-05-09', desktop: 227, mobile: 180 },
|
||||
{ date: '2024-05-10', desktop: 293, mobile: 330 },
|
||||
{ date: '2024-05-11', desktop: 335, mobile: 270 },
|
||||
{ date: '2024-05-12', desktop: 197, mobile: 240 },
|
||||
{ date: '2024-05-13', desktop: 197, mobile: 160 },
|
||||
{ date: '2024-05-14', desktop: 448, mobile: 490 },
|
||||
{ date: '2024-05-15', desktop: 473, mobile: 380 },
|
||||
{ date: '2024-05-16', desktop: 338, mobile: 400 },
|
||||
{ date: '2024-05-17', desktop: 499, mobile: 420 },
|
||||
{ date: '2024-05-18', desktop: 315, mobile: 350 },
|
||||
{ date: '2024-05-19', desktop: 235, mobile: 180 },
|
||||
{ date: '2024-05-20', desktop: 177, mobile: 230 },
|
||||
{ date: '2024-05-21', desktop: 82, mobile: 140 },
|
||||
{ date: '2024-05-22', desktop: 81, mobile: 120 },
|
||||
{ date: '2024-05-23', desktop: 252, mobile: 290 },
|
||||
{ date: '2024-05-24', desktop: 294, mobile: 220 },
|
||||
{ date: '2024-05-25', desktop: 201, mobile: 250 },
|
||||
{ date: '2024-05-26', desktop: 213, mobile: 170 },
|
||||
{ date: '2024-05-27', desktop: 420, mobile: 460 },
|
||||
{ date: '2024-05-28', desktop: 233, mobile: 190 },
|
||||
{ date: '2024-05-29', desktop: 78, mobile: 130 },
|
||||
{ date: '2024-05-30', desktop: 340, mobile: 280 },
|
||||
{ date: '2024-05-31', desktop: 178, mobile: 230 },
|
||||
{ date: '2024-06-01', desktop: 178, mobile: 200 },
|
||||
{ date: '2024-06-02', desktop: 470, mobile: 410 },
|
||||
{ date: '2024-06-03', desktop: 103, mobile: 160 },
|
||||
{ date: '2024-06-04', desktop: 439, mobile: 380 },
|
||||
{ date: '2024-06-05', desktop: 88, mobile: 140 },
|
||||
{ date: '2024-06-06', desktop: 294, mobile: 250 },
|
||||
{ date: '2024-06-07', desktop: 323, mobile: 370 },
|
||||
{ date: '2024-06-08', desktop: 385, mobile: 320 },
|
||||
{ date: '2024-06-09', desktop: 438, mobile: 480 },
|
||||
{ date: '2024-06-10', desktop: 155, mobile: 200 },
|
||||
{ date: '2024-06-11', desktop: 92, mobile: 150 },
|
||||
{ date: '2024-06-12', desktop: 492, mobile: 420 },
|
||||
{ date: '2024-06-13', desktop: 81, mobile: 130 },
|
||||
{ date: '2024-06-14', desktop: 426, mobile: 380 },
|
||||
{ date: '2024-06-15', desktop: 307, mobile: 350 },
|
||||
{ date: '2024-06-16', desktop: 371, mobile: 310 },
|
||||
{ date: '2024-06-17', desktop: 475, mobile: 520 },
|
||||
{ date: '2024-06-18', desktop: 107, mobile: 170 },
|
||||
{ date: '2024-06-19', desktop: 341, mobile: 290 },
|
||||
{ date: '2024-06-20', desktop: 408, mobile: 450 },
|
||||
{ date: '2024-06-21', desktop: 169, mobile: 210 },
|
||||
{ date: '2024-06-22', desktop: 317, mobile: 270 },
|
||||
{ date: '2024-06-23', desktop: 480, mobile: 530 },
|
||||
{ date: '2024-06-24', desktop: 132, mobile: 180 },
|
||||
{ date: '2024-06-25', desktop: 141, mobile: 190 },
|
||||
{ date: '2024-06-26', desktop: 434, mobile: 380 },
|
||||
{ date: '2024-06-27', desktop: 448, mobile: 490 },
|
||||
{ date: '2024-06-28', desktop: 149, mobile: 200 },
|
||||
{ date: '2024-06-29', desktop: 103, mobile: 160 },
|
||||
{ date: '2024-06-30', desktop: 446, mobile: 400 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
const [timeRange, setTimeRange] = React.useState('90d')
|
||||
|
||||
const filteredData = chartData.filter((item) => {
|
||||
const date = new Date(item.date)
|
||||
const now = new Date()
|
||||
let daysToSubtract = 90
|
||||
if (timeRange === '30d') {
|
||||
daysToSubtract = 30
|
||||
} else if (timeRange === '7d') {
|
||||
daysToSubtract = 7
|
||||
}
|
||||
now.setDate(now.getDate() - daysToSubtract)
|
||||
return date >= now
|
||||
})
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="flex items-center gap-2 space-y-0 border-b py-5 sm:flex-row">
|
||||
<div className="grid flex-1 gap-1 text-center sm:text-left">
|
||||
<CardTitle>Area Chart - Interactive</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 3 months</CardDescription>
|
||||
</div>
|
||||
<Select_Shadcn_ value={timeRange} onValueChange={setTimeRange}>
|
||||
<SelectTrigger_Shadcn_
|
||||
className="w-[160px] rounded-lg sm:ml-auto"
|
||||
aria-label="Select a value"
|
||||
>
|
||||
<SelectValue_Shadcn_ placeholder="Last 3 months" />
|
||||
</SelectTrigger_Shadcn_>
|
||||
<SelectContent_Shadcn_ className="rounded-xl">
|
||||
<SelectItem_Shadcn_ value="90d" className="rounded-lg">
|
||||
Last 3 months
|
||||
</SelectItem_Shadcn_>
|
||||
<SelectItem_Shadcn_ value="30d" className="rounded-lg">
|
||||
Last 30 days
|
||||
</SelectItem_Shadcn_>
|
||||
<SelectItem_Shadcn_ value="7d" className="rounded-lg">
|
||||
Last 7 days
|
||||
</SelectItem_Shadcn_>
|
||||
</SelectContent_Shadcn_>
|
||||
</Select_Shadcn_>
|
||||
</CardHeader>
|
||||
<CardContent className="px-2 pt-4 sm:px-6 sm:pt-6">
|
||||
<ChartContainer config={chartConfig} className="aspect-auto h-[250px] w-full">
|
||||
<AreaChart data={filteredData}>
|
||||
<defs>
|
||||
<linearGradient id="fillDesktop" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="5%" stopColor="var(--color-desktop)" stopOpacity={0.8} />
|
||||
<stop offset="95%" stopColor="var(--color-desktop)" stopOpacity={0.1} />
|
||||
</linearGradient>
|
||||
<linearGradient id="fillMobile" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="5%" stopColor="var(--color-mobile)" stopOpacity={0.8} />
|
||||
<stop offset="95%" stopColor="var(--color-mobile)" stopOpacity={0.1} />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="date"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
minTickGap={32}
|
||||
tickFormatter={(value) => {
|
||||
const date = new Date(value)
|
||||
return date.toLocaleDateString('en-US', {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<ChartTooltip
|
||||
cursor={false}
|
||||
content={
|
||||
<ChartTooltipContent
|
||||
labelFormatter={(value) => {
|
||||
return new Date(value).toLocaleDateString('en-US', {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
})
|
||||
}}
|
||||
indicator="dot"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Area
|
||||
dataKey="mobile"
|
||||
type="natural"
|
||||
fill="url(#fillMobile)"
|
||||
stroke="var(--color-mobile)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="url(#fillDesktop)"
|
||||
stroke="var(--color-desktop)"
|
||||
stackId="a"
|
||||
/>
|
||||
<ChartLegend content={<ChartLegendContent />} />
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import {
|
||||
ChartConfig,
|
||||
ChartContainer,
|
||||
ChartLegend,
|
||||
ChartLegendContent,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
} from 'ui'
|
||||
|
||||
export const description = 'An area chart with a legend'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Legend</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<Area
|
||||
dataKey="mobile"
|
||||
type="natural"
|
||||
fill="var(--color-mobile)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-mobile)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
stackId="a"
|
||||
/>
|
||||
<ChartLegend content={<ChartLegendContent />} />
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A linear area chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Linear</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip
|
||||
cursor={false}
|
||||
content={<ChartTooltipContent indicator="dot" hideLabel />}
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="linear"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A stacked area chart with expand stacking'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80, other: 45 },
|
||||
{ month: 'February', desktop: 305, mobile: 200, other: 100 },
|
||||
{ month: 'March', desktop: 237, mobile: 120, other: 150 },
|
||||
{ month: 'April', desktop: 73, mobile: 190, other: 50 },
|
||||
{ month: 'May', desktop: 209, mobile: 130, other: 100 },
|
||||
{ month: 'June', desktop: 214, mobile: 140, other: 160 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Stacked Expanded</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
top: 12,
|
||||
}}
|
||||
stackOffset="expand"
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<Area
|
||||
dataKey="other"
|
||||
type="natural"
|
||||
fill="var(--color-other)"
|
||||
fillOpacity={0.1}
|
||||
stroke="var(--color-other)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="mobile"
|
||||
type="natural"
|
||||
fill="var(--color-mobile)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-mobile)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
stackId="a"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A stacked area chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Stacked</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="dot" />} />
|
||||
<Area
|
||||
dataKey="mobile"
|
||||
type="natural"
|
||||
fill="var(--color-mobile)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-mobile)"
|
||||
stackId="a"
|
||||
/>
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="natural"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
stackId="a"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { Activity, TrendingUp } from 'lucide-react'
|
||||
import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A step area chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
icon: Activity,
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Area Chart - Step</CardTitle>
|
||||
<CardDescription>Showing total visitors for the last 6 months</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<AreaChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
left: 12,
|
||||
right: 12,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
tickMargin={8}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Area
|
||||
dataKey="desktop"
|
||||
type="step"
|
||||
fill="var(--color-desktop)"
|
||||
fillOpacity={0.4}
|
||||
stroke="var(--color-desktop)"
|
||||
/>
|
||||
</AreaChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<div className="flex w-full items-start gap-2 text-sm">
|
||||
<div className="grid gap-2">
|
||||
<div className="flex items-center gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="flex items-center gap-2 leading-none text-muted-foreground">
|
||||
January - June 2024
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, CartesianGrid, Rectangle, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A bar chart with an active bar'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 187, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 275, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Active</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart accessibilityLayer data={chartData}>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="browser"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => chartConfig[value as keyof typeof chartConfig]?.label}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Bar
|
||||
dataKey="visitors"
|
||||
strokeWidth={2}
|
||||
radius={8}
|
||||
activeIndex={2}
|
||||
activeBar={({ ...props }) => {
|
||||
return (
|
||||
<Rectangle
|
||||
{...props}
|
||||
fillOpacity={0.8}
|
||||
stroke={props.payload.fill}
|
||||
strokeDasharray={4}
|
||||
strokeDashoffset={4}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A bar chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart accessibilityLayer data={chartData}>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={8} />
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, XAxis, YAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A horizontal bar chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Horizontal</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
layout="vertical"
|
||||
margin={{
|
||||
left: -20,
|
||||
}}
|
||||
>
|
||||
<XAxis type="number" dataKey="desktop" hide />
|
||||
<YAxis
|
||||
dataKey="month"
|
||||
type="category"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={5} />
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, CartesianGrid, LabelList, XAxis, YAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A bar chart with a custom label'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
label: {
|
||||
color: 'hsl(var(--background))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Custom Label</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
layout="vertical"
|
||||
margin={{
|
||||
right: 16,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid horizontal={false} />
|
||||
<YAxis
|
||||
dataKey="month"
|
||||
type="category"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
hide
|
||||
/>
|
||||
<XAxis dataKey="desktop" type="number" hide />
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="line" />} />
|
||||
<Bar dataKey="desktop" layout="vertical" fill="var(--color-desktop)" radius={4}>
|
||||
<LabelList
|
||||
dataKey="month"
|
||||
position="insideLeft"
|
||||
offset={8}
|
||||
className="fill-[--color-label]"
|
||||
fontSize={12}
|
||||
/>
|
||||
<LabelList
|
||||
dataKey="desktop"
|
||||
position="right"
|
||||
offset={8}
|
||||
className="fill-foreground"
|
||||
fontSize={12}
|
||||
/>
|
||||
</Bar>
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, CartesianGrid, LabelList, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A bar chart with a label'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186 },
|
||||
{ month: 'February', desktop: 305 },
|
||||
{ month: 'March', desktop: 237 },
|
||||
{ month: 'April', desktop: 73 },
|
||||
{ month: 'May', desktop: 209 },
|
||||
{ month: 'June', desktop: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Label</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
margin={{
|
||||
top: 20,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={8}>
|
||||
<LabelList position="top" offset={12} className="fill-foreground" fontSize={12} />
|
||||
</Bar>
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, XAxis, YAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A mixed bar chart'
|
||||
|
||||
const chartData = [
|
||||
{ browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' },
|
||||
{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' },
|
||||
{ browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' },
|
||||
{ browser: 'edge', visitors: 173, fill: 'var(--color-edge)' },
|
||||
{ browser: 'other', visitors: 90, fill: 'var(--color-other)' },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
chrome: {
|
||||
label: 'Chrome',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
safari: {
|
||||
label: 'Safari',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
firefox: {
|
||||
label: 'Firefox',
|
||||
color: 'hsl(var(--chart-3))',
|
||||
},
|
||||
edge: {
|
||||
label: 'Edge',
|
||||
color: 'hsl(var(--chart-4))',
|
||||
},
|
||||
other: {
|
||||
label: 'Other',
|
||||
color: 'hsl(var(--chart-5))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Mixed</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart
|
||||
accessibilityLayer
|
||||
data={chartData}
|
||||
layout="vertical"
|
||||
margin={{
|
||||
left: 0,
|
||||
}}
|
||||
>
|
||||
<YAxis
|
||||
dataKey="browser"
|
||||
type="category"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => chartConfig[value as keyof typeof chartConfig]?.label}
|
||||
/>
|
||||
<XAxis dataKey="visitors" type="number" hide />
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
|
||||
<Bar dataKey="visitors" layout="vertical" radius={5} />
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A multiple bar chart'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Multiple</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart accessibilityLayer data={chartData}>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip cursor={false} content={<ChartTooltipContent indicator="dashed" />} />
|
||||
<Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
|
||||
<Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, CartesianGrid, Cell, LabelList } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
|
||||
|
||||
export const description = 'A bar chart with negative values'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', visitors: 186 },
|
||||
{ month: 'February', visitors: 205 },
|
||||
{ month: 'March', visitors: -207 },
|
||||
{ month: 'April', visitors: 173 },
|
||||
{ month: 'May', visitors: -209 },
|
||||
{ month: 'June', visitors: 214 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
visitors: {
|
||||
label: 'Visitors',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Negative</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart accessibilityLayer data={chartData}>
|
||||
<CartesianGrid vertical={false} />
|
||||
<ChartTooltip
|
||||
cursor={false}
|
||||
content={<ChartTooltipContent hideLabel hideIndicator />}
|
||||
/>
|
||||
<Bar dataKey="visitors">
|
||||
<LabelList position="top" dataKey="month" fillOpacity={1} />
|
||||
{chartData.map((item) => (
|
||||
<Cell
|
||||
key={item.month}
|
||||
fill={item.visitors > 0 ? 'hsl(var(--chart-1))' : 'hsl(var(--chart-2))'}
|
||||
/>
|
||||
))}
|
||||
</Bar>
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import { TrendingUp } from 'lucide-react'
|
||||
import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts'
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui'
|
||||
import {
|
||||
ChartConfig,
|
||||
ChartContainer,
|
||||
ChartLegend,
|
||||
ChartLegendContent,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
} from 'ui'
|
||||
|
||||
export const description = 'A stacked bar chart with a legend'
|
||||
|
||||
const chartData = [
|
||||
{ month: 'January', desktop: 186, mobile: 80 },
|
||||
{ month: 'February', desktop: 305, mobile: 200 },
|
||||
{ month: 'March', desktop: 237, mobile: 120 },
|
||||
{ month: 'April', desktop: 73, mobile: 190 },
|
||||
{ month: 'May', desktop: 209, mobile: 130 },
|
||||
{ month: 'June', desktop: 214, mobile: 140 },
|
||||
]
|
||||
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: 'Desktop',
|
||||
color: 'hsl(var(--chart-1))',
|
||||
},
|
||||
mobile: {
|
||||
label: 'Mobile',
|
||||
color: 'hsl(var(--chart-2))',
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
|
||||
export default function Component() {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Bar Chart - Stacked + Legend</CardTitle>
|
||||
<CardDescription>January - June 2024</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ChartContainer config={chartConfig}>
|
||||
<BarChart accessibilityLayer data={chartData}>
|
||||
<CartesianGrid vertical={false} />
|
||||
<XAxis
|
||||
dataKey="month"
|
||||
tickLine={false}
|
||||
tickMargin={10}
|
||||
axisLine={false}
|
||||
tickFormatter={(value) => value.slice(0, 3)}
|
||||
/>
|
||||
<ChartTooltip content={<ChartTooltipContent hideLabel />} />
|
||||
<ChartLegend content={<ChartLegendContent />} />
|
||||
<Bar dataKey="desktop" stackId="a" fill="var(--color-desktop)" radius={[0, 0, 4, 4]} />
|
||||
<Bar dataKey="mobile" stackId="a" fill="var(--color-mobile)" radius={[4, 4, 0, 0]} />
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</CardContent>
|
||||
<CardFooter className="flex-col items-start gap-2 text-sm">
|
||||
<div className="flex gap-2 font-medium leading-none">
|
||||
Trending up by 5.2% this month <TrendingUp className="h-4 w-4" />
|
||||
</div>
|
||||
<div className="leading-none text-muted-foreground">
|
||||
Showing total visitors for the last 6 months
|
||||
</div>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
Chart,
|
||||
ChartActions,
|
||||
ChartCard,
|
||||
ChartContent,
|
||||
ChartHeader,
|
||||
ChartTitle,
|
||||
ChartEmptyState,
|
||||
ChartLoadingState,
|
||||
ChartBar,
|
||||
ChartLine,
|
||||
} from 'ui-patterns/Chart'
|
||||
import { BarChart2, ExternalLink, LineChart } from 'lucide-react'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
export default function ChartComposedActions() {
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const [chartType, setChartType] = useState<'bar' | 'line'>('bar')
|
||||
|
||||
const actions = [
|
||||
{
|
||||
label: 'Open in Logs Explorer',
|
||||
onClick: () => {
|
||||
alert('Opening in Logs Explorer...')
|
||||
},
|
||||
icon: <ExternalLink size={12} />,
|
||||
},
|
||||
{
|
||||
label: 'Toggle Chart Type',
|
||||
onClick: () => {
|
||||
setChartType(chartType === 'bar' ? 'line' : 'bar')
|
||||
},
|
||||
icon: chartType === 'bar' ? <LineChart size={12} /> : <BarChart2 size={12} />,
|
||||
},
|
||||
]
|
||||
|
||||
const data = Array.from({ length: 46 }, (_, i) => {
|
||||
const date = new Date()
|
||||
date.setMinutes(date.getMinutes() - i * 5) // Each point 5 minutes apart
|
||||
|
||||
return {
|
||||
timestamp: date.toISOString(),
|
||||
requests: Math.floor(Math.random() * 100),
|
||||
}
|
||||
}).reverse()
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setIsLoading(false)
|
||||
}, 1000)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-6 w-8/12">
|
||||
<Chart isLoading={isLoading}>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartTitle tooltip="This is a tooltip">Total Requests</ChartTitle>
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
isEmpty={data.length === 0}
|
||||
emptyState={
|
||||
<ChartEmptyState
|
||||
icon={<BarChart2 size={16} />}
|
||||
title="No data to show"
|
||||
description="It may take up to 24 hours for data to refresh"
|
||||
/>
|
||||
}
|
||||
loadingState={<ChartLoadingState />}
|
||||
>
|
||||
<div className="h-40">
|
||||
{chartType === 'bar' ? (
|
||||
<ChartBar
|
||||
data={data}
|
||||
dataKey="requests"
|
||||
showGrid={false}
|
||||
showYAxis={true}
|
||||
YAxisProps={{
|
||||
tickFormatter: (value) => `${value}k`,
|
||||
width: 80,
|
||||
}}
|
||||
isFullHeight={true}
|
||||
/>
|
||||
) : (
|
||||
<ChartLine
|
||||
data={data}
|
||||
dataKey="requests"
|
||||
showGrid={true}
|
||||
showYAxis={true}
|
||||
YAxisProps={{
|
||||
tickFormatter: (value) => `${value}k`,
|
||||
width: 80,
|
||||
}}
|
||||
isFullHeight={true}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
Chart,
|
||||
ChartActions,
|
||||
ChartCard,
|
||||
ChartContent,
|
||||
ChartHeader,
|
||||
ChartTitle,
|
||||
ChartEmptyState,
|
||||
ChartLoadingState,
|
||||
ChartBar,
|
||||
ChartLine,
|
||||
} from 'ui-patterns/Chart'
|
||||
import { BarChart2, ExternalLink } from 'lucide-react'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
export default function ComposedChartBasic() {
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
|
||||
const actions = [
|
||||
{
|
||||
label: 'Open in Logs Explorer',
|
||||
onClick: () => {
|
||||
alert('Ta da! You clicked me! 🎉')
|
||||
},
|
||||
icon: <ExternalLink size={12} />,
|
||||
},
|
||||
]
|
||||
|
||||
const data = Array.from({ length: 46 }, (_, i) => {
|
||||
const date = new Date()
|
||||
date.setMinutes(date.getMinutes() - i * 5) // Each point 5 minutes apart
|
||||
|
||||
return {
|
||||
timestamp: date.toISOString(),
|
||||
standard_score: Math.floor(Math.random() * 100),
|
||||
}
|
||||
}).reverse()
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setIsLoading(false)
|
||||
}, 1000)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-6 w-8/12">
|
||||
<Chart isLoading={isLoading}>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartTitle tooltip="This is a tooltip">Standard Bar Chart</ChartTitle>
|
||||
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
|
||||
<ChartContent
|
||||
isEmpty={data.length === 0}
|
||||
emptyState={
|
||||
<ChartEmptyState
|
||||
icon={<BarChart2 size={16} />}
|
||||
title="No data to show"
|
||||
description="It may take up to 24 hours for data to refresh"
|
||||
/>
|
||||
}
|
||||
loadingState={<ChartLoadingState />}
|
||||
>
|
||||
<div className="h-40">
|
||||
<ChartBar
|
||||
data={data}
|
||||
dataKey="standard_score"
|
||||
showGrid={false}
|
||||
showYAxis={true}
|
||||
YAxisProps={{
|
||||
tickFormatter: (value) => `${value}k`,
|
||||
width: 80,
|
||||
}}
|
||||
isFullHeight={true}
|
||||
/>
|
||||
</div>
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
|
||||
<Chart isLoading={isLoading}>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartTitle tooltip="This is a tooltip">Standard Line Chart</ChartTitle>
|
||||
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
|
||||
<ChartContent
|
||||
isEmpty={data.length === 0}
|
||||
emptyState={
|
||||
<ChartEmptyState
|
||||
icon={<BarChart2 size={16} />}
|
||||
title="No data to show"
|
||||
description="It may take up to 24 hours for data to refresh"
|
||||
/>
|
||||
}
|
||||
loadingState={<ChartLoadingState />}
|
||||
>
|
||||
<div className="h-40">
|
||||
<ChartLine
|
||||
data={data}
|
||||
dataKey="standard_score"
|
||||
showGrid={true}
|
||||
showYAxis={true}
|
||||
YAxisProps={{
|
||||
tickFormatter: (value) => `${value}k`,
|
||||
width: 80,
|
||||
}}
|
||||
isFullHeight={true}
|
||||
/>
|
||||
</div>
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
Chart,
|
||||
ChartCard,
|
||||
ChartContent,
|
||||
ChartHeader,
|
||||
ChartEmptyState,
|
||||
ChartLoadingState,
|
||||
ChartMetric,
|
||||
} from 'ui-patterns/Chart'
|
||||
import { BarChart2 } from 'lucide-react'
|
||||
import { LogsBarChart } from 'ui-patterns/LogsBarChart'
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
export default function ComposedChartDemo() {
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
|
||||
const data = Array.from({ length: 60 }, (_, i) => {
|
||||
const date = new Date()
|
||||
date.setMinutes(date.getMinutes() - i * 5) // Each point 5 minutes apart
|
||||
|
||||
return {
|
||||
timestamp: date.toISOString(),
|
||||
ok_count: Math.floor(Math.random() * 100), // Random value 0-99
|
||||
error_count: Math.floor(Math.random() * 50), // Random value 0-50
|
||||
warning_count: Math.floor(Math.random() * 50), // Random value 0-50
|
||||
}
|
||||
}).reverse()
|
||||
|
||||
const totalUsersValue = 4663
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setIsLoading(false)
|
||||
}, 1000)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="w-8/12">
|
||||
<Chart isLoading={isLoading}>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartMetric
|
||||
label="Total Users"
|
||||
value={totalUsersValue.toLocaleString('en-US')}
|
||||
tooltip="This is a tooltip"
|
||||
/>
|
||||
<div className="flex items-center gap-6">
|
||||
<ChartMetric label="Warn" value="1.2k" status="warning" align="end" />
|
||||
<ChartMetric label="Err" value="736" status="negative" align="end" />
|
||||
</div>
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
isEmpty={data.length === 0}
|
||||
emptyState={
|
||||
<ChartEmptyState
|
||||
icon={<BarChart2 size={16} />}
|
||||
title="No data to show"
|
||||
description="It may take up to 24 hours for data to refresh"
|
||||
/>
|
||||
}
|
||||
loadingState={<ChartLoadingState />}
|
||||
>
|
||||
<div className="h-40">
|
||||
<LogsBarChart data={data} isFullHeight={true} />
|
||||
</div>
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
Chart,
|
||||
ChartCard,
|
||||
ChartHeader,
|
||||
ChartActions,
|
||||
ChartContent,
|
||||
ChartMetric,
|
||||
ChartSparkline,
|
||||
} from 'ui-patterns/Chart'
|
||||
import { ExternalLink } from 'lucide-react'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Skeleton } from 'ui'
|
||||
|
||||
export default function ChartComposedMetrics() {
|
||||
const [data, setData] = useState<Array<{ value: number; timestamp: string }>>([])
|
||||
|
||||
const actions = [
|
||||
{
|
||||
label: 'Open in Logs Explorer',
|
||||
onClick: () => {
|
||||
alert('Ta da! You clicked me! 🎉')
|
||||
},
|
||||
icon: <ExternalLink size={12} />,
|
||||
},
|
||||
]
|
||||
|
||||
useEffect(() => {
|
||||
const now = new Date()
|
||||
setData(
|
||||
Array.from({ length: 12 }, (_, i) => ({
|
||||
value: Math.floor(4000 + i * 100 + (Math.random() * 2000 - 800)),
|
||||
timestamp: new Date(now.getTime() - (11 - i) * 60 * 60 * 1000).toISOString(),
|
||||
}))
|
||||
)
|
||||
}, [])
|
||||
|
||||
const averageValue = data.reduce((acc, curr) => acc + curr.value, 0) / data.length
|
||||
|
||||
const diff = data[data.length - 1]?.value - data[0]?.value || 0
|
||||
const diffPercentage = (diff / averageValue) * 100
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-2 gap-6 w-full">
|
||||
<Chart isLoading={!data.length}>
|
||||
<ChartCard>
|
||||
<ChartHeader className="pb-4" align="start">
|
||||
<ChartMetric label="Slow Queries" value={0} />
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
<Chart isLoading={!data.length}>
|
||||
<ChartCard>
|
||||
<ChartHeader className="pb-4" align="start">
|
||||
<ChartMetric label="Sign Ups" value={127} />
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
<Chart isLoading={!data.length}>
|
||||
<ChartCard>
|
||||
<ChartHeader align="start">
|
||||
<ChartMetric
|
||||
label="Active Users"
|
||||
value={averageValue.toLocaleString(undefined, { maximumFractionDigits: 0 })}
|
||||
diffValue={diffPercentage.toFixed(2) + '%'}
|
||||
/>
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
className="p-0"
|
||||
loadingState={<Skeleton className="w-full h-[6rem] rounded-none mt-4" />}
|
||||
>
|
||||
<ChartSparkline data={data} dataKey="value" />
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
<Chart isLoading={!data.length}>
|
||||
<ChartCard>
|
||||
<ChartHeader align="start">
|
||||
<ChartMetric
|
||||
label="Active Users"
|
||||
value={averageValue.toLocaleString(undefined, { maximumFractionDigits: 0 })}
|
||||
diffValue={diffPercentage.toFixed(2) + '%'}
|
||||
/>
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
className="p-0"
|
||||
loadingState={<Skeleton className="w-full h-[6rem] rounded-none mt-4" />}
|
||||
>
|
||||
<ChartSparkline data={data} dataKey="value" />
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
'use client'
|
||||
|
||||
import { BarChart2, ExternalLink } from 'lucide-react'
|
||||
import {
|
||||
Chart,
|
||||
ChartCard,
|
||||
ChartHeader,
|
||||
ChartTitle,
|
||||
ChartActions,
|
||||
ChartContent,
|
||||
ChartEmptyState,
|
||||
ChartLoadingState,
|
||||
ChartDisabledState,
|
||||
} from 'ui-patterns/Chart'
|
||||
import { Badge } from 'ui'
|
||||
|
||||
export default function ChartComposedStates() {
|
||||
const actions = [
|
||||
{
|
||||
label: 'Open in Logs Explorer',
|
||||
onClick: () => {
|
||||
alert('Ta da! You clicked me! 🎉')
|
||||
},
|
||||
icon: <ExternalLink size={12} />,
|
||||
},
|
||||
]
|
||||
|
||||
const disabledActions = [
|
||||
{
|
||||
label: 'Upgrade to Pro',
|
||||
href: '#',
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-6 w-8/12">
|
||||
<Chart isLoading={true}>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartTitle tooltip="This is a tooltip">Response Errors</ChartTitle>
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
<ChartContent loadingState={<ChartLoadingState />}>My chart here...</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
|
||||
<Chart>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartTitle tooltip="This is a tooltip">Response Errors</ChartTitle>
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
isEmpty={true}
|
||||
emptyState={
|
||||
<ChartEmptyState
|
||||
icon={<BarChart2 size={20} />}
|
||||
title="No data to show"
|
||||
description="It may take up to 24 hours for data to refresh"
|
||||
/>
|
||||
}
|
||||
loadingState={<ChartLoadingState />}
|
||||
>
|
||||
My chart here...
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
|
||||
<Chart isDisabled={true}>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartTitle tooltip="This is a tooltip">Response Errors</ChartTitle>
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
loadingState={<ChartLoadingState />}
|
||||
disabledState={
|
||||
<ChartDisabledState
|
||||
icon={<Badge variant="success">Pro</Badge>}
|
||||
label="API Processing Time"
|
||||
description="This chart is available on the Pro plan and above"
|
||||
actions={disabledActions}
|
||||
/>
|
||||
}
|
||||
>
|
||||
My chart here...
|
||||
</ChartContent>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
'use client'
|
||||
|
||||
import {
|
||||
Chart,
|
||||
ChartActions,
|
||||
ChartCard,
|
||||
ChartContent,
|
||||
ChartHeader,
|
||||
ChartTitle,
|
||||
ChartEmptyState,
|
||||
ChartLoadingState,
|
||||
ChartBar,
|
||||
ChartFooter,
|
||||
} from 'ui-patterns/Chart'
|
||||
import { BarChart2, ExternalLink } from 'lucide-react'
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Table, TableHead, TableBody, TableRow, TableCell, TableHeader } from 'ui'
|
||||
import { format } from 'date-fns'
|
||||
|
||||
export default function ChartComposedTable() {
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
|
||||
const actions = [
|
||||
{
|
||||
label: 'Open in Logs Explorer',
|
||||
onClick: () => {
|
||||
alert('Opening in Logs Explorer...')
|
||||
},
|
||||
icon: <ExternalLink size={12} />,
|
||||
},
|
||||
]
|
||||
|
||||
const data = Array.from({ length: 46 }, (_, i) => {
|
||||
const date = new Date()
|
||||
date.setMinutes(date.getMinutes() - i * 5) // Each point 5 minutes apart
|
||||
|
||||
return {
|
||||
timestamp: date.toISOString(),
|
||||
standard_score: Math.floor(Math.random() * 100),
|
||||
}
|
||||
}).reverse()
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setIsLoading(false)
|
||||
}, 1000)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-6 w-8/12">
|
||||
<Chart isLoading={isLoading}>
|
||||
<ChartCard>
|
||||
<ChartHeader>
|
||||
<ChartTitle tooltip="This is a tooltip">Standard Bar Chart</ChartTitle>
|
||||
<ChartActions actions={actions} />
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
isEmpty={data.length === 0}
|
||||
emptyState={
|
||||
<ChartEmptyState
|
||||
icon={<BarChart2 size={16} />}
|
||||
title="No data to show"
|
||||
description="It may take up to 24 hours for data to refresh"
|
||||
/>
|
||||
}
|
||||
loadingState={<ChartLoadingState />}
|
||||
>
|
||||
<div className="h-40">
|
||||
<ChartBar
|
||||
data={data}
|
||||
dataKey="standard_score"
|
||||
showGrid={false}
|
||||
showYAxis={true}
|
||||
YAxisProps={{
|
||||
tickFormatter: (value) => `${value}k`,
|
||||
width: 80,
|
||||
}}
|
||||
isFullHeight={true}
|
||||
/>
|
||||
</div>
|
||||
</ChartContent>
|
||||
<ChartFooter>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Timestamp</TableHead>
|
||||
<TableHead className="text-right">Standard Score</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{data.slice(0, 3).map((item) => (
|
||||
<TableRow key={item.timestamp}>
|
||||
<TableCell className="text-foreground-light">
|
||||
{format(new Date(item.timestamp), 'MMM d, yyyy h:mm a')}
|
||||
</TableCell>
|
||||
<TableCell className="text-right tabular-nums">{item.standard_score}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</ChartFooter>
|
||||
</ChartCard>
|
||||
</Chart>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Loaded 100 of 147 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user