微信小程序简单的三次贝塞尔绘制坐标曲线图

样式效果

<canvas type="2d" id="columnar" style="width: 710rpx; height: 366rpx;"></canvas>
Page({

  /**
   * 页面的初始数据
   */
  data: {
    countForQuarterList:[],
    maxNuber:''
    
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
          let countForQuarterList = [[0, 0, 0, 0], [0, 1, 0, 0]];
          let arryzhi = [...countForQuarterList[0], ...countForQuarterList[1]]
          let maxNuber = Math.max(...arryzhi)
          this.setData({
            countForQuarterList,
            maxNuber
          })
          // 通过 SelectorQuery 获取 Canvas 节点
          wx.createSelectorQuery()
            .select('#columnar')
            .fields({
              node: true,
              size: true,
            })
            .exec(this.init.bind(this))
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
    
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {
    
  },
    //canvas方法
    init(useElectricity) {
      const width = useElectricity[0].width
      const height = useElectricity[0].height
      const canvas = useElectricity[0].node
      const ctx = canvas.getContext('2d')
      const dpr = wx.getSystemInfoSync().pixelRatio;
      const unit = wx.getSystemInfoSync().windowWidth / 375;
      canvas.width = width * dpr
      canvas.height = height * dpr
      ctx.scale(dpr, dpr)
      ctx.translate(0, 160 * unit);
      let xxx = [78.125, 154.375, 230.625, 306.875]
      let yyy = [0]
      // let dataList = [230, 350, 241, 190]//去年index0  this.data.countForQuarterList[0]
      let dataList = this.data.countForQuarterList[0] //去年index0  this.data.countForQuarterList[0]
      
      //let dataList2 = [130, 150, 141, 180]//今年index1 this.data.countForQuarterList[1]
      let dataList2 = this.data.countForQuarterList[1] //今年index1 this.data.countForQuarterList[1]
      if(dataList2.length<4){
        for(let a=dataList2.length;a<4;a++){
          dataList2[a]=0
        }
      }
      // if(Number(this.data.maxNuber)<5 ){
      //   this.data.maxNuber=5
      // }
      // let max = Math.max.apply(null, dataList)
      let max = this.data.maxNuber
      // if(max % 5!=0){
      //   max = max + (5 - max % 5)
      // }
      for (let i = 1; i < 6; i++) {
        yyy.push(((max / 5) * i).toFixed(2))
      }
      let dataListPoint = [];
      let dataListPoint2 = [];
      for (let j = 0; j < dataList.length; j++) {
        dataListPoint.push(dataList[j] * 150 / max)
      }
      for (let z = 0; z < dataList2.length; z++) {
        dataListPoint2.push(dataList2[z] * 150 / max)
      }
      //第一部分阴影
      ctx.beginPath();
      ctx.moveTo(xxx[0] * unit, 0 * unit);
      ctx.lineTo(xxx[0] * unit, -dataListPoint[0] * unit);
      ctx.bezierCurveTo((xxx[0] + 50) * unit, -dataListPoint[0] * unit, (xxx[1] - 50) * unit, -dataListPoint[1] * unit, xxx[1] * unit, -dataListPoint[1] * unit);
      for (let m = 1; m < 3; m++) {
        ctx.bezierCurveTo((xxx[m] + 50) * unit, -dataListPoint[m] * unit, (xxx[m + 1] - 50) * unit, -dataListPoint[m + 1] * unit, xxx[m + 1] * unit, -dataListPoint[m + 1] * unit);
        // ctx.lineTo(xxx[m] * unit, -dataListPoint[m] * unit);
      }
      ctx.lineTo(xxx[3] * unit, 0 * unit);
      ctx.lineTo(xxx[0] * unit, 0 * unit);
      ctx.closePath();
      let grd = ctx.createLinearGradient(0, 0, 0, -150);
      grd.addColorStop(0, "#FFFFFF");
      grd.addColorStop(1, "#516FEA"); //516FEA  D851EA
      ctx.fillStyle = grd;
      ctx.fill()
  
      //第二部分阴影
      ctx.beginPath();
      ctx.moveTo(xxx[0] * unit, 0 * unit);
      ctx.lineTo(xxx[0] * unit, -dataListPoint2[0] * unit);
      ctx.bezierCurveTo((xxx[0] + 50) * unit, -dataListPoint2[0] * unit, (xxx[1] - 50) * unit, -dataListPoint2[1] * unit, xxx[1] * unit, -dataListPoint2[1] * unit);
      for (let m = 1; m < 3; m++) {
        ctx.bezierCurveTo((xxx[m] + 50) * unit, -dataListPoint2[m] * unit, (xxx[m + 1] - 50) * unit, -dataListPoint2[m + 1] * unit, xxx[m + 1] * unit, -dataListPoint2[m + 1] * unit);
        // ctx.lineTo(xxx[m] * unit, -dataListPoint2[m] * unit);
      }
      ctx.lineTo(xxx[3] * unit, 0 * unit);
      ctx.closePath();
      let grd2 = ctx.createLinearGradient(0, 0, 0, -150);
      grd2.addColorStop(0, "#FFFFFF");
      grd2.addColorStop(1, "#D851EA"); //516FEA  D851EA
      ctx.fillStyle = grd2;
      ctx.fill()
  
  
  
  
  
      //第一部分曲线
      ctx.beginPath();
      ctx.moveTo(xxx[0] * unit, -dataListPoint[0] * unit);
      ctx.bezierCurveTo((xxx[0] + 50) * unit, -dataListPoint[0] * unit, (xxx[1] - 50) * unit, -dataListPoint[1] * unit, xxx[1] * unit, -dataListPoint[1] * unit);
      // ctx.bezierCurveTo(xxx[0] * unit, (-dataListPoint[0]-22) * unit, xxx[1] * unit, (-dataListPoint[1]-22) * unit, xxx[1] * unit, -dataListPoint[1] * unit);
      ctx.strokeStyle = '#FFFFFF'
      ctx.stroke()
      for (let k = 1; k < 3; k++) {
        ctx.bezierCurveTo((xxx[k] + 50) * unit, -dataListPoint[k] * unit, (xxx[k + 1] - 50) * unit, -dataListPoint[k + 1] * unit, xxx[k + 1] * unit, -dataListPoint[k + 1] * unit);
        // ctx.bezierCurveTo(xxx[k] * unit, xxx[k] * unit, cp2x, cp2y, x, y);
        // ctx.lineTo(xxx[k] * unit, -dataListPoint[k] * unit);
      }
      ctx.lineWidth = 2
      ctx.strokeStyle = '#444FF5'
      ctx.stroke()
  
      //第二部分曲线
      ctx.beginPath();
      ctx.moveTo(xxx[0] * unit, -dataListPoint2[0] * unit);
      ctx.bezierCurveTo((xxx[0] + 50) * unit, -dataListPoint2[0] * unit, (xxx[1] - 50) * unit, -dataListPoint2[1] * unit, xxx[1] * unit, -dataListPoint2[1] * unit);
      // ctx.bezierCurveTo(xxx[0] * unit, (-dataListPoint[0]-22) * unit, xxx[1] * unit, (-dataListPoint[1]-22) * unit, xxx[1] * unit, -dataListPoint[1] * unit);
      ctx.strokeStyle = '#FFFFFF';
      // ctx.stroke()
      for (let k = 1; k < 3; k++) {
        ctx.bezierCurveTo((xxx[k] + 50) * unit, -dataListPoint2[k] * unit, (xxx[k + 1] - 50) * unit, -dataListPoint2[k + 1] * unit, xxx[k + 1] * unit, -dataListPoint2[k + 1] * unit);
        // ctx.bezierCurveTo(xxx[k] * unit, xxx[k] * unit, cp2x, cp2y, x, y);
        // ctx.lineTo(xxx[k] * unit, -dataListPoint2[k] * unit);
      }
      ctx.lineWidth = 2
      ctx.strokeStyle = '#EE51F5'
      ctx.stroke()
  
      ctx.lineWidth = 1
      ctx.beginPath();
      ctx.moveTo(40 * unit, 0);
      ctx.lineTo(345 * unit, 0);
      // ctx.strokeStyle = '#9B9B9B'
      // ctx.stroke()
      // ctx.beginPath();
  
  
      ctx.moveTo(40 * unit, 0);
      ctx.lineTo(40 * unit, 5 * unit);
  
      ctx.moveTo(116.25 * unit, 0);
      ctx.lineTo(116.25 * unit, 5 * unit);
  
      ctx.moveTo(192.5 * unit, 0);
      ctx.lineTo(192.5 * unit, 5 * unit);
  
      ctx.moveTo(268.75 * unit, 0);
      ctx.lineTo(268.75 * unit, 5 * unit);
  
      ctx.moveTo(345 * unit, 0);
      ctx.lineTo(345 * unit, 5 * unit);
      ctx.strokeStyle = '#9B9B9B'
      ctx.stroke()
  
      //底部文字76.25间距
      ctx.fillStyle = "#9B9B9B";
      ctx.textAlign = "center";
      ctx.textBaseline = "middle";
  
      ctx.fillText(`1季度`, 78.125 * unit, 16 * unit);
      ctx.fillText(`2季度`, 154.375 * unit, 16 * unit);
      ctx.fillText(`3季度`, 230.625 * unit, 16 * unit);
      ctx.fillText(`4季度`, 306.875 * unit, 16 * unit);
  
      ctx.textAlign = "right";
      ctx.textBaseline = "middle";
      ctx.fillText(`${yyy[0]}`, 30 * unit, 0 * unit);
      ctx.fillText(`${yyy[1]}`, 30 * unit, -30 * unit);
      ctx.fillText(`${yyy[2]}`, 30 * unit, -60 * unit);
      ctx.fillText(`${yyy[3]}`, 30 * unit, -90 * unit);
      ctx.fillText(`${yyy[4]}`, 30 * unit, -120 * unit);
      ctx.fillText(`${yyy[5]}`, 30 * unit, -150 * unit);
  
      
  
    },
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值