Skip to content

Commit f058e8b

Browse files
authored
Merge pull request #1004 from plotly/geo-line-picking
Multiple scattergeo improvement
2 parents 987f1aa + 510cb60 commit f058e8b

30 files changed

+865
-388
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ function handleGeo(gd, ev) {
420420
geoIds = Plots.getSubplotIds(fullLayout, 'geo');
421421

422422
for(var i = 0; i < geoIds.length; i++) {
423-
var geo = fullLayout[geoIds[i]]._geo;
423+
var geo = fullLayout[geoIds[i]]._subplot;
424424

425425
if(attr === 'zoom') {
426426
var scale = geo.projection.scale();

Diff for: src/lib/geojson_utils.js

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/**
2+
* Copyright 2012-2016, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
10+
'use strict';
11+
12+
/**
13+
* Convert calcTrace to GeoJSON 'MultiLineString' coordinate arrays
14+
*
15+
* @param {object} calcTrace
16+
* gd.calcdata item.
17+
* Note that calcTrace[i].lonlat is assumed to be defined
18+
*
19+
* @return {array}
20+
* return line coords array (or array of arrays)
21+
*
22+
*/
23+
exports.calcTraceToLineCoords = function(calcTrace) {
24+
var trace = calcTrace[0].trace,
25+
connectgaps = trace.connectgaps;
26+
27+
var coords = [],
28+
lineString = [];
29+
30+
for(var i = 0; i < calcTrace.length; i++) {
31+
var calcPt = calcTrace[i];
32+
33+
lineString.push(calcPt.lonlat);
34+
35+
if(!connectgaps && calcPt.gapAfter && lineString.length > 0) {
36+
coords.push(lineString);
37+
lineString = [];
38+
}
39+
}
40+
41+
coords.push(lineString);
42+
43+
return coords;
44+
};
45+
46+
47+
/**
48+
* Make line ('LineString' or 'MultiLineString') GeoJSON
49+
*
50+
* @param {array} coords
51+
* results form calcTraceToLineCoords
52+
* @param {object} trace
53+
* (optional) full trace object to be added on to output
54+
*
55+
* @return {object} out
56+
* GeoJSON object
57+
*
58+
*/
59+
exports.makeLine = function(coords, trace) {
60+
var out = {};
61+
62+
if(coords.length === 1) {
63+
out = {
64+
type: 'LineString',
65+
coordinates: coords[0]
66+
};
67+
}
68+
else {
69+
out = {
70+
type: 'MultiLineString',
71+
coordinates: coords
72+
};
73+
}
74+
75+
if(trace) out.trace = trace;
76+
77+
return out;
78+
};
79+
80+
/**
81+
* Make polygon ('Polygon' or 'MultiPolygon') GeoJSON
82+
*
83+
* @param {array} coords
84+
* results form calcTraceToLineCoords
85+
* @param {object} trace
86+
* (optional) full trace object to be added on to output
87+
*
88+
* @return {object} out
89+
* GeoJSON object
90+
*/
91+
exports.makePolygon = function(coords, trace) {
92+
var out = {};
93+
94+
if(coords.length === 1) {
95+
out = {
96+
type: 'Polygon',
97+
coordinates: coords
98+
};
99+
}
100+
else {
101+
var _coords = new Array(coords.length);
102+
103+
for(var i = 0; i < coords.length; i++) {
104+
_coords[i] = [coords[i]];
105+
}
106+
107+
out = {
108+
type: 'MultiPolygon',
109+
coordinates: _coords
110+
};
111+
}
112+
113+
if(trace) out.trace = trace;
114+
115+
return out;
116+
};
117+
118+
/**
119+
* Make blank GeoJSON
120+
*
121+
* @return {object}
122+
* Blank GeoJSON object
123+
*
124+
*/
125+
exports.makeBlank = function() {
126+
return {
127+
type: 'Point',
128+
coordinates: []
129+
};
130+
};

Diff for: src/plot_api/subroutines.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ exports.doModeBar = function(gd) {
312312

313313
subplotIds = Plots.getSubplotIds(fullLayout, 'geo');
314314
for(i = 0; i < subplotIds.length; i++) {
315-
var geo = fullLayout[subplotIds[i]]._geo;
315+
var geo = fullLayout[subplotIds[i]]._subplot;
316316
geo.updateFx(fullLayout.hovermode);
317317
}
318318

Diff for: src/plots/cartesian/graph_interact.js

+25-14
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ function hover(gd, evt, subplot) {
379379
curvenum,
380380
cd,
381381
trace,
382+
subplotId,
382383
subploti,
383384
mode,
384385
xval,
@@ -468,7 +469,8 @@ function hover(gd, evt, subplot) {
468469
if(!cd || !cd[0] || !cd[0].trace || cd[0].trace.visible !== true) continue;
469470

470471
trace = cd[0].trace;
471-
subploti = subplots.indexOf(getSubplot(trace));
472+
subplotId = getSubplot(trace);
473+
subploti = subplots.indexOf(subplotId);
472474

473475
// within one trace mode can sometimes be overridden
474476
mode = hovermode;
@@ -495,6 +497,11 @@ function hover(gd, evt, subplot) {
495497
text: undefined
496498
};
497499

500+
// add ref to subplot object (non-cartesian case)
501+
if(fullLayout[subplotId]) {
502+
pointData.subplot = fullLayout[subplotId]._subplot;
503+
}
504+
498505
closedataPreviousLength = hoverData.length;
499506

500507
// for a highlighting array, figure out what
@@ -545,7 +552,6 @@ function hover(gd, evt, subplot) {
545552
hoverData.splice(0, closedataPreviousLength);
546553
distance = hoverData[0].distance;
547554
}
548-
549555
}
550556

551557
// nothing left: remove all labels and quit
@@ -583,31 +589,35 @@ function hover(gd, evt, subplot) {
583589
// other people and send it to the event
584590
for(itemnum = 0; itemnum < hoverData.length; itemnum++) {
585591
var pt = hoverData[itemnum];
592+
586593
var out = {
587594
data: pt.trace._input,
588595
fullData: pt.trace,
589596
curveNumber: pt.trace.index,
590-
pointNumber: pt.index,
591-
x: pt.xVal,
592-
y: pt.yVal,
593-
xaxis: pt.xa,
594-
yaxis: pt.ya
597+
pointNumber: pt.index
595598
};
596-
if(pt.zLabelVal !== undefined) out.z = pt.zLabelVal;
599+
600+
if(pt.trace._module.eventData) out = pt.trace._module.eventData(out, pt);
601+
else {
602+
out.x = pt.xVal;
603+
out.y = pt.yVal;
604+
out.xaxis = pt.xa;
605+
out.yaxis = pt.ya;
606+
607+
if(pt.zLabelVal !== undefined) out.z = pt.zLabelVal;
608+
}
609+
597610
newhoverdata.push(out);
598611
}
612+
599613
gd._hoverdata = newhoverdata;
600614

601615
if(!hoverChanged(gd, evt, oldhoverdata)) return;
602616

603-
/* Emit the custom hover handler. Bind this like:
604-
* gd.on('hover.plotly', function(extras) {
605-
* // do something with extras.data
606-
* });
607-
*/
608617
if(oldhoverdata) {
609618
gd.emit('plotly_unhover', { points: oldhoverdata });
610619
}
620+
611621
gd.emit('plotly_hover', {
612622
points: gd._hoverdata,
613623
xaxes: xaArray,
@@ -620,7 +630,7 @@ function hover(gd, evt, subplot) {
620630
// look for either .subplot (currently just ternary)
621631
// or xaxis and yaxis attributes
622632
function getSubplot(trace) {
623-
return trace.subplot || (trace.xaxis + trace.yaxis);
633+
return trace.subplot || (trace.xaxis + trace.yaxis) || trace.geo;
624634
}
625635

626636
fx.getDistanceFunction = function(mode, dx, dy, dxy) {
@@ -724,6 +734,7 @@ function cleanPoint(d, hovermode) {
724734
if(infomode.indexOf('text') === -1) d.text = undefined;
725735
if(infomode.indexOf('name') === -1) d.name = undefined;
726736
}
737+
727738
return d;
728739
}
729740

0 commit comments

Comments
 (0)