Taro+Vue3 小程序引入echarts表

news2024/9/24 19:22:40

背景:根据需求在一个报告界面需要展示不同的echarts表来使数据更友好的显示。

效果如下:

一.taro支持echarts

官方说明:Taro 文档支持引用小程序端第三方组件库

物料文档:Taro 物料市场 | 让每一个轮子产生价值

二.引入echarts-for-weixin插件

github地址: https://github.com/ecomfe/echarts-for-weixin

只引入ec-canvas文件夹下的wx-canvas.js

三.自定义 下载echarts

地址: https://echarts.apache.org/zh/builder.html

可自行选择版本,笔者测试了5.3.3和5.4.1都支持

下载后得到echarts.min.js

请根据需要自行选择需要的图表打包下载,我只选了默认的饼图、柱图、线图;
注意点:折线图中如果需要显示面积图的平均线,则要下载对应的标线组件。

经过三、四步骤之后会得到两个文件,目录结构如下:

四.封装组件ec-canvas.vue

<template>
  <canvas
    type="2d"
    class="ec-canvas"
    :class="canvasId" // 多个echarts时将canvasId作为唯一标识,动态获取canvasId用于多个                                                                           echarts可同时显示
    :canvas-id="canvasId"
    @touchStart="touchStart"
    @touchMove="touchMove"
    @touchEnd="touchEnd"
  ></canvas>
</template>

<script lang="js">
import Taro from "@tarojs/taro";
import WxCanvas from "./wx-canvas";
import * as echarts from "./echarts-5.4.1.min";

export default {
  name: "EcCanvas",
  props: {
    canvasId: {
      type: String,
      default: ""
    },
    ec: {
      type: Object,
      default: null
    }
  },
  mounted() {
    echarts.registerPreprocessor(option => {
      if (option && option.series) {
        if (option.series.length > 0) {
          option.series.forEach(series => {
            series.progressive = 0;
          });
        } else if (typeof option.series === "object") {
          option.series.progressive = 0;
        }
      }
    });
    if (!this.ec) {
      console.warn(
        '组件需绑定 ec 变量,例:<ec-canvas id="mychart-dom-bar" ' +
        'canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>'
      );
      return;
    }
    if (!this.ec.lazyLoad) {
      this.init();
    }
  },
  methods: {
    init(callback) {
      this.initByNewWay(callback);
    },
    initByNewWay(callback) {
      const query = Taro.createSelectorQuery();
      query
        .select(`.${this.canvasId}`) // 根据canvasId动态获取不同的echarts图表
        .fields({
          node: true,
          size: true
        })
        .exec(res => {
          if (!res || res.length == 0 || res[0] == null || res[0].node == null) {
            console.error('未获取到canvas的dom节点,请确认在页面渲染完成后或节点,taro中页面渲染完成的生命周期是useReady');
            return
          }
          const canvasNode = res[0].node;
          // this.canvasNode = canvasNode;

          const canvasDpr = Taro.getSystemInfoSync().pixelRatio;
          const canvasWidth = res[0].width;
          const canvasHeight = res[0].height;

          const ctx = canvasNode.getContext("2d");

          const canvas = new WxCanvas(ctx, this.canvasId, true, canvasNode);
          echarts.setCanvasCreator(() => {
            return canvas;
          });

          if (typeof callback === "function") {
            this.chart = callback(canvas, canvasWidth, canvasHeight, canvasDpr);
          } else if (typeof this.ec.onInit === "function") {

            this.chart = this.ec.onInit(
              canvas,
              canvasWidth,
              canvasHeight,
              canvasDpr
            );
          } else {

            this.triggerEvent('init', {
              canvas: canvas,
              width: canvasWidth,
              height: canvasHeight,
              dpr: canvasDpr
            })
          }
        });
    },
    canvasToTempFilePath(opt) {
      const query = Taro.createSelectorQuery().in(this);
      query
        .select(".ec-canvas")
        .fields({
          node: true,
          size: true
        })
        .exec(res => {
          const canvasNode = res[0].node;
          opt.canvas = canvasNode;
          Taro.canvasToTempFilePath(opt);
        });
    },
    touchStart(e) {
      if (this.chart && e.touches.length > 0) {
        var touch = e.touches[0];
        var handler = this.chart.getZr().handler;
        handler.dispatch("mousedown", {
          zrX: touch.x,
          zrY: touch.y
        });
        handler.dispatch("mousemove", {
          zrX: touch.x,
          zrY: touch.y
        });
        handler.processGesture(this.wrapTouch(e), "start");
      }
    },
    touchMove(e) {
      if (this.chart && e.touches.length > 0) {
        var touch = e.touches[0];
        var handler = this.chart.getZr().handler;
        handler.dispatch("mousemove", {
          zrX: touch.x,
          zrY: touch.y
        });
        handler.processGesture(this.wrapTouch(e), "change");
      }
    },
    touchEnd(e) {
      if (this.chart) {
        const touch = e.changedTouches ? e.changedTouches[0] : {};
        var handler = this.chart.getZr().handler;
        handler.dispatch("mouseup", {
          zrX: touch.x,
          zrY: touch.y
        });
        handler.dispatch("click", {
          zrX: touch.x,
          zrY: touch.y
        });
        handler.processGesture(this.wrapTouch(e), "end");
      }
    },
    wrapTouch(event) {
      for (let i = 0; i < event.touches.length; ++i) {
        const touch = event.touches[i];
        touch.offsetX = touch.x;
        touch.offsetY = touch.y;
      }
      return event;
    }
  }
};
</script>

