vue3+eachrts饼图轮流切换显示高亮数据

news2024/11/26 2:41:36

在这里插入图片描述

<template>
    <div class="charts-box">
      <div class="charts-instance" ref="chartRef">
      </div>
      // 自定义legend 样式
      <div class="charts-note">
      <span v-for="(items, index) in data.dataList" class="charts-legend">
        <span class="legend" :style="{background:colorList[index]}"></span>
        <span>{{items.name}}</span>
        <span style="color: #999999;margin-left: 5px;">{{((items.value / props.total)*100).toFixed(2) }}%</span>
      </span>
    </div>
    </div>
  </template>
  <script setup>
  import {ref, onMounted, onUnmounted, reactive, watch} from 'vue'
  import * as echarts from 'echarts'
  import useEmitter from "@/hooks/useEmitter";
  import {findRightBottomPie, removeTrailingZeros} from "@/views/BangFuData/service"; // 接口

  const props = defineProps(['timeRange', 'dictItem', 'total'])
  const emitter = useEmitter()
  const chartRef = ref()

  const data = reactive({
    dataList: [
        {
            "name": "中央统战部",
            "value": "4742.93",
            "count": null,
            "type": null
        },
        {
            "name": "民盟",
            "value": "439.47",
            "count": null,
            "type": null
        },
        {
            "name": "致公党",
            "value": "377.23",
            "count": null,
            "type": null
        },
        {
            "name": "农工党",
            "value": "1181.58",
            "count": null,
            "type": null
        },
        {
            "name": "民建",
            "value": "365.38",
            "count": null,
            "type": null
        },
        {
            "name": "民进",
            "value": "200.72",
            "count": null,
            "type": null
        },
        {
            "name": "全国工商联",
            "value": "2112.68",
            "count": null,
            "type": null
        },
        {
            "name": "民革",
            "value": "102.70",
            "count": null,
            "type": null
        },
        {
            "name": "九三学社",
            "value": "439.30",
            "count": null,
            "type": null
        },
        {
            "name": "台盟",
            "value": "24.50",
            "count": null,
            "type": null
        }
    ],
  })
  const colorList =['#876FFE', '#F85A8E','#E74C3C','#FFC476','#F1C40F','#80C269','#13B5B1','#54DCFF','#1A92FF','#5085FF', '#F85A8E','#E74C3C','#FFC476','#F1C40F','#80C269','#13B5B1']

  const findData = (callback) => {
    let rightBottomPieRes = findRightBottomPie(props.timeRange === 'previous' ? 2 : 1)
    rightBottomPieRes.then(res => {
      // let arr = []
      // props.dictItem.find(qhItem => {
      //   let result = res.find(item => item.name.indexOf(qhItem.label) > -1)
      //   if (result) {
      //     arr.push({name: qhItem.label, value: result.value})
      //   } else {
      //     arr.push({name: qhItem.label, value: 0})
      //   }
      // })
      data.dataList = res
      callback()
    })
  }

  let myChart = null
  const option = ref(null)
  const buildOption = () => {
    let _option = {
      tooltip: {
        show: false,
        trigger: 'item',
      },
      legend: {
        show: false,
        itemWidth: 12,
        itemHeight: 12,
        itemGap: 20,
        icon: 'roundRect',
        bottom: '5%',
        left: '45px',
        right: '45px',
        formatter: (name) => {
          let total = 0;
          let tarValue = 0;
          for (let i = 0; i < data.dataList.length; i++) {
            total += parseFloat(data.dataList[i].value);
          }
          for (let index = 0; index < data.dataList.length; index++) {
            if (name.indexOf(data.dataList[index].name)> -1) {
              if(total && total !== 0){
                tarValue = ((data.dataList[index].value / total)*100).toFixed(2);
              }
            }
          }
          // if(tarValue === 0){
          //   return `{oneone|${name}}`;
          // }
          return `{oneone|${name}}   {threethree|${removeTrailingZeros(tarValue)}%}`;
        },
        textStyle: {
          rich: {
            threethree: {
              color: "#999",
            }
          }
        }
      },
      title: {
            text: '0',//主标题文本
            subtext:'资金(万元)',//副标题文本
            right:'center',
            top:'42%',
            textStyle:{
                fontSize: '1.2rem',
                color:'#454c5c',
                align:'center'
            },
            subtextStyle:{
                fontFamily : "微软雅黑",
                fontSize: '0.8rem',
                color:'#6c7a89',
            }
        },
      color: colorList,
      series: [
        {
          name: '',
          type: 'pie',
          radius: ['35%', '55%'],
          center: ['50%', '50%'],
          avoidLabelOverlap: false,
          itemStyle: {
            borderRadius: 0,
            borderColor: '#fff',
            borderWidth: 2
          },
          // label: {
          //     show: false,
          //     position: 'center'
          // },
          emphasis: {
            label: {
              show: true,
              fontSize: 20,
              fontWeight: 'bold'
            },
            scale: true,
            scaleSize: 20
          },
          // labelLine: {
          //     show: false
          // },
          label: {
            show: true,
            alignTo: 'edge',
            formatter: '{name|{b}} {time|{d}%} \n',
            minMargin: 5,
            edgeDistance: 10,
            lineHeight: 15,
            rich: {
              name: {
                fontSize: 14,
                color: '#000'
              },
              time: {
                fontSize: 14,
                color: '#999'
              }
            }
          },
          labelLine: {
            show: true,
            length: 30,
            length2: 0,
            maxSurfaceAngle: 80
          },
          labelLayout: function (params) {
            const isLeft = params.labelRect.x < myChart.getWidth() / 2;
            const points = params.labelLinePoints;
            // Update the end point.
            points[2][0] = isLeft  ? params.labelRect.x : params.labelRect.x + params.labelRect.width;
            return {
              labelLinePoints: points
            };
          },
          data: data.dataList
        }
      ]
    }
    _option.series[0].data = data.dataList;
    option.value = _option
  }
  const handleChartLoop = (option, myChart) => {
      if (!myChart) {
          return;
      }
      let currentIndex = -1; // 当前高亮图形在饼图数据中的下标
      let timeTicket = setInterval(selectPie, 2000); // 设置自动切换高亮图形的定时器

      // 取消所有高亮并高亮当前图形
      function highlightPie() {
          // 遍历饼图数据,取消所有图形的高亮效果
          for (let idx in option.series[0].data) {
              myChart.dispatchAction({
                  type: "downplay",
                  seriesIndex: 0,
                  dataIndex: idx,
              });
          }
          // 高亮当前图形
          myChart.dispatchAction({
              type: "highlight",
              seriesIndex: 0,
              dataIndex: currentIndex,
          });
          let data = option.series[0].data[currentIndex] && option.series[0].data[currentIndex].value ? option.series[0].data[currentIndex].value : 0
          myChart.setOption({
            title: {
              text: removeTrailingZeros(parseFloat(data).toFixed(2))
            },
            series: {
              label: {
                show: false,
                formatter: () => {
                  if ((option.series[0].data[currentIndex] && option.series[0].data[currentIndex].value === 0)
                    || !props.total || props.total == 0) {
                    return `{name|${option.series[0].data[currentIndex].name}} {time|0%} \n`
                  }
                  let val = removeTrailingZeros(((option.series[0].data[currentIndex].value/props.total)*100).toFixed(2))
                  return `{name|${option.series[0].data[currentIndex].name}} {time|${val}%} \n`
                }
              }
            }
          })
      }

      // 用户鼠标悬浮到某一图形时,停止自动切换并高亮鼠标悬浮的图形
      myChart.on("mouseover", (params) => {
          clearInterval(timeTicket);
          currentIndex = params.dataIndex;
          highlightPie();
      });

      // 用户鼠标移出时,重新开始自动切换
      myChart.on("mouseout", (params) => {
          if (timeTicket) {
              clearInterval(timeTicket);
          }
          timeTicket = setInterval(selectPie, 1000);
      });

      // 高亮效果切换到下一个图形
      function selectPie() {
          let dataLen = option.series[0].data.length;
          currentIndex = (currentIndex + 1) % dataLen;
          highlightPie();
      }
  }

  watch(() => props.timeRange, (nv, ov) => {
    findData(()=>buildOption())
  })
  watch(()=>option.value,(newOption,oldOption)=>{
    if(myChart == null) {
      myChart = echarts.init(chartRef.value);
    }
    option.value && myChart && myChart.setOption(newOption)
    if(oldOption==null){
      option.value && myChart && handleChartLoop(option.value,myChart);
    } else {
      //option.value && myChart && handleChartLoop(option.value,myChart);
    }
  })
  onMounted(()=>{
      myChart = echarts.init(chartRef.value);
      findData(()=>buildOption());
      emitter.on('echartsTimeRangeChange',()=>setTimeout(() => myChart && myChart.resize({width:chartRef.value.clientWidth,height:chartRef.value.clientHeight}), 50))
      emitter.on('echartsUpdate',()=>myChart && myChart.resize({width:chartRef.value.clientWidth,height:chartRef.value.clientHeight}))
  })
  onUnmounted(()=>{
    emitter.off('echartsTimeRangeChange')
    emitter.off('echartsUpdate')
    myChart.dispose()
  })
  </script>
  <style scoped>
  .charts-box{
    height: calc(100% - 48px);
  }

