@@ -39,9 +39,9 @@ module.exports = function draw(gd, id) {
3939 // opts: options object, containing everything from attributes
4040 // plus a few others that are the equivalent of the colorbar "data"
4141 var opts = { } ;
42- Object . keys ( attributes ) . forEach ( function ( k ) {
42+ for ( var k in attributes ) {
4343 opts [ k ] = null ;
44- } ) ;
44+ }
4545 // fillcolor can be a d3 scale, domain is z values, range is colors
4646 // or leave it out for no fill,
4747 // or set to a string constant for single-color fill
@@ -57,17 +57,23 @@ module.exports = function draw(gd, id) {
5757 // contour map) if this is omitted, fillcolors will be
5858 // evaluated halfway between levels
5959 opts . filllevels = null ;
60+ // for continuous colorscales: fill with a gradient instead of explicit levels
61+ // value should be the colorscale [[0, c0], [v1, c1], ..., [1, cEnd]]
62+ opts . fillgradient = null ;
63+ // when using a gradient, we need the data range specified separately
64+ opts . zrange = null ;
6065
6166 function component ( ) {
6267 var fullLayout = gd . _fullLayout ,
6368 gs = fullLayout . _size ;
6469 if ( ( typeof opts . fillcolor !== 'function' ) &&
65- ( typeof opts . line . color !== 'function' ) ) {
70+ ( typeof opts . line . color !== 'function' ) &&
71+ ! opts . fillgradient ) {
6672 fullLayout . _infolayer . selectAll ( 'g.' + id ) . remove ( ) ;
6773 return ;
6874 }
69- var zrange = d3 . extent ( ( ( typeof opts . fillcolor === 'function' ) ?
70- opts . fillcolor : opts . line . color ) . domain ( ) ) ;
75+ var zrange = opts . zrange || ( d3 . extent ( ( ( typeof opts . fillcolor === 'function' ) ?
76+ opts . fillcolor : opts . line . color ) . domain ( ) ) ) ;
7177 var linelevels = [ ] ;
7278 var filllevels = [ ] ;
7379 var linecolormap = typeof opts . line . color === 'function' ?
@@ -87,7 +93,10 @@ module.exports = function draw(gd, id) {
8793 if ( l > zr0 && l < zr1 ) linelevels . push ( l ) ;
8894 }
8995
90- if ( typeof opts . fillcolor === 'function' ) {
96+ if ( opts . fillgradient ) {
97+ filllevels = [ 0 ] ;
98+ }
99+ else if ( typeof opts . fillcolor === 'function' ) {
91100 if ( opts . filllevels ) {
92101 l0 = opts . filllevels . end + opts . filllevels . size / 100 ;
93102 ls = opts . filllevels . size ;
@@ -374,21 +383,25 @@ module.exports = function draw(gd, id) {
374383 z [ 1 ] += ( z [ 1 ] > z [ 0 ] ) ? 1 : - 1 ;
375384 }
376385
377-
378- // Tinycolor can't handle exponents and
379- // at this scale, removing it makes no difference.
380- var colorString = fillcolormap ( d ) . replace ( 'e-' , '' ) ,
381- opaqueColor = tinycolor ( colorString ) . toHexString ( ) ;
382-
383386 // Colorbar cannot currently support opacities so we
384387 // use an opaque fill even when alpha channels present
385- d3 . select ( this ) . attr ( {
388+ var fillEl = d3 . select ( this ) . attr ( {
386389 x : xLeft ,
387390 width : Math . max ( thickPx , 2 ) ,
388391 y : d3 . min ( z ) ,
389392 height : Math . max ( d3 . max ( z ) - d3 . min ( z ) , 2 ) ,
390- fill : opaqueColor
391393 } ) ;
394+
395+ if ( opts . fillgradient ) {
396+ Drawing . gradient ( fillEl , gd , id , 'vertical' ,
397+ opts . fillgradient , 'fill' ) ;
398+ }
399+ else {
400+ // Tinycolor can't handle exponents and
401+ // at this scale, removing it makes no difference.
402+ var colorString = fillcolormap ( d ) . replace ( 'e-' , '' ) ;
403+ fillEl . attr ( 'fill' , tinycolor ( colorString ) . toHexString ( ) ) ;
404+ }
392405 } ) ;
393406
394407 var lines = container . select ( '.cblines' )
@@ -650,13 +663,13 @@ module.exports = function draw(gd, id) {
650663
651664 // or use .options to set multiple options at once via a dictionary
652665 component . options = function ( o ) {
653- Object . keys ( o ) . forEach ( function ( name ) {
666+ for ( var name in o ) {
654667 // in case something random comes through
655668 // that's not an option, ignore it
656669 if ( typeof component [ name ] === 'function' ) {
657670 component [ name ] ( o [ name ] ) ;
658671 }
659- } ) ;
672+ }
660673 return component ;
661674 } ;
662675
0 commit comments