Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2c83631

Browse files
committed
get 'mapbox.layers' to working state (test still to come)
1 parent d00de88 commit 2c83631

File tree

5 files changed

+253
-36
lines changed

5 files changed

+253
-36
lines changed

src/plots/mapbox/layers.js

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/**
2+
* Copyright 2012-2016, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
10+
'use strict';
11+
12+
var Lib = require('../../lib');
13+
14+
15+
function MapboxLayer(mapbox, index, opts) {
16+
this.mapbox = mapbox;
17+
this.map = mapbox.map;
18+
19+
this.uid = mapbox.uid + '-' + 'layer' + index;
20+
21+
this.idSource = this.uid + '-source';
22+
this.idLayer = this.uid + '-layer';
23+
24+
// some state variable to check if a remove/add step is needed
25+
this.sourceType = null;
26+
this.source = null;
27+
this.layerType = null;
28+
this.below = null;
29+
30+
// IMPORTANT: must create source before layer to not cause errors
31+
this.updateSource(opts);
32+
this.updateLayer(opts);
33+
}
34+
35+
var proto = MapboxLayer.prototype;
36+
37+
proto.update = function update(opts) {
38+
if(this.needsNewSource(opts)) {
39+
40+
// IMPORTANT: must delete layer before source to not cause errors
41+
this.updateLayer(opts);
42+
this.updateSource(opts);
43+
}
44+
else if(this.needsNewLayer(opts)) {
45+
this.updateLayer(opts);
46+
}
47+
48+
var paintOpts = convertPaintOpts(opts);
49+
50+
if(isVisible(opts)) {
51+
this.mapbox.setOptions(this.idLayer, 'setPaintProperty', paintOpts);
52+
}
53+
};
54+
55+
proto.needsNewSource = function(opts) {
56+
return (
57+
this.sourceType !== opts.sourcetype ||
58+
this.source !== opts.source
59+
);
60+
};
61+
62+
proto.needsNewLayer = function(opts) {
63+
return (
64+
this.layerType !== opts.type ||
65+
this.below !== opts.below
66+
);
67+
};
68+
69+
proto.updateSource = function(opts) {
70+
var map = this.map;
71+
72+
if(map.getSource(this.idSource)) map.removeSource(this.idSource);
73+
74+
this.sourceType = opts.sourcetype;
75+
this.source = opts.source;
76+
77+
if(!isVisible(opts)) return;
78+
79+
var sourceOpts = convertSourceOpts(opts);
80+
81+
map.addSource(this.idSource, sourceOpts);
82+
};
83+
84+
proto.updateLayer = function(opts) {
85+
var map = this.map;
86+
87+
if(map.getLayer(this.idLayer)) map.removeLayer(this.idLayer);
88+
89+
this.layerType = opts.type;
90+
91+
if(!isVisible(opts)) return;
92+
93+
map.addLayer({
94+
id: this.idLayer,
95+
source: this.idSource,
96+
'source-layer': opts.sourcelayer || '',
97+
type: opts.type
98+
}, opts.below);
99+
100+
// the only way to make a layer invisible is to remove it
101+
var layoutOpts = { visibility: 'visible' };
102+
this.mapbox.setOptions(this.idLayer, 'setLayoutProperty', layoutOpts);
103+
};
104+
105+
proto.dispose = function dispose() {
106+
var map = this.map;
107+
108+
map.removeLayer(this.idLayer);
109+
map.removeSource(this.idSource);
110+
};
111+
112+
function isVisible(opts) {
113+
var source = opts.source;
114+
115+
return (
116+
Lib.isPlainObject(source) ||
117+
(typeof source === 'string' && source.length > 0)
118+
);
119+
}
120+
121+
function convertPaintOpts(opts) {
122+
var paintOpts = {};
123+
124+
switch(opts.type) {
125+
126+
case 'line':
127+
Lib.extendFlat(paintOpts, {
128+
'line-width': opts.line.width,
129+
'line-color': opts.line.color,
130+
'line-opacity': opts.opacity
131+
});
132+
break;
133+
134+
case 'fill':
135+
Lib.extendFlat(paintOpts, {
136+
'fill-color': opts.fillcolor,
137+
'fill-outline-color': opts.line.color,
138+
'fill-opacity': opts.opacity
139+
140+
// no way to pass line.width at the moment
141+
});
142+
break;
143+
}
144+
145+
return paintOpts;
146+
}
147+
148+
function convertSourceOpts(opts) {
149+
var sourceType = opts.sourcetype,
150+
source = opts.source,
151+
sourceOpts = { type: sourceType },
152+
isSourceAString = (typeof source === 'string'),
153+
field;
154+
155+
if(sourceType === 'geojson') field = 'data';
156+
else if(sourceType === 'vector') {
157+
field = isSourceAString ? 'url' : 'tiles';
158+
}
159+
160+
sourceOpts[field] = source;
161+
162+
return sourceOpts;
163+
}
164+
165+
module.exports = function createMapboxLayer(mapbox, index, opts) {
166+
var mapboxLayer = new MapboxLayer(mapbox, index, opts);
167+
mapboxLayer.update(opts);
168+
169+
return mapboxLayer;
170+
};

src/plots/mapbox/layout_attributes.js

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@
99

1010
'use strict';
1111

12-
var lineAttrs = require('../../traces/scatter/attributes').line;
12+
var scatterMapboxAttrs = require('../../traces/scattermapbox/attributes');
13+
var defaultLine = require('../../components/color').defaultLine;
14+
var extendFlat = require('../../lib').extendFlat;
15+
16+
var lineAttrs = scatterMapboxAttrs.line;
1317

1418

1519
module.exports = {
@@ -76,51 +80,69 @@ module.exports = {
7680
layers: {
7781
_isLinkedToArray: true,
7882

79-
description: [
80-
''
81-
].join(' '),
82-
8383
sourcetype: {
8484
valType: 'enumerated',
85-
values: ['geojson', /* 'vector', 'raster', 'image', 'video' */],
86-
dflt: 'geojson'
85+
values: ['geojson', 'vector'],
86+
dflt: 'geojson',
87+
role: 'info',
88+
description: [
89+
'Sets the source type for this layer.',
90+
'Support for *raster*, *image* and *video* source types is coming soon.'
91+
].join(' ')
8792
},
93+
8894
source: {
8995
valType: 'any',
96+
role: 'info',
97+
description: [
98+
'Sets the source data for this layer.',
99+
'Source can be either a URL,',
100+
'a geojson object (with `sourcetype` set to *geojson*)',
101+
'or an array of tile URLS (with `sourcetype` set to *vector*).'
102+
].join(' ')
103+
},
104+
105+
sourcelayer: {
106+
valType: 'string',
107+
dflt: '',
108+
role: 'info',
109+
description: [
110+
'Required for *vector* source type that supports multiple layers.',
111+
'Specifies the layer to use from a vector tile source.'
112+
].join(' ')
90113
},
91114

