Vue3+SpringBoot+echarts实现数据可视化首页

一、前置工作

        通过npm引入echarts等就不在介绍,echarts官网地址echarts官网,可以从中挑选喜欢的组件自行修改。

        界面图形效果如下:

二、前端

        在页面首先定义一个容器,用于存放图形展示的位置。前后端交互主要思路(以折柱结合图为例):
        在页面定义好echarts后,我们需要做的主要就是从后端拿去X、Y轴数据来填充。这里需要注意X轴一般是固定的值。而Y轴的值则是与X轴对应的number值。如果你想展示一个种数据,那么后端返回一个Y轴数据,如果想展示两种数据,那么后端需要返回两个Y轴数据。以此类推。将数据填充好后剩下的就是echarts组件的一些功能按需引入,代码中有一些关键点注释,大家可以直接参考,echarts封装的组件还是非常强大的,若有一些特殊需求,请参考官网文档。此为一个完整页面,可以直接运行,若仅仅需要展示图像,那么请只关注这部分相关的逻辑。

<template>
  <div style="margin-left:15px;">
    <h2>系统公告</h2>
    <el-row style="margin-top: 15px;">
      <el-col :span="12">
        <el-collapse v-model="activeName" accordion>
          <el-collapse-item
            v-for="item in noticeData"
            :key="item.id"
            :title="item.name"
            :name="item.id"
          >
            <div style="padding:0 20px;">
              <strong>公告内容:</strong>
              {{ item.content }}
            </div>
            <div style="padding:0 20px;">
              <strong>发布时间:</strong>
              {{ item.pubDate }}
            </div>
          </el-collapse-item>
        </el-collapse>
      </el-col>
      <el-col :span="4" class="statisticStyle">
        <el-statistic title="展示数据1" :value="268500" />
      </el-col>
      <el-col :span="4" class="statisticStyle">
        <el-statistic title="展示数据2" :value="outputValue" />
      </el-col>
      <el-col :span="4" class="statisticStyle">
        <el-statistic title="展示数据3" :value="123213" />
      </el-col>
    </el-row>
    <el-row style="margin-top: 45px;">
      <el-col :span="12" class="statisticStyle">
        <div ref="echartsRef" style="height: 400px; width: 500px">gamePlay</div>
      </el-col>
      <el-col :span="12" class="statisticStyle">
        <div ref="echartsPie" style="height: 400px; width: 500px">echartsPie</div>
      </el-col>
    </el-row>
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import { useTransition } from "@vueuse/core";
import * as echarts from "echarts";
import { getData, getData2 } from "@/api/test/newindex";

