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

Skip to content

Commit e278822

Browse files
committed
got lines+markers to work!
1 parent 68c060b commit e278822

File tree

5 files changed

+315
-115
lines changed

5 files changed

+315
-115
lines changed

src/plots/mapbox/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ exports.layoutAttributes = {
9191
zoom: {
9292
valType: 'number',
9393
dflt: 1
94+
},
95+
96+
// custom geojson or topojson layers
97+
layers: {
98+
9499
}
95100
};
96101

src/plots/mapbox/mapbox.js

Lines changed: 94 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,65 +17,126 @@ function Mapbox(opts) {
1717
this.container = opts.container;
1818
this.fullLayout = opts.fullLayout;
1919

20+
this.uid = this.fullLayout._uid + '-' + this.id;
2021
this.opts = this.fullLayout[this.id];
21-
this.div = this.createDiv();
22+
this.userOpts = this.gd.layout[this.id] || {};
2223

24+
this.div = null;
2325
this.map = null;
2426
this.traceHash = {};
27+
28+
this.createDiv();
2529
}
2630

2731
var proto = Mapbox.prototype;
2832

2933
module.exports = function createMapbox(opts) {
30-
return new Mapbox(opts);
34+
var mapbox = new Mapbox(opts);
35+
36+
return mapbox;
3137
};
3238

