使用echarts绘制3DChart图表

news2024/11/17 11:41:07

使用3DChart需要安装echarts和echarts-gl。否则图标不显示。
版本要对应
“echarts”: “^5.2.2”,
“echarts-gl”: “^2.0.9”,
在这里插入图片描述

main.js

// main.js 引入echarts方式如下
import 'echarts-gl' //如果使用3DEchart图标需要下载个引入对应版本的
import * as echarts from 'echarts'
Vue.prototype.$echarts = echarts

3DEchart.vue

<template>
  <div>
    <div class="one_box" id="one_box" ref="one_box"></div>
  </div>
</template>

<script>
import getPie3D from './3DChart.js'
export default {
  components: {  },
  data() {
    return {
      option: null,
    };
  },
  mounted() {
    const data = [
      { value: 100, name: "换流站" },
      { value: 1, name: "常规站" },
      { value: 80, name: "智能站" },
    ];
    const optionData = data.map((item) => {
      return {
        ...item,
        rate: item.value / 181,
      };
    });
    this.option = getPie3D(optionData, 0, '占比');

    const myChart = this.$echarts.init(document.getElementById('one_box'));
    myChart.resize({
      height: '300px',
    });
    myChart.setOption(this.option);
  },
  methods: {
    optionFun3D() {},
  },
};
</script>

<style>
</style>

3DChart.js

let color= ['#007d7b', '#8BC34A', '#CDDC39', '#FFEB3B', '#FFC107', '#FF9800', '#FF5722', '#E91E63', '#9C27B0', '#673AB7']

const getPie3D = (pieData, internalDiameterRatio, rateName) => {
  // internalDiameterRatio:透明的空心占比
  const series = []
  let sumValue = 0
  let startValue = 0
  let endValue = 0
  const k = 1 - internalDiameterRatio
  pieData.sort((a, b) => {
    return (b.value - a.value)
  })
  // 为每一个饼图数据,生成一个 series-surface 配置
  for (let i = 0; i < pieData.length; i++) {
    sumValue += pieData[i].value
    const seriesItem = {
      name: typeof pieData[i].name === 'undefined' ? `series${i}` : pieData[i].name,
      type: 'surface',
      parametric: true,
      wireframe: {
        show: false
      },
      pieData: pieData[i],
      pieStatus: {
        selected: false,
        hovered: false,
        k: k
      },
      center: ['10%', '50%']
    }

    if (typeof pieData[i].itemStyle !== 'undefined') {
      const itemStyle = {}
      typeof pieData[i].itemStyle.color !== 'undefined' ? itemStyle.color = pieData[i].itemStyle.color : null
      typeof pieData[i].itemStyle.opacity !== 'undefined' ? itemStyle.opacity = pieData[i].itemStyle.opacity : null
      seriesItem.itemStyle = itemStyle
    }
    series.push(seriesItem)
  }

  // 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,
  // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。
  for (let i = 0; i < series.length; i++) {
    endValue = startValue + series[i].pieData.value
    series[i].pieData.startRatio = startValue / sumValue
    series[i].pieData.endRatio = endValue / sumValue
    series[i].parametricEquation = getParametricEquation(series[i].pieData.startRatio, series[i].pieData.endRatio,
      false, false, k, series[i].pieData.value)
    startValue = endValue
  }
  const boxHeight = getHeight3D(series, 26)// 通过传参设定3d饼/环的高度,26代表26px
  // const newColor = _.cloneDeep(color)
  // newColor.splice(0, 1)

  const newColor = [color[0], color[1], color[5]]

  series.push({
    type: 'pie',
    label: {
      // show: false, // 去除示例线段
      opacity: 1,
      fontSize: 12,
      lineHeight: 14,
      textStyle: {
        fontSize: 12
      }
    },
    labelLine: {
      length: 30,
      length2: 40
    },
    startAngle: -25, // 起始角度,支持范围[0, 360]。
    clockwise: false, // 饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式
    radius: ['10%', '20%'],
    center: ['50%', '45%'],
    data: pieData.map(ele => {
      return {
        ...ele,
        labelLine: { show: !!ele.value } // 值为0的 去除示例线段
      }
    }),
    itemStyle: {
      opacity: 0
    }
  })

  const option = {
    color: newColor,
    legend: {
      left: 'center',
      top: 'bottom',
      itemGap: 20,
      icon: 'square',
      formatter: (param) => {
        const item = pieData.filter(item => item.name === param)[0]
        return `${item.name}  ${item.value}`
      } // 底部示例
    },
    labelLine: {
      show: true
    },
    label: {
      show: true,
      position: 'outside',
      rich: {
        title: {
          lineHeight: 24
        },
        rich: {
          fontSize: 14
        }
      },
      formatter: data => {
        return data.value ? `{title|${data.data.name}}{rich|${data.value}}()\n{title|${rateName || '整改率'}}{rich|${data.data.rate}%}` : ''
      } // 值为0的就不展示默认的示例
    },
    tooltip: {
      show: true,
      formatter: params => {
        if (params.seriesName !== 'mouseoutSeries' && params.seriesName !== 'pie2d') {
          console.log(option.series[params.seriesIndex].pieData)
          let bfb = ((option.series[params.seriesIndex].pieData.endRatio - option.series[params.seriesIndex].pieData.startRatio) *
            100).toFixed(2)
          if (bfb === 'NaN') {
            bfb = 0
          }
          return `${params.seriesName}: ${option.series[params.seriesIndex].pieData.value}()<br/>` +
            `<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${params.color};"></span>占比:` +
            `${bfb}%`
        }
      } // hover示例
    },
    xAxis3D: {
      min: -1,
      max: 1
    },
    yAxis3D: {
      min: -1,
      max: 1
    },
    zAxis3D: {
      min: -1,
      // max: 1
      max: 'dataMax' // 坐标轴刻度最大值:可以设置成特殊值 'dataMax',此时取数据在该轴上的最大值作为最大刻度
    },
    grid3D: {
      show: false,
      boxHeight: 30, // boxHeight, // 整个圆环的最大高度
      top: '-5%',
      viewControl: { // 3d效果可以放大、旋转等,请自己去查看官方配置
        alpha: 30, // 角度
        distance: 340, // 调整视角到主体的距离,类似调整zoom
        rotateSensitivity: 0, // 设置为0无法旋转
        zoomSensitivity: 0, // 设置为0无法缩放
        panSensitivity: 0, // 设置为0无法平移
        autoRotate: false // 自动旋转
      }
    },
    series: series
  }
  return option
}