<style>
.ec-canvas {
  width: 100%;
  min-height: 400rpx;
  flex: 1;
}
</style>

 五.封装e-chart.vue组件

<template>
  <ec-canvas ref="ecCanvasRef" :canvas-id="canvasId" :ec="ec"></ec-canvas>
</template>

<script lang="js">
/**
 * 自定义下载的echarts.min.js 文件  要使用需使用js,ts需要声明文件
 * 此组件不能使用setup语法糖,会报错的.
 */
import Taro, { useLoad } from "@tarojs/taro";
import * as echarts from './ec-canvas/echarts-5.4.1.min'
import EcCanvas from './ec-canvas/ec-canvas.vue'
import { ref, reactive } from "vue";
export default {
    components: {
        EcCanvas
    },
    props: {
        canvasId: {
            type: String,
            default: ''
        }
    },
    setup(props, { expose }) {
        const ec = reactive({
            lazyLoad: true
        })
        const ecCanvasRef = ref(null);

        const refresh = (options) => {
            if (!ecCanvasRef.value) {
                console.error('ecCanvas未获取到dom');
                return
            }
            ecCanvasRef.value?.init((canvas, width, height, canvasDpr) => {
                const chart = echarts.init(canvas, null, {
                    width: width,
                    height: height,
                    devicePixelRatio: canvasDpr
                })
                canvas.setChart(chart);
                chart.setOption(options);
                return chart;
            })
        }

        expose({
            refresh,
        })
        return {// 返回值会暴露给模板和其他的选项式 API 钩子
            ec, ecCanvasRef
        }
    },
}
</script>

六.使用封装的组件

此时封装的目录结构如下:

子组件:

<template>
  <view class="cards bg-white mx-sm mt-mm">
    <view class="text-center pt-xs pb-mm">
      <text class="text-md text-dark ml-sm">借贷分析</text>
    </view>
   
    <cover-view class="container-echarts">
      <e-chart ref="barChat" canvas-id="bar-canvas" />
    </cover-view>
  </view>
</template>
<script lang="ts">
export default { name: 'loanAnalysis' };
</script>

<script lang="ts" setup>
import Taro, { useReady } from '@tarojs/taro';
import { ref } from 'vue';
import EChart from '../components/echarts/e-chart.vue';
import { getLoanView } from '@/service/report';
import { MoneyNoUnitText, FormatThousand } from '@/units/currency';

const components = { 'e-chart': EChart };

const props = defineProps({
  params: { type: Object, required: true }
});

