Spark+SpringBoot+Vue电商数据柱状图可视化

161 阅读2分钟

使用Spark+SpringBoot+Vue3+Echarts做一个简单的各个省份金额消费柱状图分析

效果如图所示 截屏2024-07-13 18.12.39.png

Spark部分

import org.apache.spark.sql.{DataFrame, SaveMode, SparkSession}

import java.util.Properties

/**
 * @Description
 * @Author Hito
 * @Date 2024/7/12
 *
 *
 */
object Spark05Read_HDFS_MYSQL {
  def main(args: Array[String]): Unit = {
    System.setProperty("HADOOP_USER_NAME","root")
    val spark = new SparkSession.Builder()
      .config("dfs.client.use.datanode.hostname", "true")
      .master("local[*]")
      .appName("READ_HDFS_FILE")
      .getOrCreate()

    val df: DataFrame = spark.read
      .option("header","true")
      .csv("hdfs://bigdata1:9000/ht/base_province")

    df.show()

    val url = "jdbc:mysql://127.0.0.1:3306/store"
    val user = "root"
    val password = "root"

    df.write
      .mode(SaveMode.Overwrite)
      .jdbc(url,"base_province",new Properties(){
        {
          put("user",user)
          put("password",password)
        }
      })

    spark.stop()
  }
}

使用spark读取存入HDFS中已经分析好的CSV文件 CSV数据如下

截屏2024-07-13 18.15.28.png 再将数据存入Mysql

SpringBoot部分

CorsConfig

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedOrigin("*"); // 允许所有来源
        config.addAllowedMethod("*"); // 允许所有请求方法
        config.addAllowedHeader("*"); // 允许所有请求头

        org.springframework.web.cors.UrlBasedCorsConfigurationSource source = new org.springframework.web.cors.UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);

        return new CorsFilter(source);
    }
}

ProvinceDao

public interface ProvinceDao extends JpaRepository<BaseProvince,String> {
}

BaseProvince

@SuppressWarnings("serial")
@Entity
@Table(name = "base_province")
public class BaseProvince {

    @Id
    private String id;

    private String name;

    private String region_id;

    private String area_code;

    private String iso_code;

    private String iso_3166_2;

    private String create_time;

    private String operate_time;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getRegion_id() {
        return region_id;
    }

    public void setRegion_id(String region_id) {
        this.region_id = region_id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getIso_code() {
        return iso_code;
    }

    public void setIso_code(String iso_code) {
        this.iso_code = iso_code;
    }

    public String getIso_3166_2() {
        return iso_3166_2;
    }

    public void setIso_3166_2(String iso_3166_2) {
        this.iso_3166_2 = iso_3166_2;
    }

    public String getCreate_time() {
        return create_time;
    }

    public void setCreate_time(String create_time) {
        this.create_time = create_time;
    }

    public String getOperate_time() {
        return operate_time;
    }

    public void setOperate_time(String operate_time) {
        this.operate_time = operate_time;
    }

    public String getArea_code() {
        return area_code;
    }

    public void setArea_code(String area_code) {
        this.area_code = area_code;
    }
}

ProvinceController

@RestController
@RequestMapping("/store")
public class ProvinceController {

    @Autowired
    private ProvinceDao provinceDao;

    @RequestMapping("/province")
    public List<BaseProvince> getProvince() {
        return provinceDao.findAll();
    }
}

dddc1dea65ff536d14368a980dc6e37a.png

接口有数据

然后再用axios接收数据,Vue3+echarts进行渲染 Province.vue

<template>
    <div id="chart" style="width: 1000px; height: 600px;"></div>
</template>

<script>
import * as echarts from "echarts";
import axios from "axios";
import { ref, onMounted } from 'vue';

export default {
    name: 'province',
    setup() {
        const data1 = ref(null);

        const fetchData = async () => {
            try {
                const response = await axios.get("http://127.0.0.1:8080/store/province");
                data1.value = response.data;
                console.log("Fetched data", data1.value);
                BarChart(); // 数据加载完成后立即渲染图表
            } catch (error) {
                console.error("Error ", error);
            }
        }

        const BarChart = () => {
            if (!data1.value) {
                return;
            }

            // 确保 chart 元素已经挂载
            if (!document.getElementById('chart')) {
                console.error("Chart container not found");
                return;
            }

            const chart = echarts.init(document.getElementById('chart'));

            const opt = {
                title: {
                    text: 'Province Data',
                    left: 'center'
                },
                tooltip: {
                    trigger: 'item'
                },
                xAxis: {
                    type: 'category',
                    data: data1.value.map(province => province.name)
                },
                yAxis: {
                    type: 'value'
                },
                series: [
                    {
                        name: 'Area Code',
                        type: 'bar',
                        data: data1.value.map(province => parseInt(province.area_code))
                    }
                ]
            };

            chart.setOption(opt);
        }

        onMounted(() => {
            fetchData();
        });

        return {
            data1,
            BarChart
        }
    }
}
</script>

<style>
    
</style>