.charts-instance{
  height: 60%;
  width: 100%;
  overflow: hidden;
}
.charts-note{
  margin-left: 15%;
  height: 40%;
  overflow: hidden;
}
.charts-legend {
  display: inline-block;
  vertical-align: middle;
  margin-top: 15px;
  width: 50%;
  font-size: 12px;
}
.legend {
  display: inline-block;
  vertical-align: middle;
  margin-right:5px;
  width: 12px;
  height: 12px;
  border-radius: 2px;
}
  </style>

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

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

相关文章

unity之 “Allow ‘unsafe‘ code“ 在哪里。

导入unity中的代码&#xff0c;出现如下错误&#xff0c;该如何解决&#xff1f; Unsafe code may only appear if compiling with /unsafe. Enable "Allow unsafe code" in Player Settings to fix this error 解决这个问题&#xff0c;只需要设置就可以。 设置的地…

【苍穹外卖】log爆红

使用了Slf4j注解&#xff0c;用于自动生成一个log对象&#xff0c;相当于private final Logger log LoggerFactory.getLogger(当前类名.class); 这个注解需要安装Lombok插件才能使用。 IDEA file—settings–plugins&#xff0c;搜索lombok–install。安装完后自动重启IDEA后…

【WEEK6】 【DAY2】DQL Data Querying - Part Two 【English Version】

