在标量数据渲染制图过程中,免不了将你渲染的颜色取出来作为一个图例对你渲染结果的属性值进行说明,以便于用户对更好的理解你的数据。本文主要介绍如何在Web前端生成颜色带对于标量数据插值结果进行渲染以及图例的绘制。
ESRI ArcGIS Pro帮助中对于配色方案的总结
如果你想要对数据插值后生成得栅格进行渲染,可以直接使用在线颜色选择工具选择几个颜色进行分级渲染即可
在线颜色选择器
随便几个颜色对其进行分级结果如下
var colorband = ["#99ffff", "#99ccff", "#9999ff", "#9966ff", "#9933ff", "#9900ff"];
此时分级的粒度较大,其实就是生成了一个离散的颜色带,上图就是其渲染结果。
var colorBandSST = ["#00A600", "#01A600", "#03A700", "#04A700", "#05A800", "#07A800", "#08A900", "#09A900", "#0BAA00", "#0CAA00", "#0DAB00", "#0FAB00", "#10AC00", "#12AC00", "#13AD00", "#14AD00", "#16AE00", "#17AE00", "#19AF00", "#1AAF00", "#1CB000", "#1DB000", "#1FB100", "#20B100", "#22B200", "#23B200", "#25B300", "#26B300", "#28B400", "#29B400", "#2BB500", "#2CB500", "#2EB600", "#2FB600", "#31B700", "#33B700", "#34B800", "#36B800", "#37B900", "#39B900", "#3BBA00", "#3CBA00", "#3EBB00", "#3FBB00", "#41BC00", "#43BC00", "#44BD00", "#46BD00", "#48BE00", "#49BE00", "#4BBF00", "#4DBF00", "#4FC000", "#50C000", "#52C100", "#54C100", "#55C200", "#57C200", "#59C300", "#5BC300", "#5DC400", "#5EC400", "#60C500", "#62C500", "#64C600", "#66C600", "#67C700", "#69C700", "#6BC800", "#6DC800", "#6FC900", "#71C900", "#72CA00", "#74CA00", "#76CB00", "#78CB00", "#7ACC00", "#7CCC00", "#7ECD00", "#80CD00", "#82CE00", "#84CE00", "#86CF00", "#88CF00", "#8AD000", "#8BD000", "#8DD100", "#8FD100", "#91D200", "#93D200", "#95D300", "#97D300", "#9AD400", "#9CD400", "#9ED500", "#A0D500", "#A2D600", "#A4D600", "#A6D700", "#A8D700", "#AAD800", "#ACD800", "#AED900", "#B0D900", "#B2DA00", "#B5DA00", "#B7DB00", "#B9DB00", "#BBDC00", "#BDDC00", "#BFDD00", "#C2DD00", "#C4DE00", "#C6DE00", "#C8DF00", "#CADF00", "#CDE000", "#CFE000", "#D1E100", "#D3E100", "#D6E200", "#D8E200", "#DAE300", "#DCE300", "#DFE400", "#E1E400", "#E3E500", "#E6E600", "#E6E402", "#E6E204", "#E6E105", "#E6DF07", "#E6DD09", "#E6DC0B", "#E6DA0D", "#E6D90E", "#E6D710", "#E6D612", "#E7D414", "#E7D316", "#E7D217", "#E7D019", "#E7CF1B", "#E7CE1D", "#E7CD1F", "#E7CB21", "#E7CA22", "#E7C924", "#E8C826", "#E8C728", "#E8C62A", "#E8C52B", "#E8C42D", "#E8C32F", "#E8C231", "#E8C133", "#E8C035", "#E8BF36", "#E9BE38", "#E9BD3A", "#E9BC3C", "#E9BB3E", "#E9BB40", "#E9BA42", "#E9B943", "#E9B945", "#E9B847", "#E9B749", "#EAB74B", "#EAB64D", "#EAB64F", "#EAB550", "#EAB552", "#EAB454", "#EAB456", "#EAB358", "#EAB35A", "#EAB35C", "#EBB25D", "#EBB25F", "#EBB261", "#EBB263", "#EBB165", "#EBB167", "#EBB169", "#EBB16B", "#EBB16C", "#EBB16E", "#ECB170", "#ECB172", "#ECB174", "#ECB176", "#ECB178", "#ECB17A", "#ECB17C", "#ECB17E", "#ECB27F", "#ECB281", "#EDB283", "#EDB285", "#EDB387", "#EDB389", "#EDB38B", "#EDB48D", "#EDB48F", "#EDB591", "#EDB593", "#EDB694", "#EEB696", "#EEB798", "#EEB89A", "#EEB89C", "#EEB99E", "#EEBAA0", "#EEBAA2", "#EEBBA4", "#EEBCA6", "#EEBDA8", "#EFBEAA", "#EFBEAC", "#EFBFAD", "#EFC0AF", "#EFC1B1", "#EFC2B3", "#EFC3B5", "#EFC4B7", "#EFC5B9", "#EFC7BB", "#F0C8BD", "#F0C9BF", "#F0CAC1", "#F0CBC3", "#F0CDC5", "#F0CEC7", "#F0CFC9", "#F0D1CB", "#F0D2CD", "#F0D3CF", "#F1D5D1", "#F1D6D3", "#F1D8D5", "#F1D9D7", "#F1DBD8", "#F1DDDA", "#F1DEDC", "#F1E0DE", "#F1E2E0", "#F1E3E2", "#F2E5E4", "#F2E7E6", "#F2E9E8", "#F2EBEA", "#F2ECEC", "#F2EEEE", "#F2F0F0", "#F2F2F2"];
在网上找了一个很多种颜色的颜色数组渲染结果如下
效果是不是好很多!!!!
但是这个颜色数据每一种颜色都有很细的粒度,甚至人眼视觉上很难分辨两种颜色的差异,很多颜色数组都是以16进制的颜色表示,我们显然不能发现一些规律但是我们可以先以rgb进行设置然后转换为16进制进行绘制。以下是要使用的渐变色带
实现代码如下
/*---------------生成任意色带数组------------------*/
function zero_fill_hex(num, digits) {
var s = num.toString(16);
while (s.length < digits)
s = "0" + s;
return s;
}
function rgb2hex(rgb) {
if (rgb.charAt(0) == '#')
return rgb;
var ds = rgb.split(/\D+/);
var decimal = Number(ds[1]) * 65536 + Number(ds[2]) * 256 + Number(ds[3]);
return "#" + zero_fill_hex(decimal, 6);
}//该函数实现从16进制颜色编码到rgb颜色编码的转换
var colorBandSWH = [];
var r, g, b, rgb;
r = 255;
g = 0;
b = 150;
while (b < 255) {
b++;
constructBand();
}
while (r > 0) {
r--;
constructBand();
}
while (g < 200) {
g++;
constructBand();
}
function constructBand() {
rgb = "(" + r + "," + g + "," + b + ")";
colorBandSWH.push(rgb);
}
for (var i = 0; i < colorBandSWH.length; i++) {
colorBandSWH[i] = rgb2hex(colorBandSWH[i]);
}
////////////////-------------生成结束-----------///////////
观察渐变色带rgb的变化规律,上述代码可以实现对于色带上任意渐变颜色16进制颜色数组的生成
是不是很酷?
上面的渲染结果是不是缺点什么,没错它没有图例,渲染的结果很酷炫但是人们并不知道颜色到数据属性值到底是如何映射的,我们必须给它加一个渐变色带的图例来方便用户更好的理解数据,这也是数据可视化的意义所在
上面这个图例就是我以海表面水汽含量(百分比)为例绘制出的图例,在一些前端可视化框架(如D3.js)中定义了一些绘制图例的类,这里我们使用html5 canvas结合原生的JS实现图例的绘制
R G B
(255, 0 , 150)
||
\/
(255, 0 , 255)
||
\/
( 0 , 0 , 255)
||
\/
( 0 ,200, 255)
上面就是该渐变颜色带的以rgb表示颜色的变化情况,观察变化规律就可以开始绘制了
步骤如下
Step1 :引入一个canvas标签,设置其大小、位置
Step2: 首先绘制一个小矩形,并在其上绘制图例的说明,比如数值表示的单位
Step3: 开始颜色的绘制,rgb颜色值经过几次过渡就将canvas标签剩余面积分成几部分进行绘制
var canvas = document.getElementById("你的canvas标签id");
var ctx = canvas.getContext("2d");
var w = canvas.attributes.width.value;
var h = canvas.attributes.height.value;
var imgdata = ctx.getImageData(0, 0, w, h);
var pixels = imgdata.data;
var i = 0;
for (var y = 20; y < h; y++) {
for (var x = 0; x < w; x++) {
if (Math.floor((y - 20) / 40) == 0) {
pixels[i++] = 255;
pixels[i++] = 0;
pixels[i++] = 150 + (y - 20) / 40 * 105;
pixels[i++] = 255;
}
else if (Math.floor((y - 20) / 40) == 1) {
pixels[i++] = 255 - ((y - 20) - 40) / 40 * 255;
pixels[i++] = 0;
pixels[i++] = 255;
pixels[i++] = 255;
} else {
pixels[i++] = 0;
pixels[i++] = 200 * ((y - 20) - 80) / 40;
pixels[i++] = 255;
pixels[i++] = 255;
}
}
}
ctx.putImageData(imgdata, 0, 0);
ctx.fillStyle = "#ffffff";
ctx.fillRect(0, 0, 20, 20);
ctx.font = "12px bold 黑体"; // 设置字体、颜色
// 设置水平对齐方式
ctx.textAlign = "center";
// 设置垂直对齐方式
ctx.textBaseline = "middle";
// 绘制文字(参数:要写的字,x坐标,y坐标)
ctx.fillStyle = "#000000";
ctx.fillText("%", 10, 10);
ctx.fillText("20", 10, 40);
ctx.fillText("35", 10, 60);
ctx.fillText("50", 10, 80);
ctx.fillText("65", 10, 100);
说明:文中代码仅供参考,不要生搬硬套,按照自己的需求改造。最近比较忙博客写的比较粗糙见谅