Echarts入门(SpringBoot + Vue)

news2024/9/20 20:18:23

一、Echarts简介

代码已上传至码云:echarts_boot: echarts使用demo

ECharts是一个使用 JavaScript 实现的"数据可视化"库, 它可以流畅的运行在 PC 和移动设备上

什么是数据可视化?

也就是可以将数据通过图表的形式展示出来,

Echarts官网:Apache ECharts

本篇文章以此柱状图为例:

二、业务背景

数据库中分别有学生表、课程表、成绩表三张表

使用echarts对 某科目全班平均分近三年变化、某个人总分数变化、某人某年各科成绩作统计和可视化操作

表结构如下:

三、数据准备

/*
 Navicat Premium Data Transfer

 Source Server         : CloudShell
 Source Server Type    : MySQL
 Source Server Version : 50736 (5.7.36)
 Source Host           : 124.70.69.186:13306
 Source Schema         : echarts_test

 Target Server Type    : MySQL
 Target Server Version : 50736 (5.7.36)
 File Encoding         : 65001

 Date: 01/07/2023 15:44:13
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `cou_num` int(11) DEFAULT NULL COMMENT '课程号',
  `cou_name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '课程名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='课程表';

-- ----------------------------
-- Records of course
-- ----------------------------
BEGIN;
INSERT INTO `course` (`id`, `cou_num`, `cou_name`) VALUES (1, 1, '语文');
INSERT INTO `course` (`id`, `cou_num`, `cou_name`) VALUES (2, 2, '数学');
INSERT INTO `course` (`id`, `cou_num`, `cou_name`) VALUES (3, 3, '英语');
COMMIT;

-- ----------------------------
-- Table structure for score
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `cou_num` int(11) NOT NULL COMMENT '课程号',
  `stu_num` int(11) NOT NULL COMMENT '学号',
  `score` int(11) DEFAULT NULL COMMENT '成绩',
  `time` timestamp NULL DEFAULT NULL COMMENT '时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='成绩表';

-- ----------------------------
-- Records of score
-- ----------------------------
BEGIN;
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (1, 1, 1, 90, '2023-06-30 09:57:19');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (2, 2, 1, 88, '2023-06-30 09:57:31');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (3, 3, 1, 95, '2023-06-30 09:57:42');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (4, 1, 2, 70, '2023-06-30 09:57:54');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (5, 2, 2, 99, '2023-06-30 09:58:04');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (6, 3, 2, 60, '2023-06-30 09:58:12');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (7, 1, 3, 56, '2023-06-30 09:58:20');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (8, 2, 3, 32, '2023-06-30 09:58:31');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (9, 3, 3, 43, '2022-06-30 09:58:48');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (10, 1, 1, 88, '2022-06-30 09:57:19');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (11, 2, 1, 86, '2022-06-30 09:57:31');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (12, 3, 1, 93, '2022-06-30 09:57:42');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (13, 1, 2, 70, '2022-06-30 09:57:54');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (14, 2, 2, 99, '2022-06-30 09:58:04');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (15, 3, 2, 60, '2022-06-30 09:58:12');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (16, 1, 3, 56, '2022-06-30 09:58:20');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (17, 2, 3, 32, '2022-06-30 09:58:31');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (18, 3, 3, 43, '2022-06-30 09:58:48');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (19, 1, 1, 86, '2021-06-30 09:57:19');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (20, 2, 1, 84, '2021-06-30 09:57:31');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (21, 3, 1, 91, '2021-06-30 09:57:42');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (22, 1, 2, 70, '2021-06-30 09:57:54');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (23, 2, 2, 99, '2021-06-30 09:58:04');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (24, 3, 2, 60, '2021-06-30 09:58:12');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (25, 1, 3, 56, '2021-06-30 09:58:20');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (26, 2, 3, 32, '2021-06-30 09:58:31');
INSERT INTO `score` (`id`, `cou_num`, `stu_num`, `score`, `time`) VALUES (27, 3, 3, 43, '2021-06-30 09:58:48');
COMMIT;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `stu_num` int(11) NOT NULL COMMENT '学号',
  `stu_name` varchar(255) COLLATE utf8mb4_bin NOT NULL COMMENT '姓名',
  `stu_sex` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='学生表';

-- ----------------------------
-- Records of student
-- ----------------------------
BEGIN;
INSERT INTO `student` (`id`, `stu_num`, `stu_name`, `stu_sex`) VALUES (1, 1, '张三', '男');
INSERT INTO `student` (`id`, `stu_num`, `stu_name`, `stu_sex`) VALUES (2, 2, '李四', '女');
INSERT INTO `student` (`id`, `stu_num`, `stu_name`, `stu_sex`) VALUES (3, 3, '王五', '男');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

四、构建后端工程 

1.添加依赖

mysql、mybaits-plus和lombok

<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- mybaits-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>

 2.编辑配置文件

server:
  port: 18889
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/echarts_test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&AllowPublicKeyRetrieval=True&useSSL=false
    username: root
    password: root


mybatis-plus:
  mapper-locations: mapper/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
  type-aliases-package: com.crazyk.echartsboot.bo

 3.根据数据库表结构构件项目包和类

以学生实体为例 

实体类

package com.crazyk.echartsboot.bo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

/**
 * @program: EchartsBoot
 * @description: 学生实体
 * @author: CrazyK
 * @create: 2023-06-30 10:02
 **/
