{"path":"/docs/react-native/charts/line","title":"Line Chart","markdown":"# Line Chart\n\n`LineChart` shows how a value changes over time or across ordered categories. Use it for trends, forecasts, performance tracking, and any metric where the shape of change matters.\n\n## Basic Line\n\n```tsx\nimport { LineChart } from \"react-native-chart-kit/v2\";\n\nconst data = [\n  { month: \"Jan\", revenue: 52 },\n  { month: \"Feb\", revenue: 86 },\n  { month: \"Mar\", revenue: 58 },\n  { month: \"Apr\", revenue: 134 },\n  { month: \"May\", revenue: 95 },\n  { month: \"Jun\", revenue: 176 },\n  { month: \"Jul\", revenue: 126 },\n  { month: \"Aug\", revenue: 218 },\n  { month: \"Sep\", revenue: 164 },\n  { month: \"Oct\", revenue: 252 },\n  { month: \"Nov\", revenue: 198 },\n  { month: \"Dec\", revenue: 286 }\n];\n\nexport function RevenueChart() {\n  return (\n    <LineChart\n      data={data}\n      xKey=\"month\"\n      yKey=\"revenue\"\n      width={410}\n      height={240}\n    />\n  );\n}\n```\n\n## Multi-Series\n\nUse `series` when each line needs its own label, color, marker, curve, or stroke style.\n\n```tsx\nconst data = [\n  { month: \"Jan\", actual: 22, forecast: 190 },\n  { month: \"Feb\", actual: 64, forecast: 168 },\n  { month: \"Mar\", actual: 39, forecast: 143 },\n  { month: \"Apr\", actual: 118, forecast: 122 },\n  { month: \"May\", actual: 73, forecast: 101 },\n  { month: \"Jun\", actual: 161, forecast: 84 },\n  { month: \"Jul\", actual: 109, forecast: 66 },\n  { month: \"Aug\", actual: 204, forecast: 48 }\n];\n\n<LineChart\n  data={data}\n  xKey=\"month\"\n  series={[\n    { yKey: \"actual\", label: \"Actual\" },\n    {\n      yKey: \"forecast\",\n      label: \"Forecast\",\n      strokeDasharray: [6, 4],\n      strokeOpacity: 0.72\n    }\n  ]}\n  legend={{ position: \"bottom\", wrap: true }}\n  width={410}\n  height={260}\n/>;\n```\n\n## Styling Lines and Dots\n\nSupported curve values are `linear`, `monotone`, and `step`.\n\n```tsx\nconst data = [\n  { date: \"Mon\", portfolio: 512, benchmark: 690 },\n  { date: \"Tue\", portfolio: 660, benchmark: 610 },\n  { date: \"Wed\", portfolio: 430, benchmark: 650 },\n  { date: \"Thu\", portfolio: 760, benchmark: 540 },\n  { date: \"Fri\", portfolio: 590, benchmark: 700 },\n  { date: \"Sat\", portfolio: 820, benchmark: 520 },\n  { date: \"Sun\", portfolio: 548, benchmark: 735 }\n];\n\n<LineChart\n  data={data}\n  xKey=\"date\"\n  series={[\n    {\n      yKey: \"portfolio\",\n      label: \"Portfolio\",\n      curve: \"monotone\",\n      strokeWidth: 3,\n      dot: {\n        shape: \"diamond\",\n        radius: 4,\n        fill: \"background\",\n        stroke: \"series\"\n      }\n    },\n    {\n      yKey: \"benchmark\",\n      label: \"Benchmark\",\n      curve: \"linear\",\n      strokeDasharray: [5, 5],\n      strokeLinecap: \"butt\",\n      dot: false\n    }\n  ]}\n  activeDot={{ radius: 6, fill: \"background\", stroke: \"series\" }}\n  width={410}\n  height={260}\n/>;\n```\n\n## Threshold Coloring\n\nThreshold coloring clips the rendered path above or below a y value. Raw points are unchanged.\n\n```tsx\nconst data = [\n  { month: \"Jan\", attainment: 62 },\n  { month: \"Feb\", attainment: 138 },\n  { month: \"Mar\", attainment: 74 },\n  { month: \"Apr\", attainment: 151 },\n  { month: \"May\", attainment: 89 },\n  { month: \"Jun\", attainment: 122 },\n  { month: \"Jul\", attainment: 55 },\n  { month: \"Aug\", attainment: 164 },\n  { month: \"Sep\", attainment: 96 },\n  { month: \"Oct\", attainment: 145 },\n  { month: \"Nov\", attainment: 78 },\n  { month: \"Dec\", attainment: 172 }\n];\n\n<LineChart\n  data={data}\n  xKey=\"month\"\n  series={[\n    {\n      yKey: \"attainment\",\n      label: \"Attainment\",\n      threshold: {\n        y: 100,\n        aboveColor: \"#16a34a\",\n        belowColor: \"#dc2626\"\n      }\n    }\n  ]}\n  referenceLines={[\n    { y: 100, label: \"Plan\", labelContainer: true, strokeDasharray: [5, 4] }\n  ]}\n  width={410}\n  height={240}\n/>;\n```\n\n## Tooltips and Selection\n\nSelection state is shared by tooltips, active dots, crosshairs, and external UI through `onSelect`.\n\n```tsx\nconst data = [\n  { date: \"Nov 03\", portfolio: 512, benchmark: 720 },\n  { date: \"Nov 04\", portfolio: 681, benchmark: 604 },\n  { date: \"Nov 05\", portfolio: 438, benchmark: 698 },\n  { date: \"Nov 10\", portfolio: 794, benchmark: 552 },\n  { date: \"Nov 11\", portfolio: 566, benchmark: 746 },\n  { date: \"Nov 12\", portfolio: 842, benchmark: 580 },\n  { date: \"Nov 13\", portfolio: 618, benchmark: 790 },\n  { date: \"Nov 14\", portfolio: 906, benchmark: 534 }\n];\n\n<LineChart\n  data={data}\n  xKey=\"date\"\n  yKeys={[\"portfolio\", \"benchmark\"]}\n  interaction={{\n    mode: \"scrub\",\n    selectionPersistence: \"whileActive\",\n    onSelect: (event) => {\n      setHeaderValue(event.series[0]?.formattedValue);\n    }\n  }}\n  tooltip={{\n    shared: true,\n    anchor: \"pointer\",\n    placement: \"above\",\n    offset: 18,\n    positionAnimationDuration: 320\n  }}\n  crosshair\n  width={410}\n  height={260}\n/>;\n```\n\nSelection modes:\n\n-   `none`: no chart selection.\n-   `tap`: tap to select the nearest x value.\n-   `scrub`: press and drag to update the nearest x value.\n\nSelection persistence:\n\n-   `persist`: keep the last selection after the gesture ends.\n-   `whileActive`: clear selection on gesture end.\n-   `none`: emit selection events without keeping internal selected state.\n\nTooltip positioning:\n\n-   `anchor: \"point\"` positions around the selected data point.\n-   `anchor: \"pointer\"` positions around the touch/mouse pointer.\n-   `placement: \"auto\" | \"above\" | \"below\"` controls vertical placement while preserving edge clamping.\n\n## Custom Crosshair\n\nUse `renderCrosshair` when a product needs branded cursors, axis badges, or a custom inspection overlay.\n\n```tsx\nimport { G, Line, Text as SvgText } from \"react-native-svg\";\n\nconst data = [\n  { month: \"Jan\", actual: 22, forecast: 190 },\n  { month: \"Feb\", actual: 64, forecast: 168 },\n  { month: \"Mar\", actual: 39, forecast: 143 },\n  { month: \"Apr\", actual: 118, forecast: 122 },\n  { month: \"May\", actual: 73, forecast: 101 },\n  { month: \"Jun\", actual: 161, forecast: 84 },\n  { month: \"Jul\", actual: 109, forecast: 66 },\n  { month: \"Aug\", actual: 204, forecast: 48 }\n];\n\n<LineChart\n  data={data}\n  xKey=\"month\"\n  yKeys={[\"actual\", \"forecast\"]}\n  selectedIndex={4}\n  crosshair={{ strokeDasharray: [3, 4] }}\n  renderCrosshair={({ config, plot, series, theme, x, xLabel, y }) => (\n    <G>\n      <Line\n        x1={x}\n        x2={x}\n        y1={plot.y}\n        y2={plot.y + plot.height}\n        stroke={config.color}\n        strokeDasharray={config.strokeDasharray}\n      />\n      <SvgText\n        x={x + 8}\n        y={y - 8}\n        fill={theme.text}\n        fontSize={theme.typography.legendLabelSize}\n        fontFamily={theme.typography.fontFamily}\n      >\n        {xLabel}: {series[0]?.formattedValue}\n      </SvgText>\n    </G>\n  )}\n  width={410}\n  height={260}\n/>;\n```\n\n## Scroll, Pan, Zoom, and Range Selector\n\nUse simple horizontal scrolling for long categorical or time-series charts.\n\n```tsx\n<LineChart\n  data={largeData}\n  xKey=\"date\"\n  yKey=\"price\"\n  scrollable\n  visiblePoints={30}\n  initialIndex=\"end\"\n  yAxisLabelWidth=\"stable\"\n  width={410}\n  height={260}\n/>\n```\n\nUse a controlled viewport for direct pan, pinch zoom, or a mini-chart range selector.\n\n```tsx\nconst [viewport, setViewport] = useState<LineChartViewportConfig>({\n  startIndex: 40,\n  endIndex: 90\n});\n\n<LineChart\n  data={portfolioHistory}\n  xKey=\"date\"\n  yKeys={[\"portfolio\", \"benchmark\"]}\n  viewport={viewport}\n  onViewportChange={(event) => setViewport(event.viewport)}\n  viewportInteraction={{ pan: true, pinchZoom: true, lockParentScroll: true }}\n  rangeSelector={{ visible: true, interactive: true, height: 68 }}\n  yAxisLabelWidth=\"stable\"\n  width={410}\n  height={340}\n/>;\n```\n\n`yAxisLabelWidth=\"stable\"` reserves label width from the full dataset, so changing the viewport does not make the plot jump when labels change.\n\n## Reference Overlays\n\nReference lines and bands are clipped to the plot bounds. Line labels default to automatic vertical placement and try to avoid nearby series geometry. Add `labelContainer` to a reference line or band when a label needs a small background chip over busy data.\n\n```tsx\nconst data = [\n  { month: \"Jan\", attainment: 62 },\n  { month: \"Feb\", attainment: 138 },\n  { month: \"Mar\", attainment: 74 },\n  { month: \"Apr\", attainment: 151 },\n  { month: \"May\", attainment: 89 },\n  { month: \"Jun\", attainment: 122 },\n  { month: \"Jul\", attainment: 55 },\n  { month: \"Aug\", attainment: 164 },\n  { month: \"Sep\", attainment: 96 },\n  { month: \"Oct\", attainment: 145 },\n  { month: \"Nov\", attainment: 78 },\n  { month: \"Dec\", attainment: 172 }\n];\n\n<LineChart\n  data={data}\n  xKey=\"month\"\n  yKey=\"attainment\"\n  referenceBands={[{ y1: 176, y2: 190, label: \"Target range\", opacity: 0.12 }]}\n  referenceLines={[{ y: 183, label: \"Plan\", strokeDasharray: [5, 4] }]}\n  width={410}\n  height={240}\n/>;\n```\n\n## Layout Debug\n\nUse `debugLayout` in development when a chart clips labels, legends, or tooltips. It draws the computed layout rectangles over the chart and exposes the same rectangles through `onLayoutDebug`.\n\nUse the overlay to identify which layout box is causing the issue, then tune the related prop:\n\n-   X labels collide or overflow: adjust `labelStrategy`, `labelRotation`, `labelMinGap`, or `edgeLabelPolicy`.\n-   Y labels clip or steal too much plot width: adjust `yAxisLabelWidth` or `formatYLabel`.\n-   Legend rows crowd the plot: adjust `legend`, hide it, or simplify series labels.\n-   Tooltip overlaps important data: adjust `tooltip` placement, width, or custom renderer.\n\n```tsx\n<LineChart\n  data={data}\n  xKey=\"month\"\n  yKey=\"revenue\"\n  debugLayout\n  onLayoutDebug={(model) => {\n    console.log(model.rects);\n  }}\n  width={410}\n  height={240}\n/>\n```\n\n## Labels and Axes\n\nUseful label props:\n\n-   `labelStrategy`: `auto`, `show`, `skip`, `rotate`, `stagger`, or `hide`.\n-   `edgeLabelPolicy`: `shift`, `hide`, or `show`.\n-   `formatXLabel`: format dates, categories, or numeric x values.\n-   `formatYLabel`: format y-axis labels and tooltip values.\n-   `axisLabelAnimation`: crossfade y-axis label changes during viewport changes.\n-   `yAxisLabelWidth`: `auto`, `stable`, or a fixed number.\n\n## Decimation\n\nLineChart uses automatic path-only min/max decimation by default. This reduces SVG path complexity for dense charts while preserving source points for selection, tooltips, labels, and custom dots.\n\n```tsx\n<LineChart\n  data={largeData}\n  xKey=\"timestamp\"\n  yKey=\"price\"\n  showDots={false}\n  decimation={{ maxPoints: 700 }}\n  width={410}\n  height={240}\n/>\n```\n\nDecimation options:\n\n-   `decimation=\"auto\"`: default. Uses roughly two rendered path points per plot pixel, with a minimum of 120.\n-   `decimation={false}`: disables path decimation.\n-   `decimation={500}`: caps each rendered path around a fixed point budget.\n-   `decimation={{ maxPoints: 700 }}`: object form for future strategy options.\n\n## Accessibility\n\nEvery LineChart generates a summary if `accessibilityLabel` is not provided. For custom accessibility output, use:\n\n```ts\nimport {\n  getLineChartAccessibilitySummary,\n  getLineChartDataTable\n} from \"react-native-chart-kit/v2\";\n```\n\n`getLineChartDataTable()` returns columns and rows suitable for an app-level table fallback or export workflow.\n\n## Props\n\n### LineChart\n\n| Prop | Type | Description |\n| --- | --- | --- |\n| `data` | `TData[]` | Object-row source data for the chart. |\n| `xKey` | `keyof TData` | Row key used for the x-axis value. |\n| `yKey` | `keyof TData` | Single row key used for y values when `series` or `yKeys` is not provided. |\n| `yKeys` | `Array<keyof TData>` | Multiple row keys rendered as separate series with default styling. |\n| `series` | `LineChartSeries<TData>[]` | Full per-series configuration, including labels, colors, stroke, dots, thresholds, and area fill. |\n| `width` | `number` | Outer chart width in pixels. |\n| `height` | `number` | Outer chart height in pixels. |\n| `theme` | `ChartKitThemeMode` or `CartesianChartTheme` | Theme mode or inline theme tokens for this chart. |\n| `preset` | `CartesianChartPresetValue` | Built-in or registered preset name used to seed chart colors and typography. |\n| `scrollable` | `boolean` | Enables a horizontal scroll viewport for long data sets. |\n| `visiblePoints` | `number` | Number of points visible in the viewport when `scrollable` is enabled. |\n| `initialIndex` | `ChartViewportInitialIndex` | Initial scroll/window position, such as `\"start\"` or `\"end\"`. |\n| `viewport` | `LineChartViewportConfig` | Controlled visible data window for scroll, pan, zoom, or range selector flows. |\n| `onViewportChange` | `(event) => void` | Called when viewport state changes from the main plot or range selector. |\n| `viewportInteraction` | `boolean` or `LineChartViewportInteractionConfig` | Enables and configures one-finger pan and pinch zoom for the viewport. |\n| `rangeSelector` | `boolean` or `LineChartRangeSelectorConfig` | Adds a mini-chart range selector below the main plot. |\n| `decimation` | `false`, `\"auto\"`, `number`, or `LineChartDecimationConfig` | Controls rendered path simplification for dense series. |\n| `curve` | `LineCurve` | Curve interpolation used for line and area paths. |\n| `connectNulls` | `boolean` | Connects defined points across `null` or missing y values. |\n| `area` | `boolean` | Renders area fills under the line series. |\n| `areaFill` | `LineChartAreaFillConfig` | Shared area fill opacity, gradient, or color configuration. |\n| `showDots` | `boolean` | Shows or hides all point markers. |\n| `dots` | `boolean` or `LineChartDotConfig` | Configures default point marker visibility, size, shape, and color. |\n| `renderDot` | `(props) => ReactNode` | Custom renderer for ordinary point markers. |\n| `selectedIndex` | `number` | Controlled selected data index. |\n| `defaultSelectedIndex` | `number` | Initial uncontrolled selected data index. |\n| `activeDot` | `boolean` or `LineChartDotConfig` | Configures the marker shown for the selected point. |\n| `renderActiveDot` | `(props) => ReactNode` | Custom renderer for the selected point marker. |\n| `interaction` | `LineChartInteraction<TData>` | Selection/scrub interaction mode and callbacks. |\n| `crosshair` | `boolean` or `LineChartCrosshairConfig` | Shows and configures the selected-point crosshair. |\n| `renderCrosshair` | `(props) => ReactNode` | Custom renderer for the crosshair. |\n| `tooltip` | `boolean` or `LineChartTooltipConfig` | Shows and configures selected-point tooltip content and placement. |\n| `renderTooltip` | `(props) => ReactNode` | Custom renderer for selected-point tooltip content. |\n| `referenceLines` | `LineChartReferenceLineConfig[]` | Horizontal reference lines drawn across the plot. Reference labels support `labelContainer`. |\n| `referenceBands` | `LineChartReferenceBandConfig[]` | Horizontal reference bands drawn behind the series. Reference labels support `labelContainer`. |\n| `showHorizontalGridLines` | `boolean` | Shows or hides horizontal grid lines. |\n| `showVerticalGridLines` | `boolean` | Shows or hides vertical grid lines. |\n| `legend` | `boolean` or `LineChartLegendConfig` | Shows and configures the chart legend. |\n| `labelStrategy` | `LineChartLabelStrategy` | Controls x-axis label density and layout. |\n| `labelRotation` | `number` | Rotation angle for x-axis labels when using rotated labels. |\n| `labelMinGap` | `number` | Minimum gap used by automatic x-axis label skipping. |\n| `edgeLabelPolicy` | `LineChartEdgeLabelPolicy` | Controls how first and last x-axis labels are shifted, hidden, or shown. |\n| `yDomain` | `NumericDomainInput` | Overrides or constrains the computed y-axis domain. |\n| `yAxisLabelWidth` | `LineChartYAxisLabelWidth` | Fixed, automatic, or stable width for y-axis labels. |\n| `axisLabelAnimation` | `boolean` or `LineChartAxisLabelAnimationConfig` | Animates y-axis label changes during viewport updates. |\n| `formatXLabel` | `(value, index) => string` | Formats x-axis labels and selected x labels. |\n| `formatYLabel` | `(value) => string` | Formats y-axis labels, selected values, and tooltip values. |\n| `renderer` | `LineChartRenderer` | Renderer implementation used for SVG-compatible primitives. |\n| `id` | `string` | Stable chart id used for internal ids and coordinated selection scope. |\n| `debugLayout` | `boolean` | Renders layout debug rectangles in development. |\n| `onLayoutDebug` | `(model) => void` | Receives computed layout debug geometry. |\n| `accessibilityLabel` | `string` | Overrides the generated accessible chart summary. |\n| `testID` | `string` | Test identifier applied to the chart container. |\n\n[Edit page](https://github.com/chart-kit/react-native-chart-kit/edit/main/docs/charts/line.md)\n\n[Previous  \nContributing](https://chartkit.io/docs/react-native/getting-started/contributing/)[Next  \nArea Chart](https://chartkit.io/docs/react-native/charts/area/)\n","url":"https://chartkit.io/docs/react-native/charts/line","markdownUrl":"https://chartkit.io/docs/react-native/charts/line.md"}