Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8ef1445

Browse filesBrowse files
authored
Merge pull request plotly#3272 from plotly/snapshot-clippath-base
Do not add <base> href to SVG clip paths during toImage
2 parents bd7fefa + 76f5ad0 commit 8ef1445
Copy full SHA for 8ef1445

File tree

Expand file treeCollapse file tree

25 files changed

+131
-82
lines changed
Filter options
Expand file treeCollapse file tree

25 files changed

+131
-82
lines changed

‎src/components/annotations/draw.js

Copy file name to clipboardExpand all lines: src/components/annotations/draw.js
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,14 +411,14 @@ function drawRaw(gd, options, index, subplotId, xa, ya) {
411411
x: borderfull + xShift - 1,
412412
y: borderfull + yShift
413413
})
414-
.call(Drawing.setClipUrl, isSizeConstrained ? annClipID : null);
414+
.call(Drawing.setClipUrl, isSizeConstrained ? annClipID : null, gd);
415415
}
416416
else {
417417
var texty = borderfull + yShift - anntextBB.top;
418418
var textx = borderfull + xShift - anntextBB.left;
419419

420420
annText.call(svgTextUtils.positionText, textx, texty)
421-
.call(Drawing.setClipUrl, isSizeConstrained ? annClipID : null);
421+
.call(Drawing.setClipUrl, isSizeConstrained ? annClipID : null, gd);
422422
}
423423

