前置机上如何地址转换_canvas原生层级较高,遮盖自定义tabbar,转换为图片解决...

f5b2b4aaf33127efe4a1dabc95d62684.png

本文章基于wepy编写

(1)问题描述:

微信小程序用echarts画统计图;在微信调试工具中,无问题;真机上出现统计图浮在底部自定义tabbar上,并且小程序中使用的第三方dropmenu的遮盖层也无法遮挡;安卓机上tabbar可点击,ios上tabbar不可点击。

(2)解决方法:

将canvas转换成图片

(3)具体实现:

封装一个生成柱状图组件

1.首先按照echats文档,生成柱状图,部分代码如下所示

// echart标签
<ec-canvas class="chart" canvas-id="{{canvasId}}" ec="{{ ec }}" bind:init="echartInit"></ec-canvas>
//data中定义ec对象
data = {      
 ec: {},      
 }
// 初始化时调用函数
echartInit(e) {                 
    this.initChart(e.detail.canvas, e.detail.width, e.detail.height)            
  }
initChart(canvas, width, height) {
      const chart = echarts.init(canvas, null, {
        width: width,
        height: height
      })
      canvas.setChart(chart)
      const option = {....}
      chart.setOption(option)
      return chart
}

2.将生成的柱状图转化为图片

调用微信的wx.canvasToTempFilePath方法,该方法需要传入canvasId,最初我直接传入的ec-canvas中我写入的canvasId,wx.canvasToTempFilePath方法始终fail,原生的canvas直接传canvasId可正确生成。

个人理解:wx.canvasToTempFilePath中需要的canvasId是canvas中的this,因为echarts是二次封装过的,所以,我们需要去echarts封装的源文件中将this暴露出来。

找到,你项目中导入的echarts的ec-canvas.js文件,修改init方法,在所有返回结果中,加上返回this,如下图

395398925afd550da065f8a4e5b4fb45.png

然后在data中定以一个变量接收echarts暴露出来的this

 data = {
      ec: {},
      radarImg: '', // 保存转换后的图片地址
      canvasThis: null //保存生成canvas的this
    }

在ec-cavas的init调用的echartInit方法中获取this

async echartInit(e) {
        this.canvasThis = e.detail.this
        await this.initChart(e.detail.canvas, e.detail.width, e.detail.height)
        // 初始化时,便生成图片
        if (this.toImg) {
          this.saveCanvasImg(this.canvasThis)
        }
      }
saveCanvasImg(e) {
      wx.canvasToTempFilePath({
        x: 0,
        y: 0,
        canvasId: this.canvasId,
        success: (res) => {
          this.radarImg = res.tempFilePath
          this.$apply()
        },
        fail(p) {
          console.log('p', p)
        }
      }, e)
    }

由于我的项目中,需要选择时间重新绘图,我还提供了重新生成canvas的方法

events= {
      'saveCanvasImg': async (type) => {
        // 判断要生成canvas还是生成img
        if (type === 'canvas') {
          this.radarImg = ''
        } else {
          this.saveCanvasImg(this.canvasThis)
        }
      }
    }
父组件中需要生成canvas时调用this.$broadcast('saveCanvasImg', 'canvas')

封装的echarts柱状图完整代码:

<!--
组件使用

 父组件传值:
 import组件-》注册组件
 <barChart :chartData="barChartData"></barChart>
 'width'、'height',可父组件传值设置,类型为string,带单位
 barChartData: {
        xAxis: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
        series: [120, 200, 150, 80, 70, 110, 130]
      }
-->

<style lang="less">
  .bar__chart {
    margin: 0 auto;
  }
</style>
<template>
  <view class="page">
    <view wx:if="{{!radarImg}}" class="bar__chart" style="width:{{ width }};height: {{height}};background-color: {{color}}">
      <ec-canvas class="chart" canvas-id="{{canvasId}}" ec="{{ ec }}" bind:init="echartInit"></ec-canvas>
    </view>
    <view wx:else class="bar__chart">
      <image src="{{radarImg}}" class="bar__chart" style="width:{{ width }};height: {{height}};background-color: {{color}}"></image>
    </view>
  </view>
</template>

