Skip to content

Commit 2ba7bdf

Browse files
authored
Merge pull request #2030 from plotly/geo-refactor+lasso
Geo refactor and lasso/select-box selections
2 parents 549ee38 + 190c733 commit 2ba7bdf

File tree

80 files changed

+22918
-1477
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+22918
-1477
lines changed

Diff for: src/components/annotations/draw.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ function drawRaw(gd, options, index, subplotId, xa, ya) {
194194

195195
var isSizeConstrained = options.width || options.height;
196196

197-
var annTextClip = fullLayout._defs.select('.clips')
197+
var annTextClip = fullLayout._topclips
198198
.selectAll('#' + annClipID)
199199
.data(isSizeConstrained ? [0] : []);
200200

Diff for: src/components/fx/layout_defaults.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,17 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
2929

3030
coerce('hovermode', hovermodeDflt);
3131

32-
// if only mapbox subplots is present on graph,
32+
// if only mapbox or geo subplots is present on graph,
3333
// reset 'zoom' dragmode to 'pan' until 'zoom' is implemented,
3434
// so that the correct modebar button is active
35-
if(layoutOut._has('mapbox') && layoutOut._basePlotModules.length === 1 &&
36-
layoutOut.dragmode === 'zoom') {
35+
var hasMapbox = layoutOut._has('mapbox');
36+
var hasGeo = layoutOut._has('geo');
37+
var len = layoutOut._basePlotModules.length;
38+
39+
if(layoutOut.dragmode === 'zoom' && (
40+
((hasMapbox || hasGeo) && len === 1) ||
41+
(hasMapbox && hasGeo && len === 2)
42+
)) {
3743
layoutOut.dragmode = 'pan';
3844
}
3945
};

Diff for: src/components/modebar/buttons.js

+35-30
Original file line numberDiff line numberDiff line change
@@ -446,23 +446,24 @@ modeBarButtons.hoverClosestGeo = {
446446
};
447447

448448
function handleGeo(gd, ev) {
449-
var button = ev.currentTarget,
450-
attr = button.getAttribute('data-attr'),
451-
val = button.getAttribute('data-val') || true,
452-
fullLayout = gd._fullLayout,
453-
geoIds = Plots.getSubplotIds(fullLayout, 'geo');
449+
var button = ev.currentTarget;
450+
var attr = button.getAttribute('data-attr');
451+
var val = button.getAttribute('data-val') || true;
452+
var fullLayout = gd._fullLayout;
453+
var geoIds = Plots.getSubplotIds(fullLayout, 'geo');
454454

455455
for(var i = 0; i < geoIds.length; i++) {
456-
var geo = fullLayout[geoIds[i]]._subplot;
456+
var id = geoIds[i];
457+
var geoLayout = fullLayout[id];
457458

458459
if(attr === 'zoom') {
459-
var scale = geo.projection.scale();
460+
var scale = geoLayout.projection.scale;
460461
var newScale = (val === 'in') ? 2 * scale : 0.5 * scale;
461-
geo.projection.scale(newScale);
462-
geo.zoom.scale(newScale);
463-
geo.render();
462+
463+
Plotly.relayout(gd, id + '.projection.scale', newScale);
464+
} else if(attr === 'reset') {
465+
resetView(gd, 'geo');
464466
}
465-
else if(attr === 'reset') geo.zoomReset();
466467
}
467468
}
468469

@@ -535,8 +536,8 @@ modeBarButtons.resetViews = {
535536
button.setAttribute('data-attr', 'resetLastSave');
536537
handleCamera3d(gd, ev);
537538

538-
// N.B handleCamera3d also triggers a replot for
539-
// geo subplots.
539+
resetView(gd, 'geo');
540+
resetView(gd, 'mapbox');
540541
}
541542
};
542543

@@ -581,22 +582,26 @@ modeBarButtons.resetViewMapbox = {
581582
attr: 'reset',
582583
icon: Icons.home,
583584
click: function(gd) {
584-
var fullLayout = gd._fullLayout;
585-
var subplotIds = Plots.getSubplotIds(fullLayout, 'mapbox');
586-
var aObj = {};
587-
588-
for(var i = 0; i < subplotIds.length; i++) {
589-
var id = subplotIds[i];
590-
var subplotObj = fullLayout[id]._subplot;
591-
var viewInitial = subplotObj.viewInitial;
592-
var viewKeys = Object.keys(viewInitial);
593-
594-
for(var j = 0; j < viewKeys.length; j++) {
595-
var key = viewKeys[j];
596-
aObj[id + '.' + key] = viewInitial[key];
597-
}
598-
}
599-
600-
Plotly.relayout(gd, aObj);
585+
resetView(gd, 'mapbox');
601586
}
602587
};
588+
589+
function resetView(gd, subplotType) {
590+
var fullLayout = gd._fullLayout;
591+
var subplotIds = Plots.getSubplotIds(fullLayout, subplotType);
592+
var aObj = {};
593+
594+
for(var i = 0; i < subplotIds.length; i++) {
595+
var id = subplotIds[i];
596+
var subplotObj = fullLayout[id]._subplot;
597+
var viewInitial = subplotObj.viewInitial;
598+
var viewKeys = Object.keys(viewInitial);
599+
600+
for(var j = 0; j < viewKeys.length; j++) {
601+
var key = viewKeys[j];
602+
aObj[id + '.' + key] = viewInitial[key];
603+
}
604+
}
605+
606+
Plotly.relayout(gd, aObj);
607+
}

