动态渲染 echarts 饼图(vue 2 + axios + Springboot)

news2025/2/1 6:47:41

目录

  • 前言
  • 1. 项目搭建
    • 1.1. 前端
    • 1.2. 后端
  • 2. 后端数据渲染前端
    • 2.1 补充1:在 vue 中使用 axios
    • 2.2. 补充2:Springboot 处理跨域问题
    • 2.3. 修改前端代码
      • 2.3.1 修改饼图样式
      • 2.3.2 调用后台数据渲染饼图
      • 2.3.3 改造成内外两个圈

前言

因为上文中提到的需求就是在 vue2 里面绘制echarts,所以,这里就搭建一个 vue2 的脚手架了。

想要深入了解 echarts 属性,请到此篇文章:如何用echarts画一个好看的饼图

至于如何在 vue2 中使用 echarts,请见这篇文章:https://blog.csdn.net/m0_54355172/article/details/131960527

1. 项目搭建

1.1. 前端

  1. 先搭建一个 vue2.0 的脚手架

    • 安装vue-cli

      1. 卸载老版本

        npm uninstall vue-cli -g
        
      2. 安装脚手架

        npm install -g @vue/cli
        
    • 新建一个 vue2 的项目

      vue create pie_front
      
  2. 引入 echarts 依赖:见博客:https://blog.csdn.net/m0_54355172/article/details/131960527

  3. MyPie.vue 初始代码如下:

    <template>
        <div>
          <div class="charts">
            <div id="comPie" style="height: 400px; width: 44em" />
          </div>
        </div>
      </template>
      
      <script>
      export default {
        name: 'myPie',
        data () {
          return {
            pieOption : {
                tooltip: {
                    trigger: 'item'
                },
                legend: {
                    top: '5%',
                    left: 'center'
                },
                series: [
                    {
                    name: 'Access From',
                    type: 'pie',
                    radius: ['40%', '70%'],
                    avoidLabelOverlap: false,
                    itemStyle: {
                        borderRadius: 10,
                        borderColor: '#fff',
                        borderWidth: 2
                    },
                    label: {
                        show: false,
                        position: 'center'
                    },
                    emphasis: {
                        label: {
                        show: true,
                        fontSize: 40,
                        fontWeight: 'bold'
                        }
                    },
                    labelLine: {
                        show: false
                    },
                    data: [
                        { value: 1048, name: 'Search Engine' },
                        { value: 735, name: 'Direct' },
                        { value: 580, name: 'Email' },
                        { value: 484, name: 'Union Ads' },
                        { value: 300, name: 'Video Ads' }
                    ]
                    }
                ]
                },
          }
        },
        mounted () {
          this.showPie()
        },
        methods: {
          showPie () {
            // 指定 echarts 图表初始化的容器
            const pieCharts = this.$echarts.init(document.querySelector('#comPie'))
            // 渲染 echarts
            pieCharts.setOption(this.pieOption, true)
          },
        },
      }
      </script>
      
      <style scoped type="text/less">
        #channelPie {
          margin-top: 1em;
        }
        button {
          width: 80px;
          height: 30px;
          border: 1px solid #2a69ee;
          border-radius: 5px;
          font: normal normal 14px 微软雅黑;
          color: #2a69ee;
          background-color: white;
        }
        .charts {
          display: flex;
          justify-content: center;
        }
      </style>
    
  4. App.vue 原始代码

    <template>
      <div id="app">
        <myPie msg="Welcome to Your Vue.js App"/>
      </div>
    </template>
    
    <script>
    import myPie from './components/MyPie.vue'
    
    export default {
      name: 'App',
      components: {
        myPie
      }
    }
    </script>
    
    <style>
    
    </style>
    
  5. 初始页面

1.2. 后端

postgreSQL 表数据:

后端接口:http://127.0.0.1:8099/pie/getPieData

依赖:

application.yml

spring:
 datasource:
   type: com.alibaba.druid.pool.DruidDataSource
   url: jdbc:postgresql://localhost:5432/study?useUnicode=true&characterEncoding=UTF-8&useSSL=false
   username: postgres
   password: admin
   driver-class-name: org.postgresql.Driver
