From 6f98f2349a55c4795939c1d81d280bd71940ed4d Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Tue, 6 Mar 2018 21:54:41 -0500 Subject: [PATCH 1/9] first stab at combined component --- dev/App.js | 69 ++++++++++--------------------------- src/PlotlyEditor.js | 14 ++++---- src/PlotlyEditorWithPlot.js | 58 +++++++++++++++++++++++++++++++ src/index.js | 2 ++ 4 files changed, 86 insertions(+), 57 deletions(-) create mode 100644 src/PlotlyEditorWithPlot.js diff --git a/dev/App.js b/dev/App.js index 9cdf97b18..1ee316f4c 100644 --- a/dev/App.js +++ b/dev/App.js @@ -1,10 +1,9 @@ import React, {Component} from 'react'; import {hot} from 'react-hot-loader'; import plotly from 'plotly.js/dist/plotly'; -import createPlotComponent from 'react-plotly.js/factory'; -import PlotlyEditor from '../src'; import '../src/styles/main.scss'; import Nav from './Nav'; +import {PlotlyEditorWithPlot} from '../src'; // https://github.com/plotly/react-chart-editor#mapbox-access-tokens import ACCESS_TOKENS from '../accessTokens'; @@ -22,18 +21,13 @@ const dataSourceOptions = Object.keys(dataSources).map(name => ({ label: name, })); -const Plot = createPlotComponent(plotly); - class App extends Component { constructor() { super(); - // The graphDiv object is passed to Plotly.js, which then causes it to be - // overwritten with a full DOM node that contains data, layout, _fullData, - // _fullLayout etc in handlePlotUpdate() this.state = { - graphDiv: {}, - plotRevision: 0, + data: [], + layout: {}, currentMockIndex: -1, mocks: [], }; @@ -49,14 +43,6 @@ class App extends Component { .then(mocks => this.setState({mocks})); } - handlePlotUpdate(graphDiv) { - this.setState({graphDiv}); - } - - handleEditorUpdate() { - this.setState(({plotRevision: x}) => ({plotRevision: x + 1})); - } - loadMock(mockIndex) { const mock = this.state.mocks[mockIndex]; fetch(mock.url, { @@ -64,46 +50,29 @@ class App extends Component { }) .then(response => response.json()) .then(figure => { - const graphDiv = this.state.graphDiv; - graphDiv.layout = figure.layout; - graphDiv.data = figure.data; - this.setState(({plotRevision: x}) => ({ + this.setState({ currentMockIndex: mockIndex, - plotRevision: x + 1, - })); + data: figure.data, + layout: figure.layout, + }); }); } render() { return (
-
- -
- -
-
+ this.setState({data, layout})} + useResizeHandler + debug + advancedTraceTypeSelector + />
+ ); + } +} + +PlotlyEditorWithPlot.propTypes = { + layout: PropTypes.object, + data: PropTypes.array, + config: PropTypes.object, + dataSourceOptions: PropTypes.array, + dataSources: PropTypes.object, + onUpdate: PropTypes.func, + plotly: PropTypes.object, + useResizeHandler: PropTypes.bool, + debug: PropTypes.bool, + advancedTraceTypeSelector: PropTypes.bool, +}; + +export default PlotlyEditorWithPlot; diff --git a/src/index.js b/src/index.js index e12d09930..5c8651829 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,5 @@ import PlotlyEditor from './PlotlyEditor'; +import PlotlyEditorWithPlot from './PlotlyEditorWithPlot'; import { connectAnnotationToLayout, connectShapeToLayout, @@ -141,6 +142,7 @@ export { localize, localizeString, walkObject, + PlotlyEditorWithPlot, }; export default PlotlyEditor; From 80b359dfd4e431b751f6e2a72a64a445acf46cea Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Wed, 7 Mar 2018 11:12:46 -0500 Subject: [PATCH 2/9] track new version of react-plotly.js --- dev/App.js | 4 +++- src/PlotlyEditor.js | 26 +++++++++++++++++++------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/dev/App.js b/dev/App.js index 1ee316f4c..ace6d0fb8 100644 --- a/dev/App.js +++ b/dev/App.js @@ -21,6 +21,8 @@ const dataSourceOptions = Object.keys(dataSources).map(name => ({ label: name, })); +const config = {mapboxAccessToken: ACCESS_TOKENS.MAPBOX, editable: true}; + class App extends Component { constructor() { super(); @@ -64,7 +66,7 @@ class App extends Component { Date: Wed, 7 Mar 2018 14:27:15 -0500 Subject: [PATCH 3/9] renaming reshuffle --- dev/App.js | 4 +- src/EditorControls.js | 292 ++++++++++++++++++++++++++++++++++ src/PlotlyEditor.js | 308 +++++------------------------------- src/PlotlyEditorWithPlot.js | 58 ------- src/index.js | 4 +- 5 files changed, 333 insertions(+), 333 deletions(-) create mode 100644 src/EditorControls.js delete mode 100644 src/PlotlyEditorWithPlot.js diff --git a/dev/App.js b/dev/App.js index ace6d0fb8..76455891f 100644 --- a/dev/App.js +++ b/dev/App.js @@ -3,7 +3,7 @@ import {hot} from 'react-hot-loader'; import plotly from 'plotly.js/dist/plotly'; import '../src/styles/main.scss'; import Nav from './Nav'; -import {PlotlyEditorWithPlot} from '../src'; +import PlotlyEditor from '../src'; // https://github.com/plotly/react-chart-editor#mapbox-access-tokens import ACCESS_TOKENS from '../accessTokens'; @@ -63,7 +63,7 @@ class App extends Component { render() { return (
- { + const axis = trace[payload.axisAttrToAdjust].charAt(0); + const currentAxisIdNumber = Number( + trace[payload.axisAttrToAdjust].slice(1) + ); + const adjustedAxisIdNumber = currentAxisIdNumber - 1; + + const currentAxisLayoutProperties = { + ...graphDiv.layout[payload.axisAttrToAdjust + currentAxisIdNumber], + }; + + // for cases when we're adjusting x2 => x, so that it becomes x not x1 + graphDiv.data[trace.index][payload.axisAttrToAdjust] = + adjustedAxisIdNumber === 1 ? axis : axis + adjustedAxisIdNumber; + + graphDiv.layout[ + payload.axisAttrToAdjust + adjustedAxisIdNumber + ] = currentAxisLayoutProperties; + }); + } + } + + handleUpdate({type, payload}) { + const {graphDiv} = this.props; + + switch (type) { + case EDITOR_ACTIONS.UPDATE_TRACES: + if (this.props.beforeUpdateTraces) { + this.props.beforeUpdateTraces(payload); + } + + // until we start utilizing Plotly.react in `react-plotly.js` + // force clear axes types when a `src` has changed. + maybeClearAxisTypes(graphDiv, payload.traceIndexes, payload.update); + + this.maybeAdjustAxisRef(payload); + + for (let i = 0; i < payload.traceIndexes.length; i++) { + for (const attr in payload.update) { + const traceIndex = payload.traceIndexes[i]; + const prop = nestedProperty(graphDiv.data[traceIndex], attr); + const value = payload.update[attr]; + + if (value !== void 0) { + prop.set(value); + } + } + } + + if (this.props.afterUpdateTraces) { + this.props.afterUpdateTraces(payload); + } + if (this.props.onUpdate) { + this.props.onUpdate(graphDiv.data.slice(), graphDiv.layout); + } + break; + + case EDITOR_ACTIONS.UPDATE_LAYOUT: + if (this.props.beforeUpdateLayout) { + this.props.beforeUpdateLayout(payload); + } + for (const attr in payload.update) { + const prop = nestedProperty(graphDiv.layout, attr); + const value = payload.update[attr]; + if (value !== void 0) { + prop.set(value); + } + } + if (this.props.afterUpdateLayout) { + this.props.afterUpdateLayout(payload); + } + if (this.props.onUpdate) { + this.props.onUpdate( + graphDiv.data, + Object.assign({}, graphDiv.layout) + ); + } + break; + + case EDITOR_ACTIONS.ADD_TRACE: + if (this.props.beforeAddTrace) { + this.props.beforeAddTrace(payload); + } + graphDiv.data.push({type: 'scatter', mode: 'markers'}); + if (this.props.afterAddTrace) { + this.props.afterAddTrace(payload); + } + if (this.props.onUpdate) { + this.props.onUpdate(graphDiv.data.slice(), graphDiv.layout); + } + break; + + case EDITOR_ACTIONS.DELETE_TRACE: + if (payload.traceIndexes && payload.traceIndexes.length) { + if (this.props.beforeDeleteTrace) { + this.props.beforeDeleteTrace(payload); + } + graphDiv.data.splice(payload.traceIndexes[0], 1); + if (this.props.afterDeleteTrace) { + this.props.afterDeleteTrace(payload); + } + if (this.props.onUpdate) { + this.props.onUpdate(graphDiv.data.slice(), graphDiv.layout); + } + } + break; + + case EDITOR_ACTIONS.DELETE_ANNOTATION: + if (isNumeric(payload.annotationIndex)) { + if (this.props.beforeDeleteAnnotation) { + this.props.beforeDeleteAnnotation(payload); + } + graphDiv.layout.annotations.splice(payload.annotationIndex, 1); + if (this.props.afterDeleteAnnotation) { + this.props.afterDeleteAnnotation(payload); + } + if (this.props.onUpdate) { + this.props.onUpdate( + graphDiv.data, + Object.assign({}, graphDiv.layout) + ); + } + } + break; + + case EDITOR_ACTIONS.DELETE_SHAPE: + if (isNumeric(payload.shapeIndex)) { + if (this.props.beforeDeleteShape) { + this.props.beforeDeleteShape(payload); + } + graphDiv.layout.shapes.splice(payload.shapeIndex, 1); + if (this.props.afterDeleteShape) { + this.props.afterDeleteShape(payload); + } + if (this.props.onUpdate) { + this.props.onUpdate( + graphDiv.data, + Object.assign({}, graphDiv.layout) + ); + } + } + break; + + case EDITOR_ACTIONS.DELETE_IMAGE: + if (isNumeric(payload.imageIndex)) { + if (this.props.beforeDeleteImage) { + this.props.beforeDeleteImage(payload); + } + graphDiv.layout.images.splice(payload.imageIndex, 1); + if (this.props.afterDeleteImage) { + this.props.afterDeleteImage(payload); + } + if (this.props.onUpdate) { + this.props.onUpdate( + graphDiv.data, + Object.assign({}, graphDiv.layout) + ); + } + } + break; + + default: + throw new Error('must specify an action type to handleEditorUpdate'); + } + } + + render() { + return ( +
+ + {this.props.graphDiv && + this.props.graphDiv._fullLayout && + (this.props.children ? this.props.children : )} + +
+ ); + } +} + +EditorControls.propTypes = { + advancedTraceTypeSelector: PropTypes.bool, + afterAddTrace: PropTypes.func, + afterDeleteAnnotation: PropTypes.func, + afterDeleteShape: PropTypes.func, + afterDeleteImage: PropTypes.func, + afterDeleteTrace: PropTypes.func, + afterUpdateLayout: PropTypes.func, + afterUpdateTraces: PropTypes.func, + beforeAddTrace: PropTypes.func, + beforeDeleteAnnotation: PropTypes.func, + beforeDeleteShape: PropTypes.func, + beforeDeleteImage: PropTypes.func, + beforeDeleteTrace: PropTypes.func, + beforeUpdateLayout: PropTypes.func, + beforeUpdateTraces: PropTypes.func, + children: PropTypes.node, + className: PropTypes.string, + dataSourceOptionRenderer: PropTypes.func, + dataSourceOptions: PropTypes.array, + dataSources: PropTypes.object, + dataSourceValueRenderer: PropTypes.func, + dictionaries: PropTypes.object, + graphDiv: PropTypes.object, + locale: PropTypes.string, + onUpdate: PropTypes.func, + plotly: PropTypes.object, + traceTypesConfig: PropTypes.object, +}; + +EditorControls.defaultProps = { + locale: 'en', + traceTypesConfig: { + categories: _ => categoryLayout(_), + traces: _ => traceTypes(_), + complex: true, + }, +}; + +EditorControls.childContextTypes = { + advancedTraceTypeSelector: PropTypes.bool, + config: PropTypes.object, + data: PropTypes.array, + dataSourceOptionRenderer: PropTypes.func, + dataSourceOptions: PropTypes.array, + dataSources: PropTypes.object, + dataSourceValueRenderer: PropTypes.func, + dictionaries: PropTypes.object, + fullData: PropTypes.array, + fullLayout: PropTypes.object, + graphDiv: PropTypes.any, + layout: PropTypes.object, + locale: PropTypes.string, + onUpdate: PropTypes.func, + plotly: PropTypes.object, + plotSchema: PropTypes.object, + traceTypesConfig: PropTypes.object, +}; + +export default EditorControls; diff --git a/src/PlotlyEditor.js b/src/PlotlyEditor.js index 2990b8000..948963644 100644 --- a/src/PlotlyEditor.js +++ b/src/PlotlyEditor.js @@ -1,292 +1,58 @@ -import DefaultEditor from './DefaultEditor'; -import PropTypes from 'prop-types'; import React, {Component} from 'react'; -import {bem} from './lib'; -import {maybeClearAxisTypes} from './shame'; -import {EDITOR_ACTIONS} from './lib/constants'; -import isNumeric from 'fast-isnumeric'; -import nestedProperty from 'plotly.js/src/lib/nested_property'; -import {categoryLayout, traceTypes} from 'lib/traceTypes'; -import {ModalProvider} from 'components/containers'; +import createPlotComponent from 'react-plotly.js/factory'; +import EditorControls from './EditorControls'; +import PropTypes from 'prop-types'; class PlotlyEditor extends Component { - constructor(props, context) { - super(props, context); - - // we only need to compute this once. - if (this.props.plotly) { - this.plotSchema = this.props.plotly.PlotSchema.get(); - } - } - - getChildContext() { - const gd = this.props.graphDiv || {}; - return { - advancedTraceTypeSelector: this.props.advancedTraceTypeSelector, - config: gd._context, - data: gd.data, - dataSources: this.props.dataSources, - dataSourceOptions: this.props.dataSourceOptions, - dataSourceValueRenderer: this.props.dataSourceValueRenderer, - dataSourceOptionRenderer: this.props.dataSourceOptionRenderer, - dictionaries: this.props.dictionaries || {}, - fullData: gd._fullData, - fullLayout: gd._fullLayout, - graphDiv: gd, - layout: gd.layout, - locale: this.props.locale, - onUpdate: this.handleUpdate.bind(this), - plotSchema: this.plotSchema, - plotly: this.props.plotly, - traceTypesConfig: this.props.traceTypesConfig, - }; - } - - maybeAdjustAxisRef(payload) { - const {graphDiv} = this.props; - if (payload.tracesNeedingAxisAdjustment) { - payload.tracesNeedingAxisAdjustment.forEach(trace => { - const axis = trace[payload.axisAttrToAdjust].charAt(0); - const currentAxisIdNumber = Number( - trace[payload.axisAttrToAdjust].slice(1) - ); - const adjustedAxisIdNumber = currentAxisIdNumber - 1; - - const currentAxisLayoutProperties = { - ...graphDiv.layout[payload.axisAttrToAdjust + currentAxisIdNumber], - }; - - // for cases when we're adjusting x2 => x, so that it becomes x not x1 - graphDiv.data[trace.index][payload.axisAttrToAdjust] = - adjustedAxisIdNumber === 1 ? axis : axis + adjustedAxisIdNumber; - - graphDiv.layout[ - payload.axisAttrToAdjust + adjustedAxisIdNumber - ] = currentAxisLayoutProperties; - }); - } - } - - handleUpdate({type, payload}) { - const {graphDiv} = this.props; - - switch (type) { - case EDITOR_ACTIONS.UPDATE_TRACES: - if (this.props.beforeUpdateTraces) { - this.props.beforeUpdateTraces(payload); - } - - // until we start utilizing Plotly.react in `react-plotly.js` - // force clear axes types when a `src` has changed. - maybeClearAxisTypes(graphDiv, payload.traceIndexes, payload.update); - - this.maybeAdjustAxisRef(payload); - - for (let i = 0; i < payload.traceIndexes.length; i++) { - for (const attr in payload.update) { - const traceIndex = payload.traceIndexes[i]; - const prop = nestedProperty(graphDiv.data[traceIndex], attr); - const value = payload.update[attr]; - - if (value !== void 0) { - prop.set(value); - } - } - } - - if (this.props.afterUpdateTraces) { - this.props.afterUpdateTraces(payload); - } - if (this.props.onUpdate) { - this.props.onUpdate(graphDiv.data.slice(), graphDiv.layout); - } - break; - - case EDITOR_ACTIONS.UPDATE_LAYOUT: - if (this.props.beforeUpdateLayout) { - this.props.beforeUpdateLayout(payload); - } - for (const attr in payload.update) { - const prop = nestedProperty(graphDiv.layout, attr); - const value = payload.update[attr]; - if (value !== void 0) { - prop.set(value); - } - } - if (this.props.afterUpdateLayout) { - this.props.afterUpdateLayout(payload); - } - if (this.props.onUpdate) { - this.props.onUpdate( - graphDiv.data, - Object.assign({}, graphDiv.layout) - ); - } - break; - - case EDITOR_ACTIONS.ADD_TRACE: - if (this.props.beforeAddTrace) { - this.props.beforeAddTrace(payload); - } - graphDiv.data.push({type: 'scatter', mode: 'markers'}); - if (this.props.afterAddTrace) { - this.props.afterAddTrace(payload); - } - if (this.props.onUpdate) { - this.props.onUpdate(graphDiv.data.slice(), graphDiv.layout); - } - break; - - case EDITOR_ACTIONS.DELETE_TRACE: - if (payload.traceIndexes && payload.traceIndexes.length) { - if (this.props.beforeDeleteTrace) { - this.props.beforeDeleteTrace(payload); - } - graphDiv.data.splice(payload.traceIndexes[0], 1); - if (this.props.afterDeleteTrace) { - this.props.afterDeleteTrace(payload); - } - if (this.props.onUpdate) { - this.props.onUpdate(graphDiv.data.slice(), graphDiv.layout); - } - } - break; - - case EDITOR_ACTIONS.DELETE_ANNOTATION: - if (isNumeric(payload.annotationIndex)) { - if (this.props.beforeDeleteAnnotation) { - this.props.beforeDeleteAnnotation(payload); - } - graphDiv.layout.annotations.splice(payload.annotationIndex, 1); - if (this.props.afterDeleteAnnotation) { - this.props.afterDeleteAnnotation(payload); - } - if (this.props.onUpdate) { - this.props.onUpdate( - graphDiv.data, - Object.assign({}, graphDiv.layout) - ); - } - } - break; - - case EDITOR_ACTIONS.DELETE_SHAPE: - if (isNumeric(payload.shapeIndex)) { - if (this.props.beforeDeleteShape) { - this.props.beforeDeleteShape(payload); - } - graphDiv.layout.shapes.splice(payload.shapeIndex, 1); - if (this.props.afterDeleteShape) { - this.props.afterDeleteShape(payload); - } - if (this.props.onUpdate) { - this.props.onUpdate( - graphDiv.data, - Object.assign({}, graphDiv.layout) - ); - } - } - break; - - case EDITOR_ACTIONS.DELETE_IMAGE: - if (isNumeric(payload.imageIndex)) { - if (this.props.beforeDeleteImage) { - this.props.beforeDeleteImage(payload); - } - graphDiv.layout.images.splice(payload.imageIndex, 1); - if (this.props.afterDeleteImage) { - this.props.afterDeleteImage(payload); - } - if (this.props.onUpdate) { - this.props.onUpdate( - graphDiv.data, - Object.assign({}, graphDiv.layout) - ); - } - } - break; - - default: - throw new Error('must specify an action type to handleEditorUpdate'); - } + constructor(props) { + super(); + this.state = {graphDiv: {}}; + this.PlotComponent = createPlotComponent(props.plotly); } render() { return ( -
- - {this.props.graphDiv && - this.props.graphDiv._fullLayout && - (this.props.children ? this.props.children : )} - +
+ +
+ this.setState({graphDiv})} + onUpdate={graphDiv => this.setState({graphDiv})} + style={{ + width: '100%', + height: '100%', + minHeight: 'calc(100vh - 50px)', + }} + /> +
); } } PlotlyEditor.propTypes = { - advancedTraceTypeSelector: PropTypes.bool, - afterAddTrace: PropTypes.func, - afterDeleteAnnotation: PropTypes.func, - afterDeleteShape: PropTypes.func, - afterDeleteImage: PropTypes.func, - afterDeleteTrace: PropTypes.func, - afterUpdateLayout: PropTypes.func, - afterUpdateTraces: PropTypes.func, - beforeAddTrace: PropTypes.func, - beforeDeleteAnnotation: PropTypes.func, - beforeDeleteShape: PropTypes.func, - beforeDeleteImage: PropTypes.func, - beforeDeleteTrace: PropTypes.func, - beforeUpdateLayout: PropTypes.func, - beforeUpdateTraces: PropTypes.func, - children: PropTypes.node, - className: PropTypes.string, - dataSourceOptionRenderer: PropTypes.func, - dataSourceOptions: PropTypes.array, - dataSources: PropTypes.object, - dataSourceValueRenderer: PropTypes.func, - dictionaries: PropTypes.object, - graphDiv: PropTypes.object, - locale: PropTypes.string, - onUpdate: PropTypes.func, - plotly: PropTypes.object, - traceTypesConfig: PropTypes.object, -}; - -PlotlyEditor.defaultProps = { - locale: 'en', - traceTypesConfig: { - categories: _ => categoryLayout(_), - traces: _ => traceTypes(_), - complex: true, - }, -}; - -PlotlyEditor.childContextTypes = { - advancedTraceTypeSelector: PropTypes.bool, - config: PropTypes.object, + layout: PropTypes.object, data: PropTypes.array, - dataSourceOptionRenderer: PropTypes.func, + config: PropTypes.object, dataSourceOptions: PropTypes.array, dataSources: PropTypes.object, - dataSourceValueRenderer: PropTypes.func, - dictionaries: PropTypes.object, - fullData: PropTypes.array, - fullLayout: PropTypes.object, - graphDiv: PropTypes.any, - layout: PropTypes.object, - locale: PropTypes.string, onUpdate: PropTypes.func, plotly: PropTypes.object, - plotSchema: PropTypes.object, - traceTypesConfig: PropTypes.object, + useResizeHandler: PropTypes.bool, + debug: PropTypes.bool, + advancedTraceTypeSelector: PropTypes.bool, }; export default PlotlyEditor; diff --git a/src/PlotlyEditorWithPlot.js b/src/PlotlyEditorWithPlot.js deleted file mode 100644 index 4f6d0cea0..000000000 --- a/src/PlotlyEditorWithPlot.js +++ /dev/null @@ -1,58 +0,0 @@ -import React, {Component} from 'react'; -import createPlotComponent from 'react-plotly.js/factory'; -import PlotlyEditor from '../src'; -import PropTypes from 'prop-types'; - -class PlotlyEditorWithPlot extends Component { - constructor(props) { - super(); - this.state = {graphDiv: {}}; - this.PlotComponent = createPlotComponent(props.plotly); - } - - render() { - return ( -
- -
- this.setState({graphDiv})} - onUpdate={graphDiv => this.setState({graphDiv})} - style={{ - width: '100%', - height: '100%', - minHeight: 'calc(100vh - 50px)', - }} - /> -
-
- ); - } -} - -PlotlyEditorWithPlot.propTypes = { - layout: PropTypes.object, - data: PropTypes.array, - config: PropTypes.object, - dataSourceOptions: PropTypes.array, - dataSources: PropTypes.object, - onUpdate: PropTypes.func, - plotly: PropTypes.object, - useResizeHandler: PropTypes.bool, - debug: PropTypes.bool, - advancedTraceTypeSelector: PropTypes.bool, -}; - -export default PlotlyEditorWithPlot; diff --git a/src/index.js b/src/index.js index 5c8651829..6cb93e6f5 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,5 @@ import PlotlyEditor from './PlotlyEditor'; -import PlotlyEditorWithPlot from './PlotlyEditorWithPlot'; +import EditorControls from './EditorControls'; import { connectAnnotationToLayout, connectShapeToLayout, @@ -142,7 +142,7 @@ export { localize, localizeString, walkObject, - PlotlyEditorWithPlot, + EditorControls, }; export default PlotlyEditor; From 61f8f177c5290f0be283d5c1a3e34bafdb51025f Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Wed, 7 Mar 2018 14:30:35 -0500 Subject: [PATCH 4/9] fix test --- src/lib/test-utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/test-utils.js b/src/lib/test-utils.js index d1b9e69ec..67882c935 100644 --- a/src/lib/test-utils.js +++ b/src/lib/test-utils.js @@ -1,6 +1,6 @@ import plotly from 'plotly.js/dist/plotly-basic'; import {extendDeep} from 'plotly.js/src/lib/extend'; -import PlotlyEditor from '../PlotlyEditor'; +import EditorControls from '../EditorControls'; import {configure, mount, shallow} from 'enzyme'; import {dereference} from '../lib'; import Adapter from 'enzyme-adapter-react-16'; @@ -151,4 +151,4 @@ function setupGraphDiv(figure) { return gd; } -export {fixtures, plotly, PlotlyEditor as TestEditor, mount, shallow}; +export {fixtures, plotly, EditorControls as TestEditor, mount, shallow}; From c663ac5dec28afc64247756a45a12ecf0bb30d97 Mon Sep 17 00:00:00 2001 From: Nicolas Kruchten Date: Thu, 8 Mar 2018 13:51:54 -0500 Subject: [PATCH 5/9] fixing up examples --- examples/custom/src/App.js | 72 +++++++++++---------------------- examples/demo/src/App.js | 76 ++++++++++++----------------------- examples/redux/src/App.js | 59 +++++++++------------------ examples/redux/src/actions.js | 17 +------- examples/redux/src/reducer.js | 17 ++------ examples/simple/src/App.js | 55 +++++++------------------ src/PlotlyEditor.js | 5 ++- 7 files changed, 92 insertions(+), 209 deletions(-) diff --git a/examples/custom/src/App.js b/examples/custom/src/App.js index 56f0f95de..d5fa246d8 100644 --- a/examples/custom/src/App.js +++ b/examples/custom/src/App.js @@ -1,6 +1,5 @@ import React, {Component} from 'react'; import plotly from 'plotly.js/dist/plotly'; -import createPlotComponent from 'react-plotly.js/factory'; import PlotlyEditor from 'react-chart-editor'; import CustomEditor from './CustomEditor'; import 'react-chart-editor/lib/react-chart-editor.css'; @@ -15,63 +14,40 @@ const dataSourceOptions = Object.keys(dataSources).map(name => ({ label: name, })); -const Plot = createPlotComponent(plotly); +const config = {editable: true}; class App extends Component { constructor() { super(); - - // The graphDiv object is passed to Plotly.js, which then causes it to be - // overwritten with a full DOM node that contains data, layout, _fullData, - // _fullLayout etc in handlePlotUpdate() this.state = { - graphDiv: { - data: [ - { - type: 'scatter', - x: dataSources.col1, - y: dataSources.col2, - marker: {color: dataSources.col3}, - }, - ], - }, - plotRevision: 0, + data: [ + { + type: 'scatter', + x: dataSources.col1, + y: dataSources.col2, + marker: {color: dataSources.col3}, + }, + ], + layout: {}, }; } - handlePlotUpdate(graphDiv) { - this.setState({graphDiv}); - } - - handleEditorUpdate() { - this.setState(({plotRevision: x}) => ({plotRevision: x + 1})); - } - render() { return ( -
- - - -
- -
-
+ this.setState({data, layout})} + useResizeHandler + debug + advancedTraceTypeSelector +> + + ); } } diff --git a/examples/demo/src/App.js b/examples/demo/src/App.js index ec728b8d3..14fd8e2f4 100644 --- a/examples/demo/src/App.js +++ b/examples/demo/src/App.js @@ -1,32 +1,31 @@ import React, {Component} from 'react'; import plotly from 'plotly.js/dist/plotly'; -import createPlotComponent from 'react-plotly.js/factory'; import PlotlyEditor from 'react-chart-editor'; import 'react-chart-editor/lib/react-chart-editor.css'; import Nav from './Nav'; const dataSources = { - col1: [1, 2, 3], // eslint-disable-line no-magic-numbers - col2: [4, 3, 2], // eslint-disable-line no-magic-numbers - col3: [17, 13, 9], // eslint-disable-line no-magic-numbers + col1: ['Jan', 'Feb', 'Mar'], // eslint-disable-line no-magic-numbers + col2: [1, 2, 3], + col3: [4, 3, 2], // eslint-disable-line no-magic-numbers + col4: [17, 13, 9], // eslint-disable-line no-magic-numbers + col5: ['blue'], + col6: ['yellow', 'green', 'yellow'], }; const dataSourceOptions = Object.keys(dataSources).map(name => ({ value: name, label: name, })); -const Plot = createPlotComponent(plotly); +const config = {editable: true}; class App extends Component { constructor() { super(); - // The graphDiv object is passed to Plotly.js, which then causes it to be - // overwritten with a full DOM node that contains data, layout, _fullData, - // _fullLayout etc in handlePlotUpdate() this.state = { - graphDiv: {}, - plotRevision: 0, + data: [], + layout: {}, currentMockIndex: -1, mocks: [], }; @@ -42,14 +41,6 @@ class App extends Component { .then(mocks => this.setState({mocks})); } - handlePlotUpdate(graphDiv) { - this.setState({graphDiv}); - } - - handleEditorUpdate() { - this.setState(({plotRevision: x}) => ({plotRevision: x + 1})); - } - loadMock(mockIndex) { const mock = this.state.mocks[mockIndex]; fetch(mock.url, { @@ -57,46 +48,29 @@ class App extends Component { }) .then(response => response.json()) .then(figure => { - const graphDiv = this.state.graphDiv; - graphDiv.layout = figure.layout; - graphDiv.data = figure.data; - this.setState(({plotRevision: x}) => ({ + this.setState({ currentMockIndex: mockIndex, - plotRevision: x + 1, - })); + data: figure.data, + layout: figure.layout, + }); }); } render() { return (
-
- -
- -
-
+ this.setState({data, layout})} + useResizeHandler + debug + advancedTraceTypeSelector + />