@@ -134,6 +134,7 @@ module.exports = function plot(gd, plotinfo, cdbox) {
134134 d . val . filter ( function ( v ) { return ( v < d . lf || v > d . uf ) ; } ) ,
135135 // normally use IQR, but if this is 0 or too small, use max-min
136136 typicalSpread = Math . max ( ( d . max - d . min ) / 10 , d . q3 - d . q1 ) ,
137+ minSpread = typicalSpread * 1e-9 ,
137138 spreadLimit = typicalSpread * JITTERSPREAD ,
138139 jitterFactors = [ ] ,
139140 maxJitterFactor = 0 ,
@@ -146,22 +147,32 @@ module.exports = function plot(gd, plotinfo, cdbox) {
146147
147148 // dynamic jitter
148149 if ( trace . jitter ) {
149- for ( i = 0 ; i < pts . length ; i ++ ) {
150- i0 = Math . max ( 0 , i - JITTERCOUNT ) ;
151- pmin = pts [ i0 ] ;
152- i1 = Math . min ( pts . length - 1 , i + JITTERCOUNT ) ;
153- pmax = pts [ i1 ] ;
154-
155- if ( trace . boxpoints !== 'all' ) {
156- if ( pts [ i ] < d . lf ) pmax = Math . min ( pmax , d . lf ) ;
157- else pmin = Math . max ( pmin , d . uf ) ;
150+ if ( typicalSpread === 0 ) {
151+ // edge case of no spread at all: fall back to max jitter
152+ maxJitterFactor = 1 ;
153+ jitterFactors = new Array ( pts . length ) ;
154+ for ( i = 0 ; i < pts . length ; i ++ ) {
155+ jitterFactors [ i ] = 1 ;
156+ }
157+ }
158+ else {
159+ for ( i = 0 ; i < pts . length ; i ++ ) {
160+ i0 = Math . max ( 0 , i - JITTERCOUNT ) ;
161+ pmin = pts [ i0 ] ;
162+ i1 = Math . min ( pts . length - 1 , i + JITTERCOUNT ) ;
163+ pmax = pts [ i1 ] ;
164+
165+ if ( trace . boxpoints !== 'all' ) {
166+ if ( pts [ i ] < d . lf ) pmax = Math . min ( pmax , d . lf ) ;
167+ else pmin = Math . max ( pmin , d . uf ) ;
168+ }
169+
170+ jitterFactor = Math . sqrt ( spreadLimit * ( i1 - i0 ) / ( pmax - pmin + minSpread ) ) || 0 ;
171+ jitterFactor = Lib . constrain ( Math . abs ( jitterFactor ) , 0 , 1 ) ;
172+
173+ jitterFactors . push ( jitterFactor ) ;
174+ maxJitterFactor = Math . max ( jitterFactor , maxJitterFactor ) ;
158175 }
159-
160- jitterFactor = Math . sqrt ( spreadLimit * ( i1 - i0 ) / ( pmax - pmin + 1e-9 ) ) || 0 ;
161- jitterFactor = Lib . constrain ( Math . abs ( jitterFactor ) , 0 , 1 ) ;
162-
163- jitterFactors . push ( jitterFactor ) ;
164- maxJitterFactor = Math . max ( jitterFactor , maxJitterFactor ) ;
165176 }
166177 newJitter = trace . jitter * 2 / maxJitterFactor ;
167178 }
0 commit comments