@Data
@TableName("student")
public class Student {

    @TableId(type = IdType.AUTO)
    private Integer id;

    /**
     * 学号
     */
    private Integer stuNum;

    /**
     * 姓名
     */
    private String stuName;

    /**
     * 性别
     */
    private String StuSex;
}

 mapper接口

package com.crazyk.echartsboot.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.crazyk.echartsboot.bo.Student;
import org.apache.ibatis.annotations.Mapper;

/**
 * @program: EchartsBoot
 * @description: 学生接口
 * @author: CrazyK
 * @create: 2023-06-30 10:08
 **/
@Mapper
public interface StudentMapper extends BaseMapper<Student> {
}

 service实现类

package com.crazyk.echartsboot.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crazyk.echartsboot.bo.Student;
import com.crazyk.echartsboot.mapper.StudentMapper;
import org.springframework.stereotype.Service;

/**
 * @program: EchartsBoot
 * @description: 学生服务
 * @author: CrazyK
 * @create: 2023-06-30 10:10
 **/
@Service
public class StudentService extends ServiceImpl<StudentMapper, Student> {
}

 controller控制类

package com.crazyk.echartsboot.controller;

import com.crazyk.echartsboot.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: EchartsBoot
 * @description: 学生控制层
 * @author: CrazyK
 * @create: 2023-06-30 10:12
 **/
@RestController
@RequestMapping("/student")
public class StudentController {

    @Autowired
    private StudentService studentService;
    
}

 mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.crazyk.echartsboot.mapper.StudentMapper">

</mapper>

 4.编写业务代码

博主太懒了,不想写sql,所以用的stream

package com.crazyk.echartsboot.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.crazyk.echartsboot.bo.Course;
import com.crazyk.echartsboot.bo.Score;
import com.crazyk.echartsboot.bo.Student;
import com.crazyk.echartsboot.service.CourseService;
import com.crazyk.echartsboot.service.ScoreService;
import com.crazyk.echartsboot.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: EchartsBoot
 * @description: 成绩控制层
 * @author: CrazyK
 * @create: 2023-06-30 10:14
 **/
@RestController
@RequestMapping("/score")
public class ScoreController {

    @Autowired
    private ScoreService scoreService;
    @Autowired
    private CourseService courseService;
    @Autowired
    private StudentService studentService;

    /**
     * 某科目全班平均分 近三年变化
     */
    @RequestMapping("avg")
    public Map<String, Integer> avg(String couName){
        Integer couNum = courseService.getOne(new QueryWrapper<Course>().eq("cou_name", couName))
                .getId();
        Map<String, List<Score>> map = scoreService.list(new QueryWrapper<Score>().eq("cou_num", couNum))
                .stream()
                .collect(Collectors.groupingBy(s -> s.getTime().toString().substring(24)));
        Map<String,Integer> res = new HashMap<>();
        for (String key : map.keySet()){
            Double average = map.get(key).stream()
                    .map(s -> s.getScore())
                    .mapToInt(Integer::valueOf)
                    .average().orElse(0D);
            Integer score = Integer.valueOf(String.valueOf(average).substring(0,2));
            res.put(key,score);
        }
        System.out.println(res);
        return res;
    }

