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

news2024/11/17 7:18:41

问题介绍

使用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>

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

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

相关文章

甘蔗基因组--文献精读30

A chromosomal-scale genome assembly of modern cultivated hybrid sugarcane provides insights into origination and evolution 现代栽培杂交甘蔗的染色体级基因组组装提供了起源和进化的洞见&#xff0c;确实甘蔗好几个基因组了~ 摘要 甘蔗是一种具有重要经济和工业价值…

提升论文质量和说服力的高阶技巧:数据驱动

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 今天分享的内容是“如何利用数据驱动的高阶技巧提升学术论文的深度与说服力”。从高级统计分析到机器学习&#xff0c;再到数据可视化和模型验证&#xff0c;我们将提供了一整套策略&am…

在Linux上搭建服务器之综合实验(web,dns,防火墙,SELinux)

其实验简图如下&#xff1a; 解读&#xff1a; 本实验需要完成4部分内容&#xff0c;web服务器的搭建&#xff0c;主从dns服务器的搭建&#xff0c;防火墙的开启&#xff0c;以及SELinux设置为强制模式。 首先dns主服务器上配置web服务&#xff08;其中我本机的IP为192.168.5.…

基于Android平台开发,仿头条新闻app

相关视频教程在某站上面(&#x1f50d;浩宇软件开发) 1. 项目模块功能思维导图 2. 项目涉及到的技术点 数据来源&#xff1a;聚合数据API使用okhttp网络请求框架获取api数据使用gson库解析json数据使用RecyclerViewadapter实现新闻列表使用SQLite数据库实现用户登录&#xff0…

数学建模·Topsis优劣解距离法

Topsis优劣解 一种新的评价方法&#xff0c;特点就是利用原有数据&#xff0c;客观性强。相较于模糊评价和层次评价 更加客观&#xff0c;充分利用原有数据&#xff0c;精确反映方案差距基本原理 离最优解最近&#xff0c;离最劣解越远具体步骤 正向化 代码与原理与熵权法…

防火墙第一次综合实验

DMZ区内的服务器&#xff0c;办公区仅能在办公时间内(9:00-18:00)可以访问&#xff0c;生产区的设备全天可以访问。 办公区设备10.8.2.1不允许访问DMZ区的FTP服务器和HTTP服务器&#xff0c;仅能ping通10.0.3.10 1.先建立拒绝BG到DMZ区的安全策略 2.建立BG到DMZ区的icmp允许 3…

探索 Electron:窗口菜单以及生命周期和对话框讲解

Electron是一个开源的桌面应用程序开发框架&#xff0c;它允许开发者使用Web技术&#xff08;如 HTML、CSS 和 JavaScript&#xff09;构建跨平台的桌面应用程序&#xff0c;它的出现极大地简化了桌面应用程序的开发流程&#xff0c;让更多的开发者能够利用已有的 Web 开发技能…

Linux文件编程(标准C库)

目录 一、标准C库打开/创建文件&#xff0c;读写文件&#xff0c;光标移动 二、标准C库写入结构体到文件 三、其他函数补充 1.fputc函数 2.feof函数和fgetc函数 前面讲到的open函数都是基于linux内核的&#xff0c;也就是说在Windows系统上无法运行&#xff0c;移植性比较…

shein测试开发会问些啥?

&#x1f3c6;本文收录于《CSDN问答解惑-》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

【thingsbord源码编译】 显示node内存不足

编译thingsbord显示报错 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory问题原因分析 重新安装java版本 编译通过

论文阅读【时空+大模型】ST-LLM(MDM2024)

论文阅读【时空大模型】ST-LLM&#xff08;MDM2024&#xff09; 论文链接&#xff1a;Spatial-Temporal Large Language Model for Traffic Prediction 代码仓库&#xff1a;https://github.com/ChenxiLiu-HNU/ST-LLM 发表于MDM2024&#xff08;Mobile Data Management&#xf…

无人机之遥控器保养

一、使用存放 1、避免让遥控器受到强烈的震动或从高处跌落&#xff0c;以免影响内部结构的精度&#xff1b; 2、遥控器在使用完后&#xff0c;需要将天线收拢&#xff0c;避免折断&#xff0c;养成定期检查天线的习惯&#xff1b; 3、定期检查遥控器按键有无裂纹、畸变、松旷…

跨境电商API的全球视野:打破地域限制,连接全球消费者与商家

在全球化日益加深的今天&#xff0c;跨境电商已成为推动全球经济一体化的重要力量。它不仅为消费者提供了前所未有的购物体验&#xff0c;让世界各地的商品触手可及&#xff0c;更为商家开辟了全新的市场蓝海&#xff0c;实现了业务的全球化拓展。在这一进程中&#xff0c;跨境…

PyTorch | 加速模型训练的妙招

引言 提升机器学习模型的训练速度是每位机器学习工程师的共同追求。训练速度的提升意味着实验周期的缩短&#xff0c;进而加速产品的迭代过程。同时&#xff0c;这也表示在进行单一模型训练时&#xff0c;所需的资源将会减少。简而言之&#xff0c;我们追求的是效率。 熟悉 PyT…

Rust代码优化的九大技巧

一.使用 Cargo 内置的性能分析工具 描述&#xff1a;Cargo 是 Rust 的包管理器&#xff0c;带有内置工具来分析代码性能&#xff0c;以识别性能瓶颈。 解释&#xff1a; 发布模式&#xff1a;在发布模式下编译启用优化&#xff0c;可以显著提高性能。 cargo build --release基…

解决vue多层弹框时存在遮挡问题

本文给大家介绍vue多层弹框时存在遮挡问题&#xff0c;解决思路首先想到的是找到对应的遮挡层的css标签&#xff0c;然后修改z-index值&#xff0c;但是本思路只能解决首次问题&#xff0c;再次打开还会存在相同的问题&#xff0c;故该思路错误&#xff0c;下面给大家带来一种正…

【鸿蒙学习笔记】文件管理

官方文档&#xff1a;Core File Kit简介 目录标题 文件分类什么是应用沙箱&#xff1f; 文件分类 应用文件&#xff0c;比如应用的安装包&#xff0c;自己的资源文件等。用户文件&#xff0c;比如用户自己的照片&#xff0c;录制的音视频等。 什么是应用沙箱&#xff1f; 应…

完美解决:MySQL8报错:Public Key Retrieval is not allowed

在配置数据源的时候直接将属性allowPublicKeyRetrieval设置为true即可 &AutoReconnecttrue

论文发表作图必备:训练结果对比,多结果绘在一个图片【Precision】【Recall】【mAP0.5】【mAP0.5-0.95】【loss】

前言:Hello大家好,我是小哥谈。YOLO(You Only Look Once)算法是一种目标检测算法,它可以在图像中实时地检测和定位目标物体。YOLO算法通过将图像划分为多个网格,并在每个网格中检测目标物体,从而实现快速的目标检测。本文所介绍的作图教程适用于所有YOLO系列版本算法,接…

Linux Ubuntu MySQL环境安装

1. 更新软件源 首先&#xff0c;确保你的Ubuntu系统已经更新了软件源列表&#xff0c;以便能够下载到最新的软件包。打开终端并输入以下命令&#xff1a; sudo apt update 2. 安装MySQL服务器 打开终端并输入以下命令来安装MySQL服务器 sudo apt install mysql-server 在…