# Line Chart

> Show trends and rates of change across an ordered dimension.

Source: https://www.honestui.com/docs/charts/line-chart/static

### Basic Chart

```tsx
"use client";

import { LineChart, type ChartConfig } from "honestui/charts";

// Scenario: Exchange volume
const data = [
  { month: "January", buys: 482, sells: 119 },
  { month: "February", buys: 1209, sells: 298 },
  { month: "March", buys: 732, sells: 192 },
  { month: "April", buys: 900, sells: 256 },
  { month: "May", buys: 638, sells: 217 },
  { month: "June", buys: 1082, sells: 267 },
  { month: "July", buys: 574, sells: 154 },
  { month: "August", buys: 1296, sells: 342 },
  { month: "September", buys: 891, sells: 243 },
  { month: "October", buys: 748, sells: 244 },
  { month: "November", buys: 1122, sells: 304 },
  { month: "December", buys: 420, sells: 106 },
];

const chartConfig = {
  buys: {
    label: "Buys",
    colors: {
      light: ["#047857"],
      dark: ["#10b981"],
    },
  },
  sells: {
    label: "Sells",
    colors: {
      light: ["#be123c"],
      dark: ["#f43f5e"],
    },
  },
} satisfies ChartConfig;

export function ExampleLineChart() {
  return (
    <LineChart
      data={data}
      config={chartConfig}
      className="h-full w-full p-4"
      xDataKey="month"
    >
      <LineChart.XAxis dataKey="month" tickFormatter={(value) => value.substring(0, 3)} />
      <LineChart.Brush formatLabel={(value) => String(value).substring(0, 3)} />
      <LineChart.Legend isClickable />
      <LineChart.Tooltip />
      <LineChart.Line dataKey="buys" strokeVariant="solid" isClickable>
        <LineChart.Dot variant="border" />
        <LineChart.ActiveDot variant="colored-border" />
      </LineChart.Line>
      <LineChart.Line dataKey="sells" strokeVariant="solid" isClickable>
        <LineChart.Dot variant="border" />
        <LineChart.ActiveDot variant="colored-border" />
      </LineChart.Line>
    </LineChart>
  );
}

```

## Overview [#overview]

Use a line chart to show trends, movement, and rate of change across an ordered dimension such as time. Use dots when individual observations matter and a brush when readers need to inspect a dense range.

## Anatomy [#anatomy]

`LineChart` owns the data, configuration, selection, and loading state. Add axes and a grid for context, one or more `Line` parts for the series, and optional `Dot`, `Legend`, `Tooltip`, and `Brush` parts for exploration.

## Accessibility [#accessibility]

Canvas charts need a nearby text summary or data table when exact values or trends are important. Use distinguishable stroke styles and clear series labels so meaning does not depend on color alone. Tooltip, brush, and direct line selection are pointer-operated; provide equivalent controls when those interactions are required.

## Installation [#installation]

<CommandBlock commands="[&#x22;honestui&#x22;]" />

## Usage [#usage]

`<LineChart>` owns the data, theme configuration, and shared state. Add axes, a grid, legend, tooltip, brush, and one or more `<LineChart.Line>` parts as needed. Each Line sets its own stroke, curve, markers, buffer treatment, and selection behavior.

```tsx
import { LineChart, type ChartConfig } from "honestui/charts";
```

```tsx
<LineChart data={data} config={chartConfig} curveType="monotone">
  <LineChart.Grid />
  <LineChart.XAxis dataKey="month" />
  <LineChart.YAxis />
  <LineChart.Legend isClickable />
  <LineChart.Tooltip />
  <LineChart.Line dataKey="buys" strokeVariant="solid" isClickable>
    <LineChart.Dot variant="border" />
    <LineChart.ActiveDot variant="colored-border" />
  </LineChart.Line>
  <LineChart.Line dataKey="sells" strokeVariant="dashed" glowing>
    <LineChart.ActiveDot variant="default" />
  </LineChart.Line>
</LineChart>
```

The root compiles its children into an ECharts option and renders the plot on a canvas. The `config` prop maps each series data key to its label and theme colors. See [Chart Config](/docs/charts/chart-config) for the complete shape.

> 
  
    Canvas rendering has a few implementation details to keep in mind: multi-color gradients tint each dot with the color at its x-position; the glow is layered gradient strokes stacked under the line, following the series' color in place of an SVG blur filter; and the zoom brush is a themed mini chart driven by ECharts' native `dataZoom` rather than the custom `HonestBrush`.
  


### Interactive Selection [#interactive-selection]

Add `isClickable` to any `<Line>` (and to `<Legend>`) to make those series selectable, then handle events via the `onSelectionChange` callback on `<LineChart>`:

```tsx
<LineChart
  data={data}
  config={chartConfig}
  onSelectionChange={(selectedDataKey) => {
    if (selectedDataKey) {
      console.log("Selected:", selectedDataKey);
    } else {
      console.log("Deselected");
    }
  }}
>
  <LineChart.XAxis dataKey="month" />
  <LineChart.Legend isClickable />
  <LineChart.Tooltip />
  <LineChart.Line dataKey="buys" strokeVariant="solid" isClickable />
  <LineChart.Line dataKey="sells" strokeVariant="solid" isClickable />
</LineChart>
```

