Vue3 + Echarts堆叠折线图的tooltip不显示问题

问题介绍

使用Echarts在Vue3+Vite项目中绘制堆叠折线图的的时候,tooltip总是不显示,经过很长时间的排查和修改,最后发现是在使用上有错误导致的。

错误图片展示

问题原因

由于Vue3底层使用proxy代理创建示例,使用其创建出来的实例与Echarts真正使用的的实例存在兼容性问题,所以Echarts无法从中获取内部变量,所以在使用Echarts实例的时候,不要使用ref或reactive等响应式方法创建Echarts对象,应该使用shallowReactive、shallowRef或者普通变量。

导致问题代码

const chartInstance3 = ref(null); //定义店铺入驻明细图表实例化
const chartContainer3 = ref();

shallowReactive、shallowRef与reactive、ref的区别

API介绍
reactive
  • reactive用于将一个对象变成响应式的。它会深度遍历对象的属性,使其内部的所有属性也变为响应式的。因此,当你修改任何层级的属性时,都会触发依赖这些属性的组件的更新。
  • 它适用于那些结构复杂并且需要整个对象及其所有属性都是响应式的情况。
shallowReactive
  • shallowReactive同样用于将对象变成响应式的,但是它只会使对象的顶层属性响应式,而不会深入到对象的嵌套属性中。这意味着如果你有一个嵌套的对象,其内部的属性更改将不会触发响应性更新。
  • 这个API对于处理大型数据结构特别有用,因为它避免了深度遍历带来的性能开销。
ref
  • ref用于创建一个响应式的引用类型,它包装了一个基本类型值或一个复杂的类型。ref的值可以通过.value属性访问和修改。
  • ref可以用于任何数据类型,但是当它包装复杂类型(如对象或数组)时,整个ref对象本身仍然是响应式的,内部的复杂类型也会被转化为响应式类型(通过reactive)。
  • ref主要用于状态管理,尤其是那些需要在组件之间共享的状态。
shallowRef
  • shallowRefref相似,但它不会将内部的复杂类型转化为响应式类型。这意味着如果shallowRef的值是一个对象,那么这个对象的内部属性更改将不会触发响应性更新。
  • 这种行为在处理大型数据结构或外部库提供的对象时非常有用,因为它们可能不希望被Vue的响应系统所影响。

总结:

  • reactiveref都提供深度响应性,但ref还提供了一层额外的封装。
  • shallowReactiveshallowRef仅提供一层响应性,这对于性能敏感的应用或不需要深度响应性的数据结构很有用。

修改后的实现效果

修改后的代码

const chartInstance3 = shallowRef(null); //定义店铺入驻明细图表实例化
const chartContainer3 = shallowRef();

附完整代码

<template>
  <div
    ref="chartContainer3"
    style="width: 100%; height: 400px; margin-top: 20px"
  ></div>
</template>

<script setup>
import * as echarts from "echarts";
import { onMounted, onUnmounted, ref, shallowRef } from "vue";
import request from "@/utils/request";
import api from "@/api";
import formatTime from "@/utils/formatTime";
const chartInstance3 = shallowRef(null); //定义店铺入驻明细图表实例化
const chartContainer3 = shallowRef();

