Skip to content

Commit 7aa7243

Browse files
committed
Dragbox compares axes by value instead of reference
1 parent f390168 commit 7aa7243

File tree

4 files changed

+84
-18
lines changed

4 files changed

+84
-18
lines changed

src/plot_api/plot_api.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2601,6 +2601,15 @@ Plotly.transition = function(gd, data, layout, traceIndices, transitionConfig) {
26012601
doCalcdata(gd);
26022602

26032603
ErrorBars.calc(gd);
2604+
2605+
// While transitions are occuring, occurring, we get a double-transform
2606+
// issue if we transform the drawn layer *and* use the new axis range to
2607+
// draw the data. This causes setConvert to use the pre-interaction values
2608+
// of the axis range:
2609+
var axList = Plotly.Axes.list(gd);
2610+
for(i = 0; i < axList.length; i++) {
2611+
axList[i].setScale(true);
2612+
}
26042613
}
26052614

26062615
var restyleList = [];
@@ -2660,7 +2669,7 @@ Plotly.transition = function(gd, data, layout, traceIndices, transitionConfig) {
26602669
var contFull = gd._fullData[traceIdx];
26612670
var module = contFull._module;
26622671

2663-
if (!module) continue;
2672+
if(!module) continue;
26642673

26652674
if(!module.animatable) {
26662675
var thisUpdate = {};

src/plots/cartesian/dragbox.js

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,28 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
158158
zb,
159159
corners;
160160

161+
function recomputeAxisLists() {
162+
xa = [plotinfo.x()];
163+
ya = [plotinfo.y()];
164+
pw = xa[0]._length;
165+
ph = ya[0]._length;
166+
167+
for(var i = 1; i < subplots.length; i++) {
168+
var subplotXa = subplots[i].x(),
169+
subplotYa = subplots[i].y();
170+
if(xa.indexOf(subplotXa) === -1) xa.push(subplotXa);
171+
if(ya.indexOf(subplotYa) === -1) ya.push(subplotYa);
172+
}
173+
allaxes = xa.concat(ya);
174+
xActive = isDirectionActive(xa, ew);
175+
yActive = isDirectionActive(ya, ns);
176+
cursor = getDragCursor(yActive + xActive, fullLayout.dragmode);
177+
xs = plotinfo.x()._offset;
178+
ys = plotinfo.y()._offset;
179+
dragOptions.xa = xa;
180+
dragOptions.ya = ya;
181+
}
182+
161183
function zoomPrep(e, startX, startY) {
162184
var dragBBox = dragger.getBoundingClientRect();
163185
x0 = startX - dragBBox.left;
@@ -358,6 +380,7 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
358380
fullLayout._plots[plotinfo.mainplot] : plotinfo;
359381

360382
function zoomWheel(e) {
383+
recomputeAxisLists();
361384
// deactivate mousewheel scrolling on embedded graphs
362385
// devs can override this with layout._enablescrollzoom,
363386
// but _ ensures this setting won't leave their page
@@ -433,6 +456,8 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
433456

434457
// plotDrag: move the plot in response to a drag
435458
function plotDrag(dx, dy) {
459+
recomputeAxisLists();
460+
436461
function dragAxList(axList, pix) {
437462
for(var i = 0; i < axList.length; i++) {
438463
var axi = axList[i];
@@ -606,6 +631,7 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
606631
// affected by this drag, and update them. look for all plots
607632
// sharing an affected axis (including the one being dragged)
608633
function updateSubplots(viewBox) {
634+
var j;
609635
var plotinfos = fullLayout._plots,
610636
subplots = Object.keys(plotinfos);
611637

@@ -614,8 +640,30 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
614640
var subplot = plotinfos[subplots[i]],
615641
xa2 = subplot.x(),
616642
ya2 = subplot.y(),
617-
editX = ew && xa.indexOf(xa2) !== -1 && !xa2.fixedrange,
618-
editY = ns && ya.indexOf(ya2) !== -1 && !ya2.fixedrange;
643+
editX = ew && !xa2.fixedrange,
644+
editY = ns && !ya2.fixedrange;
645+
646+
if(editX) {
647+
var isInX = false;
648+
for(j = 0; j < xa.length; j++) {
649+
if(xa[j]._id === xa2._id) {
650+
isInX = true;
651+
break;
652+
}
653+
}
654+
editX = editX && isInX;
655+
}
656+
657+
if(editY) {
658+
var isInY = false;
659+
for(j = 0; j < ya.length; j++) {
660+
if(ya[j]._id === ya2._id) {
661+
isInY = true;
662+
break;
663+
}
664+
}
665+
editY = editY && isInY;
666+
}
619667

620668
var xScaleFactor = editX ? xa2._length / viewBox[2] : 1,
621669
yScaleFactor = editY ? ya2._length / viewBox[3] : 1;

src/plots/cartesian/set_convert.js

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ module.exports = function setConvert(ax) {
6464
ax.p2d = function(v) { return ax.l2d(ax.p2l(v)); };
6565

6666
// set scaling to pixels
67-
ax.setScale = function() {
67+
ax.setScale = function(usePrivateRange) {
6868
var gs = ax._gd._fullLayout._size,
6969
i;
7070

@@ -78,38 +78,44 @@ module.exports = function setConvert(ax) {
7878
ax.domain = ax2.domain;
7979
}
8080

81+
// While transitions are occuring, occurring, we get a double-transform
82+
// issue if we transform the drawn layer *and* use the new axis range to
83+
// draw the data. This allows us to construct setConvert using the pre-
84+
// interaction values of the range:
85+
var range = (usePrivateRange && ax._r) ? ax._r : ax.range;
86+
8187
// make sure we have a range (linearized data values)
8288
// and that it stays away from the limits of javascript numbers
83-
if(!ax.range || ax.range.length !== 2 || ax.range[0] === ax.range[1]) {
84-
ax.range = [-1, 1];
89+
if(!range || range.length !== 2 || range[0] === range[1]) {
90+
range = [-1, 1];
8591
}
8692
for(i = 0; i < 2; i++) {
87-
if(!isNumeric(ax.range[i])) {
88-
ax.range[i] = isNumeric(ax.range[1 - i]) ?
89-
(ax.range[1 - i] * (i ? 10 : 0.1)) :
93+
if(!isNumeric(range[i])) {
94+
range[i] = isNumeric(range[1 - i]) ?
95+
(range[1 - i] * (i ? 10 : 0.1)) :
9096
(i ? 1 : -1);
9197
}
9298

93-
if(ax.range[i] < -(Number.MAX_VALUE / 2)) {
94-
ax.range[i] = -(Number.MAX_VALUE / 2);
99+
if(range[i] < -(Number.MAX_VALUE / 2)) {
100+
range[i] = -(Number.MAX_VALUE / 2);
95101
}
96-
else if(ax.range[i] > Number.MAX_VALUE / 2) {
97-
ax.range[i] = Number.MAX_VALUE / 2;
102+
else if(range[i] > Number.MAX_VALUE / 2) {
103+
range[i] = Number.MAX_VALUE / 2;
98104
}
99105

100106
}
101107

102108
if(ax._id.charAt(0) === 'y') {
103109
ax._offset = gs.t + (1 - ax.domain[1]) * gs.h;
104110
ax._length = gs.h * (ax.domain[1] - ax.domain[0]);
105-
ax._m = ax._length / (ax.range[0] - ax.range[1]);
106-
ax._b = -ax._m * ax.range[1];
111+
ax._m = ax._length / (range[0] - range[1]);
112+
ax._b = -ax._m * range[1];
107113
}
108114
else {
109115
ax._offset = gs.l + ax.domain[0] * gs.w;
110116
ax._length = gs.w * (ax.domain[1] - ax.domain[0]);
111-
ax._m = ax._length / (ax.range[1] - ax.range[0]);
112-
ax._b = -ax._m * ax.range[0];
117+
ax._m = ax._length / (range[1] - range[0]);
118+
ax._b = -ax._m * range[0];
113119
}
114120

115121
if(!isFinite(ax._m) || !isFinite(ax._b)) {

test/jasmine/karma.conf.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ func.defaultConfig = {
4848
// N.B. this field is filled below
4949
files: [],
5050

51-
exclude: [],
51+
exclude: [
52+
'tests/gl_plot_interact_test.js',
53+
'tests/mapbox_test.js',
54+
],
5255

5356
// preprocess matching files before serving them to the browser
5457
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor

0 commit comments

Comments
 (0)