前言
前面的文章我们已经介绍了如何获取沪深300成分股所述行业以及权重的数据,想要了解这部分内容的小伙伴可以阅读上一篇文章
springboot+jdbcTemplate+sqlite编程示例——以沪深300成分股数据处理为例-CSDN博客
那么有了上文获取的数据,我们实际上可以计算一下沪深300按照行业分布的权重占比数据,最后的成果如下所示
是不是效果还挺酷的,下面就来介绍一下技术细节。
后端技术细节
首先来讲一下后端的技术细节,其实后端需要做的就是从表中获取按行业区分的权重数据,我们先来看一下数据表
数据表中包含了所述行业和权重占比,那么思路就很明确了,我们只需要查出所有的行业,然后按照行业统计权重之和就行了。
我们的实体类非常简单,就是所属行业和对应的权重
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CSI300DistVO {
private String industry;
private Double weight;
}
接着就是使用JdbcTemplate将数据查出来
public List<CSI300DistVO> queryDist() {
// 首先查询所有的行业
String sql = "SELECT DISTINCT industry FROM "+ tableName;
List<String> industrys = jdbcTemplate.queryForList(sql, String.class);
// 查询每个行业的权重和
List<CSI300DistVO> csi300DistVOList = new ArrayList<>();
for(int i=0; i<industrys.size(); i++) {
sql = "SELECT SUM(weight) FROM " + tableName +
" WHERE industry=?";
Object[] params = new Object[] {
industrys.get(i),
};
Double weight = jdbcTemplate.queryForObject(sql, params,Double.class);
// 保留四位小数
String tmp = String.format("%.4f", weight);
weight = Double.parseDouble(tmp);
CSI300DistVO entity = new CSI300DistVO(industrys.get(i), weight);
csi300DistVOList.add(entity);
log.info(entity.toString());
}
return csi300DistVOList;
}
然后通过get请求提供查询服务
@RequestMapping("/queryDist")
@ResponseBody
public String queryDist() {
List<CSI300DistVO> csi300DistVOS = sqlIteCSI300Dao.queryDist();
return JSON.toJSONString(csi300DistVOS);
}
最后获取的数据如下
[{
"industry": "金融业",
"weight": 21.714
}, {
"industry": "房地产业",
"weight": 1.342
}, {
"industry": "制造业",
"weight": 55.217
}, {
"industry": "批发和零售业",
"weight": 0.324
}, {
"industry": "采矿业",
"weight": 4.333
}, {
"industry": "电力、热力、燃气及水的生产和供应业",
"weight": 3.193
}, {
"industry": "租赁和商务服务业",
"weight": 0.889
}, {
"industry": "交通运输、仓储和邮政业",
"weight": 3.242
}, {
"industry": "信息传输、软件和信息技术服务业",
"weight": 4.308
}, {
"industry": "农、林、牧、渔业",
"weight": 1.206
}, {
"industry": "卫生和社会工作业",
"weight": 0.569
}, {
"industry": "科学研究和技术服务业",
"weight": 1.346
}, {
"industry": "文化、体育和娱乐业",
"weight": 0.112
}, {
"industry": "建筑业",
"weight": 2.109
}, {
"industry": "住宿和餐饮业",
"weight": 0.09
}]
后端的逻辑非常简单,下面来介绍一下前端的技术细节。
前端技术细节
前端我们采用的技术栈是vue+elemenet-plus+axios+echarts,思路大概就是都使用axios请求后端的数据,等到数据获取到了然后再将echarts图标绘制到页面上。
这里面主要是echart饼图的绘制,这里面我研究了好久,参数还挺多的,我会着重介绍一下。
我们之前说过,整个过程就是首先使用axios通过get请求获取后端数据,然后再进行图标的渲染,我们知道axios的请求是异步的,我们需要首先请求数据,等到数据请求成功后再进行图表的绘制。
下面我将绘制饼状图的代码都贴出来
// 绘制饼状图
create_pie() {
var url = "http://localhost:9001/queryDist";
axios
.get(url)
.then((response) => {
console.log(response);
for (var i = 0; i < response.data.length; i++) {
this.pie_data.push({
value: response.data[i].weight,
name: response.data[i].industry,
});
}
console.log(this.pie_data);
var myChart = this.echarts.init(this.$refs["myChart"]);
var option = {
title: {
text: "沪深300行业权重分布", //标题
},
tooltip: {},
legend: {
y: 50,
textStyle: {
fontSize: 14,
},
},
label: {
show: true,
},
series: [
{
name: "分布", //数据的名字
type: "pie", //表示柱状图
radius: "70%", //圆的半径
center: ["50%", "60%"],
label: {
formatter: function (params) {
console.log(params.name + " " + params.value + "%");
return params.name + " " + params.value + "%";
},
textStyle: {
fontSize: 14,
fontWeight: "bolder",
},
color: "inherit",
},
data: this.pie_data,
selectedMode: "single", //选中效果,使选中区域偏离圆心一小段距离,single或者multiple
selectedOffset: 10, //偏离圆心的一小段距离
},
],
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
})
.catch((error) => {
console.log(error);
});
},
我们介绍一些比较重要的参数,绘制的时候比较重要的参数都在series中
series中对应的参数如下:
- name:名称
- type:图标的类型,当设置成"pie"的时候表示饼状图
- radues:表示饼状图半径的大小
- center:表示圆心在画面中的位置,横着的是x轴,竖着的是y轴,我这样设置就会让饼状图中屏幕中间偏下的位置,方便上方标签的显示
- label:表示饼状图中标签的文字显示
- formatter表示我们要显示标签的格式,我们可以自定义要显示的内容
- textStyle可以设置文字的大小和样式
- color可以设置文字的颜色,"inherit"表示颜色跟随对应的扇形的颜色
- data:我们要展示的数据
- selectedMode:表示选中的效果
- selectedOffset:扇形被选中的时候放大的幅度
我们目前只是用了这些属性,当然echart还有非常多的属性可以设置,感兴趣的可以自行探索。
下面是这个页面的完整代码
<template>
<div>
<el-row class="container">
<div class="left-grid">
<el-card>
<el-table
:data="table_data"
:show-header="true"
:max-height="615"
stripe
>
<el-table-column
prop="id"
label="序号"
width="65%"
></el-table-column>
<el-table-column prop="code" label="股票代码"></el-table-column>
<el-table-column prop="name" label="公司简称"></el-table-column>
<el-table-column prop="industry" label="所属行业"></el-table-column>
<el-table-column prop="weight" label="权重占比"></el-table-column>
</el-table>
</el-card>
</div>
<div class="right-grid" ref="myChart"></div>
</el-row>
</div>
</template>
<script>
import axios from "axios";
import { getCurrentInstance } from "vue";
export default {
data() {
return {
table_data: [],
pie_data: [],
echarts: getCurrentInstance().appContext.config.globalProperties.$echarts,
};
},
mounted() {
this.init();
},
methods: {
init() {
var url = "http://localhost:9001/queryAll";
axios
.get(url)
.then((response) => {
this.table_data = response.data;
console.log(response);
})
.catch((error) => {
console.log(error);
});
this.create_pie();
},
// 绘制饼状图
create_pie() {
var url = "http://localhost:9001/queryDist";
axios
.get(url)
.then((response) => {
console.log(response);
for (var i = 0; i < response.data.length; i++) {
this.pie_data.push({
value: response.data[i].weight,
name: response.data[i].industry,
});
}
console.log(this.pie_data);
var myChart = this.echarts.init(this.$refs["myChart"]);
var option = {
title: {
text: "沪深300行业权重分布", //标题
},
tooltip: {},
legend: {
y: 50,
textStyle: {
fontSize: 14,
},
},
label: {
show: true,
},
series: [
{
name: "分布", //数据的名字
type: "pie", //表示柱状图
radius: "70%", //圆的半径
center: ["50%", "60%"],
label: {
formatter: function (params) {
console.log(params.name + " " + params.value + "%");
return params.name + " " + params.value + "%";
},
textStyle: {
fontSize: 14,
fontWeight: "bolder",
},
color: "inherit",
},
data: this.pie_data,
selectedMode: "single", //选中效果,使选中区域偏离圆心一小段距离,single或者multiple
selectedOffset: 10, //偏离圆心的一小段距离
},
],
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
})
.catch((error) => {
console.log(error);
});
},
},
};
</script>
<style scoped>
.container {
display: grid;
grid-template-columns: 35% 65%;
width: 100%;
height: 80vh;
}
.left-grid {
background-color: #f0f0f0;
border-radius: 2%;
padding: 10px;
height: 95%;
}
.right-grid {
background-color: #f9ecc3;
border-radius: 2%;
padding: 10px;
height: 95%;
}
</style>
最后再放一张显示的效果
数据分析
这部分我们进行一下简单的数据分析。
从数据中可以看出来,目前沪深300指数中制造业占比最高,高达55.217%;金融业第二,占比21.714%;排名第三的是采矿业,占比4.333%;排名第四的是信息技术服务业,占比4.308%;排名第五的是物流行业,占比3.242%;排名第六的是电力等基础设施行业,占比3.193%,剩下的一些行业占比就比较低了。
从这组数据中我们可以看出来,我们国家的经济发展还是以制造业为主,金融业为辅的模式,至少沪深300指数构成来看是这样的。
好了,本文就到这里了,有什么想说的欢迎留言和我交流。