### Loading State [#loading-state]

### isLoading='true'

```tsx
"use client";

import { LineChart, type ChartConfig } from "honestui/charts";

// Scenario: Delivery distance
const data: { month: string; urban: number; rural: number }[] = [];

const chartConfig = {
  urban: {
    label: "Urban",
    colors: {
      light: ["#047857"],
      dark: ["#10b981"],
    },
  },
  rural: {
    label: "Rural",
    colors: {
      light: ["#be123c"],
      dark: ["#f43f5e"],
    },
  },
} satisfies ChartConfig;

export function ExampleLineChart() {
  return (
    <LineChart
      data={data} // if isLoading is true, pass empty array → i.e isLoading ? [] : data
      config={chartConfig}
      className="h-full w-full p-4"
      isLoading={true} // [!code highlight]
      curveType="bump"
    >
      <LineChart.XAxis dataKey="month" tickFormatter={(value) => value.substring(0, 3)} />
      <LineChart.YAxis dataKey="urban" />
      <LineChart.Legend isClickable />
      <LineChart.Tooltip />
      <LineChart.Line dataKey="urban" strokeVariant="solid" isClickable>
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
      <LineChart.Line dataKey="rural" strokeVariant="solid" isClickable>
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
    </LineChart>
  );
}

```

> 
  
    Pass `isLoading` to show an animated skeleton, `loadingPoints` to set how many points it draws, and `curveType` to match the real chart's curve.
  


### Buffer Line [#buffer-line]

### enableBufferLine='true'

```tsx
"use client";

import { LineChart, type ChartConfig } from "honestui/charts";

// Scenario: Active subscriptions
const data = [
  { month: "January", active: 246, churned: 105 },
  { month: "February", active: 636, churned: 284 },
  { month: "March", active: 389, churned: 178 },
  { month: "April", active: 483, churned: 242 },
  { month: "May", active: 328, churned: 203 },
  { month: "June", active: 569, churned: 253 },
  { month: "July", active: 305, churned: 140 },
  { month: "August", active: 693, churned: 328 },
  { month: "September", active: 462, churned: 229 },
  { month: "October", active: 392, churned: 230 },
  { month: "November", active: 595, churned: 290 },
  { month: "December", active: 228, churned: 92 },
];

const chartConfig = {
  active: {
    label: "Active",
    colors: {
      light: ["#047857"],
      dark: ["#10b981"],
    },
  },
  churned: {
    label: "Churned",
    colors: {
      light: ["#be123c"],
      dark: ["#f43f5e"],
    },
  },
} satisfies ChartConfig;

export function ExampleLineChart() {
  return (
    <LineChart
      data={data}
      config={chartConfig}
      className="h-full w-full p-4"
      xDataKey="month"
    >
      <LineChart.XAxis dataKey="month" tickFormatter={(value) => value.substring(0, 3)} />
      <LineChart.Brush />
      <LineChart.Legend isClickable />
      <LineChart.Tooltip />
      <LineChart.Line
        dataKey="active"
        strokeVariant="solid"
        enableBufferLine // [!code highlight]
        isClickable
      >
        <LineChart.Dot variant="border" />
        <LineChart.ActiveDot variant="colored-border" />
      </LineChart.Line>
      <LineChart.Line
        dataKey="churned"
        strokeVariant="solid"
        enableBufferLine // [!code highlight]
        isClickable
      >
        <LineChart.Dot variant="border" />
        <LineChart.ActiveDot variant="colored-border" />
      </LineChart.Line>
    </LineChart>
  );
}

```

> 
  
    With `enableBufferLine`, each line's last segment renders dashed while the rest stays solid, useful for marking projected, estimated, or incomplete data at the end of a series, as in financial charts and forecasting dashboards.
  


### Hover Reveal [#hover-reveal]

### enableHoverReveal='true'

```tsx
"use client";

import { LineChart, type ChartConfig } from "honestui/charts";

// Scenario: Call center demand
const data = [
  { month: "January", incoming: 374, answered: 261 },
  { month: "February", incoming: 908, answered: 661 },
  { month: "March", incoming: 563, answered: 412 },
  { month: "April", incoming: 688, answered: 547 },
  { month: "May", incoming: 488, answered: 450 },
  { month: "June", incoming: 815, answered: 600 },
  { month: "July", incoming: 447, answered: 333 },
  { month: "August", incoming: 979, answered: 753 },
  { month: "September", incoming: 673, answered: 516 },
  { month: "October", incoming: 571, answered: 511 },
  { month: "November", incoming: 848, answered: 686 },
  { month: "December", incoming: 338, answered: 223 },
];

const chartConfig = {
  incoming: {
    label: "Incoming",
    colors: {
      light: ["#047857"],
      dark: ["#10b981"],
    },
  },
  answered: {
    label: "Answered",
    colors: {
      light: ["#be123c"],
      dark: ["#f43f5e"],
    },
  },
} satisfies ChartConfig;

export function ExampleLineChart() {
  return (
    <LineChart
      data={data}
      config={chartConfig}
      className="h-full w-full p-4"
      enableHoverReveal // [!code highlight]
    >
      <LineChart.Grid />
      <LineChart.XAxis dataKey="month" tickFormatter={(value) => value.substring(0, 3)} />
      <LineChart.Legend />
      <LineChart.Tooltip />
      <LineChart.Line dataKey="incoming" strokeVariant="solid">
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
      <LineChart.Line dataKey="answered" strokeVariant="solid">
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
    </LineChart>
  );
}

```

