Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 982176a

Browse files
committed
colorscale: generalize make scale function
- so that contour, heatmap and colorbar can call it to generate their color scale function - as the interpolation logic isn't trivial (in order to support rgba colorscale), reusing the same logic everywhere is a big +
1 parent ad864c4 commit 982176a

File tree

1 file changed

+71
-17
lines changed

1 file changed

+71
-17
lines changed

src/components/colorscale/make_scale_function.js

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,35 +13,89 @@ var d3 = require('d3');
1313
var tinycolor = require('tinycolor2');
1414
var isNumeric = require('fast-isnumeric');
1515

16-
var Lib = require('../../lib');
1716
var Color = require('../color');
1817

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);
1963

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();
2566

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 ];
3068
}
3169

32-
var sclFunc = d3.scale.linear()
70+
var _sclFunc = d3.scale.linear()
3371
.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;
3680

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+
};
4187

4288
return tinycolor(colorObj).toRgbString();
4389
}
4490
else if(tinycolor(v).isValid()) return v;
4591
else return Color.defaultLine;
4692
};
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;
47101
};

0 commit comments

Comments
 (0)