Skip to content

Commit bdbb3d6

Browse files
committed
replace nested geo SVG with cliped <g geolayer> in main SVG
- 🔪 geo container <div> - 🔪 geoimages <g> and (now obsolete) toSVG method
1 parent d8441a0 commit bdbb3d6

File tree

4 files changed

+36
-86
lines changed

4 files changed

+36
-86
lines changed

src/plot_api/plot_api.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2762,11 +2762,6 @@ function makePlotFramework(gd) {
27622762
fullLayout._glcontainer.enter().append('div')
27632763
.classed('gl-container', true);
27642764

2765-
fullLayout._geocontainer = fullLayout._paperdiv.selectAll('.geo-container')
2766-
.data([0]);
2767-
fullLayout._geocontainer.enter().append('div')
2768-
.classed('geo-container', true);
2769-
27702765
fullLayout._paperdiv.selectAll('.main-svg').remove();
27712766

27722767
fullLayout._paper = fullLayout._paperdiv.insert('svg', ':first-child')
@@ -2810,6 +2805,9 @@ function makePlotFramework(gd) {
28102805
// single ternary layer for the whole plot
28112806
fullLayout._ternarylayer = fullLayout._paper.append('g').classed('ternarylayer', true);
28122807

2808+
// single geo layer for the whole plot
2809+
fullLayout._geolayer = fullLayout._paper.append('g').classed('geolayer', true);
2810+
28132811
// upper shape layer
28142812
// (only for shapes to be drawn above the whole plot, including subplots)
28152813
var layerAbove = fullLayout._paper.append('g')
@@ -2824,7 +2822,6 @@ function makePlotFramework(gd) {
28242822

28252823
// fill in image server scrape-svg
28262824
fullLayout._glimages = fullLayout._paper.append('g').classed('glimages', true);
2827-
fullLayout._geoimages = fullLayout._paper.append('g').classed('geoimages', true);
28282825

28292826
// lastly info (legend, annotations) and hover layers go on top
28302827
// these are in a different svg element normally, but get collapsed into a single

src/plots/geo/geo.js

Lines changed: 29 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ var createGeoZoom = require('./zoom');
2525
var createGeoZoomReset = require('./zoom_reset');
2626
var constants = require('./constants');
2727

28-
var xmlnsNamespaces = require('../../constants/xmlns_namespaces');
2928
var topojsonUtils = require('../../lib/topojson_utils');
3029
var topojsonFeature = require('topojson-client').feature;
3130

@@ -39,8 +38,6 @@ function Geo(options, fullLayout) {
3938
this.container = options.container;
4039
this.topojsonURL = options.topojsonURL;
4140

42-
this.hoverContainer = null;
43-
4441
this.topojsonName = null;
4542
this.topojson = null;
4643

@@ -54,8 +51,6 @@ function Geo(options, fullLayout) {
5451
this.zoom = null;
5552
this.zoomReset = null;
5653

57-
this.xaxis = null;
58-
this.yaxis = null;
5954

6055
this.makeFramework();
6156
this.updateFx(fullLayout.hovermode);
@@ -232,38 +227,30 @@ proto.makePath = function() {
232227
this.path = d3.geo.path().projection(this.projection);
233228
};
234229

235-
/*
236-
* <div this.container>
237-
* <div this.geoDiv>
238-
* <svg this.hoverContainer>
239-
* <svg this.framework>
240-
*/
241230
proto.makeFramework = function() {
242-
var geoDiv = this.geoDiv = d3.select(this.container).append('div');
243-
geoDiv
244-
.attr('id', this.id)
245-
.style('position', 'absolute');
246-
247-
// only choropleth traces use this,
248-
// scattergeo traces use Fx.hover and fullLayout._hoverlayer
249-
var hoverContainer = this.hoverContainer = geoDiv.append('svg');
250-
hoverContainer
251-
.attr(xmlnsNamespaces.svgAttrs)
252-
.style({
253-
'position': 'absolute',
254-
'z-index': 20,
255-
'pointer-events': 'none'
256-
});
257-
258-
var framework = this.framework = geoDiv.append('svg');
231+
var fullLayout = this.graphDiv._fullLayout;
232+
var clipId = 'clip' + fullLayout._uid + this.id;
233+
234+
var defGroup = fullLayout._defs.selectAll('g.clips')
235+
.data([0]);
236+
defGroup.enter().append('g')
237+
.classed('clips', true);
238+
239+
var clipDef = this.clipDef = defGroup.selectAll('#' + clipId)
240+
.data([0]);
241+
242+
clipDef.enter().append('clipPath').attr('id', clipId)
243+
.append('rect');
244+
245+
var framework = this.framework = d3.select(this.container).append('g');
246+
259247
framework
260-
.attr(xmlnsNamespaces.svgAttrs)
261-
.attr({
262-
'position': 'absolute',
263-
'preserveAspectRatio': 'none'
264-
});
248+
.attr('class', 'geo ' + this.id)
249+
.style('pointer-events', 'all')
250+
.call(Drawing.setClipUrl, clipId);
265251

266-
framework.append('g').attr('class', 'bglayer')
252+
framework.append('g')
253+
.attr('class', 'bglayer')
267254
.append('rect');
268255

269256
framework.append('g').attr('class', 'baselayer');
@@ -274,8 +261,6 @@ proto.makeFramework = function() {
274261
// N.B. disable dblclick zoom default
275262
framework.on('dblclick.zoom', null);
276263

277-
// TODO use clip paths instead of nested SVG
278-
279264
this.xaxis = { _id: 'x' };
280265
this.yaxis = { _id: 'y' };
281266
};
@@ -286,28 +271,20 @@ proto.adjustLayout = function(geoLayout, graphSize) {
286271
var left = graphSize.l + graphSize.w * domain.x[0] + geoLayout._marginX,
287272
top = graphSize.t + graphSize.h * (1 - domain.y[1]) + geoLayout._marginY;
288273

289-
this.geoDiv.style({
290-
left: left + 'px',
291-
top: top + 'px',
292-
width: geoLayout._width + 'px',
293-
height: geoLayout._height + 'px'
294-
});
274+
Drawing.setTranslate(this.framework, left, top);
295275

296-
this.hoverContainer.attr({
276+
var dimsAttrs = {
277+
x: 0,
278+
y: 0,
297279
width: geoLayout._width,
298280
height: geoLayout._height
299-
});
281+
};
300282

301-
this.framework.attr({
302-
width: geoLayout._width,
303-
height: geoLayout._height
304-
});
283+
this.clipDef.select('rect')
284+
.attr(dimsAttrs);
305285

306286
this.framework.select('.bglayer').select('rect')
307-
.attr({
308-
width: geoLayout._width,
309-
height: geoLayout._height
310-
})
287+
.attr(dimsAttrs)
311288
.call(Color.fill, geoLayout.bgcolor);
312289

313290
this.xaxis._offset = left;

src/plots/geo/index.js

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,11 @@ exports.plot = function plotGeo(gd) {
4848
geoCalcData = Plots.getSubplotCalcData(calcData, 'geo', geoId),
4949
geo = fullLayout[geoId]._subplot;
5050

51-
// If geo is not instantiated, create one!
5251
if(!geo) {
5352
geo = new Geo({
5453
id: geoId,
5554
graphDiv: gd,
56-
container: fullLayout._geocontainer.node(),
55+
container: fullLayout._geolayer.node(),
5756
topojsonURL: gd._context.topojsonURL
5857
},
5958
fullLayout
@@ -74,31 +73,8 @@ exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout)
7473
var oldGeo = oldFullLayout[oldGeoKey]._subplot;
7574

7675
if(!newFullLayout[oldGeoKey] && !!oldGeo) {
77-
oldGeo.geoDiv.remove();
76+
oldGeo.framework.remove();
77+
oldGeo.clipDef.remove();
7878
}
7979
}
8080
};
81-
82-
exports.toSVG = function(gd) {
83-
var fullLayout = gd._fullLayout,
84-
geoIds = Plots.getSubplotIds(fullLayout, 'geo'),
85-
size = fullLayout._size;
86-
87-
for(var i = 0; i < geoIds.length; i++) {
88-
var geoLayout = fullLayout[geoIds[i]],
89-
domain = geoLayout.domain,
90-
geoFramework = geoLayout._subplot.framework;
91-
92-
geoFramework.attr('style', null);
93-
geoFramework
94-
.attr({
95-
x: size.l + size.w * domain.x[0] + geoLayout._marginX,
96-
y: size.t + size.h * (1 - domain.y[1]) + geoLayout._marginY,
97-
width: geoLayout._width,
98-
height: geoLayout._height
99-
});
100-
101-
fullLayout._geoimages.node()
102-
.appendChild(geoFramework.node());
103-
}
104-
};

test/jasmine/tests/geo_test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ describe('Test geo interactions', function() {
404404
}
405405

406406
function countGeos() {
407-
return d3.select('div.geo-container').selectAll('div').size();
407+
return d3.select('g.geolayer').selectAll('.geo').size();
408408
}
409409

410410
function countColorBars() {

0 commit comments

Comments
 (0)