    /**
     *  某个人总分数变化
     */
    @RequestMapping("sum")
    public Map<String,Integer> sum(String stuName){
        Integer stuNum = studentService.getOne(new QueryWrapper<Student>().eq("stu_name",stuName)).getStuNum();
        Map<String, List<Score>> map = scoreService.list(new QueryWrapper<Score>().eq("stu_num", stuNum))
                .stream()
                .collect(Collectors.groupingBy(s -> s.getTime().toString().substring(24)));
        Map<String,Integer> res = new HashMap<>();
        for (String key : map.keySet()){
            Integer sum = map.get(key).stream()
                    .map(s -> s.getScore())
                    .mapToInt(Integer::valueOf)
                    .sum();
            res.put(key,sum);
        }
        System.out.println(res);
        return res;
    }

    /**
     *  某人某年各科成绩
     */
    @RequestMapping("own")
    public Map<String,Integer> own(String stuName,String year){
        Integer stuNum = studentService.getOne(new QueryWrapper<Student>().eq("stu_name",stuName)).getStuNum();
        Map<Integer, List<Score>> map = scoreService.list(new QueryWrapper<Score>().eq("stu_num", stuNum))
                .stream()
                .filter(s -> s.getTime().toString().substring(24).equals(year))
                .collect(Collectors.groupingBy(s -> s.getCouNum()));
        Map<String,Integer> res = new HashMap<>();
        for (Integer key : map.keySet()){
            String couName = courseService.getOne(new QueryWrapper<Course>().eq("cou_num",map.get(key).get(0).getCouNum())).getCouName();
            Integer score = map.get(key).get(0).getScore();
            res.put(couName,score);
        }
        System.out.println(res);
        return res;
    }
}

5.接口测试

测试一下刚才写的三个接口

测试没问题就可以开始写前端了

五、构建前端工程

1.创建Vue工程

我创建的是vue2

vue create 项目名

部署成功后安装需要的依赖

npm install vue-router --save #vueRouter
npm i element-ui -S #element-ui
npm install echarts -S #echarts

npm install axios #axios

 2.全局引入

在main.js全局引入,这是vue项目的入口

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import * as echarts from "echarts";
import {postRequest} from "@/utils/api";
import {getRequest} from "@/utils/api";
import {putRequest} from "@/utils/api";
import {deleteRequest} from "@/utils/api";



Vue.config.productionTip = false
Vue.use(ElementUI,{size:'small'});
Vue.prototype.$echarts = echarts;



new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

3.配置代理 

在vue.config.js文件中添加代理,使请求转发到后端端口

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true
})

let proxyObj = {}

proxyObj['/'] = {
  //websocket
  ws: false,
  //目标地址
  target: 'http://localhost:18889',
  changeOrigin: true,
  pathRewrite: {
    '^/': '/'
  }
};

module.exports = defineConfig({
  transpileDependencies: true,
  devServer:{
    host: 'localhost',
    port: 8080,
    proxy: proxyObj
  }
})

4.编写请求工具类 

api.js用于封装请求

import axios from "axios";

let base = '';

//json格式post请求
export const postRequest = (url,params) => {
    return axios({
        method: 'post',
        url: base + url,
        data:params
    })
}

//put请求
export const putRequest = (url,params) => {
    return axios({
        method: 'put',
        url:base + url,
        data:params
    })
}

//get请求
export const getRequest = (url,params) => {
    return axios({
        method: 'get',
        url:base + url,
        data:params
    })
}

//delete请求
export const deleteRequest = (url,params) => {
    return axios({
        method: 'delete',
        url:base + url,
        data:params
    })
}

 然后在main.js中引入请求封装

//插件形式使用请求
Vue.prototype.postRequest = postRequest;
Vue.prototype.getRequest = getRequest;
Vue.prototype.putRequest = putRequest;
Vue.prototype.deleteRequest = deleteRequest;

 5.编写业务组件

