Skip to content

Commit 7bf81a0

Browse files
committed
Dragbox compares axes by value instead of reference
1 parent 68df357 commit 7bf81a0

File tree

4 files changed

+83
-17
lines changed

4 files changed

+83
-17
lines changed

src/plot_api/plot_api.js

+9
Original file line numberDiff line numberDiff line change
@@ -2593,6 +2593,15 @@ Plotly.transition = function(gd, data, layout, traceIndices, transitionConfig) {
25932593
doCalcdata(gd);
25942594

25952595
ErrorBars.calc(gd);
2596+
2597+
// While transitions are occuring, occurring, we get a double-transform
2598+
// issue if we transform the drawn layer *and* use the new axis range to
2599+
// draw the data. This causes setConvert to use the pre-interaction values
2600+
// of the axis range:
2601+
var axList = Plotly.Axes.list(gd);
2602+
for(i = 0; i < axList.length; i++) {
2603+
axList[i].setScale(true);
2604+
}
25962605
}
25972606

25982607
var restyleList = [];

src/plots/cartesian/dragbox.js

+50-2
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,28 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
102102
axRange[1] = Number(axRange[1]);
103103
}
104104

105+
function recomputeAxisLists () {
106+
xa = [plotinfo.x()];
107+
ya = [plotinfo.y()];
108+
pw = xa[0]._length;
109+
ph = ya[0]._length;
110+
111+
for(var i = 1; i < subplots.length; i++) {
112+
var subplotXa = subplots[i].x(),
113+
subplotYa = subplots[i].y();
114+
if(xa.indexOf(subplotXa) === -1) xa.push(subplotXa);
115+
if(ya.indexOf(subplotYa) === -1) ya.push(subplotYa);
116+
}
117+
allaxes = xa.concat(ya);
118+
xActive = isDirectionActive(xa, ew);
119+
yActive = isDirectionActive(ya, ns);
120+
cursor = getDragCursor(yActive + xActive, fullLayout.dragmode);
121+
xs = plotinfo.x()._offset;
122+
ys = plotinfo.y()._offset;
123+
dragOptions.xa = xa;
124+
dragOptions.ya = ya;
125+
}
126+
105127
var dragOptions = {
106128
element: dragger,
107129
gd: gd,
@@ -357,6 +379,7 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
357379
fullLayout._plots[plotinfo.mainplot] : plotinfo;
358380

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

433456
// plotDrag: move the plot in response to a drag
434457
function plotDrag(dx, dy) {
458+
recomputeAxisLists();
459+
435460
function dragAxList(axList, pix) {
436461
for(var i = 0; i < axList.length; i++) {
437462
var axi = axList[i];
@@ -602,6 +627,7 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
602627
// affected by this drag, and update them. look for all plots
603628
// sharing an affected axis (including the one being dragged)
604629
function updateSubplots(viewBox) {
630+
var j;
605631
var plotinfos = fullLayout._plots,
606632
subplots = Object.keys(plotinfos);
607633

@@ -610,8 +636,30 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
610636
var subplot = plotinfos[subplots[i]],
611637
xa2 = subplot.x(),
612638
ya2 = subplot.y(),
613-
editX = ew && xa.indexOf(xa2) !== -1 && !xa2.fixedrange,
614-
editY = ns && ya.indexOf(ya2) !== -1 && !ya2.fixedrange;
639+
editX = ew && !xa2.fixedrange,
640+
editY = ns && !ya2.fixedrange;
641+
642+
if (editX) {
643+
var isInX = false;
644+
for (j = 0; j < xa.length; j++) {
645+
if (xa[j]._id === xa2._id) {
646+
isInX = true;
647+
break;
648+
}
649+
}
650+
editX = editX && isInX;
651+
}
652+
653+
if (editY) {
654+
var isInY = false;
655+
for (j = 0; j < ya.length; j++) {
656+
if (ya[j]._id === ya2._id) {
657+
isInY = true;
658+
break;
659+
}
660+
}
661+
editY = editY && isInY;
662+
}
615663

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

src/plots/cartesian/set_convert.js

+20-14
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

+4-1
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)