今日在工作项目中遇到了需要在spring boot + vue项目中实现饼图,我就选择了使用平时使用比较广泛的echarts,话不多说 先看效果
饼图中的所有所需数据,只调用了一次sql 那么我的实现思路是什么呢
我们通过查阅官方资料可以知道,data中的数据便是我们在饼图效果展示中所需要用到的数据,那么我们如果想要实现这样一个饼图,我们在后端按照它的数据格式返回相应的数据就可以了
也就是说我们需要返回一个List<Map<Object,Object>>这样的值回到前端,那么我们需要在sql进行查询的时候,按照所需值获取相应的数据
首先我们需要一个name值,用来说明每个'块'中所包含的内容,然后我们需要一个count值进行数据统计,所以我们可以很简单的得到以下的查询结果
如图所示,我们查出来的数据中包含一个name和一个count,由于我的这个字段为外键,所以后续需要进行二次处理加工
那么我们所需要的值得到了,后端代码只需要返回到前端即可
public AjaxResult count(){ List<Map<Object,Object>> stringIntegerMap = GeneralService.countByGeneralLevel(); List<Map<Object,Object>> transformedData = new ArrayList<>(); for (Map<Object,Object> item : stringIntegerMap) { Object count = item.get("count"); Object general_level = item.get("general_level"); // 创建包含名称和数据的 Map 对象 Map<Object, Object> seriesData = new HashMap<>(); seriesData.put("value", count); seriesData.put("name", general_level); // 将 Map 对象添加到转换后的数据列表中 transformedData.add(seriesData); } return AjaxResult.success(transformedData); }
这边进行说明,本身我们在图中需要的值分别为“value”以及“name” 那么我们查询到的字段名显然是不符合规则的,那么我们就需要进行二次加工,将数据转化为我们想要的名称格式再进行返回,当然,我们在查询的时候给数据指定别名也是可以达到同样的效果
我们在后端返回之后查看前端代码
由于我们是基于echarts来实现的饼图效果,那么我们在vue的main文件中需要先进行安装引用
npm install echarts --save
import * as echarts from 'echarts';
Vue.prototype.$echarts = echarts
ok,基本工作解决以后 我们开始实现效果
这是官方的文档,很多朋友刚开始学习使用echarts的时候可能不清楚应该如何去使用
给大家看一下我的代码实现
<div class="echart" id="mychart" :style="myChartStyle"></div>
这部分代码在写在前端显示的位置,style是我们在下面声明的图表样式
//饼图
myChart: {},
countList:[],
pieName: [],
myChartStyle: { float: "left", width: "100%", height: "300px" }, //图表样式
这部分代码声明参数,并设置样式,写在data的return下
async initEcharts() {
let mychat = this.$echarts.init(document.getElementById("mychart"));
await countGeneral().then(response => {
const data = response.data;
this.countList = data.map(item => {
const name = this.selectDictLabel(this.dict.type.fk_general_level, item.name);
return {name:name,value:item.value}
})
})
// 饼图
const option = {
tooltip: {
trigger: 'item'
},
legend: {
top: '5%',
left: 'left',
textStyle: {
color: '#D7E5FF',
},
},
grid: {
left: "0%",
top: "10%",
right: "20%",
bottom: "15%",
},
series: [
{
name: '防范等级',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2,
},
color: [
"#ff0000",
"#ffff00",
"#87CEFA",
],
label: {
show: true,
position: 'outside',
formatter: '{b}: {d}%'
},
emphasis: {
label: {
show: true,
fontSize: 30,
fontWeight: 'bold'
}
},
labelLine: {
show: true
},
data:this.countList
}
]
};
mychat.setOption(option);
},
这就是我们实现效果所需要的全部代码,和官方代码不同的是
由于我们是需要从后端获取到数据,所以我在这边选择使用async设置同步进行,并且在我们调用方法获取返回值的位置使用await来等待参数获取成功
刚才讲过,我在数据库中保存的数据是使用的外键,所以需要额外进行处理,循环获取到外键关联的name值,并存入数组中
那么当我们的数据全部处理结束的时候,我们就可以将处理好的数据放到data中去
data:this.countList
这样的话,我们这个方法的执行逻辑就结束了
还有一个问题是大家需要注意的
我们在饼图的实现,是一定要写在mounted钩子中的,不然会产生报错
比如说我们在created钩子中进行加载
就会产生如图所示的报错 “初始化错误,无效dom”
所以一定不要忘记,图的加载要写在 mounted 钩子中
本次记录结束,欢迎大家留言讨论,共同学习