---
title: Chart
description: Beautiful charts. Built using templ. Copy and paste into your apps.
---

```templ
package examples

import (
	"fmt"
	"strings"
	"time"

	"github.com/axadrn/shadcn-templ/v2/components/card"
	"github.com/axadrn/shadcn-templ/v2/components/chart"
	"github.com/axadrn/shadcn-templ/v2/utils"
)

// The docs hero demo, the pendant of chart-demo.tsx: an interactive bar
// chart over thirty days.

var chartDemoData = []chart.Datum{
	{"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},
}

var chartDemoConfig = chart.Config{
	{Key: "views", Label: "Page Views"},
	{Key: "desktop", Label: "Desktop", Color: "var(--chart-2)"},
	{Key: "mobile", Label: "Mobile", Color: "var(--chart-1)"},
}

func chartDemoShortDate(v any) string {
	t, _ := time.Parse("2006-01-02", v.(string))
	return t.Format("Jan 2")
}

func chartDemoLongDate(v any) string {
	t, _ := time.Parse("2006-01-02", v.(string))
	return t.Format("Jan 2, 2006")
}

func chartDemoTotal(series string) string {
	sum := 0
	for _, d := range chartDemoData {
		sum += d[series].(int)
	}
	s := fmt.Sprintf("%d", sum)
	var sb strings.Builder
	for i, r := range s {
		if i > 0 && (len(s)-i)%3 == 0 {
			sb.WriteRune(',')
		}
		sb.WriteRune(r)
	}
	return sb.String()
}

templ ChartDemo() {
	@card.Card(card.Props{Class: "py-0 pb-4"}) {
		@card.Header(card.HeaderProps{Class: "flex flex-col items-stretch border-b p-0! sm:flex-row"}) {
			<div class="flex flex-1 flex-col justify-center gap-1 px-6 pt-4 pb-3 sm:py-0!">
				@card.Title() {
					Bar Chart - Interactive
				}
				@card.Description() {
					Showing total visitors for the last 3 months
				}
			</div>
			<div class="flex">
				for _, series := range []string{"desktop", "mobile"} {
					<button
						data-active={ utils.IfElse(series == "desktop", "true", "false") }
						data-tui-chart-series={ series }
						class="relative z-30 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-t-0 sm:border-l sm:px-8 sm:py-6"
					>
						<span class="text-xs text-muted-foreground">
							{ chartDemoConfig.Label(series) }
						</span>
						<span class="text-lg leading-none font-bold sm:text-3xl">
							{ chartDemoTotal(series) }
						</span>
					</button>
				}
			</div>
		}
		@card.Content(card.ContentProps{Class: "px-2 sm:p-6"}) {
			@chart.Container(chart.ContainerProps{ID: "chart-demo", Config: chartDemoConfig, Class: "aspect-auto h-[250px] w-full"}) {
				for _, series := range []string{"desktop", "mobile"} {
					<div data-tui-chart-series-panel={ series } hidden?={ series != "desktop" } style="width:100%;height:100%">
						@chart.BarChart(chart.BarChartProps{
							Data:   chartDemoData,
							Margin: &chart.Margin{Left: 12, Right: 12},
						}) {
							@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
							@chart.XAxis(chart.XAxisProps{
								DataKey:       "date",
								TickMargin:    8,
								MinTickGap:    32,
								TickFormatter: chartDemoShortDate,
							})
							@chart.Tooltip(chart.TooltipProps{
								Content: chart.TooltipContentProps{
									Class:          "w-[150px]",
									NameKey:        "views",
									LabelFormatter: chartDemoLongDate,
								},
							})
							@chart.Bar(chart.BarProps{DataKey: series, Fill: "var(--color-" + series + ")"})
						}
					</div>
				}
			}
		}
	}
}
```

Introducing **Charts**. A collection of chart components that you can copy and paste into your apps.

Charts are designed to look great out of the box. They work well with the other components and are fully customizable to fit your project.

[Browse the Charts Library](/charts).

## Component