server:
 port: 8099

PieReadMapper.java

@Repository
public interface PieReadMapper extends BaseMapper<Commodity> {

}

Commodity.java 实体类

@TableName("t_commodity")
@Data
public class Commodity {

    @TableId("cid")
    private String id;
    @TableField("cname")
    private String name;
    private Integer count;
    private BigDecimal income;
}

PieController.java

@Slf4j
@RestController
@RequestMapping("/pie")
public class PieController {

    @Resource
    private PieReadMapper pieReadMapper;


    @PostMapping("getPieData")
    public JSONArray getPieData(String param) {
        log.info("前端参数===>{}", param);
//        QueryWrapper<Commodity> wrapper = new QueryWrapper<>();
//        wrapper.setEntity(new Commodity());
        List<Commodity> commodities = pieReadMapper.selectList(null);
        String s = JSONObject.toJSONString(commodities);
        return JSONArray.parseArray(s);
    }
}

PieBackApplication.java 启动类

@MapperScan("com.chenjy.pie_back.mapper.**")
@SpringBootApplication
public class PieBackApplication {
    public static void main(String[] args) {
        SpringApplication.run(PieBackApplication.class, args);
    }

}

2. 后端数据渲染前端

2.1 补充1:在 vue 中使用 axios

  1. 引入依赖

    npm install axios
    
  2. main.js 全局引入 axios

    import axios from 'axios'
    
    Vue.prototype.$axios = axios
    
  3. 使用 axios 发送 post 请求

          getPieData() {
            const url = 'http://127.0.0.1:8099/pie/getPieData'
            this.$axios({
                method: 'post',
                url: url,
                data: null
            }).then(res => {
                console.log(res.data)
            }, err => {
                console.log('错误信息:', err.message)
            })
          }
    

    那如何用 axios 发送 GET 请求呢?如下:

          testGet() {
            const url = 'http://127.0.0.1:8099/pie/testGet'
            this.$axios({
                // method: 'get', 默认 get,可不写
                url: url,
                params: {
                    str: '前端发起一次 get 请求'
                }
            }).then(res => {
                console.log(res.data)
            }, err => {
                console.log('错误信息:', err.message)
            })
          }
    

2.2. 补充2:Springboot 处理跨域问题

  1. 解决跨域问题

    在后台新加一个配置类

    @Configuration
    public class config implements WebMvcConfigurer {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOriginPatterns("*")
                    .allowCredentials(true)
                    .allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH")
                    .maxAge(3600);
        }
    
    }
    

2.3. 修改前端代码

2.3.1 修改饼图样式

假数据先不去掉,后续把方法加上了再去掉。

        pieOption : {
            title: {
                show: true,
                text: '商品收益',
                x: 'left',
                y: 'top'
            },
            tooltip: {
                trigger: 'item'
            },
            legend: {
                orient: 'vertical',
                x: 'right',
                y: 'center',
                align: 'left',
                icon: 'circle',
            },
            series: [
                {
                type: 'pie',
                radius: ['60%', '70%'],
                roseType: 'area',
                avoidLabelOverlap: false,
                itemStyle: {
                    borderRadius: 10,
                    borderColor: '#fff',
                    borderWidth: 2
                },
                label: {
                    show: false,
                    position: 'center'
                },
                labelLine: {
                    show: false
                },
                data: [
                    { value: 1048, name: 'Search Engine' },
                    { value: 735, name: 'Direct' },
                    { value: 580, name: 'Email' },
                    { value: 484, name: 'Union Ads' },
                    { value: 300, name: 'Video Ads' }
                ]
                }
            ]
            },
      }

2.3.2 调用后台数据渲染饼图

