|
8 | 8 |
|
9 | 9 | 'use strict';
|
10 | 10 |
|
11 |
| -var Registry = require('../../registry'); |
12 | 11 | var Axes = require('../../plots/cartesian/axes');
|
13 | 12 | var Lib = require('../../lib');
|
14 | 13 |
|
15 |
| -module.exports = function setPositions(gd, plotinfo) { |
16 |
| - var fullLayout = gd._fullLayout; |
| 14 | +var orientations = ['v', 'h']; |
| 15 | + |
| 16 | +function setPositions(gd, plotinfo) { |
| 17 | + var calcdata = gd.calcdata; |
17 | 18 | var xa = plotinfo.xaxis;
|
18 | 19 | var ya = plotinfo.yaxis;
|
19 |
| - var orientations = ['v', 'h']; |
20 |
| - |
21 |
| - // TODO figure this out |
22 |
| - // should violins and boxes share 'num' fields? |
23 |
| - var numKey = '_numBoxes'; |
24 |
| - |
25 |
| - var posAxis, i, j, k; |
26 | 20 |
|
27 |
| - for(i = 0; i < orientations.length; ++i) { |
28 |
| - var orientation = orientations[i], |
29 |
| - boxlist = [], |
30 |
| - boxpointlist = [], |
31 |
| - minPad = 0, |
32 |
| - maxPad = 0, |
33 |
| - cd, |
34 |
| - t, |
35 |
| - trace; |
36 |
| - |
37 |
| - // set axis via orientation |
38 |
| - if(orientation === 'h') posAxis = ya; |
39 |
| - else posAxis = xa; |
| 21 | + for(var i = 0; i < orientations.length; i++) { |
| 22 | + var orientation = orientations[i]; |
| 23 | + var posAxis = orientation === 'h' ? ya : xa; |
| 24 | + var boxList = []; |
| 25 | + var minPad = 0; |
| 26 | + var maxPad = 0; |
40 | 27 |
|
41 | 28 | // make list of boxes
|
42 |
| - for(j = 0; j < gd.calcdata.length; ++j) { |
43 |
| - cd = gd.calcdata[j]; |
44 |
| - t = cd[0].t; |
45 |
| - trace = cd[0].trace; |
| 29 | + for(var j = 0; j < calcdata.length; j++) { |
| 30 | + var cd = calcdata[j]; |
| 31 | + var t = cd[0].t; |
| 32 | + var trace = cd[0].trace; |
46 | 33 |
|
47 | 34 | if(trace.visible === true && trace.type === 'box' &&
|
48 | 35 | !t.empty &&
|
49 | 36 | trace.orientation === orientation &&
|
50 | 37 | trace.xaxis === xa._id &&
|
51 |
| - trace.yaxis === ya._id) { |
52 |
| - boxlist.push(j); |
| 38 | + trace.yaxis === ya._id |
| 39 | + ) { |
| 40 | + boxList.push(j); |
| 41 | + |
53 | 42 | if(trace.boxpoints !== false) {
|
54 | 43 | minPad = Math.max(minPad, trace.jitter - trace.pointpos - 1);
|
55 | 44 | maxPad = Math.max(maxPad, trace.jitter + trace.pointpos - 1);
|
56 | 45 | }
|
57 | 46 | }
|
58 | 47 | }
|
59 | 48 |
|
60 |
| - // make list of box points |
61 |
| - for(j = 0; j < boxlist.length; j++) { |
62 |
| - cd = gd.calcdata[boxlist[j]]; |
63 |
| - for(k = 0; k < cd.length; k++) boxpointlist.push(cd[k].pos); |
64 |
| - } |
65 |
| - if(!boxpointlist.length) continue; |
| 49 | + setPositionOffset('box', gd, boxList, posAxis, [minPad, maxPad]); |
| 50 | + } |
| 51 | +} |
66 | 52 |
|
67 |
| - // box plots - update dPos based on multiple traces |
68 |
| - // and then use for posAxis autorange |
| 53 | +function setPositionOffset(traceType, gd, boxList, posAxis, pad) { |
| 54 | + var calcdata = gd.calcdata; |
| 55 | + var fullLayout = gd._fullLayout; |
| 56 | + var pointList = []; |
| 57 | + |
| 58 | + // N.B. reused in violin |
| 59 | + var numKey = traceType === 'violin' ? '_numViolins' : '_numBoxes'; |
69 | 60 |
|
70 |
| - var boxdv = Lib.distinctVals(boxpointlist); |
71 |
| - var dPos = boxdv.minDiff / 2; |
| 61 | + var i, j, calcTrace; |
72 | 62 |
|
73 |
| - // if there's no duplication of x points, |
74 |
| - // disable 'group' mode by setting counter to 1 |
75 |
| - if(boxpointlist.length === boxdv.vals.length) { |
76 |
| - fullLayout[numKey] = 1; |
| 63 | + // make list of box points |
| 64 | + for(i = 0; i < boxList.length; i++) { |
| 65 | + calcTrace = calcdata[boxList[i]]; |
| 66 | + for(j = 0; j < calcTrace.length; j++) { |
| 67 | + pointList.push(calcTrace[j].pos); |
77 | 68 | }
|
| 69 | + } |
78 | 70 |
|
79 |
| - // check for forced minimum dtick |
80 |
| - Axes.minDtick(posAxis, boxdv.minDiff, boxdv.vals[0], true); |
| 71 | + if(!pointList.length) return; |
81 | 72 |
|
82 |
| - // set the width of all boxes |
83 |
| - for(i = 0; i < boxlist.length; i++) { |
84 |
| - var boxListIndex = boxlist[i]; |
85 |
| - gd.calcdata[boxListIndex][0].t.dPos = dPos; |
86 |
| - } |
| 73 | + // box plots - update dPos based on multiple traces |
| 74 | + // and then use for posAxis autorange |
| 75 | + var boxdv = Lib.distinctVals(pointList); |
| 76 | + var dPos = boxdv.minDiff / 2; |
87 | 77 |
|
88 |
| - // TODO this won't work when both boxes and violins are present |
89 |
| - // on same graph |
90 |
| - var gap = fullLayout.boxgap || fullLayout.violingap; |
91 |
| - var groupgap = fullLayout.boxgroupgap || fullLayout.violingroupgap; |
92 |
| - |
93 |
| - // autoscale the x axis - including space for points if they're off the side |
94 |
| - // TODO: this will overdo it if the outermost boxes don't have |
95 |
| - // their points as far out as the other boxes |
96 |
| - var padfactor = (1 - gap) * (1 - groupgap) * dPos / fullLayout[numKey]; |
97 |
| - Axes.expand(posAxis, boxdv.vals, { |
98 |
| - vpadminus: dPos + minPad * padfactor, |
99 |
| - vpadplus: dPos + maxPad * padfactor |
100 |
| - }); |
| 78 | + // if there's no duplication of x points, |
| 79 | + // disable 'group' mode by setting counter to 1 |
| 80 | + if(pointList.length === boxdv.vals.length) { |
| 81 | + fullLayout[numKey] = 1; |
101 | 82 | }
|
| 83 | + |
| 84 | + // check for forced minimum dtick |
| 85 | + Axes.minDtick(posAxis, boxdv.minDiff, boxdv.vals[0], true); |
| 86 | + |
| 87 | + // set the width of all boxes |
| 88 | + for(i = 0; i < boxList.length; i++) { |
| 89 | + calcTrace = calcdata[boxList[i]]; |
| 90 | + calcTrace[0].t.dPos = dPos; |
| 91 | + } |
| 92 | + |
| 93 | + var gap = fullLayout[traceType + 'gap']; |
| 94 | + var groupgap = fullLayout[traceType + 'groupgap']; |
| 95 | + var padfactor = (1 - gap) * (1 - groupgap) * dPos / fullLayout[numKey]; |
| 96 | + |
| 97 | + // autoscale the x axis - including space for points if they're off the side |
| 98 | + // TODO: this will overdo it if the outermost boxes don't have |
| 99 | + // their points as far out as the other boxes |
| 100 | + Axes.expand(posAxis, boxdv.vals, { |
| 101 | + vpadminus: dPos + pad[0] * padfactor, |
| 102 | + vpadplus: dPos + pad[1] * padfactor |
| 103 | + }); |
| 104 | +} |
| 105 | + |
| 106 | +module.exports = { |
| 107 | + setPositions: setPositions, |
| 108 | + setPositionOffset: setPositionOffset |
102 | 109 | };
|
0 commit comments