摘要:
最近项目中遇到这样一个场景,就是画热力图根据数值大小,颜色不同,当然这个用echarts中的visualMap视觉映射组件就能实现了,想看配置的给你个链接https://www.makeapie.cn/echarts_content/xm25Dt4GlB.html,echarts的实现如图:
但是,随着业务的变化,也就不能使用现成的echarts去画这个热力图了。
so,就自己根据需求画了下,这个难点还是色值的生成上,在网上扒现有的js插件库,解决这个问题🧐,…没找到。
所以经过不断摸索优化,写了个通用函数。
先看看我这个是怎么用的:
效果:
注:我这里是15个模块,一个模块16个单体,一分钟240个色块。
colorCalc(['rgb(0,255,0)', 'rgb(255,255,0)', 'rgb(255,0,0)'], 28,34,value)
我这里是部分调用函数,列举一条;先看范围28-34,根据三大色值,“绿” “黄” “红”,右 侧调用的**colorCalc()**函数生成色值块(展示的效果色值块会闪烁,实际不会闪,视频转gif的原因,不重要😅),进行展示说明范围色值。
内容区每一个色块是根据范围和目标值,当前目标值在此范围中的色值。
结论:
通用函数如下:
附每一行的代码解释,方便理解。
/**
* 从多重颜色渐变中根据目标值取出对应颜色
* @param {Array} colorArr 颜色数组,hex或者rgb
* @param {*} min 最小值
* @param {*} max 最大值
* @param {*} value 目标值
* @returns
*/
colorCalc = (colorArr, min, max, value) => {
// 兼容传入颜色类型,支持hex, rgb, rgba
const color2RGB = str => {
if (str.indexOf('#') != -1) {
let reg = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/
if (!reg.test(str)) { return; }
let newStr = (str.toLowerCase()).replace(/\#/g, '')
let len = newStr.length;
if (len == 3) {
let t = ''
for (var i = 0; i < len; i++) {
t += newStr.slice(i, i + 1).concat(newStr.slice(i, i + 1))
}
newStr = t
}
let arr = []; //将字符串分隔,两个两个的分隔
for (var i = 0; i < 6; i = i + 2) {
let s = newStr.slice(i, i + 2)
arr.push(parseInt("0x" + s))
}
return arr;
}
if (str.indexOf('rgb') != -1) {
let newStr = str.replace(/rgb(a?)|\(|\)/g, '');
let arr = newStr.split(',').map(Number)
return arr
}
return [255, 255, 255];
}
if(colorArr?.length===0||!value)return '';
// 如果最小值和最大值相等,呢就取值第一个 ==> 纯绿色
if(min === max) return colorArr[0];
// 拿到 中间值到最小值 || 中间值到最大值的范围
let colorInterval = (max - min)/(colorArr.length-1);
// 生成颜色区间,为计算比例需要
const Interval = Array(colorArr.length-1).fill().map((item,index) => {
if(index ==0)return [min, min+colorInterval];
if(index === colorArr.length-2)return [min+(colorInterval*index),max]
return [min+(colorInterval*index), min+colorInterval*(index+1)]
})
// console.log("颜色", colorArr, value);
// console.log("颜色区间", Interval);
// 根据目标值,确定颜色区间
let cIndex = 0;
for (let i = 0; i < Interval.length; i++) {
if (value >= Interval[i][0] && value <= Interval[i][1]) {
cIndex = i;
break;
}
}
// 计算两种颜色间百分比
let rate = (value - Interval[cIndex][0]) / (Interval[cIndex][1] - Interval[cIndex][0]);
// 计算rgb
let color1 = color2RGB(colorArr[cIndex]);
let color2 = color2RGB(colorArr[cIndex + 1]);
let r = color1[0] + (color2[0] - color1[0]) * rate;
let g = color1[1] + (color2[1] - color1[1]) * rate;
let b = color1[2] + (color2[2] - color1[2]) * rate;
// console.log('输入出颜色', `rgb(${r},${g},${b})`);
return `rgb(${r},${g},${b})`
}