react-plotly.js

repository·main·Indexed 22 days ago

https://github.com/plotly/react-plotly.js

A React wrapper for the plotly.js graphing library (version 4.1.0) that provides a declarative way to integrate interactive charts into React applications. It features a Plot component that accepts data, layout, and config props, supports TypeScript via PlotParams and Figure types, and provides a factory method createPlotlyComponent for custom plotly.js bundles.

Tokens
6K
Snippets
16
Records
19
Agent score
78%

What's inside react-plotly.js

  1. Access the underlying plotly.js DOM element via Refs

    main

    You can attach a ref to the <Plot> component. The resolved ref will be the rendered <div> element (the plotly graph div). This allows you to call low-level plotly.js APIs directly on the element, such as Plotly.toImage(ref.current).

    const plotRef = useRef<HTMLDivElement>(null);
    
    // Later in an effect or handler
    if (plotRef.current) {
      // Call low-level plotly.js APIs
      // Plotly.toImage(plotRef.current);
    }
    
    <Plot ref={plotRef} ... />
  2. How state management works in react-plotly.js

    main

    The Plot component is a "dumb" component, meaning it does not automatically merge its internal state (like zoom levels or pan positions) with updates passed via props. If a user interacts with the plot, those changes will be lost on the next re-render unless you capture the state using the onInitialized or onUpdate callback props and store it in your application state.

    import {useState} from 'react';
    import Plot from 'react-plotly.js';
    
    function App() {
      const [figure, setFigure] = useState({data: [], layout: {}, frames: [], config: {}});
      return (
        <Plot
          data={figure.data}
          layout={figure.layout}
          frames={figure.frames}
          config={figure.config}
          onInitialized={setFigure}
          onUpdate={setFigure}
        />
      );
    }
  3. Refreshing the Plot

    main

    The component uses Plotly.react to refresh the plot. To trigger a refresh, one of the following must occur:

    1. The revision prop is defined and its value changes.
    2. The identity of data, layout, or config changes (checked via shallow === comparison).
    3. The number of elements in the frames array changes.

    Important: Because the component relies on shallow identity checks, mutating an existing object (e.g., pushing a new value to an existing x array or changing a property inside layout) will not trigger a re-render. You must either:

    • Use immutable update patterns (e.g., creating a new object/array).
    • Use the revision prop to force a re-render.
    • Use layout.datarevision to force a data refresh.
  4. Quick start with the Plot component

    main

    The simplest way to render a plot is to import the Plot component and provide data and layout props. The data prop is an array of trace objects, and the layout prop defines the chart's dimensions and titles.

    import Plot from 'react-plotly.js';
    
    function App() {
      return (
        <Plot
          data={[
            {
              x: [1, 2, 3],
              y: [2, 6, 3],
              type: 'scatter',
              mode: 'lines+markers',
              marker: {color: 'red'},
            },
            {type: 'bar', x: [1, 2, 3], y: [2, 5, 3]},
          ]}
          layout={{width: 320, height: 240, title: {text: 'A Fancy Plot'}}}
        />
      );
    }
  5. Load react-plotly.js via <script> tags

    main

    For quick demos (e.g., JSFiddle), you can load the component via CDN. Note that React is pinned to version 18 in these examples because React 19 does not ship UMD builds. For React 19, use an importmap or a bundler.

    1. Load React and ReactDOM (UMD).
    2. Load plotly.js (CDN).
    3. Load create-plotly-component.min.js.
    4. Use the global createPlotlyComponent to build the component and render it.
    <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
    <script src="https://cdn.plot.ly/plotly-3.6.0.min.js"></script>
    <script src="https://unpkg.com/react-plotly.js@latest/dist/create-plotly-component.min.js"></script>
    const Plot = createPlotlyComponent(Plotly);
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      React.createElement(Plot, {
        data: [{x: [1, 2, 3], y: [2, 1, 3]}],
      })
    );
  6. Customize the plotly.js bundle using createPlotlyComponent

    main

    By default, import Plot from 'react-plotly.js' uses a precompiled version of all of plotly.js (approx. 2MB minified). If you want to use a custom bundle, a partial bundle, or load plotly.js from a CDN, use the createPlotlyComponent factory method instead of the default import.

    To use a custom Plotly object:

    1. Import createPlotlyComponent from react-plotly.js/factory.
    2. Pass your Plotly instance to the factory to create a custom Plot component.
    // simplest method: uses precompiled complete bundle from `plotly.js`
    import Plot from 'react-plotly.js';
    
    // customizable method: use your own `Plotly` object
    import createPlotlyComponent from 'react-plotly.js/factory';
    const Plot = createPlotlyComponent(Plotly);
  7. Understand Figure and FigureCallback types

    main

    When using lifecycle callbacks like onInitialized, onUpdate, or onPurge, you receive a Figure object representing the current snapshot of the plot state.

    Important: The data, layout, and frames properties within the Figure object are the raw plotly.js objects. Because this package avoids a direct dependency on @types/plotly.js, these fields are typed as unknown. If you require specific type safety for these objects, you should manually cast them or re-declare them using types from plotly.js.

    export interface Figure {
      data: unknown[];
      layout: unknown;
      frames: unknown[] | null;
    }
    
    export type FigureCallback = (figure: Figure, graphDiv: HTMLElement) => void;
  8. Understand event naming conventions in react-plotly.js

    main

    The react-plotly.js wrapper maps underlying plotly.js events to React props using a specific naming convention:

    1. Underlying plotly.js events: These are prefixed with plotly_ and use lowercase names (e.g., plotly_click).
    2. React props: These are prefixed with on followed by the event name (e.g., onClick).

    Important Note on triggersUpdate events: Some events (like Relayout, Restyle, or Redraw) are marked as triggersUpdate: true. This means the wrapper listens for these events emitted by plotly.js after the figure has changed and subsequently fires an onUpdate prop.

    Warning: Do not attempt to use triggersUpdate events for cancelable logic (where you might return false to prevent an action). Because the wrapper adds its own listener to handle onUpdate, it may interfere with your ability to cancel the event, as plotly.js typically only respects the return value of the last registered listener.

  9. Make a plot responsive

    main

    To make a plot fill its container and resize automatically with the window, you must:

    1. Leave the width and height properties unset in the layout object.
    2. Set autosize: true in the layout object.
    3. Add the useResizeHandler prop to the <Plot /> component.
    4. Size the wrapper <div> (or the component itself via style) using CSS (e.g., width: '100%', height: '100%').
    <Plot
      data={[{x: [1, 2, 3], y: [2, 6, 3], type: 'scatter'}]}
      layout={{autosize: true, title: {text: 'Responsive'}}}
      style={{width: '100%', height: '100%'}}
      useResizeHandler
    />
  10. Access the graph div via ref

    main

    Attaching a ref to the <Plot /> component resolves to the underlying rendered plotly graph div. This allows you to call low-level plotly.js methods (like Plotly.toImage) directly on the DOM element.

    import {useRef} from 'react';
    import Plot from 'react-plotly.js';
    import Plotly from 'plotly.js';
    
    function ExportButton() {
      const ref = useRef(null);
      const exportPng = async () => {
        const dataUrl = await Plotly.toImage(ref.current, {format: 'png'});
        console.log(dataUrl);
      };
      return (
        <>
          <Plot ref={ref} data={[{x: [1, 2, 3], y: [2, 6, 3], type: 'scatter'}]} layout={{}} />
          <button onClick={exportPng}>Export PNG</button>
        </>
      );
    }
  11. Use TypeScript with react-plotly.js

    main

    The package includes its own declaration files. You can import types like PlotParams and Figure to ensure type safety for your plot configurations and event handlers.

    import Plot, {PlotParams, Figure} from 'react-plotly.js';
    
    const onUpdate = (figure: Figure, gd: HTMLElement) => {
      console.log('figure data length:', figure.data.length, 'gd id:', gd.id);
    };
    
    const params: PlotParams = {
      data: [{x: [1, 2, 3], y: [2, 6, 3], type: 'scatter'}],
      layout: {title: {text: 'Typed'}},
      onUpdate,
    };
    
    export const App = () => <Plot {...params} />;