diff --git a/src/plots/mapbox/mapbox.js b/src/plots/mapbox/mapbox.js index bee610b70eb..0a7edcfdb38 100644 --- a/src/plots/mapbox/mapbox.js +++ b/src/plots/mapbox/mapbox.js @@ -125,7 +125,7 @@ proto.createMap = function(calcData, fullLayout, resolve, reject) { }); // keep track of pan / zoom in user layout and emit relayout event - map.on('move', function() { + map.on('moveend', function(eventData) { var view = self.getView(); opts._input.center = opts.center = view.center; @@ -133,9 +133,19 @@ proto.createMap = function(calcData, fullLayout, resolve, reject) { 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); + // 'moveend' gets triggered by map.setCenter, map.setZoom, + // map.setBearing and map.setPitch. + // + // Here, we make sure that 'plotly_relayout' is + // triggered here only when the 'moveend' originates from a + // mouse target (filtering out API calls) to not + // duplicate 'plotly_relayout' events. + + if(eventData.originalEvent) { + var update = {}; + update[self.id] = Lib.extendFlat({}, view); + gd.emit('plotly_relayout', update); + } }); map.on('mousemove', function(evt) { diff --git a/test/jasmine/tests/mapbox_test.js b/test/jasmine/tests/mapbox_test.js index f0fe06c5b25..043af340a14 100644 --- a/test/jasmine/tests/mapbox_test.js +++ b/test/jasmine/tests/mapbox_test.js @@ -295,9 +295,10 @@ describe('mapbox plots', function() { }).then(function() { expect(countVisibleTraces(gd, modes)).toEqual(2); - mock.data[0].visible = false; + var mockCopy = Lib.extendDeep({}, mock); + mockCopy.data[0].visible = false; - return Plotly.newPlot(gd, mock.data, mock.layout); + return Plotly.newPlot(gd, mockCopy.data, mockCopy.layout); }).then(function() { expect(countVisibleTraces(gd, modes)).toEqual(1); @@ -344,6 +345,17 @@ describe('mapbox plots', function() { }); it('should be able to restyle', function(done) { + var restyleCnt = 0, + relayoutCnt = 0; + + gd.on('plotly_restyle', function() { + restyleCnt++; + }); + + gd.on('plotly_relayout', function() { + relayoutCnt++; + }); + function assertMarkerColor(expectations) { return new Promise(function(resolve) { setTimeout(function() { @@ -366,6 +378,9 @@ describe('mapbox plots', function() { return Plotly.restyle(gd, 'marker.color', 'green'); }) .then(function() { + expect(restyleCnt).toEqual(1); + expect(relayoutCnt).toEqual(0); + return assertMarkerColor([ [0, 0.5019, 0, 1], [0, 0.5019, 0, 1] @@ -375,6 +390,9 @@ describe('mapbox plots', function() { return Plotly.restyle(gd, 'marker.color', 'red', [1]); }) .then(function() { + expect(restyleCnt).toEqual(2); + expect(relayoutCnt).toEqual(0); + return assertMarkerColor([ [0, 0.5019, 0, 1], [1, 0, 0, 1] @@ -384,6 +402,17 @@ describe('mapbox plots', function() { }); it('should be able to relayout', function(done) { + var restyleCnt = 0, + relayoutCnt = 0; + + gd.on('plotly_restyle', function() { + restyleCnt++; + }); + + gd.on('plotly_relayout', function() { + relayoutCnt++; + }); + function assertLayout(style, center, zoom, dims) { var mapInfo = getMapInfo(gd); @@ -403,22 +432,37 @@ describe('mapbox plots', function() { assertLayout('Mapbox Dark', [-4.710, 19.475], 1.234, [80, 100, 908, 270]); Plotly.relayout(gd, 'mapbox.center', { lon: 0, lat: 0 }).then(function() { + expect(restyleCnt).toEqual(0); + expect(relayoutCnt).toEqual(1); + assertLayout('Mapbox Dark', [0, 0], 1.234, [80, 100, 908, 270]); return Plotly.relayout(gd, 'mapbox.zoom', '6'); }).then(function() { + expect(restyleCnt).toEqual(0); + expect(relayoutCnt).toEqual(2); + assertLayout('Mapbox Dark', [0, 0], 6, [80, 100, 908, 270]); return Plotly.relayout(gd, 'mapbox.style', 'light'); }).then(function() { + expect(restyleCnt).toEqual(0); + expect(relayoutCnt).toEqual(3); + assertLayout('Mapbox Light', [0, 0], 6, [80, 100, 908, 270]); return Plotly.relayout(gd, 'mapbox.domain.x', [0, 0.5]); }).then(function() { + expect(restyleCnt).toEqual(0); + expect(relayoutCnt).toEqual(4); + assertLayout('Mapbox Light', [0, 0], 6, [80, 100, 454, 270]); return Plotly.relayout(gd, 'mapbox.domain.y[0]', 0.5); }).then(function() { + expect(restyleCnt).toEqual(0); + expect(relayoutCnt).toEqual(5); + assertLayout('Mapbox Light', [0, 0], 6, [80, 100, 454, 135]); done(); @@ -652,9 +696,11 @@ describe('mapbox plots', function() { }); it('should respond drag / scroll interactions', function(done) { - var updateData; + var relayoutCnt = 0, + updateData; gd.on('plotly_relayout', function(eventData) { + relayoutCnt++; updateData = eventData; }); @@ -663,6 +709,9 @@ describe('mapbox plots', function() { return _mouseEvent('mousedown', p0, noop); }).then(function() { return _mouseEvent('mousemove', p1, noop); + }).then(function() { + // repeat mousemove to simulate long dragging motion + return _mouseEvent('mousemove', p1, noop); }).then(function() { return _mouseEvent('mouseup', p1, noop); }).then(function() { @@ -695,6 +744,7 @@ describe('mapbox plots', function() { var p1 = [pointPos[0] + 50, pointPos[1] - 20]; _drag(pointPos, p1, function() { + expect(relayoutCnt).toEqual(1); assertLayout([-19.651, 13.751], 1.234, { withUpdateData: true }); })