2024.4.2 Tuesday Following the previous article 【WEEK6】 【DAY1】DQL Data Query - Part One【English Version】 Contents 4.4. Join Queries4.4.1. JOIN Comparison4.4.2. Seven Types of JOINs4.4.3. Examples4.4.3.1. In this example, the results of INNER JOIN and…

DLL导出API注意事项

文章目录 问题原则示例一解决方案 示例二解决方法 参考 问题 在 windows 平台下&#xff0c;如果在动态库的接口中使用 std::string 或其它 std 容器&#xff0c;会导致崩溃或其它内存问题&#xff0c;所以一般要求动态库的接口必须是 C 语言实现。 原则 一个原则&#xff1a;…

LabVIEW专栏二、调用子VI

该节目标是创建带子vi&#xff0c;修改vi属性&#xff0c;测试可重入和不可重入的区别 一 、设置子VI 把VI封装成为子VI&#xff0c;可以帮助模块化程序&#xff0c;简化代码结构。 任何VI本身都可以成为别的VI的子VI。 1.1、设置输入输出端子 1、在前面板空白处&#xff0…

JavaScript中什么叫深拷贝?

在 JavaScript 中&#xff0c;深拷贝指的是创建一个新的对象&#xff0c;这个新的对象与原始对象完全独立&#xff0c;没有任何共享的属性或者数据&#xff0c;它们不共享同一块内存地址。深拷贝会复制原始对象的所有属性和嵌套对象的所有属性&#xff0c;包括嵌套对象中的属性…

Mybatis——查询数据

查询操作 根据用户id查询单条记录&#xff0c;在映射器接口(UserMapper)中定义如下方法&#xff1a; package org.example.mapper;import org.example.demo.User;import java.util.List;public interface UserMapper {//根据id查询UserUser selectUserById(Integer userId); …

使用 RisingWave、NATS JetStream 和 Superset 进行实时物联网监控

在物联网&#xff08;IoT&#xff09;背景下&#xff0c;处理实时数据会遇到一些特定的障碍&#xff0c;如边缘计算资源不足、网络条件限制、扩展性存在问题、设备间有多样性差异。要克服这些挑战&#xff0c;需要高效的边缘计算技术、强大的安全措施、标准化协议、可扩展的管理…

【升降自如】OLED升降透明屏,智能调节,打造个性化观影体验

