Skip to content

Styling, export and integration

React adapter ​

A component that owns a canvas and nothing else ​

plotscope-react is a component, PlotCanvas, and the hook it is built on, usePlot. It makes the plot when it mounts, sizes it to its element, destroys it when it unmounts and hands the page everything in between. The chart above is a React component, mounted in this page:

tsx
import { useState } from "react";
import { PlotCanvas } from "plotscope-react";
import type { PlotControls } from "plotscope-react";
import type { Plot, PlotEvent, ThemeName } from "plotscope";

export function Monitor({ licence, theme }: { licence: string; theme: ThemeName }) {
  const [said, setSaid] = useState("Move over the chart.");

  function fill(plot: Plot, controls: PlotControls) {
    // Your licence key. Without one the plot draws the same, with a mark.
    plot.activate(licence);
    // Uploaded onto the plot, not passed as a prop: React never diffs the arrays.
    const x = plot.uploadBuffer(Float64Array.from({ length: 300 }, (_, i) => i / 10));
    const y = plot.uploadBuffer(Float32Array.from({ length: 300 }, (_, i) => Math.cos(i / 20)));
    plot.setCharts({ charts: [{ series: [{ x, y, label: "signal" }] }] });
    // Through the controls, which also hand over the events the frame produced.
    controls.render();
  }

  function show(events: PlotEvent[]) {
    for (const event of events) {
      if (event.type === "hover") setSaid(`point ${event.index}: ${event.y.toFixed(3)} at ${event.x.toFixed(1)}`);
    }
  }

  return (
    <>
      <PlotCanvas height="340px" animate theme={theme} onReady={fill} onEvents={show} />
      <output className="said">{said}</output>
    </>
  );
}
sh
npm install plotscope plotscope-react

It works with React 18.2 and 19.

Data never goes in as a prop ​

The component takes no data. It calls onReady with the plot, and the page uploads onto it with the same calls it would make without React.

A prop is something React compares on every render, and a buffer the GPU already holds is not that. Props carry configuration: theme, height, animate, className and style.

Draw through the controls ​

onReady hands over the plot and its controls. controls.render() draws a frame, delivers the events that frame produced through onEvents, and notices a GPU device that has gone away. plot.render() only draws, so a page that calls it directly never hears a hover.

A plot whose data changes only when something happens draws on demand, as above. A live one sets animate and writes its buffers from onFrame, which is called just before each frame is drawn.

Strict mode and the server ​

Strict mode mounts every component twice in development. The hook still makes only one plot and one GPU device.

Every module in the package opens with "use client". A canvas and a GPU are not things a server has, so under React Server Components the component is a client component without the page saying so.

What it calls back ​

PropWhen
onReadyThe plot exists. Upload and set documents here
onFrameA frame is about to be drawn. Only with animate
onEventsWhat the charts reported on a frame: hovers, clicks, a changed view
onErrorThe plot could not start, which is how a browser without WebGPU shows up
onLostThe GPU device went away, with the browser's reason

Several plots, or a canvas of your own ​

usePlot is the same lifecycle without the element, for a component that already has a canvas or wants several plots created and destroyed together.