92115
type: {
93116
valType: 'enumerated',
94-
values: ['line', /* 'background', 'symbol', 'raster', 'circle' */ ],
117+
values: ['line', 'fill'],
95118
dflt: 'line',
96-
role: 'info'
119+
role: 'info',
120+
description: [
121+
'',
122+
'Support for *raster*, *background* types is coming soon.'
123+
].join(' ')
97124
},
98125

99126
below: {
100127
valType: 'string',
101128
dflt: '',
102129
role: 'info',
103130
description: [
104-
'If a value for before is provided, the layer will be inserted',
105-
'before the layer with the specified ID. If before is omitted,',
131+
'Determines if the layer will be inserted',
132+
'before the layer with the specified ID.',
133+
'If omitted or set to \'\',',
106134
'the layer will be inserted above every existing layer.'
107135
].join(' ')
108136
},
109137

110138
line: {
111-
color: lineAttrs.color,
112-
width: lineAttrs.width,
113-
dash: lineAttrs.dash
139+
color: extendFlat({}, lineAttrs.color, {
140+
dflt: defaultLine
141+
}),
142+
width: lineAttrs.width
114143
},
115144

116-
fillcolor: {
117-
valType: 'color',
118-
dflt: 'rgba(0,0,0,0)',
119-
role: 'info',
120-
description: [
121-
'Sets the color filling the layer\'s interior.'
122-
].join(' ')
123-
},
145+
fillcolor: scatterMapboxAttrs.fillcolor,
124146

