Skip to content

Commit 7729133

Browse files
committed
Deactivate clip path temporarily while dragging shapes [2038]
- Hint: only deactivate for auto-ranged axes. - Reason: to allow for more accuracy when dragging shapes outside of the plot's bounds.
1 parent 1b9bb8a commit 7729133

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

src/components/shapes/draw.js

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,20 +108,24 @@ function drawOne(gd, index) {
108108
.call(Color.fill, options.fillcolor)
109109
.call(Drawing.dashLine, options.line.dash, options.line.width);
110110

111-
// note that for layer="below" the clipAxes can be different from the
112-
// subplot we're drawing this in. This could cause problems if the shape
113-
// spans two subplots. See https://github.com/plotly/plotly.js/issues/1452
114-
var clipAxes = (options.xref + options.yref).replace(/paper/g, '');
115-
116-
path.call(Drawing.setClipUrl, clipAxes ?
117-
('clip' + gd._fullLayout._uid + clipAxes) :
118-
null
119-
);
111+
setClipPath(path, gd, options);
120112

121113
if(gd._context.edits.shapePosition) setupDragElement(gd, path, options, index, shapeLayer);
122114
}
123115
}
124116

117+
function setClipPath(shapePath, gd, shapeOptions) {
118+
// note that for layer="below" the clipAxes can be different from the
119+
// subplot we're drawing this in. This could cause problems if the shape
120+
// spans two subplots. See https://github.com/plotly/plotly.js/issues/1452
121+
var clipAxes = (shapeOptions.xref + shapeOptions.yref).replace(/paper/g, '');
122+
123+
shapePath.call(Drawing.setClipUrl, clipAxes ?
124+
('clip' + gd._fullLayout._uid + clipAxes) :
125+
null
126+
);
127+
}
128+
125129
function setupDragElement(gd, shapePath, shapeOptions, index, shapeLayer) {
126130
var MINWIDTH = 10,
127131
MINHEIGHT = 10;
@@ -291,11 +295,15 @@ function setupDragElement(gd, shapePath, shapeOptions, index, shapeLayer) {
291295

292296
// setup dragMode and the corresponding handler
293297
updateDragMode(evt);
298+
deactivateClipPathTemporarily(shapePath, shapeOptions, gd);
294299
dragOptions.moveFn = (dragMode === 'move') ? moveShape : resizeShape;
295300
}
296301

297302
function endDrag() {
298303
setCursor(shapePath);
304+
305+
// Don't rely on clipPath being activated during re-layout
306+
setClipPath(shapePath, gd, shapeOptions);
299307
Registry.call('relayout', gd, update);
300308
}
301309

@@ -404,6 +412,22 @@ function setupDragElement(gd, shapePath, shapeOptions, index, shapeLayer) {
404412

405413
shapePath.attr('d', getPathString(gd, shapeOptions));
406414
}
415+
416+
function deactivateClipPathTemporarily(shapePath, shapeOptions, gd) {
417+
var xref = shapeOptions.xref,
418+
yref = shapeOptions.yref,
419+
xa = Axes.getFromId(gd, xref),
420+
ya = Axes.getFromId(gd, yref);
421+
422+
var clipAxes = '';
423+
if(xref !== 'paper' && !xa.autorange) clipAxes += xref;
424+
if(yref !== 'paper' && !ya.autorange) clipAxes += yref;
425+
426+
shapePath.call(Drawing.setClipUrl, clipAxes ?
427+
'clip' + gd._fullLayout._uid + clipAxes :
428+
null
429+
);
430+
}
407431
}
408432

409433
function getPathString(gd, options) {

0 commit comments

Comments
 (0)