We use a small client runtime under the hood that draws Recharts compatible SVG and ports Recharts' and d3's exact algorithms.

We designed the chart component with composition in mind. **You build your charts using chart components and only bring in custom components, such as the tooltip, when and where you need it**.

```templ showLineNumbers /chart.Container/ /chart.Tooltip/
import "github.com/axadrn/shadcn-templ/v2/components/chart"

templ MyChart() {
	@chart.Container(chart.ContainerProps{Config: chartConfig}) {
		@chart.BarChart(chart.BarChartProps{Data: chartData}) {
			@chart.Bar(chart.BarProps{DataKey: "value"})
			@chart.Tooltip()
		}
	}
}
```

The chart elements mirror the Recharts composition one to one. This means you're not locked into a shadcn-templ abstraction: shadcn and Recharts chart examples translate directly, element for element.

The runtime watches the DOM, so charts arriving through htmx or Datastar swaps render out of the box, with no framework specific wiring.

**The components are yours**.

## Installation

<CodeTabs>

<TabsList>
  <TabsTrigger value="cli">Command</TabsTrigger>
  <TabsTrigger value="manual">Manual</TabsTrigger>
</TabsList>
<TabsContent value="cli">

```bash
shadcn-templ add chart
```

</TabsContent>

<TabsContent value="manual">

<Steps className="mb-0 pt-2">

<Step>Copy and paste the following code into your project.</Step>

<ComponentSource name="chart" title="components/chart/chart.templ" />

<ComponentSource name="chart" title="components/chart/chart.js" />

<Step>Add the following colors to your CSS file</Step>

```css title="assets/css/globals.css" showLineNumbers
@layer base {
  :root {
    --chart-1: oklch(0.646 0.222 41.116);
    --chart-2: oklch(0.6 0.118 184.704);
    --chart-3: oklch(0.398 0.07 227.392);
    --chart-4: oklch(0.828 0.189 84.429);
    --chart-5: oklch(0.769 0.188 70.08);
  }

  .dark {
    --chart-1: oklch(0.488 0.243 264.376);
    --chart-2: oklch(0.696 0.17 162.48);
    --chart-3: oklch(0.769 0.188 70.08);
    --chart-4: oklch(0.627 0.265 303.9);
    --chart-5: oklch(0.645 0.246 16.439);
  }
}
```

