An open API service indexing awesome lists of open source software.

https://github.com/margelo/react-native-graph

📈 Beautiful, high-performance Graphs and Charts for React Native built with Skia
https://github.com/margelo/react-native-graph

android animated animation beautiful chart charts crypto graph graphs ios library linegraph performance react react-native skia stock svg wallet

Last synced: 18 days ago
JSON representation

📈 Beautiful, high-performance Graphs and Charts for React Native built with Skia

Awesome Lists containing this project

README

          





Nitro Modules


📈

react-native-graph



Beautiful, high-performance Graphs/Charts for React Native.

## About

**react-native-graph** is a Line Graph implementation based on the high performance 2D graphics rendering engine "Skia". It's used in the [Bamboo app](https://bambooassets.com) to power thousands of token graphs every day.

- 🏎️ Faster and smoother than react-native-svg graphs
- ⚡️ Native path interpolation in Skia
- 🐎 Up to 120 FPS animations
- 📈 Cubic bezier rendering for smoother edges
- 👍 Smooth pan/scrubbing gesture
- 💰 Made for crypto apps and Wallets
- ❌ Does not block navigation, press or scroll animations

## Installation


yarn add react-native-reanimated # Reanimated requires react-native-worklets
yarn add react-native-gesture-handler
yarn add @shopify/react-native-skia
yarn add react-native-graph

### Expo

The [Expo example](./example/) runs in Expo Go with Expo SDK 57. Install `react-native-graph` alongside the Expo SDK's compatible versions of Skia, Reanimated, Worklets, and Gesture Handler. Start the example from its `example` directory and open it in Expo Go to try the graph without building a custom development client.

## Usage

```tsx
import { LineGraph, type GraphPoint } from 'react-native-graph';

const priceHistory: GraphPoint[] = [
{ date: new Date('2026-08-27T00:00:00Z'), value: 3.44 },
{ date: new Date('2026-08-28T00:00:00Z'), value: 3.51 },
{ date: new Date('2026-08-29T00:00:00Z'), value: 3.49 },
];

function App() {
return (

);
}
```

`react-native-graph` does not fetch data or provide a `usePriceHistory` hook. Create the `GraphPoint[]` from your own API, state, or local data. Each point uses a `Date` for its horizontal position and a `number` for its vertical value; keep the points ordered from oldest to newest. Categorical string values are not supported on the x-axis.

## Configuration

