一图胜千言,相信很多开发者都没有绕开过图表制作这个坑,在小程序中也是,当然可以用第三方echart等制图插件来做,但小程序要求代码量最大12M,还得分好几个包,一个echart插件就将近1M,要是只做一张表或几张表实在浪费,况且小程序的加载速度与程序包大小也是息息相关的。因此写这系列文章,目的是降低程序包大小,又能实现需要的图表。
上篇文章微信小程序之图表系列——一步步用canvas实现柱状图制作了柱状图,做完之后不管对制作图表还是canvas都会有一个新的认识,这篇文章做个练习,制作一下饼状图,同时还要再增加一个点击效果,因为毕竟很多图表是需要与用户交互的。
上效果:

体验路径:

实现思路:
1、与柱状图一样,本质上还是通过计算参数用canvas画,只不过这次需要用到canvas的arc方法,画圆弧,再构成扇形
2、点击效果就需要监听touch方法,也是通过计算判断点击在哪个扇形区域,从而重新绘制

代码:
js

Page({/*** 页面的初始数据*/data: {canvasInfo: {},dataList: [{title: "男",value: 3,background: "#b8f2e6"}, {title: "女",value: 8,background: "#ffa69e"}, {title: "未知",value: 9,background: "#f7db70"}],pieInfo: {}},/*** 生命周期函数--监听页面加载*/onLoad: function(options) {this.messureCanvas()},messureCanvas() {let query = wx.createSelectorQuery().in(this);// 然后逐个取出navbar和header的节点信息// 选择器的语法与jQuery语法相同query.select('#pieCanvas').boundingClientRect();// 执行上面所指定的请求,结果会按照顺序存放于一个数组中,在callback的第一个参数中返回var that = thisquery.exec((res) => {// 分别取出navbar和header的高度 console.log(res)var canvasInfo = {}canvasInfo.width = res[0].widthcanvasInfo.height = res[0].heightthat.setData({canvasInfo: canvasInfo})console.log(canvasInfo)that.drawPie(-1)})},drawPie(index) {const ctxPie = wx.createCanvasContext("pieCanvas")var canvasInfo = this.data.canvasInfovar dataList = this.data.dataListvar pieInfo = this.data.pieInfovar pieRadius = (canvasInfo.width - 90) / 4pieInfo.pieRadius = pieRadiusvar pieX = 30 + pieRadiuspieInfo.centerX = pieXvar pieY = 30 + pieRadiuspieInfo.centerY = pieYvar totalValue = 0for (var i = 0; i < dataList.length; i++) {totalValue = totalValue + dataList[i].value}var area = []for (var i = 0; i < dataList.length; i++) {var areaItem = {}ctxPie.beginPath()var start = 0for (var j = 0; j < i; j++) {start = start + dataList[j].value}if (i < dataList.length - 1) {if(index==i){ctxPie.arc(pieX, pieY, pieRadius+5, start / totalValue * 2 * Math.PI, (start + dataList[i].value) / totalValue * 2 * Math.PI)}else{ctxPie.arc(pieX, pieY, pieRadius, start / totalValue * 2 * Math.PI, (start + dataList[i].value) / totalValue * 2 * Math.PI)}areaItem.start = start / totalValue * 2 * Math.PIareaItem.end = (start + dataList[i].value) / totalValue * 2 * Math.PI} else {if(index == i){ctxPie.arc(pieX, pieY, pieRadius+5, start / totalValue * 2 * Math.PI, 2 * Math.PI)}else{ctxPie.arc(pieX, pieY, pieRadius, start / totalValue * 2 * Math.PI, 2 * Math.PI)}areaItem.start = start / totalValue * 2 * Math.PIareaItem.end = 2 * Math.PI}area.push(areaItem)ctxPie.lineTo(pieX, pieY);ctxPie.setFillStyle(dataList[i].background);ctxPie.fill();ctxPie.closePath();//绘制标注var startX = 2 * pieRadius + 60var startY = (30 + pieRadius) - 30 * dataList.length / 2 + i * 30ctxPie.setFillStyle(dataList[i].background)ctxPie.fillRect(startX, startY, 20, 20)ctxPie.setFillStyle('#8a8a8a')ctxPie.setFontSize(12)ctxPie.fillText(dataList[i].title, startX + 30, startY + 15)ctxPie.fillText(dataList[i].value + "", startX + 70, startY + 15)ctxPie.fillText(parseInt(dataList[i].value * 100 / totalValue) + "%" + "", startX + 100, startY + 15)}pieInfo.area = areathis.data.pieInfo = pieInfoconsole.log(this.data.pieInfo)ctxPie.draw()},touchStart(e) {var pieInfo = this.data.pieInfovar x = e.touches[0].xvar y = e.touches[0].yif ((Math.pow(x - pieInfo.centerX, 2) + Math.pow(y - pieInfo.centerY, 2)) > Math.pow(pieInfo.pieRadius, 2)) {console.log("在圆外,不执行")return}var pointPos = 0console.log("在圆内,继续执行")var angle = Math.atan((y - pieInfo.centerY) / (x - pieInfo.centerX)) / (Math.PI / 180)//判断角度值if (x > pieInfo.centerX) {if (angle > 0) {pointPos = angle / 180 * Math.PI} else {pointPos = angle / 180 * Math.PI + 2 * Math.PI}} else {if (angle > 0) {pointPos = angle / 180 * Math.PI + Math.PI} else {pointPos = angle / 180 * Math.PI + Math.PI}}var index = 0for(var i = 0;i<pieInfo.area.length;i++){if(pointPos>pieInfo.area[i].start&&pointPos<pieInfo.area[i].end){index = i}}console.log("在第"+index+"个区域")this.drawPie(index)},
})

wxml

<view class="container"><canvas style="width:100%;height:350px;margin-top:20px;" canvas-id="pieCanvas" id="pieCanvas" bindtouchstart="touchStart"></canvas>
</view>

微信小程序之图表系列——canvas绘制饼状图,带点击效果相关推荐

  1. uni-app 之canvas绘制饼状图

    uni-app 之canvas绘制饼状图 一开始,对于canvas我是拒绝的,后来,我发现我爱上了它,像爱上小哥哥一样~~ 说起canvas,是css3新增的标签.而饼状图又是canvas经典,我们公 ...

  2. 第166天:canvas绘制饼状图动画

    canvas绘制饼状图动画 1.HTML 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 < ...

  3. 微信小程序之图表系列——最简单的表格制作

    一图胜千言,相信很多开发者都没有绕开过图表制作这个坑,在小程序中也是,当然可以用第三方echart等制图插件来做,但小程序要求代码量最大12M,还得分好几个包,一个echart插件就将近1M,要是只做 ...

  4. 微信小程序-wx-charts 图表插件

    微信小程序图表插件(wx-charts)基于canvas绘制,体积小巧,支持图表类型饼图.线图.柱状图 .区域图等图表图形绘制. 支持图标类型 饼图 pie 圆环图 ring 线图 line 柱状图 ...

  5. 微信小程序 F2 图表组件

    @antv/f2-canvas 微信小程序 F2 图表组件 安装 npm i @antv/f2-canvas 快速开始 下面我们就开始使用 f2-canvas 组件来绘制图表吧,这里假设用户已经初步了 ...

  6. [转]微信小程序之购物车 —— 微信小程序实战商城系列(5)

    本文转自:http://blog.csdn.net/michael_ouyang/article/details/70755892 续上一篇的文章:微信小程序之商品属性分类  -- 微信小程序实战商城 ...

  7. 微信小程序--放入个性化手绘地图具体步骤(腾讯地图)

    微信小程序–放入个性化手绘地图具体步骤(腾讯地图) 前言:小程序中想要实现个性化手绘地图需要通过H5嵌入的模式进行实现. 1.首先需要一个腾讯地图的账号(微信登录即可),然后选择个性化地图进入(htt ...

  8. 微信小程序之仿淘宝分类入口 —— 微信小程序实战商城系列(2)

    分类入口,已经成为了商城项目必须的布局之一,这里以仿照淘宝的分类入口来做案例 下图红框部分,就是本文重点讲解部分,另外本文并没有写点击某个入口跳转页面. 如需学习页面跳转的同学,可以参考此文 微信小程 ...

  9. 微信小程序子组件使用canvas无效,线条画不出颜色

    微信小程序子组件使用canvas无效,线条画不出颜色 小程序中在page中直接使用canvas是这样使用的: // canvas 全局配置 var context = null; Page({data ...

最新文章

  1. 【uva10829-求形如UVU的串的个数】后缀数组+rmq or 直接for水过
  2. 网站结构优化——不能忽视的优化重点
  3. 密码学 / 哈希算法
  4. js json制表符报错_JS自学_常见错误复盘
  5. cisco无线网络实施方案
  6. 豆瓣网络爬虫-java网络爬虫[验证码模拟登陆]详细介绍
  7. Struts2+Spring+Hibernate搭建全解!
  8. XDeepFM高阶特征交互,特征交互:一种极深因子分解机模型
  9. [转载] python eval序列化函数
  10. win10任务栏透明_几款软件让你的 Win10 与众不同(简洁篇)
  11. 计算机需要那些高中数学知识点,高中必考数学知识点归纳整理
  12. windows cmd 提示 ‘系统找不到指定路径‘ 提示 ‘ECHO 处于关闭状态‘
  13. WinISO5.3的注册码吧
  14. Linux操作系统引导过程及MBR扇区故障解决
  15. win10系统word2019显示目录只显示部分一级二级解决办法
  16. Ubuntu16.04中文输入法安装初战
  17. 拼多多API接口大全
  18. 详解2.5G/5G/10G Base-T以太网接口物理层一致性测试!
  19. HTTP服务(超文本传输协议)
  20. 开源C++单元测试框架Google Test介绍

热门文章

  1. 用Python语言巧妙的实现对WIFI密码的破解
  2. List集合与Set集合学习笔记
  3. vscode关闭C++红色波浪线
  4. Linux___压缩解压命令__11
  5. 2022年AI 技术成熟度曲线发布!
  6. 数据结构:树和二叉树 思维导图
  7. 真正统治世界的十大算法(转)
  8. mojito 脚本编写
  9. 视博云虚拟现实制造业技术创新战略联盟共创VR产业新未来!
  10. 【微课制作软件】Focusky教程 | 支持同时打开多个文档并相互复制粘贴