// 获取3d丙图的最高扇区的高度
const getHeight3D = (series, height) => {
  series.sort((a, b) => {
    return (b.pieData.value - a.pieData.value)
  })
  // return height * 25 / series[0].pieData.value
  return 1000 / series[0].pieData.value
}

// 生成扇形的曲面参数方程,用于 series-surface.parametricEquation
const getParametricEquation = (startRatio, endRatio, isSelected, isHovered, k, h) => {
  // 计算
  const midRatio = (startRatio + endRatio) / 2
  const startRadian = startRatio * Math.PI * 2
  const endRadian = endRatio * Math.PI * 2
  const midRadian = midRatio * Math.PI * 2
  // 如果只有一个扇形,则不实现选中效果。
  if (startRatio === 0 && endRatio === 1) {
    isSelected = false
  }
  // 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
  k = typeof k !== 'undefined' ? k : 1 / 3
  // 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
  const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0
  const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0
  // 计算高亮效果的放大比例(未高亮,则比例为 1)
  const hoverRate = isHovered ? 1.05 : 1
  // 返回曲面参数方程
  return {
    u: {
      min: -Math.PI,
      max: Math.PI * 3,
      step: Math.PI / 32
    },
    v: {
      min: 0,
      max: Math.PI * 2,
      step: Math.PI / 20
    },
    x: function(u, v) {
      if (u < startRadian) {
        return offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
      }
      if (u > endRadian) {
        return offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
      }
      return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate
    },
    y: function(u, v) {
      if (u < startRadian) {
        return offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
      }
      if (u > endRadian) {
        return offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
      }
      return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate
    },
    z: function(u, v) {
      if (u < -Math.PI * 0.5) {
        return Math.sin(u)
      }
      if (u > Math.PI * 2.5) {
        return Math.sin(u) * h * 0.1
      }
      return Math.sin(v) > 0 ? 1 * h * 0.1 : -1
    }
  }
}