125147
opacity: {
126148
valType: 'number',

src/plots/mapbox/layout_defaults.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,24 @@ function handleLayerDefaults(containerIn, containerOut) {
5151
layerIn = layersIn[i];
5252
layerOut = {};
5353

54-
coerce('sourcetype')
55-
coerce('source')
54+
var sourceType = coerce('sourcetype');
55+
coerce('source');
5656

57+
if(sourceType === 'vector') coerce('sourcelayer');
58+
59+
// maybe add smart default based off 'fillcolor' ???
5760
var type = coerce('type');
5861

59-
if(type === 'line') {
60-
coerce('line.color');
61-
coerce('line.width');
62-
coerce('line.dash');
63-
coerce('fillcolor');
62+
var lineColor;
63+
if(type === 'line' || type === 'fill') {
64+
lineColor = coerce('line.color');
6465
}
6566

67+
// no way to pass line.width to fill layers
68+
if(type === 'line') coerce('line.width');
69+
70+
if(type === 'fill') coerce('fillcolor', lineColor);
71+
6672
coerce('below');
6773
coerce('opacity');
6874

src/plots/mapbox/mapbox.js

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ var mapboxgl = require('mapbox-gl');
1313

1414
var Fx = require('../cartesian/graph_interact');
1515
var constants = require('./constants');
16+
var createMapboxLayer = require('./layers');
1617

1718

1819
function Mapbox(opts) {
@@ -37,7 +38,7 @@ function Mapbox(opts) {
3738

3839
this.map = null;
3940
this.traceHash = {};
40-
this.layerHash = {};
41+
this.layerList = [];
4142
}
4243

4344
var proto = Mapbox.prototype;
@@ -210,7 +211,7 @@ proto.updateLayout = function(fullLayout) {
210211
map.setBearing(opts.bearing);
211212
map.setPitch(opts.pitch);
212213

213-
this.updateLayers();
214+
this.updateLayers();
214215
this.updateFramework(fullLayout);
215216
this.map.resize();
216217
};
@@ -297,11 +298,27 @@ proto.updateFramework = function(fullLayout) {
297298
};
298299

299300
proto.updateLayers = function() {
300-
var opts = this.opts,
301-
layers = opts.layers;
301+
var opts = this.opts,
302+
layers = opts.layers,
303+
layerList = this.layerList,
304+
i;
305+
306+
if(layers.length !== layerList.length) {
307+
for(i = layerList.length - 1; i > -1; i--) {
308+
layerList[i].dispose();
309+
layerList[i].pop();
310+
}
302311

303-
304-
}
312+
for(i = 0; i < layers.length; i++) {
313+
layerList.push(createMapboxLayer(this, i, layers[i]));
314+
}
315+
}
316+
else {
317+
for(i = 0; i < layers.length; i++) {
318+
layerList[i].update(layers[i]);
319+
}
320+
}
321+
};
305322

306323
proto.destroy = function() {
307324
this.map.remove();

src/traces/scattermapbox/attributes.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ module.exports = {
5151
line: {
5252
color: lineAttrs.color,
5353
width: lineAttrs.width,
54-
dash: lineAttrs.dash // TODO
54+
55+
// TODO
56+
dash: lineAttrs.dash
5557
},
5658

5759
connectgaps: scatterAttrs.connectgaps,

0 commit comments

Comments
 (0)