HSV渐变色模型为Highcharts的分组堆叠柱图配置渐变色

项目中有需求为highcharts的分组堆叠柱图配置渐变色,该类柱图原始的实现是随机色的,那么配置为渐变色就须要咱们调用highchart的配色api写入咱们计算好的渐变色的颜色编码前端


具体实现能够将问题抽象成 为一个二维数组配置渐变色,初步想一想差很少就是颜色代码0~255之间累加就能够了,后来发现不是这么回事。 那咱们来仔细看看这个问题。编程

首先咱们来抽象一下问题。json

有二维数组a,假设为 m * n 维度:
a = [
 [{value:1,color:null}, {value:2,color:null}, ····n个····, {value:3,color:null}],
 ·
 ·
 m个
 ·
 ·
 [{value:7,color:null}, {value:8,color:null}, ····n个····, {value:9,color:null}],  
]

咱们的任务就是把m个一级维度设计为一个大色系,其中每一个里面的n个二级维度设计为由浅至深的渐变色。 据此设计需求将相应的颜色代码值填充到每一个json对象的color属性中。api

ok问题明确,咱们来了解一下相关的颜色代码知识。 通常网页设计中颜色代码经常使用表示方法有:数组

#667788, #333, RGB(0.2,0.4,0.5), rgb(100%,0%,0%), 文字"红色"

可是这些代码都是RGB颜色模型的,它们是经过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来获得各式各样的颜色 RGB数学模型以下:
浏览器


直观的就能发现,这个颜色模型没有选项来解决渐变色的问题,深刻一下还会发现这个模型不能进行可编程式的颜色划分。 亦即咱们不能简单的在RGB三个通道上等值累加来得到不一样的颜色红橙黄等等系列或实现指定色系的颜色渐变。 这么作咱们得到的仅仅是不一样程度的灰色。 如#333#666#999是逐渐变浅的灰色, 而这些颜色也是通常前端人员惟一记住的颜色代码 :)编码

通过一番资料搜寻,终于发现一个HSV模型,
spa




这是一个六角锥体模型,这个模型中颜色的参数分别表明了:色调(H),饱和度(S),亮度(V)。
设计

ok,找到一个合适的模型后,咱们就方便编程实现了。 咱们能够以下设计: 在H参数的360度范围内步进来实现颜色系的切换,在S参数的0 ~ 100%范围内实现颜色渐变,V参数在0 ~ 100% 范围内咱们就取值一个合适的固定值80%吧。 在了解了这些以后,剩下的问题就只剩下数学模型间的转换了,也就是把得到的HSV对象转换为浏览器可识别的RGB对象就完成了。 ok, 针对这个抽象好的问题上代码。code

/*************************************//**** start to fill in color code ****//*************************************///raw data without color code,  Dimension: m*nvar rawData = [  [{value:1,color:null}, {value:2,color:null}, ····n个····, {value:3,color:null}],  ·  ·  m个  ·  ·  [{value:7,color:null}, {value:8,color:null}, ····n个····, {value:9,color:null}],  ];var dataWithColor = [];var sediaoStep = Math.round(360 / m); //caculate the step value for sediao, var jianbianStep = Math.round(100 / n); //caculate the step value for jianbian,var sediao = 0;rawData.forEach(function(item, index){ var jianbian = 0; //every time we switch the color, we init the jianbian with zero sediao += sediaoStep; //switch the color item.forEach(function(one){ jianbian += jianbianStep; //switch the jianbian var hsv = { h: sediao, s: jianbian, v: 80, }; var color = HSV_To_RGB(hsv); dataWithColor[index] || dataWithColor.push( [] ); //judge if the index item is exist in dataWithColor, if not ,push in on empty array dataWithColor[index].push({ value: one.value, color: color, }); });});//Convert HSV obj like {h:195, s:70, v:60}  to RGB object like {r:220, g:160, b:80}//@param {object} HSV  The param strcture is {h:*, s:*, v:*}  H:指定色调 S:指定饱和度,用于颜色渐变 V:指定亮度//@return {object}  The return object strcture is like {r:null, g:null, b:null}function HSV_To_RGB(HSV){ var result = { r: 0, g: 0, b: 0 }; var h = HSV.h / 360; var s = HSV.s / 100; var v = HSV.v / 100; if (s == 0) { result.r = v * 255; result.g = v * 255; result.v = v * 255; } else { var_h = h * 6; var_i = Math.floor(var_h); var_1 = v * (1 - s); var_2 = v * (1 - s * (var_h - var_i)); var_3 = v * (1 - s * (1 - (var_h - var_i))); if (var_i == 0) { var_r = v; var_g = var_3; var_b = var_1 } else if (var_i == 1) { var_r = var_2; var_g = v; var_b = var_1 } else if (var_i == 2) { var_r = var_1; var_g = v; var_b = var_3 } else if (var_i == 3) { var_r = var_1; var_g = var_2; var_b = v } else if (var_i == 4) { var_r = var_3; var_g = var_1; var_b = v } else { var_r = v; var_g = var_1; var_b = var_2 }; result.r = var_r * 255; result.g = var_g * 255; result.b = var_b * 255; result.r = Math.round(result.r); result.g = Math.round(result.g); result.b = Math.round(result.b); } return RGB_To_Color(result);},//Convert the RGB Object like {r:220, g:160, b:80} to "#768844"//@param {object} obj  The RGB object//@return {string} The return color stringfunction RGB_To_Color(obj){ obj.r = Math.round(obj.r); obj.g = Math.round(obj.g); obj.b = Math.round(obj.b); var color = '#'; color += (obj.r < 16 ? '0' : '') + obj.r.toString(16); color += (obj.g < 16 ? '0' : '') + obj.g.toString(16); color += (obj.b < 16 ? '0' : '') + obj.b.toString(16); return color;},/******************************//**** end to fill in color ****//******************************/
相关文章
相关标签/搜索