const ServiceCategoryList = ref([]); //店铺类别列表
// 获取所有店铺类别
const getShopCategory = async () => {
  const res = await request.get(api.getShopCategory);
  res.data.forEach((item) => {
    ServiceCategoryList.value.push({
      name: item.name,
      type: "line", //图标的类型,line:折线图
      // stack: "total",
      shopType: item.type,
      smooth: "true",
      data: [],
    });
  });
};
const shopList = ref([]); //入驻店铺列表
const startTime = ref(""); //入住店铺最早的创建时间
const endTime = new Date(); //当前时间
const dateArray = ref([]); //日期数组
// 创建时间列表
const createTimeList = (start, end) => {
  while (start <= end) {
    dateArray.value.push(start.toISOString().substring(0, 10)); // 只保留YYYY-MM-DD格式
    start.setDate(start.getDate() + 1); // 增加一天
  }
};
// 获取入驻平台的所有店铺
const getShopList = async () => {
  await request.get(api.shopList).then((res) => {
    res.data.forEach((item) => {
      item.createTime = formatTime(item.createTime).nohour;
      item.createTimeObj = new Date(item.createTime);
      shopList.value.push({
        shopName: item.shopName,
        createTime: item.createTime,
        shopType: item.shopType,
      });
    });
    // 使用sort方法对shopList按创建时间排序,并找出最早入驻的时间
    res.data.sort((a, b) => a.createTimeObj - b.createTimeObj);
    startTime.value = new Date(res.data[0].createTime);
    createTimeList(startTime.value, endTime); //生成时间列表
    // 将所有的店铺按照店铺类别进行分组
    const shopsGroupedByTypeAndTime = res.data.reduce((groups, shop) => {
      const shopType = shop.shopType;
      const shopTime = shop.createTime;
      // 如果还没有对应店铺类型的分组,则创建它
      if (!groups[shopType]) {
        groups[shopType] = {};
      }
      // 如果还没有对应时间的分组,则创建它
      if (!groups[shopType][shopTime]) {
        groups[shopType][shopTime] = 0;
      }
      // 将对应时间和类型的计数增加1
      groups[shopType][shopTime]++;
      return groups;
    }, {});
    ServiceCategoryList.value.forEach((item) => {
      if (shopsGroupedByTypeAndTime[item.shopType]) {
        item.data = shopsGroupedByTypeAndTime[item.shopType];
      }
      dateArray.value.forEach((date) => {
        if (!item.data[date]) {
          item.data[date] = 0;
        }
      });
      item.data = Object.entries(item.data)
        .sort(([keyA], [keyB]) => new Date(keyA) - new Date(keyB))
        .map(([key, value]) => value);
    });
  });
};
const setOptions3 = () => {
  chartInstance3.value.setOption({
    title: {
      text: "商家入驻数据明细",
    },
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "cross",
      },
    },
    legend: {
      data: ServiceCategoryList.value.map((item) => item.name),
    },
    grid: {
      left: "3%",
      right: "4%",
      bottom: "3%",
      containLabel: true,
    },
    xAxis: {
      type: "category",
      boundaryGap: false,
      data: dateArray.value,
    },
    yAxis: {
      type: "value",
    },
    series: [...ServiceCategoryList.value],
  });
};
onMounted(async () => {
  await getShopCategory();
  await getShopList();
  chartInstance3.value = echarts.init(chartContainer3.value);
  setOptions3();
});
onUnmounted(() => {
  // 组件卸载时销毁图表实例
  chartInstance3.value.dispose();
});
</script>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何监控员工电脑行为?(其实不难,这种方法先码住!)

你的企业有没有面临以下几种问题&#xff1a; 这些问题&#xff0c;不仅影响企业员工的工作效率&#xff0c;更给企业数据带来不少的安全隐患。为了解决这些问题&#xff0c;很多企业采用监控员工电脑行为来解决当下的问题。 但我们需要注意的是&#xff0c;正确的监控不仅可以…

【Oracle】实验三 Oracle数据库的创建和管理

【实验目的】 掌握Oracle数据库的创建方法使用DBCA创建数据库在数据库中装入SCOTT用户及其表 【实验内容】 使用DBCA创建数据库&#xff0c;名为MYDB&#xff0c;找到其初始化文件(文本型和服务器型文件都要找到)&#xff0c;查看各类默认位置并记录下来(包括物理文件所在目…

LabVIEW与ABB工业机器人据监控

​1. 前言 随着工业自动化的发展&#xff0c;工业机器人在制造业中的应用越来越广泛。为了实现对工业机器人的高效监控和控制&#xff0c;本文介绍了利用OPC&#xff08;OLE for Process Control&#xff09;服务器将ABB工业机器人与LabVIEW连接起来的解决方案。通过OPC服务器…

OpenCV和PIL进行前景提取

摘要 在图像处理和分析中&#xff0c;前景提取是一项关键技术&#xff0c;尤其是在计算机视觉和模式识别领域。本文介绍了一种结合OpenCV和PIL库的方法&#xff0c;实现在批量处理图像时有效提取前景并保留原始图像的EXIF数据。具体步骤包括从指定文件夹中读取图像&#xff0c…

TQZC706开发板教程:在ZC706+ADRV9009硬件平台运行ADI Linux

本教程使用2024-06-18的ADI镜像文件&#xff0c;创建ZC706ADRV9009的linux工程进行测试。 首先需要下载ADI的镜像文件下载地址如所示&#xff1a; https://wiki.analog.com/resources/tools-software/linux-software/adi-kuiper_images/release_notes#r2_patch_1 烧写完成后若…

JAVA毕业设计147—基于Java+Springboot的手机维修管理系统(源代码+数据库)

基于JavaSpringboot的手机维修管理系统(源代码数据库)147 一、系统介绍 本项目分为用户、管理员、维修员三种角色 1、用户&#xff1a; 注册、登录、新闻公告、售后申请、申请列表、意见反馈、个人信息、密码修改 2、管理员&#xff1a; 用户管理、用户管理、栏目管理、网…

SpringSecurity中文文档(Servlet Authorize HttpServletRequests)

Authorize HttpServletRequests SpringSecurity 允许您在请求级别对授权进行建模。例如&#xff0c;对于 Spring Security&#xff0c;可以说/admin 下的所有页面都需要一个权限&#xff0c;而其他所有页面只需要身份验证。 默认情况下&#xff0c;SpringSecurity 要求对每个…

6、Redis系统-数据结构-04-Hash

