微信小程序canvas组件横向溢出滚动(基于wx-charts)

公司要求在微信小程序里插入折线图,上网搜了下,发现wx-charts还挺好用的,就用他了。
wx-charts具体用法就不介绍了,网上有很多教程,还有不懂的可以留言讨论。折线图完成了,却发现了一个问题:展示数据长度不确定,导致如果数据很长的话,数据就会挤成一团,很不好看,如果长度较大,canvas能滚动就好了。
动态设置canvas宽度不难:获取数据长度,让canvas长度为数据长度乘以固定值,再获取屏幕宽度,如果canvas宽度小于屏幕宽度,让canvas宽度等于屏幕宽度:

width: windowWidth < simulationData.categories.length * 70 ? simulationData.categories.length * 70 : windowWidth

在web网页里,直接设置父元素固定宽度,子元素宽度超过父元素,让父元素overflow:auto;就行了,可是对微信小程序的canvas组件不起作用。
第一时间想到scroll-view组件,马上给view套上,在开发者工具里面预览ok,就以为完事大吉了,哪想真机测试滚动完全没反应,仔细查看api才发现:
微信小程序canvas组件横向溢出滚动(基于wx-charts)_第1张图片
原来scroll-view里不支持canvas,可是一定要canvas滚动怎么办呢?
研究发现,虽然canvas不会响应scroll-view的滚动,但是bindscroll方法是有返回值的:

<scroll-view class='canvas-container' scroll-x='{{true}}' bindscroll="scroll">
    <canvas canvas-id="lineCanvas" disable-scroll="true"></canvas>
</scroll-view>

scroll:function(e){
    console.log(e);//{type: "scroll", timeStamp: 2389, target: {…}, currentTarget: {…}, detail: {…}}
}

展开发现,e.detail里有个scrollLeft参数,是随滚动不断变化的,利用他就能实现,以下是代码:

wxml部分,此处也要动态设置canvas所在容器宽度,以及偏移量:

<scroll-view class='canvas-container' scroll-x='{{true}}' bindscroll="scroll">
  <view style='width:{{dataLength*70}}px;min-width:100%;translateX:-{{scrollLeft}}px'>
    <canvas style='width:{{dataLength*70}}px' canvas-id="lineCanvas" disable-scroll="true">canvas>
  view>
scroll-view>

css部分:

.canvas-container{
  width: 98%;
  height: 200px;
  overflow: auto
}
.canvas-container canvas{
  min-width: 100%;
  height: 200px;
}

js部分,因为wx-charts的touchHandler方法会和scroll-view的scroll方法冲突,只能舍弃:

var wxCharts = require('../../static/js/wxcharts.js');
var lineChart = null;
Page({
  data: {
  },
  // touchHandler: function (e) {
  //   console.log(lineChart.getCurrentDataIndex(e));
  //   lineChart.showToolTip(e, {
  //     // background: '#7cb5ec',
  //     format: function (item, category) {
  //       return category + ' ' + item.name + ':' + item.data
  //     }
  //   });
  // },
  scroll:function(e){
    console.log(e);
    var scrollLeft=e.detail.scrollLeft;
    this.setData({scrollLeft:scrollLeft})
  },
  createSimulationData: function () {
    var categories = [];
    var data = [];
    var dataLength = parseInt(Math.random() * 20);
    this.setData({
      dataLength:dataLength
    })
    for (var i = 0; i < dataLength; i++) {
      categories.push('第' + (i + 1)+'年');
      data.push(Math.random() * (20 - 10) + 10);
    }
    return {
      categories: categories,
      data: data
    }
  },
  onLoad: function (e) {
    var windowWidth = 320;
    try {
      var res = wx.getSystemInfoSync();
      windowWidth = res.windowWidth;
    } catch (e) {
      console.error('getSystemInfoSync failed!');
    }
    var simulationData = this.createSimulationData();
    if (windowWidth < simulationData.categories.length*70){
      windowWidth = simulationData.categories.length*70
    }
    console.log(this.data.dataLength);
    lineChart = new wxCharts({
      canvasId: 'lineCanvas',
      type: 'line',
      categories: simulationData.categories,
      legend:false,
      animation: true,
      // background: '#f5f5f5',
      series: [{
        name: '成交量1',
        data: simulationData.data,
        format: function (val, name) {
          return val.toFixed(2) + '万';
        }
      }],
      xAxis: {
        disableGrid: true
      },
      yAxis: {
        title: '成交金额 (万元)',
        format: function (val) {
          return val.toFixed(2);
        },
      },
      width: windowWidth,
      height: 200,
      dataLabel: true,
      dataPointShape: true,
      extra: {
        lineStyle: 'curve'
      }
    });
  }
});

如此,当数据较少时,canvas会全屏展示,不能滚动,当数据较多时,可以左右滚动。
不足之处:1、因为canvas的滚动是在滑动结束,获取到scrollLeft值之后的操作,所以滚动很生硬,不流畅;
2、不能使用wx-charts内置方法touchHandler。
如有哪位高手有好的解决办法,希望不吝赐教,本人感激不尽!

你可能感兴趣的:(微信小程序)