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
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
8000
Diff view
Prev Previous commit
Next Next commit
sync pan/scroll interactions into user/full layout
- and emit mocked `plotly_relayout` event on mouseup
- I chose to not call Plotly.relayout directly for performance
  reasons.
  • Loading branch information
etpinard committed Sep 22, 2017
commit 9faa1b17bf4c0340f9a4fc0d3ae3bf8052397bd6
101 changes: 71 additions & 30 deletions src/plots/geo/zoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,66 @@
'use strict';

var d3 = require('d3');
var Lib = require('../../lib');

var radians = Math.PI / 180,
degrees = 180 / Math.PI,
zoomstartStyle = { cursor: 'pointer' },
zoomendStyle = { cursor: 'auto' };

var radians = Math.PI / 180;
var degrees = 180 / Math.PI;
var zoomstartStyle = {cursor: 'pointer'};
var zoomendStyle = {cursor: 'auto'};

function createGeoZoom(geo, geoLayout) {
var projection = geo.projection;
var zoomConstructor;

if(geoLayout._isScoped) zoomConstructor = zoomScoped;
else if(geoLayout._clipAngle) zoomConstructor = zoomClipped;
else zoomConstructor = zoomNonClipped;
if(geoLayout._isScoped) {
zoomConstructor = zoomScoped;
} else if(geoLayout._isClipped) {
zoomConstructor = zoomClipped;
} else {
zoomConstructor = zoomNonClipped;
}

// TODO add a conic-specific zoom

return zoomConstructor(geo, geoLayout.projection);
return zoomConstructor(geo, projection);
}

module.exports = createGeoZoom;

// common to all zoom types
function initZoom(projection, projLayout) {
var fullScale = projLayout._fullScale;

function initZoom(geo, projection) {
return d3.behavior.zoom()
.translate(projection.translate())
.scale(projection.scale())
.scaleExtent([0.5 * fullScale, 100 * fullScale]);
.scale(projection.scale());
}

// sync zoom updates with user & full layout
function sync(geo, projection, cb) {
var id = geo.id;
var gd = geo.graphDiv;
var userOpts = gd.layout[id];
var fullOpts = gd._fullLayout[id];

var eventData = {};

function set(propStr, val) {
var fullNp = Lib.nestedProperty(fullOpts, propStr);

if(fullNp.get() !== val) {
fullNp.set(val);
Lib.nestedProperty(userOpts, propStr).set(val);
eventData[id + '.' + propStr] = val;
}
}

cb(set);
set('projection.scale', projection.scale() / geo.fitScale);
gd.emit('plotly_relayout', eventData);
}

// zoom for scoped projections
function zoomScoped(geo, projLayout) {
var projection = geo.projection,
zoom = initZoom(projection, projLayout);
function zoomScoped(geo, projection) {
var zoom = initZoom(geo, projection);

function handleZoomstart() {
d3.select(this).style(zoomstartStyle);
Expand All @@ -54,12 +79,19 @@ function zoomScoped(geo, projLayout) {
projection
.scale(d3.event.scale)
.translate(d3.event.translate);

geo.render();
}

function syncCb(set) {
var center = projection.invert(geo.midPt);

set('center.lon', center[0]);
set('center.lat', center[1]);
}

function handleZoomend() {
d3.select(this).style(zoomendStyle);
sync(geo, projection, syncCb);
}

zoom
Expand All @@ -71,9 +103,8 @@ function zoomScoped(geo, projLayout) {
}

// zoom for non-clipped projections
function zoomNonClipped(geo, projLayout) {
var projection = geo.projection,
zoom = initZoom(projection, projLayout);
function zoomNonClipped(geo, projection) {
var zoom = initZoom(geo, projection);

var INSIDETOLORANCEPXS = 2;

Expand Down Expand Up @@ -108,7 +139,6 @@ function zoomNonClipped(geo, projLayout) {
}

projection.scale(d3.event.scale);

projection.translate([translate0[0], d3.event.translate[1]]);

if(!zoomPoint) {
Expand All @@ -127,10 +157,16 @@ function zoomNonClipped(geo, projLayout) {

function handleZoomend() {
d3.select(this).style(zoomendStyle);
sync(geo, projection, syncCb);
}

function syncCb(set) {
var rotate = projection.rotate();
var center = projection.invert(geo.midPt);

// or something like
// http://www.jasondavies.com/maps/gilbert/
// ... a little harder with multiple base layers
set('projection.rotation.lon', -rotate[0]);
set('center.lon', center[0]);
set('center.lat', center[1]);
}

zoom
Expand All @@ -143,10 +179,9 @@ function zoomNonClipped(geo, projLayout) {

// zoom for clipped projections
// inspired by https://www.jasondavies.com/maps/d3.geo.zoom.js
function zoomClipped(geo, projLayout) {
var projection = geo.projection,
view = {r: projection.rotate(), k: projection.scale()},
zoom = initZoom(projection, projLayout),
function zoomClipped(geo, projection) {
var view = {r: projection.rotate(), k: projection.scale()},
zoom = initZoom(geo, projection),
event = d3_eventDispatch(zoom, 'zoomstart', 'zoom', 'zoomend'),
zooming = 0,
zoomOn = zoom.on;
Expand Down Expand Up @@ -179,7 +214,6 @@ function zoomClipped(geo, projLayout) {
// if not, don't do anything new but scale
// if it is, then we can assume between will exist below
// so we don't need the 'bank' function, whatever that is.
// TODO: is this right?
else if(position(projection, mouse1)) {
// go back to original projection temporarily
// except for scale... that's kind of independent?
Expand Down Expand Up @@ -212,6 +246,7 @@ function zoomClipped(geo, projLayout) {
d3.select(this).style(zoomendStyle);
zoomOn.call(zoom, 'zoom', null);
zoomended(event.of(this, arguments));
sync(geo, projection, syncCb);
})
.on('zoom.redraw', function() {
geo.render();
Expand All @@ -229,6 +264,12 @@ function zoomClipped(geo, projLayout) {
if(!--zooming) dispatch({type: 'zoomend'});
}

function syncCb(set) {
var _rotate = projection.rotate();
set('projection.rotation.lon', -_rotate[0]);
set('projection.rotation.lat', -_rotate[1]);
}

return d3.rebind(zoom, event, 'on');
}

Expand Down
381A
0