Component scripts are loaded through the shared script bundle, see [JavaScript](/docs/installation#javascript).

<Step>Update the import paths to match your project setup.</Step>

</Steps>

</TabsContent>

</CodeTabs>

## Your First Chart

Let's build your first chart. We'll build a bar chart, add a grid, axis, tooltip and legend.

<Steps>

<Step>Start by defining your data</Step>

The following data represents the number of desktop and mobile users for each month.

<Callout className="mt-4">

**Note:** Your data can be in any shape. You are not limited to the shape of the data below. Use the `DataKey` prop to map your data to the chart.

</Callout>

```go title="chart_example.templ" showLineNumbers
var chartData = []chart.Datum{
	{"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},
}
```

<Step>Define your chart config</Step>

The chart config holds configuration for the chart. This is where you place human-readable strings, such as labels, icons and color tokens for theming.

```go title="chart_example.templ" showLineNumbers
var chartConfig = chart.Config{
	{Key: "desktop", Label: "Desktop", Color: "#2563eb"},
	{Key: "mobile", Label: "Mobile", Color: "#60a5fa"},
}
```

<Step>Build your chart</Step>

You can now build your chart using the chart components.

<Callout className="mt-4 bg-amber-50 border-amber-200 dark:bg-amber-950/50 dark:border-amber-950">

**Important:** Remember to set a `min-h-[VALUE]` on the `Container` component. This is required for the chart to be responsive.

</Callout>

```templ title="chart_example.templ" showLineNumbers
@chart.Container(chart.ContainerProps{ID: "chart-example", Config: chartConfig, Class: "min-h-[200px] w-full"}) {
	@chart.BarChart(chart.BarChartProps{Data: chartData}) {
		@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
		@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
	}
}
```

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/chart"

// The "Your First Chart" steps from the chart docs, the pendants of
// chart-example.tsx and the grid, axis, tooltip and legend variants.

var chartExampleData = []chart.Datum{
	{"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},
}

var chartExampleConfig = chart.Config{
	{Key: "desktop", Label: "Desktop", Color: "#2563eb"},
	{Key: "mobile", Label: "Mobile", Color: "#60a5fa"},
}

func chartExampleMonthShort(v any) string {
	return v.(string)[:3]
}

templ ChartExample() {
	@chart.Container(chart.ContainerProps{ID: "chart-example", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleGrid() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-grid", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleAxis() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-axis", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleTooltip() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-tooltip", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Tooltip()
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleLegend() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-legend", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Tooltip()
			@chart.Legend()
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}
```

</Steps>

### Add a Grid

Let's add a grid to the chart.

<Steps className="mb-0 pt-2">

<Step>Add the `CartesianGrid` component to your chart.</Step>

```templ showLineNumbers {3}
@chart.Container(chart.ContainerProps{ID: "chart-example", Config: chartConfig, Class: "min-h-[200px] w-full"}) {
	@chart.BarChart(chart.BarChartProps{Data: chartData}) {
		@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
		@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
		@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
	}
}
```

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/chart"

// The "Your First Chart" steps from the chart docs, the pendants of
// chart-example.tsx and the grid, axis, tooltip and legend variants.

var chartExampleData = []chart.Datum{
	{"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},
}

var chartExampleConfig = chart.Config{
	{Key: "desktop", Label: "Desktop", Color: "#2563eb"},
	{Key: "mobile", Label: "Mobile", Color: "#60a5fa"},
}

func chartExampleMonthShort(v any) string {
	return v.(string)[:3]
}

templ ChartExample() {
	@chart.Container(chart.ContainerProps{ID: "chart-example", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleGrid() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-grid", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleAxis() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-axis", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleTooltip() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-tooltip", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Tooltip()
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleLegend() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-legend", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Tooltip()
			@chart.Legend()
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}
```

</Steps>

### Add an Axis

To add an x-axis to the chart, we'll use the `XAxis` component.

<Steps className="mb-0 pt-2">

<Step>Define a tick formatter</Step>

The `TickFormatter` is a plain Go function. This one shortens the month names to three letters.

```go title="chart_example.templ" showLineNumbers
func monthShort(v any) string {
	return v.(string)[:3]
}
```

<Step>Add the `XAxis` component to your chart.</Step>

```templ showLineNumbers {4-8}
@chart.Container(chart.ContainerProps{ID: "chart-example", Config: chartConfig, Class: "min-h-[200px] w-full"}) {
	@chart.BarChart(chart.BarChartProps{Data: chartData}) {
		@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
		@chart.XAxis(chart.XAxisProps{
			DataKey:       "month",
			TickMargin:    10,
			TickFormatter: monthShort,
		})
		@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
		@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
	}
}
```

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/chart"

// The "Your First Chart" steps from the chart docs, the pendants of
// chart-example.tsx and the grid, axis, tooltip and legend variants.

var chartExampleData = []chart.Datum{
	{"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},
}

var chartExampleConfig = chart.Config{
	{Key: "desktop", Label: "Desktop", Color: "#2563eb"},
	{Key: "mobile", Label: "Mobile", Color: "#60a5fa"},
}

func chartExampleMonthShort(v any) string {
	return v.(string)[:3]
}

templ ChartExample() {
	@chart.Container(chart.ContainerProps{ID: "chart-example", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleGrid() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-grid", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleAxis() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-axis", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleTooltip() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-tooltip", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Tooltip()
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleLegend() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-legend", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Tooltip()
			@chart.Legend()
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}
```

</Steps>

### Add Tooltip

So far we've only used components from the chart element set. They look great out of the box thanks to some customization in the `chart` component.

To add a tooltip, we'll use the custom `Tooltip` component from `chart`.

<Steps className="mb-0 pt-2">

<Step>Add the `Tooltip` component to your chart.</Step>

```templ showLineNumbers {9}
@chart.Container(chart.ContainerProps{ID: "chart-example", Config: chartConfig, Class: "min-h-[200px] w-full"}) {
	@chart.BarChart(chart.BarChartProps{Data: chartData}) {
		@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
		@chart.XAxis(chart.XAxisProps{
			DataKey:       "month",
			TickMargin:    10,
			TickFormatter: monthShort,
		})
		@chart.Tooltip()
		@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
		@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
	}
}
```

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/chart"

// The "Your First Chart" steps from the chart docs, the pendants of
// chart-example.tsx and the grid, axis, tooltip and legend variants.

var chartExampleData = []chart.Datum{
	{"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},
}

var chartExampleConfig = chart.Config{
	{Key: "desktop", Label: "Desktop", Color: "#2563eb"},
	{Key: "mobile", Label: "Mobile", Color: "#60a5fa"},
}

func chartExampleMonthShort(v any) string {
	return v.(string)[:3]
}

templ ChartExample() {
	@chart.Container(chart.ContainerProps{ID: "chart-example", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleGrid() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-grid", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleAxis() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-axis", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleTooltip() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-tooltip", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Tooltip()
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleLegend() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-legend", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Tooltip()
			@chart.Legend()
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}
```

Hover to see the tooltips. Easy, right? One component, and we've got a beautiful tooltip.

</Steps>

### Add Legend

We'll do the same for the legend. We'll use the `Legend` component from `chart`.

<Steps className="mb-0 pt-2">

<Step>Add the `Legend` component to your chart.</Step>

```templ showLineNumbers {10}
@chart.Container(chart.ContainerProps{ID: "chart-example", Config: chartConfig, Class: "min-h-[200px] w-full"}) {
	@chart.BarChart(chart.BarChartProps{Data: chartData}) {
		@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
		@chart.XAxis(chart.XAxisProps{
			DataKey:       "month",
			TickMargin:    10,
			TickFormatter: monthShort,
		})
		@chart.Tooltip()
		@chart.Legend()
		@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
		@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
	}
}
```

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/chart"

// The "Your First Chart" steps from the chart docs, the pendants of
// chart-example.tsx and the grid, axis, tooltip and legend variants.

var chartExampleData = []chart.Datum{
	{"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},
}

var chartExampleConfig = chart.Config{
	{Key: "desktop", Label: "Desktop", Color: "#2563eb"},
	{Key: "mobile", Label: "Mobile", Color: "#60a5fa"},
}

func chartExampleMonthShort(v any) string {
	return v.(string)[:3]
}

templ ChartExample() {
	@chart.Container(chart.ContainerProps{ID: "chart-example", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleGrid() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-grid", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleAxis() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-axis", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleTooltip() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-tooltip", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Tooltip()
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}

templ ChartExampleLegend() {
	@chart.Container(chart.ContainerProps{ID: "chart-example-legend", Config: chartExampleConfig, Class: "min-h-[200px] w-full"}) {
		@chart.BarChart(chart.BarChartProps{Data: chartExampleData}) {
			@chart.CartesianGrid(chart.CartesianGridProps{Vertical: chart.Bool(false)})
			@chart.XAxis(chart.XAxisProps{
				DataKey:       "month",
				TickMargin:    10,
				TickFormatter: chartExampleMonthShort,
			})
			@chart.Tooltip()
			@chart.Legend()
			@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)", Radius: 4})
			@chart.Bar(chart.BarProps{DataKey: "mobile", Fill: "var(--color-mobile)", Radius: 4})
		}
	}
}
```

</Steps>

Done. You've built your first chart! What's next?

- [Themes and Colors](/docs/components/chart#theming)
- [Tooltip](/docs/components/chart#tooltip)
- [Legend](/docs/components/chart#legend)

## Chart Config

The chart config is where you define the labels, icons and colors for a chart.

It is intentionally decoupled from chart data.

This allows you to share config and color tokens between charts. It can also work independently for cases where your data or color tokens live remotely or in a different format.

```go showLineNumbers /chart.Config/
import "github.com/axadrn/shadcn-templ/v2/components/icon"

var chartConfig = chart.Config{
	{
		Key:   "desktop",
		Label: "Desktop",
		Icon:  icon.Monitor(),
		// A color like "hsl(220, 98%, 61%)" or "var(--color-name)"
		Color: "#2563eb",
		// OR a theme with light and dark colors
		Theme: &chart.SeriesTheme{
			Light: "#2563eb",
			Dark:  "#dc2626",
		},
	},
}
```

## Theming

Charts have built-in support for theming. You can use css variables (recommended) or color values in any color format, such as hex, hsl or oklch.

### CSS Variables

<Steps className="mb-0 pt-2">

<Step>Define your colors in your css file</Step>

```css title="assets/css/globals.css" showLineNumbers
@layer base {
  :root {
    --chart-1: oklch(0.646 0.222 41.116);
    --chart-2: oklch(0.6 0.118 184.704);
  }

  .dark {
    --chart-1: oklch(0.488 0.243 264.376);
    --chart-2: oklch(0.696 0.17 162.48);
  }
}
```

<Step>Add the color to your `chartConfig`</Step>

```go showLineNumbers
var chartConfig = chart.Config{
	{Key: "desktop", Label: "Desktop", Color: "var(--chart-1)"},
	{Key: "mobile", Label: "Mobile", Color: "var(--chart-2)"},
}
```

</Steps>

### hex, hsl or oklch

You can also define your colors directly in the chart config. Use the color format you prefer.

```go showLineNumbers
var chartConfig = chart.Config{
	{Key: "desktop", Label: "Desktop", Color: "#2563eb"},
	{Key: "mobile", Label: "Mobile", Color: "hsl(220, 98%, 61%)"},
	{Key: "tablet", Label: "Tablet", Color: "oklch(0.5 0.2 240)"},
	{Key: "laptop", Label: "Laptop", Color: "var(--chart-2)"},
}
```

### Using Colors

To use the theme colors in your chart, reference the colors using the format `var(--color-KEY)`.

#### Components

```templ
@chart.Bar(chart.BarProps{DataKey: "desktop", Fill: "var(--color-desktop)"})
```

#### Chart Data

```go showLineNumbers
var chartData = []chart.Datum{
	{"browser": "chrome", "visitors": 275, "fill": "var(--color-chrome)"},
	{"browser": "safari", "visitors": 200, "fill": "var(--color-safari)"},
}
```

#### Tailwind

Every `Class` prop takes Tailwind utility classes, so you can also color chart parts with the arbitrary property syntax.

```templ
@chart.LabelList(chart.LabelListProps{Class: "fill-(--color-desktop)"})
```

## Tooltip

A chart tooltip contains a label, name, indicator and value. You can use a combination of these to customize your tooltip.

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/utils"

// The pendant of chart-tooltip-demo.tsx: the static tooltip showcase in
// the chart docs, hand built tooltip boxes with the annotation arrows.

type chartTooltipItem struct {
	Name string
	// Value is preformatted like toLocaleString, e.g. "12,486".
	Value string
	Fill  string
}

// chartTooltipIndicator is the indicator class set of the source's cn
// call: dot, line and dashed, with the dashed inset when the label nests.
func chartTooltipIndicator(indicator string, nestLabel bool) string {
	cls := "shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)"
	switch indicator {
	case "line":
		cls += " w-1"
	case "dashed":
		cls += " w-0 border-[1.5px] border-dashed bg-transparent"
		if nestLabel {
			cls += " my-0.5"
		}
	default:
		cls += " h-2.5 w-2.5"
	}
	return cls
}

// chartTooltipBox is the source's local TooltipDemo component.
templ chartTooltipBox(label string, hideLabel bool, indicator string, class string, payload []chartTooltipItem) {
	{{ nestLabel := len(payload) == 1 && indicator != "dot" }}
	<div
		class={ utils.CN(
			"grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl transition-all ease-in-out hover:-translate-y-0.5",
			class,
		) }
	>
		if !nestLabel && !hideLabel {
			<div class="font-medium">{ label }</div>
		}
		<div class="grid gap-1.5">
			for _, item := range payload {
				<div
					class={ "flex w-full items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground" + utils.IfElse(indicator == "dot" || indicator == "", " items-center", "") }
				>
					<div
						class={ chartTooltipIndicator(indicator, nestLabel) }
						style={ templ.SafeCSS("--color-bg:" + item.Fill + ";--color-border:" + item.Fill) }
					></div>
					<div class={ "flex flex-1 justify-between leading-none " + utils.IfElse(nestLabel, "items-end", "items-center") }>
						<div class="grid gap-1.5">
							if nestLabel && !hideLabel {
								<div class="font-medium">{ label }</div>
							}
							<span class="text-muted-foreground">{ item.Name }</span>
						</div>
						<span class="font-mono font-medium text-foreground tabular-nums">{ item.Value }</span>
					</div>
				</div>
			}
		</div>
	</div>
}

templ ChartTooltipExample() {
	<div class="grid aspect-video w-full max-w-md justify-center text-foreground md:grid-cols-2 [&>div]:relative [&>div]:flex [&>div]:h-[137px] [&>div]:w-[224px] [&>div]:items-center [&>div]:justify-center [&>div]:p-4">
		<div>
			<div class="absolute top-[45px] left-[-35px] z-10 text-sm font-medium">
				Label
			</div>
			<svg
				xmlns="http://www.w3.org/2000/svg"
				viewBox="0 0 193 40"
				width="50"
				height="12"
				fill="none"
				class="absolute top-[50px] left-[5px] z-10"
			>
				<g clip-path="url(#a)">
					<path
						fill="currentColor"
						d="M173.928 21.13C115.811 44.938 58.751 45.773 0 26.141c4.227-4.386 7.82-2.715 10.567-1.88 21.133 5.64 42.9 6.266 64.457 7.101 31.066 1.253 60.441-5.848 89.183-17.335 1.268-.418 2.325-1.253 4.861-2.924-14.582-2.924-29.165 2.089-41.845-3.76.212-.835.212-1.879.423-2.714 9.51-.627 19.231-1.253 28.742-2.089 9.51-.835 18.808-1.88 28.318-2.506 6.974-.418 9.933 2.924 7.397 9.19-3.17 8.145-7.608 15.664-11.623 23.391-.423.836-1.057 1.88-1.902 2.298-2.325.835-4.65 1.044-7.186 1.67-.422-2.088-1.479-4.386-1.268-6.265.423-2.506 1.902-4.595 3.804-9.19Z"
					></path>
				</g>
				<defs>
					<clipPath id="a">
						<path fill="currentColor" d="M0 0h193v40H0z"></path>
					</clipPath>
				</defs>
			</svg>
			@chartTooltipBox("Page Views", false, "dot", "w-[8rem]", []chartTooltipItem{
				{Name: "Desktop", Value: "186", Fill: "var(--chart-1)"},
				{Name: "Mobile", Value: "80", Fill: "var(--chart-2)"},
			})
		</div>
		<div class="items-end">
			<div class="absolute top-[0px] left-[122px] z-10 text-sm font-medium">
				Name
			</div>
			<svg
				xmlns="http://www.w3.org/2000/svg"
				width="35"
				height="42"
				fill="none"
				viewBox="0 0 122 148"
				class="absolute top-[10px] left-[85px] z-10 -scale-x-100"
			>
				<g clip-path="url(#ab)">
					<path
						fill="currentColor"
						d="M0 2.65c6.15-4.024 12.299-2.753 17.812-.847a115.56 115.56 0 0 1 21.84 10.59C70.4 32.727 88.849 61.744 96.483 97.54c1.908 9.108 2.544 18.639 3.817 29.017 8.481-4.871 12.934-14.402 21.416-19.909 1.061 4.236-1.06 6.989-2.756 9.319-6.998 9.531-14.207 19.062-21.63 28.382-3.604 4.448-6.36 4.871-10.177 1.059-8.058-7.837-12.935-17.368-14.42-28.382 0-.424.636-1.059 1.485-2.118 9.118 2.33 6.997 13.979 14.843 18.215 3.393-14.614.848-28.593-2.969-42.149-4.029-14.19-9.33-27.746-17.812-39.82-8.27-11.86-18.66-21.392-30.11-30.287C26.93 11.758 14.207 6.039 0 2.65Z"
					></path>
				</g>
				<defs>
					<clipPath id="ab">
						<path fill="currentColor" d="M0 0h122v148H0z"></path>
					</clipPath>
				</defs>
			</svg>
			@chartTooltipBox("Browser", true, "dashed", "w-[8rem]", []chartTooltipItem{
				{Name: "Chrome", Value: "1,286", Fill: "var(--chart-3)"},
				{Name: "Firefox", Value: "1,000", Fill: "var(--chart-4)"},
			})
		</div>
		<div class="hidden! md:flex!">
			@chartTooltipBox("Page Views", false, "line", "w-[9rem]", []chartTooltipItem{
				{Name: "Desktop", Value: "12,486", Fill: "var(--chart-3)"},
			})
		</div>
		<div class="items-start! justify-start!">
			<div class="absolute top-[60px] left-[50px] z-10 text-sm font-medium">
				Indicator
			</div>
			@chartTooltipBox("Browser", true, "dot", "w-[8rem]", []chartTooltipItem{
				{Name: "Chrome", Value: "1,286", Fill: "var(--chart-1)"},
			})
			<svg
				xmlns="http://www.w3.org/2000/svg"
				width="15"
				height="34"
				fill="none"
				viewBox="0 0 75 175"
				class="absolute top-[38px] left-[30px] z-10 rotate-[-40deg]"
			>
				<g clip-path="url(#abc)">
					<path
						fill="currentColor"
						d="M20.187 175c-4.439-2.109-7.186-2.531-8.032-4.008-3.17-5.484-6.763-10.968-8.454-17.084-5.073-16.242-4.439-32.694-1.057-49.146 5.707-28.053 18.388-52.942 34.24-76.565 1.692-2.531 3.171-5.063 4.862-7.805 0-.21-.211-.632-.634-1.265-4.65 1.265-9.511 2.53-14.161 3.585-2.537.422-5.496.422-8.032-.421-1.48-.422-3.593-2.742-3.593-4.219 0-1.898 1.48-4.218 2.747-5.906 1.057-1.054 2.96-1.265 4.65-1.687C35.406 7.315 48.088 3.729 60.98.776c10.99-2.53 14.584 1.055 13.95 11.812-.634 11.18-.846 22.358-1.268 33.326-.212 3.375-.846 6.96-1.268 10.757-8.878-4.007-8.878-4.007-12.048-38.177C47.03 33.259 38.153 49.289 29.91 65.741 21.667 82.193 16.17 99.49 13.212 117.84c-2.959 18.984.634 36.912 6.975 57.161Z"
					></path>
				</g>
				<defs>
					<clipPath id="abc">
						<path fill="currentColor" d="M0 0h75v175H0z"></path>
					</clipPath>
				</defs>
			</svg>
		</div>
	</div>
}
```

The tooltip trails the cursor inside the plot area and snaps to the active data point.

You can turn the label and the indicator on and off using the `HideLabel` and `HideIndicator` props and customize the indicator style using the `Indicator` prop. Use `LabelKey` and `NameKey` to use a custom key for the tooltip label and name.

Chart comes with the `Tooltip` component and its `TooltipContentProps`, the pendant of `ChartTooltip` and `ChartTooltipContent`. You can use these to add tooltips to your chart.

```templ
@chart.Tooltip(chart.TooltipProps{
	Cursor:  chart.Bool(false),
	Content: chart.TooltipContentProps{Indicator: "line"},
})
```

### Props

`chart.TooltipProps`

| Prop           | Type                | Description                                           |
| :------------- | :------------------ | :---------------------------------------------------- |
| `Cursor`       | *bool               | Hover cursor, defaults to on.                         |
| `Content`      | TooltipContentProps | The rendered tooltip content.                         |
| `DefaultIndex` | *int                | Shows the tooltip on mount at that category.          |

`chart.TooltipContentProps`

| Prop             | Type                     | Description                                                    |
| :--------------- | :----------------------- | :------------------------------------------------------------- |
| `Indicator`      | `dot` `line` or `dashed` | The indicator style for the tooltip.                           |
| `LabelKey`       | string                   | Config key to use for the tooltip label.                       |
| `HideLabel`      | bool                     | Whether to hide the label.                                     |
| `HideIndicator`  | bool                     | Whether to hide the indicator.                                 |
| `NameKey`        | string                   | Config key to use for the series name.                         |
| `LabelFormatter` | func(any) string         | Formats the tooltip label.                                     |
| `Formatter`      | func(value any, name string, item chart.Datum, index int) templ.Component | Replaces a row's default markup, rendered per data row. |
| `Class`          | string                   | Extra classes for the tooltip content.                         |
| `LabelClassName`     | string                   | Extra classes for the tooltip label.                           |
| `Color`          | string                   | Overrides the indicator color for every row.                   |

### Colors

Colors are automatically referenced from the chart config.

### Custom

To use a custom key for tooltip label and names, use the `LabelKey` and `NameKey` props.

```go showLineNumbers /browser/
var chartData = []chart.Datum{
	{"browser": "chrome", "visitors": 187, "fill": "var(--color-chrome)"},
	{"browser": "safari", "visitors": 200, "fill": "var(--color-safari)"},
}

var chartConfig = chart.Config{
	{Key: "visitors", Label: "Total Visitors"},
	{Key: "chrome", Label: "Chrome", Color: "var(--chart-1)"},
	{Key: "safari", Label: "Safari", Color: "var(--chart-2)"},
}
```

```templ
@chart.Tooltip(chart.TooltipProps{
	Content: chart.TooltipContentProps{LabelKey: "visitors", NameKey: "browser"},
})
```

This will use `Total Visitors` for label and `Chrome` and `Safari` for the tooltip names.

## Legend

You can use the `Legend` component to add a legend to your chart.

```templ
@chart.Legend()
```

It renders the label and color of every series, and the colors are automatically referenced from the chart config. When a config entry sets an `Icon`, it replaces the color swatch.

### Props

`chart.LegendProps`

| Prop            | Type   | Description                                                     |
| :-------------- | :----- | :-------------------------------------------------------------- |
| `NameKey`       | string | Config key to use for the legend labels.                        |
| `Class`         | string | Extra classes for the legend content.                           |
| `VerticalAlign` | string | `top` places the legend above the plot, everything else below.  |
| `HideIcon`      | bool   | Drops the config icon and falls back to the color swatch.       |

### Custom

To use a custom key for the legend names, use the `NameKey` prop.

```go showLineNumbers /browser/
var chartData = []chart.Datum{
	{"browser": "chrome", "visitors": 275, "fill": "var(--color-chrome)"},
	{"browser": "safari", "visitors": 200, "fill": "var(--color-safari)"},
}

var chartConfig = chart.Config{
	{Key: "chrome", Label: "Chrome", Color: "var(--chart-1)"},
	{Key: "safari", Label: "Safari", Color: "var(--chart-2)"},
}
```

```templ
@chart.Legend(chart.LegendProps{NameKey: "browser"})
```

This will use the config labels of the `browser` values for the legend names.

## Accessibility

Set `AccessibilityLayer: true` on the chart root to enable the keyboard layer, the pendant of Recharts' `accessibilityLayer` prop.

```templ
@chart.BarChart(chart.BarChartProps{AccessibilityLayer: true, Data: chartData}) {
	...
}
```

The chart becomes focusable, focusing it shows the tooltip and the left and right arrow keys walk the tooltip through the categories.
