this.setState({data, layout})}
+ onUpdate={(data, layout, frames) =>
+ this.setState({data, layout, frames})
+ }
useResizeHandler
debug
advancedTraceTypeSelector
diff --git a/examples/custom/src/App.js b/examples/custom/src/App.js
index b10b51c2b..e6d832bae 100644
--- a/examples/custom/src/App.js
+++ b/examples/custom/src/App.js
@@ -29,6 +29,7 @@ class App extends Component {
},
],
layout: {},
+ frames: [],
};
}
@@ -39,10 +40,13 @@ class App extends Component {
data={this.state.data}
layout={this.state.layout}
config={config}
+ frames={this.state.frames}
dataSources={dataSources}
dataSourceOptions={dataSourceOptions}
plotly={plotly}
- onUpdate={(data, layout) => this.setState({data, layout})}
+ onUpdate={(data, layout, frames) =>
+ this.setState({data, layout, frames})
+ }
useResizeHandler
debug
advancedTraceTypeSelector
diff --git a/examples/demo/src/App.js b/examples/demo/src/App.js
index 148d3291a..598c5981f 100644
--- a/examples/demo/src/App.js
+++ b/examples/demo/src/App.js
@@ -26,6 +26,7 @@ class App extends Component {
this.state = {
data: [],
layout: {},
+ frames: [],
currentMockIndex: -1,
mocks: [],
};
@@ -52,6 +53,7 @@ class App extends Component {
currentMockIndex: mockIndex,
data: figure.data,
layout: figure.layout,
+ frames: figure.frames,
});
});
}
@@ -63,10 +65,13 @@ class App extends Component {
data={this.state.data}
layout={this.state.layout}
config={config}
+ frames={this.state.frames}
dataSources={dataSources}
dataSourceOptions={dataSourceOptions}
plotly={plotly}
- onUpdate={(data, layout) => this.setState({data, layout})}
+ onUpdate={(data, layout, frames) =>
+ this.setState({data, layout, frames})
+ }
useResizeHandler
debug
advancedTraceTypeSelector
diff --git a/examples/redux/src/App.js b/examples/redux/src/App.js
index 6a5184db6..63ba2b2cf 100644
--- a/examples/redux/src/App.js
+++ b/examples/redux/src/App.js
@@ -29,7 +29,14 @@ class App extends Component {
}
render() {
- const {actions, dataSources, dataSourceOptions, data, layout} = this.props;
+ const {
+ actions,
+ dataSources,
+ dataSourceOptions,
+ data,
+ layout,
+ frames,
+ } = this.props;
return (
@@ -37,6 +44,7 @@ class App extends Component {
data={data}
layout={layout}
config={config}
+ frames={frames}
dataSources={dataSources}
dataSourceOptions={dataSourceOptions}
plotly={plotly}
@@ -56,6 +64,7 @@ App.propTypes = {
dataSources: PropTypes.object,
data: PropTypes.array,
layout: PropTypes.object,
+ frames: PropTypes.array,
};
const mapStateToProps = state => ({
@@ -63,6 +72,7 @@ const mapStateToProps = state => ({
dataSources: state.dataSources,
data: state.data,
layout: state.layout,
+ frames: state.frames,
});
const mapDispatchToProps = dispatch => ({
diff --git a/examples/redux/src/actions.js b/examples/redux/src/actions.js
index b660cc5b8..259e1507a 100644
--- a/examples/redux/src/actions.js
+++ b/examples/redux/src/actions.js
@@ -14,9 +14,9 @@ export function dataSourceOptionsUpdate(payload) {
};
}
-export function editorUpdate(data, layout) {
+export function editorUpdate(data, layout, frames) {
return {
type: ACTIONS.EDITOR_UPDATE,
- payload: {data, layout},
+ payload: {data, layout, frames},
};
}
diff --git a/examples/redux/src/reducer.js b/examples/redux/src/reducer.js
index e76e1cc99..d46a454bf 100644
--- a/examples/redux/src/reducer.js
+++ b/examples/redux/src/reducer.js
@@ -5,6 +5,7 @@ const initialState = {
dataSourceOptions: [],
data: [],
layout: {},
+ frames: [],
};
export default (state = initialState, action) => {
@@ -18,6 +19,7 @@ export default (state = initialState, action) => {
...state,
data: action.payload.data,
layout: action.payload.layout,
+ frames: action.payload.frames,
};
default:
return state;
diff --git a/examples/simple/src/App.js b/examples/simple/src/App.js
index 9cb3ea83e..37403e84e 100644
--- a/examples/simple/src/App.js
+++ b/examples/simple/src/App.js
@@ -19,7 +19,7 @@ const config = {editable: true};
class App extends Component {
constructor() {
super();
- this.state = {data: [], layout: {}};
+ this.state = {data: [], layout: {}, frames: []};
}
render() {
@@ -29,10 +29,13 @@ class App extends Component {
data={this.state.data}
layout={this.state.layout}
config={config}
+ frames={this.state.frames}
dataSources={dataSources}
dataSourceOptions={dataSourceOptions}
plotly={plotly}
- onUpdate={(data, layout) => this.setState({data, layout})}
+ onUpdate={(data, layout, frames) =>
+ this.setState({data, layout, frames})
+ }
useResizeHandler
debug
advancedTraceTypeSelector
diff --git a/scripts/translationKeys/combined-translation-keys.txt b/scripts/translationKeys/combined-translation-keys.txt
index 29abf5b72..92b1de46e 100644
--- a/scripts/translationKeys/combined-translation-keys.txt
+++ b/scripts/translationKeys/combined-translation-keys.txt
@@ -14,6 +14,7 @@ $
90 // react-chart-editor: /default_panels/StyleAxesPanel.js:199
@ // react-chart-editor: /default_panels/StyleAxesPanel.js:252
A // react-chart-editor: /components/fields/derived.js:530
+Active Color // react-chart-editor: /default_panels/StyleSlidersPanel.js:26
Africa // react-chart-editor: /components/fields/derived.js:441
Aitoff // react-chart-editor: /components/fields/derived.js:474
Albers USA // react-chart-editor: /components/fields/derived.js:483
@@ -33,8 +34,8 @@ Aspect Ratio
Asymmetric // react-chart-editor: /components/fields/ErrorBars.js:81
Atlas Map // react-chart-editor: /lib/computeTraceOptionsFromSchema.js:67
Auto // react-chart-editor: /default_panels/StyleAxesPanel.js:89
-Autoscale // plotly.js: components/modebar/buttons.js:139
-Axes // react-chart-editor: /DefaultEditor.js:24
+Autoscale // plotly.js: components/modebar/buttons.js:137
+Axes // react-chart-editor: /DefaultEditor.js:26
Axes to Use // react-chart-editor: /default_panels/GraphCreatePanel.js:69
Axis Background // react-chart-editor: /default_panels/StyleAxesPanel.js:167
Axis Line // react-chart-editor: /default_panels/StyleAxesPanel.js:114
@@ -42,12 +43,14 @@ Axis to Style
Azimuthal Equal Area // react-chart-editor: /components/fields/derived.js:463
Azimuthal Equidistant // react-chart-editor: /components/fields/derived.js:464
B // react-chart-editor: /components/fields/derived.js:531
+Background // react-chart-editor: /default_panels/StyleSlidersPanel.js:24
Background Color // react-chart-editor: /default_panels/StyleAxesPanel.js:326
Bar // react-chart-editor: /lib/computeTraceOptionsFromSchema.js:19
Bar Padding // react-chart-editor: /default_panels/StyleTracesPanel.js:148
Bar Width // react-chart-editor: /default_panels/StyleTracesPanel.js:146
Bars // react-chart-editor: /components/containers/TraceMarkerSection.js:20
Blank // react-chart-editor: /default_panels/StyleTracesPanel.js:173
+Border // react-chart-editor: /default_panels/StyleSlidersPanel.js:28
Border Color // react-chart-editor: /default_panels/StyleAxesPanel.js:335
Border Width // react-chart-editor: /default_panels/StyleAxesPanel.js:330
Borders and Background // react-chart-editor: /default_panels/StyleColorbarsPanel.js:306
@@ -58,9 +61,11 @@ Bottom Right
Boundaries // react-chart-editor: /default_panels/StyleAxesPanel.js:61
Box // react-chart-editor: /lib/computeTraceOptionsFromSchema.js:15
Box Padding // react-chart-editor: /default_panels/StyleTracesPanel.js:149
-Box Select // plotly.js: components/modebar/buttons.js:103
+Box Select // plotly.js: components/modebar/buttons.js:101
Box Width // react-chart-editor: /default_panels/StyleTracesPanel.js:147
Boxes // react-chart-editor: /default_panels/StyleTracesPanel.js:384
+Button // react-chart-editor: /components/fields/UpdateMenuButtons.js:18
+Button Labels // react-chart-editor: /default_panels/StyleUpdateMenusPanel.js:24
C // react-chart-editor: /components/fields/derived.js:532
Candlestick // react-chart-editor: /lib/computeTraceOptionsFromSchema.js:115
Canvas // react-chart-editor: /default_panels/StyleLayoutPanel.js:19
@@ -71,25 +76,25 @@ Cell Options
Cells // react-chart-editor: /default_panels/StyleTracesPanel.js:77
Center // react-chart-editor: /default_panels/StyleColorbarsPanel.js:105
Choropleth // react-chart-editor: /lib/computeTraceOptionsFromSchema.js:71
-Click to enter Colorscale title // plotly.js: plots/plots.js:320
-Click to enter Component A title // plotly.js: plots/ternary/ternary.js:392
-Click to enter Component B title // plotly.js: plots/ternary/ternary.js:407
-Click to enter Component C title // plotly.js: plots/ternary/ternary.js:418
-Click to enter Plot title // plotly.js: plot_api/plot_api.js:590
-Click to enter X axis title // plotly.js: plots/plots.js:318
-Click to enter Y axis title // plotly.js: plots/plots.js:319
-Click to enter radial axis title // plotly.js: plots/polar/polar.js:373
+Click to enter Colorscale title // plotly.js: plots/plots.js:317
+Click to enter Component A title // plotly.js: plots/ternary/ternary.js:394
+Click to enter Component B title // plotly.js: plots/ternary/ternary.js:409
+Click to enter Component C title // plotly.js: plots/ternary/ternary.js:420
+Click to enter Plot title // plotly.js: plot_api/plot_api.js:598
+Click to enter X axis title // plotly.js: plots/plots.js:315
+Click to enter Y axis title // plotly.js: plots/plots.js:316
+Click to enter radial axis title // plotly.js: plots/polar/polar.js:376
Close // react-chart-editor: /default_panels/GraphCreatePanel.js:61
Collapse All // react-chart-editor: /components/containers/PanelHeader.js:30
Color // react-chart-editor: /default_panels/GraphCreatePanel.js:133
Color Bar // react-chart-editor: /default_panels/StyleColorbarsPanel.js:308
-Color Bars // react-chart-editor: /DefaultEditor.js:26
+Color Bars // react-chart-editor: /DefaultEditor.js:28
Coloring // react-chart-editor: /default_panels/StyleTracesPanel.js:257
Colorscale // react-chart-editor: /default_panels/StyleTracesPanel.js:136
Column Options // react-chart-editor: /default_panels/GraphCreatePanel.js:97
Columns // react-chart-editor: /default_panels/GraphCreatePanel.js:66
Common Case: An 'All' tab might display this message because the X and Y tabs contain different settings. // react-chart-editor: /lib/constants.js:24
-Compare data on hover // plotly.js: components/modebar/buttons.js:167
+Compare data on hover // plotly.js: components/modebar/buttons.js:165
Conic Conformal // react-chart-editor: /components/fields/derived.js:466
Conic Equal Area // react-chart-editor: /components/fields/derived.js:465
Conic Equidistant // react-chart-editor: /components/fields/derived.js:467
@@ -109,7 +114,7 @@ Contour Width
Contours // react-chart-editor: /default_panels/StyleTracesPanel.js:255
Country Abbreviations (ISO-3) // react-chart-editor: /default_panels/GraphCreatePanel.js:112
Country Names // react-chart-editor: /default_panels/GraphCreatePanel.js:111
-Create // react-chart-editor: /DefaultEditor.js:20
+Create // react-chart-editor: /DefaultEditor.js:22
Custom // react-chart-editor: /default_panels/StyleAxesPanel.js:90
Custom Color // react-chart-editor: /components/widgets/ColorPicker.js:52
Custom Data // react-chart-editor: /components/fields/ErrorBars.js:110
@@ -120,12 +125,12 @@ Diffuse
Disable // react-chart-editor: /default_panels/StyleAxesPanel.js:345
Display // react-chart-editor: /default_panels/StyleTracesPanel.js:96
Distributions // react-chart-editor: /lib/traceTypes.js:21
-Double-click on legend to isolate one trace // plotly.js: components/legend/handle_click.js:90
-Double-click to zoom back out // plotly.js: plots/cartesian/dragbox.js:963
-Download plot as a png // plotly.js: components/modebar/buttons.js:52
+Double-click on legend to isolate one trace // plotly.js: components/legend/handle_click.js:89
+Double-click to zoom back out // plotly.js: plots/cartesian/dragbox.js:969
+Download plot as a png // plotly.js: components/modebar/buttons.js:50
E+6 // react-chart-editor: /default_panels/StyleAxesPanel.js:212
Eckert4 // react-chart-editor: /components/fields/derived.js:462
-Edit in Chart Studio // plotly.js: components/modebar/buttons.js:76
+Edit in Chart Studio // plotly.js: components/modebar/buttons.js:74
Edit in HTML // react-chart-editor: /components/widgets/text_editors/MultiFormat.js:35
Edit in Rich Text // react-chart-editor: /components/widgets/text_editors/MultiFormat.js:250
Ellipse // react-chart-editor: /default_panels/StyleShapesPanel.js:31
@@ -158,6 +163,7 @@ First
Fixed Height // react-chart-editor: /default_panels/StyleLayoutPanel.js:28
Fixed Width // react-chart-editor: /default_panels/StyleLayoutPanel.js:27
Flatshading // react-chart-editor: /default_panels/StyleTracesPanel.js:107
+Font // react-chart-editor: /default_panels/StyleSlidersPanel.js:32
Font Color // react-chart-editor: /default_panels/GraphCreatePanel.js:87
Font Size // react-chart-editor: /default_panels/GraphCreatePanel.js:88
Fraction of Plot // react-chart-editor: /default_panels/StyleColorbarsPanel.js:71
@@ -168,7 +174,7 @@ Global Font
Gnomonic // react-chart-editor: /components/fields/derived.js:468
Go back // react-chart-editor: /components/widgets/text_editors/MultiFormat.js:198
Go to the 'Create' tab to define traces. // react-chart-editor: /components/containers/TraceRequiredPanel.js:16
-Graph // react-chart-editor: /DefaultEditor.js:20
+Graph // react-chart-editor: /DefaultEditor.js:22
Grid Lines // react-chart-editor: /default_panels/StyleAxesPanel.js:144
Hammer // react-chart-editor: /components/fields/derived.js:471
Header // react-chart-editor: /default_panels/StyleTracesPanel.js:58
@@ -193,9 +199,9 @@ Hover Action
Hover Projections // react-chart-editor: /default_panels/StyleAxesPanel.js:350
Hover on // react-chart-editor: /default_panels/StyleTracesPanel.js:382
I (Optional) // react-chart-editor: /default_panels/GraphCreatePanel.js:55
-IE only supports svg. Changing format to svg. // plotly.js: components/modebar/buttons.js:60
+IE only supports svg. Changing format to svg. // plotly.js: components/modebar/buttons.js:58
Image // react-chart-editor: /components/containers/ImageAccordion.js:23
-Images // react-chart-editor: /DefaultEditor.js:28
+Images // react-chart-editor: /DefaultEditor.js:30
Increasing Trace Styles // react-chart-editor: /default_panels/StyleTracesPanel.js:310
Individual // react-chart-editor: /components/containers/TraceAccordion.js:84
Inside // react-chart-editor: /default_panels/StyleAxesPanel.js:287
@@ -210,13 +216,14 @@ LaTeX is a math typesetting language that doesn't work with rich text.
Label // react-chart-editor: /default_panels/StyleTracesPanel.js:50
Label Formatting // react-chart-editor: /default_panels/StyleAxesPanel.js:220
Labels // react-chart-editor: /default_panels/GraphCreatePanel.js:26
-Lasso Select // plotly.js: components/modebar/buttons.js:112
+Lasso Select // plotly.js: components/modebar/buttons.js:110
Last // react-chart-editor: /default_panels/StyleAxesPanel.js:228
Latitude // react-chart-editor: /components/fields/derived.js:512
Layout // react-chart-editor: /default_panels/StyleAxesPanel.js:60
Left // react-chart-editor: /components/fields/derived.js:89
Legend // react-chart-editor: /default_panels/StyleLegendPanel.js:19
Legend Box // react-chart-editor: /default_panels/StyleLegendPanel.js:32
+Legth // react-chart-editor: /default_panels/StyleSlidersPanel.js:45
Length // react-chart-editor: /default_panels/StyleAxesPanel.js:292
Light Position // react-chart-editor: /default_panels/StyleTracesPanel.js:304
Lighting // react-chart-editor: /default_panels/StyleTracesPanel.js:288
@@ -260,7 +267,7 @@ None
Normal // react-chart-editor: /default_panels/StyleLegendPanel.js:96
North America // react-chart-editor: /components/fields/derived.js:442
Note Text // react-chart-editor: /default_panels/StyleNotesPanel.js:23
-Notes // react-chart-editor: /DefaultEditor.js:23
+Notes // react-chart-editor: /DefaultEditor.js:25
Number of Contours // react-chart-editor: /default_panels/StyleTracesPanel.js:274
Number of Labels // react-chart-editor: /default_panels/StyleAxesPanel.js:268
Number of Markers // react-chart-editor: /default_panels/StyleAxesPanel.js:296
@@ -271,14 +278,14 @@ On Hover
Opacity // react-chart-editor: /default_panels/StyleShapesPanel.js:53
Open // react-chart-editor: /default_panels/GraphCreatePanel.js:58
Options // react-chart-editor: /default_panels/GraphCreatePanel.js:102
-Orbital rotation // plotly.js: components/modebar/buttons.js:276
+Orbital rotation // plotly.js: components/modebar/buttons.js:274
Order // react-chart-editor: /default_panels/GraphCreatePanel.js:99
Orientation // react-chart-editor: /default_panels/StyleLegendPanel.js:83
Orthographic // react-chart-editor: /components/fields/derived.js:457
Outside // react-chart-editor: /default_panels/StyleAxesPanel.js:288
Overlay // react-chart-editor: /default_panels/StyleAxesPanel.js:63
Padding // react-chart-editor: /default_panels/StyleColorbarsPanel.js:131
-Pan // plotly.js: components/modebar/buttons.js:94
+Pan // plotly.js: components/modebar/buttons.js:92
Parallel Coordinates // react-chart-editor: /lib/computeTraceOptionsFromSchema.js:87
Pie // react-chart-editor: /lib/computeTraceOptionsFromSchema.js:39
Pixels // react-chart-editor: /default_panels/StyleColorbarsPanel.js:72
@@ -299,12 +306,12 @@ Range Slider
Rectangle // react-chart-editor: /default_panels/StyleShapesPanel.js:30
Relative To // react-chart-editor: /default_panels/StyleImagesPanel.js:51
Relative to // react-chart-editor: /default_panels/StyleShapesPanel.js:36
-Reset // plotly.js: components/modebar/buttons.js:432
-Reset axes // plotly.js: components/modebar/buttons.js:148
-Reset camera to default // plotly.js: components/modebar/buttons.js:314
-Reset camera to last save // plotly.js: components/modebar/buttons.js:322
-Reset view // plotly.js: components/modebar/buttons.js:581
-Reset views // plotly.js: components/modebar/buttons.js:529
+Reset // plotly.js: components/modebar/buttons.js:430
+Reset axes // plotly.js: components/modebar/buttons.js:146
+Reset camera to default // plotly.js: components/modebar/buttons.js:312
+Reset camera to last save // plotly.js: components/modebar/buttons.js:320
+Reset view // plotly.js: components/modebar/buttons.js:579
+Reset views // plotly.js: components/modebar/buttons.js:527
Reversed // react-chart-editor: /default_panels/StyleLegendPanel.js:97
Rich Text // react-chart-editor: /components/widgets/text_editors/MultiFormat.js:25
Rich text is incompatible with LaTeX. // react-chart-editor: /components/widgets/text_editors/MultiFormat.js:121
@@ -319,19 +326,21 @@ Scatter GL
Select an Option // react-chart-editor: /components/widgets/Dropdown.js:66
Selection // react-chart-editor: /default_panels/StyleAxesPanel.js:85
Shape // react-chart-editor: /components/containers/ShapeAccordion.js:23
-Shapes // react-chart-editor: /DefaultEditor.js:27
+Shapes // react-chart-editor: /DefaultEditor.js:29
Show // react-chart-editor: /default_panels/StyleAxesPanel.js:118
Show Contour // react-chart-editor: /default_panels/StyleTracesPanel.js:368
Show Sides // react-chart-editor: /default_panels/StyleAxesPanel.js:360
-Show closest data on hover // plotly.js: components/modebar/buttons.js:157
+Show closest data on hover // plotly.js: components/modebar/buttons.js:155
Side // react-chart-editor: /default_panels/StyleAxesPanel.js:80
Simple // react-chart-editor: /lib/traceTypes.js:9
Sinusoidal // react-chart-editor: /components/fields/derived.js:475
Size // react-chart-editor: /default_panels/StyleColorbarsPanel.js:65
Size and Positioning // react-chart-editor: /default_panels/StyleColorbarsPanel.js:64
Size and Spacing // react-chart-editor: /default_panels/StyleTracesPanel.js:145
-Snapshot succeeded // plotly.js: components/modebar/buttons.js:66
-Sorry, there was a problem downloading your snapshot! // plotly.js: components/modebar/buttons.js:69
+Slider // react-chart-editor: /components/containers/SliderAccordion.js:17
+Sliders // react-chart-editor: /DefaultEditor.js:31
+Snapshot succeeded // plotly.js: components/modebar/buttons.js:64
+Sorry, there was a problem downloading your snapshot! // plotly.js: components/modebar/buttons.js:67
Source // react-chart-editor: /default_panels/StyleImagesPanel.js:25
South America // react-chart-editor: /components/fields/derived.js:443
Specialized // react-chart-editor: /lib/traceTypes.js:29
@@ -343,14 +352,14 @@ Step Offset
Step Size // react-chart-editor: /default_panels/StyleAxesPanel.js:278
Stereographic // react-chart-editor: /components/fields/derived.js:469
Stretch // react-chart-editor: /default_panels/StyleImagesPanel.js:33
-Style // react-chart-editor: /DefaultEditor.js:21
+Style // react-chart-editor: /DefaultEditor.js:23
Suffix // react-chart-editor: /default_panels/StyleAxesPanel.js:233
Sum // react-chart-editor: /default_panels/GraphCreatePanel.js:131
Surface // react-chart-editor: /lib/computeTraceOptionsFromSchema.js:59
Symbol // react-chart-editor: /default_panels/StyleTracesPanel.js:140
Symmetric // react-chart-editor: /components/fields/ErrorBars.js:80
Table // react-chart-editor: /lib/computeTraceOptionsFromSchema.js:95
-Taking snapshot - this may take a few seconds // plotly.js: components/modebar/buttons.js:57
+Taking snapshot - this may take a few seconds // plotly.js: components/modebar/buttons.js:55
Ternary Scatter // react-chart-editor: /lib/computeTraceOptionsFromSchema.js:47
Text // react-chart-editor: /components/fields/derived.js:504
Text Alignment // react-chart-editor: /default_panels/StyleTracesPanel.js:64
@@ -358,6 +367,8 @@ Text Attributes
Text Position // react-chart-editor: /default_panels/StyleTracesPanel.js:190
The anchor point determines which side of the annotation's positioning coordinates refer to. // react-chart-editor: /default_panels/StyleNotesPanel.js:52
The positioning inputs are relative to the anchor points on the text box. // react-chart-editor: /default_panels/StyleLegendPanel.js:46
+There are no sliders to style in your plot // react-chart-editor: /components/containers/SliderAccordion.js:27
+There are no update menus to style in your plot // react-chart-editor: /components/containers/UpdateMenuAccordion.js:31
Thickness // react-chart-editor: /default_panels/StyleAxesPanel.js:122
This input has multiple values associated with it. Changing this setting will override these custom inputs. // react-chart-editor: /lib/constants.js:20
This panel could not be displayed due to an error. // react-chart-editor: /components/containers/Panel.js:17
@@ -371,23 +382,25 @@ Title and Fonts
Titles // react-chart-editor: /default_panels/StyleAxesPanel.js:53
To Next // react-chart-editor: /components/fields/derived.js:562
To Self // react-chart-editor: /components/fields/derived.js:561
-Toggle Spike Lines // plotly.js: components/modebar/buttons.js:548
-Toggle show closest data on hover // plotly.js: components/modebar/buttons.js:353
+Toggle Spike Lines // plotly.js: components/modebar/buttons.js:546
+Toggle show closest data on hover // plotly.js: components/modebar/buttons.js:351
Top // react-chart-editor: /components/fields/derived.js:101
Top Center // react-chart-editor: /default_panels/StyleTracesPanel.js:195
Top Left // react-chart-editor: /default_panels/StyleTracesPanel.js:194
Top Right // react-chart-editor: /default_panels/StyleTracesPanel.js:196
Trace // react-chart-editor: /components/containers/TraceAccordion.js:40
Trace Order // react-chart-editor: /default_panels/StyleLegendPanel.js:92
-Traces // react-chart-editor: /DefaultEditor.js:21
+Traces // react-chart-editor: /DefaultEditor.js:23
Transpose // react-chart-editor: /default_panels/GraphCreatePanel.js:135
Transverse Mercator // react-chart-editor: /components/fields/derived.js:472
-Turntable rotation // plotly.js: components/modebar/buttons.js:285
+Turntable rotation // plotly.js: components/modebar/buttons.js:283
Type // react-chart-editor: /default_panels/GraphCreatePanel.js:23
Typeface // react-chart-editor: /default_panels/StyleAxesPanel.js:55
URL // react-chart-editor: /components/widgets/text_editors/RichText/LinkEditor.js:93
USA // react-chart-editor: /components/fields/derived.js:438
USA State Abbreviations (e.g. NY) // react-chart-editor: /default_panels/GraphCreatePanel.js:114
+Update Menu // react-chart-editor: /components/containers/UpdateMenuAccordion.js:20
+Update Menus // react-chart-editor: /DefaultEditor.js:32
Value // react-chart-editor: /components/fields/ErrorBars.js:107
Value (-) // react-chart-editor: /components/fields/ErrorBars.js:132
Values // react-chart-editor: /components/fields/derived.js:503
@@ -423,10 +436,10 @@ Your plot does not have any axes to style.
Z // react-chart-editor: /components/fields/derived.js:497
Z Values // react-chart-editor: /default_panels/GraphCreatePanel.js:50
Zero Line // react-chart-editor: /default_panels/StyleAxesPanel.js:155
-Zoom // plotly.js: components/modebar/buttons.js:85
+Zoom // plotly.js: components/modebar/buttons.js:83
Zoom Interactivity // react-chart-editor: /default_panels/StyleAxesPanel.js:340
-Zoom in // plotly.js: components/modebar/buttons.js:121
-Zoom out // plotly.js: components/modebar/buttons.js:130
+Zoom in // plotly.js: components/modebar/buttons.js:119
+Zoom out // plotly.js: components/modebar/buttons.js:128
^ // react-chart-editor: /default_panels/StyleAxesPanel.js:262
close: // plotly.js: traces/ohlc/transform.js:139
custom // react-chart-editor: /default_panels/StyleAxesPanel.js:253
@@ -446,14 +459,14 @@ mean ± σ:
mean: // plotly.js: traces/box/calc.js:140
median: // plotly.js: traces/box/calc.js:135
min: // plotly.js: traces/box/calc.js:136
-new text // plotly.js: plots/plots.js:321 && react-chart-editor: /components/containers/AnnotationAccordion.js:38
+new text // plotly.js: plots/plots.js:318 && react-chart-editor: /components/containers/AnnotationAccordion.js:38
open: // plotly.js: traces/ohlc/transform.js:136
outgoing flow count: // plotly.js: traces/sankey/plot.js:143
q1: // plotly.js: traces/box/calc.js:137
q3: // plotly.js: traces/box/calc.js:138
source: // plotly.js: traces/sankey/plot.js:140
target: // plotly.js: traces/sankey/plot.js:141
-trace // plotly.js: plots/plots.js:323
+trace // plotly.js: plots/plots.js:320
upper fence: // plotly.js: traces/box/calc.js:142
x // react-chart-editor: /default_panels/StyleAxesPanel.js:249
x10^6 // react-chart-editor: /default_panels/StyleAxesPanel.js:213
diff --git a/scripts/translationKeys/translation-keys.txt b/scripts/translationKeys/translation-keys.txt
index 8f2e1e61f..84c79216d 100644
--- a/scripts/translationKeys/translation-keys.txt
+++ b/scripts/translationKeys/translation-keys.txt
@@ -14,6 +14,7 @@ $
90 // /default_panels/StyleAxesPanel.js:199
@ // /default_panels/StyleAxesPanel.js:252
A // /components/fields/derived.js:530
+Active Color // /default_panels/StyleSlidersPanel.js:26
Africa // /components/fields/derived.js:441
Aitoff // /components/fields/derived.js:474
Albers USA // /components/fields/derived.js:483
@@ -33,7 +34,7 @@ Aspect Ratio
Asymmetric // /components/fields/ErrorBars.js:81
Atlas Map // /lib/computeTraceOptionsFromSchema.js:67
Auto // /default_panels/StyleAxesPanel.js:89
-Axes // /DefaultEditor.js:24
+Axes // /DefaultEditor.js:26
Axes to Use // /default_panels/GraphCreatePanel.js:69
Axis Background // /default_panels/StyleAxesPanel.js:167
Axis Line // /default_panels/StyleAxesPanel.js:114
@@ -41,12 +42,14 @@ Axis to Style
Azimuthal Equal Area // /components/fields/derived.js:463
Azimuthal Equidistant // /components/fields/derived.js:464
B // /components/fields/derived.js:531
+Background // /default_panels/StyleSlidersPanel.js:24
Background Color // /default_panels/StyleAxesPanel.js:326
Bar // /lib/computeTraceOptionsFromSchema.js:19
Bar Padding // /default_panels/StyleTracesPanel.js:148
Bar Width // /default_panels/StyleTracesPanel.js:146
Bars // /components/containers/TraceMarkerSection.js:20
Blank // /default_panels/StyleTracesPanel.js:173
+Border // /default_panels/StyleSlidersPanel.js:28
Border Color // /default_panels/StyleAxesPanel.js:335
Border Width // /default_panels/StyleAxesPanel.js:330
Borders and Background // /default_panels/StyleColorbarsPanel.js:306
@@ -59,6 +62,8 @@ Box
Box Padding // /default_panels/StyleTracesPanel.js:149
Box Width // /default_panels/StyleTracesPanel.js:147
Boxes // /default_panels/StyleTracesPanel.js:384
+Button // /components/fields/UpdateMenuButtons.js:18
+Button Labels // /default_panels/StyleUpdateMenusPanel.js:24
C // /components/fields/derived.js:532
Candlestick // /lib/computeTraceOptionsFromSchema.js:115
Canvas // /default_panels/StyleLayoutPanel.js:19
@@ -73,7 +78,7 @@ Close
Collapse All // /components/containers/PanelHeader.js:30
Color // /default_panels/GraphCreatePanel.js:133
Color Bar // /default_panels/StyleColorbarsPanel.js:308
-Color Bars // /DefaultEditor.js:26
+Color Bars // /DefaultEditor.js:28
Coloring // /default_panels/StyleTracesPanel.js:257
Colorscale // /default_panels/StyleTracesPanel.js:136
Column Options // /default_panels/GraphCreatePanel.js:97
@@ -98,7 +103,7 @@ Contour Width
Contours // /default_panels/StyleTracesPanel.js:255
Country Abbreviations (ISO-3) // /default_panels/GraphCreatePanel.js:112
Country Names // /default_panels/GraphCreatePanel.js:111
-Create // /DefaultEditor.js:20
+Create // /DefaultEditor.js:22
Custom // /default_panels/StyleAxesPanel.js:90
Custom Color // /components/widgets/ColorPicker.js:52
Custom Data // /components/fields/ErrorBars.js:110
@@ -143,6 +148,7 @@ First
Fixed Height // /default_panels/StyleLayoutPanel.js:28
Fixed Width // /default_panels/StyleLayoutPanel.js:27
Flatshading // /default_panels/StyleTracesPanel.js:107
+Font // /default_panels/StyleSlidersPanel.js:32
Font Color // /default_panels/GraphCreatePanel.js:87
Font Size // /default_panels/GraphCreatePanel.js:88
Fraction of Plot // /default_panels/StyleColorbarsPanel.js:71
@@ -153,7 +159,7 @@ Global Font
Gnomonic // /components/fields/derived.js:468
Go back // /components/widgets/text_editors/MultiFormat.js:198
Go to the 'Create' tab to define traces. // /components/containers/TraceRequiredPanel.js:16
-Graph // /DefaultEditor.js:20
+Graph // /DefaultEditor.js:22
Grid Lines // /default_panels/StyleAxesPanel.js:144
Hammer // /components/fields/derived.js:471
Header // /default_panels/StyleTracesPanel.js:58
@@ -179,7 +185,7 @@ Hover Projections
Hover on // /default_panels/StyleTracesPanel.js:382
I (Optional) // /default_panels/GraphCreatePanel.js:55
Image // /components/containers/ImageAccordion.js:23
-Images // /DefaultEditor.js:28
+Images // /DefaultEditor.js:30
Increasing Trace Styles // /default_panels/StyleTracesPanel.js:310
Individual // /components/containers/TraceAccordion.js:84
Inside // /default_panels/StyleAxesPanel.js:287
@@ -200,6 +206,7 @@ Layout
Left // /components/fields/derived.js:89
Legend // /default_panels/StyleLegendPanel.js:19
Legend Box // /default_panels/StyleLegendPanel.js:32
+Legth // /default_panels/StyleSlidersPanel.js:45
Length // /default_panels/StyleAxesPanel.js:292
Light Position // /default_panels/StyleTracesPanel.js:304
Lighting // /default_panels/StyleTracesPanel.js:288
@@ -243,7 +250,7 @@ None
Normal // /default_panels/StyleLegendPanel.js:96
North America // /components/fields/derived.js:442
Note Text // /default_panels/StyleNotesPanel.js:23
-Notes // /DefaultEditor.js:23
+Notes // /DefaultEditor.js:25
Number of Contours // /default_panels/StyleTracesPanel.js:274
Number of Labels // /default_panels/StyleAxesPanel.js:268
Number of Markers // /default_panels/StyleAxesPanel.js:296
@@ -293,7 +300,7 @@ Scatter GL
Select an Option // /components/widgets/Dropdown.js:66
Selection // /default_panels/StyleAxesPanel.js:85
Shape // /components/containers/ShapeAccordion.js:23
-Shapes // /DefaultEditor.js:27
+Shapes // /DefaultEditor.js:29
Show // /default_panels/StyleAxesPanel.js:118
Show Contour // /default_panels/StyleTracesPanel.js:368
Show Sides // /default_panels/StyleAxesPanel.js:360
@@ -303,6 +310,8 @@ Sinusoidal
Size // /default_panels/StyleColorbarsPanel.js:65
Size and Positioning // /default_panels/StyleColorbarsPanel.js:64
Size and Spacing // /default_panels/StyleTracesPanel.js:145
+Slider // /components/containers/SliderAccordion.js:17
+Sliders // /DefaultEditor.js:31
Source // /default_panels/StyleImagesPanel.js:25
South America // /components/fields/derived.js:443
Specialized // /lib/traceTypes.js:29
@@ -314,7 +323,7 @@ Step Offset
Step Size // /default_panels/StyleAxesPanel.js:278
Stereographic // /components/fields/derived.js:469
Stretch // /default_panels/StyleImagesPanel.js:33
-Style // /DefaultEditor.js:21
+Style // /DefaultEditor.js:23
Suffix // /default_panels/StyleAxesPanel.js:233
Sum // /default_panels/GraphCreatePanel.js:131
Surface // /lib/computeTraceOptionsFromSchema.js:59
@@ -328,6 +337,8 @@ Text Attributes
Text Position // /default_panels/StyleTracesPanel.js:190
The anchor point determines which side of the annotation's positioning coordinates refer to. // /default_panels/StyleNotesPanel.js:52
The positioning inputs are relative to the anchor points on the text box. // /default_panels/StyleLegendPanel.js:46
+There are no sliders to style in your plot // /components/containers/SliderAccordion.js:27
+There are no update menus to style in your plot // /components/containers/UpdateMenuAccordion.js:31
Thickness // /default_panels/StyleAxesPanel.js:122
This input has multiple values associated with it. Changing this setting will override these custom inputs. // /lib/constants.js:20
This panel could not be displayed due to an error. // /components/containers/Panel.js:17
@@ -347,7 +358,7 @@ Top Left
Top Right // /default_panels/StyleTracesPanel.js:196
Trace // /components/containers/TraceAccordion.js:40
Trace Order // /default_panels/StyleLegendPanel.js:92
-Traces // /DefaultEditor.js:21
+Traces // /DefaultEditor.js:23
Transpose // /default_panels/GraphCreatePanel.js:135
Transverse Mercator // /components/fields/derived.js:472
Type // /default_panels/GraphCreatePanel.js:23
@@ -355,6 +366,8 @@ Typeface
URL // /components/widgets/text_editors/RichText/LinkEditor.js:93
USA // /components/fields/derived.js:438
USA State Abbreviations (e.g. NY) // /default_panels/GraphCreatePanel.js:114
+Update Menu // /components/containers/UpdateMenuAccordion.js:20
+Update Menus // /DefaultEditor.js:32
Value // /components/fields/ErrorBars.js:107
Value (-) // /components/fields/ErrorBars.js:132
Values // /components/fields/derived.js:503
diff --git a/src/DefaultEditor.js b/src/DefaultEditor.js
index 50c2da057..61311b5ae 100644
--- a/src/DefaultEditor.js
+++ b/src/DefaultEditor.js
@@ -9,9 +9,11 @@ import {
StyleLegendPanel,
StyleNotesPanel,
StyleShapesPanel,
+ StyleSlidersPanel,
StyleImagesPanel,
StyleTracesPanel,
StyleColorbarsPanel,
+ StyleUpdateMenusPanel,
} from './default_panels';
const DefaultEditor = ({localize: _}) => (
@@ -26,6 +28,8 @@ const DefaultEditor = ({localize: _}) => (
+
+
);
diff --git a/src/EditorControls.js b/src/EditorControls.js
index 19b91dbe4..a89364c81 100644
--- a/src/EditorControls.js
+++ b/src/EditorControls.js
@@ -30,6 +30,7 @@ class EditorControls extends Component {
dataSourceValueRenderer: this.props.dataSourceValueRenderer,
dataSourceOptionRenderer: this.props.dataSourceOptionRenderer,
dictionaries: this.props.dictionaries || {},
+ frames: gd._transitionData ? gd._transitionData._frames : [],
fullData: gd._fullData,
fullLayout: gd._fullLayout,
graphDiv: gd,
@@ -98,7 +99,11 @@ class EditorControls extends Component {
this.props.afterUpdateTraces(payload);
}
if (this.props.onUpdate) {
- this.props.onUpdate(graphDiv.data.slice(), graphDiv.layout);
+ this.props.onUpdate(
+ graphDiv.data.slice(),
+ graphDiv.layout,
+ graphDiv._transitionData._frames
+ );
}
break;
@@ -278,6 +283,7 @@ EditorControls.childContextTypes = {
dataSources: PropTypes.object,
dataSourceValueRenderer: PropTypes.func,
dictionaries: PropTypes.object,
+ frames: PropTypes.array,
fullData: PropTypes.array,
fullLayout: PropTypes.object,
graphDiv: PropTypes.any,
diff --git a/src/PlotlyEditor.js b/src/PlotlyEditor.js
index 79ef57df4..7bab41ba9 100644
--- a/src/PlotlyEditor.js
+++ b/src/PlotlyEditor.js
@@ -33,6 +33,7 @@ class PlotlyEditor extends Component {
0 &&
+ sliders.map((sli, i) => (
+
+ {children}
+
+ ));
+
+ return (
+ sliders.length > 0]}
+ extraEmptyPanelMessages={[
+ {
+ heading: _('There are no sliders to style in your plot'),
+ message: '',
+ },
+ ]}
+ >
+ {content ? content : null}
+
+ );
+ }
+}
+
+SliderAccordion.contextTypes = {
+ layout: PropTypes.object,
+};
+
+SliderAccordion.propTypes = {
+ children: PropTypes.node,
+ localize: PropTypes.func,
+};
+
+export default localize(SliderAccordion);
diff --git a/src/components/containers/UpdateMenuAccordion.js b/src/components/containers/UpdateMenuAccordion.js
new file mode 100644
index 000000000..30d31a3ef
--- /dev/null
+++ b/src/components/containers/UpdateMenuAccordion.js
@@ -0,0 +1,58 @@
+import Fold from './Fold';
+import TraceRequiredPanel from './TraceRequiredPanel';
+import PropTypes from 'prop-types';
+import React, {Component} from 'react';
+import {connectUpdateMenuToLayout, localize, capitalize} from 'lib';
+
+const UpdateMenuFold = connectUpdateMenuToLayout(Fold);
+
+class UpdateMenuAccordion extends Component {
+ render() {
+ const {layout: {updatemenus = []}} = this.context;
+ const {children, localize: _} = this.props;
+
+ const content =
+ updatemenus.length > 0 &&
+ updatemenus.map((upd, i) => {
+ const updateMenuType = capitalize(upd.type) || 'Dropdown';
+ const activeElementLabel = upd.buttons.filter(
+ b => b.index === upd.active
+ )[0].label;
+
+ return (
+
+ {children}
+
+ );
+ });
+
+ return (
+ updatemenus.length > 0]}
+ extraEmptyPanelMessages={[
+ {
+ heading: _('There are no update menus to style in your plot'),
+ message: '',
+ },
+ ]}
+ >
+ {content ? content : null}
+
+ );
+ }
+}
+
+UpdateMenuAccordion.contextTypes = {
+ layout: PropTypes.object,
+};
+
+UpdateMenuAccordion.propTypes = {
+ children: PropTypes.node,
+ localize: PropTypes.func,
+};
+
+export default localize(UpdateMenuAccordion);
diff --git a/src/components/containers/index.js b/src/components/containers/index.js
index e98b4ee33..afe7de13e 100644
--- a/src/components/containers/index.js
+++ b/src/components/containers/index.js
@@ -1,6 +1,8 @@
import AnnotationAccordion from './AnnotationAccordion';
import ShapeAccordion from './ShapeAccordion';
+import SliderAccordion from './SliderAccordion';
import ImageAccordion from './ImageAccordion';
+import UpdateMenuAccordion from './UpdateMenuAccordion';
import AxesFold from './AxesFold';
import Fold from './Fold';
import MenuPanel from './MenuPanel';
@@ -18,7 +20,9 @@ import SectionHeader from './SectionHeader';
export {
AnnotationAccordion,
ShapeAccordion,
+ SliderAccordion,
ImageAccordion,
+ UpdateMenuAccordion,
MenuPanel,
Fold,
Panel,
diff --git a/src/components/fields/UpdateMenuButtons.js b/src/components/fields/UpdateMenuButtons.js
new file mode 100644
index 000000000..1e2f38dad
--- /dev/null
+++ b/src/components/fields/UpdateMenuButtons.js
@@ -0,0 +1,52 @@
+import PropTypes from 'prop-types';
+import React, {Component} from 'react';
+import {Dropdown, TextEditor} from '../index';
+import Field from './Field';
+import {connectToContainer, localize} from 'lib';
+
+class UpdateMenuButtons extends Component {
+ constructor(props, context) {
+ super(props, context);
+ this.state = {
+ currentButtonIndex: 0,
+ };
+ }
+
+ renderDropdown() {
+ const _ = this.props.localize;
+ const options = this.props.fullValue.map((button, index) => {
+ return {label: _('Button') + ` ${index + 1}`, value: index};
+ });
+ return (
+ this.setState({currentButtonIndex: index})}
+ clearable={false}
+ fullValue={this.state.currentButtonIndex}
+ />
+ );
+ }
+
+ render() {
+ return (
+
+ {this.renderDropdown()}
+
+
+ );
+ }
+}
+
+UpdateMenuButtons.propTypes = {
+ attr: PropTypes.string,
+ localize: PropTypes.func,
+ fullValue: PropTypes.array,
+ updatePlot: PropTypes.func,
+};
+
+export default connectToContainer(localize(UpdateMenuButtons));
diff --git a/src/components/fields/index.js b/src/components/fields/index.js
index 566002e25..f411cefe5 100644
--- a/src/components/fields/index.js
+++ b/src/components/fields/index.js
@@ -14,6 +14,7 @@ import SymbolSelector from './SymbolSelector';
import TraceSelector from './TraceSelector';
import ErrorBars from './ErrorBars';
import AxisCreator from './AxisCreator';
+import UpdateMenuButtons from './UpdateMenuButtons';
import {
AnnotationArrowRef,
AnnotationRef,
@@ -77,4 +78,5 @@ export {
AxisCreator,
AxisOverlayDropdown,
AxisSide,
+ UpdateMenuButtons,
};
diff --git a/src/components/index.js b/src/components/index.js
index 4454c68b1..864d50e2b 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -37,12 +37,15 @@ import {
TextEditor,
TraceOrientation,
TraceSelector,
+ UpdateMenuButtons,
} from './fields';
import {
AnnotationAccordion,
ShapeAccordion,
+ SliderAccordion,
ImageAccordion,
+ UpdateMenuAccordion,
AxesFold,
Fold,
LayoutPanel,
@@ -67,7 +70,9 @@ export {
AxisOverlayDropdown,
AxisSide,
ShapeAccordion,
+ SliderAccordion,
ImageAccordion,
+ UpdateMenuAccordion,
AnnotationArrowRef,
AnnotationRef,
PositioningRef,
@@ -117,4 +122,5 @@ export {
TraceSelector,
TraceTypeSection,
SectionHeader,
+ UpdateMenuButtons,
};
diff --git a/src/default_panels/StyleSlidersPanel.js b/src/default_panels/StyleSlidersPanel.js
new file mode 100644
index 000000000..efc3c27e2
--- /dev/null
+++ b/src/default_panels/StyleSlidersPanel.js
@@ -0,0 +1,54 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import {
+ ColorPicker,
+ FontSelector,
+ Numeric,
+ Radio,
+ Section,
+ SliderAccordion,
+} from '../components';
+
+import {localize} from '../lib';
+
+const StyleSlidersPanel = ({localize: _}) => (
+
+
+
+
+
+
+
+
+);
+
+StyleSlidersPanel.propTypes = {
+ localize: PropTypes.func,
+};
+
+export default localize(StyleSlidersPanel);
diff --git a/src/default_panels/StyleUpdateMenusPanel.js b/src/default_panels/StyleUpdateMenusPanel.js
new file mode 100644
index 000000000..3deaad184
--- /dev/null
+++ b/src/default_panels/StyleUpdateMenusPanel.js
@@ -0,0 +1,52 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import {
+ ColorPicker,
+ FontSelector,
+ Numeric,
+ Radio,
+ Section,
+ UpdateMenuAccordion,
+ UpdateMenuButtons,
+} from '../components';
+
+import {localize} from '../lib';
+
+const StyleUpdateMenusPanel = ({localize: _}) => (
+
+
+
+
+
+
+
+
+);
+
+StyleUpdateMenusPanel.propTypes = {
+ localize: PropTypes.func,
+};
+
+export default localize(StyleUpdateMenusPanel);
diff --git a/src/default_panels/index.js b/src/default_panels/index.js
index dd080d2eb..1625a2d34 100644
--- a/src/default_panels/index.js
+++ b/src/default_panels/index.js
@@ -4,9 +4,11 @@ import StyleAxesPanel from './StyleAxesPanel';
import StyleLegendPanel from './StyleLegendPanel';
import StyleNotesPanel from './StyleNotesPanel';
import StyleShapesPanel from './StyleShapesPanel';
+import StyleSlidersPanel from './StyleSlidersPanel';
import StyleImagesPanel from './StyleImagesPanel';
import StyleTracesPanel from './StyleTracesPanel';
import StyleColorbarsPanel from './StyleColorbarsPanel';
+import StyleUpdateMenusPanel from './StyleUpdateMenusPanel';
export {
GraphCreatePanel,
@@ -15,7 +17,9 @@ export {
StyleLegendPanel,
StyleNotesPanel,
StyleShapesPanel,
+ StyleSlidersPanel,
StyleImagesPanel,
StyleTracesPanel,
StyleColorbarsPanel,
+ StyleUpdateMenusPanel,
};
diff --git a/src/lib/connectSliderToLayout.js b/src/lib/connectSliderToLayout.js
new file mode 100644
index 000000000..1b8d8e9be
--- /dev/null
+++ b/src/lib/connectSliderToLayout.js
@@ -0,0 +1,75 @@
+import React, {Component} from 'react';
+import PropTypes from 'prop-types';
+import {getDisplayName} from '../lib';
+
+export default function connectSliderToLayout(WrappedComponent) {
+ class SliderConnectedComponent extends Component {
+ constructor(props, context) {
+ super(props, context);
+ this.updateSlider = this.updateSlider.bind(this);
+ this.setLocals(props, context);
+ }
+
+ componentWillReceiveProps(nextProps, nextContext) {
+ this.setLocals(nextProps, nextContext);
+ }
+
+ setLocals(props, context) {
+ const {sliderIndex} = props;
+ const {container, fullContainer} = context;
+
+ const sliders = container.sliders || [];
+ const fullSliders = fullContainer.sliders || [];
+ this.container = sliders[sliderIndex];
+ this.fullContainer = fullSliders[sliderIndex];
+ }
+
+ getChildContext() {
+ return {
+ updateContainer: this.updateSlider,
+ container: this.container,
+ fullContainer: this.fullContainer,
+ };
+ }
+
+ updateSlider(update) {
+ const newUpdate = {};
+ const {sliderIndex} = this.props;
+ for (const key in update) {
+ const newkey = `sliders[${sliderIndex}].${key}`;
+ newUpdate[newkey] = update[key];
+ }
+ this.context.updateContainer(newUpdate);
+ }
+
+ render() {
+ return ;
+ }
+ }
+
+ SliderConnectedComponent.displayName = `SliderConnected${getDisplayName(
+ WrappedComponent
+ )}`;
+
+ SliderConnectedComponent.propTypes = {
+ sliderIndex: PropTypes.number.isRequired,
+ };
+
+ SliderConnectedComponent.contextTypes = {
+ container: PropTypes.object,
+ fullContainer: PropTypes.object,
+ onUpdate: PropTypes.func,
+ updateContainer: PropTypes.func,
+ };
+
+ SliderConnectedComponent.childContextTypes = {
+ updateContainer: PropTypes.func,
+ container: PropTypes.object,
+ fullContainer: PropTypes.object,
+ };
+
+ const {plotly_editor_traits} = WrappedComponent;
+ SliderConnectedComponent.plotly_editor_traits = plotly_editor_traits;
+
+ return SliderConnectedComponent;
+}
diff --git a/src/lib/connectUpdateMenuToLayout.js b/src/lib/connectUpdateMenuToLayout.js
new file mode 100644
index 000000000..fdd101c78
--- /dev/null
+++ b/src/lib/connectUpdateMenuToLayout.js
@@ -0,0 +1,75 @@
+import React, {Component} from 'react';
+import PropTypes from 'prop-types';
+import {getDisplayName} from '../lib';
+
+export default function connectUpdateMenuToLayout(WrappedComponent) {
+ class UpdateMenuConnectedComponent extends Component {
+ constructor(props, context) {
+ super(props, context);
+ this.updateUpdateMenu = this.updateUpdateMenu.bind(this);
+ this.setLocals(props, context);
+ }
+
+ componentWillReceiveProps(nextProps, nextContext) {
+ this.setLocals(nextProps, nextContext);
+ }
+
+ setLocals(props, context) {
+ const {updateMenuIndex} = props;
+ const {container, fullContainer} = context;
+
+ const updatemenus = container.updatemenus || [];
+ const fullUpdateMenus = fullContainer.updatemenus || [];
+ this.container = updatemenus[updateMenuIndex];
+ this.fullContainer = fullUpdateMenus[updateMenuIndex];
+ }
+
+ getChildContext() {
+ return {
+ updateContainer: this.updateUpdateMenu,
+ container: this.container,
+ fullContainer: this.fullContainer,
+ };
+ }
+
+ updateUpdateMenu(update) {
+ const newUpdate = {};
+ const {updateMenuIndex} = this.props;
+ for (const key in update) {
+ const newkey = `updatemenus[${updateMenuIndex}].${key}`;
+ newUpdate[newkey] = update[key];
+ }
+ this.context.updateContainer(newUpdate);
+ }
+
+ render() {
+ return ;
+ }
+ }
+
+ UpdateMenuConnectedComponent.displayName = `UpdateMenuConnected${getDisplayName(
+ WrappedComponent
+ )}`;
+
+ UpdateMenuConnectedComponent.propTypes = {
+ updateMenuIndex: PropTypes.number.isRequired,
+ };
+
+ UpdateMenuConnectedComponent.contextTypes = {
+ container: PropTypes.object,
+ fullContainer: PropTypes.object,
+ onUpdate: PropTypes.func,
+ updateContainer: PropTypes.func,
+ };
+
+ UpdateMenuConnectedComponent.childContextTypes = {
+ updateContainer: PropTypes.func,
+ container: PropTypes.object,
+ fullContainer: PropTypes.object,
+ };
+
+ const {plotly_editor_traits} = WrappedComponent;
+ UpdateMenuConnectedComponent.plotly_editor_traits = plotly_editor_traits;
+
+ return UpdateMenuConnectedComponent;
+}
diff --git a/src/lib/index.js b/src/lib/index.js
index 2fa0640cf..56e4df5ad 100644
--- a/src/lib/index.js
+++ b/src/lib/index.js
@@ -1,7 +1,9 @@
import bem from './bem';
import connectAnnotationToLayout from './connectAnnotationToLayout';
import connectShapeToLayout from './connectShapeToLayout';
+import connectSliderToLayout from './connectSliderToLayout';
import connectImageToLayout from './connectImageToLayout';
+import connectUpdateMenuToLayout from './connectUpdateMenuToLayout';
import connectAxesToLayout from './connectAxesToLayout';
import connectLayoutToPlot, {getLayoutContext} from './connectLayoutToPlot';
import connectToContainer, {
@@ -52,6 +54,9 @@ function tooLight(color) {
}
function renderTraceIcon(trace, prefix = 'Plot') {
+ if (!trace) {
+ return null;
+ }
const componentName = `${prefix}${pascalCase(trace)}Icon`;
return PlotlyIcons[componentName]
? PlotlyIcons[componentName]
@@ -70,6 +75,8 @@ export {
clamp,
connectAnnotationToLayout,
connectShapeToLayout,
+ connectSliderToLayout,
+ connectUpdateMenuToLayout,
connectImageToLayout,
connectAxesToLayout,
connectLayoutToPlot,