@@ -118,12 +118,14 @@ function extractScale(cont) {
118118 var cmax = cOpts . max ;
119119
120120 // Check if a log type is defined on the colorbar
121+ // (Colorscale.calc guarantees cmin/cmax are strictly positive whenever
122+ // type is still 'log' by the time we get here - see maskNonPositive)
121123 var type = ( cOpts . colorbar && cOpts . colorbar . type ) || 'linear' ;
122124
123125 // Convert domain boundaries to base-10 log if required
124126 if ( type === 'log' ) {
125- if ( cmin > 0 ) cmin = Math . log10 ( cmin ) ;
126- if ( cmax > 0 ) cmax = Math . log10 ( cmax ) ;
127+ cmin = Math . log10 ( cmin ) ;
128+ cmax = Math . log10 ( cmax ) ;
127129 }
128130
129131 var scl = cOpts . reversescale ?
@@ -217,30 +219,33 @@ function makeColorScaleFunc(specs, opts) {
217219}
218220
219221function makeColorScaleFuncFromTrace ( trace , opts ) {
220- var baseColorFn = makeColorScaleFunc ( extractScale ( trace ) , opts ) ;
221222 var cOpts = extractOpts ( trace ) ;
222223 var type = ( cOpts . colorbar && cOpts . colorbar . type ) || 'linear' ;
224+ var baseColorFn = makeColorScaleFunc ( extractScale ( trace ) , opts ) ;
223225
224- // Wrap the base generator if we need to dynamically apply log transformations
225- if ( type === 'log' ) {
226- var wrappedFunc = function ( v ) {
227- if ( isNumeric ( v ) ) {
228- if ( v <= 0 ) return 'rgba(0,0,0,0)' ; // Logarithm of zero/negative is undefined
229- return baseColorFn ( Math . log10 ( v ) ) ;
230- } else if ( tinycolor ( v ) . isValid ( ) ) {
231- return v ;
232- } else {
233- return Color . defaultLine ;
234- }
235- } ;
226+ if ( type !== 'log' ) return baseColorFn ;
236227
237- // Preserve native domain and range methods for the draw components
238- wrappedFunc . domain = baseColorFn . domain ;
239- wrappedFunc . range = baseColorFn . range ;
240- return wrappedFunc ;
241- }
228+ opts = opts || { } ;
229+ var noNumericCheck = opts . noNumericCheck ;
230+ var returnArray = opts . returnArray ;
231+
232+ // Wrap the base generator to dynamically apply log transformations,
233+ // matching the array/string return shape makeColorScaleFunc would have used
234+ var wrappedFunc = function ( v ) {
235+ if ( noNumericCheck || isNumeric ( v ) ) {
236+ // log of zero/negative is undefined - treat as out-of-range
237+ if ( v > 0 ) return baseColorFn ( Math . log10 ( v ) ) ;
238+ return returnArray ? [ 0 , 0 , 0 , 0 ] : 'rgba(0,0,0,0)' ;
239+ } else if ( tinycolor ( v ) . isValid ( ) ) {
240+ return v ;
241+ }
242+ return Color . defaultLine ;
243+ } ;
242244
243- return baseColorFn ;
245+ // Preserve native domain and range methods for the draw components
246+ wrappedFunc . domain = baseColorFn . domain ;
247+ wrappedFunc . range = baseColorFn . range ;
248+ return wrappedFunc ;
244249}
245250
246251function colorArray2rbga ( colorArray ) {
@@ -261,4 +266,4 @@ module.exports = {
261266 flipScale : flipScale ,
262267 makeColorScaleFunc : makeColorScaleFunc ,
263268 makeColorScaleFuncFromTrace : makeColorScaleFuncFromTrace
264- } ;
269+ } ;
0 commit comments