Skip to content

Commit 35784a4

Browse files
remove requirement that plotly.js is passed into Editor fixes #86
1 parent cf40784 commit 35784a4

File tree

7 files changed

+60
-52
lines changed

7 files changed

+60
-52
lines changed

src/PlotlyEditor.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ class PlotlyEditor extends Component {
1212
noShame({plotly: this.props.plotly});
1313

1414
// we only need to compute this once.
15-
this.plotSchema = this.props.plotly.PlotSchema.get();
15+
if (this.props.plotly) {
16+
this.plotSchema = this.props.plotly.PlotSchema.get();
17+
}
1618
}
1719

1820
getChildContext() {
@@ -51,7 +53,7 @@ class PlotlyEditor extends Component {
5153

5254
PlotlyEditor.propTypes = {
5355
onUpdate: PropTypes.func,
54-
plotly: PropTypes.object.isRequired,
56+
plotly: PropTypes.object,
5557
graphDiv: PropTypes.object,
5658
locale: PropTypes.string,
5759
dataSources: PropTypes.object,
@@ -72,8 +74,8 @@ PlotlyEditor.childContextTypes = {
7274
layout: PropTypes.object,
7375
locale: PropTypes.string,
7476
onUpdate: PropTypes.func,
75-
plotSchema: PropTypes.object.isRequired,
76-
plotly: PropTypes.object.isRequired,
77+
plotSchema: PropTypes.object,
78+
plotly: PropTypes.object,
7779
};
7880

7981
export default PlotlyEditor;

src/components/containers/__tests__/Layout-test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import {Fold, Panel, Section} from '..';
33
import NumericInput from '../../widgets/NumericInputStatefulWrapper';
44
import React from 'react';
55
import {EDITOR_ACTIONS} from '../../../constants';
6-
import {TestEditor, fixtures, plotly} from '../../../lib/test-utils';
6+
import {TestEditor, fixtures} from '../../../lib/test-utils';
77
import {connectLayoutToPlot} from '../../../lib';
88
import {mount} from 'enzyme';
99

1010
const Layouts = [Panel, Fold, Section].map(connectLayoutToPlot);
1111
const Editor = props => (
12-
<TestEditor {...{plotly, onUpdate: jest.fn(), ...props}} />
12+
<TestEditor {...{onUpdate: jest.fn(), ...props}} />
1313
);
1414

1515
Layouts.forEach(Layout => {

src/components/containers/__tests__/Section-test.js

+5-21
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import Section from '../Section';
33
import MenuPanel from '../MenuPanel';
44
import {Flaglist, Info, Numeric} from '../../fields';
5-
import {TestEditor, fixtures, plotly} from '../../../lib/test-utils';
5+
import {TestEditor, fixtures} from '../../../lib/test-utils';
66
import {connectTraceToPlot} from '../../../lib';
77
import {mount} from 'enzyme';
88

@@ -12,11 +12,7 @@ describe('Section', () => {
1212
it('is visible if it contains any visible children', () => {
1313
// mode is visible with scatter. Hole is not visible. Section should show.
1414
const wrapper = mount(
15-
<TestEditor
16-
plotly={plotly}
17-
onUpdate={jest.fn()}
18-
{...fixtures.scatter({deref: true})}
19-
>
15+
<TestEditor onUpdate={jest.fn()} {...fixtures.scatter({deref: true})}>
2016
<TraceSection traceIndex={0} name="test-section">
2117
<Flaglist
2218
attr="mode"
@@ -50,11 +46,7 @@ describe('Section', () => {
5046

5147
it('is visible if it contains any non attr children', () => {
5248
const wrapper = mount(
53-
<TestEditor
54-
plotly={plotly}
55-
onUpdate={jest.fn()}
56-
{...fixtures.scatter({deref: true})}
57-
>
49+
<TestEditor onUpdate={jest.fn()} {...fixtures.scatter({deref: true})}>
5850
<Section name="test-section">
5951
<Info>INFO</Info>
6052
</Section>
@@ -69,11 +61,7 @@ describe('Section', () => {
6961
it('is not visible if it contains no visible children', () => {
7062
// pull and hole are not scatter attrs. Section should not show.
7163
const wrapper = mount(
72-
<TestEditor
73-
plotly={plotly}
74-
onUpdate={jest.fn()}
75-
{...fixtures.scatter({deref: true})}
76-
>
64+
<TestEditor onUpdate={jest.fn()} {...fixtures.scatter({deref: true})}>
7765
<TraceSection traceIndex={0} name="test-section">
7866
<Numeric attr="pull" min={0} max={1} step={0.1} traceIndex={0} />
7967
<Numeric attr="hole" min={0} max={1} step={0.1} traceIndex={0} />
@@ -93,11 +81,7 @@ describe('Section', () => {
9381

9482
it('will render first menuPanel even with no visible attrs', () => {
9583
const wrapper = mount(
96-
<TestEditor
97-
plotly={plotly}
98-
onUpdate={jest.fn()}
99-
{...fixtures.scatter({deref: true})}
100-
>
84+
<TestEditor onUpdate={jest.fn()} {...fixtures.scatter({deref: true})}>
10185
<Section name="test-section">
10286
<MenuPanel show>
10387
<Info>INFO</Info>

src/lib/connectAxesToLayout.js

+17-11
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ function deepCopyPublic(value) {
3434
/*
3535
* Test that we can connectLayoutToPlot(connectAxesToLayout(Panel))
3636
*/
37-
function setMultiValuedContainer(intoObj, fromObj, key, searchArrays) {
37+
function setMultiValuedContainer(intoObj, fromObj, key, config = {}) {
3838
var intoVal = intoObj[key],
3939
fromVal = fromObj[key];
4040

41+
var searchArrays = config.searchArrays;
42+
4143
// don't merge private attrs
4244
if (
4345
(typeof key === 'string' && key.charAt(0) === '_') ||
@@ -126,18 +128,22 @@ export default function connectAxesToLayout(WrappedComponent) {
126128
setLocals(nextProps, nextState, nextContext) {
127129
const {plotly, graphDiv, container, fullContainer} = nextContext;
128130
const {axesTarget} = nextState;
129-
this.axes = plotly.Axes.list(graphDiv);
131+
if (plotly) {
132+
this.axes = plotly.Axes.list(graphDiv);
133+
} else {
134+
this.axes = [];
135+
}
130136
this.axesOptions = computeAxesOptions(fullContainer, this.axes);
131137

132138
if (axesTarget === 'allaxes') {
133139
const multiValuedContainer = deepCopyPublic(this.axes[0]);
134-
this.axes
135-
.slice(1)
136-
.forEach(ax =>
137-
Object.keys(ax).forEach(key =>
138-
setMultiValuedContainer(multiValuedContainer, ax, key)
139-
)
140-
);
140+
this.axes.slice(1).forEach(ax =>
141+
Object.keys(ax).forEach(key =>
142+
setMultiValuedContainer(multiValuedContainer, ax, key, {
143+
searchArrays: true,
144+
})
145+
)
146+
);
141147
this.fullContainer = multiValuedContainer;
142148
this.defaultContainer = this.axes[0];
143149
// what should this be set to? Probably doesn't matter.
@@ -214,8 +220,8 @@ export default function connectAxesToLayout(WrappedComponent) {
214220
container: PropTypes.object.isRequired,
215221
fullContainer: PropTypes.object.isRequired,
216222
graphDiv: PropTypes.object.isRequired,
217-
plotly: PropTypes.object.isRequired,
218-
updateContainer: PropTypes.func.isRequired,
223+
plotly: PropTypes.object,
224+
updateContainer: PropTypes.func,
219225
};
220226

221227
AxesConnectedComponent.childContextTypes = {

src/lib/connectLayoutToPlot.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@ export default function connectLayoutToPlot(WrappedComponent) {
1414

1515
getChildContext() {
1616
const {layout, fullLayout, plotly} = this.context;
17-
return {
18-
getValObject: attr =>
17+
18+
let getValObject;
19+
if (plotly) {
20+
getValObject = attr =>
1921
plotly.PlotSchema.getLayoutValObject(
2022
fullLayout,
2123
nestedProperty({}, attr).parts
22-
),
24+
);
25+
}
26+
return {
27+
getValObject,
2328
updateContainer: this.updateContainer,
2429
container: layout,
2530
fullContainer: fullLayout,
@@ -48,7 +53,7 @@ export default function connectLayoutToPlot(WrappedComponent) {
4853
LayoutConnectedComponent.contextTypes = {
4954
layout: PropTypes.object,
5055
fullLayout: PropTypes.object,
51-
plotly: PropTypes.object.isRequired,
56+
plotly: PropTypes.object,
5257
onUpdate: PropTypes.func,
5358
};
5459

src/lib/connectTraceToPlot.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,18 @@ export default function connectTraceToPlot(WrappedComponent) {
2020
const trace = data[traceIndex] || {};
2121
const fullTraceIndex = findFullTraceIndex(fullData, traceIndex);
2222
const fullTrace = fullData[fullTraceIndex] || {};
23-
return {
24-
getValObject: attr =>
23+
24+
let getValObject;
25+
if (plotly) {
26+
getValObject = attr =>
2527
plotly.PlotSchema.getTraceValObject(
2628
fullTrace,
2729
nestedProperty({}, attr).parts
28-
),
30+
);
31+
}
32+
33+
return {
34+
getValObject,
2935
updateContainer: this.updateTrace,
3036
deleteContainer: this.deleteTrace,
3137
container: trace,
@@ -70,7 +76,7 @@ export default function connectTraceToPlot(WrappedComponent) {
7076
TraceConnectedComponent.contextTypes = {
7177
fullData: PropTypes.array,
7278
data: PropTypes.array,
73-
plotly: PropTypes.object.isRequired,
79+
plotly: PropTypes.object,
7480
onUpdate: PropTypes.func,
7581
};
7682

src/lib/unpackPlotProps.js

+11-6
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ export default function unpackPlotProps(props, context, ComponentClass) {
3434
}
3535

3636
// Property descriptions and meta:
37-
const attrMeta = context.getValObject(props.attr) || {};
37+
let attrMeta;
38+
if (getValObject) {
39+
attrMeta = context.getValObject(props.attr) || {};
40+
}
3841

3942
// Update data functions:
4043
const updatePlot = v => updateContainer && updateContainer({[props.attr]: v});
@@ -61,11 +64,13 @@ export default function unpackPlotProps(props, context, ComponentClass) {
6164
multiValued,
6265
};
6366

64-
if (isNumeric(attrMeta.max)) {
65-
plotProps.max = attrMeta.max;
66-
}
67-
if (isNumeric(attrMeta.min)) {
68-
plotProps.min = attrMeta.min;
67+
if (attrMeta) {
68+
if (isNumeric(attrMeta.max)) {
69+
plotProps.max = attrMeta.max;
70+
}
71+
if (isNumeric(attrMeta.min)) {
72+
plotProps.min = attrMeta.min;
73+
}
6974
}
7075

7176
// Give Component Classes the space to modify plotProps:

0 commit comments

Comments
 (0)