Skip to content

Commit

Permalink
Merge pull request #2865 from plotly/faster-axis-autorange
Browse files Browse the repository at this point in the history
Merging #2860 to master
  • Loading branch information
etpinard authored Aug 2, 2018
2 parents 6f94816 + 20db59a commit 6a6d1dc
Show file tree
Hide file tree
Showing 53 changed files with 1,103 additions and 781 deletions.
101 changes: 46 additions & 55 deletions src/components/annotations/calc_autorange.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,63 +34,54 @@ function annAutorange(gd) {
Lib.filterVisible(fullLayout.annotations).forEach(function(ann) {
var xa = Axes.getFromId(gd, ann.xref);
var ya = Axes.getFromId(gd, ann.yref);
var headSize = 3 * ann.arrowsize * ann.arrowwidth || 0;
var startHeadSize = 3 * ann.startarrowsize * ann.arrowwidth || 0;

var headPlus, headMinus, startHeadPlus, startHeadMinus;

if(xa) {
headPlus = headSize + ann.xshift;
headMinus = headSize - ann.xshift;
startHeadPlus = startHeadSize + ann.xshift;
startHeadMinus = startHeadSize - ann.xshift;
ann._extremes = {};
if(xa) calcAxisExpansion(ann, xa);
if(ya) calcAxisExpansion(ann, ya);
});
}

if(ann.axref === ann.xref) {
// expand for the arrowhead (padded by arrowhead)
Axes.expand(xa, [xa.r2c(ann.x)], {
ppadplus: headPlus,
ppadminus: headMinus
});
// again for the textbox (padded by textbox)
Axes.expand(xa, [xa.r2c(ann.ax)], {
ppadplus: Math.max(ann._xpadplus, startHeadPlus),
ppadminus: Math.max(ann._xpadminus, startHeadMinus)
});
}
else {
startHeadPlus = ann.ax ? startHeadPlus + ann.ax : startHeadPlus;
startHeadMinus = ann.ax ? startHeadMinus - ann.ax : startHeadMinus;
Axes.expand(xa, [xa.r2c(ann.x)], {
ppadplus: Math.max(ann._xpadplus, headPlus, startHeadPlus),
ppadminus: Math.max(ann._xpadminus, headMinus, startHeadMinus)
});
}
}
function calcAxisExpansion(ann, ax) {
var axId = ax._id;
var letter = axId.charAt(0);
var pos = ann[letter];
var apos = ann['a' + letter];
var ref = ann[letter + 'ref'];
var aref = ann['a' + letter + 'ref'];
var padplus = ann['_' + letter + 'padplus'];
var padminus = ann['_' + letter + 'padminus'];
var shift = {x: 1, y: -1}[letter] * ann[letter + 'shift'];
var headSize = 3 * ann.arrowsize * ann.arrowwidth || 0;
var headPlus = headSize + shift;
var headMinus = headSize - shift;
var startHeadSize = 3 * ann.startarrowsize * ann.arrowwidth || 0;
var startHeadPlus = startHeadSize + shift;
var startHeadMinus = startHeadSize - shift;
var extremes;

if(ya) {
headPlus = headSize - ann.yshift;
headMinus = headSize + ann.yshift;
startHeadPlus = startHeadSize - ann.yshift;
startHeadMinus = startHeadSize + ann.yshift;
if(aref === ref) {
// expand for the arrowhead (padded by arrowhead)
var extremeArrowHead = Axes.findExtremes(ax, [ax.r2c(pos)], {
ppadplus: headPlus,
ppadminus: headMinus
});
// again for the textbox (padded by textbox)
var extremeText = Axes.findExtremes(ax, [ax.r2c(apos)], {
ppadplus: Math.max(padplus, startHeadPlus),
ppadminus: Math.max(padminus, startHeadMinus)
});
extremes = {
min: [extremeArrowHead.min[0], extremeText.min[0]],
max: [extremeArrowHead.max[0], extremeText.max[0]]
};
} else {
startHeadPlus = apos ? startHeadPlus + apos : startHeadPlus;
startHeadMinus = apos ? startHeadMinus - apos : startHeadMinus;
extremes = Axes.findExtremes(ax, [ax.r2c(pos)], {
ppadplus: Math.max(padplus, headPlus, startHeadPlus),
ppadminus: Math.max(padminus, headMinus, startHeadMinus)
});
}

if(ann.ayref === ann.yref) {
Axes.expand(ya, [ya.r2c(ann.y)], {
ppadplus: headPlus,
ppadminus: headMinus
});
Axes.expand(ya, [ya.r2c(ann.ay)], {
ppadplus: Math.max(ann._ypadplus, startHeadPlus),
ppadminus: Math.max(ann._ypadminus, startHeadMinus)
});
}
else {
startHeadPlus = ann.ay ? startHeadPlus + ann.ay : startHeadPlus;
startHeadMinus = ann.ay ? startHeadMinus - ann.ay : startHeadMinus;
Axes.expand(ya, [ya.r2c(ann.y)], {
ppadplus: Math.max(ann._ypadplus, headPlus, startHeadPlus),
ppadminus: Math.max(ann._ypadminus, headMinus, startHeadMinus)
});
}
}
});
ann._extremes[axId] = extremes;
}
5 changes: 5 additions & 0 deletions src/components/annotations/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ function handleAnnotationDefaults(annIn, annOut, fullLayout) {
// xref, yref
var axRef = Axes.coerceRef(annIn, annOut, gdMock, axLetter, '', 'paper');

if(axRef !== 'paper') {
var ax = Axes.getFromId(gdMock, axRef);
ax._annIndices.push(annOut._index);
}

// x, y
Axes.coercePosition(annOut, gdMock, coerce, axRef, axLetter, 0.5);

Expand Down
24 changes: 13 additions & 11 deletions src/components/errorbars/calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,15 @@ module.exports = function calc(gd) {
var calcdata = gd.calcdata;

for(var i = 0; i < calcdata.length; i++) {
var calcTrace = calcdata[i],
trace = calcTrace[0].trace;

if(!Registry.traceIs(trace, 'errorBarsOK')) continue;

var xa = Axes.getFromId(gd, trace.xaxis),
ya = Axes.getFromId(gd, trace.yaxis);

calcOneAxis(calcTrace, trace, xa, 'x');
calcOneAxis(calcTrace, trace, ya, 'y');
var calcTrace = calcdata[i];
var trace = calcTrace[0].trace;

if(trace.visible === true && Registry.traceIs(trace, 'errorBarsOK')) {
var xa = Axes.getFromId(gd, trace.xaxis);
var ya = Axes.getFromId(gd, trace.yaxis);
calcOneAxis(calcTrace, trace, xa, 'x');
calcOneAxis(calcTrace, trace, ya, 'y');
}
}
};

Expand All @@ -57,5 +56,8 @@ function calcOneAxis(calcTrace, trace, axis, coord) {
}
}