useReady(() => {
  initMultiBarChart();
});
const barChat = ref<any>();
let loanAmount = ref<number>();
let repaymentLoanAmount = ref<number>();
let prototypeOption = {
  grid: { left: 14, right: 18, bottom: 8, top: 40, containLabel: true },
  legend: { show: false },
  color: ['#40a9ff', '#FF5652'],
  xAxis: [
    {
      type: 'category',
      data: [],
      axisLabel: { fontSize: 10, color: 'rgba(0, 0, 0, 0.56)' },
      axisLine: { show: false },
      axisTick: { show: false }
    }
  ],
  yAxis: [
    {
      type: 'value',
      name: '万元',
      nameTextStyle: { padding: [0, 40, 0, 0], color: 'rgba(0,0,0,0.56)' },
      axisLabel: { fontSize: 10, color: 'rgba(0, 0, 0, 0.56)' },
      axisLine: { show: false },
      axisTick: { show: false },
      splitNumber: 2
    }
  ],
  series: [
    {
      name: '贷款、借款流入',
      type: 'bar',
      data: [],
      barMaxWidth: 12,
      barMinHeight: 1,
      stack: 'cr',
      itemStyle: {
        barBorderRadius: [0, 2, 0, 0]
      }
    },
    {
      name: '偿还贷款、借款',
      type: 'bar',
      data: [],
      barMaxWidth: 12,
      barMinHeight: 1,
      stack: 'cr',
      itemStyle: {
        barBorderRadius: [0, 0, 0, 2]
      }
    }
  ]
};

const initMultiBarChart = () => {
  getLoanView(props.params).then(res => {
    if (res) {
      loanAmount.value = MoneyNoUnitText(res.loanAmount || 0);
      repaymentLoanAmount.value = MoneyNoUnitText(res.repaymentLoanAmount || 0);

      prototypeOption.xAxis[0].data = res.list.map(
        i => i.dateId.toString().slice(2, 4) + '.' + i.dateId.toString().slice(4)
      );
      prototypeOption.yAxis[0].axisLabel = {
        formatter: (v: any) => (Math.abs(v) > 0 ? FormatThousand(parseInt(v / 10000), 0) : v),
        color: 'rgba(0, 0, 0, 0.56)'
      };
      prototypeOption.series[0].data = res.list.map(i => (i.loanAmount > 0 ? i.loanAmount : null));
      prototypeOption.series[1].data = res.list.map(i =>
        i.repaymentLoanAmount > 0 ? -i.repaymentLoanAmount : null
      );

      Taro.nextTick(() => {
        barChat.value.refresh(prototypeOption);
      });
    }
  });
};
</script>

<style>
.container-echarts {
  height: 400rpx;
  width: 100%;
}
</style>

父组件引用子组件:

import loanAnalysis from './loan-analysis.vue';

 <loan-analysis :params="params"></loan-analysis>



【 问题描述 】在小程序使用echarts,图表展示出来之后不跟随页面滚动,浮在最上方。
【 问题原因 】布局中含有position:fixed或absulote的元素,导致echarts图表无法滑动。
官方文件说明:canvas为原生组件故有一下的性质: bash 由于原生组件脱离在 WebView 
渲染流程外,因此在使用时有以下限制: 组件的层级是最高的,所以页面中的其他组件无论设置
 z-index 为多少,都无法盖在原生组件上。 后插入的原生组件可以覆盖之前的原生组件。 
原生组件还无法在 scroll-view、swiper、picker-view、movable-view 中使用。 
部分CSS样式无法应用于原生组件,例如: 无法对原生组件设置 CSS 动画 无法定义
原生组件为 position: fixed 不能在父级节点使用 overflow:hidden 来裁剪
原生组件的显示区域
【 解决方法 】所有父级元素(有包含ec-canvas的所有view元素)的position不可为
fixed或absulote,将其改为其他,另外兄弟元素可以为position:absulote或fixed,
否在还是会有重叠

原文链接:https://blog.csdn.net/samscat/article/details/126182735

 参考博文:Taro3+Vue3使用echarts_taro使用echarts_江渚清沨的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/430818.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt5.12實戰之Linux靜態庫編譯與調用完整過程