> 
  
    With `enableHoverReveal`, hovering colors each line only up to the pointer's position and mutes everything past it to a neutral gray, with the active dot riding the cursor, a scrubbing effect for reading a series left-to-right. When not hovering, the chart looks completely normal.
  


## Examples [#examples]

Examples with different settings. Change `strokeVariant` on a `<Line>` or `curveType` on the chart to restyle it.

### Gradient Colors [#gradient-colors]

### gradient colors

```tsx
"use client";

import { LineChart, type ChartConfig } from "honestui/charts";

// Scenario: Ocean conditions
const data = [
  { month: "January", waveHeight: 340, swellPeriod: 186 },
  { month: "February", waveHeight: 827, swellPeriod: 463 },
  { month: "March", waveHeight: 514, swellPeriod: 293 },
  { month: "April", waveHeight: 629, swellPeriod: 389 },
  { month: "May", waveHeight: 444, swellPeriod: 324 },
  { month: "June", waveHeight: 742, swellPeriod: 419 },
  { month: "July", waveHeight: 409, swellPeriod: 237 },
  { month: "August", waveHeight: 892, swellPeriod: 528 },
  { month: "September", waveHeight: 612, swellPeriod: 368 },
  { month: "October", waveHeight: 520, swellPeriod: 366 },
  { month: "November", waveHeight: 773, swellPeriod: 477 },
  { month: "December", waveHeight: 310, swellPeriod: 162 },
];

const chartConfig = {
  waveHeight: {
    label: "Wave height",
    colors: {
      light: ["red", "orange", "rosybrown", "purple", "blue"], // [!code highlight]
      dark: ["red", "orange", "rosybrown", "purple", "blue"], // [!code highlight]
    },
  },
  swellPeriod: {
    label: "Swell period",
    colors: {
      light: ["gray"],
      dark: ["gray"],
    },
  },
} satisfies ChartConfig;

export function ExampleLineChart() {
  return (
    <LineChart data={data} config={chartConfig} className="h-full w-full p-4">
      <LineChart.XAxis dataKey="month" tickFormatter={(value) => value.substring(0, 3)} />
      <LineChart.Legend isClickable />
      <LineChart.Tooltip />
      <LineChart.Line dataKey="waveHeight" strokeVariant="solid" isClickable>
        <LineChart.Dot variant="colored-border" />
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
      <LineChart.Line dataKey="swellPeriod" strokeVariant="solid" isClickable>
        <LineChart.Dot variant="colored-border" />
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
    </LineChart>
  );
}

```

### gradient colors - bump

```tsx
"use client";

import { LineChart, type ChartConfig } from "honestui/charts";

// Scenario: Newsletter growth
const data = [
  { month: "January", subscribers: 307, unsubscribes: 169 },
  { month: "February", subscribers: 745, unsubscribes: 422 },
  { month: "March", subscribers: 465, unsubscribes: 268 },
  { month: "April", subscribers: 569, unsubscribes: 356 },
  { month: "May", subscribers: 399, unsubscribes: 297 },
  { month: "June", subscribers: 669, unsubscribes: 381 },
  { month: "July", subscribers: 370, unsubscribes: 216 },
  { month: "August", subscribers: 806, unsubscribes: 482 },
  { month: "September", subscribers: 551, unsubscribes: 337 },
  { month: "October", subscribers: 470, unsubscribes: 336 },
  { month: "November", subscribers: 697, unsubscribes: 434 },
  { month: "December", subscribers: 283, unsubscribes: 148 },
];

const chartConfig = {
  subscribers: {
    label: "Subscribers",
    colors: {
      light: ["red", "orange", "rosybrown", "purple", "blue"],
      dark: ["red", "orange", "rosybrown", "purple", "blue"],
    },
  },
  unsubscribes: {
    label: "Unsubscribes",
    colors: {
      light: ["gray"],
      dark: ["gray"],
    },
  },
} satisfies ChartConfig;

export function ExampleLineChart() {
  return (
    <LineChart
      data={data}
      config={chartConfig}
      className="h-full w-full p-4"
      curveType="bump" // [!code highlight]
    >
      <LineChart.XAxis dataKey="month" tickFormatter={(value) => value.substring(0, 3)} />
      <LineChart.Legend isClickable />
      <LineChart.Tooltip />
      <LineChart.Line dataKey="subscribers" strokeVariant="solid" isClickable>
        <LineChart.Dot variant="colored-border" />
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
      <LineChart.Line dataKey="unsubscribes" strokeVariant="solid" isClickable>
        <LineChart.Dot variant="colored-border" />
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
    </LineChart>
  );
}

```

