npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

uplot-react-native

v0.1.12

Published

React Native wrapper for uPlot on web, iOS, and Android

Readme

uplot-react-native

Description

React native wrapper around uPlot. Works on web, iOS, and Android. Wraps uPlot in a WebView on iOS and Android. The video below demos its performance on an Expo iOS development build (iPhone 15 Pro).

Caveats

  1. The library is not a simple drop-in replacement for uPlot. It requires a decent amount of setup and understanding how this wrapper works.

  2. Interactions like zooming and panning are not supported on iOS and Android. This is due to the limitations of the WebView component. I suggest using react-native-gesture-handler, react-native-reanimated, and react-native-animateable-text to roll your own interactions and legend display.

  3. The library is still in active development, so things may change. I've not tested all possible features of uPlot. Feel free to open an issue / PR to improve it.

Why?

I needed a cross-platform library to plot thousands of data points in a streaming / real-time fashion. The performance of every library that I tested degraded after a couple thousand data points, except for uPlot. uPlot is one of the fastest javascript libraries for plotting data.

Installation

npm install uplot-react-native
# or
yarn add uplot-react-native

Usage

Create a uPlot chart via ChartUPlot. The data and options props are structured the same as when you call new uPlot(options, data). You update the chart via a ref.

import { useRef, useEffect } from 'react';
import { ChartUPlot } from 'uplot-react-native';

var x = 6;
const data = [
  [1, 2, 3, 4, 5],
  [5, 4, 3, 2, 1],
];

const options = {
  id: 'chart',
  width: 300,
  height: 300,
  scales: { x: { time: false } },
  series: [{ label: 'X' }, { label: 'Value', stroke: 'blue', width: 2 }],
  axes: [{ scale: 'x' }, {}],
};

const MyChart = () => {
  const chartRef = useRef(null);

  useEffect(() => {
    setInterval(() => {
      // add a new data point every 33ms
      chartRef.current?.pushData([x, Math.random() * 10]);
      x += 1;
    }, 33);
  }, []);

  return (
    <ChartUPlot
      ref={chartRef}
      data={data}
      options={options}
      style={{ width: 500, height: 200, backgroundColor: 'white' }}
    />
  );
};

The ref exposes the following methods:

  • createChart(options, data): Create a new chart. The initial render of ChartUPlot will automatically call this method with the initial options and data.
  • setData(newData): Replace the data in the chart.
  • pushData(newData): Push new data to the chart. This is useful for streaming data.
  • setScale(axis, options): Set the scale options for a specific axis. The axis can be 'x' or 'y'.
  • setSize(width, height): Set the size of the chart.
  • destroy(): Destroy the chart instance.

Dimensions

You can set the width and height either through the uPlot options or by passing a style prop to the ChartUPlot component. If you set both, the uPlot options will take precedence. Any changes to the width and height in the options will not automatically update the chart size.

Margins

Margin for the title and legend will be subtracted from the final width and height for the chart. You can control the margin via the margin: { title?: number; legend?: number } prop.

Functions

If you have custom functions within your uPlot options, have them defined elsewhere; do not use inline functions. Then to make use of them on iOS and Android version, wrap all functions into a single string to pass them to the ChartUPlot's injectedJavaScript prop.

Any dependencies in each function must be:

  • One of the other functions passed to the injectedJavaScript prop.
  • Anything globally available within a WebView.
  • A function from the uPlot library that is available in the webview.
// for web version of uPlot
function format_value(self, ticks) {
  return ticks.map((val) => {
    return 2;
  });
}

// for iOS and Android version
const injectedJavaScript = `
function format_value(self, ticks) {
  return ticks.map((val) => {
    return 2;
  });
}
`;

const options = {
  width: 300,
  height: 300,
  scales: { x: { time: false } },
  series: [{ label: 'X' }, { label: 'Value', stroke: 'blue', width: 2 }],
  axes: [
    {
      scale: 'x',
      values: format_value,
    },
    {},
  ],
};

<ChartUPlot options={options} injectedJavaScript={injectedJavaScript} />;

Why is it done this way?

There may be a better way to do this, so please open an issue if you have a suggestion. Passing javascript functions to the webview is tricky, so the current solution is to pass them as strings into WebView's injectedJavaScript prop. You might suggest doing something like, function.toString(), but in iOS build toString() does not actually return the javascript source code, so it won't work.

Demo app

The demo folder contains an example Expo app that demonstrates how to use the library. You can run it by cloning the repository and running:

cd demo
yarn

# for web demo
npx expo start

# for iOS or Android simulators
npx expo run:ios

# for development build on a physical device
eas build --profile development --platform ios --local

Tips

  1. Don't create inline props to the ChartUPlot component, otherwise uPlot instance may get out of sync with the rendered component. Instead, use a useMemo hook to memoize the options and data.

  2. The functions you pass to the injectedJavaScript can be tricky to debug, so be sure to test them in a web environment first.

  3. Clear the ref you pass to ChartUPlot when the component unmounts.

Contributing

If you would like to contribute, please open an issue or a pull request. Contributions are welcome!

License

This project is licensed under the MIT License - see the LICENSE file for details.