diff --git a/src/plots/mapbox/mapbox.js b/src/plots/mapbox/mapbox.js index f1a71b60374..89b966a53bc 100644 --- a/src/plots/mapbox/mapbox.js +++ b/src/plots/mapbox/mapbox.js @@ -12,6 +12,7 @@ var mapboxgl = require('mapbox-gl'); var Fx = require('../cartesian/graph_interact'); +var Lib = require('../../lib'); var constants = require('./constants'); var layoutAttributes = require('./layout_attributes'); var createMapboxLayer = require('./layers'); @@ -97,8 +98,8 @@ proto.createMap = function(calcData, fullLayout, resolve, reject) { // clear navigation container var className = constants.controlContainerClassName, - controlContainer = this.div.getElementsByClassName(className)[0]; - this.div.removeChild(controlContainer); + controlContainer = self.div.getElementsByClassName(className)[0]; + self.div.removeChild(controlContainer); self.rejectOnError(reject); @@ -109,13 +110,18 @@ proto.createMap = function(calcData, fullLayout, resolve, reject) { self.resolveOnRender(resolve); }); - // keep track of pan / zoom in user layout + // keep track of pan / zoom in user layout and emit relayout event map.on('move', function() { - var center = map.getCenter(); - opts._input.center = opts.center = { lon: center.lng, lat: center.lat }; - opts._input.zoom = opts.zoom = map.getZoom(); - opts._input.bearing = opts.bearing = map.getBearing(); - opts._input.pitch = opts.pitch = map.getPitch(); + var view = self.getView(); + + opts._input.center = opts.center = view.center; + opts._input.zoom = opts.zoom = view.zoom; + opts._input.bearing = opts.bearing = view.bearing; + opts._input.pitch = opts.pitch = view.pitch; + + var update = {}; + update[self.id] = Lib.extendFlat({}, view); + gd.emit('plotly_relayout', update); }); map.on('mousemove', function(evt) { @@ -368,6 +374,21 @@ proto.project = function(v) { return this.map.project(new mapboxgl.LngLat(v[0], v[1])); }; +// get map's current view values in plotly.js notation +proto.getView = function() { + var map = this.map; + + var mapCenter = map.getCenter(), + center = { lon: mapCenter.lng, lat: mapCenter.lat }; + + return { + center: center, + zoom: map.getZoom(), + bearing: map.getBearing(), + pitch: map.getPitch() + }; +}; + function convertStyleUrl(style) { var styleValues = layoutAttributes.style.values; diff --git a/test/jasmine/tests/mapbox_test.js b/test/jasmine/tests/mapbox_test.js index ae19adc1bd3..6cde3b89f5e 100644 --- a/test/jasmine/tests/mapbox_test.js +++ b/test/jasmine/tests/mapbox_test.js @@ -576,6 +576,59 @@ describe('mapbox plots', function() { }); }); + it('should respond drag / scroll interactions', function(done) { + var updateData; + + gd.on('plotly_relayout', function(eventData) { + updateData = eventData; + }); + + function _drag(p0, p1, cb) { + var promise = _mouseEvent('mousemove', p0, noop).then(function() { + return _mouseEvent('mousedown', p0, noop); + }).then(function() { + return _mouseEvent('mousemove', p1, noop); + }).then(function() { + return _mouseEvent('mouseup', p1, noop); + }).then(function() { + return _mouseEvent('mouseup', p1, noop); + }).then(cb); + + return promise; + } + + function assertLayout(center, zoom, opts) { + var mapInfo = getMapInfo(gd), + layout = gd.layout.mapbox; + + expect([mapInfo.center.lng, mapInfo.center.lat]).toBeCloseToArray(center); + expect(mapInfo.zoom).toBeCloseTo(zoom); + + expect([layout.center.lon, layout.center.lat]).toBeCloseToArray(center); + expect(layout.zoom).toBeCloseTo(zoom); + + if(opts && opts.withUpdateData) { + var mapboxUpdate = updateData.mapbox; + + expect([mapboxUpdate.center.lon, mapboxUpdate.center.lat]).toBeCloseToArray(center); + expect(mapboxUpdate.zoom).toBeCloseTo(zoom); + } + } + + assertLayout([-4.710, 19.475], 1.234); + + var p1 = [pointPos[0] + 50, pointPos[1] - 20]; + + _drag(pointPos, p1, function() { + assertLayout([-19.651, 13.751], 1.234, { withUpdateData: true }); + + }) + .then(done); + + // TODO test scroll + + }); + it('should respond to click interactions by', function(done) { var ptData; @@ -610,45 +663,6 @@ describe('mapbox plots', function() { .then(done); }); - it('should respond drag / scroll interactions', function(done) { - function _drag(p0, p1, cb) { - var promise = _mouseEvent('mousemove', p0, noop).then(function() { - return _mouseEvent('mousedown', p0, noop); - }).then(function() { - return _mouseEvent('mousemove', p1, noop); - }).then(function() { - return _mouseEvent('mouseup', p1, cb); - }); - - return promise; - } - - function assertLayout(center, zoom) { - var mapInfo = getMapInfo(gd), - layout = gd.layout.mapbox; - - expect([mapInfo.center.lng, mapInfo.center.lat]) - .toBeCloseToArray(center); - expect(mapInfo.zoom).toBeCloseTo(zoom); - - expect([layout.center.lon, layout.center.lat]) - .toBeCloseToArray(center); - expect(layout.zoom).toBeCloseTo(zoom); - } - - assertLayout([-4.710, 19.475], 1.234); - - var p1 = [pointPos[0] + 50, pointPos[1] - 20]; - - _drag(pointPos, p1, function() { - assertLayout([-19.651, 13.751], 1.234); - }) - .then(done); - - // TODO test scroll - - }); - function getMapInfo(gd) { var subplot = gd._fullLayout.mapbox._subplot, map = subplot.map;