Axes.expand(axis, vals, {padded: true});
var extremes = Axes.findExtremes(axis, vals, {padded: true});
var axId = axis._id;
trace._extremes[axId].min = trace._extremes[axId].min.concat(extremes.min);
trace._extremes[axId].max = trace._extremes[axId].max.concat(extremes.max);
}
11 changes: 4 additions & 7 deletions src/components/rangeslider/calc_autorange.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,12 @@ module.exports = function calcAutorange(gd) {
// this step in subsequent draw calls.

for(var i = 0; i < axes.length; i++) {
var ax = axes[i],
opts = ax[constants.name];
var ax = axes[i];
var opts = ax[constants.name];

// Don't try calling getAutoRange if _min and _max are filled in.
// This happens on updates where the calc step is skipped.

if(opts && opts.visible && opts.autorange && ax._min.length && ax._max.length) {
if(opts && opts.visible && opts.autorange) {
opts._input.autorange = true;
opts._input.range = opts.range = getAutoRange(ax);
opts._input.range = opts.range = getAutoRange(gd, ax);
}
}
};
10 changes: 7 additions & 3 deletions src/components/shapes/calc_autorange.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ module.exports = function calcAutorange(gd) {

for(var i = 0; i < shapeList.length; i++) {
var shape = shapeList[i];
shape._extremes = {};

var ax, bounds;

Expand All @@ -33,8 +34,9 @@ module.exports = function calcAutorange(gd) {
ax = Axes.getFromId(gd, shape.xref);

bounds = shapeBounds(ax, vx0, vx1, shape.path, constants.paramIsX);

if(bounds) Axes.expand(ax, bounds, calcXPaddingOptions(shape));
if(bounds) {
shape._extremes[ax._id] = Axes.findExtremes(ax, bounds, calcXPaddingOptions(shape));
}
}

if(shape.yref !== 'paper') {
Expand All @@ -43,7 +45,9 @@ module.exports = function calcAutorange(gd) {
ax = Axes.getFromId(gd, shape.yref);

bounds = shapeBounds(ax, vy0, vy1, shape.path, constants.paramIsY);
if(bounds) Axes.expand(ax, bounds, calcYPaddingOptions(shape));
if(bounds) {
shape._extremes[ax._id] = Axes.findExtremes(ax, bounds, calcYPaddingOptions(shape));
}
}
}
};
Expand Down
1 change: 1 addition & 0 deletions src/components/shapes/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ function handleShapeDefaults(shapeIn, shapeOut, fullLayout) {

if(axRef !== 'paper') {
ax = Axes.getFromId(gdMock, axRef);
ax._shapeIndices.push(shapeOut._index);
r2pos = helpers.rangeToShapePosition(ax);
pos2r = helpers.shapePositionToRange(ax);
}
Expand Down
15 changes: 15 additions & 0 deletions src/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,21 @@ lib.isIndex = function(v, len) {
lib.noop = require('./noop');
lib.identity = require('./identity');

/**
* create an array of length 'cnt' filled with 'v' at all indices
*
* @param {any} v
* @param {number} cnt
* @return {array}
*/
lib.repeat = function(v, cnt) {
var out = new Array(cnt);
for(var i = 0; i < cnt; i++) {
out[i] = v;
}
return out;
};

/**
* swap x and y of the same attribute in container cont
* specify attr with a ? in place of x/y
Expand Down
2 changes: 1 addition & 1 deletion src/plot_api/subroutines.js
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ exports.doAutoRangeAndConstraints = function(gd) {
for(var i = 0; i < axList.length; i++) {
var ax = axList[i];
cleanAxisConstraints(gd, ax);
doAutoRange(ax);
doAutoRange(gd, ax);
}

enforceAxisConstraints(gd);
Expand Down
Loading

0 comments on commit 6a6d1dc

Please sign in to comment.