@@ -13,35 +13,89 @@ var d3 = require('d3');
13
13
var tinycolor = require ( 'tinycolor2' ) ;
14
14
var isNumeric = require ( 'fast-isnumeric' ) ;
15
15
16
- var Lib = require ( '../../lib' ) ;
17
16
var Color = require ( '../color' ) ;
18
17
18
+ /**
19
+ * General colorscale function generator.
20
+ *
21
+ * By default, the routine compute that domain and range,
22
+ * but optional can be called with pre-computed values.
23
+ *
24
+ * @param {array } scl
25
+ * plotly.js colorscale array of arrays as found in fullData
26
+ * @param {number } cmin
27
+ * minimum color value (used to clamp scale)
28
+ * @param {number } cmax
29
+ * maximum color value (used to clamp scale)
30
+ * @param {object } opts [optional]
31
+ * - domain {array} precomputed domain
32
+ * - range {array} precomputed range
33
+ * - noNumericCheck {boolean} if true, scale func bypasses numeric checks
34
+ * - returnArray {boolean} if true, scale func return 4-item array instead of color strings
35
+ *
36
+ * @return {function }
37
+ *
38
+ */
39
+ module . exports = function makeScaleFunction ( scl , cmin , cmax , opts ) {
40
+ opts = opts || { } ;
41
+
42
+ var N = scl . length ;
43
+
44
+ var domain , rangeOrig , i ;
45
+
46
+ if ( opts . domain && opts . range ) {
47
+ domain = opts . domain ;
48
+ rangeOrig = opts . range ;
49
+ }
50
+ else {
51
+ domain = new Array ( N ) ;
52
+ rangeOrig = new Array ( N ) ;
53
+
54
+ for ( i = 0 ; i < N ; i ++ ) {
55
+ var si = scl [ i ] ;
56
+
57
+ domain [ i ] = cmin + si [ 0 ] * ( cmax - cmin ) ;
58
+ rangeOrig [ i ] = si [ 1 ] ;
59
+ }
60
+ }
61
+
62
+ var range = new Array ( N ) ;
19
63
20
- module . exports = function makeScaleFunction ( scl , cmin , cmax ) {
21
- var N = scl . length ,
22
- domain = new Array ( N ) ,
23
- range = new Array ( N ) ,
24
- si ;
64
+ for ( i = 0 ; i < N ; i ++ ) {
65
+ var rgba = tinycolor ( rangeOrig [ i ] ) . toRgb ( ) ;
25
66
26
- for ( var i = 0 ; i < N ; i ++ ) {
27
- si = scl [ i ] ;
28
- domain [ i ] = cmin + si [ 0 ] * ( cmax - cmin ) ;
29
- range [ i ] = tinycolor ( si [ 1 ] ) . toRgb ( ) ;
67
+ range [ i ] = [ rgba . r , rgba . g , rgba . b , rgba . a ] ;
30
68
}
31
69
32
- var sclFunc = d3 . scale . linear ( )
70
+ var _sclFunc = d3 . scale . linear ( )
33
71
. domain ( domain )
34
- . interpolate ( d3 . interpolateObject )
35
- . range ( range ) ;
72
+ . range ( range )
73
+ . clamp ( true ) ;
74
+
75
+ var sclFunc = function ( v ) {
76
+ if ( opts . noNumericCheck || isNumeric ( v ) ) {
77
+ var colorArray = _sclFunc ( v ) ;
78
+
79
+ if ( opts . returnArray ) return colorArray ;
36
80
37
- return function ( v ) {
38
- if ( isNumeric ( v ) ) {
39
- var sclVal = Lib . constrain ( v , cmin , cmax ) ,
40
- colorObj = sclFunc ( sclVal ) ;
81
+ var colorObj = {
82
+ r : colorArray [ 0 ] ,
83
+ g : colorArray [ 1 ] ,
84
+ b : colorArray [ 2 ] ,
85
+ a : colorArray [ 3 ]
86
+ } ;
41
87
42
88
return tinycolor ( colorObj ) . toRgbString ( ) ;
43
89
}
44
90
else if ( tinycolor ( v ) . isValid ( ) ) return v ;
45
91
else return Color . defaultLine ;
46
92
} ;
93
+
94
+ // colorbar draw looks into the d3 scale closure for domain and range
95
+
96
+ sclFunc . domain = _sclFunc . domain ;
97
+
98
+ sclFunc . range = function ( ) { return rangeOrig ; } ;
99
+
100
+ return sclFunc ;
47
101
} ;
0 commit comments