先上图 不能耽误大家时间。由于也是才入手小程序 很多不会代码有点乱 看官些能用就用不能用就看看哈。

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绘制曲线图表相关推荐

  1. 微信小程序-canvas绘制文字实现自动换行

    微信小程序-canvas绘制文字实现自动换行 在使用微信小程序canvas绘制文字时,时常会遇到这样的问题:因为canvasContext.fillText参数为 我们只能设置文本的最大宽度,这就产生 ...

  2. 微信 html 字体 自动换行,详解微信小程序-canvas绘制文字实现自动换行

    在使用微信小程序canvas绘制文字时,时常会遇到这样的问题:因为canvascontext.filltext参数为 我们只能设置文本的最大宽度,这就产生一定的了问题.如果我们绘制的文本长度不确定或者 ...

  3. 微信小程序canvas绘制坐标图

    这里是微信小程序项目中用到的canvas绘制柱状图.线图.饼状图,跟html里的canvas略微差别,不做详细介绍,仅做个记录防失忆啊,微lin 1.线图 function draw(data, ct ...

  4. 微信小程序Canvas绘制曲线图饼图柱状图雷达图蛛网图实现(附源码)

    小程序绘制曲线图 <view class="container"><canvas canvas-id="lineCanvas" disable ...

  5. 微信小程序Canvas绘制主页保存到手机相册

    本篇文章适用于保存用户主页.海报等至手机相册,内容包含圆角头像.文字超出显示省略号.多行超出显示省略号!(整体代码放入最下方可直接复制查看) 话不多说上图 页面如下 保存相册之后如下 整体分三部分来讲 ...

  6. 微信小程序Canvas绘制证件照底色,小程序Canvas绘图

    小程序提供了Canvas绘图的API,我们很轻松就可以使用Canvas绘制一张图片并保存下来.本次案例使用绘制证件照的方式演示Canvas的示例. 准备 去掉背景的证件照(宽160px,高230px) ...

  7. 微信小程序canvas绘制插件

    针对小程序新推出的canvas 2d api 简单封装了几个常用功能,用于应付日常海报快捷生成等用途. <canvas id="myCanvas" type="2d ...

  8. 微信小程序Canvas绘制图案(生成海报、朋友圈海报)

    现在小程序生成海报是很常见的,例如生成打卡海报.生成文案.生成宣传图.生成推广图等,都是少不了一个技术,就是图片绘制,有些是通过前端Canvas绘制,有些是通过后端绘制,当然前端Canvas绘制是比较 ...

  9. 微信小程序canvas绘制环形图(含动画)

    页面版 效果图 思路 1.使用一个canvas绘制(带动画): 2.通过画弧线,设置线宽,来实现圆环效果: 3.计算每段圆弧的起始角度和终止角度,用递归做动画: 绘制完第一段圆弧块–>再绘制下一 ...

最新文章

  1. 原码,反码,补码,移码的概念以及各自的用途和优点
  2. mysql导入数据表越来越慢,快速解决mysql导数据时,格式不对、导入慢、丢数据的问题...
  3. OpenCV与Qt:IplImage转换为QImage
  4. Win7下安装配置gVim
  5. 反转 鼠标_新版 Win10 中改变鼠标颜色
  6. C++ Primer Plus学习(十)——类和对象
  7. JAVA中Long与Integer
  8. Javascript:实现字符串replaceAll方法
  9. K3Cloud WebAPI 学习笔记:财务会计-总账-凭证
  10. matlab神经网络训练结果常用评价指标
  11. swagger常用注解
  12. Region Proposal Network
  13. 麦语言和python区别_放弃文华财经,自己编程实现期货程序化交易
  14. character not supported here
  15. 模拟狗狗的“魔鬼步伐”,比更真还更真
  16. 客2消,客1消,客0消...脉脉劝退客户端多次的你们究竟是何用意?
  17. Windows Shell 编程 第十章
  18. js 免费可靠cdn地址(富文本编辑器tinymce的实践)
  19. dock运行环境对linux的版本要求,Latte Dock 0.8发布,KDE Plasma 5.12或更高版本才能用...
  20. ISO 标准下载 网站

热门文章

  1. ajax请求封装,封装的ajax请求
  2. OpenCV之图像对比度、亮度值调整
  3. 自学方法|明确学习的出发点【可能的阶梯】
  4. highlight.js使用探索
  5. AC97,i2S,HD-AUDIO接口的声卡,输出是什么?
  6. 纪念第一届cccc天梯赛
  7. Redis管理工具(Redis Assistant)更新啦
  8. 基于D2Admin 简化模板自己做的前端系统 (一)
  9. C语言——用函数实现模块化设计
  10. python for-Python for死循环