美文网首页
微信小程序:自定义柱状图

微信小程序:自定义柱状图

作者: like26th | 来源:发表于2020-06-29 16:00 被阅读0次

    1
    EChart在某些配置较低的手机上出现无法交互的情况,换成自定义控件解决了这个问题。

    2
    新建一个自定义组件,布局如下
    wxml

    <view style="position:relative; background:#f6f6f6; border-radius:5px; padding-bottom:16rpx;">
        <!-- 统计图 -->
        <canvas type="2d" id="scatterCanvas"
                 bindtouchstart='touchstart' bindtouchmove='touchmove'
                 style="height:{{height}}rpx; width:{{width}}rpx;"></canvas>
        <!-- 提示条 -->
        <canvas type="2d" id="IndacatorCanvas" bindtouchstart='touchstart' bindtouchmove='touchmove' bindtouchend='touchend'
                style="position:absolute; left:0; top:0; height:{{height}}rpx; width:{{width}}rpx;"></canvas>
    </view>
    

    根据官方文档的说法,最好使用canvas2d进行绘制。


    canvas

    3
    js
    通过SelectorQuery获取canvas对象,这里的in方法用于获取自定义组件中的节点。

    wx.createSelectorQuery().in(context)
      .select('#id')
      .fields({
        node: true,
        size: true,
      }).exec(function(res){
        //doth
      }
    

    node属性用于获取节点实例,即canvas对象,size用于获取节点尺寸,就是canvas的宽高。这里有一个坑,通过节点获取到的画布宽高,仅仅是画布的宽高,想要在真机上正常显示,还需要获取手机的密度,并将画布的宽高乘以密度,canvasContext同样缩放屏幕密度倍数。

    mDpr = wx.getSystemInfoSync().pixelRatio
    
    let canvas = res[0].node
    let width = res[0].width
    let height = res[0].height
        
    canvas.width = width * mDpr
    canvas.height = height * mDpr
    
    let ctx = canvas.getContext('2d')
    ctx.scale(mDpr, mDpr)
    

    pixelRatio,官方说明为像素比,应该就是开发android时,1dp等于多少px。

    4
    绘制柱状图,其实并不复杂,统计图的要素就那么多。

    首先是标题,如果需要标题的话,那么就要在绘制标题时,就需要指定标题的样式,然后预留出标题周围需要的边距。然后可以把绘制标题的方法抽取一个单独的方法。

    /**
    * 绘制标题
    * @param {*} title 标题
    */
    function drawTitle(canvas, title) {
      canvas.textBaseline = 'top'
      canvas.fillStyle = '#666666'
      canvas.font = '14px Arial'
      canvas.textAlign = 'left'
      canvas.fillText(title, marginAround, marginAround)
    }
    

    坐标轴,确认坐标轴原点的位置,要考虑预留出坐标轴名称的位置,预留刻度名称的位置。

    function drawAxises(ctx) {
        ctx.strokeStyle = "#999999"
        ctx.beginPath()
        ctx.moveTo(mAxisOriginX, mAxisOriginY)
        ctx.lineTo(mAxisOriginEndX, mAxisOriginY)
        ctx.stroke()
    }
    

    当获取到数据时,绘制跟数据有关的部分,也就是刷新方法。

    /**
    * 刷新统计图
    */
    function refresh(index) {
      //见源码...
    }
    

    如果需要动态刷新,js的canvas需要把原有的画布内容清空,于是要有一个clear方法。

    /**
    * 清空一个canvas区域
    */
    function clearArea(canvas, left, top, width, height){
      canvas.clearRect(left, top, width, height)
    }
    

    5
    提示条canvas的要覆盖在统计图canvas上,同理要根据屏幕密度对画布进行调整。同时初始化一组跟统计图canvas同样的坐标系。
    绑定屏幕点击事件bindtouchastart,点击屏幕时记录点击的位置,显示提示条。

    showIndicator(){
        //见源码...
    }
    

    6
    当手指在屏幕上滑动时,监听事件bindtouchmove,根据滑动距离变化触发页面刷新,统计图canvas,提示条canvas根据需要,是否都需要刷新。

    function touchRefresh(isLeft){
      if(isLeft){
        //向左滑动
        if(mValueIndex >= (allAxisXValue.length - MAX_VALUE_COUNT)){return}
    
          ++mValueIndex
      } else {
        //向右滑动
        if (mValueIndex <= 0) {return}
    
        --mValueIndex
      }
    
      refresh(mValueIndex)
    }
    

    大致思路是这样,源码供参考。

    效果图

    相关文章

      网友评论

          本文标题:微信小程序:自定义柱状图

          本文链接:https://www.haomeiwen.com/subject/twbwfktx.html