微信小程序canvas绘制曲线图表
先上图 不能耽误大家时间。由于也是才入手小程序 很多不会代码有点乱 看官些能用就用不能用就看看哈。
view代码
<view class="efficacy"><!-- 曲线 --><view class="chartsBox"><view style="display:flex;justify-content: space-between;"><view class="efficacyName" style="color:{{curve.lineColor}}">{{curve.name}}<view style="background:{{curve.lineColor}}"></view></view></view><view class="canvasBox"><scroll-view class="temp_day_box" scroll-x bindscroll='scrollCanvas'><canvas canvas-id='curveCanvas' id='curveCanvas' class='curveCanvas'> </canvas><canvas canvas-id='lines' id='lines' class='lines'> </canvas><view class="xCoordinate" bindtap="getZuoBiao" ><view class="xCoordinateTime{{index}} xCoordinateTime" wx:for="{{curve.date}}" wx:key="index" data-index="{{index}}" >{{item}}<!-- 分数提示线 --><cover-view class="scoreTip" wx-if="{{numShiow&&index==tipIndex}}"><cover-view class="scoreBg" style="height:{{144}}px;"><cover-view class="score" style="top:-{{180-tipHeight}}px;color:{{curve.lineColor}}">{{score}}</cover-view><cover-view class="scoreBox" style="top:-{{174-tipHeight}}px;background:{{curve.lineColor}}"></cover-view></cover-view><cover-view class="scoreLine" style="height:{{190-tipHeight}}px;background:{{curve.lineColor}}"></cover-view></cover-view></view></view></scroll-view></view></view>
</view>
css代码
/* pages/curveCharts/curveCharts.wxss *//* pages/experience/tests/tests.wxss */
.efficacy{/* width: 100%; *//* height: 1000px; */background: #eef7fe;padding:30rpx;
}
/* 曲线 */
.efficacyName {color: #e2c162;font-size: 26rpx;font-weight: bold;display: flex;margin-bottom: 30rpx;line-height: 30rpx;
}.efficacyName>view {width: 26rpx;height: 26rpx;margin-left: 10rpx;border-radius: 4rpx;
}
.chartsBox{position: relative;width: 100%;margin-bottom:40rpx;
}
.canvasBox{width:690rpx;height:420rpx;position: relative;background: #fff;border-radius: 30rpx;box-shadow: 0 10px 15px rgba(0,0,0,0.1);overflow: auto;overflow-y:hidden;/* overflow-x:scroll; */
}
.curveCanvas{/* width:100%; */width:450px;height:500rpx;position: relative;left: -10px;top: -28px;
}
.xCoordinate{position: absolute;top: 0;/* left:30rpx; */display: flex;/* width: 690rpx; */height: 100%;overflow: auto;
}
.xCoordinateTime{padding-left:4rpx;font-size:20rpx;color: #fff;/* color: red; */width: 98rpx;
}
.lines{/* width:100%; */width:450px;position: absolute;top: -21px;left: -10px;
}
canvas{width:none;height: none;
}
.scoreTip{position: absolute;
top:0;
height:345rpx;
}
.scoreBg{width:80rpx;height:170rpx;background: rgba(255, 255, 255, 0.8);display: flex;flex-direction: column;align-items: center;justify-content: flex-end;position: relative;
}
.score{color: #d2b567;font-size: 20rpx;position: relative;bottom: 10rpx;top: 10rpx;
}
.scoreBox{width: 12rpx;height: 12rpx;background:#d2b567;border-radius: 50%;position: relative;bottom: 10rpx;top: 10rpx;
}
.scoreLine{width:8rpx;height:119px;background:#d2b567;border-radius:3rpx;position: absolute;left:0;right: 0;bottom:8rpx;
margin:auto;
}
js代码
// pages/experience/tests/tests.js
let curve = {mW: 345, //canvas宽mH: 250, //canvas高mCenter: 180, //中心点hCenter: 125, //中心点points: []
};
Page({/*** 页面的初始数据*/data: {// 数字提示numShiow: false,tipLeft: 0, //提示的x坐标tipHeight: 0, //提示线条的高度curveColText: ['100', '80', '60', '40', '20', '0'], //y轴// 主要数据curve: {bgColor: "#fcede0",date: ["09-08", "09-09", "09-11", "09-12", "09-14", "09-16", "09-17", "09-18", "09-28"],lineColor: "#f9d3b5",list: [62, 67, 76, 70, 76, 85, 85, 88, 57],name: "肤色",xData: [],},tipIndex: 0,whatShow: false,getshow: false,},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {let {curveColText } = this.data //y坐标let {bgColor,date,lineColor,list,xData } = this.data.curve //y坐标let curveCanvas = wx.createCanvasContext('curveCanvas');let lines = wx.createCanvasContext('lines');this.drawLines(list, lines);this.drawCurve(curveCanvas, curveColText, date, list, xData, lineColor, bgColor);},// gundongscrollCanvas: function (e) {console.log(e);let index = e.currentTarget.dataset.indexvar canvasLen = e.detail.scrollLeft;this.setData({indexScroll: index,canvasLen: canvasLen})},/*** 生命周期函数--监听页面初次渲染完成*/onReady: function () {},// 获取坐标getZuoBiao(e) {let indexs = e.currentTarget.dataset.indexslet index = e.target.dataset.indexlet x = e.detail.xthis.setData({tipIndexs: indexs,tipIndex: index})console.log(e)let tipHeight =this.data.curve.xData[index].ylet tipLeft =this.data.curve.xData[index].xconsole.log('x坐标',x)console.log(tipHeight)this.setData({numShiow: true,tipLeft:tipLeft-10,tipHeight:tipHeight})let score = this.data.curve.list[index]console.log(this.data.curve.list[index])console.log(this.data.curve.date[index])this.setData({score: score,})},/*** 生命周期函数--监听页面显示*/onShow: function () {},//// 曲线drawCurve(curveCtx, curveColText, curveText, curveData, xData, LineColor, colorEnd) {this.drawLineBg(curveCtx); //画横纵坐标框架this.drawLineColText(curveColText, curveCtx); //绘制纵坐标文字this.drawLineRowText(curveText, curveCtx, xData); //绘制横坐标文字this.drawCurveCtx(curveData, curveCtx, xData, LineColor, colorEnd); //绘制曲线curveCtx.draw();},// 阴影drawLines(curveData, curveCtx) {this.drawCurveCtxs(curveData, curveCtx); //绘制曲线curveCtx.draw();},drawCurveCtx(mData, lineCtx, xData, LineColor, colorEnd) {curve.points = [];for (let i = 0; i < mData.length; i++) {curve.points.push({x: 29.5 + i * 52,y: 200 - mData[i] / 100 * 150});}this.drawCurvePath(curve.points, lineCtx, LineColor, colorEnd);// 获取y轴做线条高度curve.points.forEach((v, i) => {xData[i].y = v.y})},// 阴影drawCurveCtxs(mData, lineCtx) {curve.points = [];for (let i = 0; i < mData.length; i++) {curve.points.push({x: 29.5 + i * 52,y: 200 - mData[i] / 100 * 150});}this.drawCurvePaths(curve.points, lineCtx);},// 绘制曲线背景drawCurvePath(path, ctx, LineColor, colorEnd) {var point = getControlPoint(path);ctx.beginPath();const grd = ctx.createLinearGradient(174, 180, 200, 0);grd.addColorStop(0, '#ffffff');grd.addColorStop(0.8, colorEnd);grd.addColorStop(1, colorEnd);ctx.setFillStyle(grd);ctx.setGlobalAlpha(0.8);ctx.beginPath();ctx.moveTo(29, 200);ctx.lineTo(curve.points[0].x, curve.points[0].y);var int = 0;for (let i = 0; i < curve.points.length; i++) {if (i == 0) {ctx.quadraticCurveTo(point[0].x, point[0].y, curve.points[1].x, curve.points[1].y);int = int + 1;} else if (i < curve.points.length - 2) {ctx.bezierCurveTo(point[int].x, point[int].y, point[int + 1].x, point[int + 1].y, curve.points[i + 1].x, curve.points[i + 1].y);int += 2;} else if (i == curve.points.length - 2) {ctx.quadraticCurveTo(point[point.length - 1].x, point[point.length - 1].y, curve.points[curve.points.length - 1].x, curve.points[curve.points.length - 1].y);}}ctx.lineTo(curve.points[curve.points.length - 1].x, 200);ctx.fill();ctx.closePath();this.drawCurveSign(point, ctx, LineColor)},// 绘制点加线drawCurveSign(point, ctx, LineColor) {// 绘制线ctx.beginPath();ctx.setStrokeStyle(LineColor);ctx.setGlobalAlpha(1);ctx.setLineWidth(4);var int = 0;ctx.moveTo(curve.points[0].x - 20, curve.points[0].y);for (var i = 0; i < curve.points.length; i++) {if (i == 0) {ctx.quadraticCurveTo(point[0].x, point[0].y, curve.points[1].x, curve.points[1].y);int = int + 1;} else if (i < curve.points.length - 2) {ctx.bezierCurveTo(point[int].x, point[int].y, point[int + 1].x, point[int + 1].y, curve.points[i + 1].x, curve.points[i + 1].y);int += 2;} else if (i == curve.points.length - 2) {ctx.quadraticCurveTo(point[point.length - 1].x, point[point.length - 1].y, curve.points[curve.points.length - 1].x, curve.points[curve.points.length - 1].y);}}ctx.stroke();// 绘制点// ctx.beginPath();// ctx.setGlobalAlpha(1);// for (let i = 0; i < curve.points.length; i++) {// ctx.beginPath();// ctx.arc(curve.points[i].x, curve.points[i].y, 5, 0, 2 * Math.PI);// console.log('点',curve.points[i].x, curve.points[i].y, 5, 0, 2 * Math.PI)// ctx.setFillStyle("#3388FF");// ctx.fill();// ctx.closePath();// }},// 阴影// 绘制曲线背景drawCurvePaths(path, ctx) {var point = getControlPoint(path);ctx.beginPath();this.drawCurveSigns(point, ctx)},drawCurveSigns(point, ctx) {// 绘制线ctx.beginPath();ctx.setStrokeStyle("rgba(0,0,0,0.05)");// ctx.setStrokeStyle("red");ctx.setGlobalAlpha(1);ctx.setLineWidth(4);var int = 0;ctx.moveTo(curve.points[0].x - 20, curve.points[0].y);for (var i = 0; i < curve.points.length; i++) {if (i == 0) {ctx.quadraticCurveTo(point[0].x, point[0].y, curve.points[1].x, curve.points[1].y);int = int + 1;} else if (i < curve.points.length - 2) {ctx.bezierCurveTo(point[int].x, point[int].y, point[int + 1].x, point[int + 1].y, curve.points[i + 1].x, curve.points[i + 1].y);int += 2;} else if (i == curve.points.length - 2) {ctx.quadraticCurveTo(point[point.length - 1].x, point[point.length - 1].y, curve.points[curve.points.length - 1].x, curve.points[curve.points.length - 1].y);}}ctx.stroke();},// 画横坐标drawLineBg(lineCtx) {lineCtx.setStrokeStyle("#fff");for (let i = 0; i < 6; i++) {lineCtx.moveTo(curve.mCenter - 160, 50 + 30 * i);lineCtx.lineTo(curve.mCenter + 160, 50 + 30 * i);lineCtx.stroke();}},// 绘制横坐标文字drawLineRowText(mData, lineCtx, xData) {lineCtx.setFillStyle("#333");lineCtx.setFontSize(12); //设置字体for (let i = 0; i < mData.length; i++) {if (mData.length >= 3 && mData[1] != '') {lineCtx.fillText(mData[i], 20 + i * 49, 220);xData.push({tiem: mData[i],x: 20 + i * 49,y: 0})// lineCtx.fillText(mData[i][1], 15 + i * 65, 235);} else if (mData[1] == '') {// 数据小于等于2的时候的坐标lineCtx.fillText(mData[i], 60 + i * 90, 220);// lineCtx.fillText(mData[i][1], 35 + i * 80, 235);xData.push({tiem: mData[i],x: 20 + i * 49,y: 0})} else if (mData[2] == '') {// 数据小于等于1的时候的坐标lineCtx.fillText(mData[i], 20 + i * 90, 220);// lineCtx.fillText(mData[i][1], 35 + i * 80, 235);xData.push({tiem: mData[i],x: 20 + i * 49,y: 0})}}// this.setData({// xData: xData// })},// 绘制纵坐标文字drawLineColText(mData, lineCtx) {lineCtx.beginPath();lineCtx.setFillStyle("#fff");for (let i = 0; i < 6; i++) {lineCtx.fillText(mData[i], 10, 55 + 30 * i);}},/*** 生命周期函数--监听页面隐藏*/onHide: function () {},/*** 生命周期函数--监听页面卸载*/onUnload: function () {},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh: function () {},/*** 页面上拉触底事件的处理函数*/onReachBottom: function () {},/*** 用户点击右上角分享*/onShareAppMessage: function () {},// 日历// 日历onDayClick: function (event) {console.log(event.detail)wx.showToast({title: '日期被点击,具体信息请看Console信息',icon: 'none'})},onRangeComplete: function (event) {console.log(event.detail)var begin = new Date(event.detail.begin);var end = new Date(event.detail.end);// + ' ' + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds()var begintime = begin.getFullYear() + '-' + (begin.getMonth() + 1) + '-' + begin.getDate();var endtime = end.getFullYear() + '-' + (end.getMonth() + 1) + '-' + end.getDate();console.log(begintime)console.log(endtime)this.setData({beginDate: begintime,endDate: endtime})this.getJieGuo(begintime, endtime)},onMonthChange: function (event) {console.log(event.detail)wx.showToast({title: '月份变换,具体信息请看Console信息',icon: 'none'})},
})
// quxian
// 折线变曲线
let Vector2 = function (x, y) {this.x = x;this.y = y;
};
Vector2.prototype = {"length": function () {return Math.sqrt(this.x * this.x + this.y * this.y);},"normalize": function () {let inv = 1 / this.length() == Infinity ? 0 : 1 / this.length();return new Vector2(this.x * inv, this.y * inv);},"add": function (v) {return new Vector2(this.x + v.x, this.y + v.y);},"multiply": function (f) {return new Vector2(this.x * f, this.y * f);},"dot": function (v) {return this.x * v.x + this.y * v.y;},"angle": function (v) {return Math.acos(this.dot(v) / (this.length() * v.length())) * 180 / Math.PI;}
};function getControlPoint(path) {let rt = 0.3;let count = path.length - 2;let arr = [];for (let i = 0; i < count; i++) {let a = path[i];let b = path[i + 1];let c = path[i + 2];let v1 = new Vector2(a.x - b.x, a.y - b.y);let v2 = new Vector2(c.x - b.x, c.y - b.y);let v1Len = v1.length();let v2Len = v2.length();let centerV = v1.normalize().add(v2.normalize()).normalize();let ncp1 = new Vector2(centerV.y, centerV.x * -1);let ncp2 = new Vector2(centerV.y * -1, centerV.x);if (ncp1.angle(v1) < 90) {let p1 = ncp1.multiply(v1Len * rt).add(b);let p2 = ncp2.multiply(v2Len * rt).add(b);arr.push(p1, p2);} else {let p1 = ncp1.multiply(v2Len * rt).add(b);let p2 = ncp2.multiply(v1Len * rt).add(b);arr.push(p2, p1);}}return arr;
};
借鉴
完整代码块
微信小程序canvas绘制曲线图表相关推荐
- 微信小程序-canvas绘制文字实现自动换行
微信小程序-canvas绘制文字实现自动换行 在使用微信小程序canvas绘制文字时,时常会遇到这样的问题:因为canvasContext.fillText参数为 我们只能设置文本的最大宽度,这就产生 ...
- 微信 html 字体 自动换行,详解微信小程序-canvas绘制文字实现自动换行
在使用微信小程序canvas绘制文字时,时常会遇到这样的问题:因为canvascontext.filltext参数为 我们只能设置文本的最大宽度,这就产生一定的了问题.如果我们绘制的文本长度不确定或者 ...
- 微信小程序canvas绘制坐标图
这里是微信小程序项目中用到的canvas绘制柱状图.线图.饼状图,跟html里的canvas略微差别,不做详细介绍,仅做个记录防失忆啊,微lin 1.线图 function draw(data, ct ...
- 微信小程序Canvas绘制曲线图饼图柱状图雷达图蛛网图实现(附源码)
小程序绘制曲线图 <view class="container"><canvas canvas-id="lineCanvas" disable ...
- 微信小程序Canvas绘制主页保存到手机相册
本篇文章适用于保存用户主页.海报等至手机相册,内容包含圆角头像.文字超出显示省略号.多行超出显示省略号!(整体代码放入最下方可直接复制查看) 话不多说上图 页面如下 保存相册之后如下 整体分三部分来讲 ...
- 微信小程序Canvas绘制证件照底色,小程序Canvas绘图
小程序提供了Canvas绘图的API,我们很轻松就可以使用Canvas绘制一张图片并保存下来.本次案例使用绘制证件照的方式演示Canvas的示例. 准备 去掉背景的证件照(宽160px,高230px) ...
- 微信小程序canvas绘制插件
针对小程序新推出的canvas 2d api 简单封装了几个常用功能,用于应付日常海报快捷生成等用途. <canvas id="myCanvas" type="2d ...
- 微信小程序Canvas绘制图案(生成海报、朋友圈海报)
现在小程序生成海报是很常见的,例如生成打卡海报.生成文案.生成宣传图.生成推广图等,都是少不了一个技术,就是图片绘制,有些是通过前端Canvas绘制,有些是通过后端绘制,当然前端Canvas绘制是比较 ...
- 微信小程序canvas绘制环形图(含动画)
页面版 效果图 思路 1.使用一个canvas绘制(带动画): 2.通过画弧线,设置线宽,来实现圆环效果: 3.计算每段圆弧的起始角度和终止角度,用递归做动画: 绘制完第一段圆弧块–>再绘制下一 ...
最新文章
- 原码,反码,补码,移码的概念以及各自的用途和优点
- mysql导入数据表越来越慢,快速解决mysql导数据时,格式不对、导入慢、丢数据的问题...
- OpenCV与Qt:IplImage转换为QImage
- Win7下安装配置gVim
- 反转 鼠标_新版 Win10 中改变鼠标颜色
- C++ Primer Plus学习(十)——类和对象
- JAVA中Long与Integer
- Javascript:实现字符串replaceAll方法
- K3Cloud WebAPI 学习笔记:财务会计-总账-凭证
- matlab神经网络训练结果常用评价指标
- swagger常用注解
- Region Proposal Network
- 麦语言和python区别_放弃文华财经,自己编程实现期货程序化交易
- character not supported here
- 模拟狗狗的“魔鬼步伐”,比更真还更真
- 客2消,客1消,客0消...脉脉劝退客户端多次的你们究竟是何用意?
- Windows Shell 编程 第十章
- js 免费可靠cdn地址(富文本编辑器tinymce的实践)
- dock运行环境对linux的版本要求,Latte Dock 0.8发布,KDE Plasma 5.12或更高版本才能用...
- ISO 标准下载 网站