Skip to content

Commit 9798734

Browse files
wip
1 parent 3668590 commit 9798734

File tree

8 files changed

+220
-34
lines changed

8 files changed

+220
-34
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"draft-js-utils": "^1.3.3",
1515
"fast-isnumeric": "^1.1.2",
1616
"immutability-helper": "^3.0.0",
17-
"plotly-icons": "1.3.12",
17+
"plotly-icons": "1.3.13",
1818
"plotly.js": "1.49.4",
1919
"prop-types": "^15.7.2",
2020
"raf": "^3.4.1",

src/EditorControls.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,19 @@ class EditorControls extends Component {
277277
}
278278
break;
279279

280+
case EDITOR_ACTIONS.DELETE_MAPBOXLAYER:
281+
if (isNumeric(payload.mapboxLayerIndex)) {
282+
graphDiv.layout[payload.mapboxId].layers.splice(payload.mapboxLayerIndex, 1);
283+
if (this.props.onUpdate) {
284+
this.props.onUpdate(
285+
graphDiv.data,
286+
Object.assign({}, graphDiv.layout),
287+
graphDiv._transitionData._frames
288+
);
289+
}
290+
}
291+
break;
292+
280293
case EDITOR_ACTIONS.DELETE_TRANSFORM:
281294
if (isNumeric(payload.transformIndex) && payload.traceIndex < graphDiv.data.length) {
282295
if (graphDiv.data[payload.traceIndex].transforms.length === 1) {
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import PlotlyFold from './PlotlyFold';
2+
import PlotlyPanel from './PlotlyPanel';
3+
import PropTypes from 'prop-types';
4+
import React, {Component} from 'react';
5+
import {connectLayersToMapbox, getParsedTemplateString} from 'lib';
6+
7+
const MapboxLayersFold = connectLayersToMapbox(PlotlyFold);
8+
9+
class MapboxLayersAccordion extends Component {
10+
render() {
11+
const {
12+
fullContainer: {layers = []},
13+
localize: _,
14+
layout: meta,
15+
} = this.context;
16+
const {children} = this.props;
17+
18+
const content =
19+
layers.length &&
20+
layers.map((layer, i) => (
21+
<MapboxLayersFold
22+
key={i}
23+
mapboxLayerIndex={i}
24+
name={getParsedTemplateString(layer.name, {meta})}
25+
canDelete={true}
26+
>
27+
{children}
28+
</MapboxLayersFold>
29+
));
30+
31+
const addAction = {
32+
label: _('Layer'),
33+
handler: context => {
34+
const {fullContainer, updateContainer} = context;
35+
if (updateContainer) {
36+
const mapboxLayerIndex = Array.isArray(fullContainer.layers)
37+
? fullContainer.layers.length
38+
: 0;
39+
40+
updateContainer({
41+
[`layers[${mapboxLayerIndex}]`]: {
42+
name: `Layer ${mapboxLayerIndex}`,
43+
sourcetype: 'geojson',
44+
source: {
45+
type: 'FeatureCollection',
46+
features: [],
47+
},
48+
},
49+
});
50+
}
51+
},
52+
};
53+
54+
return <PlotlyPanel addAction={addAction}>{content ? content : null}</PlotlyPanel>;
55+
}
56+
}
57+
58+
MapboxLayersAccordion.contextTypes = {
59+
fullContainer: PropTypes.object,
60+
localize: PropTypes.func,
61+
layout: PropTypes.object,
62+
};
63+
64+
MapboxLayersAccordion.propTypes = {
65+
children: PropTypes.node,
66+
};
67+
68+
MapboxLayersAccordion.plotly_editor_traits = {
69+
no_visibility_forcing: true,
70+
};
71+
72+
export default MapboxLayersAccordion;

src/components/containers/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import SliderAccordion from './SliderAccordion';
44
import ImageAccordion from './ImageAccordion';
55
import UpdateMenuAccordion from './UpdateMenuAccordion';
66
import RangeSelectorAccordion from './RangeSelectorAccordion';
7+
import MapboxLayersAccordion from './MapboxLayersAccordion';
78
import AxesFold from './AxesFold';
89
import PlotlyFold, {Fold} from './PlotlyFold';
910
import MenuPanel from './MenuPanel';
@@ -27,6 +28,7 @@ export {
2728
ImageAccordion,
2829
UpdateMenuAccordion,
2930
RangeSelectorAccordion,
31+
MapboxLayersAccordion,
3032
MenuPanel,
3133
PlotlyFold,
3234
Fold,

src/components/fields/derived.js

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {UnconnectedColorPicker} from './ColorPicker';
1212
import {UnconnectedTextEditor} from './TextEditor';
1313
import {UnconnectedVisibilitySelect} from './VisibilitySelect';
1414
import {connectToContainer, getAllAxes, getAxisTitle, axisIdToAxisName} from 'lib';
15+
import PropTypes from 'prop-types';
1516

1617
export const AxisAnchorDropdown = connectToContainer(UnconnectedDropdown, {
1718
modifyPlotProps: (props, context, plotProps) => {
@@ -664,29 +665,32 @@ export const MapboxStyleDropdown = connectToContainer(UnconnectedDropdown, {
664665
modifyPlotProps: (props, context, plotProps) => {
665666
const {mapBoxAccess, localize: _} = context;
666667

667-
plotProps.options = [
668+
plotProps.options = (!mapBoxAccess
669+
? []
670+
: [
671+
{label: _('Mapbox Basic'), value: 'basic'},
672+
{label: _('Mapbox Outdoors'), value: 'outdoors'},
673+
{label: _('Mapbox Light'), value: 'light'},
674+
{label: _('Mapbox Dark'), value: 'dark'},
675+
{label: _('Mapbox Satellite'), value: 'satellite'},
676+
{label: _('Mapbox Satellite with Streets'), value: 'satellite-streets'},
677+
]
678+
).concat([
668679
{label: _('No tiles (white background)'), value: 'white-bg'},
669680
{label: _('Open Street Map'), value: 'open-street-map'},
670681
{label: _('Carto Positron'), value: 'carto-positron'},
671682
{label: _('Carto Dark Matter'), value: 'carto-darkmatter'},
672683
{label: _('Stamen Terrain'), value: 'stamen-terrain'},
673684
{label: _('Stamen Toner'), value: 'stamen-toner'},
674685
{label: _('Stamen Watercolor'), value: 'stamen-watercolor'},
675-
].concat(
676-
!mapBoxAccess
677-
? []
678-
: [
679-
{label: _('Mapbox Basic'), value: 'basic'},
680-
{label: _('Mapbox Outdoors'), value: 'outdoors'},
681-
{label: _('Mapbox Light'), value: 'light'},
682-
{label: _('Mapbox Dark'), value: 'dark'},
683-
{label: _('Mapbox Satellite'), value: 'satellite'},
684-
{label: _('Mapbox Satellite with Streets'), value: 'satellite-streets'},
685-
]
686-
);
686+
]);
687687
plotProps.clearable = false;
688688
},
689689
});
690+
MapboxStyleDropdown.contextTypes = {
691+
mapBoxAccess: PropTypes.bool,
692+
...MapboxStyleDropdown.contextTypes,
693+
};
690694

691695
export const HoveronDropdown = connectToContainer(UnconnectedDropdown, {
692696
modifyPlotProps: (props, context, plotProps) => {

src/default_panels/StyleMapsPanel.js

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import {
44
SubplotAccordion,
55
PlotlySection,
66
Dropdown,
7+
MapboxStyleDropdown,
8+
MapboxLayersAccordion,
79
Radio,
810
Numeric,
911
ColorPicker,
@@ -12,26 +14,20 @@ import {
1214
const StyleMapsPanel = (props, {localize: _}) => (
1315
<SubplotAccordion>
1416
<PlotlySection name={_('Base Map')} attr="style">
15-
<Dropdown
16-
label={_('Tiles')}
17-
attr="style"
18-
options={[
19-
{label: _('No tiles (white background)'), value: 'white-bg'},
20-
{label: _('Open Street Map'), value: 'open-street-map'},
21-
{label: _('Carto Positron'), value: 'carto-positron'},
22-
{label: _('Carto Dark Matter'), value: 'carto-darkmatter'},
23-
{label: _('Stamen Terrain'), value: 'stamen-terrain'},
24-
{label: _('Stamen Toner'), value: 'stamen-toner'},
25-
{label: _('Stamen Watercolor'), value: 'stamen-watercolor'},
26-
{label: _('Mapbox Basic'), value: 'basic'},
27-
{label: _('Mapbox Outdoors'), value: 'outdoors'},
28-
{label: _('Mapbox Light'), value: 'light'},
29-
{label: _('Mapbox Dark'), value: 'dark'},
30-
{label: _('Mapbox Satellite'), value: 'satellite'},
31-
{label: _('Mapbox Satellite with Streets'), value: 'satellite-streets'},
32-
]}
33-
clearable={false}
34-
/>
17+
<MapboxStyleDropdown label={_('Tiles')} attr="style" />
18+
</PlotlySection>
19+
<PlotlySection name={_('Layers')} attr="style">
20+
<MapboxLayersAccordion>
21+
<Radio
22+
attr="visible"
23+
options={[{label: _('Show'), value: true}, {label: _('Hide'), value: false}]}
24+
/>
25+
<Radio
26+
label={_('Layer Type')}
27+
attr="sourcetype"
28+
options={[{label: _('GeoJSON'), value: 'geojson'}, {label: _('Tiles'), value: 'raster'}]}
29+
/>
30+
</MapboxLayersAccordion>
3531
</PlotlySection>
3632
<PlotlySection name={_('Map Positioning')}>
3733
<Numeric label={_('Center Latitude')} attr="center.lat" />

src/lib/connectLayersToMapbox.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import React, {Component} from 'react';
2+
import PropTypes from 'prop-types';
3+
import {getDisplayName} from '../lib';
4+
import {EDITOR_ACTIONS} from './constants';
5+
6+
export default function connectLayersToMapbox(WrappedComponent) {
7+
class MapboxLayerConnectedComponent extends Component {
8+
constructor(props, context) {
9+
super(props, context);
10+
11+
this.deleteMapboxLayer = this.deleteMapboxLayer.bind(this);
12+
this.updateMapboxLayer = this.updateMapboxLayer.bind(this);
13+
this.setLocals(props, context);
14+
}
15+
16+
componentWillReceiveProps(nextProps, nextContext) {
17+
this.setLocals(nextProps, nextContext);
18+
}
19+
20+
setLocals(props, context) {
21+
const {mapboxLayerIndex} = props;
22+
const {container, fullContainer} = context;
23+
24+
const mapboxLayers = container.layers || [];
25+
const fullmapboxLayers = fullContainer.layers || [];
26+
this.container = mapboxLayers[mapboxLayerIndex];
27+
this.fullContainer = fullmapboxLayers[mapboxLayerIndex];
28+
}
29+
30+
getChildContext() {
31+
return {
32+
getValObject: attr =>
33+
!this.context.getValObject ? null : this.context.getValObject(`layers[].${attr}`),
34+
updateContainer: this.updateMapboxLayer,
35+
deleteContainer: this.deleteMapboxLayer,
36+
container: this.container,
37+
fullContainer: this.fullContainer,
38+
};
39+
}
40+
41+
updateMapboxLayer(update) {
42+
const newUpdate = {};
43+
const {mapboxLayerIndex} = this.props;
44+
for (const key in update) {
45+
const newkey = `layers[${mapboxLayerIndex}].${key}`;
46+
newUpdate[newkey] = update[key];
47+
}
48+
this.context.updateContainer(newUpdate);
49+
}
50+
51+
deleteMapboxLayer() {
52+
if (this.context.onUpdate) {
53+
this.context.onUpdate({
54+
type: EDITOR_ACTIONS.DELETE_MAPBOXLAYER,
55+
payload: {
56+
mapboxId: this.context.fullContainer._subplot.id,
57+
mapboxLayerIndex: this.props.mapboxLayerIndex,
58+
},
59+
});
60+
}
61+
}
62+
63+
render() {
64+
return <WrappedComponent {...this.props} />;
65+
}
66+
}
67+
68+
MapboxLayerConnectedComponent.displayName = `MapboxLayerConnected${getDisplayName(
69+
WrappedComponent
70+
)}`;
71+
72+
MapboxLayerConnectedComponent.propTypes = {
73+
mapboxLayerIndex: PropTypes.number.isRequired,
74+
};
75+
76+
MapboxLayerConnectedComponent.contextTypes = {
77+
container: PropTypes.object,
78+
fullContainer: PropTypes.object,
79+
data: PropTypes.array,
80+
onUpdate: PropTypes.func,
81+
updateContainer: PropTypes.func,
82+
getValObject: PropTypes.func,
83+
};
84+
85+
MapboxLayerConnectedComponent.childContextTypes = {
86+
updateContainer: PropTypes.func,
87+
deleteContainer: PropTypes.func,
88+
container: PropTypes.object,
89+
fullContainer: PropTypes.object,
90+
getValObject: PropTypes.func,
91+
};
92+
93+
const {plotly_editor_traits} = WrappedComponent;
94+
MapboxLayerConnectedComponent.plotly_editor_traits = plotly_editor_traits;
95+
96+
return MapboxLayerConnectedComponent;
97+
}

src/lib/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import connectSliderToLayout from './connectSliderToLayout';
77
import connectImageToLayout from './connectImageToLayout';
88
import connectUpdateMenuToLayout from './connectUpdateMenuToLayout';
99
import connectRangeSelectorToAxis from './connectRangeSelectorToAxis';
10+
import connectLayersToMapbox from './connectLayersToMapbox';
1011
import connectTransformToTrace from './connectTransformToTrace';
1112
import connectAggregationToTransform from './connectAggregationToTransform';
1213
import connectAxesToLayout from './connectAxesToLayout';
@@ -230,6 +231,7 @@ export {
230231
connectLayoutToPlot,
231232
connectNonCartesianSubplotToLayout,
232233
connectRangeSelectorToAxis,
234+
connectLayersToMapbox,
233235
connectShapeToLayout,
234236
connectSliderToLayout,
235237
connectToContainer,

0 commit comments

Comments
 (0)