Source: colormap.js

/**
 * A collection of color scales from colormap: https://github.com/bpostlethwaite/colormap
 */
const colorScales = {
    "jet": [{"index": 0, "rgb": [0, 0, 131]}, {"index": 0.125, "rgb": [0, 60, 170]}, {
        "index": 0.375,
        "rgb": [5, 255, 255]
    }, {"index": 0.625, "rgb": [255, 255, 0]}, {"index": 0.875, "rgb": [250, 0, 0]}, {"index": 1, "rgb": [128, 0, 0]}],

    "hsv": [{"index": 0, "rgb": [255, 0, 0]}, {"index": 0.169, "rgb": [253, 255, 2]}, {
        "index": 0.173,
        "rgb": [247, 255, 2]
    }, {"index": 0.337, "rgb": [0, 252, 4]}, {"index": 0.341, "rgb": [0, 252, 10]}, {
        "index": 0.506,
        "rgb": [1, 249, 255]
    }, {"index": 0.671, "rgb": [2, 0, 253]}, {"index": 0.675, "rgb": [8, 0, 253]}, {
        "index": 0.839,
        "rgb": [255, 0, 251]
    }, {"index": 0.843, "rgb": [255, 0, 245]}, {"index": 1, "rgb": [255, 0, 6]}],

    "hot": [{"index": 0, "rgb": [0, 0, 0]}, {"index": 0.3, "rgb": [230, 0, 0]}, {
        "index": 0.6,
        "rgb": [255, 210, 0]
    }, {"index": 1, "rgb": [255, 255, 255]}],

    "spring": [{"index": 0, "rgb": [255, 0, 255]}, {"index": 1, "rgb": [255, 255, 0]}],

    "summer": [{"index": 0, "rgb": [0, 128, 102]}, {"index": 1, "rgb": [255, 255, 102]}],

    "autumn": [{"index": 0, "rgb": [255, 0, 0]}, {"index": 1, "rgb": [255, 255, 0]}],

    "winter": [{"index": 0, "rgb": [0, 0, 255]}, {"index": 1, "rgb": [0, 255, 128]}],

    "bone": [{"index": 0, "rgb": [0, 0, 0]}, {"index": 0.376, "rgb": [84, 84, 116]}, {
        "index": 0.753,
        "rgb": [169, 200, 200]
    }, {"index": 1, "rgb": [255, 255, 255]}],

    "copper": [{"index": 0, "rgb": [0, 0, 0]}, {"index": 0.804, "rgb": [255, 160, 102]}, {
        "index": 1,
        "rgb": [255, 199, 127]
    }],

    "greys": [{"index": 0, "rgb": [0, 0, 0]}, {"index": 1, "rgb": [255, 255, 255]}],

    "yignbu": [{"index": 0, "rgb": [8, 29, 88]}, {"index": 0.125, "rgb": [37, 52, 148]}, {
        "index": 0.25,
        "rgb": [34, 94, 168]
    }, {"index": 0.375, "rgb": [29, 145, 192]}, {"index": 0.5, "rgb": [65, 182, 196]}, {
        "index": 0.625,
        "rgb": [127, 205, 187]
    }, {"index": 0.75, "rgb": [199, 233, 180]}, {"index": 0.875, "rgb": [237, 248, 217]}, {
        "index": 1,
        "rgb": [255, 255, 217]
    }],

    "greens": [{"index": 0, "rgb": [0, 68, 27]}, {"index": 0.125, "rgb": [0, 109, 44]}, {
        "index": 0.25,
        "rgb": [35, 139, 69]
    }, {"index": 0.375, "rgb": [65, 171, 93]}, {"index": 0.5, "rgb": [116, 196, 118]}, {
        "index": 0.625,
        "rgb": [161, 217, 155]
    }, {"index": 0.75, "rgb": [199, 233, 192]}, {"index": 0.875, "rgb": [229, 245, 224]}, {
        "index": 1,
        "rgb": [247, 252, 245]
    }],

    "yiorrd": [{"index": 0, "rgb": [128, 0, 38]}, {"index": 0.125, "rgb": [189, 0, 38]}, {
        "index": 0.25,
        "rgb": [227, 26, 28]
    }, {"index": 0.375, "rgb": [252, 78, 42]}, {"index": 0.5, "rgb": [253, 141, 60]}, {
        "index": 0.625,
        "rgb": [254, 178, 76]
    }, {"index": 0.75, "rgb": [254, 217, 118]}, {"index": 0.875, "rgb": [255, 237, 160]}, {
        "index": 1,
        "rgb": [255, 255, 204]
    }],

    "bluered": [{"index": 0, "rgb": [0, 0, 255]}, {"index": 1, "rgb": [255, 0, 0]}],

    "rdbu": [{"index": 0, "rgb": [5, 10, 172]}, {"index": 0.35, "rgb": [106, 137, 247]}, {
        "index": 0.5,
        "rgb": [190, 190, 190]
    }, {"index": 0.6, "rgb": [220, 170, 132]}, {"index": 0.7, "rgb": [230, 145, 90]}, {
        "index": 1,
        "rgb": [178, 10, 28]
    }],

    "picnic": [{"index": 0, "rgb": [0, 0, 255]}, {"index": 0.1, "rgb": [51, 153, 255]}, {
        "index": 0.2,
        "rgb": [102, 204, 255]
    }, {"index": 0.3, "rgb": [153, 204, 255]}, {"index": 0.4, "rgb": [204, 204, 255]}, {
        "index": 0.5,
        "rgb": [255, 255, 255]
    }, {"index": 0.6, "rgb": [255, 204, 255]}, {"index": 0.7, "rgb": [255, 153, 255]}, {
        "index": 0.8,
        "rgb": [255, 102, 204]
    }, {"index": 0.9, "rgb": [255, 102, 102]}, {"index": 1, "rgb": [255, 0, 0]}],

    "rainbow": [{"index": 0, "rgb": [150, 0, 90]}, {"index": 0.125, "rgb": [0, 0, 200]}, {
        "index": 0.25,
        "rgb": [0, 25, 255]
    }, {"index": 0.375, "rgb": [0, 152, 255]}, {"index": 0.5, "rgb": [44, 255, 150]}, {
        "index": 0.625,
        "rgb": [151, 255, 0]
    }, {"index": 0.75, "rgb": [255, 234, 0]}, {"index": 0.875, "rgb": [255, 111, 0]}, {"index": 1, "rgb": [255, 0, 0]}],

    "portland": [{"index": 0, "rgb": [12, 51, 131]}, {"index": 0.25, "rgb": [10, 136, 186]}, {
        "index": 0.5,
        "rgb": [242, 211, 56]
    }, {"index": 0.75, "rgb": [242, 143, 56]}, {"index": 1, "rgb": [217, 30, 30]}],

    "blackbody": [{"index": 0, "rgb": [0, 0, 0]}, {"index": 0.2, "rgb": [230, 0, 0]}, {
        "index": 0.4,
        "rgb": [230, 210, 0]
    }, {"index": 0.7, "rgb": [255, 255, 255]}, {"index": 1, "rgb": [160, 200, 255]}],

    "earth": [{"index": 0, "rgb": [0, 0, 130]}, {"index": 0.1, "rgb": [0, 180, 180]}, {
        "index": 0.2,
        "rgb": [40, 210, 40]
    }, {"index": 0.4, "rgb": [230, 230, 50]}, {"index": 0.6, "rgb": [120, 70, 20]}, {
        "index": 1,
        "rgb": [255, 255, 255]
    }],

    "electric": [{"index": 0, "rgb": [0, 0, 0]}, {"index": 0.15, "rgb": [30, 0, 100]}, {
        "index": 0.4,
        "rgb": [120, 0, 100]
    }, {"index": 0.6, "rgb": [160, 90, 0]}, {"index": 0.8, "rgb": [230, 200, 0]}, {"index": 1, "rgb": [255, 250, 220]}],

    "alpha": [{"index": 0, "rgb": [255, 255, 255, 0]}, {"index": 1, "rgb": [255, 255, 255, 1]}],

    "viridis": [{"index": 0, "rgb": [68, 1, 84]}, {"index": 0.13, "rgb": [71, 44, 122]}, {
        "index": 0.25,
        "rgb": [59, 81, 139]
    }, {"index": 0.38, "rgb": [44, 113, 142]}, {"index": 0.5, "rgb": [33, 144, 141]}, {
        "index": 0.63,
        "rgb": [39, 173, 129]
    }, {"index": 0.75, "rgb": [92, 200, 99]}, {"index": 0.88, "rgb": [170, 220, 50]}, {
        "index": 1,
        "rgb": [253, 231, 37]
    }],

    "inferno": [{"index": 0, "rgb": [0, 0, 4]}, {"index": 0.13, "rgb": [31, 12, 72]}, {
        "index": 0.25,
        "rgb": [85, 15, 109]
    }, {"index": 0.38, "rgb": [136, 34, 106]}, {"index": 0.5, "rgb": [186, 54, 85]}, {
        "index": 0.63,
        "rgb": [227, 89, 51]
    }, {"index": 0.75, "rgb": [249, 140, 10]}, {"index": 0.88, "rgb": [249, 201, 50]}, {
        "index": 1,
        "rgb": [252, 255, 164]
    }],

    "magma": [{"index": 0, "rgb": [0, 0, 4]}, {"index": 0.13, "rgb": [28, 16, 68]}, {
        "index": 0.25,
        "rgb": [79, 18, 123]
    }, {"index": 0.38, "rgb": [129, 37, 129]}, {"index": 0.5, "rgb": [181, 54, 122]}, {
        "index": 0.63,
        "rgb": [229, 80, 100]
    }, {"index": 0.75, "rgb": [251, 135, 97]}, {"index": 0.88, "rgb": [254, 194, 135]}, {
        "index": 1,
        "rgb": [252, 253, 191]
    }],

    "plasma": [{"index": 0, "rgb": [13, 8, 135]}, {"index": 0.13, "rgb": [75, 3, 161]}, {
        "index": 0.25,
        "rgb": [125, 3, 168]
    }, {"index": 0.38, "rgb": [168, 34, 150]}, {"index": 0.5, "rgb": [203, 70, 121]}, {
        "index": 0.63,
        "rgb": [229, 107, 93]
    }, {"index": 0.75, "rgb": [248, 148, 65]}, {"index": 0.88, "rgb": [253, 195, 40]}, {
        "index": 1,
        "rgb": [240, 249, 33]
    }],

    "warm": [{"index": 0, "rgb": [125, 0, 179]}, {"index": 0.13, "rgb": [172, 0, 187]}, {
        "index": 0.25,
        "rgb": [219, 0, 170]
    }, {"index": 0.38, "rgb": [255, 0, 130]}, {"index": 0.5, "rgb": [255, 63, 74]}, {
        "index": 0.63,
        "rgb": [255, 123, 0]
    }, {"index": 0.75, "rgb": [234, 176, 0]}, {"index": 0.88, "rgb": [190, 228, 0]}, {
        "index": 1,
        "rgb": [147, 255, 0]
    }],

    "cool": [{"index": 0, "rgb": [125, 0, 179]}, {"index": 0.13, "rgb": [116, 0, 218]}, {
        "index": 0.25,
        "rgb": [98, 74, 237]
    }, {"index": 0.38, "rgb": [68, 146, 231]}, {"index": 0.5, "rgb": [0, 204, 197]}, {
        "index": 0.63,
        "rgb": [0, 247, 146]
    }, {"index": 0.75, "rgb": [0, 255, 88]}, {"index": 0.88, "rgb": [40, 255, 8]}, {"index": 1, "rgb": [147, 255, 0]}],

    "rainbow-soft": [{"index": 0, "rgb": [125, 0, 179]}, {"index": 0.1, "rgb": [199, 0, 180]}, {
        "index": 0.2,
        "rgb": [255, 0, 121]
    }, {"index": 0.3, "rgb": [255, 108, 0]}, {"index": 0.4, "rgb": [222, 194, 0]}, {
        "index": 0.5,
        "rgb": [150, 255, 0]
    }, {"index": 0.6, "rgb": [0, 255, 55]}, {"index": 0.7, "rgb": [0, 246, 150]}, {
        "index": 0.8,
        "rgb": [50, 167, 222]
    }, {"index": 0.9, "rgb": [103, 51, 235]}, {"index": 1, "rgb": [124, 0, 186]}],

    "bathymetry": [{"index": 0, "rgb": [40, 26, 44]}, {"index": 0.13, "rgb": [59, 49, 90]}, {
        "index": 0.25,
        "rgb": [64, 76, 139]
    }, {"index": 0.38, "rgb": [63, 110, 151]}, {"index": 0.5, "rgb": [72, 142, 158]}, {
        "index": 0.63,
        "rgb": [85, 174, 163]
    }, {"index": 0.75, "rgb": [120, 206, 163]}, {"index": 0.88, "rgb": [187, 230, 172]}, {
        "index": 1,
        "rgb": [253, 254, 204]
    }],

    "cdom": [{"index": 0, "rgb": [47, 15, 62]}, {"index": 0.13, "rgb": [87, 23, 86]}, {
        "index": 0.25,
        "rgb": [130, 28, 99]
    }, {"index": 0.38, "rgb": [171, 41, 96]}, {"index": 0.5, "rgb": [206, 67, 86]}, {
        "index": 0.63,
        "rgb": [230, 106, 84]
    }, {"index": 0.75, "rgb": [242, 149, 103]}, {"index": 0.88, "rgb": [249, 193, 135]}, {
        "index": 1,
        "rgb": [254, 237, 176]
    }],

    "chlorophyll": [{"index": 0, "rgb": [18, 36, 20]}, {"index": 0.13, "rgb": [25, 63, 41]}, {
        "index": 0.25,
        "rgb": [24, 91, 59]
    }, {"index": 0.38, "rgb": [13, 119, 72]}, {"index": 0.5, "rgb": [18, 148, 80]}, {
        "index": 0.63,
        "rgb": [80, 173, 89]
    }, {"index": 0.75, "rgb": [132, 196, 122]}, {"index": 0.88, "rgb": [175, 221, 162]}, {
        "index": 1,
        "rgb": [215, 249, 208]
    }],

    "density": [{"index": 0, "rgb": [54, 14, 36]}, {"index": 0.13, "rgb": [89, 23, 80]}, {
        "index": 0.25,
        "rgb": [110, 45, 132]
    }, {"index": 0.38, "rgb": [120, 77, 178]}, {"index": 0.5, "rgb": [120, 113, 213]}, {
        "index": 0.63,
        "rgb": [115, 151, 228]
    }, {"index": 0.75, "rgb": [134, 185, 227]}, {"index": 0.88, "rgb": [177, 214, 227]}, {
        "index": 1,
        "rgb": [230, 241, 241]
    }],

    "freesurface-blue": [{"index": 0, "rgb": [30, 4, 110]}, {"index": 0.13, "rgb": [47, 14, 176]}, {
        "index": 0.25,
        "rgb": [41, 45, 236]
    }, {"index": 0.38, "rgb": [25, 99, 212]}, {"index": 0.5, "rgb": [68, 131, 200]}, {
        "index": 0.63,
        "rgb": [114, 156, 197]
    }, {"index": 0.75, "rgb": [157, 181, 203]}, {"index": 0.88, "rgb": [200, 208, 216]}, {
        "index": 1,
        "rgb": [241, 237, 236]
    }],

    "freesurface-red": [{"index": 0, "rgb": [60, 9, 18]}, {"index": 0.13, "rgb": [100, 17, 27]}, {
        "index": 0.25,
        "rgb": [142, 20, 29]
    }, {"index": 0.38, "rgb": [177, 43, 27]}, {"index": 0.5, "rgb": [192, 87, 63]}, {
        "index": 0.63,
        "rgb": [205, 125, 105]
    }, {"index": 0.75, "rgb": [216, 162, 148]}, {"index": 0.88, "rgb": [227, 199, 193]}, {
        "index": 1,
        "rgb": [241, 237, 236]
    }],

    "oxygen": [{"index": 0, "rgb": [64, 5, 5]}, {"index": 0.13, "rgb": [106, 6, 15]}, {
        "index": 0.25,
        "rgb": [144, 26, 7]
    }, {"index": 0.38, "rgb": [168, 64, 3]}, {"index": 0.5, "rgb": [188, 100, 4]}, {
        "index": 0.63,
        "rgb": [206, 136, 11]
    }, {"index": 0.75, "rgb": [220, 174, 25]}, {"index": 0.88, "rgb": [231, 215, 44]}, {
        "index": 1,
        "rgb": [248, 254, 105]
    }],

    "par": [{"index": 0, "rgb": [51, 20, 24]}, {"index": 0.13, "rgb": [90, 32, 35]}, {
        "index": 0.25,
        "rgb": [129, 44, 34]
    }, {"index": 0.38, "rgb": [159, 68, 25]}, {"index": 0.5, "rgb": [182, 99, 19]}, {
        "index": 0.63,
        "rgb": [199, 134, 22]
    }, {"index": 0.75, "rgb": [212, 171, 35]}, {"index": 0.88, "rgb": [221, 210, 54]}, {
        "index": 1,
        "rgb": [225, 253, 75]
    }],

    "phase": [{"index": 0, "rgb": [145, 105, 18]}, {"index": 0.13, "rgb": [184, 71, 38]}, {
        "index": 0.25,
        "rgb": [186, 58, 115]
    }, {"index": 0.38, "rgb": [160, 71, 185]}, {"index": 0.5, "rgb": [110, 97, 218]}, {
        "index": 0.63,
        "rgb": [50, 123, 164]
    }, {"index": 0.75, "rgb": [31, 131, 110]}, {"index": 0.88, "rgb": [77, 129, 34]}, {
        "index": 1,
        "rgb": [145, 105, 18]
    }],

    "salinity": [{"index": 0, "rgb": [42, 24, 108]}, {"index": 0.13, "rgb": [33, 50, 162]}, {
        "index": 0.25,
        "rgb": [15, 90, 145]
    }, {"index": 0.38, "rgb": [40, 118, 137]}, {"index": 0.5, "rgb": [59, 146, 135]}, {
        "index": 0.63,
        "rgb": [79, 175, 126]
    }, {"index": 0.75, "rgb": [120, 203, 104]}, {"index": 0.88, "rgb": [193, 221, 100]}, {
        "index": 1,
        "rgb": [253, 239, 154]
    }],

    "temperature": [{"index": 0, "rgb": [4, 35, 51]}, {"index": 0.13, "rgb": [23, 51, 122]}, {
        "index": 0.25,
        "rgb": [85, 59, 157]
    }, {"index": 0.38, "rgb": [129, 79, 143]}, {"index": 0.5, "rgb": [175, 95, 130]}, {
        "index": 0.63,
        "rgb": [222, 112, 101]
    }, {"index": 0.75, "rgb": [249, 146, 66]}, {"index": 0.88, "rgb": [249, 196, 65]}, {
        "index": 1,
        "rgb": [232, 250, 91]
    }],

    "turbidity": [{"index": 0, "rgb": [34, 31, 27]}, {"index": 0.13, "rgb": [65, 50, 41]}, {
        "index": 0.25,
        "rgb": [98, 69, 52]
    }, {"index": 0.38, "rgb": [131, 89, 57]}, {"index": 0.5, "rgb": [161, 112, 59]}, {
        "index": 0.63,
        "rgb": [185, 140, 66]
    }, {"index": 0.75, "rgb": [202, 174, 88]}, {"index": 0.88, "rgb": [216, 209, 126]}, {
        "index": 1,
        "rgb": [233, 246, 171]
    }],

    "velocity-blue": [{"index": 0, "rgb": [17, 32, 64]}, {"index": 0.13, "rgb": [35, 52, 116]}, {
        "index": 0.25,
        "rgb": [29, 81, 156]
    }, {"index": 0.38, "rgb": [31, 113, 162]}, {"index": 0.5, "rgb": [50, 144, 169]}, {
        "index": 0.63,
        "rgb": [87, 173, 176]
    }, {"index": 0.75, "rgb": [149, 196, 189]}, {"index": 0.88, "rgb": [203, 221, 211]}, {
        "index": 1,
        "rgb": [254, 251, 230]
    }],

    "velocity-green": [{"index": 0, "rgb": [23, 35, 19]}, {"index": 0.13, "rgb": [24, 64, 38]}, {
        "index": 0.25,
        "rgb": [11, 95, 45]
    }, {"index": 0.38, "rgb": [39, 123, 35]}, {"index": 0.5, "rgb": [95, 146, 12]}, {
        "index": 0.63,
        "rgb": [152, 165, 18]
    }, {"index": 0.75, "rgb": [201, 186, 69]}, {"index": 0.88, "rgb": [233, 216, 137]}, {
        "index": 1,
        "rgb": [255, 253, 205]
    }],

    "cubehelix": [{"index": 0, "rgb": [0, 0, 0]}, {"index": 0.07, "rgb": [22, 5, 59]}, {
        "index": 0.13,
        "rgb": [60, 4, 105]
    }, {"index": 0.2, "rgb": [109, 1, 135]}, {"index": 0.27, "rgb": [161, 0, 147]}, {
        "index": 0.33,
        "rgb": [210, 2, 142]
    }, {"index": 0.4, "rgb": [251, 11, 123]}, {"index": 0.47, "rgb": [255, 29, 97]}, {
        "index": 0.53,
        "rgb": [255, 54, 69]
    }, {"index": 0.6, "rgb": [255, 85, 46]}, {"index": 0.67, "rgb": [255, 120, 34]}, {
        "index": 0.73,
        "rgb": [255, 157, 37]
    }, {"index": 0.8, "rgb": [241, 191, 57]}, {"index": 0.87, "rgb": [224, 220, 93]}, {
        "index": 0.93,
        "rgb": [218, 241, 142]
    }, {"index": 1, "rgb": [227, 253, 198]}]
};