export default getPie3D

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

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

相关文章

旅游网站HTML

代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>旅游网</title> </head> <body><!--采用table编辑--> <!--最晚曾table,用于整个页面那布局--><table width&q…

【星海出品】ansible入门(四)playbook kolla开源例子

简介 Kolla-ansible项目提供一个完整的Ansible Playbook&#xff0c;来部署Docker的镜像&#xff0c;再完成openstack组件的自动化部署。并提供all-in-one和multihost的环境。 安装后会将kolla-ansible内置为一个shell启动文件。 kolla-ansible: /usr/local/bin/kolla-ansible…

获取手机号归属地详情,精准高效的API接口服务

在现代社会中&#xff0c;通讯工具如手机成为了人们生活中不可缺少的部分。但是&#xff0c;有时我们会收到陌生电话&#xff0c;需要了解电话号码的归属地以判断其可信性。这个时候&#xff0c;获取手机号归属地的API接口服务就会发挥重要作用。 一、API接口服务简介 API接口…

解决video层级过高在app的问题

直接上代码,写一个组件 <template><iframe :onload"inner"></iframe> </template> <script>export default {props: {src: {}},data() {return {inner: }},created() {this.inner this.contentWindow.document.body.innerHTML <v…

一文搞懂二叉树后序遍历的三种方法

系列文章&#xff1a; 相关题目&#xff1a; 145. 二叉树的后序遍历 先序遍历结果为&#xff1a;4 5 2 6 7 3 1 总体上分为两种框架&#xff0c;递归框架和非递归框架&#xff0c;递归框架又分为两种思路&#xff1a;分解思路和遍历思路。 递归 1、分解思路 【分解为子问题】…

直线模组的应用场景

直线模组是一种由直线导轨、滑块、驱动部件等组成的直线运动系统&#xff0c;具有高精度、高速度、高效率等特点。直线模组被广泛应用于各种机械设备中&#xff0c;以下是其主要的应用场景&#xff1a; 1、数控机床&#xff1a;直线模组是数控机床中的重要组成部分&#xff0c;…

过滤器的实现及其原理责任链设计模式

Filter过滤器 过滤器的应用 DeptServlet,EmpServlet,OrderServlet三个业务类的业务方法执行之前都需要编写判断用户是否登录和解决的中文乱码的代码,代码没有得到重复利用 Filter是过滤器可以用来编写请求的过滤规则和多个Servlet都会执行的公共代码,Filter中的业务代码既可…

docker安装Jenkins完整教程

1.docker拉取 Jenkins镜像并启动容器 新版本的Jenkins依赖于JDK11 我们选择docker中jdk11版本的镜像 # 拉取镜像 docker pull jenkins/jenkins:2.346.3-2-lts-jdk11 2.宿主机上创建文件夹 # 创建Jenkins目录文件夹 mkdir -p /data/jenkins_home # 设置权限 chmod 777 -R /dat…

【C/C++】指针与函数传参

1、值传递 2、地址传递 注意&#xff1a;如果实参是一个普通变量&#xff0c;地址传参的话就需要形参是一级指针&#xff0c; 如果实参是一个一级指针&#xff0c;地址传参的话就需要形参是一个二级指针&#xff0c; 以此类推 3、传数组&#xff1a; 将数组作为参数传递给函…

DATA URL:嵌入 URL 中的数据资源

文章目录 参考环境DATA URL概念结构DATA URL 的优缺点优点缺点 DATA URL 与图片获取图片的 Base64 编码结果在 HTML 中应用 DATA URL 以展示图片 DATA URL 与 allow_url_fopen 及 allow_url_include 配置项allow_url_fopen 配置项allow_url_include 配置项allow_url_fopen 与 a…

Word中设置粘贴为纯文本的自定义快捷键

1、依次点击左上角 File(文件)->options(选项)-> Customize ribbon(自定义功能区)->Customize (自定义快捷键) 2、选择 All commands(所有命令)->PasteTextOnly(粘贴纯文本)&#xff0c; 在 Press new shortcut key (键入新快捷键)中输入自己喜欢的快捷键&#xff…

华为云云耀云服务器L实例评测|华为云上的CentOS性能监测与调优指南

目录 引言 ​编辑1 性能调优的基本要素 2 性能监控功能 2.1 监控数据指标 2.2 数据历史记录 2.3 多种统计指标 3 性能优化策略 3.1 资源分配 3.2 磁盘性能优化 3.3 网络性能优化 3.4 操作系统参数和内核优化 结论 引言 在云计算时代&#xff0c;性能优化和调优对于…

视觉效果绝佳的制作电子宣传册的网站

随着数字技术与设计理念的融合&#xff0c;电子宣传册不再是平面的文字与图片堆砌&#xff0c;而是通过多媒体元素、动画效果和交互性功能营造出沉浸式的阅读体验。小编向大家推荐一款名为FLBOOK的制作电子宣传册的网站。 首先&#xff0c;打开FLBOOK电子杂志制作网站然后点击模…

长城网络靶场第五题,流量包分析

关卡描述&#xff1a;1.小利访问最频繁的网站是&#xff1f;&#xff08;只填写一级域名&#xff09; 因为是一级域名所以只要 gamersky.com 关卡描述&#xff1a;2.小利的IP是多少&#xff1f; 看数据包很明显 标准答案&#xff1a;192.168.12.126 关卡描述&#xff1a;3.黑…

Win11通过注册表或者kernel32.dll的SetUserGeoName等方式设置国家或地区后重启过一会就自动变回原来的值...

最近同事 panwangvie 尝试通过代码设置国家或地区&#xff0c;尝试过注册表或者kernel32.dll的SetUserGeoName等方式设置&#xff0c;重启过一会就自动变回原来的值 我也尝试了以下方式均不行&#xff1a; 1. 一开始怀疑是自动时钟影响&#xff0c;所以把自动时钟关闭了 2. 然后…

c++桥接模式,中介者模式应用实现状态跳转

上图为例&#xff0c;按上述两种方式实现的模式跳转&#xff0c;如果在原先的三种模式之间再增加多一种模式&#xff0c;就会引起每个模式都会要求改变&#xff0c;并且逻辑混乱&#xff0c;因此更改模式为桥接中介者访问&#xff0c;将抽象和实现分离&#xff0c;实现之间采用…

STM32单片机裸机程序怎么处理大量网络数据?

STM32单片机裸机程序怎么处理大量网络数据? 无论是在中断中处理数据&#xff0c;还是在主循环里处理数据&#xff0c;你用于处理数据的时间是不变的。 你可以算一下&#xff0c;处理数据的时间&#xff08;速率&#xff09;和单片机的处理能力相差有多大&#xff0c;单片机是…

Android原生实现控件圆角方案(API28及以上)

Android控件的圆角效果的实现方式有很多种&#xff0c;这里介绍一下另一种Android原生的圆角实现方案&#xff08;API28及以上&#xff09;。 我们利用ShapeAppearanceModel、MaterialShapeDrawable来实现一个圆角/切角的Button。 实现效果如下图 我们在为控件添加阴影的基础上…

【软考设计师】S01 数据结构 E01 线性结构 P01 线性表

线性表 前言——线性结构线性表线性表的定义线性表的特点线性表的存储结构顺序存储链式存储单链表双向链表循环链表静态链表 前言——线性结构 线性结构是一种基本的数据结构&#xff0c;主要用于对客观世界中具有单一前驱和后继的数据关系进行描述。线性结构的特点是数据元素…

漏刻有时数据可视化Echarts组件开发(43)水球图svg温度计动画

SVG是一种用XML定义的语言&#xff0c;用来描述二维矢量及矢量/栅格图形。具体来说&#xff0c;SVG图形是可伸缩的矢量图形&#xff0c;其图像质量不会因放大或改变尺寸而损失。 在SVG中&#xff0c;可以创建和修改图像、对图像进行搜索和索引、对其进行脚本化或压缩。此外&am…