8000 Geo refactor and lasso/select-box selections by etpinard · Pull Request #2030 · plotly/plotly.js · GitHub
[go: up one dir, main page]

Skip to content

Geo refactor and lasso/select-box selections #2030

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 42 commits into from
Sep 28, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
4c1ddb8
Introduce geo 2.0
etpinard Sep 21, 2017
482cca1
merge geo axis attrs module into 'main' layout attr module
etpinard Sep 21, 2017
a0be087
add 'geo.center' + improve defaults & :books:
etpinard Sep 21, 2017
e9efdd0
use relayout in geo modeBar buttons
etpinard Sep 21, 2017
9faa1b1
sync pan/scroll interactions into user/full layout
etpinard Sep 21, 2017
d0ea7c9
adapt scattergeo to new geo layers and projection logic
etpinard Sep 21, 2017
a981eb5
adapt choropleth plot and hover (in preparation for selections)
etpinard Sep 21, 2017
44f56dd
prelim stuff for geo selections
etpinard Sep 21, 2017
e53a908
DRY up select test suite
etpinard Sep 21, 2017
0e22ba0
add scattergeo lasso/select
etpinard Sep 21, 2017
397d47c
add choropleth lasso/select
etpinard Sep 21, 2017
825e24d
resolves #1995 - add a miter limit on scattergeo
etpinard Sep 21, 2017
24c2422
clean up and improve geo defaults tests
etpinard Sep 21, 2017
c2b0f9c
resolves #292 - add mucho test for geo pan/scroll interactions
etpinard Sep 21, 2017
3bd89d3
add one geo base layer update test
etpinard Sep 21, 2017
e59c90b
resolves #1698 - add geo_across-antimeridian mock
etpinard Sep 21, 2017
eaf44a8
resolves #1996 - add `geo_scattergeo-out-of-usa`
etpinard Sep 21, 2017
4d9b566
resolves #1486 - add `geo_centering` mock
etpinard Sep 21, 2017
32a29c7
update conic baselines
etpinard Sep 21, 2017
be59f69
update a few scoped baseline
etpinard Sep 21, 2017
36833d4
update `geo_fill` mock
etpinard Sep 22, 2017
7e5bb41
update baseline to show proper marker.opacity
etpinard Sep 22, 2017
a30beea
update other geo baselines
etpinard Sep 22, 2017
fd5bf11
:hocho: obsolete files and logic
etpinard Sep 22, 2017
ae48369
rename temporary geo2.js -> geo.js :tada:
etpinard Sep 22, 2017
5bc2c71
add 'step' name to failure message
etpinard Sep 25, 2017
ab05990
compute geo.midPt more efficiently
etpinard Sep 25, 2017
ce31666
lint (rename params -> exports)
etpinard Sep 25, 2017
eeee911
use {} instead of [] to identify line & fill layers
etpinard Sep 25, 2017
71c5355
improve selection queries
etpinard Sep 25, 2017
a3df09e
use beforeEach in per-trace select tests
etpinard Sep 25, 2017
05e8194
update across antimeridian mock
etpinard Sep 25, 2017
935e4ac
add jasmine test
etpinard Sep 25, 2017
2488f4b
add per-basePlot-module updateFx methods
etpinard Sep 25, 2017
303de22
add `stroke-miterlimit: 2` to base layer lines
etpinard Sep 25, 2017
9bb7d91
use dragElement.unhover to queued Fx.hover calls
etpinard Sep 26, 2017
1c26ec4
add geo.project and use that in scattergeo hover
etpinard Sep 26, 2017
1d2ce2d
handle invalid geo setting that lead to invalid bounds
etpinard Sep 26, 2017
651399e
fix choropleth hover for countries w/ have polygons that cross -180
etpinard Sep 27, 2017
8f9b75a
add _clips and _topclips <g> in makePlotFramework
etpinard Sep 27, 2017
0089488
lint
etpinard Sep 27, 2017
190c733
fix choropleth hover over Antarctica
etpinard Sep 27, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
fix choropleth hover over Antarctica
- ++ cleaner hover polygon logic
- no mutation when offsetting RUS and FJI longitudes
- do not offset RUS and FJI polygons that do not need modification
  for hover!
  • Loading branch information
