cover_image

uni-app微信小程序平台兼容常用图表库

陈建波 微医大前端技术
2022年07月07日 00:00
图片

作者:陈建波,微医前端技术部,喜欢唱、跳、rap!

前言

  从使用场景上来说,这篇更应该看作是如何在微信小程序中使用常用h5图表库 (antv/f2、echarts等) 。但是得益于uni-app的跨平台能力,能让我们使用更加熟悉的vue框架来实现微信小程序的开发。对于uni-app用户来说,如若使用图表能力,只能去dcloud社区插件 (https://ext.dcloud.net.cn/) 中搜寻,亦或是自己动手。下面来看一下,如何自己封装组件使用这些h5图表库。

antv/f2

  由于新的4.x版本使用的是jsx语法,不是很习惯。这里演示的是3.x (https://f2-v3.antv.vision/zh/docs/tutorial/getting-started) 版本。在官方文档中我们很容易发现:F2 是基于 CanvasRenderingContext2D (https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D) 的标准接口绘制的,所以只要能提供标准 CanvasRenderingContext2D 接口的实现对象,F2就能进行图表绘制。

  因为在小程序中给的 context 对象不是标准的 CanvasRenderingContext2D , 所以封装的核心思路是将 context 和 CanvasRenderingContext2D 对齐,所以 F2 针对支付宝和微信这2个常见的场景做了一层 context 的对齐,详情可见:https://github.com/antvis/f2-context,其他小程序也可以按同样的思路封装。

  当然微信小程序,f2已经兼容过,在使用的时候可以省略这一步。

  首先在src (基于vue-cli) 目录下components文件夹下新建组件f2-uni,在f2-uni.vue文件的template中添加。

<template>
  <canvas
    type="2d"
    class="f2-canvas"
    @touchstart="touchStart"
    @touchmove="touchMove"
    @touchend="touchEnd"
  >

  </canvas>

</template>

  给容器设定个宽高。

<style lang="less">
.f2-canvas {
  width100%;
  height: 600rpx;
}
</style>

  组件接收一个参数onInit,用来接收F2构造方法和config。

props: {
    onInit: {
      typeFunction,
      default() => {}
    }
  },

  注册组件初始化的时候调用方法,从这里也能看出,小程序与h5在dom操作时选择器方法的差别。

const query = uni.createSelectorQuery().in(this)
      query.select('.f2-canvas')
        .fields({
          nodetrue,
          sizetrue
        })
        .exec(res => {
          const { node, width, height } = res[0]
          const context = node.getContext('2d'// 微信基础库2.7.0 以上支持
          const pixelRatio = uni.getSystemInfoSync().pixelRatio
          // 高清设置
          node.width = width * pixelRatio
          node.height = height * pixelRatio

          const config = { context, width, height, pixelRatio }
          const chart = this.onInit(F2, config)
          if (chart) {
            this.canvasEl = chart.get('el')
          }
        })

  注:canvas.getContext 基础库2.7.0开始支持,如果对兼容性有要求可参考官方兼容处理 (https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html) 。

  touch事件处理 (其他两个同理) 。

function wrapEvent (e{
  if (!e) return
  if (!e.preventDefault) {
    e.preventDefault = function ({}
  }
  return e
}
touchStart (e) {
  const canvasEl = this.canvasEl
  if (!canvasEl) {
    return
  }
  canvasEl.dispatchEvent('touchstart', wrapEvent(e))
}

  至此组件主体封装已完成,在页面中使用。

    <f2-uni class="f2-chart" :onInit="onInitChart"></f2-uni>
methods: {
    onInitChart(F2Constructor, config) => {
      const chart = new F2Constructor.Chart(config)
      const data = [
        { value63.4city'New York'date'2011-10-01' },
        { value62.7city'Alaska'date'2011-10-01' },
        { value72.2city'Austin'date'2011-10-01' },
        { value58city'New York'date'2011-10-02' },
        { value59.9city'Alaska'date'2011-10-02' },
        { value67.7city'Austin'date'2011-10-02' },
        { value53.3city'New York'date'2011-10-03' },
        { value59.1city'Alaska'date'2011-10-03' },
        { value69.4city'Austin'date'2011-10-03' }
      ]
      chart.source(data, {
        date: {
          range: [01],
          type'timeCat',
          mask'MM-DD'
        },
        value: {
          max300,
          tickCount4
        }
      })
      chart.area().position('date*value').color('city').adjust('stack')
      chart.line().position('date*value').color('city').adjust('stack')
      chart.render()
      // 注意:需要把chart return 出来
      return chart
    }
  }
}

  成功渲染出示例图表。图片

  本文旨在提供思路,具体封装可以更加灵活易用。

  完整代码 (https://code.juejin.cn/pen/7113852538541047821) 。

echarts

  与上面同理,主要针对小程序的dom选择器和canvas context做一些兼容处理。具体封装可参考dcloud社区中一款不错的插件 echarts for uniapp(https://ext.dcloud.net.cn/plugin?id=8017)下载插件zip包,可查看源码。

  如果只在微信小程序平台编译使用,且条件编译不生效,我提炼了纯净版:代码片段 (https://code.juejin.cn/pen/7113871812777230372)。

图片图片


继续滑动看下一个
微医大前端技术
向上滑动看下一个