OLED升降透明屏&#xff0c;作为科技领域的创新之作&#xff0c;以其升降自如、智能调节的特点&#xff0c;为用户带来了前所未有的个性化观影体验。 这款透明屏采用先进的OLED显示技术&#xff0c;不仅色彩鲜艳、对比度高&#xff0c;而且具备出色的透明性能。更值得一提的是&…

3D人脸扫描技术与数字人深度定制服务:赋能打造超写实3D数字分身

在数字时代&#xff0c;3D数字分身有着广泛的应用场景&#xff0c;在动画视频、广告宣传片、大型活动主持人、AI交互数字人等领域&#xff0c;发挥着重要的商业价值。其中&#xff0c;3D人脸扫描技术&#xff0c;推动了超写实3D数字分身的诞生。 公司案例 2023海心沙元宇宙音乐…

10_MVC

文章目录 JSON常用的JSON解析Jackson的常规使用指定日期格式 MVC设计模式MVC介绍前后端分离案例&#xff08;开发与Json相关接口&#xff09; 三层架构三层架构介绍 JSON JSON&#xff08;JavaScript Object Notation&#xff09; 是一种轻量级的数据交换格式&#xff0c;是存…

[中级]软考_软件设计_计算机组成与体系结构_06_ 流水线技术

流水线技术 前言相关考试考点一&#xff1a;流水线执行时间概念流水线步骤解析参数计算案例解析&#xff1a;流水线计算第一问第二问 考点二&#xff1a;流水线吞吐率 前言 第一章比较重要的一种计算题型&#xff0c;经常考到&#xff0c;一般考试1 ~ 2分。 相关考试 流水线…

【智能算法】蜜獾算法(HBA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2021年&#xff0c;FA Hashim等人受到自然界中蜜獾狩猎行为启发&#xff0c;提出了蜜獾算法&#xff08;(Honey Badger Algorithm&#xff0c;HBA&#xff09;。 2.算法原理 2.1算法思想 蜜獾以其…

文献速递:深度学习胰腺癌诊断--深度学习算法用于从疾病轨迹预测胰腺癌风险

文献速递&#xff1a;深度学习胰腺癌诊断--深度学习算法用于从疾病轨迹预测胰腺癌风险 麦田医学 美好事物中转站 2024-04-02 14:36 Title 题目 A deep learning algorithm to predict risk of pancreatic cancer from disease trajectories 深度学习算法用于从疾病轨迹预测…

WPF-基础及进阶扩展合集(持续更新)

目录 一、基础 1、GridSplitter分割线 2、x:static访问资源文件 3、wpf触发器 4、添加xaml资源文件 5、Convert转换器 6、多路绑定与多路转换器 二、进阶扩展 1、HierarchicalDataTemplate 2、XmlDataProvider从外部文件获取源 3、TextBox在CellTemplate中的焦点问题…

【LeetCode热题100】79. 单词搜索(回溯)

一.题目要求 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平…

揭秘代码安全:告别硬编码,灵活策略守护你的账户密码信息安全

前言 在编写代码时&#xff0c;为了遵循严格的安全规范&#xff0c;应避免硬编码任何敏感信息如账号凭证、密钥等直接出现在源代码中。相反&#xff0c;推荐采取安全措施&#xff0c;如使用环境变量、加密存储或安全凭据管理系统来间接引用和保护这类数据。如此一来&#xff0c…

使用 Docker 部署 Puter 云桌面系统

1&#xff09;Puter 介绍 :::info GitHub&#xff1a;https://github.com/HeyPuter/puter ::: Puter 是一个先进的开源桌面环境&#xff0c;运行在浏览器中&#xff0c;旨在具备丰富的功能、异常快速和高度可扩展性。它可以用于构建远程桌面环境&#xff0c;也可以作为云存储服…

c++对象指针

对象指针在使用之前必须先进行初始化。可以让它指向一个已定义的对象&#xff0c;也可以用new运算符动态建立堆对象。 定义对象指针的格式为&#xff1a; 类名 *对象指针 &对象; //或者 类名 *对象指针 new 类名(参数); 用对象指针访问对象数据成员的格式为&#xff1a…

python很坐标报错ufunc ‘isfinite‘ not supported for the input types

python使用plt画图的时候&#xff0c;出错。 出错全文如下&#xff1a; Traceback (most recent call last): plt.show() return _get_backend_mod().show(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ __call__ manager.show(**kwar…