424424
annTextClip.select('rect').call(Drawing.setRect, borderfull, borderfull,

‎src/components/drawing/index.js

Copy file name to clipboardExpand all lines: src/components/drawing/index.js
+15-19Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,32 +1000,28 @@ function nodeHash(node) {
10001000
node.getAttribute('style');
10011001
}
10021002

1003-
/*
1004-
* make a robust clipPath url from a local id
1005-
* note! We'd better not be exporting from a page
1006-
* with a <base> or the svg will not be portable!
1003+
/**
1004+
* Set clipPath URL in a way that work for all situations.
1005+
*
1006+
* In details, graphs on pages with <base> HTML tags need to prepend
1007+
* the clip path ids with the page's base url EXCEPT during toImage exports.
1008+
*
1009+
* @param {d3 selection} s : node to add clip-path attribute
1010+
* @param {string} localId : local clip-path (w/o base url) id
1011+
* @param {DOM element || object} gd
1012+
* - context._baseUrl {string}
1013+
* - context._exportedPlot {boolean}
10071014
*/
1008-
drawing.setClipUrl = function(s, localId) {
1015+
drawing.setClipUrl = function(s, localId, gd) {
10091016
if(!localId) {
10101017
s.attr('clip-path', null);
10111018
return;
10121019
}
10131020

1014-
if(drawing.baseUrl === undefined) {
1015-
var base = d3.select('base');
1016-
1017-
// Stash base url once and for all!
1018-
// We may have to stash this elsewhere when
1019-
// we'll try to support for child windows
1020-
// more info -> https://github.com/plotly/plotly.js/issues/702
1021-
if(base.size() && base.attr('href')) {
1022-
drawing.baseUrl = window.location.href.split('#')[0];
1023-
} else {
1024-
drawing.baseUrl = '';
1025-
}
1026-
}
1021+
var context = gd._context;
1022+
var baseUrl = context._exportedPlot ? '' : (context._baseUrl || '');
10271023

1028-
s.attr('clip-path', 'url(' + drawing.baseUrl + '#' + localId + ')');
1024+
s.attr('clip-path', 'url(' + baseUrl + '#' + localId + ')');
10291025
};
10301026

10311027
drawing.getTranslate = function(element) {

‎src/components/errorbars/plot.js

Copy file name to clipboardExpand all lines: src/components/errorbars/plot.js
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var isNumeric = require('fast-isnumeric');
1515
var Drawing = require('../drawing');
1616
var subTypes = require('../../traces/scatter/subtypes');
1717

18-
module.exports = function plot(traces, plotinfo, transitionOpts) {
18+
module.exports = function plot(gd, traces, plotinfo, transitionOpts) {
1919
var isNew;
2020

2121
var xa = plotinfo.xaxis;
@@ -66,7 +66,7 @@ module.exports = function plot(traces, plotinfo, transitionOpts) {
6666
.style('opacity', 1);
6767
}
6868

69-
Drawing.setClipUrl(errorbars, plotinfo.layerClipId);
69+
Drawing.setClipUrl(errorbars, plotinfo.layerClipId, gd);
7070

7171
errorbars.each(function(d) {
7272
var errorbar = d3.select(this);

‎src/components/images/draw.js

Copy file name to clipboardExpand all lines: src/components/images/draw.js
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,10 @@ module.exports = function draw(gd) {
168168
yId = ya ? ya._id : '',
169169
clipAxes = xId + yId;
170170

171-
thisImage.call(Drawing.setClipUrl, clipAxes ?
172-
('clip' + fullLayout._uid + clipAxes) :
173-
null
171+
Drawing.setClipUrl(
172+
thisImage,
173+
clipAxes ? ('clip' + fullLayout._uid + clipAxes) : null,
174+
gd
174175
);
175176
}
176177

‎src/components/legend/draw.js

Copy file name to clipboardExpand all lines: src/components/legend/draw.js
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ module.exports = function draw(gd) {
224224
y: opts.borderwidth
225225
});
226226

227-
Drawing.setClipUrl(scrollBox, clipId);
227+
Drawing.setClipUrl(scrollBox, clipId, gd);
228228

229229
Drawing.setRect(scrollBar, 0, 0, 0, 0);
230230
delete opts._scrollY;
@@ -262,7 +262,7 @@ module.exports = function draw(gd) {
262262
y: opts.borderwidth + scrollBoxY
263263
});
264264

265-
Drawing.setClipUrl(scrollBox, clipId);
265+
Drawing.setClipUrl(scrollBox, clipId, gd);
266266

267267
scrollHandler(scrollBoxY, scrollBarHeight, scrollRatio);
268268

‎src/components/rangeslider/draw.js

Copy file name to clipboardExpand all lines: src/components/rangeslider/draw.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ function drawRangePlot(rangeSlider, gd, axisOpts, opts) {
401401

402402
rangePlots.enter().append('g')
403403
.attr('class', function(id) { return constants.rangePlotClassName + ' ' + id; })
404-
.call(Drawing.setClipUrl, opts._clipId);
404+
.call(Drawing.setClipUrl, opts._clipId, gd);
405405

406406
rangePlots.order();
407407

‎src/components/shapes/draw.js

Copy file name to clipboardExpand all lines: src/components/shapes/draw.js
+8-6Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,10 @@ function setClipPath(shapePath, gd, shapeOptions) {
120120
// spans two subplots. See https://github.com/plotly/plotly.js/issues/1452
121121
var clipAxes = (shapeOptions.xref + shapeOptions.yref).replace(/paper/g, '');
122122

123-
shapePath.call(Drawing.setClipUrl, clipAxes ?
124-
('clip' + gd._fullLayout._uid + clipAxes) :
125-
null
123+
Drawing.setClipUrl(
124+
shapePath,
125+
clipAxes ? 'clip' + gd._fullLayout._uid + clipAxes : null,
126+
gd
126127
);
127128
}
128129

@@ -493,9 +494,10 @@ function setupDragElement(gd, shapePath, shapeOptions, index, shapeLayer) {
493494
if(xref !== 'paper' && !xa.autorange) clipAxes += xref;
494495
if(yref !== 'paper' && !ya.autorange) clipAxes += yref;
495496

496-
shapePath.call(Drawing.setClipUrl, clipAxes ?
497-
'clip' + gd._fullLayout._uid + clipAxes :
498-
null
497+
Drawing.setClipUrl(
498+
shapePath,
499+
clipAxes ? 'clip' + gd._fullLayout._uid + clipAxes : null,
500+
gd
499501
);
500502
}
501503
}

‎src/components/updatemenus/scrollbox.js

Copy file name to clipboardExpand all lines: src/components/updatemenus/scrollbox.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ ScrollBox.prototype.enable = function enable(position, translateX, translateY) {
254254
height: Math.ceil(clipB) - Math.floor(clipT)
255255
});
256256

257-
this.container.call(Drawing.setClipUrl, clipId);
257+
this.container.call(Drawing.setClipUrl, clipId, this.gd);
258258

259259
this.bg.attr({
260260
x: l,

‎src/plot_api/plot_api.js

Copy file name to clipboardExpand all lines: src/plot_api/plot_api.js
+13-4Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,6 @@ exports.plot = function(gd, data, layout, config) {
110110
// so we can share cached text across tabs
111111
Drawing.makeTester();
112112

113-
// clear stashed base url
114-
delete Drawing.baseUrl;
115-
116113
// collect promises for any async actions during plotting
117114
// any part of the plotting code can push to gd._promises, then
118115
// before we move to the next step, we check that they're all
@@ -419,7 +416,16 @@ function opaqueSetBackground(gd, bgColor) {
419416
}
420417

421418
function setPlotContext(gd, config) {
422-
if(!gd._context) gd._context = Lib.extendDeep({}, defaultConfig);
419+
if(!gd._context) {
420+
gd._context = Lib.extendDeep({}, defaultConfig);
421+
422+
// stash <base> href, used to make robust clipPath URLs
423+
var base = d3.select('base');
424+
gd._context._baseUrl = base.size() && base.attr('href') ?
425+
window.location.href.split('#')[0] :
426+
'';
427+
}
428+
423429
var context = gd._context;
424430

425431
var i, keys, key;
@@ -465,6 +471,9 @@ function setPlotContext(gd, config) {
465471
}
466472
}
467473
}
474+
475+
// not part of the user-facing config options
476+
context._exportedPlot = config._exportedPlot;
468477
}
469478

470479
// staticPlot forces a bunch of others:

‎src/plot_api/subroutines.js

Copy file name to clipboardExpand all lines: src/plot_api/subroutines.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ function lsInner(gd) {
224224
layerClipId = null;
225225
}
226226

227-
Drawing.setClipUrl(plotinfo.plot, plotClipId);
227+
Drawing.setClipUrl(plotinfo.plot, plotClipId, gd);
228228

229229
// stash layer clipId value (null or same as clipId)
230230
// to DRY up Drawing.setClipUrl calls on trace-module and trace layers

‎src/plot_api/to_image.js

Copy file name to clipboardExpand all lines: src/plot_api/to_image.js
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ function toImage(gd, opts) {
137137

138138
// extend config for static plot
139139
var configImage = Lib.extendFlat({}, config, {
140+
_exportedPlot: true,
140141
staticPlot: true,
141142
setBackground: setBackground
142143
});

‎src/plots/cartesian/index.js

Copy file name to clipboardExpand all lines: src/plots/cartesian/index.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ function plotOne(gd, plotinfo, cdSubplot, transitionOpts, makeOnCompleteCallback
262262

263263
// layers that allow `cliponaxis: false`
264264
if(className !== 'scatterlayer' && className !== 'barlayer') {
265-
Drawing.setClipUrl(sel, plotinfo.layerClipId);
265+
Drawing.setClipUrl(sel, plotinfo.layerClipId, gd);
266266
}
267267
});
268268

‎src/plots/geo/geo.js

Copy file name to clipboardExpand all lines: src/plots/geo/geo.js
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,8 @@ proto.updateFx = function(fullLayout, geoLayout) {
470470

471471
proto.makeFramework = function() {
472472
var _this = this;
473-
var fullLayout = _this.graphDiv._fullLayout;
473+
var gd = _this.graphDiv;
474+
var fullLayout = gd._fullLayout;
474475
var clipId = 'clip' + fullLayout._uid + _this.id;
475476

476477
_this.clipDef = fullLayout._clips.append('clipPath')
@@ -480,7 +481,7 @@ proto.makeFramework = function() {
480481

481482
_this.framework = d3.select(_this.container).append('g')
482483
.attr('class', 'geo ' + _this.id)
483-
.call(Drawing.setClipUrl, clipId);
484+
.call(Drawing.setClipUrl, clipId, gd);
484485

485486
// sane lonlat to px
486487
_this.project = function(v) {

‎src/plots/polar/polar.js

Copy file name to clipboardExpand all lines: src/plots/polar/polar.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ proto.updateLayout = function(fullLayout, polarLayout) {
290290

291291
layers.frontplot
292292
.attr('transform', strTranslate(xOffset2, yOffset2))
293-
.call(Drawing.setClipUrl, _this._hasClipOnAxisFalse ? null : _this.clipIds.forTraces);
293+
.call(Drawing.setClipUrl, _this._hasClipOnAxisFalse ? null : _this.clipIds.forTraces, _this.gd);
294294

295295
layers.bg
296296
.attr('d', dPath)

‎src/plots/ternary/ternary.js

Copy file name to clipboardExpand all lines: src/plots/ternary/ternary.js
+5-3Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ proto.plot = function(ternaryCalcData, fullLayout) {
7777

7878
proto.makeFramework = function(fullLayout) {
7979
var _this = this;
80+
var gd = _this.graphDiv;
8081
var ternaryLayout = fullLayout[_this.id];
8182

8283
var clipId = _this.clipId = 'clip' + _this.layoutId + _this.id;
@@ -96,8 +97,8 @@ proto.makeFramework = function(fullLayout) {
9697
_this.plotContainer = Lib.ensureSingle(_this.container, 'g', _this.id);
9798
_this.updateLayers(ternaryLayout);
9899

99-
Drawing.setClipUrl(_this.layers.backplot, clipId);
100-
Drawing.setClipUrl(_this.layers.grids, clipId);
100+
Drawing.setClipUrl(_this.layers.backplot, clipId, gd);
101+
Drawing.setClipUrl(_this.layers.grids, clipId, gd);
101102
};
102103

103104
proto.updateLayers = function(ternaryLayout) {
@@ -345,7 +346,8 @@ proto.adjustLayout = function(ternaryLayout, graphSize) {
345346

346347
Drawing.setClipUrl(
347348
_this.layers.frontplot,
348-
_this._hasClipOnAxisFalse ? null : _this.clipId
349+
_this._hasClipOnAxisFalse ? null : _this.clipId,
350+
_this.graphDiv
349351
);
350352
};
351353

‎src/traces/bar/plot.js

Copy file name to clipboardExpand all lines: src/traces/bar/plot.js
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ module.exports = function plot(gd, plotinfo, cdbar, barLayer) {
124124
.style('vector-effect', 'non-scaling-stroke')
125125
.attr('d',
126126
'M' + x0 + ',' + y0 + 'V' + y1 + 'H' + x1 + 'V' + y0 + 'Z')
127-
.call(Drawing.setClipUrl, plotinfo.layerClipId);
127+
.call(Drawing.setClipUrl, plotinfo.layerClipId, gd);
128128

129129
appendBarText(gd, bar, cd, i, x0, x1, y0, y1);
130130

@@ -136,11 +136,11 @@ module.exports = function plot(gd, plotinfo, cdbar, barLayer) {
136136
// lastly, clip points groups of `cliponaxis !== false` traces
137137
// on `plotinfo._hasClipOnAxisFalse === true` subplots
138138
var hasClipOnAxisFalse = cd0.trace.cliponaxis === false;
139-
Drawing.setClipUrl(plotGroup, hasClipOnAxisFalse ? null : plotinfo.layerClipId);
139+
Drawing.setClipUrl(plotGroup, hasClipOnAxisFalse ? null : plotinfo.layerClipId, gd);
140140
});
141141

142142
// error bars are on the top
143-
Registry.getComponentMethod('errorbars', 'plot')(bartraces, plotinfo);
143+
Registry.getComponentMethod('errorbars', 'plot')(gd, bartraces, plotinfo);
144144
};
145145

146146
function appendBarText(gd, bar, calcTrace, i, x0, x1, y0, y1) {

‎src/traces/barpolar/plot.js

Copy file name to clipboardExpand all lines: src/traces/barpolar/plot.js
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ module.exports = function plot(gd, subplot, cdbar) {
6969
});
7070

7171
// clip plotGroup, when trace layer isn't clipped
72-
Drawing.setClipUrl(plotGroup, subplot._hasClipOnAxisFalse ? subplot.clipIds.forTraces : null);
72+
Drawing.setClipUrl(
73+
plotGroup,
74+
subplot._hasClipOnAxisFalse ? subplot.clipIds.forTraces : null,
75+
gd
76+
);
7377
});
7478
};
7579

‎src/traces/contour/plot.js

Copy file name to clipboardExpand all lines: src/traces/contour/plot.js
+8-8Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ var costConstants = constants.LABELOPTIMIZER;
2929
exports.plot = function plot(gd, plotinfo, cdcontours, contourLayer) {
3030
var xa = plotinfo.xaxis;
3131
var ya = plotinfo.yaxis;
32-
var fullLayout = gd._fullLayout;
3332

3433
Lib.makeTraceGroups(contourLayer, cdcontours, 'contour').each(function(cd) {
3534
var plotGroup = d3.select(this);
@@ -78,7 +77,7 @@ exports.plot = function plot(gd, plotinfo, cdcontours, contourLayer) {
7877
makeBackground(plotGroup, perimeter, contours);
7978
makeFills(plotGroup, fillPathinfo, perimeter, contours);
8079
makeLinesAndLabels(plotGroup, pathinfo, gd, cd0, contours, perimeter);
81-
clipGaps(plotGroup, plotinfo, fullLayout._clips, cd0, perimeter);
80+
clipGaps(plotGroup, plotinfo, gd, cd0, perimeter);
8281
});
8382
};
8483

@@ -230,8 +229,7 @@ function makeLinesAndLabels(plotgroup, pathinfo, gd, cd0, contours, perimeter) {
230229
// In this case we'll remove the lines after making the labels.
231230
var linegroup = exports.createLines(lineContainer, showLines || showLabels, pathinfo);
232231

233-
var lineClip = exports.createLineClip(lineContainer, clipLinesForLabels,
234-
gd._fullLayout._clips, cd0.trace.uid);
232+
var lineClip = exports.createLineClip(lineContainer, clipLinesForLabels, gd, cd0.trace.uid);
235233

236234
var labelGroup = plotgroup.selectAll('g.contourlabels')
237235
.data(showLabels ? [0] : []);
@@ -373,7 +371,8 @@ exports.createLines = function(lineContainer, makeLines, pathinfo) {
373371
return linegroup;
374372
};
375373

376-
exports.createLineClip = function(lineContainer, clipLinesForLabels, clips, uid) {
374+
exports.createLineClip = function(lineContainer, clipLinesForLabels, gd, uid) {
375+
var clips = gd._fullLayout._clips;
377376
var clipId = clipLinesForLabels ? ('clipline' + uid) : null;
378377

379378
var lineClip = clips.selectAll('#' + clipId)
@@ -384,7 +383,7 @@ exports.createLineClip = function(lineContainer, clipLinesForLabels, clips, uid)
384383
.classed('contourlineclip', true)
385384
.attr('id', clipId);
386385

387-
Drawing.setClipUrl(lineContainer, clipId);
386+
Drawing.setClipUrl(lineContainer, clipId, gd);
388387

389388
return lineClip;
390389
};
@@ -615,7 +614,8 @@ exports.drawLabels = function(labelGroup, labelData, gd, lineClip, labelClipPath
615614
}
616615
};
617616

618-
function clipGaps(plotGroup, plotinfo, clips, cd0, perimeter) {
617+
function clipGaps(plotGroup, plotinfo, gd, cd0, perimeter) {
618+
var clips = gd._fullLayout._clips;
619619
var clipId = 'clip' + cd0.trace.uid;
620620

621621
var clipPath = clips.selectAll('#' + clipId)
@@ -654,7 +654,7 @@ function clipGaps(plotGroup, plotinfo, clips, cd0, perimeter) {
654654
}
655655
else clipId = null;
656656

657-
plotGroup.call(Drawing.setClipUrl, clipId);
657+
Drawing.setClipUrl(plotGroup, clipId, gd);
658658
}
659659

660660
function makeClipMask(cd0) {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.