微信小程序 使用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 相关文章推荐
Extjs EditorGridPanel中ComboBox列的显示问题
Jul 04 Javascript
JS 排序输出实现table行号自增前端动态生成的tr
Aug 13 Javascript
jQuery插件HighCharts绘制的2D堆柱状图效果示例【附demo源码下载】
Mar 14 Javascript
详解使用Node.js 将txt文件转为Excel文件
Jul 05 Javascript
JavaScript中正则表达式判断匹配规则及常用方法
Aug 03 Javascript
vue 页面加载进度条组件实例
Feb 05 Javascript
Vue+webpack项目基础配置教程
Feb 12 Javascript
LayerClose弹窗关闭刷新方法
Aug 17 Javascript
微信小程序实现顶部导航特效
Jan 28 Javascript
vue增加强缓存和版本号的实现方法
May 01 Javascript
JS在Array数组中按指定位置删除或添加元素对象方法示例
Nov 19 Javascript
Element Tooltip 文字提示的使用示例
Jul 26 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代码
2008/09/10 PHP
php和mysql中uft-8中文编码乱码的几种解决办法
2012/04/19 PHP
PHP获取当前日期和时间及格式化方法参数
2015/05/11 PHP
php使用Jpgraph绘制柱形图的方法
2015/06/10 PHP
一个完整的php文件上传类实例讲解
2015/10/27 PHP
在WordPress的后台中添加顶级菜单和子菜单的函数详解
2016/01/11 PHP
Laravel框架源码解析之入口文件原理分析
2020/05/14 PHP
学习ExtJS 访问容器对象
2009/10/07 Javascript
html 锁定页面(js遮罩层弹出div效果)
2009/10/27 Javascript
基于jquery的修改当前TAB显示标题的代码
2010/12/11 Javascript
js编码之encodeURIComponent使用介绍(asp,php)
2012/03/01 Javascript
jquery Mobile入门—多页面切换示例学习
2013/01/08 Javascript
jQuery实现的Div窗口震动效果实例
2015/08/07 Javascript
asp.net中oracle 存储过程(图文)
2015/08/12 Javascript
原生JS实现移动端web轮播图详解(结合Tween算法造轮子)
2017/09/10 Javascript
jQuery实现所有验证通过方可提交的表单验证
2017/11/21 jQuery
详解VUE-地区选择器(V-Distpicker)组件使用心得
2018/05/07 Javascript
vue中子组件调用兄弟组件方法
2018/07/06 Javascript
vue修改对象的属性值后页面不重新渲染的实例
2018/08/09 Javascript
layer弹出层父子页面事件相互调用方法
2018/08/17 Javascript
vue自定义指令的创建和使用方法实例分析
2018/12/04 Javascript
node app 打包工具pkg的具体使用
2019/01/17 Javascript
vue实现搜索过滤效果
2019/05/28 Javascript
JavaScript数组排序的六种常见算法总结
2020/08/18 Javascript
使用python搭建Django应用程序步骤及版本冲突问题解决
2013/11/19 Python
Flask web开发处理POST请求实现(登录案例)
2018/07/26 Python
python数值基础知识浅析
2019/11/19 Python
美国电视购物:QVC
2017/02/06 全球购物
英国领先的杂志订阅网站:Magazine.co.uk
2018/01/25 全球购物
ECOSUSI官网:女式皮革背包
2019/09/27 全球购物
香港艺人陈冠希创办的潮流品牌:JUICESTORE
2021/03/04 全球购物
SQL Server提供的3种恢复模型都是什么? 有什么区别?
2012/05/13 面试题
代理商会议邀请函
2014/01/27 职场文书
专题组织生活会方案
2014/06/15 职场文书
计划生育标语
2014/06/23 职场文书
文明和谐家庭事迹材料(2016精选版)
2016/02/29 职场文书