/**
 * Calculates an RGB color for a floating point value.
 * @param v a floating point value in range [0, 1]
 * @param colorScale the name of a color scale in {@link colorScales}
 * @param interpolate a boolean flag. If true, the colors between to steps of the color scale are interpolated
 * @return number[] the calculated RGB color
 */
const getColor = (v, colorScale = 'jet', interpolate = false) => {
    if (!colorScales[colorScale]) {
        throw new Error(`Color scale doesn't exist: ${colorScale}`);
    }
    const scale = colorScales[colorScale];
    for (let i = 0; i < scale.length; ++i) {
        if (i !== scale.length - 1 && v >= scale[i].index && v < scale[i + 1].index) {
            const alpha = v - scale[i].index;
            if (interpolate) {
                const cold = scale[i].rgb;
                const hot = scale[i + 1].rgb;
                return [
                    Math.floor(cold[0] * (1 - alpha) + hot[0] * alpha),
                    Math.floor(cold[1] * (1 - alpha) + hot[1] * alpha),
                    Math.floor(cold[2] * (1 - alpha) + hot[2] * alpha)
                ];
            } else {
                return alpha < 0.5 ? scale[i].rgb : scale[i + 1].rgb;
            }
        }
    }
    return scale[scale.length - 1].rgb;
};

/**
 * Calculates an RGB color using {@link getColor} and returns a string in the form of 'rgb(r, g, b)'.
 * @param v a floating point value in range [0, 1]
 * @param colorScale the name of a color scale in {@link colorScales}
 * @param interpolate a boolean flag. If true, the colors between to steps of the color scale are interpolated
 * @return string the calculated RGB color as a string
 */
const getColorString = (v, colorScale = 'jet', interpolate = false) => {
    const rgb = getColor(v, colorScale, interpolate);
    if (rgb[0] === 0 && rgb[1] === 0 && rgb[2] === 0) {
        console.log(rgb, v, colorScale);
    }
    return `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;
};