` into which the plot is rendered |
-| `frames` | `Array` | `undefined` | list of frame objects |
-| `useResizeHandler` | `Boolean` | `false` | When true, adds a call to `Plotly.Plot.resize()` as a `window.resize` event handler |
-| `revision` | `Number` | `undefined` | When provided, causes the plot to update _only_ when the revision is incremented. |
-| `debug` | `Boolean` | `false` | Assign the graph div to `window.gd` for debugging |
-| `onInitialized` | `Function` | `undefined` | Callback executed after plot is initialized. This function recieves a reference to the `
` DOM node as an argument, from which `data`, `layout`, `config`, and `frames` can be extracted and persisted. |
-| `onPurge` | `Function` | `undefined` | Callback executed when component unmounts. Unmounting triggers a Plotly.purge event which strips the graphDiv of all plotly.js related information including data and layout. This hook gives application writers a chance to pull data and layout off the DOM. |
-| `onUpdate` | `Function` | `undefined` | Callback executed when a plotly.js API method resolves. This function recieves a reference to the `
` DOM node as an argument, from which `data`, `layout`, `config`, and `frames` can be extracted and persisted. |
-| `onError` | `Function` | `undefined` | Callback executed when a plotly.js API method rejects |
-| `fit` | `Boolean` | `false` | _deprecated_ When true, will set `layout.height` and `layout.width` to the component's parent's size if they are unspecified, and will update them on `window.resize` |
-
-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 will implement the behaviour documented here: https://plot.ly/javascript/responsive-fluid-layout/
+* `figure` is a serializable object with three keys corresponding to input props: `data`, `layout` and `frames`.
+ * As mentioned above, for the time being, this component may _mutate_ its `layout` and `data` props in response to user input, going against React rules. This behaviour will change in the near future once https://github.com/plotly/plotly.js/issues/2389 is completed.
+* `graphDiv` is a reference to the (unserializable) DOM node into which the figure was rendered.
### Event handler props
-Event handlers for
-[`plotly.js` events](https://plot.ly/javascript/plotlyjs-events/) may be
-attached through the following props.
+Event handlers for specific [`plotly.js` events](https://plot.ly/javascript/plotlyjs-events/) may be attached through the following props:
| Prop | Type | Plotly Event |
| ------------------------- | ---------- | ------------------------------ |
@@ -183,6 +178,48 @@ attached through the following props.
| `onTransitionInterrupted` | `Function` | `plotly_transitioninterrupted` |
| `onUnhover` | `Function` | `plotly_unhover` |
+## Customizing the `plotly.js` bundle
+
+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.
+
+If you do not wish to use this version of `plotly.js`, e.g. if you want to use a [different precompiled bundle](https://github.com/plotly/plotly.js/blob/master/dist/README.md#partial-bundles) or if your wish to [assemble you own customized bundle](https://github.com/plotly/plotly.js#modules), or if you wish to load `plotly.js` [from a CDN](https://github.com/plotly/plotly.js#use-the-plotlyjs-cdn-hosted-by-fastly), you can skip the installation of as a peer dependency (and ignore the resulting warning) and use the `createPlotComponent` method to get a `Plot` component, instead of importing it:
+
+```javascript
+// 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);
+```
+
+## Loading from a `
+
+```
+
+And instantiate the component with
+
+```javascript
+const Plot = createPlotlyComponent(Plotly);
+
+ReactDOM.render(
+ React.createElement(Plot, {
+ data: [{x: [1, 2, 3], y: [2, 1, 3]}],
+ }),
+ document.getElementById('root')
+);
+```
+
+You can see an example of this method in action
+[here](https://codepen.io/rsreusser/pen/qPgwwJ?editors=1010).
+
## Development
To get started:
diff --git a/src/factory.js b/src/factory.js
index ff4b786..c704f47 100644
--- a/src/factory.js
+++ b/src/factory.js
@@ -63,7 +63,7 @@ export default function plotComponentFactory(Plotly) {
this.attachUpdateEvents = this.attachUpdateEvents.bind(this);
this.getRef = this.getRef.bind(this);
this.handleUpdate = this.handleUpdate.bind(this);
- this.handleUpdateWithProps = this.handleUpdateWithProps.bind(this);
+ this.figureCallback = this.figureCallback.bind(this);
}
componentDidMount() {
@@ -79,12 +79,10 @@ export default function plotComponentFactory(Plotly) {
.then(() => this.syncWindowResize(null, false))
.then(this.syncEventHandlers)
.then(this.attachUpdateEvents)
- .then(
- () => this.props.onInitialized && this.props.onInitialized(this.el)
- )
- .catch(e => {
- console.error('Error while plotting:', e);
- return this.props.onError && this.props.onError();
+ .then(() => this.figureCallback(this.props.onInitialized))
+ .catch(err => {
+ console.error('Error while plotting:', err);
+ return this.props.onError && this.props.onError(err);
});
}
@@ -124,7 +122,7 @@ export default function plotComponentFactory(Plotly) {
.then(() => {
if (!hasReactAPIMethod) this.attachUpdateEvents();
})
- .then(() => this.handleUpdateWithProps(nextProps))
+ .then(() => this.figureCallback(nextProps.onUpdate))
.catch(err => {
console.error('Error while plotting:', err);
this.props.onError && this.props.onError(err);
@@ -132,9 +130,8 @@ export default function plotComponentFactory(Plotly) {
}
componentWillUnmount() {
- if (this.props.onPurge) {
- this.props.onPurge(this.el);
- }
+ this.figureCallback(this.props.onPurge);
+
if (this.fitHandler && isBrowser) {
window.removeEventListener('resize', this.fitHandler);
this.fitHandler = null;
@@ -166,12 +163,14 @@ export default function plotComponentFactory(Plotly) {
}
handleUpdate() {
- this.handleUpdateWithProps(this.props);
+ this.figureCallback(this.props.onUpdate);
}
- handleUpdateWithProps(props) {
- if (props.onUpdate && typeof props.onUpdate === 'function') {
- props.onUpdate(this.el);
+ figureCallback(callback) {
+ if (typeof callback === 'function') {
+ const {data, layout, _transitionData: {_frames: frames}} = this.el;
+ const figure = {data, layout, frames}; // for extra clarity!
+ callback(figure, this.el);
}
}