Skip to content

Commit

Permalink
Dragbox compares axes by value instead of reference
Browse files Browse the repository at this point in the history
  • Loading branch information
rreusser committed Aug 5, 2016
1 parent 68df357 commit 7bf81a0
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 17 deletions.
9 changes: 9 additions & 0 deletions src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -2593,6 +2593,15 @@ Plotly.transition = function(gd, data, layout, traceIndices, transitionConfig) {
doCalcdata(gd);

ErrorBars.calc(gd);

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

var restyleList = [];
Expand Down
52 changes: 50 additions & 2 deletions src/plots/cartesian/dragbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,28 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
axRange[1] = Number(axRange[1]);
}

function recomputeAxisLists () {
xa = [plotinfo.x()];
ya = [plotinfo.y()];
pw = xa[0]._length;
ph = ya[0]._length;

for(var i = 1; i < subplots.length; i++) {
var subplotXa = subplots[i].x(),
subplotYa = subplots[i].y();
if(xa.indexOf(subplotXa) === -1) xa.push(subplotXa);
if(ya.indexOf(subplotYa) === -1) ya.push(subplotYa);
}
allaxes = xa.concat(ya);
xActive = isDirectionActive(xa, ew);
yActive = isDirectionActive(ya, ns);
cursor = getDragCursor(yActive + xActive, fullLayout.dragmode);
xs = plotinfo.x()._offset;
ys = plotinfo.y()._offset;
dragOptions.xa = xa;
dragOptions.ya = ya;
}

var dragOptions = {
element: dragger,
gd: gd,
Expand Down Expand Up @@ -357,6 +379,7 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
fullLayout._plots[plotinfo.mainplot] : plotinfo;

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

// plotDrag: move the plot in response to a drag
function plotDrag(dx, dy) {
recomputeAxisLists();

function dragAxList(axList, pix) {
for(var i = 0; i < axList.length; i++) {
var axi = axList[i];
Expand Down Expand Up @@ -602,6 +627,7 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
// affected by this drag, and update them. look for all plots
// sharing an affected axis (including the one being dragged)
function updateSubplots(viewBox) {
var j;
var plotinfos = fullLayout._plots,
subplots = Object.keys(plotinfos);

Expand All @@ -610,8 +636,30 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
var subplot = plotinfos[subplots[i]],
xa2 = subplot.x(),
ya2 = subplot.y(),
editX = ew && xa.indexOf(xa2) !== -1 && !xa2.fixedrange,
editY = ns && ya.indexOf(ya2) !== -1 && !ya2.fixedrange;
editX = ew && !xa2.fixedrange,
editY = ns && !ya2.fixedrange;

if (editX) {
var isInX = false;
for (j = 0; j < xa.length; j++) {
if (xa[j]._id === xa2._id) {
isInX = true;
break;
}
}
editX = editX && isInX;
}

if (editY) {
var isInY = false;
for (j = 0; j < ya.length; j++) {
if (ya[j]._id === ya2._id) {
isInY = true;
break;
}
}
editY = editY && isInY;
}

var xScaleFactor = editX ? xa2._length / viewBox[2] : 1,
yScaleFactor = editY ? ya2._length / viewBox[3] : 1;
Expand Down
34 changes: 20 additions & 14 deletions src/plots/cartesian/set_convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ module.exports = function setConvert(ax) {
ax.p2d = function(v) { return ax.l2d(ax.p2l(v)); };

// set scaling to pixels
ax.setScale = function() {
ax.setScale = function(usePrivateRange) {
var gs = ax._gd._fullLayout._size,
i;

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

// While transitions are occuring, occurring, we get a double-transform
// issue if we transform the drawn layer *and* use the new axis range to
// draw the data. This allows us to construct setConvert using the pre-
// interaction values of the range:
var range = (usePrivateRange && ax._r) ? ax._r : ax.range;

// make sure we have a range (linearized data values)
// and that it stays away from the limits of javascript numbers
if(!ax.range || ax.range.length !== 2 || ax.range[0] === ax.range[1]) {
ax.range = [-1, 1];
if(!range || range.length !== 2 || range[0] === range[1]) {
range = [-1, 1];
}
for(i = 0; i < 2; i++) {
if(!isNumeric(ax.range[i])) {
ax.range[i] = isNumeric(ax.range[1 - i]) ?
(ax.range[1 - i] * (i ? 10 : 0.1)) :
if(!isNumeric(range[i])) {
range[i] = isNumeric(range[1 - i]) ?
(range[1 - i] * (i ? 10 : 0.1)) :
(i ? 1 : -1);
}

if(ax.range[i] < -(Number.MAX_VALUE / 2)) {
ax.range[i] = -(Number.MAX_VALUE / 2);
if(range[i] < -(Number.MAX_VALUE / 2)) {
range[i] = -(Number.MAX_VALUE / 2);
}
else if(ax.range[i] > Number.MAX_VALUE / 2) {
ax.range[i] = Number.MAX_VALUE / 2;
else if(range[i] > Number.MAX_VALUE / 2) {
range[i] = Number.MAX_VALUE / 2;
}

}

if(ax._id.charAt(0) === 'y') {
ax._offset = gs.t + (1 - ax.domain[1]) * gs.h;
ax._length = gs.h * (ax.domain[1] - ax.domain[0]);
ax._m = ax._length / (ax.range[0] - ax.range[1]);
ax._b = -ax._m * ax.range[1];
ax._m = ax._length / (range[0] - range[1]);
ax._b = -ax._m * range[1];
}
else {
ax._offset = gs.l + ax.domain[0] * gs.w;
ax._length = gs.w * (ax.domain[1] - ax.domain[0]);
ax._m = ax._length / (ax.range[1] - ax.range[0]);
ax._b = -ax._m * ax.range[0];
ax._m = ax._length / (range[1] - range[0]);
ax._b = -ax._m * range[0];
}

if(!isFinite(ax._m) || !isFinite(ax._b)) {
Expand Down
5 changes: 4 additions & 1 deletion test/jasmine/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ func.defaultConfig = {
// N.B. this field is filled below
files: [],

exclude: [],
exclude: [
'tests/gl_plot_interact_test.js',
'tests/mapbox_test.js',
],

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

0 comments on commit 7bf81a0

Please sign in to comment.