From 92324a348de1199b74e570d30e23a64cd25432d5 Mon Sep 17 00:00:00 2001 From: acailly Date: Tue, 25 Apr 2017 17:46:49 +0200 Subject: [PATCH 1/3] :sparkles: Now pass container element in listeners --- README.md | 45 ++++++++++++++++++++++++++++++++++++++++++ src/PlotlyComponent.js | 10 +++++----- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ebabfad..c4e81d2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ + React-PlotlyJS [![npm version](https://badge.fury.io/js/react-plotlyjs.svg)](http://badge.fury.io/js/react-plotlyjs) ============= @@ -65,6 +66,50 @@ Here's a simple example render method: ); } +``` + + + +To add some interaction to the graph, you can use the following handlers: + +- onClick(data, graphDiv) +- onBeforeHover(graphDiv) +- onHover(data, graphDiv) +- onUnHover(data, graphDiv) +- onSelected(eventData, graphDiv) + +For more information, see https://plot.ly/javascript/plotlyjs-events/. + +```javascript + +function handler(data, graphDiv){ + var pn='', + tn='', + colors=[]; + for(var i=0; i < data.points.length; i++){ + pn = data.points[i].pointNumber; + tn = data.points[i].curveNumber; + colors = data.points[i].data.marker.color; + }; + colors[pn] = '#C54C82'; + var update = {'marker':{color: colors, size:16}}; + Plotly.restyle(graphDiv, update, [tn]); +}); + +render() { + let data = [ + ... + ]; + let layout = { + ... + }; + let config = { + ... + }; + return ( + + ); + } ``` diff --git a/src/PlotlyComponent.js b/src/PlotlyComponent.js index 6c409a1..0f9ea28 100644 --- a/src/PlotlyComponent.js +++ b/src/PlotlyComponent.js @@ -16,15 +16,15 @@ let createPlotlyComponent = (plotlyInstance) => React.createClass({ attachListeners: function() { if (this.props.onClick) - this.container.on('plotly_click', this.props.onClick); + this.container.on('plotly_click', (data) => this.props.onClick(data, this.container)); if (this.props.onBeforeHover) - this.container.on('plotly_beforehover', this.props.onBeforeHover); + this.container.on('plotly_beforehover', () => this.props.onBeforeHover(this.container)); if (this.props.onHover) - this.container.on('plotly_hover', this.props.onHover); + this.container.on('plotly_hover', (data) => this.props.onHover(data, this.container)); if (this.props.onUnHover) - this.container.on('plotly_unhover', this.props.onUnHover); + this.container.on('plotly_unhover', (data) => this.props.onUnHover(data, this.container)); if (this.props.onSelected) - this.container.on('plotly_selected', this.props.onSelected); + this.container.on('plotly_selected', (eventData) => this.props.onSelected(eventData, this.container)); }, shouldComponentUpdate(nextProps) { From 765ac2227cbc8b2327ec3ebbf2025015973ccc30 Mon Sep 17 00:00:00 2001 From: acailly Date: Tue, 25 Apr 2017 18:09:33 +0200 Subject: [PATCH 2/3] :hammer: Use new ES6 syntax --- README.md | 7 ++- src/PlotlyComponent.js | 112 ++++++++++++++++++++--------------------- 2 files changed, 57 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index c4e81d2..ab10015 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,9 @@ As the full Plotly bundle is huge, this library lets you pass a custom bundle to ```javascript -import createPlotlyComponent from 'react-plotlyjs'; +import PlotlyComponent from 'react-plotlyjs'; //See the list of possible plotly bundles at https://github.com/plotly/plotly.js/blob/master/dist/README.md#partial-bundles or roll your own import Plotly from 'plotly.js/dist/plotly-cartesian'; -const PlotlyComponent = createPlotlyComponent(Plotly); ``` Here's a simple example render method: @@ -63,7 +62,7 @@ Here's a simple example render method: displayModeBar: true }; return ( - + ); } ``` @@ -108,7 +107,7 @@ render() { ... }; return ( - + ); } ``` diff --git a/src/PlotlyComponent.js b/src/PlotlyComponent.js index 0f9ea28..130e8c8 100644 --- a/src/PlotlyComponent.js +++ b/src/PlotlyComponent.js @@ -1,70 +1,66 @@ -import React from 'react'; -import cloneDeep from 'lodash.clonedeep'; +import React from 'react' +import cloneDeep from 'lodash.clonedeep' +import PropTypes from 'prop-types' -let createPlotlyComponent = (plotlyInstance) => React.createClass({ - displayName: 'Plotly', - propTypes: { - data: React.PropTypes.array, - layout: React.PropTypes.object, - config: React.PropTypes.object, - onClick: React.PropTypes.func, - onBeforeHover: React.PropTypes.func, - onHover: React.PropTypes.func, - onUnHover: React.PropTypes.func, - onSelected: React.PropTypes.func - }, - - attachListeners: function() { - if (this.props.onClick) - this.container.on('plotly_click', (data) => this.props.onClick(data, this.container)); - if (this.props.onBeforeHover) - this.container.on('plotly_beforehover', () => this.props.onBeforeHover(this.container)); - if (this.props.onHover) - this.container.on('plotly_hover', (data) => this.props.onHover(data, this.container)); - if (this.props.onUnHover) - this.container.on('plotly_unhover', (data) => this.props.onUnHover(data, this.container)); - if (this.props.onSelected) - this.container.on('plotly_selected', (eventData) => this.props.onSelected(eventData, this.container)); - }, +class PlotlyComponent extends React.Component { + attachListeners () { + if (this.props.onClick) { this.container.on('plotly_click', (data) => this.props.onClick(data, this.container)) } + if (this.props.onBeforeHover) { this.container.on('plotly_beforehover', () => this.props.onBeforeHover(this.container)) } + if (this.props.onHover) { this.container.on('plotly_hover', (data) => this.props.onHover(data, this.container)) } + if (this.props.onUnHover) { this.container.on('plotly_unhover', (data) => this.props.onUnHover(data, this.container)) } + if (this.props.onSelected) { this.container.on('plotly_selected', (eventData) => this.props.onSelected(eventData, this.container)) } + } - shouldComponentUpdate(nextProps) { - //TODO logic for detecting change in props - return true; - }, + shouldComponentUpdate (nextProps) { + // TODO logic for detecting change in props + return true + } - componentDidMount() { - let {data, layout, config} = this.props; - plotlyInstance.newPlot(this.container, data, cloneDeep(layout), config); //We clone the layout as plotly mutates it. - this.attachListeners(); - }, + componentDidMount () { + let {data, layout, config, plotly} = this.props + plotly.newPlot(this.container, data, cloneDeep(layout), config) // We clone the layout as plotly mutates it. + this.attachListeners() + } - componentDidUpdate(prevProps) { - //TODO use minimal update for given changes + componentDidUpdate (prevProps) { + // TODO use minimal update for given changes if (prevProps.data !== this.props.data || prevProps.layout !== this.props.layout) { - plotlyInstance.newPlot(this.container, this.props.data, this.props.layout); - this.attachListeners(); + this.props.plotly.newPlot(this.container, this.props.data, this.props.layout) + this.attachListeners() } - }, + } - componentWillUnmount: function() { - plotlyInstance.purge(this.container); - }, + componentWillUnmount () { + this.props.plotly.purge(this.container) + } - resize: function() { - plotlyInstance.Plots.resize(this.container); - }, + resize () { + this.props.plotly.Plots.resize(this.container) + } - render: function () { - let {data, layout, config, ...other } = this.props; - //Remove props that would cause React to warn for unknown props. - delete other.onClick; - delete other.onBeforeHover; - delete other.onHover; - delete other.onUnHover; - delete other.onSelected; + render () { + let { plotly, data, layout, config, ...other } = this.props + // Remove props that would cause React to warn for unknown props. + delete other.onClick + delete other.onBeforeHover + delete other.onHover + delete other.onUnHover + delete other.onSelected - return
this.container=node} /> + return
this.container = node} /> } -}); +} + +PlotlyComponent.propTypes = { + plotly: PropTypes.object, + data: PropTypes.array, + layout: PropTypes.object, + config: PropTypes.object, + onClick: PropTypes.func, + onBeforeHover: PropTypes.func, + onHover: PropTypes.func, + onUnHover: PropTypes.func, + onSelected: PropTypes.func +} -export default createPlotlyComponent; +export default PlotlyComponent From 8f735aa9b72fcafec1dd788b3dca553b269f86aa Mon Sep 17 00:00:00 2001 From: acailly Date: Tue, 25 Apr 2017 18:16:16 +0200 Subject: [PATCH 3/3] :sparkles: Added resize with window feature --- README.md | 16 ++++++++++++++++ src/PlotlyComponent.js | 5 ++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ab10015..1bf1f51 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ This is a very early, simple wrapper with the following problems: However it does support event handling via the onClick, onBeforeHover, onHover, onUnHover and onSelected props. Note that currently, however, changes to these event handlers after initial creation will not be propogated. + + +## Getting started + As the full Plotly bundle is huge, this library lets you pass a custom bundle to create the component. Therefore you will need Plotly as a direct dependancy of your project. @@ -69,6 +73,8 @@ Here's a simple example render method: +## Event Handling + To add some interaction to the graph, you can use the following handlers: - onClick(data, graphDiv) @@ -112,3 +118,13 @@ render() { } ``` + + +## Resize with window + +To make the plot redraw when the window size changes, you can use the `resizeWithWindow` prop. + +```javascript +*/resizeWithWindow data={data} layout={layout} config={config} onClick={handler}/> +``` + diff --git a/src/PlotlyComponent.js b/src/PlotlyComponent.js index 130e8c8..e169a94 100644 --- a/src/PlotlyComponent.js +++ b/src/PlotlyComponent.js @@ -19,6 +19,7 @@ class PlotlyComponent extends React.Component { componentDidMount () { let {data, layout, config, plotly} = this.props plotly.newPlot(this.container, data, cloneDeep(layout), config) // We clone the layout as plotly mutates it. + if (this.props.resizeWithWindow) window.addEventListener('resize', this.resize.bind(this)) this.attachListeners() } @@ -31,6 +32,7 @@ class PlotlyComponent extends React.Component { } componentWillUnmount () { + if (this.props.resizeWithWindow) window.removeEventListener('resize', this.resize.bind(this)) this.props.plotly.purge(this.container) } @@ -60,7 +62,8 @@ PlotlyComponent.propTypes = { onBeforeHover: PropTypes.func, onHover: PropTypes.func, onUnHover: PropTypes.func, - onSelected: PropTypes.func + onSelected: PropTypes.func, + resizeWithWindow: PropTypes.bool } export default PlotlyComponent