-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathcross_trace_calc.js
146 lines (120 loc) · 4.49 KB
/
cross_trace_calc.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/**
* Copyright 2012-2018, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
var Axes = require('../../plots/cartesian/axes');
var Lib = require('../../lib');
var orientations = ['v', 'h'];
function getPosition(di) {
return di.pos;
}
function crossTraceCalc(gd, plotinfo) {
var calcdata = gd.calcdata;
var xa = plotinfo.xaxis;
var ya = plotinfo.yaxis;
for(var i = 0; i < orientations.length; i++) {
var orientation = orientations[i];
var posAxis = orientation === 'h' ? ya : xa;
var boxList = [];
var minPad = 0;
var maxPad = 0;
// make list of boxes / candlesticks
// For backward compatibility, candlesticks are treated as if they *are* box traces here
for(var j = 0; j < calcdata.length; j++) {
var cd = calcdata[j];
var t = cd[0].t;
var trace = cd[0].trace;
if(trace.visible === true &&
(trace.type === 'box' || trace.type === 'candlestick') &&
!t.empty &&
(trace.orientation || 'v') === orientation &&
trace.xaxis === xa._id &&
trace.yaxis === ya._id
) {
boxList.push(j);
if(trace.boxpoints) {
minPad = Math.max(minPad, trace.jitter - trace.pointpos - 1);
maxPad = Math.max(maxPad, trace.jitter + trace.pointpos - 1);
}
}
}
setPositionOffset('box', gd, boxList, posAxis, [minPad, maxPad]);
}
}
function setPositionOffset(traceType, gd, boxList, posAxis, pad) {
var calcdata = gd.calcdata;
var fullLayout = gd._fullLayout;
var pointList = [];
// N.B. reused in violin
var numKey = traceType === 'violin' ? '_numViolins' : '_numBoxes';
var i, j, calcTrace;
// make list of box points
for(i = 0; i < boxList.length; i++) {
calcTrace = calcdata[boxList[i]];
for(j = 0; j < calcTrace.length; j++) {
pointList.push(calcTrace[j].pos);
}
}
if(!pointList.length) return;
// box plots - update dPos based on multiple traces
// and then use for posAxis autorange
var boxdv = Lib.distinctVals(pointList);
var dPos = boxdv.minDiff / 2;
// if there's no duplication of x points,
// disable 'group' mode by setting counter to 1
if(pointList.length === boxdv.vals.length) {
fullLayout[numKey] = 1;
}
// check for forced minimum dtick
Axes.minDtick(posAxis, boxdv.minDiff, boxdv.vals[0], true);
var gap = fullLayout[traceType + 'gap'];
var groupgap = fullLayout[traceType + 'groupgap'];
var padfactor = (1 - gap) * (1 - groupgap) * dPos / fullLayout[numKey];
// Find maximum trace width
// we baseline this at dPos
var maxHalfWidth = dPos;
for(i = 0; i < boxList.length; i++) {
calcTrace = calcdata[boxList[i]];
if(calcTrace[0].trace.width) {
if(calcTrace[0].trace.width / 2 > maxHalfWidth) {
maxHalfWidth = calcTrace[0].trace.width / 2;
}
}
}
for(i = 0; i < boxList.length; i++) {
calcTrace = calcdata[boxList[i]];
// set the width of this box
// override dPos with trace.width if present
var thisDPos = calcTrace[0].t.dPos = (calcTrace[0].trace.width / 2) || dPos;
var positions = calcTrace.map(getPosition);
// autoscale the x axis - including space for points if they're off the side
// TODO: this will overdo it if the outermost boxes don't have
// their points as far out as the other boxes
var vpadminus = 0;
var vpadplus = 0;
if(calcTrace[0].trace.side === 'positive') {
vpadminus = 0;
vpadplus = thisDPos + pad[1] * padfactor;
} else if(calcTrace[0].trace.side === 'negative') {
vpadminus = thisDPos + pad[0] * padfactor;
vpadplus = 0;
} else {
// if side === 'both'
vpadminus = thisDPos + pad[0] * padfactor;
vpadplus = thisDPos + pad[1] * padfactor;
}
var extremes = Axes.findExtremes(posAxis, positions, {
vpadminus: vpadminus,
vpadplus: vpadplus
});
calcTrace[0].trace._extremes[posAxis._id] = extremes;
}
}
module.exports = {
crossTraceCalc: crossTraceCalc,
setPositionOffset: setPositionOffset
};