forked from plotly/plotly.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalc_autorange.js
126 lines (101 loc) · 3.89 KB
/
calc_autorange.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
'use strict';
var Lib = require('../../lib');
var Axes = require('../../plots/cartesian/axes');
var constants = require('./constants');
var helpers = require('./helpers');
module.exports = function calcAutorange(gd) {
var fullLayout = gd._fullLayout;
var shapeList = Lib.filterVisible(fullLayout.shapes);
if(!shapeList.length || !gd._fullData.length) return;
for(var i = 0; i < shapeList.length; i++) {
var shape = shapeList[i];
shape._extremes = {};
var ax; var bounds;
var xRefType = Axes.getRefType(shape.xref);
var yRefType = Axes.getRefType(shape.yref);
// paper and axis domain referenced shapes don't affect autorange
if(shape.xref !== 'paper' && xRefType !== 'domain') {
ax = Axes.getFromId(gd, shape.xref);
bounds = shapeBounds(ax, shape, constants.paramIsX);
if(bounds) {
shape._extremes[ax._id] = Axes.findExtremes(ax, bounds, calcXPaddingOptions(shape));
}
}
if(shape.yref !== 'paper' && yRefType !== 'domain') {
ax = Axes.getFromId(gd, shape.yref);
bounds = shapeBounds(ax, shape, constants.paramIsY);
if(bounds) {
shape._extremes[ax._id] = Axes.findExtremes(ax, bounds, calcYPaddingOptions(shape));
}
}
}
};
function calcXPaddingOptions(shape) {
return calcPaddingOptions(shape.line.width, shape.xsizemode, shape.x0, shape.x1, shape.path, false);
}
function calcYPaddingOptions(shape) {
return calcPaddingOptions(shape.line.width, shape.ysizemode, shape.y0, shape.y1, shape.path, true);
}
function calcPaddingOptions(lineWidth, sizeMode, v0, v1, path, isYAxis) {
var ppad = lineWidth / 2;
var axisDirectionReverted = isYAxis;
if(sizeMode === 'pixel') {
var coords = path ?
helpers.extractPathCoords(path, isYAxis ? constants.paramIsY : constants.paramIsX) :
[v0, v1];
var maxValue = Lib.aggNums(Math.max, null, coords);
var minValue = Lib.aggNums(Math.min, null, coords);
var beforePad = minValue < 0 ? Math.abs(minValue) + ppad : ppad;
var afterPad = maxValue > 0 ? maxValue + ppad : ppad;
return {
ppad: ppad,
ppadplus: axisDirectionReverted ? beforePad : afterPad,
ppadminus: axisDirectionReverted ? afterPad : beforePad
};
} else {
return {ppad: ppad};
}
}
function shapeBounds(ax, shape, paramsToUse) {
var dim = ax._id.charAt(0) === 'x' ? 'x' : 'y';
var isCategory = ax.type === 'category' || ax.type === 'multicategory';
var v0;
var v1;
var shiftStart = 0;
var shiftEnd = 0;
var convertVal = isCategory ? ax.r2c : ax.d2c;
var isSizeModeScale = shape[dim + 'sizemode'] === 'scaled';
if(isSizeModeScale) {
v0 = shape[dim + '0'];
v1 = shape[dim + '1'];
if(isCategory) {
shiftStart = shape[dim + '0shift'];
shiftEnd = shape[dim + '1shift'];
}
} else {
v0 = shape[dim + 'anchor'];
v1 = shape[dim + 'anchor'];
}
if(v0 !== undefined) return [convertVal(v0) + shiftStart, convertVal(v1) + shiftEnd];
if(!shape.path) return;
var min = Infinity;
var max = -Infinity;
var segments = shape.path.match(constants.segmentRE);
var i;
var segment;
var drawnParam;
var params;
var val;
if(ax.type === 'date') convertVal = helpers.decodeDate(convertVal);
for(i = 0; i < segments.length; i++) {
segment = segments[i];
drawnParam = paramsToUse[segment.charAt(0)].drawn;
if(drawnParam === undefined) continue;
params = segments[i].substr(1).match(constants.paramRE);
if(!params || params.length < drawnParam) continue;
val = convertVal(params[drawnParam]);
if(val < min) min = val;
if(val > max) max = val;
}
if(max >= min) return [min, max];
}