Skip to content

Commit 20db59a

Browse files
authored
Merge pull request #2860 from plotly/per-trace-ax-extremes-maintenance
Recycled commits from abandoned fast trace toggle PRs
2 parents 1cdc36b + 89aebd1 commit 20db59a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1103
-781
lines changed

src/components/annotations/calc_autorange.js

+46-55
Original file line numberDiff line numberDiff line change
@@ -34,63 +34,54 @@ function annAutorange(gd) {
3434
Lib.filterVisible(fullLayout.annotations).forEach(function(ann) {
3535
var xa = Axes.getFromId(gd, ann.xref);
3636
var ya = Axes.getFromId(gd, ann.yref);
37-
var headSize = 3 * ann.arrowsize * ann.arrowwidth || 0;
38-
var startHeadSize = 3 * ann.startarrowsize * ann.arrowwidth || 0;
3937

40-
var headPlus, headMinus, startHeadPlus, startHeadMinus;
41-
42-
if(xa) {
43-
headPlus = headSize + ann.xshift;
44-
headMinus = headSize - ann.xshift;
45-
startHeadPlus = startHeadSize + ann.xshift;
46-
startHeadMinus = startHeadSize - ann.xshift;
38+
ann._extremes = {};
39+
if(xa) calcAxisExpansion(ann, xa);
40+
if(ya) calcAxisExpansion(ann, ya);
41+
});
42+
}
4743

48-
if(ann.axref === ann.xref) {
49-
// expand for the arrowhead (padded by arrowhead)
50-
Axes.expand(xa, [xa.r2c(ann.x)], {
51-
ppadplus: headPlus,
52-
ppadminus: headMinus
53-
});
54-
// again for the textbox (padded by textbox)
55-
Axes.expand(xa, [xa.r2c(ann.ax)], {
56-
ppadplus: Math.max(ann._xpadplus, startHeadPlus),
57-
ppadminus: Math.max(ann._xpadminus, startHeadMinus)
58-
});
59-
}
60-
else {
61-
startHeadPlus = ann.ax ? startHeadPlus + ann.ax : startHeadPlus;
62-
startHeadMinus = ann.ax ? startHeadMinus - ann.ax : startHeadMinus;
63-
Axes.expand(xa, [xa.r2c(ann.x)], {
64-
ppadplus: Math.max(ann._xpadplus, headPlus, startHeadPlus),
65-
ppadminus: Math.max(ann._xpadminus, headMinus, startHeadMinus)
66-
});
67-
}
68-
}
44+
function calcAxisExpansion(ann, ax) {
45+
var axId = ax._id;
46+
var letter = axId.charAt(0);
47+
var pos = ann[letter];
48+
var apos = ann['a' + letter];
49+
var ref = ann[letter + 'ref'];
50+
var aref = ann['a' + letter + 'ref'];
51+
var padplus = ann['_' + letter + 'padplus'];
52+
var padminus = ann['_' + letter + 'padminus'];
53+
var shift = {x: 1, y: -1}[letter] * ann[letter + 'shift'];
54+
var headSize = 3 * ann.arrowsize * ann.arrowwidth || 0;
55+
var headPlus = headSize + shift;
56+
var headMinus = headSize - shift;
57+
var startHeadSize = 3 * ann.startarrowsize * ann.arrowwidth || 0;
58+
var startHeadPlus = startHeadSize + shift;
59+
var startHeadMinus = startHeadSize - shift;
60+
var extremes;
6961

70-
if(ya) {
71-
headPlus = headSize - ann.yshift;
72-
headMinus = headSize + ann.yshift;
73-
startHeadPlus = startHeadSize - ann.yshift;
74-
startHeadMinus = startHeadSize + ann.yshift;
62+
if(aref === ref) {
63+
// expand for the arrowhead (padded by arrowhead)
64+
var extremeArrowHead = Axes.findExtremes(ax, [ax.r2c(pos)], {
65+
ppadplus: headPlus,
66+
ppadminus: headMinus
67+
});
68+
// again for the textbox (padded by textbox)
69+
var extremeText = Axes.findExtremes(ax, [ax.r2c(apos)], {
70+
ppadplus: Math.max(padplus, startHeadPlus),
71+
ppadminus: Math.max(padminus, startHeadMinus)
72+
});
73+
extremes = {
74+
min: [extremeArrowHead.min[0], extremeText.min[0]],
75+
max: [extremeArrowHead.max[0], extremeText.max[0]]
76+
};
77+
} else {
78+
startHeadPlus = apos ? startHeadPlus + apos : startHeadPlus;
79+
startHeadMinus = apos ? startHeadMinus - apos : startHeadMinus;
80+
extremes = Axes.findExtremes(ax, [ax.r2c(pos)], {
81+
ppadplus: Math.max(padplus, headPlus, startHeadPlus),
82+
ppadminus: Math.max(padminus, headMinus, startHeadMinus)
83+
});
84+
}
7585

76-
if(ann.ayref === ann.yref) {
77-
Axes.expand(ya, [ya.r2c(ann.y)], {
78-
ppadplus: headPlus,
79-
ppadminus: headMinus
80-
});
81-
Axes.expand(ya, [ya.r2c(ann.ay)], {
82-
ppadplus: Math.max(ann._ypadplus, startHeadPlus),
83-
ppadminus: Math.max(ann._ypadminus, startHeadMinus)
84-
});
85-
}
86-
else {
87-
startHeadPlus = ann.ay ? startHeadPlus + ann.ay : startHeadPlus;
88-
startHeadMinus = ann.ay ? startHeadMinus - ann.ay : startHeadMinus;
89-
Axes.expand(ya, [ya.r2c(ann.y)], {
90-
ppadplus: Math.max(ann._ypadplus, headPlus, startHeadPlus),
91-
ppadminus: Math.max(ann._ypadminus, headMinus, startHeadMinus)
92-
});
93-
}
94-
}
95-
});
86+
ann._extremes[axId] = extremes;
9687
}

