diff --git a/README.md b/README.md index ebabfad..ab10015 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) ============= @@ -15,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: @@ -62,9 +62,53 @@ Here's a simple example render method: displayModeBar: true }; return ( - + ); } +``` + + + +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..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', this.props.onClick); - if (this.props.onBeforeHover) - this.container.on('plotly_beforehover', this.props.onBeforeHover); - if (this.props.onHover) - this.container.on('plotly_hover', this.props.onHover); - if (this.props.onUnHover) - this.container.on('plotly_unhover', this.props.onUnHover); - if (this.props.onSelected) - this.container.on('plotly_selected', this.props.onSelected); - }, +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