const echartsRef = ref();
const echartsPie = ref();
const echartsLine = ref();
const noticeData = [
  { id: 1, name: "公告标题1", content: "公告内容1", pubDate: "2024-04-11" },
  { id: 2, name: "公告标题2", content: "公告内容2", pubDate: "2024-04-11" },
  { id: 3, name: "公告标题3", content: "公告内容3", pubDate: "2024-04-11" },
  { id: 4, name: "公告标题4", content: "公告内容4", pubDate: "2024-04-11" },
  { id: 5, name: "公告标题5", content: "公告内容5", pubDate: "2024-04-11" },
];
const activeName = ref(noticeData.length > 0 ? noticeData[0].id : "");
onMounted(() => {
  initBar();
});
const source = ref(0);
const outputValue = useTransition(source, {
  duration: 1500
});
source.value = 172000;
function initBar() {
  getData().then(res => {
    if (res.code == 200 && res.data != null) {
      getBar(res.data.xAxis, res.data.yAxis, res.data.yAxis2);
    }
  });
  getData2().then(res => {
    if (res.code == 200 && res.data != null) {
      getPie(res.data);
    }
  });
}
function getBar(xAxis, yAxis, yAxis2) {
  const myChart = echarts.init(echartsRef.value);
  // 指定图表的配置项和数据
  const option = {
    title: {
      text: "柱状图示例"
    },
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "cross",
        crossStyle: {
          color: "#999"
        }
      }
    },
    //右上角操作区
    toolbox: {
      feature: {
        dataView: { show: true, readOnly: false },
        magicType: { show: true, type: ["line", "bar"] },
        restore: { show: true },
        saveAsImage: { show: true }
      }
    },
    //图例
    legend: {
      data: ["错误数量", "占比"]
    },
    xAxis: {
      data: xAxis
    },
    yAxis: [
      {
        type: "value",
        name: "错误数量",
        show: true,
        interval: 10,
        axisLine: {
          lineStyle: {
            color: "#5e859e",
            width: 2
          }
        }
      },
      {
        type: "value",
        name: "占比",
        min: 0,
        max: 100,
        interval: 10,
        axisLabel: {
          formatter: "{value} %"
        },
        axisLine: {
          lineStyle: {
            color: "#5e859e", //纵坐标轴和字体颜色
            width: 2
          }
        }
      }
    ],
    series: [
      {
        name: "错误数量",
        type: "bar",
        data: yAxis
      },
      {
        name: "占比",
        type: "line",
        smooth: true,
        yAxisIndex: 1, //索引从0开始
        data: yAxis2,
        tooltip: {
          valueFormatter: function(value) {
            return value + " %";
          }
        }
      }
    ]
  };

  // 使用刚指定的配置项和数据显示图表。
  myChart.setOption(option);
}
function getLine(xAxis, yAxis) {
  const myChartLine = echarts.init(echartsLine.value);
  // 指定图表的配置项和数据
  const option = {
    title: {
      text: "折线图示例"
    },
    tooltip: {},
    legend: {
      data: [
        {
          name: "错误数量",
          // 强制设置图形为圆。
          icon: "circle",
          // 设置文本为红色
          textStyle: {
            color: "black"
          }
        }
      ]
    },
    xAxis: {
      data: xAxis
    },
    yAxis: {},
    series: [
      {
        name: "错误数量",
        type: "line",
        data: yAxis
      }
    ]
  };
  // 使用刚指定的配置项和数据显示图表。
  myChartLine.setOption(option);
}
function getPie(data) {
  const myChartPie = echarts.init(echartsPie.value);
  const option = {
    title: {
      text: "饼状图示例"
    },
    tooltip: {
      trigger: "item"
    },
    // //右上角操作区
    // toolbox: {
    //   feature: {
    //     dataView: { show: true, readOnly: false },
    //     restore: { show: true },
    //     saveAsImage: { show: true }
    //   }
    // },
    radius: ["40%", "70%"],
    legend: {
      top: "5%",
      left: "center"
    },
    series: [
      {
        name: "访问来源",
        type: "pie", // 设置图表类型为饼图
        radius: ["40%", "70%"], // 饼图的半径,外半径为可视区尺寸(容器高宽中较小一项)的 55% 长度。
        itemStyle: {
          borderRadius: 10,
          borderColor: "#fff",
          borderWidth: 2
        },
        toolyip: {
          trigger: "item",
          formatter: "{b}:{c}({d}%)"
        },
        label: {
          show: false,
          position: "center"
        },
        //中间框字体样式
        emphasis: {
          label: {
            show: true,
            fontSize: 30,
            fontWeight: "bold"
          }
        },
        labelLine: {
          show: false
        },
        data
      }
    ]
  };

  myChartPie.setOption(option);
}
</script>
<style scoped>
.el-statistic {
  --el-statistic-content-font-size: 38px;
  --el-statistic-title-font-size: 18px;
}
.el-collapse-item{
  --el-collapse-header-font-size: 16px;
  
}
::v-deep .el-collapse-item__header{
  font-weight: 550;
}
.statisticStyle {
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  flex-wrap: nowrap; /* 防止子元素换行 */
}
</style>>

三、后端 

        此处仅仅演示了前后端交互效果,并没有具体业务逻辑,大家可以根据自己业务逻辑来实现。

@RestController
@RequestMapping("/echartsData")
public class EchartsDataController {


    @GetMapping("/echarts/chartOne")
    public AjaxResult chartOne(){
        //返回前端的数据
        List<Map<String,Object>> mapList = new ArrayList<>();
            //循环
        List<String> xAxis = new ArrayList<>();
        List<Integer> yAxis = new ArrayList<>();
        List<Integer> yAxis2 = new ArrayList<>();
        String[] clothes = {"数字", "宽带", "OTT", "移网", "固话", "集团"};
        xAxis.addAll(Arrays.asList(clothes));
        int[] number = {5, 20, 36, 10, 10, 20};
        for (int num : number) {
            yAxis.add(num);
        }
        int[] number2 = {5, 30, 66, 10, 20, 80};
        for (int num : number2) {
            yAxis2.add(num);
        }
        Map<String,Object> map = new HashMap<>();
        map.put("xAxis",xAxis);
        map.put("yAxis",yAxis);
        map.put("yAxis2",yAxis2);
        return AjaxResult.success(map);
    }

    @GetMapping("/echarts/chartTwo")
    public AjaxResult chartTwo(){
        //返回前端的数据
        List<PieDto> list = new ArrayList<>();
        list.add(new PieDto("视频广告",235));
        list.add(new PieDto("邮件营销",610));
        list.add(new PieDto("直接访问",335));
        list.add(new PieDto("搜索引擎",600));
        list.add(new PieDto("小程序跳转",835));
        return AjaxResult.success(list);
    }

dto如下

@Data
@AllArgsConstructor
public class TestDto {
    private String name;
    private int number;
    private String type;
}
@Data
@AllArgsConstructor
public class PieDto {
    private String name;
    private int value;
}

 

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值