1.安裝gedit sudo apt-get install gedit -y 2.使用gedit編輯靜態庫源文件test.cpp gedit test.cpp 輸入下面內容 &#xff1a; #include <stdio.h> int func() {return 888; } 如下圖操作&#xff1a; 保存test.cpp並編譯 爲目標文件 gcc -c test.cpp如下圖示&am…

【剑指 Offer】(1)

文章目录前言一、 数组中重复的数字:fire: 解决方法:dog: 代码二、二维数组中的查找:fire:思路:dog:代码三、替换空格:fire:思路:dog: 代码四、从尾到头打印链表:fire:思路:dog:代码:dog: 代码五、重建二叉树:fire:思路:dog: 代码总结前言 剑指offer系列是一本非常著名的面试题…

【BUG SHOW】一个由高并发引起的缺陷分析

软件质量保障: 所寫即所思&#xff5c;一个阿里质量人对测试的所感所悟。 缺陷介绍 平台有这样的两个功能&#xff1a; ​功能01: 用户发起支付&#xff0c;成功则将表pay单据状态推进SUCCESS&#xff0c;然后发出支付结果消息&#xff1b;反之如果支付失败&#xff0c;则状态…

vue 报错 error:03000086:digital envelope routines::initialization error解决方案

目录 1. 引言: 2. 更换版本出现问题: 3. 出现原因: 4. 解决办法: -> 4. 1 删了 再换回16.15版本 -> 4.2 指令修改(好使) ---> 4.2.1效果如图 -> 4.3 其他指令就别试了 压根不好使 1. 引言: npm出现问题 , 卸载后 装了个新node 18.15版本 2. 更换版本…

Servlet-搭建个人博客系统(MVC架构模式简介,maven的配置和使用)

目录 1. MVC架构模式简介 2. maven的配置和使用 3. 项目总述&#x1f43b; 3.1 &#x1f34e;Controller层 3.2 &#x1f34e;Model层 3.3 &#x1f34e;View层 4. 页面的主要功能实现&#x1f43b; 4.1 &#x1f34e;登陆页面&#xff08;login.html&#xff09; 4.2…

Oracle Recovery Tools快速恢复断电引起的无法正常启动数据库----惜分飞

由于异常断电,数据库启动报错ORA-01113和ORA-01110&#xff0c;ORA-00322和ORA-00312以及ORA-00314和ORA-00312错误 Mon Apr 17 09:35:04 2023 ALTER DATABASE OPEN Errors in file D:\APP\ADMINISTRATOR\diag\rdbms\orcl\orcl\trace\orcl_ora_10192.trc: ORA-01113: 文件 1 需…

史上最牛二分查找,不服来战

&#x1f929;本文作者&#xff1a;大家好&#xff0c;我是paperjie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 &#x1f970;内容专栏&#xff1a;这里是《算法详解》&#xff0c;笔者用重金(时间和精力)打造&#xff0c;将算法知识一网打尽&#xff0c;希望可以…

音视频-ffplay的音视频同步

最近自己在做一个视频播放器&#xff0c;渲染视频帧时有些疑惑&#xff0c;所以特意来学习一下ffplay中是如何处理视频帧的渲染的&#xff01;&#x1f60a; 我自己最初的理解是这样 1、只关心视频本身的时间戳&#xff0c;不考虑音视频同步以及其他的同步时钟&#xff0c;或…

写了那么久的文章,现在才改回来!

大家好&#xff0c;我是即兴小索奇&#xff0c;最近在阅读文章时发现了自己文章的一个缺陷&#xff0c;就记录下来并分享给大家&#xff0c;大家写文章时也可以借鉴。 这是我以前写的的文章&#xff0c;light亮色下显示正常 -当我不经意间把手机调成深色模式阅读文章时&#xf…

Leetcode912.排序数组(三路划分)

文章目录 一、三路划分二、Leetcode912.排序数组 一、三路划分 为何还会有三路划分&#xff1f; 快速排序算法在某个数据大量重复时效率极低&#xff0c;在运行程序时会超出时间限制&#xff0c;为了解决数据大量重复的情况下&#xff0c;三路划分诞生了。三路划分是基于快速排…

第五回:如何使用ListView Widget

