微信小程序 使用canvas制作K线实例详解


Posted in Javascript onJanuary 12, 2017

微信小程序 使用canvas制作K线

实现效果图:

微信小程序 使用canvas制作K线实例详解

前言:

我们目的是想要一条平滑的曲线来表示均线等,而不是一条转折点明显的折线。因此还得继续探索api。我们发现,在canvas API中,能够画出曲线的有2个

beZierCurveTo(num1, num2, num3, num4, x, y)
quadraticCurveTo(num1, num2, x, y)

这两个api都是通过贝塞尔曲线来绘制路径。好在学习PS的时候,对贝塞尔曲线的具体表现也是有一定的熟练程度的,因此知道要确定一条由多个点组成的曲线路径,每一个转折点都得有2个控制点来控制曲线的表现

而在曲线的起点和终点,就只能有一个控制点了。因此,我们在绘制起点和终点时,得使用quadraticCurveTo,绘制中间的点,则使用beZierCurveTo。

现在的难点是,如何通过已知的要经过的点,计算出他们的控制点?

为了找到一个行之有效的公式,于是草稿走起。画了一个只有自己看得懂的草稿。

微信小程序 使用canvas制作K线实例详解

没想到告别高中数学那么多年,凭着一点点的记忆,花了一上午,强行搞了一个公式出来,我想如果我还是高中的数学水平的话,估计也就10分钟就能怼出来了,汗!

不知道大家还记不记得切线的概念,如果我们要画一条贝塞尔曲线,M[i-1]是起点,M[i]是终点,另外的两个控制点为A1, A2,这2个控制点一定会在某一个曲面的切线上,而切线则可以由三个点来确定,如我的草稿中,最上面橘黄色的线条就是切线,我们只需要在这条切线上,随意取2个点,分别作为前后曲线的控制点即可

于是,经过我长时间的思考,总结了一个公式如下

A1[M[i-1][0] + a*(M[i][0] - M[i-2][0]), M[i-1][1] + b*(M[i][1] - M[i-2][1])]

A2[M[i][0] - b*(M[i+1][0] - M[i-1][0]), M[i][1] - b*(M[i+1][1] - M[i-1][1])]

其中系数a, b是一个根据情况我随意取的一个值,我试过,建议在0.3附近取值并调试,试试看具体效果再确定

第一个点和最后一点因为无法通过这种方式取得2个控制点,因此我就在点集合的前后各加了一个随意自定自定的点,在实际遍历的时候忽略他们即可。

整理了思路,具体实现如下

bezierLine (canvasId, options) {
let windowWidth = 0
wx.getSystemInfo({
 success (result) {
  windowWidth = result.windowWidth
 }
})
let a = windowWidth / (options.xAxis.length-1)
let data = []
options.xAxis.map((item, i) => {
 data.push([i * a, 200 - options.yAxis[i]])
})
data.unshift(data[0])
data.push(data[data.length - 1])

const ctx = wx.createCanvasContext(canvasId)
ctx.beginPath()
data.map((item, i) => {
 const a = 0.25
 const b = 0.25
 if (i == 0 || i == data.length - 1) {
  // do nothing
 } else if (i == 1) {
  ctx.moveTo(item[0], item[1])
 } else {
  const a1 = data[i - 1][0] + a * (data[i][0] - data[i - 2][0])
  const a2 = data[i - 1][1] + b * (data[i][1] - data[i - 2][1])
  const b1 = data[i][0] - b * (data[i + 1][0] - data[i - 1][0])
  const b2 = data[i][1] - b * (data[i + 1][1] - data[i - 1][1])
  ctx.bezierCurveTo(a1, a2, b1, b2, item[0], item[1])
 }
})
ctx.setLineWidth(1)
ctx.setStrokeStyle('red')
ctx.stroke()
ctx.draw()
}
// 在onLoad中调用
this.bezierLine('stage', {
 xAxis: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
 yAxis: [11, 33, 22, 32, 14, 15, 20, 60, 23, 44, 77, 122, 133, 89, 156, 122,128, 143, 111, 101, 132, 99, 98, 44, 62, 74, 111, 13, 42, 55]
})

oh yeah! 效果还可以,以后再也不用担心曲线的绘制了,理我们的k线图又近了一步

