通用函数-给定两端范围,根据数值大小生成色值

请添加图片描述

摘要:

最近项目中遇到这样一个场景,就是画热力图根据数值大小,颜色不同,当然这个用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})`
}
 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值