@@ -13,11 +13,6 @@ var Lib = require('../../lib');
1313
1414var orientations = [ 'v' , 'h' ] ;
1515
16-
17- function getPosition ( di ) {
18- return di . pos ;
19- }
20-
2116function crossTraceCalc ( gd , plotinfo ) {
2217 var calcdata = gd . calcdata ;
2318 var xa = plotinfo . xaxis ;
@@ -27,8 +22,6 @@ function crossTraceCalc(gd, plotinfo) {
2722 var orientation = orientations [ i ] ;
2823 var posAxis = orientation === 'h' ? ya : xa ;
2924 var boxList = [ ] ;
30- var minPad = 0 ;
31- var maxPad = 0 ;
3225
3326 // make list of boxes / candlesticks
3427 // For backward compatibility, candlesticks are treated as if they *are* box traces here
@@ -45,27 +38,24 @@ function crossTraceCalc(gd, plotinfo) {
4538 trace . yaxis === ya . _id
4639 ) {
4740 boxList . push ( j ) ;
48-
49- if ( trace . boxpoints ) {
50- minPad = Math . max ( minPad , trace . jitter - trace . pointpos - 1 ) ;
51- maxPad = Math . max ( maxPad , trace . jitter + trace . pointpos - 1 ) ;
52- }
5341 }
5442 }
5543
56- setPositionOffset ( 'box' , gd , boxList , posAxis , [ minPad , maxPad ] ) ;
44+ setPositionOffset ( 'box' , gd , boxList , posAxis ) ;
5745 }
5846}
5947
60- function setPositionOffset ( traceType , gd , boxList , posAxis , pad ) {
48+ function setPositionOffset ( traceType , gd , boxList , posAxis ) {
6149 var calcdata = gd . calcdata ;
6250 var fullLayout = gd . _fullLayout ;
63- var pointList = [ ] ;
51+ var axId = posAxis . _id ;
52+ var axLetter = axId . charAt ( 0 ) ;
6453
6554 // N.B. reused in violin
6655 var numKey = traceType === 'violin' ? '_numViolins' : '_numBoxes' ;
6756
6857 var i , j , calcTrace ;
58+ var pointList = [ ] ;
6959
7060 // make list of box points
7161 for ( i = 0 ; i < boxList . length ; i ++ ) {
@@ -78,9 +68,8 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) {
7868 if ( ! pointList . length ) return ;
7969
8070 // box plots - update dPos based on multiple traces
81- // and then use for posAxis autorange
8271 var boxdv = Lib . distinctVals ( pointList ) ;
83- var dPos = boxdv . minDiff / 2 ;
72+ var dPos0 = boxdv . minDiff / 2 ;
8473
8574 // if there's no duplication of x points,
8675 // disable 'group' mode by setting counter to 1
@@ -91,33 +80,92 @@ function setPositionOffset(traceType, gd, boxList, posAxis, pad) {
9180 // check for forced minimum dtick
9281 Axes . minDtick ( posAxis , boxdv . minDiff , boxdv . vals [ 0 ] , true ) ;
9382
94- var gap = fullLayout [ traceType + 'gap' ] ;
95- var groupgap = fullLayout [ traceType + 'groupgap' ] ;
96- var padfactor = ( 1 - gap ) * ( 1 - groupgap ) * dPos / fullLayout [ numKey ] ;
83+ var num = fullLayout [ numKey ] ;
84+ var group = ( fullLayout [ traceType + 'mode' ] === 'group' && num > 1 ) ;
85+ var groupFraction = 1 - fullLayout [ traceType + 'gap' ] ;
86+ var groupGapFraction = 1 - fullLayout [ traceType + 'groupgap' ] ;
9787
98- // Find maximum trace width
99- // we baseline this at dPos
10088 for ( i = 0 ; i < boxList . length ; i ++ ) {
10189 calcTrace = calcdata [ boxList [ i ] ] ;
102- // set the width of this box
103- // override dPos with trace.width if present
104- var thisDPos = calcTrace [ 0 ] . t . dPos = ( calcTrace [ 0 ] . trace . width / 2 ) || dPos ;
105- var positions = calcTrace . map ( getPosition ) ;
106- // autoscale the x axis - including space for points if they're off the side
107- // TODO: this will overdo it if the outermost boxes don't have
108- // their points as far out as the other boxes
90+
10991 var trace = calcTrace [ 0 ] . trace ;
110- var vpadminus_pos_side = ( trace . pointpos <= 0 ) ? ( - trace . pointpos ) * padfactor * fullLayout [ numKey ] : 0 ;
111- var vpadplus_neg_side = ( trace . pointpos >= 0 ) ? trace . pointpos * padfactor * fullLayout [ numKey ] : 0 ;
112- var side = calcTrace [ 0 ] . trace . side ;
113- var vpadminus = ( side === 'positive' ) ? vpadminus_pos_side : ( thisDPos + pad [ 0 ] * padfactor ) ;
114- var vpadplus = ( side === 'negative' ) ? vpadplus_neg_side : ( thisDPos + pad [ 1 ] * padfactor ) ;
115- var extremes = Axes . findExtremes ( posAxis , positions , {
92+ var t = calcTrace [ 0 ] . t ;
93+ var width = trace . width ;
94+ var side = trace . side ;
95+ var pointpos = trace . pointpos ;
96+
97+ // position coordinate delta
98+ var dPos ;
99+ // box half width;
100+ var bdPos ;
101+ // box center offset
102+ var bPos ;
103+ // half-width within which to accept hover for this box/violin
104+ // always split the distance to the closest box/violin
105+ var wHover ;
106+
107+ if ( width ) {
108+ dPos = bdPos = wHover = width / 2 ;
109+ bPos = 0 ;
110+ } else {
111+ dPos = dPos0 ;
112+ bdPos = dPos * groupFraction * groupGapFraction / ( group ? num : 1 ) ;
113+ bPos = group ? 2 * dPos * ( - 0.5 + ( t . num + 0.5 ) / num ) * groupFraction : 0 ;
114+ wHover = dPos * ( group ? groupFraction / num : 1 ) ;
115+ }
116+ t . dPos = dPos ;
117+ t . bPos = bPos ;
118+ t . bdPos = bdPos ;
119+ t . wHover = wHover ;
120+
121+ var edge = bPos + bdPos ;
122+ // data-space padding
123+ var vpadplus = 0 ;
124+ var vpadminus = 0 ;
125+ // pixel-space padding
126+ var ppadplus ;
127+ var ppadminus ;
128+
129+ if ( side === 'positive' ) {
130+ vpadplus = edge ;
131+ vpadminus = bPos ;
132+ } else if ( side === 'negative' ) {
133+ vpadplus = bPos ;
134+ vpadminus = edge ;
135+ } else {
136+ vpadplus = edge ;
137+ vpadminus = edge ;
138+ }
139+
140+ if ( trace . boxpoints || trace . points ) {
141+ var jitter = trace . jitter ;
142+ var ms = trace . marker . size / 2 ;
143+
144+ if ( ( pointpos + jitter ) > 0 ) {
145+ ppadplus = ms ;
146+ var pp = bPos + bdPos * ( pointpos + jitter ) ;
147+ if ( pp > vpadplus ) vpadplus = pp ;
148+ }
149+ if ( ( pointpos - jitter ) < 0 ) {
150+ ppadminus = ms ;
151+ var pm = - bPos - bdPos * ( pointpos - jitter ) ;
152+ if ( pm > vpadminus ) vpadminus = pm ;
153+ }
154+ }
155+
156+ // calcdata[i][j] are in ascending order
157+ var firstPos = calcTrace [ 0 ] . pos ;
158+ var lastPos = calcTrace [ calcTrace . length - 1 ] . pos ;
159+
160+ trace . _extremes [ axId ] = Axes . findExtremes ( posAxis , [ firstPos , lastPos ] , {
116161 vpadminus : vpadminus ,
117162 vpadplus : vpadplus ,
163+ // N.B. SVG px-space positive/negative
164+ ppadminus : { x : ppadminus , y : ppadplus } [ axLetter ] ,
165+ ppadplus : { x : ppadplus , y : ppadminus } [ axLetter ] ,
166+ // add 5% of both sides
118167 padded : true
119168 } ) ;
120- calcTrace [ 0 ] . trace . _extremes [ posAxis . _id ] = extremes ;
121169 }
122170}
123171
0 commit comments