文章目录概念介绍使用方法示例代码我们在上一章回中介绍了Container Widget,本章回中将介绍 ListView这种Widget&#xff0c;闲话休提&#xff0c;让我们一起Talk Flutter吧。概念介绍 ListView就是一个滚动的列表&#xff0c;它可以看作是在Column的基础上添加了滚动功能&…

WPS表格查找替换技巧:让你的工作效率翻倍

WPS表格中查找和替换是最基础的操作&#xff0c;看似简单&#xff0c;但是还有很多人在工作中不会熟练使用&#xff0c;其实掌握一些小技巧可以快速提高工作效率&#xff0c;本节课就来介绍几种比较有效的“查找和替换技巧”。 本节课目录&#xff1a; 1、常规的查找和替换 2…

AIGC市场群雄逐鹿,阿里云发出了什么大招?

如果要评选当下IT圈最火爆的话题&#xff0c;相信就算生成式AI&#xff08;Artificial Intelligence Generated Content&#xff0c;简称AIGC&#xff09;甘认第二&#xff0c;也没有人敢认第一。于是我们看到&#xff0c;在ChatGPT快速升级迭代的同时&#xff0c;百度、360、商…

基于树莓派的智能家居控制系统设计论文参考

完整论文咨询可WX联系&#xff1a;gyf1842965496 智能家居控制系统功能实现详细介绍&#xff1a;基于树莓派的智能家居控制系统设计https://blog.csdn.net/G1842965496/article/details/125491350#comments_26030679 目录 论文简述 摘要 随着科技的进步&#xff0c;人们生活水…

DAY 37 shell免交互

Here Document 概述 常用的交互程序&#xff1a;read&#xff0c;ftp&#xff0c;passwd&#xff0c;su&#xff0c;sudo cat也可配合免交互的方式重定向输出到文件 Here Document 的作用 使用I/O重定向的方式将命令列表提供给交互式程序标准输入的一种替代品 格式 命令 &…

创建部署你的第一个智能合约

原文参考地址 【Web3 开发系列教程—创建你的第一个智能合约&#xff08;2&#xff09;】部署第一个智能合约&#xff0c;增加自己的内容 如果你是区块链开发的新手并且不知道从哪里开始&#xff0c;或者你只是想了解如何部署智能合约并与之交互&#xff0c;那么本指南适合你。…

大数据技术(入门篇)--- 使用Spring Boot 操作 CDH6.2.0 Spark SQL进行离线计算

前言 CDH 6.2.0 搭建的环境&#xff0c;并不能直接使用 spark 相关资源&#xff0c;需要对此服务端环境进行一些修改Spark 目前仅支持 JDK1.8, Java项目运行环境只能使用JDK 1.8我这里使用的是 CDH6.2.0集群&#xff0c;因此使用的依赖为CDH专用依赖&#xff0c;需要先添加仓库…

跨平台开发工具怎么选?IDE工具推荐

软件开发工具链的价值&#xff0c;越来越多企业看到了它。近年来&#xff0c;国内也迎来了软件开发工具的自主化浪潮&#xff0c;今天就来跟大家盘点一下2023年十大移动开发IDE工具。 一、Android Studio 作为Android开发IDE工具的首选&#xff0c;Android Studio提供了一个全…

API7 助力头部券商实现数字化转型

背景 随着中国经济步入高质量发展阶段&#xff0c;数字化转型正在被更多的企业提上议程。2021 年证监会出台的《证券期货行业科技发展“十四五”规划》中指出&#xff0c;需“提升证券期货业数据治理水平”&#xff0c;“深化数字化转型标准建设&#xff0c;推动行业数据接口的…

涨点神器:Yolov8引入CVPR2023 InternImage:注入新机制,扩展DCNv3,助力涨点,COCO新纪录65.4mAP!

1.InternImage介绍 论文:https://arxiv.org/abs/2211.05778 代码:GitHub - OpenGVLab/InternImage: [CVPR 2023 Highlight] InternImage: Exploring Large-Scale Vision Foundation Models with Deformable Convolutions 理论部分参考知乎:CVPR2023 Highlight | 书生模型霸…