*新闻详情页*/>
日期:2021-01-19 类型:科技新闻 我要分享
关键词:公众号小程序,小程序正规价格表,微信群签到小程序,网络抽签小程序,个人做小程序需要什么
写在最前
本次共享1下在canvas中将绘图出来的折直线的棱角“磨平”,也便是根据贝塞尔曲线图穿过各个描点来替代原来的折线图。
为何要光滑拟合折直线
先看来下Echarts下折线图的3D渲染实际效果:
1刚开始我没留意到实际上这个折直线是曲线图穿以往的,只觉得是单纯性的描点制图,因此最初我完成的“简(丑)易(陋)”版本号是这样的:
不必关心款式,关键便是完成以后才发现看起来人家Echarts的完成描点十分的圆润,也由此引起了以后的讨论。如何有规律性的画光滑曲线图?
实际效果图
先看来下最后效仿的完成:
由于我也不知道道Echarts內部如何完成的(逃
看起来早已十分圆滑了,和大家最开始的构想10分贴近了。再看下曲线图是不是穿过了描点:
好的!結果很显著如今来再次看下大家的完成方法。
完成全过程
仿真模拟数据信息
var data = [Math.random() * 300]; for (var i = 1; i < 50; i++) { //依照echarts data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1])); } option = { canvas:{ id: 'canvas' }, series: { name: '仿真模拟数据信息', itemStyle: { color: 'rgb(255, 70, 131)' }, areaStyle: { color: 'rgb(255, 158, 68)' }, data: data } };
绘图折线图
最先原始化1个结构涵数来置放必须用到的数据信息:
function LinearGradient(option) { this.canvas = document.getElementById(option.canvas.id) this.ctx = this.canvas.getContext('2d') this.width = this.canvas.width this.height = this.canvas.height this.tooltip = option.tooltip this.title = option.text this.series = option.series //储放仿真模拟数据信息 }
绘图折线图:
LinearGradient.prototype.draw1 = function() { //折线参照线 ... //要考虑到到canvas中的原点是左上角, //因此下面要做1些换算, //diff为x,y轴被数据信息最大值和最少值的赋值范畴所均分的等份。 this.series.data.forEach(function(item, index) { var x = diffX * index, y = Math.floor(self.height - diffY * (item - dataMin)) self.ctx.lineTo(x, y) //绘图各个数据信息点 }) ... }
贝塞尔曲线图光滑拟合
贝塞尔曲线图的重要点在于操纵点的挑选,这个网站能够动态性的呈现操纵点不一样而绘图的不一样的曲线图。而针对操纵点的测算。。作者還是挑选了百度搜索1下终究数学课不太好:)。实际优化算法有兴趣爱好的同学能够深层次掌握下,如今立即说下测算操纵点的结果。
上面的公式涉及到到4个座标点,当今点,前1个点和后两个点,而当座标值为下图展现的情况下绘图出来的曲线图以下所示:
但是会有1个难题便是起止点和最终1个点不可以用这个公式,但是那篇文章内容也得出了界限值的解决方法:
因此在将折线换为光滑曲线图的情况下,将界限值和别的操纵点测算好以后代入到贝塞尔涵数中就进行了:
//关键完成 this.series.data.forEach(function(item, index) { //寻找前1个点到下1个点正中间的操纵点 var scale = 0.1 //各自针对ab操纵点的1个正数,能够各自自主调剂 var last1X = diffX * (index - 1), last1Y = Math.floor(self.height - diffY * (self.series.data[index - 1] - dataMin)), //前1个点座标 last2X = diffX * (index - 2), last2Y = Math.floor(self.height - diffY * (self.series.data[index - 2] - dataMin)), //前两个点座标 nowX = diffX * (index), nowY = Math.floor(self.height - diffY * (self.series.data[index] - dataMin)), //当期点座标 nextX = diffX * (index + 1), nextY = Math.floor(self.height - diffY * (self.series.data[index + 1] - dataMin)), //下1个点座标 cAx = last1X + (nowX - last2X) * scale, cAy = last1Y + (nowY - last2Y) * scale, cBx = nowX - (nextX - last1X) * scale, cBy = nowY - (nextY - last1Y) * scale if(index === 0) { self.ctx.lineTo(nowX, nowY) return } else if(index ===1) { cAx = last1X + (nowX - 0) * scale cAy = last1Y + (nowY - self.height) * scale } else if(index === self.series.data.length - 1) { cBx = nowX - (nowX - last1X) * scale cBy = nowY - (nowY - last1Y) * scale } self.ctx.bezierCurveTo(cAx, cAy, cBx, cBy, nowX, nowY); //绘图出上1个点到当今点的贝塞尔曲线图 })
因为我每次遍历的点全是当今点,可是文章内容中得出的公式是测算会了解下1个点的操纵点优化算法,故在编码完成中我将全部点的测算挪前了1位。当index = 0时也便是原始点是不必须曲线图绘图的,由于大家绘图的是从前1个点到当今点的曲线图,沒有到0的曲线图必须绘图。从index = 1刚开始大家便可以一切正常刚开始绘图,从0到1的曲线图,因为index = 1时是沒有在他前面第2个点的故其属于界限值点,也便是必须独特开展测算,和最终1个点。其余均依照一切正常公式算出AB的xy座标代入贝塞尔涵数便可。
最终
源码见这里
以上便是本文的所有內容,期待对大伙儿的学习培训有一定的协助,也期待大伙儿多多适用脚本制作之家。
Copyright © 2002-2020 公众号小程序_小程序正规价格表_微信群签到小程序_网络抽签小程序_个人做小程序需要什么 版权所有 (网站地图) 粤ICP备10235580号