赞
踩
前言:我并不知道后端处理的是什么后缀的文件。我这里需要使用的只有一些属性值。形状如下。
最终成品图如下:
如你所见最终的结果是一个扇形图。这是由数据本身决定的。
在进入正题之前,先说明这图着色的具体的原理。先上代码
class ColorRangeMaker { option = {}; constructor(option) { let vRange = option.value[1] - option.value[0]; if (option.color.length == 2) {//仅有两个颜色 let rA = (option.color[1][0] - option.color[0][0]) / vRange; let gA = (option.color[1][1] - option.color[0][1]) / vRange; let bA = (option.color[1][2] - option.color[0][2]) / vRange; this.option = { vRange, rA, gA, bA, option }; } else {//两个以上颜色 const makers = []; let vA = vRange / (option.color.length - 1); for (let i = 1; i < option.color.length; i++) { const maker = new ColorRangeMaker({ color: [option.color[i - 1], option.color[i]], value: [option.value[0] + vA * (i - 1), option.value[0] + vA * i] }); makers.push(maker); } this.option = { makers, vA, option }; } } make(value) { const { makers, vRange, rA, gA, bA, vA, option } = this.option; if (value < option.value[0]) { return option.color[0]; } else if (value > option.value[option.value.length - 1]) { return option.color[option.color.length - 1]; } else { if (option.color.length == 2) {//仅有两个颜色 let color = option.color[0].map(a => a); let vATmp = value - option.value[0]; color[0] += parseInt(rA * vATmp); color[1] += parseInt(gA * vATmp); color[2] += parseInt(bA * vATmp); return color.join(','); } else { for (let i = 1; i < option.color.length; i++) { if (value <= option.value[0] + vA * i) { return makers[i - 1].make(value); } } } } } } export default ColorRangeMaker;
这个我忘记是从哪里找的了。。原谅我懒得翻出来贴上原地址。
简要说明一下具体的原理: 根据最大最小值作为坐标轴的区间,用颜色数组的长度来进行分段。通过查看当前值在哪两个分段值内,通过比例计算当前值得RGB值。
const cm = new ColorRangeMaker({
color: colors,
value: [Number(minData), Number(maxData)],
})
cm.make(value); // [111,111,111] => '111,111,111'
createFanChart: function () { let header = testdata.header let data = testdata.data let valSize = header.valSize let latMin = header.latMin let lonMin = header.lonMin let latMax = header.latMax let lonMax = header.lonMax // 这里为什么加 1 是一个根据色块的渲染做的判断。如果不明白可以往下看 fillRect 的参数 let width = header.lonMax - header.lonMin + 1 let height = header.latMax - header.latMin + 1 let canvas = document.createElement('canvas') let ctx = canvas.getContext('2d') // 这里 乘10的原因在于 需要 放大 10 倍去绘制,可以让锯齿明显的减少。 canvas.height = height * 10 canvas.width = width * 10 //颜色 let colors = [] // colors 应该是这种形式的 [ [0,0,0] , [ 111,111,111] ]; let [minData, maxData] = [header.valMin, header.valMax] const cm = new ColorRangeMaker({ color: colors, value: [Number(minData), Number(maxData)], }) // 绘制 散列点 到canvas上 for (let i = 0; i < valSize; i++) { ctx.fillStyle = 'rgb(' + cm.make(data.val[i]) + ')' // 这里 x 位置上 减去最小经度的原因是因为: 这个值是负的。 // 所以理论上来说 这段代码 只包含了这种 情况: // lonMin = - ? , lonMax = + ? , latMax = + , latMin = + // 由于目前只是写了demo 出来 这部分转换还是没有去做的。望知晓。 // 我认为在上面做处理会更好。 在这里 应该是有一个统一的公式的。 ctx.fillRect( (data.lon[i] - lonMin) * 10, (latMax - data.lat[i]) * 10, 10, 10 ) } // 剪切 canvas 图片. console.log(canvas.toDataURL()) return canvas.toDataURL() },
这个时候肯定会有老哥出来说了,你这啥玩意 ,没有openlayers为啥标题还写openlayers 。。反正我需求是根据地形的数据画扇形图,至于用openlayers 或者cesium 这些 框架 咋贴上去,我只能说,多的是博客教你。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。