### Curve Types [#curve-types]

### curveType='bump'

```tsx
"use client";

import { LineChart, type ChartConfig } from "honestui/charts";

// Scenario: River levels
const data = [
  { month: "January", upstream: 280, downstream: 122 },
  { month: "February", upstream: 718, downstream: 325 },
  { month: "March", upstream: 438, downstream: 204 },
  { month: "April", upstream: 542, downstream: 275 },
  { month: "May", upstream: 372, downstream: 230 },
  { month: "June", upstream: 642, downstream: 291 },
  { month: "July", upstream: 343, downstream: 161 },
  { month: "August", upstream: 779, downstream: 374 },
  { month: "September", upstream: 524, downstream: 260 },
  { month: "October", upstream: 443, downstream: 260 },
  { month: "November", upstream: 670, downstream: 334 },
  { month: "December", upstream: 256, downstream: 106 },
];

const chartConfig = {
  upstream: {
    label: "Upstream",
    colors: {
      light: ["#047857"],
      dark: ["#10b981"],
    },
  },
  downstream: {
    label: "Downstream",
    colors: {
      light: ["#be123c"],
      dark: ["#f43f5e"],
    },
  },
} satisfies ChartConfig;

export function ExampleLineChart() {
  return (
    <LineChart
      data={data}
      config={chartConfig}
      className="h-full w-full p-4"
      curveType="bump" // [!code highlight]
    >
      <LineChart.XAxis dataKey="month" tickFormatter={(value) => value.substring(0, 3)} />
      <LineChart.YAxis dataKey="upstream" />
      <LineChart.Legend isClickable />
      <LineChart.Tooltip />
      <LineChart.Line dataKey="upstream" strokeVariant="solid" isClickable>
        <LineChart.Dot variant="default" />
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
      <LineChart.Line dataKey="downstream" strokeVariant="solid" isClickable>
        <LineChart.Dot variant="default" />
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
    </LineChart>
  );
}

```

### curveType='step'

```tsx
"use client";

import { LineChart, type ChartConfig } from "honestui/charts";

// Scenario: Garden growth
const data = [
  { month: "January", tomatoes: 469, peppers: 180 },
  { month: "February", tomatoes: 1099, peppers: 409 },
  { month: "March", tomatoes: 688, peppers: 271 },
  { month: "April", tomatoes: 835, peppers: 351 },
  { month: "May", tomatoes: 603, peppers: 298 },
  { month: "June", tomatoes: 989, peppers: 371 },
  { month: "July", tomatoes: 551, peppers: 223 },
  { month: "August", tomatoes: 1178, peppers: 463 },
  { month: "September", tomatoes: 823, peppers: 333 },
  { month: "October", tomatoes: 700, peppers: 333 },
  { month: "November", tomatoes: 1025, peppers: 419 },
  { month: "December", tomatoes: 419, peppers: 162 },
];

const chartConfig = {
  tomatoes: {
    label: "Tomatoes",
    colors: {
      light: ["#047857"],
      dark: ["#10b981"],
    },
  },
  peppers: {
    label: "Peppers",
    colors: {
      light: ["#be123c"],
      dark: ["#f43f5e"],
    },
  },
} satisfies ChartConfig;

export function ExampleLineChart() {
  return (
    <LineChart
      data={data}
      config={chartConfig}
      className="h-full w-full p-4"
      curveType="step" // [!code highlight]
    >
      <LineChart.XAxis dataKey="month" tickFormatter={(value) => value.substring(0, 3)} />
      <LineChart.YAxis dataKey="tomatoes" />
      <LineChart.Legend isClickable />
      <LineChart.Tooltip />
      <LineChart.Line dataKey="tomatoes" strokeVariant="solid" isClickable>
        <LineChart.Dot variant="default" />
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
      <LineChart.Line dataKey="peppers" strokeVariant="solid" isClickable>
        <LineChart.Dot variant="default" />
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
    </LineChart>
  );
}

```

### curveType='monotoneY'

