12
12
var mapboxgl = require ( 'mapbox-gl' ) ;
13
13
14
14
var constants = require ( './constants' ) ;
15
+ var xmlnsNamespaces = require ( '../../constants/xmlns_namespaces' ) ;
15
16
16
17
17
18
function Mapbox ( opts ) {
18
19
this . id = opts . id ;
19
20
this . gd = opts . gd ;
20
21
this . container = opts . container ;
21
- var fullLayout = this . fullLayout = opts . fullLayout ;
22
22
23
- this . uid = this . fullLayout . _uid + '-' + this . id ;
24
- this . opts = this . fullLayout [ this . id ] ;
25
- this . userOpts = this . gd . layout [ this . id ] || { } ;
23
+ var fullLayout = opts . fullLayout ;
24
+ this . uid = fullLayout . _uid + '-' + this . id ;
25
+ this . opts = fullLayout [ this . id ] ;
26
26
27
- // create div on instantiation for smoother first plot call
28
- this . div = this . createDiv ( ) ;
29
- this . updateDiv ( fullLayout ) ;
27
+ // create div on instantiation for a smoother first plot call
28
+ this . div = null ;
29
+ this . hoverLayer = null ;
30
+ this . createFramework ( fullLayout ) ;
30
31
31
32
this . map = null ;
32
33
this . traceHash = { } ;
@@ -42,8 +43,11 @@ module.exports = function createMapbox(opts) {
42
43
43
44
proto . plot = function ( fullData , fullLayout , promises ) {
44
45
var self = this ;
45
- var promise ;
46
46
47
+ // feed in new mapbox options
48
+ self . opts = fullLayout [ this . id ] ;
49
+
50
+ var promise ;
47
51
// might want to use map.loaded() ???
48
52
49
53
// how to get streaming to work ???
@@ -63,8 +67,8 @@ proto.plot = function(fullData, fullLayout, promises) {
63
67
} ;
64
68
65
69
proto . createMap = function ( fullData , fullLayout , resolve ) {
66
- var self = this ;
67
- var opts = self . opts ;
70
+ var self = this ,
71
+ opts = this . opts ;
68
72
69
73
var map = self . map = new mapboxgl . Map ( {
70
74
container : self . uid ,
@@ -84,30 +88,33 @@ proto.createMap = function(fullData, fullLayout, resolve) {
84
88
// hover code goes here !!!
85
89
} ) ;
86
90
87
- // TODO is that enough to keep layout and fullLayout in sync ???
88
- map . on ( 'move' , function ( eventData ) {
89
- map . getCenter ( ) ;
90
- map . getZoom ( ) ;
91
+ // keep track of pan / zoom in user layout
92
+ map . on ( 'move' , function ( ) {
93
+ var center = map . getCenter ( ) ;
94
+ opts . _input . center = opts . center = { lon : center . lng , lat : center . lat } ;
95
+ opts . _input . zoom = opts . zoom = map . getZoom ( ) ;
91
96
} ) ;
92
97
93
98
} ;
94
99
95
100
proto . updateMap = function ( fullData , fullLayout , resolve ) {
96
101
var self = this ,
97
- map = self . map ,
98
- opts = fullLayout [ self . id ] ;
102
+ map = self . map ;
99
103
100
104
var currentStyle = self . getStyle ( ) ,
101
- style = opts . style ;
105
+ style = self . opts . style ;
102
106
103
107
if ( style !== currentStyle ) {
104
108
console . log ( 'reload style' )
105
109
map . setStyle ( convertStyleUrl ( style ) ) ;
106
110
107
111
map . style . once ( 'load' , function ( ) {
108
112
console . log ( 'on style reload' )
109
- // ...
113
+
114
+ // need to rebuild trace layers on reload
115
+ // to avoid 'lost event' errors
110
116
self . traceHash = { } ;
117
+
111
118
self . updateData ( fullData ) ;
112
119
self . updateLayout ( fullLayout ) ;
113
120
resolve ( ) ;
@@ -153,41 +160,53 @@ proto.updateData = function(fullData) {
153
160
} ;
154
161
155
162
proto . updateLayout = function ( fullLayout ) {
156
- var opts = fullLayout [ this . id ] ,
157
- map = this . map ;
163
+ var map = this . map ,
164
+ opts = this . opts ;
158
165
159
166
map . setCenter ( convertCenter ( opts . center ) ) ;
160
167
map . setZoom ( opts . zoom ) ;
161
168
162
- this . updateDiv ( fullLayout )
163
- // resize()
169
+
170
+ this . updateFramework ( fullLayout )
171
+ this . map . resize ( ) ;
164
172
} ;
165
173
166
- proto . createDiv = function ( ) {
167
- var div = document . createElement ( 'div' ) ;
168
- this . container . appendChild ( div ) ;
174
+ proto . createFramework = function ( fullLayout ) {
175
+ var div = this . div = document . createElement ( 'div' ) ;
169
176
170
177
div . id = this . uid ;
171
178
div . style . position = 'absolute' ;
172
179
173
- return div ;
174
- } ;
180
+ var hoverLayer = this . hoverLayer = document . createElementNS (
181
+ xmlnsNamespaces . svg , 'svg'
182
+ ) ;
183
+
184
+ var hoverStyle = hoverLayer . style ;
175
185
176
- proto . updateDiv = function ( fullLayout ) {
177
- var div = this . div ;
186
+ hoverStyle . position = 'absolute' ;
187
+ hoverStyle . top = hoverStyle . left = '0px' ;
188
+ hoverStyle . width = hoverStyle . height = '100%' ;
189
+ hoverStyle [ 'z-index' ] = 20 ;
190
+ hoverStyle [ 'pointer-events' ] = 'none' ;
178
191
192
+ this . container . appendChild ( div ) ;
193
+ this . container . appendChild ( hoverLayer ) ;
194
+
195
+ this . updateFramework ( fullLayout ) ;
196
+ } ;
197
+
198
+ proto . updateFramework = function ( fullLayout ) {
179
199
var domain = fullLayout [ this . id ] . domain ,
180
- size = fullLayout . _size ,
181
- style = div . style ;
200
+ size = fullLayout . _size ;
201
+
202
+ var style = this . div . style ;
203
+
204
+ // Is this correct? It seems to get the map zoom level wrong?
182
205
183
- style . left = size . l + domain . x [ 0 ] * size . w + 'px' ;
184
- style . top = size . t + ( 1 - domain . y [ 1 ] ) * size . h + 'px' ;
185
206
style . width = size . w * ( domain . x [ 1 ] - domain . x [ 0 ] ) + 'px' ;
186
207
style . height = size . h * ( domain . y [ 1 ] - domain . y [ 0 ] ) + 'px' ;
187
-
188
- // style.top = 0;
189
- // style.bottom = 0;
190
- // style.width = '100%';
208
+ style . left = size . l + domain . x [ 0 ] * size . w + 'px' ;
209
+ style . top = size . t + ( 1 - domain . y [ 1 ] ) * size . h + 'px' ;
191
210
} ;
192
211
193
212
proto . destroy = function ( ) {
0 commit comments