`LineGraph` accepts the following props. It also accepts React Native [`ViewProps`](https://reactnative.dev/docs/view#props), which are forwarded to the root view.

| Prop | Type | Default | Availability | Description |
| ------------------------- | ------------------------------------------ | -------------------------------------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `animated` | `boolean` | `false` | Always | Uses the animated renderer when `true` and the lightweight static renderer when `false`. |
| `points` | `GraphPoint[]` | None. Required. | Always | The points to draw. Each point contains a numeric `value` and a `Date`. The graph scales to fit them unless `range` overrides an axis. |
| `color` | `string` | None. Required. | Always | The graph line color. |
| `checkExactPoints` | `boolean` | `true` | Always | Samples points to limit path density. Set to `false` to use every point at its date-derived horizontal position. Large datasets create larger paths. |
| `range` | `GraphRange` | `undefined`. Both axes are inferred from `points`. | Always | Overrides all or part of the visible x-axis and y-axis ranges. |
| `gradientFillColors` | `Color[]` | `undefined`. No area fill is drawn. | `animated={true}` | Colors for the vertical gradient below the graph line. |
| `lineThickness` | `number` | `3` | Always | The graph line width in points. |
| `enableFadeInMask` | `boolean` | `false` | Always | Fades in the start of the graph line. |
| `enablePanGesture` | `boolean` | `false` | `animated={true}` | Lets the user press and scrub through graph points. |
| `panGestureDelay` | `number` | `300` | `animated={true}` | Time in milliseconds that a press must be held before scrubbing starts. Set it to `0` to start immediately. |
| `onGestureStart` | `() => void` | `undefined`. No callback runs. | `animated={true}` | Called when scrubbing starts. |
| `onPointSelected` | `(point: GraphPoint) => void` | `undefined`. No callback runs. | `animated={true}` | Called when scrubbing reaches a different point. |
| `onGestureEnd` | `() => void` | `undefined`. No callback runs. | `animated={true}` | Called when scrubbing ends. |
| `SelectionDot` | `ComponentType \| null` | Built-in `SelectionDot` | `animated={true}` | Renders the current scrub position. Pass `null` to hide it. |
| `selectionDotShadowColor` | `string` | `undefined` | `animated={true}` | Currently unused. This prop has no visual effect. |
| `horizontalPadding` | `number` | `10` when the indicator is enabled, otherwise `0` | `animated={true}` | Adds space to both horizontal edges of the drawing area. |
| `verticalPadding` | `number` | The value of `lineThickness` | `animated={true}` | Adds space to both vertical edges of the drawing area. |
| `enableIndicator` | `boolean` | `false` | `animated={true}` | Shows an indicator at the last graph point. |
| `indicatorPulsating` | `boolean` | `false` | `animated={true}` | Pulses the indicator while the graph is idle. Requires `enableIndicator`. |
| `TopAxisLabel` | `() => ReactElement \| null` | `undefined`. Nothing is rendered. | `animated={true}` | Renders a label above the graph. |
| `BottomAxisLabel` | `() => ReactElement \| null` | `undefined`. Nothing is rendered. | `animated={true}` | Renders a label below the graph. |

### Data types

```ts
interface GraphPoint {
value: number;
date: Date;
}

interface GraphRange {
x?: { min: Date; max: Date };
y?: { min: number; max: number };
}
```

You can provide either axis in `range` and let the graph infer the other one from `points`.

## Prop examples

### `animated`

Whether to animate between data changes. Defaults to `false` when omitted.

Animations run using the [Skia animation system](https://shopify.github.io/react-native-skia/docs/animations/animations), with path interpolation handled on the UI thread.

If `animated` is `false`, the graph uses a lightweight static renderer. This is useful when displaying many graphs in a list.

Example:

```jsx

```

---

### `enablePanGesture`

Whether to enable the pan gesture. Defaults to `false`.

> Requires `animated` to be `true`.

There are three events fired when the user interacts with the graph:

1. `onGestureStart`: Fires once the user presses and holds the graph. The pan gesture activates.
2. `onPointSelected`: Fires for each point the user pans through. Use it to update a label or highlight the selected value.
3. `onGestureEnd`: Fires once the user releases the graph. The pan gesture deactivates.

The pan gesture can be configured using these props:

- `panGestureDelay` controls how long the user must hold before the gesture activates. It defaults to `300` milliseconds. Set it to `0` to start immediately.

Example:

```jsx
hapticFeedback('impactLight')}
onPointSelected={(p) => updatePriceTitle(p)}
onGestureEnd={() => resetPriceTitle()}
/>
```

---

### `TopAxisLabel` / `BottomAxisLabel`

Renders labels above or below the graph. Both props default to `undefined`, so no labels are rendered.

> Requires `animated` to be `true`.

These labels usually show the maximum and minimum values. `AxisLabel` is not a component exported by this package: both props are callbacks that receive no arguments and render any React Native element you provide. The graph reserves a row above or below the canvas; positioning and styling inside that row belong to your label component.

Example:

```tsx
import { Text } from 'react-native';

function PriceGraph() {
const values = priceHistory.map((point) => point.value);
const maxValue = Math.max(...values);
const minValue = Math.min(...values);

return (
{`Max: ${maxValue.toFixed(2)}`}}
BottomAxisLabel={() => {`Min: ${minValue.toFixed(2)}`}}
/>
);
}
```

### `range`

Defines the visible range of the graph canvas. It defaults to `undefined`, which infers both axes from `points`.

Use a custom range to show a fixed time frame or value scale, even when the data does not cover the whole range. Points outside the x-axis range are not drawn.




This example shows January 2000 and sets the y-axis range to 0 through 200:

```jsx

```

---

### `SelectionDot`

Renders the selection dot. It defaults to the built-in `SelectionDot`. Pass `null` to hide it.

> Requires `animated` and `enablePanGesture` to be `true`.

A custom selection-dot component receives these props from `LineGraph`. They are all required and have no defaults when you render `SelectionDot` directly.

| Prop | Type | Default | Description |
| --------------- | ---------------------- | --------------- | ----------------------------------------------------------- |
| `isActive` | `SharedValue` | None. Required. | Whether the pan gesture is active. |
| `color` | `string` | None. Required. | The graph line color. |
| `lineThickness` | `number \| undefined` | None. Required. | The resolved graph line width when supplied by `LineGraph`. |
| `circleX` | `SharedValue` | None. Required. | The selected point's x-coordinate. |
| `circleY` | `SharedValue` | None. Required. | The selected point's y-coordinate. |

Example:

```jsx

```

See this [example `` component](./example/src/components/CustomSelectionDot.tsx).

## Sponsor

**react-native-graph** is sponsored by [Pink Panda](https://pinkpanda.io).

Download the Pink Panda mobile app to see react-native-graph in action!

## Community Discord

[Join the Margelo Community Discord](https://discord.gg/6CSHz2qAvA) to chat about react-native-graph or other Margelo libraries.

## Adopting at scale

react-native-graph was built at Margelo, an elite app development agency. For enterprise support or other business inquiries, contact us at hello@margelo.com!

## Thanks

Special thanks to [William Candillon](https://github.com/wcandillon) and [Christian Falch](https://github.com/chrfalch) for their amazing help and support for React Native Skia ❤️