<template>
    <div>
      <div class="charts">
        <div id="comPie" style="height: 400px; width: 44em" />
      </div>
    </div>
  </template>
  
  <script>


  export default {
    name: 'myPie',
    data () {
      return {
        pieOption : {
            title: {
                show: true,
                text: '商品收益',
                left: 100,
            },
            tooltip: {
                trigger: 'item',
                formatter: '{b}&emsp;&emsp;{d}% <br> 商品收益}&emsp;&emsp;{c}',
            },
            legend: {
                orient: 'vertical',
                right: 80,
                top: 100,
                align: 'left',
                icon: 'circle',
                data:[],
            },
            series: [
                {
                type: 'pie',
                radius: ['60%', '70%'],
                roseType: 'area',
                avoidLabelOverlap: false,
                itemStyle: {
                    borderRadius: 10,
                    borderColor: '#fff',
                    borderWidth: 2
                },
                label: {
                    show: false,
                    position: 'center'
                },
                labelLine: {
                    show: false
                },
                data: []
                }
            ]
            },
      }
    },
    mounted () {
      this.getPieData()
    },
    methods: {
      // 每次给饼图传入新的数据之后都要调用这个函数来重新渲染饼图
      showPie () {
        // 指定 echarts 图表初始化的容器
        const pieCharts = this.$echarts.init(document.querySelector('#comPie'))
        // 渲染 echarts
        pieCharts.setOption(this.pieOption, true)
      },
      // 调用后台获取饼图数据,并重新渲染饼图
      getPieData() {
        const url = 'http://127.0.0.1:8099/pie/getPieData'
        this.$axios({
            method: 'post',
            url: url,
            data: null
        }).then(res => {
            const datas = res.data
            this.setPieData(datas)
            this.showPie()
        }, err => {
            console.log('错误信息:', err.message)
        })
      },
      // 根据传入数据给饼图参数赋值
      setPieData(datas) {
        // 根据 arrays 配置 option 的 legend 和 series.data 的数据
        const data = Array.from(datas)
        const legendArr = []
        const seriesArr = []
        for (let i = 0; i < data.length; i++) {
           const seriesObj = {}
           legendArr.push(data[i].name)
           seriesObj.value = data[i].income
           seriesObj.name = data[i].name
           seriesArr.push(seriesObj)
        }
        this.pieOption.legend.data = legendArr
        this.pieOption.series[0].data = seriesArr
      }
    },
  }
  </script>
  
  <style scoped type="text/less">
    #channelPie {
      margin-top: 1em;
    }
    button {
      width: 80px;
      height: 30px;
      border: 1px solid #2a69ee;
      border-radius: 5px;
      font: normal normal 14px 微软雅黑;
      color: #2a69ee;
      background-color: white;
    }
    .charts {
      display: flex;
      justify-content: center;
    }
  </style>

2.3.3 改造成内外两个圈

如果要弄成内外两个圈的饼图,可以在 series 中再加一个数组:

series: [
                {
                name: '商品收益',
                type: 'pie',
                radius: ['60%', '70%'],
                roseType: 'area',
                avoidLabelOverlap: false,
                itemStyle: {
                    borderRadius: 10,
                    borderColor: '#fff',
                    borderWidth: 2
                },
                label: {
                    show: false,
                    position: 'center'
                },
                labelLine: {
                    show: false
                },
                data: []
                },
                {
                name: '商品收益',
                type: 'pie',
                radius: '35%',
                // roseType: 'area',
                avoidLabelOverlap: false,
                itemStyle: {
                    borderRadius: 10,
                    borderColor: '#fff',
                    borderWidth: 2
                },
                label: {
                    show: false,
                    position: 'center'
                },
                labelLine: {
                    show: false
                },
                data: []
                }
            ]
            },
      setPieData(datas) {
        // 根据 arrays 配置 option 的 legend 和 series.data 的数据
        const data = Array.from(datas)
        const legendArr = []
        const seriesArr = []
        for (let i = 0; i < data.length; i++) {
           const seriesObj = {}
           legendArr.push(data[i].name)
           seriesObj.value = data[i].income
           seriesObj.name = data[i].name
           seriesArr.push(seriesObj)
        }

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

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

相关文章

轻松上手Three.js:JavaScript 3D库指南

1.Three.js概述 Three.js是使用JavaScript语言编写的一款运行在浏览器中的3D引擎。与WebGL不同&#xff0c;开发人员在使用Three.js进行开发时&#xff0c;无须掌握高深的图形学知识&#xff0c;只需使用少量JavaScript代码即可创建出一个3D场景。可以说&#xff0c;Three.js的…

恒运资本:小盘股的优点?投资小盘股要注意哪些方面?

股市是一个充溢时机和危险的当地&#xff0c;不同出资者有不同的偏好&#xff0c;有的人喜爱追逐大盘蓝筹股&#xff0c;有的人则钟情于小盘股。那么小盘股的长处&#xff1f;出资小盘股要注意哪些方面&#xff1f;恒运资本也为我们准备了相关内容&#xff0c;以供参考。 小盘股…

vue+springboot+mysql的垃圾分类管理系统

1、引言 设计结课作业,课程设计无处下手&#xff0c;网页要求的总数量太多&#xff1f;没有合适的模板&#xff1f;数据库&#xff0c;java&#xff0c;python&#xff0c;vue&#xff0c;html作业复杂工程量过大&#xff1f;毕设毫无头绪等等一系列问题。你想要解决的问题&am…

六、Hive数据仓库应用之Hive事务(超详细步骤指导操作,WIN10,VMware Workstation 15.5 PRO,CentOS-6.7)

Hive远程模式部署参考&#xff1a; 一、Hive数据仓库应用之Hive部署&#xff08;超详细步骤指导操作&#xff0c;WIN10&#xff0c;VMware Workstation 15.5 PRO&#xff0c;CentOS-6.7&#xff09; 文章目录 一、事务的设计与特点1、事务的特点2、事务的设计3、事务的实现 二、…

【LeetCode刷题笔记】动态规划 — 70.爬楼梯

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 更多算法知识专栏&#xff1a;算法分析&#x1f525; 给大家跳段街舞感谢…

Python不是一种伟大的编程语言?

作为一门简洁易用、生态蓬勃且具有高泛用性的编程语言&#xff0c;Python一直以来都被不少人称作“编程语言中的瑞士军刀”。 尤其随着近来AI热潮席卷全球&#xff0c;Python在编程语言圈中的地位也随之水涨船高&#xff0c;甚至一度被视作AI专用语言或大数据专用语言。 然而…

Netty核心原理:一、基础入门-04:NettyServer字符串解码器

文章目录 一、前言介绍二、代码实现2.1 工程结构2.2 Netty服务端字符串解码器实现2.2.1 服务端处理器2.2.2 通道初始化2.2.3 netty服务端 2.3 单元测试 一、前言介绍 &#x1f4a1; 服务端接收数据后我们希望是一个字符串或者是一个对象类型,而不是字节码。 在 netty 中是否可以…

数据结构与算法基础-学习-33-归并排序

目录 一、基本思想 二、算法思路 1、合并两个有序序列 2、分治法 三、算法源码 1、MergeSortTwoSortData 2、TwoWayMergeSortRecurtionSentryQueue 四、算法效率分析 五、Linux环境编译测试 六、小感慨 排序的其他相关知识点和源码分享可以参考之前的博客&#xff1a…

解决 Android 依赖冲突

解决办法 问题原因就是&#xff0c;各个模块所有的依赖&#xff08;递归&#xff09;的 jar 包最后都会加载到安卓的项目中&#xff0c;你可以选择 project 形式查看 External Libraries&#xff0c;都在这了。所以解决问题关键就是干掉冲突&#xff0c;剩下一个就行了&#xf…

将Apache服务与内网穿透结合,让您的网站可以公网访问

Apache服务安装配置与结合内网穿透实现公网访问 文章目录 Apache服务安装配置与结合内网穿透实现公网访问前言1.Apache服务安装配置1.1 进入官网下载安装包1.2 Apache服务配置 2.安装cpolar内网穿透2.1 注册cpolar账号2.2 下载cpolar客户端 3. 获取远程桌面公网地址3.1 登录cpo…

2023年中国电影行业研究报告

第一章 行业概况 1.1 定义 电影行业是一门涉及电影制作、发行、放映和推广的综合艺术和商业活动。它结合了戏剧、音乐、舞蹈、绘画等多种艺术形式&#xff0c;通过视觉和听觉的方式向观众展示故事和情感。 电影不仅仅是一门艺术&#xff0c;更是一项复杂的商业运作。它涵盖了…

element el-input 二次封装

说明&#xff1a;为实现输入限制&#xff0c;不可输入空格&#xff0c;长度限制。 inputView.vue <template><!-- 输入框 --><el-input:type"type":placeholder"placeholder"v-model"input"input"inputChange":maxle…

短信轰炸漏洞绕过的多种方法技巧

前言&#xff1a; 在测试甲方业务或者挖 SRC 等业务的时候&#xff0c;经常碰到发送短信验证的地方&#xff0c;我们可以联想到的就是任意用户登陆、短信轰炸、任意用户修改密码等逻辑性的漏洞&#xff0c; 简单的漏洞也是需要清晰的思维分析&#xff0c;拿几个短信轰炸多个绕…

实战系列(三)| Mybatis和MybatisPlus区别,包含详细代码

目录 1. 底层框架&#xff1a;2. 代码差异&#xff1a;3. 使用差异&#xff1a;4. 案例代码分析&#xff1a;4.1 MyBatis4.2 MyBatisPlus MyBatis 和 MyBatisPlus 都是基于 MyBatis 的扩展库&#xff0c;用于简化 MyBatis 的开发。MyBatisPlus 是在 MyBatis 的基础上进行封装&a…

华为云云耀云服务器L实例评测 | 华为云云耀云服务器L实例使用教学

文章目录 前言一、登录华为云二、创建云服务器L实例三、登录云服务器L实例四、使用云服务器L实例后记 前言 华为云是中国领先的云计算服务提供商之一&#xff0c;旗下的云耀云服务器是一种高性能、高可靠性、灵活可扩展的云服务器。 下面&#xff0c;我将为大家介绍华为云云耀云…

STM32-固件打包部署

STM32-固件打包部署 Fang XS.1452512966qq.com STM32固件输出 工程上使用Keil开发STM32软件&#xff1b;在调试过程中&#xff0c;可直接编译下载&#xff1b;例如bootloader和APP&#xff0c;在调试时&#xff0c;可以直接下载2次&#xff1b;但是工程上&#xff0c;需要大…

第四章 Linux常用命令

第四章 Linux常用命令 1.Linux命令 ​ 要使用命令&#xff0c;必须先启动Shell程序。用户可以通过桌面右键打开终端&#xff0c;或使用CtrlAltT组合启动Shell&#xff0c;当然也可以从左侧dock面板上找到终端图标打开&#xff0c;打开后如下图&#xff1a; ​ Shell命令由命令…

真嘟假嘟?!这么清晰简单的字符函数和字符串函数!!!

目录​​​​​​​ 1. 字符分类函数 1.1 小练习 1.1.1 方法一 2. 字符转换函数 2.1 小练习的方法二 3. strlen的使⽤和模拟实现 3.1 注意事项 3.1.1 注意事项2的练习 3.2 strlen函数的模拟实现 3.2.1 方法一 3.2.2 方法二&#xff08;指针—指针&#xff09; 3.2.…

Unreal Engine Loop 流程

引擎LOOP 虚幻引擎的启动是怎么一个过程。 之前在分析热更新和加载流程过程中&#xff0c;做了一个图。记录一下&#xff01;&#xff01; ![在这里插入图片描述](https://img-blog.csdnimg.cn/f11f7762f5dd42f9b4dd9b7455fa7a74.png#pic_center 只是记录&#xff0c;以备后用…

C++ 中 API 兼容与 ABI 兼容万字详解

文章目录 API 的生命周期兼容性级别向后兼容性向前兼容性功能兼容性源代码兼容性二进制兼容性 究竟是什么导致了二进制不兼容二进制不兼容可能导致的现象怎样维护源代码兼容添加功能修改功能弃用声明&#xff08;向后兼容&#xff09;移除功能&#xff08;向后兼容&#xff09;…