src/components/annotations/defaults.js

+5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ function handleAnnotationDefaults(annIn, annOut, fullLayout) {
4848
// xref, yref
4949
var axRef = Axes.coerceRef(annIn, annOut, gdMock, axLetter, '', 'paper');
5050

51+
if(axRef !== 'paper') {
52+
var ax = Axes.getFromId(gdMock, axRef);
53+
ax._annIndices.push(annOut._index);
54+
}
55+
5156
// x, y
5257
Axes.coercePosition(annOut, gdMock, coerce, axRef, axLetter, 0.5);
5358

src/components/errorbars/calc.js

+13-11
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,15 @@ module.exports = function calc(gd) {
2121
var calcdata = gd.calcdata;
2222

2323
for(var i = 0; i < calcdata.length; i++) {
24-
var calcTrace = calcdata[i],
25-
trace = calcTrace[0].trace;
26-
27-
if(!Registry.traceIs(trace, 'errorBarsOK')) continue;
28-
29-
var xa = Axes.getFromId(gd, trace.xaxis),
30-
ya = Axes.getFromId(gd, trace.yaxis);
31-
32-
calcOneAxis(calcTrace, trace, xa, 'x');
33-
calcOneAxis(calcTrace, trace, ya, 'y');
24+
var calcTrace = calcdata[i];
25+
var trace = calcTrace[0].trace;
26+
27+
if(trace.visible === true && Registry.traceIs(trace, 'errorBarsOK')) {
28+
var xa = Axes.getFromId(gd, trace.xaxis);
29+
var ya = Axes.getFromId(gd, trace.yaxis);
30+
calcOneAxis(calcTrace, trace, xa, 'x');
31+
calcOneAxis(calcTrace, trace, ya, 'y');
32+
}
3433
}
3534
};
3635

@@ -57,5 +56,8 @@ function calcOneAxis(calcTrace, trace, axis, coord) {
5756
}
5857
}
5958

60-
Axes.expand(axis, vals, {padded: true});
59+
var extremes = Axes.findExtremes(axis, vals, {padded: true});
60+
var axId = axis._id;
61+
trace._extremes[axId].min = trace._extremes[axId].min.concat(extremes.min);
62+
trace._extremes[axId].max = trace._extremes[axId].max.concat(extremes.max);
6163
}

src/components/rangeslider/calc_autorange.js

+4-7
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,12 @@ module.exports = function calcAutorange(gd) {
2121
// this step in subsequent draw calls.
2222

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

27-
// Don't try calling getAutoRange if _min and _max are filled in.
28-
// This happens on updates where the calc step is skipped.
29-
30-
if(opts && opts.visible && opts.autorange && ax._min.length && ax._max.length) {
27+
if(opts && opts.visible && opts.autorange) {
3128
opts._input.autorange = true;
32-
opts._input.range = opts.range = getAutoRange(ax);
29+
opts._input.range = opts.range = getAutoRange(gd, ax);
3330
}
3431
}
3532
};

src/components/shapes/calc_autorange.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ module.exports = function calcAutorange(gd) {
2424

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

2829
var ax, bounds;
2930

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

3536
bounds = shapeBounds(ax, vx0, vx1, shape.path, constants.paramIsX);
36-
37-
if(bounds) Axes.expand(ax, bounds, calcXPaddingOptions(shape));
37+
if(bounds) {
38+
shape._extremes[ax._id] = Axes.findExtremes(ax, bounds, calcXPaddingOptions(shape));
39+
}
3840
}
3941

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

4547
bounds = shapeBounds(ax, vy0, vy1, shape.path, constants.paramIsY);
46-
if(bounds) Axes.expand(ax, bounds, calcYPaddingOptions(shape));
48+
if(bounds) {
49+
shape._extremes[ax._id] = Axes.findExtremes(ax, bounds, calcYPaddingOptions(shape));
50+
}
4751
}
4852
}
4953
};

src/components/shapes/defaults.js

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ function handleShapeDefaults(shapeIn, shapeOut, fullLayout) {
6161

6262
if(axRef !== 'paper') {
6363
ax = Axes.getFromId(gdMock, axRef);
64+
ax._shapeIndices.push(shapeOut._index);
6465
r2pos = helpers.rangeToShapePosition(ax);
6566
pos2r = helpers.shapePositionToRange(ax);
6667
}

src/lib/index.js

+15
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,21 @@ lib.isIndex = function(v, len) {
150150
lib.noop = require('./noop');
151151
lib.identity = require('./identity');
152152

153+
/**
154+
* create an array of length 'cnt' filled with 'v' at all indices
155+
*
156+
* @param {any} v
157+
* @param {number} cnt
158+
* @return {array}
159+
*/
160+
lib.repeat = function(v, cnt) {
161+
var out = new Array(cnt);
162+
for(var i = 0; i < cnt; i++) {
163+
out[i] = v;
164+
}
165+
return out;
166+
};
167+
153168
/**
154169
* swap x and y of the same attribute in container cont
155170
* specify attr with a ? in place of x/y

src/plot_api/subroutines.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ exports.doAutoRangeAndConstraints = function(gd) {
576576
for(var i = 0; i < axList.length; i++) {
577577
var ax = axList[i];
578578
cleanAxisConstraints(gd, ax);
579-
doAutoRange(ax);
579+
doAutoRange(gd, ax);
580580
}
581581

582582
enforceAxisConstraints(gd);

0 commit comments

Comments
 (0)