<script>
  import wepy from 'wepy'
  import echarts from '../ec-canvas/echarts.js'

  export default class BarChart extends wepy.component {
    config = {
      navigationBarTitleText: 'BarChart',
      usingComponents: {
      }
    }

    components = {}

    props = {
      width: {
        type: String,
        default: '100%'
      },
      height: {
        type: String,
        default: '355rpx'
      },
      color: {
        type: String,
        default: '#fff'
      },
      canvasId: {
        type: String,
        default: 'mychart-bar'
      },
      chartData: {
        type: Object,
        default: () => {
          return {}
        }
      },
      toImg: { // 父组件是否需要初始化时将canvas转为图片
        type: Boolean,
        default: false
      }
    }

    data = {
      ec: {},
      radarImg: '', // 保存转换后的图片地址
      canvasThis: null //保存生成canvas的this
    }

    computed = {}

    methods = {
      async echartInit(e) {
        this.canvasThis = e.detail.this
        await this.initChart(e.detail.canvas, e.detail.width, e.detail.height)
        if (this.toImg) {
          this.saveCanvasImg(this.canvasThis)
        }
      }
    }

    saveCanvasImg(e) {
      wx.canvasToTempFilePath({
        x: 0,
        y: 0,
        canvasId: this.canvasId,
        success: (res) => {
          this.radarImg = res.tempFilePath
          this.$apply()
        },
        fail(p) {
          console.log('p', p)
        }
      }, e)
    }

    initChart(canvas, width, height) {
      const chart = echarts.init(canvas, null, {
        width: width,
        height: height
      })
      canvas.setChart(chart)
      // option配置
      const option = {
        grid: {
          top: 30,
          left: '2%',
          right: '2%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          axisTick: {
            show: false
          },
          axisLine: {
            show: false
          },
          axisLabel: {
            interval: 0,
            textStyle: {
              color: '#a8a8a8'
            }
          },
          data: this.chartData.xAxis
        },
        yAxis: {
          type: 'value',
          axisTick: {
            show: false
          },
          axisLine: {
            show: false
          },
          splitLine: {
            lineStyle: {
              color: '#eee'
            }
          },
          axisLabel: {
            textStyle: {
              color: '#a8a8a8'
            }
          }
        },
        series: [{
          animation: false,
          itemStyle: {
            normal: {
              color: new echarts.graphic.LinearGradient(
                0, 0, 0, 1,
                [
                  {offset: 1, color: 'rgba(0,111,255,0.6)'},
                  {offset: 0, color: 'rgba(163,203,255,0.6)'}
                ]
              )
            },
            emphasis: {
              color: new echarts.graphic.LinearGradient(
                0, 0, 0, 1,
                [
                  {offset: 0, color: '#2378f7'},
                  {offset: 0.7, color: '#2378f7'},
                  {offset: 1, color: '#83bff6'}
                ]
              )
            }
          },
          label: {
            normal: {
              show: true,
              // rotate: 90,
              formatter: '{c}',
              fontSize: 12,
              color: '#fff'
            }
          },
          data: this.chartData.series,
          type: 'bar',
          barWidth: '50%'
        }]
      }

      chart.setOption(option, true)
      return chart
    }

    events= {
      'saveCanvasImg': async (type) => {
        // 判断要生成canvas还是生成img
        if (type === 'canvas') {
          this.radarImg = ''
        } else {
          this.saveCanvasImg(this.canvasThis)
        }
      }
    }

    onLoad() {
    }
  }
</script>

父组件引用样式

        // 柱状图组件使用
        <barChart
          wx:if="{{ staffAttendance.series && staffAttendance.series.length }}"
          :chartData.sync="staffAttendance"
          :toImg.sync="toImg"
        >
        </barChart>

        // 时间选择
        <picker mode="date" value="{{start_date}}"
                @change="handleChange">

// 引入组件
  import BarChart from '../components/public/barChart'
// 定义组件
  components = {
    barChart: BarChart  
  }
  data = {
    toImg: true,
    studentAttendance: {},
  }

父组件中调用样例:

// 改变时间时调用函数
handleChange(e) {
      // 将需要生成图的数据置空,不然柱状图组件数据不响应改变
      this.studentAttendance = {}
      this.$apply()
      this.selfAttendance()
    }

  async selfAttendance () {
    // 先将图片转化成canvas
    this.$broadcast('saveCanvasImg', 'canvas')
    // todo 调用接口获取生成统计图数据
    const res = await selfAttendance()
    if (res) {
      this.studentAttendance.xAxis = res.statistics.map(item => {
        return attendanceStatusFil[item.status]
      })
      this.studentAttendance.series = res.statistics.map(item => {
        return item.num
      })
    }
    wx.stopPullDownRefresh()
    this.$apply()
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值