etpinard committed Sep 27, 2017
commit 190c7338b3f2a6271d54bf90129129374e5596f8
119 changes: 93 additions & 26 deletions src/traces/choropleth/plot.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,8 @@ function calcGeoJSON(calcTrace, topojson) {
var trace = calcTrace[0].trace;
var len = calcTrace.length;
var features = getTopojsonFeatures(trace, topojson);
var i, j, k, m;

for(i = 0; i < len; i++) {
for(var i = 0; i < len; i++) {
var calcPt = calcTrace[i];
var feature = locationToFeature(trace.locationmode, calcPt.loc, features);

Expand All @@ -66,48 +65,116 @@ function calcGeoJSON(calcTrace, topojson) {
continue;
}


calcPt.geojson = feature;
calcPt.ct = feature.properties.ct;
calcPt.index = i;
calcPt._polygons = feature2polygons(feature);
}
}

var geometry = feature.geometry;
var coords = geometry.coordinates;
calcPt._polygons = [];
function feature2polygons(feature) {
var geometry = feature.geometry;
var coords = geometry.coordinates;
var loc = feature.id;

var polygons = [];
var appendPolygon, j, k, m;

function doesCrossAntiMerdian(pts) {
for(var l = 0; l < pts.length - 1; l++) {
if(pts[l][0] > 0 && pts[l + 1][0] < 0) return l;
}
return null;
}

if(loc === 'RUS' || loc === 'FJI') {
// Russia and Fiji have landmasses that cross the antimeridian,
// we need to add +360 to their longitude coordinates, so that
// polygon 'contains' doesn't get confused when crossing the antimeridian.
//
// Note that other countries have polygons on either side of the antimeridian
// (e.g. some Aleutian island for the USA), but those don't confuse
// the 'contains' method; these are skipped here.
if(calcPt.loc === 'RUS' || calcPt.loc === 'FJI') {
for(j = 0; j < coords.length; j++) {
for(k = 0; k < coords[j].length; k++) {
for(m = 0; m < coords[j][k].length; m++) {
if(coords[j][k][m][0] < 0) {
coords[j][k][m][0] += 360;
}
}
appendPolygon = function(_pts) {
var pts;

if(doesCrossAntiMerdian(_pts) === null) {
pts = _pts;
} else {
pts = new Array(_pts.length);
for(m = 0; m < _pts.length; m++) {
// do nut mutate calcdata[i][j].geojson !!
pts[m] = [
_pts[m][0] < 0 ? _pts[m][0] + 360 : _pts[m][0],
_pts[m][1]
];
}
}
}

switch(geometry.type) {
case 'MultiPolygon':
for(j = 0; j < coords.length; j++) {
for(k = 0; k < coords[j].length; k++) {
calcPt._polygons.push(polygon.tester(coords[j][k]));
}
polygons.push(polygon.tester(pts));
};
} else if(loc === 'ATA') {
// Antarctica has a landmass that wraps around every longitudes which
// confuses the 'contains' methods.
appendPolygon = function(pts) {
var crossAntiMeridianIndex = doesCrossAntiMerdian(pts);

// polygon that do not cross anti-meridian need no special handling
if(crossAntiMeridianIndex === null) {
return polygons.push(polygon.tester(pts));
}

// stitch polygon by adding pt over South Pole,
// so that it covers the projected region covers all latitudes
//
// Note that the algorithm below only works for polygons that
// start and end on longitude -180 (like the ones built by
// https://github.com/etpinard/sane-topojson).
var stitch = new Array(pts.length + 1);
var si = 0;

for(m = 0; m < pts.length; m++) {
if(m > crossAntiMeridianIndex) {
stitch[si++] = [pts[m][0] + 360, pts[m][1]];
} else if(m === crossAntiMeridianIndex) {
stitch[si++] = pts[m];
stitch[si++] = [pts[m][0], -90];
} else {
stitch[si++] = pts[m];
}
break;
case 'Polygon':
for(j = 0; j < coords.length; j++) {
calcPt._polygons.push(polygon.tester(coords[j]));
}

// polygon.tester by default appends pt[0] to the points list,
// we must remove it here, to avoid a jump in longitude from 180 to -180,
// that would confuse the 'contains' method
var tester = polygon.tester(stitch);
tester.pts.pop();
polygons.push(tester);
};
} else {
// otherwise using same array ref is fine
appendPolygon = function(pts) {
polygons.push(polygon.tester(pts));
};
}

switch(geometry.type) {
case 'MultiPolygon':
for(j = 0; j < coords.length; j++) {
for(k = 0; k < coords[j].length; k++) {
appendPolygon(coords[j][k]);
}
break;
}
}
break;
case 'Polygon':
for(j = 0; j < coords.length; j++) {
appendPolygon(coords[j]);
}
break;
}

return polygons;
}

function style(geo) {
Expand Down
15 changes: 13 additions & 2 deletions test/jasmine/tests/geo_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1306,8 +1306,8 @@ describe('Test geo interactions', function() {

Plotly.newPlot(gd, [{
type: 'choropleth',
locations: ['RUS', 'FJI'],
z: [0, 1]
locations: ['RUS', 'FJI', 'ATA'],
z: [0, 1, 2]
}])
.then(function() {
check([81, 66], 1, 'spot in north-central Russia that polygon.contains gets wrong before +360 shift');
Expand All @@ -1326,6 +1326,17 @@ describe('Test geo interactions', function() {
.then(function() {
check([179, -16.6], 1, 'spot on Fiji island that cross antimeridian west of antimeridian');
check([-179.9, -16.2], 1, 'spot on Fiji island that cross antimeridian east of antimeridian');

return Plotly.relayout(gd, {
'geo.center.lat': null,
'geo.projection': {
type: 'orthographic',
rotation: {lat: -90}
}
});
})
.then(function() {
check([-150, -89], 1, 'spot in Antarctica that requires *stitching*');
})
.catch(fail)
.then(done);
Expand Down
0