```tsx
"use client";

import { LineChart, type ChartConfig } from "honestui/charts";

// Scenario: Music royalties
const data = [
  { month: "January", earned: 401, paid: 147 },
  { month: "February", earned: 935, paid: 326 },
  { month: "March", earned: 590, paid: 220 },
  { month: "April", earned: 715, paid: 284 },
  { month: "May", earned: 515, paid: 245 },
  { month: "June", earned: 842, paid: 295 },
  { month: "July", earned: 474, paid: 182 },
  { month: "August", earned: 1006, paid: 370 },
  { month: "September", earned: 700, paid: 271 },
  { month: "October", earned: 598, paid: 272 },
  { month: "November", earned: 875, paid: 332 },
  { month: "December", earned: 365, paid: 134 },
];

const chartConfig = {
  earned: {
    label: "Earned",
    colors: {
      light: ["#047857"],
      dark: ["#10b981"],
    },
  },
  paid: {
    label: "Paid",
    colors: {
      light: ["#be123c"],
      dark: ["#f43f5e"],
    },
  },
} satisfies ChartConfig;

export function ExampleLineChart() {
  return (
    <LineChart
      data={data}
      config={chartConfig}
      className="h-full w-full p-4"
      curveType="monotoneY" // [!code highlight]
    >
      <LineChart.XAxis dataKey="month" tickFormatter={(value) => value.substring(0, 3)} />
      <LineChart.YAxis dataKey="earned" />
      <LineChart.Legend isClickable />
      <LineChart.Tooltip />
      <LineChart.Line dataKey="earned" strokeVariant="solid" isClickable>
        <LineChart.Dot variant="default" />
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
      <LineChart.Line dataKey="paid" strokeVariant="solid" isClickable>
        <LineChart.Dot variant="default" />
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
    </LineChart>
  );
}

```

### Stroke Variants [#stroke-variants]

### strokeVariant='solid'

```tsx
"use client";

import { LineChart, type ChartConfig } from "honestui/charts";

// Scenario: School enrollment
const data = [
  { month: "January", enrolled: 435, waitlisted: 164 },
  { month: "February", enrolled: 1017, waitlisted: 367 },
  { month: "March", enrolled: 639, waitlisted: 246 },
  { month: "April", enrolled: 775, waitlisted: 317 },
  { month: "May", enrolled: 559, waitlisted: 272 },
  { month: "June", enrolled: 916, waitlisted: 333 },
  { month: "July", enrolled: 513, waitlisted: 203 },
  { month: "August", enrolled: 1092, waitlisted: 416 },
  { month: "September", enrolled: 761, waitlisted: 302 },
  { month: "October", enrolled: 649, waitlisted: 302 },
  { month: "November", enrolled: 950, waitlisted: 376 },
  { month: "December", enrolled: 392, waitlisted: 148 },
];

const chartConfig = {
  enrolled: {
    label: "Enrolled",
    colors: {
      light: ["#047857"],
      dark: ["#10b981"],
    },
  },
  waitlisted: {
    label: "Waitlisted",
    colors: {
      light: ["#be123c"],
      dark: ["#f43f5e"],
    },
  },
} satisfies ChartConfig;

export function ExampleLineChart() {
  return (
    <LineChart data={data} config={chartConfig} className="h-full w-full p-4">
      <LineChart.XAxis dataKey="month" tickFormatter={(value) => value.substring(0, 3)} />
      <LineChart.YAxis dataKey="enrolled" />
      <LineChart.Legend isClickable />
      <LineChart.Tooltip />
      <LineChart.Line
        dataKey="enrolled"
        strokeVariant="solid" // [!code highlight]
        isClickable
      >
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
      <LineChart.Line
        dataKey="waitlisted"
        strokeVariant="solid" // [!code highlight]
        isClickable
      >
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
    </LineChart>
  );
}

```

### strokeVariant='dashed'

```tsx
"use client";

import { LineChart, type ChartConfig } from "honestui/charts";

// Scenario: Podcast audience
const data = [
  { month: "January", streams: 313, downloads: 138 },
  { month: "February", streams: 800, downloads: 367 },
  { month: "March", streams: 487, downloads: 229 },
  { month: "April", streams: 602, downloads: 309 },
  { month: "May", streams: 417, downloads: 256 },
  { month: "June", streams: 715, downloads: 329 },
  { month: "July", streams: 382, downloads: 181 },
  { month: "August", streams: 865, downloads: 421 },
  { month: "September", streams: 585, downloads: 291 },
  { month: "October", streams: 493, downloads: 291 },
  { month: "November", streams: 746, downloads: 377 },
  { month: "December", streams: 283, downloads: 120 },
];

const chartConfig = {
  streams: {
    label: "Streams",
    colors: {
      light: ["#047857"],
      dark: ["#10b981"],
    },
  },
  downloads: {
    label: "Downloads",
    colors: {
      light: ["#be123c"],
      dark: ["#f43f5e"],
    },
  },
} satisfies ChartConfig;

export function ExampleLineChart() {
  return (
    <LineChart data={data} config={chartConfig} className="h-full w-full p-4">
      <LineChart.XAxis dataKey="month" tickFormatter={(value) => value.substring(0, 3)} />
      <LineChart.YAxis dataKey="streams" />
      <LineChart.Legend isClickable />
      <LineChart.Tooltip />
      <LineChart.Line
        dataKey="streams"
        strokeVariant="dashed" // [!code highlight]
        isClickable
      >
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
      <LineChart.Line
        dataKey="downloads"
        strokeVariant="dashed" // [!code highlight]
        isClickable
      >
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
    </LineChart>
  );
}

```

### strokeVariant='animated-dashed'