ps: 数据的组织形式可以多种多样,可以是数组,可以是二位数组,也可以是对象,这并不是最主要的点,只要能正确处理就行了

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
JavaScript中的prototype使用说明
Apr 13 Javascript
你的 mixin 真的兼容 ECMAScript 5 吗?
Apr 11 Javascript
用jQuery实现一些导航条切换,显示隐藏的实例代码
Jun 08 Javascript
JS如何将UTC格式时间转本地格式
Sep 04 Javascript
jquery 页面滚动到底部自动加载插件集合
Jan 31 Javascript
jquery 选取方法都有哪些
May 18 Javascript
Javascript 构造函数详解
Oct 22 Javascript
jQuery实现新消息在网页标题闪烁提示
Jun 23 Javascript
详解jQuery中ajax.load()方法
Jan 25 Javascript
js form表单input框限制20个字符,10个汉字代码实例
Apr 12 Javascript
Node.js API详解之 repl模块用法实例分析
May 25 Javascript
Vue全局使用less样式,组件使用全局样式文件中定义的变量操作
Oct 21 Javascript
JS实现仿百度文库评分功能
Jan 12 #Javascript
移动端基础事件总结与应用
Jan 12 #Javascript
微信小程序 PHP后端form表单提交实例详解
Jan 12 #Javascript
简单的渐变轮播插件
Jan 12 #Javascript
那些精彩的JavaScript代码片段
Jan 12 #Javascript
JavaScript实现星级评分
Jan 12 #Javascript
angular2倒计时组件使用详解
Jan 12 #Javascript
You might like
php !function_exists("T7FC56270E7A70FA81A5935B72EACBE29"))代码解密
2011/01/07 PHP
php设置编码格式的方法
2013/03/05 PHP
使用配置类定义Codeigniter全局变量
2014/06/12 PHP
header与缓冲区之间的深层次分析
2016/07/30 PHP
浅谈php处理后端&接口访问超时的解决方法
2016/10/29 PHP
Laravel实现定时任务的示例代码
2017/08/10 PHP
event.keyCode键码值表 附只能输入特定的字符串代码
2009/05/15 Javascript
JavaScript 数组运用实现代码
2010/04/13 Javascript
基于jquery实现的上传图片及图片大小验证、图片预览效果代码
2011/04/12 Javascript
js数组转json并在后台对其解析具体实现
2013/11/20 Javascript
div失去焦点事件实现思路
2014/04/22 Javascript
jQuery中change事件用法实例
2014/12/26 Javascript
基于jQuery倾斜打开侧边栏菜单特效代码
2015/09/15 Javascript
基于javascript实现最简单的选项卡切换效果
2016/05/16 Javascript
vue2.0 自定义日期时间过滤器
2017/06/07 Javascript
一次围绕setTimeout的前端面试经验分享
2017/06/15 Javascript
vue-router+nginx 非根路径配置方法
2018/06/30 Javascript
JavaScript使用小插件实现倒计时的方法讲解
2019/03/11 Javascript
Vue页面切换和a链接的本质区别详解
2019/11/12 Javascript
vue data引入本地图片的两种方式小结
2019/11/13 Javascript
Vue(定时器)解决mounted不能获取到data中的数据问题
2020/07/30 Javascript
[01:38]DOTA2辉夜杯 欢乐的观众现场采访
2015/12/26 DOTA
跟老齐学Python之开始真正编程
2014/09/12 Python
在Python 不同级目录之间模块的调用方法
2019/01/19 Python
如何在Django中添加没有微秒的 DateTimeField 属性详解
2019/01/30 Python
Python日志器使用方法及原理解析
2020/09/27 Python
基于Python爬取搜狐证券股票过程解析
2020/11/18 Python
Django中日期时间型字段进行年月日时分秒分组统计
2020/11/27 Python
python如何构建mock接口服务
2021/01/28 Python
韩国三大免税店之一:THE GRAND 中文免税店
2016/07/21 全球购物
万户网络JAVA程序员岗位招聘笔试试卷
2013/01/08 面试题
班训口号大全
2014/06/18 职场文书
春游踏青活动方案
2014/08/14 职场文书
公司周年庆活动方案
2014/08/25 职场文书
置业顾问岗位职责
2015/02/09 职场文书
董事会决议范本
2015/07/01 职场文书