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

Skip to content
This repository was archived by the owner on Oct 6, 2022. It is now read-only.

Commit 87f6cd5

Browse files
committed
solid wip
- first pass scattergeo & choropleth selections - rewrote geo setScale logic using a d3 v4 fitExtent rip - bind calcdata item to scattergeo line and choropleth selection (instead of *special* geojson objects) - clean up geo modebar (with e.g. viewInitial)! - add sync step to zoom end handlers - got choropleth layering to work TODO: - get `geo.position` working (important!) - try out `geo.projection.center` - bg layer pointer-event style is off -> maybe try to use dragElement for all interactions
1 parent 8f20e28 commit 87f6cd5

File tree

25 files changed

+20895
-376
lines changed

25 files changed

+20895
-376
lines changed

src/components/fx/layout_defaults.js

Lines changed: 9 additions & 3 deletions
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
};

src/components/modebar/buttons.js

Lines changed: 35 additions & 30 deletions
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+
}

src/components/modebar/manage.js

Lines changed: 17 additions & 23 deletions
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);

src/lib/geojson_utils.js

Lines changed: 8 additions & 28 deletions
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
/**

src/plot_api/plot_api.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,14 +2196,13 @@ function _relayout(gd, aobj) {
21962196
else flags.doplot = true;
21972197
}
21982198
else {
2199-
var pp1 = String(p.parts[1] || '');
22002199
// check whether we can short-circuit a full redraw
2201-
// 3d or geo at this point just needs to redraw.
2200+
var pp1 = String(p.parts[1] || '');
2201+
22022202
if(proot.indexOf('scene') === 0) {
22032203
if(p.parts[1] === 'camera') flags.docamera = true;
22042204
else flags.doplot = true;
22052205
}
2206-
else if(proot.indexOf('geo') === 0) flags.doplot = true;
22072206
else if(proot.indexOf('ternary') === 0) flags.doplot = true;
22082207
else if(ai === 'paper_bgcolor') flags.doplot = true;
22092208
else if(proot === 'margin' ||

src/plot_api/subroutines.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ exports.doTicksRelayout = function(gd) {
490490

491491
exports.doModeBar = function(gd) {
492492
var fullLayout = gd._fullLayout;
493-
var subplotIds, subplotObj, i;
493+
var subplotIds, subplotLayout, subplotObj, i;
494494

495495
ModeBar.manage(gd);
496496
initInteractions(gd);
@@ -513,6 +513,13 @@ exports.doModeBar = function(gd) {
513513
subplotObj.updateFx(fullLayout);
514514
}
515515

516+
subplotIds = Plots.getSubplotIds(fullLayout, 'geo');
517+
for(i = 0; i < subplotIds.length; i++) {
518+
subplotLayout = fullLayout[subplotIds[i]];
519+
subplotObj = subplotLayout._subplot;
520+
subplotObj.updateFx(fullLayout, subplotLayout);
521+
}
522+
516523
return Plots.previousPromises(gd);
517524
};
518525

src/plots/cartesian/select.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,18 @@ module.exports = function prepSelect(e, startX, startY, dragOptions, mode) {
7979
if(!trace._module || !trace._module.selectPoints) continue;
8080

8181
if(dragOptions.subplot) {
82-
if(trace.subplot !== dragOptions.subplot) continue;
83-
84-
searchTraces.push({
85-
selectPoints: trace._module.selectPoints,
86-
cd: cd,
87-
xaxis: dragOptions.xaxes[0],
88-
yaxis: dragOptions.yaxes[0]
89-
});
90-
}
91-
else {
82+
if(
83+
trace.subplot === dragOptions.subplot ||
84+
trace.geo === dragOptions.subplot
85+
) {
86+
searchTraces.push({
87+
selectPoints: trace._module.selectPoints,
88+
cd: cd,
89+
xaxis: dragOptions.xaxes[0],
90+
yaxis: dragOptions.yaxes[0]
91+
});
92+
}
93+
} else {
9294
if(xAxisIds.indexOf(trace.xaxis) === -1) continue;
9395
if(yAxisIds.indexOf(trace.yaxis) === -1) continue;
9496

src/plots/geo/constants.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ params.fillLayers = ['ocean', 'land', 'lakes'];
135135
// base layer with a only a line color
136136
params.lineLayers = ['subunits', 'countries', 'coastlines', 'rivers', 'frame'];
137137

138+
// TODO should 'frame' sit below or above front and back plot?
139+
138140
params.layers = [
139141
'bg',
140142
'ocean', 'land', 'lakes',

0 commit comments

Comments
 (0)