```tsx
"use client";

import { LineChart, type ChartConfig } from "honestui/charts";

// Scenario: Temperature range
const data = [
  { month: "January", highTemp: 212, lowTemp: 88 },
  { month: "February", highTemp: 554, lowTemp: 243 },
  { month: "March", highTemp: 339, lowTemp: 153 },
  { month: "April", highTemp: 423, lowTemp: 209 },
  { month: "May", highTemp: 284, lowTemp: 176 },
  { month: "June", highTemp: 495, lowTemp: 216 },
  { month: "July", highTemp: 266, lowTemp: 119 },
  { month: "August", highTemp: 607, lowTemp: 281 },
  { month: "September", highTemp: 401, lowTemp: 197 },
  { month: "October", highTemp: 341, lowTemp: 199 },
  { month: "November", highTemp: 520, lowTemp: 247 },
  { month: "December", highTemp: 201, lowTemp: 79 },
];

const chartConfig = {
  highTemp: {
    label: "High",
    colors: {
      light: ["#047857"],
      dark: ["#10b981"],
    },
  },
  lowTemp: {
    label: "Low",
    colors: {
      light: ["#be123c"],
      dark: ["#f43f5e"],
    },
  },
} satisfies ChartConfig;

export function ExampleLineChart() {
  return (
    <LineChart data={data} config={chartConfig} className="h-full w-full p-4">
      <LineChart.XAxis dataKey="month" tickFormatter={(value) => value.substring(0, 3)} />
      <LineChart.YAxis dataKey="highTemp" />
      <LineChart.Legend isClickable />
      <LineChart.Tooltip />
      <LineChart.Line
        dataKey="highTemp"
        strokeVariant="animated-dashed" // [!code highlight]
        isClickable
      >
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
      <LineChart.Line
        dataKey="lowTemp"
        strokeVariant="animated-dashed" // [!code highlight]
        isClickable
      >
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
    </LineChart>
  );
}

```

### Glowing Lines [#glowing-lines]

### Hospital census

```tsx
"use client";

import { LineChart, type ChartConfig } from "honestui/charts";

// Scenario: Hospital census
const data = [
  { month: "January", admissions: 239, discharges: 136 },
  { month: "February", admissions: 581, discharges: 339 },
  { month: "March", admissions: 366, discharges: 218 },
  { month: "April", admissions: 450, discharges: 289 },
  { month: "May", admissions: 311, discharges: 244 },
  { month: "June", admissions: 522, discharges: 305 },
  { month: "July", admissions: 293, discharges: 175 },
  { month: "August", admissions: 634, discharges: 388 },
  { month: "September", admissions: 428, discharges: 274 },
  { month: "October", admissions: 368, discharges: 274 },
  { month: "November", admissions: 547, discharges: 348 },
  { month: "December", admissions: 228, discharges: 120 },
];

const chartConfig = {
  admissions: {
    label: "Admissions",
    colors: {
      light: ["red", "orange", "rosybrown", "purple", "blue"],
      dark: ["red", "orange", "rosybrown", "purple", "blue"],
    },
  },
  discharges: {
    label: "Discharges",
    colors: {
      light: ["gray"],
      dark: ["gray"],
    },
  },
} satisfies ChartConfig;

export function ExampleLineChart() {
  return (
    <LineChart data={data} config={chartConfig} className="h-full w-full p-4">
      <LineChart.XAxis dataKey="month" tickFormatter={(value) => value.substring(0, 3)} />
      <LineChart.Legend isClickable />
      <LineChart.Tooltip />
      <LineChart.Line
        dataKey="admissions"
        strokeVariant="solid"
        glowing // [!code highlight]
        isClickable
      >
        <LineChart.Dot variant="colored-border" />
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
      <LineChart.Line dataKey="discharges" strokeVariant="solid" isClickable>
        <LineChart.Dot variant="colored-border" />
        <LineChart.ActiveDot variant="default" />
      </LineChart.Line>
    </LineChart>
  );
}

```

### Train punctuality

```tsx
"use client";

import { LineChart, type ChartConfig } from "honestui/charts";

// Scenario: Train punctuality
const data = [
  { month: "January", arrivals: 273, departures: 152 },
  { month: "February", arrivals: 663, departures: 381 },
  { month: "March", arrivals: 416, departures: 243 },
  { month: "April", arrivals: 510, departures: 323 },
  { month: "May", arrivals: 355, departures: 270 },
  { month: "June", arrivals: 596, departures: 343 },
  { month: "July", arrivals: 332, departures: 195 },
  { month: "August", arrivals: 720, departures: 435 },
  { month: "September", arrivals: 489, departures: 305 },
  { month: "October", arrivals: 419, departures: 305 },
  { month: "November", arrivals: 622, departures: 391 },
  { month: "December", arrivals: 255, departures: 134 },
];

const chartConfig = {
  arrivals: {
    label: "Arrivals",
    colors: {
      light: ["#047857"],
      dark: ["#10b981"],
    },
  },
  departures: {
    label: "Departures",
    colors: {
      light: ["#be123c"],
      dark: ["#f43f5e"],
    },
  },
} satisfies ChartConfig;

export function ExampleLineChart() {
  return (
    <LineChart data={data} config={chartConfig} className="h-full w-full p-4">
      <LineChart.XAxis dataKey="month" tickFormatter={(value) => value.substring(0, 3)} />
      <LineChart.Legend isClickable />
      <LineChart.Tooltip />
      <LineChart.Line dataKey="arrivals" strokeVariant="solid" isClickable>
        <LineChart.Dot variant="border" />
        <LineChart.ActiveDot variant="colored-border" />
      </LineChart.Line>
      <LineChart.Line
        dataKey="departures"
        strokeVariant="solid"
        glowing // [!code highlight]
        isClickable
      >
        <LineChart.Dot variant="border" />
        <LineChart.ActiveDot variant="colored-border" />
      </LineChart.Line>
    </LineChart>
  );
}

```