Diff for: src/components/modebar/manage.js

+17-23
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,16 @@ module.exports = function manageModeBar(gd) {
7171

7272
// logic behind which buttons are displayed by default
7373
function getButtonGroups(gd, buttonsToRemove, buttonsToAdd) {
74-
var fullLayout = gd._fullLayout,
75-
fullData = gd._fullData;
74+
var fullLayout = gd._fullLayout;
75+
var fullData = gd._fullData;
7676

77-
var hasCartesian = fullLayout._has('cartesian'),
78-
hasGL3D = fullLayout._has('gl3d'),
79-
hasGeo = fullLayout._has('geo'),
80-
hasPie = fullLayout._has('pie'),
81-
hasGL2D = fullLayout._has('gl2d'),
82-
hasTernary = fullLayout._has('ternary'),
83-
hasMapbox = fullLayout._has('mapbox');
77+
var hasCartesian = fullLayout._has('cartesian');
78+
var hasGL3D = fullLayout._has('gl3d');
79+
var hasGeo = fullLayout._has('geo');
80+
var hasPie = fullLayout._has('pie');
81+
var hasGL2D = fullLayout._has('gl2d');
82+
var hasTernary = fullLayout._has('ternary');
83+
var hasMapbox = fullLayout._has('mapbox');
8484

8585
var groups = [];
8686

@@ -112,18 +112,13 @@ function getButtonGroups(gd, buttonsToRemove, buttonsToAdd) {
112112
addGroup(['hoverClosest3d']);
113113
}
114114

115-
if(hasGeo) {
116-
addGroup(['zoomInGeo', 'zoomOutGeo', 'resetGeo']);
117-
addGroup(['hoverClosestGeo']);
118-
}
119-
120115
var allAxesFixed = areAllAxesFixed(fullLayout),
121116
dragModeGroup = [];
122117

123118
if(((hasCartesian || hasGL2D) && !allAxesFixed) || hasTernary) {
124119
dragModeGroup = ['zoom2d', 'pan2d'];
125120
}
126-
if(hasMapbox) {
121+
if(hasMapbox || hasGeo) {
127122
dragModeGroup = ['pan2d'];
128123
}
129124
if(isSelectable(fullData)) {
@@ -138,18 +133,17 @@ function getButtonGroups(gd, buttonsToRemove, buttonsToAdd) {
138133

139134
if(hasCartesian && hasPie) {
140135
addGroup(['toggleHover']);
141-
}
142-
else if(hasGL2D) {
136+
} else if(hasGL2D) {
143137
addGroup(['hoverClosestGl2d']);
144-
}
145-
else if(hasCartesian) {
138+
} else if(hasCartesian) {
146139
addGroup(['toggleSpikelines', 'hoverClosestCartesian', 'hoverCompareCartesian']);
147-
}
148-
else if(hasPie) {
140+
} else if(hasPie) {
149141
addGroup(['hoverClosestPie']);
150-
}
151-
else if(hasMapbox) {
142+
} else if(hasMapbox) {
152143
addGroup(['resetViewMapbox', 'toggleHover']);
144+
} else if(hasGeo) {
145+
addGroup(['zoomInGeo', 'zoomOutGeo', 'resetGeo']);
146+
addGroup(['hoverClosestGeo']);
153147
}
154148

155149
return appendButtonsToGroups(groups, buttonsToAdd);

Diff for: src/lib/array_to_calc_item.js

-15
This file was deleted.

Diff for: src/lib/geojson_utils.js

+8-28
Original file line numberDiff line numberDiff line change
@@ -54,70 +54,50 @@ exports.calcTraceToLineCoords = function(calcTrace) {
5454
*
5555
* @param {array} coords
5656
* results form calcTraceToLineCoords
57-
* @param {object} trace
58-
* (optional) full trace object to be added on to output
59-
*
6057
* @return {object} out
6158
* GeoJSON object
6259
*
6360
*/
64-
exports.makeLine = function(coords, trace) {
65-
var out = {};
66-
61+
exports.makeLine = function(coords) {
6762
if(coords.length === 1) {
68-
out = {
63+
return {
6964
type: 'LineString',
7065
coordinates: coords[0]
7166
};
72-
}
73-
else {
74-
out = {
67+
} else {
68+
return {
7569
type: 'MultiLineString',
7670
coordinates: coords
7771
};
7872
}
79-
80-
if(trace) out.trace = trace;
81-
82-
return out;
8373
};
8474

8575
/**
8676
* Make polygon ('Polygon' or 'MultiPolygon') GeoJSON
8777
*
8878
* @param {array} coords
8979
* results form calcTraceToLineCoords
90-
* @param {object} trace
91-
* (optional) full trace object to be added on to output
92-
*
9380
* @return {object} out
9481
* GeoJSON object
9582
*/
96-
exports.makePolygon = function(coords, trace) {
97-
var out = {};
98-
83+
exports.makePolygon = function(coords) {
9984
if(coords.length === 1) {
100-
out = {
85+
return {
10186
type: 'Polygon',
10287
coordinates: coords
10388
};
104-
}
105-
else {
89+
} else {
10690
var _coords = new Array(coords.length);
10791

10892
for(var i = 0; i < coords.length; i++) {
10993
_coords[i] = [coords[i]];
11094
}
11195

112-
out = {
96+
return {
11397
type: 'MultiPolygon',
11498
coordinates: _coords
11599
};
116100
}
117-
118-
if(trace) out.trace = trace;
119-
120-
return out;
121101
};
122102

123103
/**

Diff for: src/plot_api/plot_api.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -2748,8 +2748,8 @@ Plotly.purge = function purge(gd) {
27482748
// makePlotFramework: Create the plot container and axes
27492749
// -------------------------------------------------------
27502750
function makePlotFramework(gd) {
2751-
var gd3 = d3.select(gd),
2752-
fullLayout = gd._fullLayout;
2751+
var gd3 = d3.select(gd);
2752+
var fullLayout = gd._fullLayout;
27532753

27542754
// Plot container
27552755
fullLayout._container = gd3.selectAll('.plot-container').data([0]);
@@ -2795,9 +2795,15 @@ function makePlotFramework(gd) {
27952795
fullLayout._defs = fullLayout._paper.append('defs')
27962796
.attr('id', 'defs-' + fullLayout._uid);
27972797

2798+
fullLayout._clips = fullLayout._defs.append('g')
2799+
.classed('clips', true);
2800+
27982801
fullLayout._topdefs = fullLayout._toppaper.append('defs')
27992802
.attr('id', 'topdefs-' + fullLayout._uid);
28002803

2804+
fullLayout._topclips = fullLayout._topdefs.append('g')
2805+
.classed('clips', true);
2806+
28012807
fullLayout._bgLayer = fullLayout._paper.append('g')
28022808
.classed('bglayer', true);
28032809

Diff for: src/plot_api/subroutines.js

+4-18
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,7 @@ exports.lsInner = function(gd) {
151151
// Clip so that data only shows up on the plot area.
152152
plotinfo.clipId = 'clip' + fullLayout._uid + subplot + 'plot';
153153

154-
var plotClip = fullLayout._defs.selectAll('g.clips')
155-
.selectAll('#' + plotinfo.clipId)
154+
var plotClip = fullLayout._clips.selectAll('#' + plotinfo.clipId)
156155
.data([0]);
157156

158157
plotClip.enter().append('clipPath')
@@ -490,28 +489,15 @@ exports.doTicksRelayout = function(gd) {
490489

491490
exports.doModeBar = function(gd) {
492491
var fullLayout = gd._fullLayout;
493-
var subplotIds, subplotObj, i;
494492

495493
ModeBar.manage(gd);
496494
initInteractions(gd);
497495

498-
subplotIds = Plots.getSubplotIds(fullLayout, 'gl3d');
499-
for(i = 0; i < subplotIds.length; i++) {
500-
subplotObj = fullLayout[subplotIds[i]]._scene;
501-
subplotObj.updateFx(fullLayout.dragmode, fullLayout.hovermode);
496+
for(var i = 0; i < fullLayout._basePlotModules.length; i++) {
497+
var updateFx = fullLayout._basePlotModules[i].updateFx;
498+
if(updateFx) updateFx(fullLayout);
502499
}
503500

504-
subplotIds = Plots.getSubplotIds(fullLayout, 'gl2d');
505-
for(i = 0; i < subplotIds.length; i++) {
506-
subplotObj = fullLayout._plots[subplotIds[i]]._scene2d;
507-
subplotObj.updateFx(fullLayout.dragmode);
508-
}
509-
510-
subplotIds = Plots.getSubplotIds(fullLayout, 'mapbox');
511-
for(i = 0; i < subplotIds.length; i++) {
512-
subplotObj = fullLayout[subplotIds[i]]._subplot;
513-
subplotObj.updateFx(fullLayout);
514-
}
515501

516502
return Plots.previousPromises(gd);
517503
};

0 commit comments

Comments
 (0)