<template>
  <div>
    <div>
      <table>
        <tr>
          <td><el-tag>请输入年份</el-tag></td>
          <td><el-input v-model="year" size="small" style="margin-left: 8px"></el-input></td>
          <td><div>&emsp;</div></td>
          <td><el-tag>请输入学生姓名</el-tag></td>
          <td><el-input v-model="stuName" size="small" style="margin-left: 8px"></el-input></td>
          <td><div>&emsp;</div></td>
          <span slot="footer" class="dialog-footer">
            <el-button type="primary" @click="own" size="mini">查询某人某年各科成绩</el-button>
          </span>
        </tr>
        <tr>
          <td><el-tag>请输入学生姓名</el-tag></td>
          <td><el-input v-model="stuName" size="small" style="margin-left: 8px"></el-input></td>
          <td><div>&emsp;</div></td>
          <span slot="footer" class="dialog-footer">
            <el-button type="primary" @click="sum" size="mini">查询某个人总分数变化</el-button>
          </span>
        </tr>
        <tr>
          <td><el-tag>请输入科目名称</el-tag></td>
          <td><el-input v-model="couName" size="small" style="margin-left: 8px"></el-input></td>
          <td><div>&emsp;</div></td>
          <span slot="footer" class="dialog-footer">
            <el-button type="primary" @click="avg" size="mini">查询某科目班级平均分</el-button>
          </span>
        </tr>
      </table>

    </div>
    <div style="height: 500px">
      <h2>this.titleEcharts</h2>
      <div style="height: 100%;width: 100%" ref="histChart"></div>
    </div>
  </div>

</template>

<script >
import * as echarts from 'echarts'
export default {
  data() {
    return {
      chart:null,
      option:{
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: [
          {
            type: 'category',
            data: [],
            axisTick: {
              alignWithLabel: true
            }
          }
        ],
        yAxis: [
          {
            type: 'value'
          }
        ],
        series: [
          {
            name: 'Direct',
            type: 'bar',
            barWidth: '60%',
            data: []
          }
        ]
      },
      year:"",
      stuName:"",
      couName:"",
      titleEcharts:"输入表单信息点击按钮查询"
    }
  },
  watch: {
    seriveData: {
      deep: true,
      handler() {
        this.updateChartView()
      }
    }
  },
  mounted() {
    this.chart = echarts.init(this.$refs.histChart);
    this.updateChartView();
    window.addEventListener('resize',this.handleWindowResize);
  },
  updated() {
    this.updateChartView();
  },
  beforeDestroy() {
    window.removeEventListener('resize',this.handleWindowResize);
  },
  methods: {
    /**
     * 某人某年各科成绩
     */
    own(){
      this.option.xAxis[0].data = [];
      this.option.series[0].data = [];
      let url = '/score/own?stuName=' + this.stuName + '&year=' + this.year;
      this.getRequest(url).then(resp => {
        console.log(resp.data)
        const map = new Map(Object.entries(resp.data));
        for (let [key,value] of map){
          this.option.xAxis[0].data.push(key);
          this.option.series[0].data.push(value);
        }
        this.titleEcharts = this.stuName + "同学" + this.year + "年各科成绩"
        this.stuName = "";
        this.year = "";
        this.updateChartView();
      });
    },
    /**
     * 某个人总分数变化
     */
    sum(){
      this.option.xAxis[0].data = [];
      this.option.series[0].data = [];
      let url = '/score/sum?stuName=' + this.stuName;
      this.getRequest(url).then(resp => {
        console.log(resp.data)
        const map = new Map(Object.entries(resp.data));
        for (let [key,value] of map){
          this.option.xAxis[0].data.push(key);
          this.option.series[0].data.push(value);
        }
        this.titleEcharts = this.stuName + "同学各年总分数变化"
        this.stuName = "";
        this.year = "";
        this.updateChartView();
      });
    },
    /**
     * 某科目班级平均分
     */
    avg(){
      this.option.xAxis[0].data = [];
      this.option.series[0].data = [];
      let url = '/score/avg?couName=' + this.couName;
      this.getRequest(url).then(resp => {
        console.log(resp.data)
        const map = new Map(Object.entries(resp.data));
        for (let [key,value] of map){
          this.option.xAxis[0].data.push(key);
          this.option.series[0].data.push(value);
        }
        this.titleEcharts = this.couName + "科目班级平均分"
        this.couName = "";
        this.updateChartView();
      });
    },
    /**
     * 更新echarts视图
     */
    updateChartView() {
      if (!this.chart) return

      this.chart.setOption(this.option, true)
    },
    /**
     * 窗口缩放时动态调整echarts大小
     */
    handleWindowResize() {
      if (!this.chart) return;
      this.chart.resize();
    }

  }
}
</script>

