将数组中的任意值映射到另一个数组中存在的颜色

Map an arbitrary value from an array to a color that exists in another array

我想将任意值映射到色标,以便在热图中使用。

我已经能够生成 2 种极端颜色之间的色谱作为数组,如下所示:

create_color_spectrum("#b33939", "#ff5252", 20)

...输出如下:

["#fb5050", "#f74f4f", "#f34e4e", "#ef4d4d", "#ec4b4b", "#e84a4a", "#e44949", "#e04848", "#dc4646", "#d94545", "#d54444", "#d14343", "#cd4141", "#c94040", "#c63f3f", "#c23e3e", "#be3c3c", "#ba3b3b", "#b63a3a", "#b23838"]

现在假设我有另一个值数组 (values array) 像这样(与 colors 数组 长度相同):

[0.020565500406834823, 0.0006918573709419904, 0.03614457831325302, 0.014884840151254727, 0.9638554216867471, 0.005208333333333333, 0.0006248326341158618, 0.14285714285714285, 0.004872900466547537, 0.8571428571428577, 0, 0.2142857142857144, 0, 0.2499999999999991, 0.5000000004656613, 0.45534591194968543, 0.6349489795918367, 0.25, 0.15218156916454706, 0]

如何从 colors 数组 中为 values 数组 中的每个值提取合适的颜色?这个想法是,较小的值朝向 colors 数组 的开头,较大的值朝向 colors 数组 .[=13 的结尾=]

我需要从 values 数组 中读取一个值并将其映射到 colors 数组 中的索引。

我可以尝试重新缩放值数组,但这不会产生不同的整数值,而索引 colors 数组.

需要这些值

这里我构建了一个小对象数组来包含values数组中的值和原始索引。然后我按值对新数组进行排序,按新索引为每个元素分配颜色,然后按原始索引重新排序。

const colors = ["#fb5050", "#f74f4f", "#f34e4e", "#ef4d4d", "#ec4b4b", "#e84a4a", "#e44949", "#e04848", "#dc4646", "#d94545", "#d54444", "#d14343", "#cd4141", "#c94040", "#c63f3f", "#c23e3e", "#be3c3c", "#ba3b3b", "#b63a3a", "#b23838"];

const values = [0.020565500406834823, 0.0006918573709419904, 0.03614457831325302, 0.014884840151254727, 0.9638554216867471, 0.005208333333333333, 0.0006248326341158618, 0.14285714285714285, 0.004872900466547537, 0.8571428571428577, 0, 0.2142857142857144, 0, 0.2499999999999991, 0.5000000004656613, 0.45534591194968543, 0.6349489795918367, 0.25, 0.15218156916454706, 0];

// keep track of the old index and sort by value
const valueMap = values.map((val, i) => ({oldIndex: i, value: val})).sort((a,b) => a.value - b.value);

// add the appropriate color to each element of the sorted array
valueMap.forEach((val, i) => val.color = colors[i]);
//check this console.log to verify it sorted/assigned properly
//console.log(JSON.stringify(valueMap));

// resort it by oldIndex
valueMap.sort((a,b) => a.oldIndex - b.oldIndex);

// get just the array of colors
const newColors = valueMap.map(val => val.color);
console.log(newColors);

您需要将每个值映射到颜色图中的索引。为此,您需要知道期望看到的最小值(在您的示例中看起来像 0)、期望看到的最大值(我猜是 1)和数字可用颜色数(20 此处)。

// You can hard code these if you know them and want a constant representation
// The lowest possible value
const valueFloor = Math.min(...values);
// The range between the lowest and highest possible value
const valueRange = Math.max(...values) - valueFloor;

const maxColorIdx = colors.length - 1;

for (const value of values) {
    // Normalize your value to something between 0 and 1
    const normalizedValue = (value - valueFloor) / valueRange;
    // Scale your normalized value to an integerrepresenting a color index 
    const colorIdx = Math.round(normalizedValue * maxColorIdx);
    console.debug(colors[colorIdx]);
}

这将为您的每个值打印出“热图”颜色。