四、哈希表&#xff08;Hashtable&#xff09; 哈希表是一种高效的键值对数据结构&#xff0c;通过散列函数将键映射到表中的位置&#xff0c;实现快速的插入、删除和查找操作。Redis 广泛使用哈希表来实现 Hash 对象和数据库的键值存储。以下将从结构设计、哈希冲突与链式哈希…

快速测试electron环境是否安装成功

快速测试electron环境是否安装成功 测试代码正确运行的效果运行错误的效果v22.4.1 版本无法使用v20.15.1版本无法使用v18.20.4 版本无法使用 终极解决办法 测试代码 1.npx create-electron-app my-electron-app 2.cd my-electron-app 3.npm start 正确运行的效果 环境没问题…

Android系统设置kernel log level的方法

Android log相关文档索引&#xff1a; 使用ADB命令控制logcat日志本地存储功能-CSDN博客 Android系统通过属性设置来控制log输出的方案-CSDN博客 Android系统设置kernel log level的方法-CSDN博客 Android系统设置kernel log level的方法 背景 kernel log内容过多/过少会影…

oak相机使用oak官网方式标定

目录 一、depthai ROS驱动 一、depthai ROS驱动 &#xff08;1&#xff09;驱动下载地址&#xff1a;2. C 开发快速上手 — DepthAI Docs 0.3.0.0 documentation sudo apt install ./depthai_2.17.1_arm64.deb //运行 Python3 utilities/cam_test.py -mres 400 -cams rgb,m …

Wireshark 对 https 请求抓包并展示为明文

文章目录 1、目标2、环境准备3、Wireshark 基本使用4、操作步骤4.1、彻底关闭 Chrome 进程4.2、配置 SSLKEYLOGFILE [核心步骤]4.3、把文件路径配置到 Wireshark 指定位置4.4、在浏览器发起请求4.5、抓包配置4.6、过滤4.6.1、过滤域名 http.host contains "baidu.com4.6.2…

AIGC时代创意设计师从“创作”向“智作”升级

随着人工智能技术的飞速发展&#xff0c;AIGC&#xff08;AI Generated Content&#xff0c;即人工智能生成内容&#xff09;时代已经到来&#xff0c;为创意设计领域带来了前所未有的变革。在这一时代背景下&#xff0c;创意设计师们正经历着从传统的“创作”向“智作”的转型…

FreeRTOS 队列

队列是一种任务到任务、任务到中断、中断到任务数据交流的一种机制。在队列中可以存 储数量有限、大小固定的多个数据&#xff0c;队列中的每一个数据叫做队列项目&#xff0c;队列能够存储队列项 目的最大数量称为队列的长度&#xff0c;在创建队列的时候&#xff0c;就需要指…

html5——CSS基础选择器

目录 标签选择器 类选择器 id选择器 三种选择器优先级 标签指定式选择器 包含选择器 群组选择器 通配符选择器 Emmet语法&#xff08;扩展补充&#xff09; 标签选择器 HTML标签作为标签选择器的名称&#xff1a; <h1>…<h6>、<p>、<img/> 语…

在pycharm中使用jupyter

在pycharm中使用jupyter 前置条件&#xff1a;你的环境中应该有juptyer &#xff0c;没有的话 pip install jupyter 点击项目目录&#xff0c;右键->new->jupyter notebook 打开file settings 找到 jupyter server &#xff08;按照默认的用代理服务器就行&#xff09; P…

ollama + lobechat 搭建自己的多模型助手

背景 人工智能已经推出了快2年了&#xff0c;各种模型和插件&#xff0c;有渐渐变成熟的趋势&#xff0c;打造一个类似 hao123网站的人工智能模型入口&#xff0c;也变得有需求了。用户会去比较多个ai给出的答案&#xff0c;作为程序员想拥有一台自己的GPU服务器来为自己服务。…

react启用mobx @decorators装饰器语法

react如果没有经过配置&#xff0c;直接使用decorators装饰器语法会报错&#xff1a; Support for the experimental syntax ‘decorators’ isn’t currently enabled 因为react默认是不支持装饰器语法&#xff0c;需要做一些配置来启用装饰器语法。 step1: 在 tsconfig.js…

always块敏感列表的相关报错,

在综合的时候&#xff0c;报错如下 Synthesis synth_1 [Synth 8-91] ambiguous clock in event control ["E:/FPGA/FPGA_project/handwrite_fft/handwrite_fft.srcs/sources_1/new/reg_s2p.v":140] 猜测报错原因&#xff08;暂时没有时间寻找原因&#xff0c;后续在…

【linux】服务器卸载cuda

【linux】服务器卸载cuda 文章目录 【linux】服务器卸载cuda1、查找已安装的 CUDA 包&#xff1a;2、卸载 CUDA&#xff1a;3、删除残留文件4、更新系统的包索引&#xff1a;5、检查是否卸载干净&#xff1a; 1、查找已安装的 CUDA 包&#xff1a; dpkg -l | grep cuda2、卸载…