<style scoped>
h2{
  text-align: center;
  padding: 30px;
  font-size: 18px;
}

</style>

 六、页面展示

1.查询某人某年各科成绩

2.查询某个人总分数变化

3.查询某科目班级平均分

 

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

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

相关文章

9-如何获取N维数组元素?【视频版】

目录 问题视频解答 问题 视频解答 点击观看&#xff1a; 9-如何获取N维数组元素&#xff1f;

基于 Opencv python实现批量图片去黑边—裁剪—压缩软件

简介 批量处理图片文件&#xff0c;批量提取GIF图片中的每一帧&#xff0c;具有范围裁剪、自动去除黑/白边、调整大小、压缩体积等功能。 先看一些软件的界面&#xff0c;是基于Tkinter写的GUI 裁剪等功能基于Opencv 下载 我添加了处理GIF的github&#xff1a; 原作者的gith…

基于Ant DesignPro Vue + SpringBoot 前后端分离 - 后端微服化 + 接口网关 + Nacos

基于Ant DesignPro Vue SpringBoot 前后端分离 - 后端微服化 接口网关 Nacos 通过Ant DesignPro Vue SpringBoot 搭建的后台管理系统后&#xff0c;实现了前后端分离&#xff0c;并实现了登录认证&#xff0c;认证成功后返回该用户相应权限范围内可见的菜单。 后端采用Spri…

一、枚举类型——新特性(将 switch 作为表达式)

switch 一直以来都只是一个语句&#xff0c;并不会生成结果。 JDK 14 使得 switch 还可以作为 一个表达式来使用&#xff0c;因此它可以得到一个值&#xff1a; SwitchExpression.java public class SwitchExpression {static int colon(String s) {var result switch (s) {ca…

基于单片机的智能点滴速度输液液体检测

功能介绍 以51单片机作为主控系统&#xff1b;显示液位&#xff0c;滴数&#xff0c;温度等信息&#xff1b;通过水位传感器检测当前药瓶是否有水&#xff1b;通过滴速传传感器利用单片机定时器计算当前滴速&#xff1b;通过DS18B20温度传感器采集当前药液温度&#xff0c;继电…

【前端】JS语法——数据类型转换

一、字符串&#xff08;里面必须数字&#xff09;转换为数字类型&#xff08;number&#xff09; 1、强制转换&#xff1a;(parseInt()、parseFloat()、Number())&#xff1b; 2、隐式转换&#xff08;number[-/*%]string&#xff09;&#xff1b; <script>let s &qu…

红米K60刷入MIUI.EU安装面具magisk与root教程

文章目录 前言1.解锁BootLoader2.刷入Recovery3.刷入EU的ROM包4.刷入magisk面具后话 前言 教程大概就是四步&#xff0c;解锁&#xff0c;刷入rec&#xff0c;刷入系统&#xff0c;刷入面具&#xff0c;跟着教程走即可。这次是刷机方式&#xff1a;卡刷&#xff08;Recovery&a…

SELECT * 会导致查询效率低的原因

SELECT * 会导致查询效率低的原因 前言一、适合SELECT * 的使用场景二、SELECT * 会导致查询效率低的原因2.1、数据库引擎的查询流程2.2、SELECT * 的实际执行过程2.3、使用 SELECT * 查询语句带来的不良影响 三、优化查询效率的方法四、总结 前言 因为 SELECT * 查询语句会查…

PCL可视化 3D点云PCD文件

工具安装 sudo apt install pcl-tools 启动命令&#xff1a; pcl_viewer 000000.pcd

chatgpt赋能python:在Python官网上下载Python:一位有10年Python编程经验的工程师分享

