-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathcross_trace_calc.js
129 lines (104 loc) · 3.96 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
/**
* 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 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 max_half_width = dPos;
for(i = 0; i < boxList.length; i++) {
calcTrace = calcdata[boxList[i]];
if(calcTrace[0].trace.width) {
if(calcTrace[0].trace.width / 2 > max_half_width) {
max_half_width = calcTrace[0].trace.width / 2;
}
}
}
// 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 extremes = Axes.findExtremes(posAxis, boxdv.vals, {
vpadminus: max_half_width + pad[0] * padfactor,
vpadplus: max_half_width + pad[1] * padfactor
});
for(i = 0; i < boxList.length; i++) {
calcTrace = calcdata[boxList[i]];
// set the width of all boxes
// override dPos with trace.width if present
calcTrace[0].t.dPos = (calcTrace[0].trace.width / 2) || dPos;
// link extremes to all boxes
calcTrace[0].trace._extremes[posAxis._id] = extremes;
}
}
module.exports = {
crossTraceCalc: crossTraceCalc,
setPositionOffset: setPositionOffset
};