## API Reference [#api-reference]

The chart is composed of several parts; the props below are grouped by part. On canvas each part is declarative config the root compiles.

<ApiHeading>
  LineChart
</ApiHeading>

The root container. It owns the data, shared selection state, loading skeleton, and optional native `dataZoom` brush. Everything visual is composed as its children and compiled into the ECharts option.


  ### `data`

type: `TData[]`

The chart data, an array of objects, one per data point (`TData extends Record<string, unknown>`).

  ### `config`

type: `ChartConfig`

Defines the chart's series, each key matches a data key with a `label` and per-theme `colors` array. Same contract as every Honest UI chart; see [Chart Config](/docs/charts/chart-config).

  ### `children`

type: `ReactNode`

The composed chart parts, `<Grid />`, `<XAxis />`, `<YAxis />`, `<Legend />`, `<Tooltip />`, and one or more `<Line />`.

  ### `className`

type: `string`

Additional CSS classes for the chart container.

  ### `xDataKey`

type: `keyof TData & string`

The data key for the x-axis categories. Falls back to the `<XAxis dataKey="…" />` value, then to the first data column no `<Line />` claims.

  ### `curveType`

type: `&#x22;linear&#x22; | &#x22;smooth&#x22; | &#x22;bump&#x22; | &#x22;monotone&#x22; | &#x22;monotoneX&#x22; | &#x22;monotoneY&#x22; | &#x22;natural&#x22; | &#x22;step&#x22;` · default: `&#x22;linear&#x22;`

Default curve interpolation inherited by every `<Line />`. Each `<Line />` may override it locally.

  ### `animation`

type: `boolean` · default: `true`

Master switch for the intro draw-in. Pass `false` to render the chart instantly, regardless of `animationType`.

  ### `animationType`

type: `&#x22;none&#x22; | &#x22;left-to-right&#x22; | &#x22;right-to-left&#x22; | &#x22;center-out&#x22; | &#x22;edges-in&#x22;` · default: `&#x22;left-to-right&#x22;`

The intro animation inherited by every `<Line />`. Any value but `"none"` plays ECharts' native progressive draw-in: the line traces in and dots appear as its front passes. Direction values control the reveal origin. `"none"` disables it, and devices set to reduced motion fall back to `"none"` automatically.

  ### `enableHoverHighlight`

type: `boolean` · default: `false`

Highlights the hovered line by dimming the rest, the hover twin of click selection. Dim levels match the selection styling; a glowing line's glow and a buffer line's dashed tail dim and brighten with their parent.

  ### `enableHoverReveal`

type: `boolean` · default: `false`

On hover, colors each line up to the pointer's x-position and mutes the rest to a neutral gray, with the active dot at the cursor. A standalone hover mode that takes visual precedence over `enableHoverHighlight`; idle, the chart renders normally.

  ### `defaultSelectedDataKey`

type: `string | null` · default: `null`

The series selected on first render.

  ### `onSelectionChange`



void">
    Fires when a series is selected or deselected via a clickable `<Line />` or `<Legend />`. Receives the selected data key, or `null` on deselect.

  ### `isLoading`

type: `boolean` · default: `false`

Shows the animated loading skeleton.

  ### `loadingPoints`

type: `number` · default: `14`

Number of points in the loading skeleton.

  ### `chartOptions`



