Skip to content

Commit 3bfd1c8

Browse files
committed
Update README per v4 changes
1 parent 2d8ae17 commit 3bfd1c8

2 files changed

Lines changed: 155 additions & 72 deletions

File tree

README.md

Lines changed: 155 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
# react-plotly.js
22

3-
![plotly-react-logo](https://images.plot.ly/plotly-documentation/thumbnail/react.png)
3+
![plotly-react-logo](plotly-react-logo.png)
44

55
> A [plotly.js](https://github.com/plotly/plotly.js) React component from
6-
> [Plotly](https://plot.ly/). The basis of Plotly's
7-
> [React component suite](https://plot.ly/products/react/).
8-
9-
👉 [DEMO](http://react-plotly.js-demo.getforge.io/)
10-
11-
👉 [Demo source code](https://github.com/plotly/react-plotly.js-demo-app)
6+
> [Plotly](https://plotly.com/).
127
138
<div align="center">
149
<a href="https://dash.plotly.com/project-maintenance">
@@ -24,9 +19,14 @@
2419
- [Quick start](#quick-start)
2520
- [State management](#state-management)
2621
- [Refreshing the Plot](#refreshing-the-plot)
27-
- [API](#api)
22+
- [API](#api-reference)
2823
- [Basic props](#basic-props)
2924
- [Event handler props](#event-handler-props)
25+
- [Examples](#examples)
26+
- [Responsive plot](#responsive-plot)
27+
- [Event handlers](#event-handlers)
28+
- [TypeScript](#typescript)
29+
- [Grabbing the graph div via `ref`](#grabbing-the-graph-div-via-ref)
3030
- [Customizing the `plotly.js` bundle](#customizing-the-plotlyjs-bundle)
3131
- [Loading from a `<script>` tag](#loading-from-a-script-tag)
3232
- [Development](#development)
@@ -42,27 +42,24 @@ $ npm install react-plotly.js plotly.js
4242
The easiest way to use this component is to import and pass data to a plot component:
4343

4444
```javascript
45-
import React from 'react';
4645
import Plot from 'react-plotly.js';
4746

48-
class App extends React.Component {
49-
render() {
50-
return (
51-
<Plot
52-
data={[
53-
{
54-
x: [1, 2, 3],
55-
y: [2, 6, 3],
56-
type: 'scatter',
57-
mode: 'lines+markers',
58-
marker: {color: 'red'},
59-
},
60-
{type: 'bar', x: [1, 2, 3], y: [2, 5, 3]},
61-
]}
62-
layout={{width: 320, height: 240, title: 'A Fancy Plot'}}
63-
/>
64-
);
65-
}
47+
function App() {
48+
return (
49+
<Plot
50+
data={[
51+
{
52+
x: [1, 2, 3],
53+
y: [2, 6, 3],
54+
type: 'scatter',
55+
mode: 'lines+markers',
56+
marker: {color: 'red'},
57+
},
58+
{type: 'bar', x: [1, 2, 3], y: [2, 5, 3]},
59+
]}
60+
layout={{width: 320, height: 240, title: {text: 'A Fancy Plot'}}}
61+
/>
62+
);
6663
}
6764
```
6865

@@ -74,8 +71,8 @@ You should see a plot like this:
7471

7572
For a full description of Plotly chart types and attributes see the following resources:
7673

77-
- [Plotly JavaScript API documentation](https://plot.ly/javascript/)
78-
- [Full plotly.js attribute listing](https://plot.ly/javascript/reference/)
74+
- [Plotly JavaScript API documentation](https://plotly.com/javascript/)
75+
- [Full plotly.js attribute listing](https://plotly.com/javascript/reference/)
7976

8077
## State management
8178

@@ -84,38 +81,35 @@ This is a "dumb" component that doesn't merge its internal state with any update
8481
Here is a simple example of how to capture and store state in a parent object:
8582

8683
```javascript
87-
class App extends React.Component {
88-
constructor(props) {
89-
super(props);
90-
this.state = {data: [], layout: {}, frames: [], config: {}};
91-
}
92-
93-
render() {
94-
return (
95-
<Plot
96-
data={this.state.data}
97-
layout={this.state.layout}
98-
frames={this.state.frames}
99-
config={this.state.config}
100-
onInitialized={(figure) => this.setState(figure)}
101-
onUpdate={(figure) => this.setState(figure)}
102-
/>
103-
);
104-
}
84+
import {useState} from 'react';
85+
import Plot from 'react-plotly.js';
86+
87+
function App() {
88+
const [figure, setFigure] = useState({data: [], layout: {}, frames: [], config: {}});
89+
return (
90+
<Plot
91+
data={figure.data}
92+
layout={figure.layout}
93+
frames={figure.frames}
94+
config={figure.config}
95+
onInitialized={setFigure}
96+
onUpdate={setFigure}
97+
/>
98+
);
10599
}
106100
```
107101

108102
## Refreshing the Plot
109103

110-
This component will refresh the plot via [`Plotly.react`](https://plot.ly/javascript/plotlyjs-function-reference/#plotlyreact) if any of the following are true:
104+
This component will refresh the plot via [`Plotly.react`](https://plotly.com/javascript/plotlyjs-function-reference/#plotlyreact) if any of the following are true:
111105

112106
- The `revision` prop is defined and has changed, OR;
113107
- One of `data`, `layout` or `config` has changed identity as checked via a shallow `===`, OR;
114108
- The number of elements in `frames` has changed
115109

116-
Furthermore, when called, [`Plotly.react`](https://plot.ly/javascript/plotlyjs-function-reference/#plotlyreact) will only refresh the data being plotted if the _identity_ of the data arrays (e.g. `x`, `y`, `marker.color` etc) has changed, or if `layout.datarevision` has changed.
110+
Furthermore, when called, [`Plotly.react`](https://plotly.com/javascript/plotlyjs-function-reference/#plotlyreact) will only refresh the data being plotted if the _identity_ of the data arrays (e.g. `x`, `y`, `marker.color` etc) has changed, or if `layout.datarevision` has changed.
117111

118-
In short, this means that simply adding data points to a trace in `data` or changing a value in `layout` will not cause a plot to update unless this is done immutably via something like [immutability-helper](https://github.com/kolodny/immutability-helper) if performance considerations permit it, or unless `revision` and/or [`layout.datarevision`](https://plot.ly/javascript/reference/#layout-datarevision) are used to force a rerender.
112+
In short, this means that simply adding data points to a trace in `data` or changing a value in `layout` will not cause a plot to update unless this is done immutably via something like [immutability-helper](https://github.com/kolodny/immutability-helper) if performance considerations permit it, or unless `revision` and/or [`layout.datarevision`](https://plotly.com/javascript/reference/#layout-datarevision) are used to force a rerender.
119113

120114
## API Reference
121115

@@ -125,10 +119,10 @@ In short, this means that simply adding data points to a trace in `data` or chan
125119

126120
| Prop | Type | Default | Description |
127121
| ------------------ | ---------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
128-
| `data` | `Array` | `[]` | list of trace objects (see https://plot.ly/javascript/reference/) |
129-
| `layout` | `Object` | `undefined` | layout object (see https://plot.ly/javascript/reference/#layout) |
130-
| `frames` | `Array` | `undefined` | list of frame objects (see https://plot.ly/javascript/reference/) |
131-
| `config` | `Object` | `undefined` | config object (see https://plot.ly/javascript/configuration-options/) |
122+
| `data` | `Array` | `[]` | list of trace objects (see https://plotly.com/javascript/reference/) |
123+
| `layout` | `Object` | `undefined` | layout object (see https://plotly.com/javascript/reference/#layout) |
124+
| `frames` | `Array` | `undefined` | list of frame objects (see https://plotly.com/javascript/reference/) |
125+
| `config` | `Object` | `undefined` | config object (see https://plotly.com/javascript/configuration-options/) |
132126
| `revision` | `Number` | `undefined` | When provided, causes the plot to update when the revision is incremented. |
133127
| `onInitialized` | `Function(figure, graphDiv)` | `undefined` | Callback executed after plot is initialized. See below for parameter information. |
134128
| `onUpdate` | `Function(figure, graphDiv)` | `undefined` | Callback executed when a plot is updated due to new data or layout, or when user interacts with a plot. See below for parameter information. |
@@ -140,7 +134,11 @@ In short, this means that simply adding data points to a trace in `data` or chan
140134
| `debug` | `Boolean` | `false` | Assign the graph div to `window.gd` for debugging |
141135
| `useResizeHandler` | `Boolean` | `false` | When true, adds a call to `Plotly.Plot.resize()` as a `window.resize` event handler |
142136

143-
**Note**: To make a plot responsive, i.e. to fill its containing element and resize when the window is resized, use `style` or `className` to set the dimensions of the element (i.e. using `width: 100%; height: 100%` or some similar values) and set `useResizeHandler` to `true` while setting `layout.autosize` to `true` and leaving `layout.height` and `layout.width` undefined. This can be seen in action in [this CodePen](https://codepen.io/nicolaskruchten/pen/ERgBZX) and will implement the behaviour documented here: https://plot.ly/javascript/responsive-fluid-layout/
137+
**Refs**: a `ref` attached to `<Plot>` resolves to the rendered `<div>` element (the plotly graph div), so you can call low-level plotly.js APIs against it directly (e.g. `Plotly.toImage(ref.current)`).
138+
139+
**TypeScript**: this package ships its own declaration files. Trace and layout shapes are typed as `unknown` since the wrapper does not bind to a specific plotly.js type surface; consumers wanting tighter typing on the `data` / `layout` props can re-declare them locally.
140+
141+
**Note**: To make a plot responsive, i.e. to fill its containing element and resize when the window is resized, use `style` or `className` to set the dimensions of the element (i.e. using `width: 100%; height: 100%` or some similar values) and set `useResizeHandler` to `true` while setting `layout.autosize` to `true` and leaving `layout.height` and `layout.width` undefined. A short example is in the [Responsive plot](#responsive-plot) section below. See also the [responsive layout reference](https://plotly.com/javascript/responsive-fluid-layout/).
144142

145143
#### Callback signature: `Function(figure, graphDiv)`
146144

@@ -152,7 +150,7 @@ The `onInitialized`, `onUpdate` and `onPurge` props are all functions which will
152150

153151
### Event handler props
154152

155-
Event handlers for specific [`plotly.js` events](https://plot.ly/javascript/plotlyjs-events/) may be attached through the following props:
153+
Event handlers for specific [`plotly.js` events](https://plotly.com/javascript/plotlyjs-events/) may be attached through the following props:
156154

157155
| Prop | Type | Plotly Event |
158156
| ------------------------- | ---------- | ------------------------------ |
@@ -190,6 +188,85 @@ Event handlers for specific [`plotly.js` events](https://plot.ly/javascript/plot
190188
| `onUnhover` | `Function` | `plotly_unhover` |
191189
| `onWebGlContextLost` | `Function` | `plotly_webglcontextlost` |
192190

191+
## Examples
192+
193+
### Responsive plot
194+
195+
To make the plot fill its container and resize with the window, leave the layout's `width`/`height` unset, enable `autosize`, and turn on `useResizeHandler`. Size the wrapper `<div>` with `style` or `className`:
196+
197+
```javascript
198+
<Plot
199+
data={[{x: [1, 2, 3], y: [2, 6, 3], type: 'scatter'}]}
200+
layout={{autosize: true, title: {text: 'Responsive'}}}
201+
style={{width: '100%', height: '100%'}}
202+
useResizeHandler
203+
/>
204+
```
205+
206+
### Event handlers
207+
208+
All [plotly.js events](https://plotly.com/javascript/plotlyjs-events/) are surfaced as `on<EventName>` props (see the [Event handler props](#event-handler-props) table). Each handler receives the raw plotly.js event payload:
209+
210+
```javascript
211+
<Plot
212+
data={[{x: [1, 2, 3], y: [2, 6, 3], type: 'scatter', mode: 'markers'}]}
213+
layout={{title: {text: 'Click me'}}}
214+
onClick={(event) => {
215+
const point = event.points[0];
216+
console.log(`clicked (${point.x}, ${point.y})`);
217+
}}
218+
onRelayout={(event) => {
219+
if (event['xaxis.range[0]']) {
220+
console.log('user zoomed to', event['xaxis.range[0]'], event['xaxis.range[1]']);
221+
}
222+
}}
223+
/>
224+
```
225+
226+
### TypeScript
227+
228+
The package ships its own declaration files.
229+
230+
```typescript
231+
import Plot, {PlotParams, Figure} from 'react-plotly.js';
232+
233+
const onUpdate = (figure: Figure, gd: HTMLElement) => {
234+
console.log('figure data length:', figure.data.length, 'gd id:', gd.id);
235+
};
236+
237+
const params: PlotParams = {
238+
data: [{x: [1, 2, 3], y: [2, 6, 3], type: 'scatter'}],
239+
layout: {title: {text: 'Typed'}},
240+
onUpdate,
241+
};
242+
243+
export const App = () => <Plot {...params} />;
244+
```
245+
246+
### Grabbing the graph div via `ref`
247+
248+
A `ref` attached to `<Plot>` resolves to the rendered plotly graph div. Use it to call low-level plotly.js APIs:
249+
250+
```javascript
251+
import {useRef} from 'react';
252+
import Plot from 'react-plotly.js';
253+
import Plotly from 'plotly.js';
254+
255+
function ExportButton() {
256+
const ref = useRef(null);
257+
const exportPng = async () => {
258+
const dataUrl = await Plotly.toImage(ref.current, {format: 'png'});
259+
console.log(dataUrl);
260+
};
261+
return (
262+
<>
263+
<Plot ref={ref} data={[{x: [1, 2, 3], y: [2, 6, 3], type: 'scatter'}]} layout={{}} />
264+
<button onClick={exportPng}>Export PNG</button>
265+
</>
266+
);
267+
}
268+
```
269+
193270
## Customizing the `plotly.js` bundle
194271

195272
By default, the `Plot` component exported by this library loads a precompiled version of all of `plotly.js`, so `plotly.js` must be installed as a peer dependency. This bundle is around 6Mb unminified, and minifies to just over 2Mb.
@@ -207,31 +284,29 @@ const Plot = createPlotlyComponent(Plotly);
207284

208285
## Loading from a `<script>` tag
209286

210-
For quick one-off demos on [CodePen](https://codepen.io/) or [JSFiddle](https://jsfiddle.net/), you may wish to just load the component directly as a script tag. We don't host the bundle directly, so you should never rely on this to work forever or in production, but you can use a third-party service to load the factory version of the component from, for example, [https://unpkg.com/react-plotly.js@latest/dist/create-plotly-component.min.js](https://unpkg.com/react-plotly.js@latest/dist/create-plotly-component.min.js).
211-
212-
You can load plotly.js and the component factory with:
287+
For quick one-off demos in JSFiddle or similar environments, you can load the component directly as a script tag. We don't host the bundle ourselves, so don't rely on this in production, but you can pull it from a CDN such as [unpkg](https://unpkg.com) or [jsdelivr](https://www.jsdelivr.com):
213288

214289
```html
215-
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
290+
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
291+
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
292+
<script src="https://cdn.plot.ly/plotly-3.6.0.min.js"></script>
216293
<script src="https://unpkg.com/react-plotly.js@latest/dist/create-plotly-component.min.js"></script>
217294
```
218295

219-
And instantiate the component with
296+
React is pinned to 18 here because React 19 stopped shipping UMD builds; consumers wanting React 19 should load it via [importmap](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap) or use a bundler.
297+
298+
The factory is exposed as the global `createPlotlyComponent`. Build the component and mount it:
220299

221300
```javascript
222301
const Plot = createPlotlyComponent(Plotly);
223-
224-
ReactDOM.render(
302+
const root = ReactDOM.createRoot(document.getElementById('root'));
303+
root.render(
225304
React.createElement(Plot, {
226305
data: [{x: [1, 2, 3], y: [2, 1, 3]}],
227-
}),
228-
document.getElementById('root')
306+
})
229307
);
230308
```
231309

232-
You can see an example of this method in action
233-
[here](https://codepen.io/rsreusser/pen/qPgwwJ?editors=1010).
234-
235310
## Development
236311

237312
To get started:
@@ -240,18 +315,26 @@ To get started:
240315
$ npm install
241316
```
242317

243-
To transpile from ES2015 + JSX into the ES5 npm-distributed version:
318+
To build the published artifacts (`dist/index.{mjs,cjs}`, `dist/factory.{mjs,cjs}`, the UMD bundle, and the declaration files) via [tsup](https://tsup.egoist.dev/):
244319

245320
```bash
246-
$ npm run prepublishOnly
321+
$ npm run build
247322
```
248323

249-
To run the tests:
324+
To run lint + typecheck + jest:
250325

251326
```bash
252327
$ npm run test
253328
```
254329

330+
To watch source files and rebuild on change:
331+
332+
```bash
333+
$ npm run watch
334+
```
335+
336+
Releases are cut from `master` per the steps in [`RELEASE.md`](./RELEASE.md).
337+
255338
## License
256339

257-
&copy; 2017-2020 Plotly, Inc. MIT License.
340+
&copy; 2017-2026 Plotly, Inc. MIT License.

plotly-react-logo.png

3.1 KB
Loading

0 commit comments

Comments
 (0)