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

Skip to content

Commit 68c060b

Browse files
committed
first pass at 'mapbox' subplot and 'scattermapbox' trace type
1 parent 96887ac commit 68c060b

File tree

6 files changed

+324
-1
lines changed

6 files changed

+324
-1
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ build/*
77
!build/README.md
88

99
npm-debug.log*
10+
11+
creds.json

lib/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ Core.register([
3030
require('./scattergeo'),
3131
require('./choropleth'),
3232
require('./scattergl'),
33-
require('./scatterternary')
33+
require('./scatterternary'),
34+
35+
require('../src/traces/scattermapbox')
3436
]);
3537

3638
module.exports = Core;

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
"gl-select-box": "^1.0.1",
7171
"gl-spikes2d": "^1.0.1",
7272
"gl-surface3d": "^1.2.3",
73+
"mapbox-gl": "^0.18.0",
7374
"mouse-change": "^1.1.1",
7475
"mouse-wheel": "^1.0.2",
7576
"ndarray": "^1.0.16",

src/plots/mapbox/index.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
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 mapboxgl = require('mapbox-gl');
13+
14+
var Plots = require('../plots');
15+
var handleSubplotDefaults = require('../subplot_defaults');
16+
17+
var createMapbox = require('./mapbox');
18+
19+
// TODO maybe this should be a config argument?
20+
var CREDS = require('../../../creds.json');
21+
22+
exports.name = 'mapbox';
23+
24+
exports.attr = 'subplot';
25+
26+
exports.idRoot = 'mapbox';
27+
28+
exports.idRegex = /^mapbox([2-9]|[1-9][0-9]+)?$/;
29+
30+
exports.attrRegex = /^mapbox([2-9]|[1-9][0-9]+)?$/;
31+
32+
exports.attributes = {
33+
subplot: {
34+
valType: 'subplotid',
35+
role: 'info',
36+
dflt: 'mapbox',
37+
description: [
38+
'Sets a reference between this trace\'s data coordinates and',
39+
'a mapbox subplot.',
40+
'If *mapbox* (the default value), the data refer to `layout.mapbox`.',
41+
'If *mapbox2*, the data refer to `layout.mapbox2`, and so on.'
42+
].join(' ')
43+
}
44+
};
45+
46+
exports.layoutAttributes = {
47+
domain: {
48+
x: {
49+
valType: 'info_array',
50+
role: 'info',
51+
items: [
52+
{valType: 'number', min: 0, max: 1},
53+
{valType: 'number', min: 0, max: 1}
54+
],
55+
dflt: [0, 1],
56+
description: [
57+
'Sets the horizontal domain of this subplot',
58+
'(in plot fraction).'
59+
].join(' ')
60+
},
61+
y: {
62+
valType: 'info_array',
63+
role: 'info',
64+
items: [
65+
{valType: 'number', min: 0, max: 1},
66+
{valType: 'number', min: 0, max: 1}
67+
],
68+
dflt: [0, 1],
69+
description: [
70+
'Sets the vertical domain of this subplot',
71+
'(in plot fraction).'
72+
].join(' ')
73+
}
74+
},
75+
76+
style: {
77+
valType: 'enumerated',
78+
values: ['light-v8', 'dark-v8'],
79+
dflt: 'streets-v8'
80+
},
81+
center: {
82+
lon: {
83+
valType: 'number',
84+
dflt: 0
85+
},
86+
lat: {
87+
valType: 'number',
88+
dflt: 0
89+
}
90+
},
91+
zoom: {
92+
valType: 'number',
93+
dflt: 1
94+
}
95+
};
96+
97+
exports.supplyLayoutDefaults = function(layoutIn, layoutOut, fullData) {
98+
handleSubplotDefaults(layoutIn, layoutOut, fullData, {
99+
type: 'mapbox',
100+
attributes: exports.layoutAttributes,
101+
handleDefaults: handleDefaults,
102+
partition: 'y'
103+
});
104+
};
105+
106+
function handleDefaults(containerIn, containerOut, coerce) {
107+
coerce('style');
108+
coerce('center.lon');
109+
coerce('center.lat');
110+
coerce('zoom');
111+
}
112+
113+
exports.plot = function plotMapbox(gd) {
114+
mapboxgl.accessToken = CREDS.accessToken;
115+
116+
var fullLayout = gd._fullLayout,
117+
fullData = gd._fullData,
118+
mapboxIds = Plots.getSubplotIds(fullLayout, 'mapbox');
119+
120+
for(var i = 0; i < mapboxIds.length; i++) {
121+
var id = mapboxIds[i],
122+
fullMapboxData = Plots.getSubplotData(fullData, 'mapbox', id),
123+
mapbox = fullLayout[id]._mapbox;
124+
125+
if(!mapbox) {
126+
mapbox = createMapbox({
127+
gd: gd,
128+
container: fullLayout._glcontainer.node(),
129+
id: id,
130+
fullLayout: fullLayout
131+
});
132+
133+
fullLayout[id]._mapbox = mapbox;
134+
}
135+
136+
mapbox.plot(fullMapboxData, fullLayout, gd._promises);
137+
}
138+
};
139+
140+
exports.clean = function() {};

src/plots/mapbox/mapbox.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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 mapboxgl = require('mapbox-gl');
13+
14+
function Mapbox(opts) {
15+
this.id = opts.id;
16+
this.gd = opts.gd;
17+
this.container = opts.container;
18+
this.fullLayout = opts.fullLayout;
19+
20+
this.opts = this.fullLayout[this.id];
21+
this.div = this.createDiv();
22+
23+
this.map = null;
24+
this.traceHash = {};
25+
}
26+
27+
var proto = Mapbox.prototype;
28+
29+
module.exports = function createMapbox(opts) {
30+
return new Mapbox(opts);
31+
};
32+
33+
proto.createDiv = function() {
34+
var div = document.createElement('div');
35+
36+
div.id = this.id;
37+
this.container.appendChild(div);
38+
39+
var style = div.style;
40+
style.position = 'absolute';
41+
style.top = 0;
42+
style.bottom = 0;
43+
style.width = '100%';
44+
45+
return div;
46+
};
47+
48+
proto.plot = function(fullData, fullLayout, promises) {
49+
var self = this;
50+
51+
var promise = new Promise(function(resolve) {
52+
53+
self.map = new mapboxgl.Map({
54+
55+
// container id
56+
container: self.id,
57+
58+
// stylesheet location
59+
style: 'mapbox://styles/mapbox/' + self.opts.style,
60+
61+
// starting position
62+
center: [self.opts.center.lon, self.opts.center.lat],
63+
64+
// starting zoom
65+
zoom: self.opts.zoom
66+
});
67+
68+
self.map.on('load', function() {
69+
70+
for(var i = 0; i < fullData.length; i++) {
71+
var trace = fullData[i];
72+
73+
trace._module.plot(self, trace);
74+
}
75+
76+
resolve(self.map);
77+
});
78+
});
79+
80+
promises.push(promise);
81+
};

src/traces/scattermapbox/index.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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+
'use strict';
10+
11+
var isNumeric = require('fast-isnumeric');
12+
13+
14+
exports.moduleType = 'trace';
15+
16+
exports.name = 'scattermapbox';
17+
18+
exports.categories = ['mapbox', 'gl'];
19+
20+
exports.meta = {
21+
description: [
22+
'(beta)'
23+
].join(' ')
24+
};
25+
26+
exports.basePlotModule = require('../../plots/mapbox');
27+
28+
exports.attributes = require('../scattergeo/attributes');
29+
30+
exports.supplyDefaults = require('../scattergeo/defaults');
31+
32+
exports.plot = function(mapbox, trace) {
33+
var map = mapbox.map;
34+
35+
var opts = convert(trace);
36+
37+
map.addSource(trace.uid, {
38+
type: 'geojson',
39+
data: opts.geojson
40+
});
41+
42+
map.addLayer({
43+
id: trace.uid + '-markers',
44+
source: trace.uid,
45+
46+
type: 'circle', // 'background', 'fill', 'line', 'symbol', 'raster', 'circle'
47+
48+
// circle properties: https://www.mapbox.com/mapbox-gl-style-spec/#layers-circle
49+
layout: opts.layout,
50+
51+
// circle properties: https://www.mapbox.com/mapbox-gl-style-spec/#layers-circle
52+
paint: opts.paint
53+
});
54+
};
55+
56+
function convert(trace) {
57+
var len = trace.lon.length;
58+
var coordinates = [];
59+
60+
for(var i = 0; i < len; i++) {
61+
var lon = trace.lon[i],
62+
lat = trace.lat[i];
63+
64+
if(isNumeric(lon) && isNumeric(lat)) {
65+
coordinates.push([+lon, +lat]);
66+
}
67+
}
68+
69+
var geojson = {
70+
type: 'FeatureCollection',
71+
features: [{
72+
type: 'Feature',
73+
geometry: {
74+
type: trace.mode === 'markers' ? 'MultiPoint' : 'LineString',
75+
coordinates: coordinates
76+
}
77+
}]
78+
};
79+
80+
var layout = {
81+
visibility: (trace.visible === true) ? 'visible' : 'none'
82+
};
83+
84+
var marker = trace.marker || {};
85+
86+
var paint = {
87+
'circle-radius': marker.size / 2,
88+
'circle-color': marker.color,
89+
'circle-opacity': marker.opacity
90+
};
91+
92+
return {
93+
geojson: geojson,
94+
layout: layout,
95+
paint: paint
96+
};
97+
}

0 commit comments

Comments
 (0)