">
    Escape hatch merged over the built ECharts option object. See the [ECharts option documentation](https://echarts.apache.org/en/option.html).


<ApiHeading>
  Line
</ApiHeading>

A single line series. Each `<Line />` is self-contained, its own stroke, glow, and clickability, so a chart can hold any number of independently styled lines.


  ### `dataKey`

type: `string`

The series key. Must exist on both the data rows and the chart `config`.

  ### `strokeVariant`

type: `&#x22;solid&#x22; | &#x22;dashed&#x22; | &#x22;animated-dashed&#x22;` · default: `&#x22;solid&#x22;`

The stroke style for this line.

  ### `strokeWidth`

type: `number` · default: `0.8`

Stroke thickness for this line, in pixels.

  ### `curveType`

type: `&#x22;linear&#x22; | &#x22;smooth&#x22; | &#x22;bump&#x22; | &#x22;monotone&#x22; | &#x22;monotoneX&#x22; | &#x22;monotoneY&#x22; | &#x22;natural&#x22; | &#x22;step&#x22;`

The curve interpolation for this line. Falls back to the chart's `curveType` when omitted.

  ### `animationType`

type: `&#x22;none&#x22; | &#x22;left-to-right&#x22; | &#x22;right-to-left&#x22; | &#x22;center-out&#x22; | &#x22;edges-in&#x22;`

The intro draw-in for this line (the first `<Line />`'s value drives the chart). Falls back to the chart's `animationType` when omitted.

  ### `connectNulls`

type: `boolean` · default: `false`

Whether to connect line segments across null or missing values.

  ### `isClickable`

type: `boolean` · default: `false`

Lets this line be selected by clicking it. When any line is selected, the rest become semi-transparent.

  ### `glowing`

type: `boolean` · default: `false`

Applies a soft outer glow to this line, tinted with its series color.

  ### `enableBufferLine`

type: `boolean` · default: `false`

Renders this line's last segment as a dashed buffer while the rest stays solid, useful for projected or incomplete data at the end of a series.

  ### `children`

type: `ReactNode`

Optional `<Dot />` and `<ActiveDot />` config that adds point markers to this line.


<ApiHeading>
  Dot and ActiveDot
</ApiHeading>

Point markers composed inside a `<Line />`. `<Dot />` is the resting marker; `<ActiveDot />` is the hovered marker. They render nothing on their own, the parent `<Line />` reads their `variant`.


  ### `variant`

type: `&#x22;default&#x22; | &#x22;border&#x22; | &#x22;colored-border&#x22;` · default: `&#x22;default&#x22;`

The visual style of the point marker.


<ApiHeading>
  XAxis and YAxis
</ApiHeading>

The category and value axes. Include `<XAxis />` for x-axis labels and `<YAxis />` for the y-axis; omit either to hide it. Both hide automatically while the chart loads.


  ### `dataKey`

type: `string`

The data key for the axis values.

  ### `tickFormatter`



string">
    Formats the axis tick labels.

  ### `label`

type: `string`

An axis title rendered clear of the tick labels, centered below the x-axis labels, or rotated alongside the y-axis ones.

  ### `hideDots`

type: `boolean` · default: `false`

Hides the small tick dots that sit beside this axis's labels.


<ApiHeading>
  Grid
</ApiHeading>

The background grid lines. Include it to render the dashed horizontal split lines; omit it and they don't draw. Takes no props.

<ApiHeading>
  Tooltip
</ApiHeading>

The hover tooltip. Include it to enable the tooltip; omit it and none shows. It reads the chart's selection state, dimming unselected series in its content.


  ### `variant`

type: `&#x22;default&#x22; | &#x22;frosted-glass&#x22;` · default: `&#x22;default&#x22;`

The visual style of the tooltip surface.

  ### `roundness`

type: `&#x22;sm&#x22; | &#x22;md&#x22; | &#x22;lg&#x22; | &#x22;xl&#x22;` · default: `&#x22;lg&#x22;`

Controls the border-radius of the tooltip.

  ### `cursor`

type: `boolean` · default: `true`

Whether the vertical cursor line follows the pointer on hover.

  ### `position`

type: `&#x22;fixed&#x22; | &#x22;variable&#x22;` · default: `&#x22;variable&#x22;`

How the tooltip is anchored. `"variable"` follows both axes (the default). `"fixed"` pins the tooltip near the top of the chart and only tracks the pointer's X.


<ApiHeading>
  Legend
</ApiHeading>

The series legend, rendered as HTML above the canvas. Include it to show the legend; omit it and none shows. With `isClickable`, each entry toggles selection of its series.


  ### `variant`

type: `&#x22;square&#x22; | &#x22;circle&#x22; | &#x22;circle-outline&#x22; | &#x22;rounded-square&#x22; | &#x22;rounded-square-outline&#x22; | &#x22;vertical-bar&#x22; | &#x22;horizontal-bar&#x22;`

The visual style of the legend indicators.

  ### `align`

type: `&#x22;left&#x22; | &#x22;center&#x22; | &#x22;right&#x22;` · default: `&#x22;right&#x22;`

Horizontal placement of the legend.

  ### `verticalAlign`

type: `&#x22;top&#x22; | &#x22;middle&#x22; | &#x22;bottom&#x22;` · default: `&#x22;top&#x22;`

Vertical placement of the legend.

  ### `isClickable`

type: `boolean` · default: `false`

Lets each legend entry toggle selection of its series.


<ApiHeading>
  Brush
</ApiHeading>

An optional zoom brush below the chart, a themed mini chart driven by ECharts' native `dataZoom`. Include `<LineChart.Brush />` to render it; dragging the range filters the main chart.


  ### `height`

type: `number` · default: `56`

Height of the brush preview strip in pixels.

  ### `formatLabel`



string">
    Formats the range-handle labels below the brush.

  ### `onChange`



void">
    Fires when the brush selection range changes.