33-
proto.createDiv = function() {
34-
var div = document.createElement('div');
39+
proto.plot = function(fullData, fullLayout, promises) {
40+
var self = this;
41+
var promise;
3542

36-
div.id = this.id;
37-
this.container.appendChild(div);
43+
// might want to use map.loaded() ???
3844

39-
var style = div.style;
40-
style.position = 'absolute';
41-
style.top = 0;
42-
style.bottom = 0;
43-
style.width = '100%';
45+
if(!self.map) {
46+
promise = new Promise(function(resolve) {
47+
self.createMap(fullData, fullLayout, resolve);
48+
});
49+
}
50+
else {
51+
promise = new Promise(function(resolve) {
52+
self.updateMap(fullData, fullLayout);
53+
resolve();
54+
});
55+
}
4456

45-
return div;
57+
promises.push(promise);
4658
};
4759

48-
proto.plot = function(fullData, fullLayout, promises) {
60+
proto.createMap = function(fullData, fullLayout, resolve) {
4961
var self = this;
62+
var opts = self.opts;
5063

51-
var promise = new Promise(function(resolve) {
64+
var map = self.map = new mapboxgl.Map({
65+
container: self.uid,
66+
style: 'mapbox://styles/mapbox/' + opts.style,
67+
center: [opts.center.lon, opts.center.lat],
68+
zoom: opts.zoom
69+
});
5270

53-
self.map = new mapboxgl.Map({
71+
map.on('load', function() {
72+
self.updateMap(fullData, fullLayout);
73+
resolve();
74+
});
5475

55-
// container id
56-
container: self.id,
76+
map.on('mousemove', function(eventData) {
77+
// hover code goes here !!!
78+
});
5779

58-
// stylesheet location
59-
style: 'mapbox://styles/mapbox/' + self.opts.style,
80+
// TODO is that enough to keep layout and fullLayout in sync ???
81+
map.on('move', function(eventData) {
82+
map.getCenter();
83+
map.getZoom();
84+
});
6085

61-
// starting position
62-
center: [self.opts.center.lon, self.opts.center.lat],
86+
};
6387

64-
// starting zoom
65-
zoom: self.opts.zoom
66-
});
88+
// is this async in general ???
89+
proto.updateMap = function(fullData, fullLayout) {
90+
var traceHash = this.traceHash;
91+
var traceObj, i, j;
92+
93+
// update or create trace objects
94+
for(i = 0; i < fullData.length; i++) {
95+
var trace = fullData[i];
96+
traceObj = traceHash[trace.uid];
97+
98+
if(traceObj) traceObj.update(trace);
99+
else {
100+
traceHash[trace.uid] = trace._module.plot(this, trace);
101+
}
102+
}
103+
104+
// remove empty trace objects
105+
var ids = Object.keys(traceHash);
106+
id_loop:
107+
for(i = 0; i < ids.length; i++) {
108+
var id = ids[i];
109+
110+
for(j = 0; j < fullData.length; j++) {
111+
if(id === fullData[j].uid) continue id_loop;
112+
}
113+
114+
traceObj = traceHash[id];
115+
traceObj.dispose();
116+
delete traceHash[id];
117+
}
118+
};
67119

68-
self.map.on('load', function() {
120+
proto.createDiv = function() {
121+
var div = this.div = document.createElement('div');
69122

70-
for(var i = 0; i < fullData.length; i++) {
71-
var trace = fullData[i];
123+
div.id = this.uid;
124+
this.container.appendChild(div);
72125

73-
trace._module.plot(self, trace);
74-
}
126+
this.updateDiv();
127+
};
75128

76-
resolve(self.map);
77-
});
78-
});
129+
proto.updateDiv = function() {
130+
var div = this.div;
79131

80-
promises.push(promise);
132+
var style = div.style;
133+
style.position = 'absolute';
134+
style.top = 0;
135+
style.bottom = 0;
136+
style.width = '100%';
137+
};
138+
139+
proto.destroy = function() {
140+
this.map.remove();
141+
this.container.removerChild(this.div);
81142
};

src/traces/scattermapbox/convert.js

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
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 isNumeric = require('fast-isnumeric');
13+
14+
var Lib = require('../../lib');
15+
var subTypes = require('../scatter/subtypes');
16+
17+
18+
module.exports = function convert(trace) {
19+
var isVisible = (trace.visible === true),
20+
hasLines = subTypes.hasLines(trace),
21+
hasMarkers = subTypes.hasMarkers(trace);
22+
23+
var coordinates = (isVisible) ? calcCoords(trace) : [];
24+
25+
var geojsonLines = makeGeoJson('LineString', coordinates);
26+
var layoutLines = {
27+
visibility: (isVisible && hasLines) ? 'visible' : 'none'
28+
};
29+
var paintLines = {};
30+
31+
if(hasLines) {
32+
var line = trace.line;
33+
34+
Lib.extendFlat(paintLines, {
35+
'line-width': line.width,
36+
'line-color': line.color,
37+
'line-opacity': trace.opacity
38+
});
39+
40+
// could probably convert line.dash into
41+
// line-dasharray and line-pattern
42+
}
43+
44+
var geojsonMarkers = makeGeoJson('MultiPoint', coordinates);
45+
var layoutMarkers = {
46+
visibility: (isVisible && hasMarkers) ? 'visible' : 'none'
47+
};
48+
var paintMarkers = {};
49+
50+
if(hasMarkers) {
51+
var marker = trace.marker;
52+
53+
Lib.extendFlat(paintMarkers, {
54+
'circle-radius': marker.size / 2,
55+
'circle-color': marker.color,
56+
'circle-opacity': trace.opacity * marker.opacity
57+
});
58+
59+
// could probably translate arrayOk properties into
60+
// multiple layers by making paintMarkers a array!
61+
}
62+
63+
return {
64+
geojsonLines: geojsonLines,
65+
layoutLines: layoutLines,
66+
paintLines: paintLines,
67+
68+
geojsonMarkers: geojsonMarkers,
69+
layoutMarkers: layoutMarkers,
70+
paintMarkers: paintMarkers
71+
};
72+
};
73+
74+
function calcCoords(trace) {
75+
var len = trace.lon.length;
76+
var coordinates = [];
77+
78+
for(var i = 0; i < len; i++) {
79+
var lon = trace.lon[i],
80+
lat = trace.lat[i];
81+
82+
if(isNumeric(lon) && isNumeric(lat)) {
83+
coordinates.push([+lon, +lat]);
84+
}
85+
}
86+
87+
return coordinates;
88+
}
89+
90+
function makeGeoJson(geometryType, coordinates) {
91+
return {
92+
type: 'FeatureCollection',
93+
features: [{
94+
type: 'Feature',
95+
geometry: {
96+
type: geometryType,
97+
coordinates: coordinates
98+
}
99+
}]
100+
};
101+
}

src/traces/scattermapbox/index.js

Lines changed: 26 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -8,90 +8,34 @@
88

99
'use strict';
1010

11-
var isNumeric = require('fast-isnumeric');
1211

13-
14-
exports.moduleType = 'trace';
15-
16-
exports.name = 'scattermapbox';
17-
18-
exports.categories = ['mapbox', 'gl'];
19-
20-
exports.meta = {
12+
var ScatterMapbox = {};
13+
14+
// For first version:
15+
// - Different symbols
16+
// - Different line dashes
17+
// - no `locations` support
18+
// - no 'text' mode support
19+
// - arrayOk properties would require multi layers per source
20+
// - support for marker.line ???
21+
ScatterMapbox.attributes = require('../scattergeo/attributes');
22+
ScatterMapbox.supplyDefaults = require('../scattergeo/defaults');
23+
ScatterMapbox.colorbar = require('../scatter/colorbar');
24+
ScatterMapbox.calc = require('../scattergeo/calc');
25+
ScatterMapbox.plot = require('./plot');
26+
27+
ScatterMapbox.moduleType = 'trace';
28+
ScatterMapbox.name = 'scattermapbox';
29+
ScatterMapbox.basePlotModule = require('../../plots/mapbox');
30+
ScatterMapbox.categories = ['mapbox', 'gl', 'markerColorscale', 'showLegend'];
31+
ScatterMapbox.meta = {
32+
hrName: 'scatter_mapbox',
2133
description: [
22-
'(beta)'
34+
'The data visualized as scatter point or lines',
35+
'on a Mapbox GL geographic map',
36+
'is provided either by longitude/latitude pairs in `lon` and `lat`',
37+
'respectively or by geographic location IDs or names in `locations`.'
2338
].join(' ')
2439
};
2540

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-
}
41+
module.exports = ScatterMapbox;

0 commit comments

Comments
 (0)