微信小程序 使用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 相关文章推荐
取得父标签
Nov 14 Javascript
如何让easyui gridview 宽度自适应窗口改变及fitColumns应用
Jan 25 Javascript
javascript实现行拖动的方法
May 27 Javascript
JS+CSS实现仿支付宝菜单选中效果代码
Sep 25 Javascript
angular.js 路由及页面传参示例
Feb 24 Javascript
Vue form 表单提交+ajax异步请求+分页效果
Apr 22 Javascript
JavaScript事件方法(实例讲解)
Jun 27 Javascript
vue给input file绑定函数获取当前上传的对象完美实现方法
Dec 15 Javascript
vue利用axios来完成数据的交互
Mar 23 Javascript
es6中比较有用的7个技巧小结
Jul 12 Javascript
JavaScript动画实例之粒子文本的实现方法详解
Jul 28 Javascript
在vue项目中引用Antv G2,以饼图为例讲解
Oct 28 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设置session(过期、失效、有效期)
2015/11/12 PHP
WordPress中制作导航菜单的PHP核心方法讲解
2015/12/11 PHP
PHPExcel实现表格导出功能示例【带有多个工作sheet】
2018/06/13 PHP
利用404错误页面实现UrlRewrite的实现代码
2008/08/20 Javascript
在IE6下发生Internet Explorer cannot open the Internet site错误
2010/06/21 Javascript
AJAX 网页保留浏览器前进后退等功能
2011/02/12 Javascript
使用cluster 将自己的Node服务器扩展为多线程服务器
2014/11/10 Javascript
jQuery Ajax自定义分页组件(jquery.loehpagerv1.0)实例详解
2017/05/01 jQuery
JS实现自定义弹窗功能
2018/08/08 Javascript
基于js Canvas实现二次贝塞尔曲线
2018/12/25 Javascript
详解小程序退出页面时清除定时器
2019/04/28 Javascript
webpack中如何加载静态文件的方法步骤
2019/05/18 Javascript
JS前端知识点offset,scroll,client,冒泡,事件对象的应用整理总结
2019/06/27 Javascript
IntelliJ IDEA编辑器配置vue高亮显示
2019/09/26 Javascript
vue 使用v-for进行循环的实例代码详解
2020/02/19 Javascript
Python中的自省(反射)详解
2015/06/02 Python
Python字符串格式化输出方法分析
2016/04/13 Python
Python错误提示:[Errno 24] Too many open files的分析与解决
2017/02/16 Python
Python 机器学习库 NumPy入门教程
2018/04/19 Python
python集合是否可变总结
2019/06/20 Python
python 函数中的内置函数及用法详解
2019/07/02 Python
DJango的创建和使用详解(默认数据库sqlite3)
2019/11/18 Python
django-orm F对象的使用 按照两个字段的和,乘积排序实例
2020/05/18 Python
PyCharm 2020.2 安装详细教程
2020/09/25 Python
有关HTML5中背景音乐的自动播放功能
2017/10/16 HTML / CSS
Pharmacy Online中文直邮网站:澳洲大型药房
2020/06/27 全球购物
毕业实习评语
2014/02/10 职场文书
课程改革实施方案
2014/03/16 职场文书
公共艺术专业自荐信
2014/09/01 职场文书
2014年教师学期工作总结
2014/11/08 职场文书
就业推荐表自我评价范文
2015/03/02 职场文书
社区文明创建工作总结2015
2015/04/21 职场文书
伊索寓言读书笔记
2015/06/30 职场文书
《草虫的村落》教学反思
2016/02/20 职场文书
HTML5中 rem适配方案与 viewport 适配问题详解
2021/04/27 HTML / CSS
golang为什么要统一错误处理
2022/04/03 Golang