在Python官网上下载Python&#xff1a;一位有10年Python编程经验的工程师分享 Python是如今最受欢迎的编程语言之一。它是一种易学易用、具有广泛用途的开源语言。如果您刚开始使用Python&#xff0c;或者想要更新到最新版本的Python&#xff0c;Python官网是一个很好的起点。…

QT学习笔记4--自定义信号的槽

逻辑&#xff1a;下课后&#xff0c;老师饿了&#xff0c;学生请吃饭。 使用connect函数连接自定义的信号和槽函数。 创建类 信号 #ifndef TEACHER_H #define TEACHER_H#include <QObject>class teacher : public QObject {Q_OBJECT public:explicit teacher(QObjec…

浙江专升本高等数学易错例题讲解-函数间断点

例题 考察内容&#xff1a;间断点的判断 易错点分析&#xff1a;化简时不能把负数带入根号 浙江专升本高等数学易错例题讲解-函数间断点

【前端1】标签,css,js

文章目录 1.标签&#xff1a;input1.1 html&#xff1a;HTML&#xff08;用于创建网页结构&#xff09;&#xff0c;CSS&#xff08;对页面进行美化&#xff09;&#xff0c;JavaScript&#xff08;用于与用户交互&#xff09;1.2 文本标签&#xff1a;字体属性1.3 a标签&#…

【动手学习深度学习--逐行代码解析合集】03图像分类数据集

【动手学习深度学习】逐行代码解析合集 03图像分类数据集 视频链接&#xff1a;B站-动手学习深度学习 课程主页&#xff1a;https://courses.d2l.ai/zh-v2/ 教材&#xff1a;https://zh-v2.d2l.ai/ 代码 以下代码是在PyCharm中运行的 import matplotlib # 注意这个也要import一…

word整理pdf转换来的文章,或者从网页复制的格式

这是对文章的格式整理。 1、去除 分节符 首先&#xff0c;用格式工厂或者别的pdf转换器等&#xff0c;都会出现为了保持原有格式不变因此增加分节符的情况 添加分节符后&#xff0c;即使这一页还有很大的空白&#xff0c;下一段也会另起一页 而且&#xff0c;单纯的backspa…

Java+控制台实现员工信息管理系统

Java控制台实现员工信息管理系统 一、系统介绍二、功能展示1.主页2.添加员工3.员工列表4.根据员工号查询信息5.根据员工号删除信息6.根据员工号调整员工工资7.退出系统 四、其它1.其他系统实现2.获取源码 一、系统介绍 使用ArrayList对完成一个员工管理系统&#xff0c;员工信…

Flutter 实现任意控件拖动

文章目录 前言一、如何实现&#xff1f;1、使用GestureDetector响应拖动事件2、使用Transform变换控件位置3、计算拖动区域 二、完整代码三、使用示例1、基本用法 总结 前言 使用flutter开发是需要控件能拖动&#xff0c;比如画板中的元素&#xff0c;或者工具条&#xff0c;搜…

chatgpt赋能python:用Python进行数据挖掘来优化SEO排名

用Python进行数据挖掘来优化SEO排名 您是否一直在为如何在搜索引擎排名上优化自己的网站而苦恼&#xff1f;事实上&#xff0c;Python可以成为您的得力助手&#xff0c;来简化您的分析和优化过程&#xff0c;并帮助您在搜索引擎排名上获得更好的结果。 什么是SEO&#xff1f;…

tomcat与自定义类加载器

类加载器与类的”相同“判断 类加载器除了用于加载类外&#xff0c;还可用于确定类在Java虚拟机中的唯一性。 不同类加载器加载的类在 JVM 看来是两个不同的类&#xff0c;因为在 JVM 中一个类的唯一标识是 类加载器类名(包括包名)。 类加载器种类 启动类加载器&#xff0c;…

phpstorm左边变黄,页面内跳转追踪等功能不好使了

第一种方法&#xff1a;删除项目根目录中.idea文件夹(确保删除成功)&#xff0c;然后再重新打开项目即可&#xff08;这个方法对我无效&#xff09; 第二种方法&#xff1a;点击File(文件)->Repair IDE(修复IDE)&#xff0c;按照右下角的指示一步步操作即可&#xff08;这种…