5月28日
由于应届生并不清楚自己将要从事行业的基本行情,我们的系统提供了行业分析模块,为应届毕业生就业方向的选择提供可参考的可视化界面。行业分析模块基于已爬取数据集中的数据,进行数据库中SQL聚合函数的搜索,并将搜索结果返回至前端中进行图表的可视化展示。近期,我完成了行业分析模块的功能实现以及前端可视化展示。
行业薪资数据的查询:
在爬取到的数据中,具有26个热门城市以及36个行业类别的岗位信息,可以通过address与job_type项进行聚合函数的搜索,获取到行业的最高薪资平均以及最低薪资平均数据,搜索的SQL语句如下:
select address,job_type,avg(max_salary) max_salary,avg(min_salary) min_salary
from ourproject.all_positions
group by address,job_type
order by max_salary desc;
将SQL语句写入到dao层MyBatis框架的配置文件,并注入到Spring的容器中,由service层获取到数据并进行处理。
后端部分的数据处理:
建立实体类Analysedata,并编写有参与无参的构造函数、set与get函数、重写toString()方法,实体类包含的字段如下:
private String address;
private String jobType;
private double maxSalary;
private double minSalary;
在controller层中,获取到service层得到的搜索结果,以List数组的形式存储。在这里将完成数据处理并传入到前端展示,需要向前端传递四个List数组,分别为cityLabels、cityName、maxSalaryData、minSalaryData,以供前端的JavaScript直接调用。遍历analysedata,将analysedata中的数据解析至四个List数组中,并返回至前端页面:
@RequestMapping("/toIndustryAnalyse{industry}")
public String toIndustryAnalyse(@PathVariable String industry, HttpSession session) {
List<Analysedata> analysedata = JdServiceImpl.selAnalysedata(industry);
List<String> cityLabels = new ArrayList<>();
List<String> cityName = new ArrayList<>();
List<Integer> maxSalaryData = new ArrayList<>();
List<Integer> minSalaryData = new ArrayList<>();
for (int i = 0; i < analysedata.size(); i++) {
Analysedata ana=analysedata.get(i);
cityLabels.add('"'+ana.getAddress()+'"');
cityName.add(ana.getAddress());
maxSalaryData.add((int)ana.getMaxSalary());
minSalaryData.add((int)ana.getMinSalary());
}
session.setAttribute("industry",industry);
session.setAttribute("cityLabelsList",cityLabels);
session.setAttribute("cityNameList",cityName);
session.setAttribute("maxSalaryData",maxSalaryData);
session.setAttribute("minSalaryData",minSalaryData);
session.setAttribute("isIndustry", true);
return "industryAnalyse";
}
以上为针对各个行业的热门城市平均薪资水平分析的实现,针对各城市的行业平均薪资水平分析的数据处理方式与此相同。
前端部分的可视化实现:
用JavaScript生成Chart对象,把后端传入的数据放进柱状图中,以可视化展示出来:
<script>
$(function() {
// Bar chart
new Chart(document.getElementById("chartjs-bar"), {
type: "bar",
data: {
labels: <%=session.getAttribute("cityLabelsList")%>,
datasets: [{
label: "最高年薪的平均",
backgroundColor: window.theme.primary,
borderColor: window.theme.primary,
hoverBackgroundColor: window.theme.primary,
hoverBorderColor: window.theme.primary,
data: <%=session.getAttribute("maxSalaryData")%>,
barPercentage: .75,
categoryPercentage: .5
}, {
label: "最低年薪的平均",
backgroundColor: "#dee2e6",
borderColor: "#dee2e6",
hoverBackgroundColor: "#dee2e6",
hoverBorderColor: "#dee2e6",
data: <%=session.getAttribute("minSalaryData")%>,
barPercentage: .75,
categoryPercentage: .5
}]
},
options: {
maintainAspectRatio: false,
legend: {
display: false
},
scales: {
yAxes: [{
gridLines: {
display: false
},
stacked: false,
ticks: {
stepSize: 20
}
}],
xAxes: [{
stacked: false,
gridLines: {
color: "transparent"
}
}]
}
}
});
});
</script>
另外,将具体数据内容以表的形式直观地展示出来,使用c:forEach与c:if来进行展示内容的判断:
<c:forEach var="i" begin="0" end="${sessionScope.cityNameList.size()-1}">
<tr>
<th scope="row">${i+1}</th>
<c:if test="${sessionScope.isIndustry == true}">
<td>${sessionScope.cityNameList.get(i)}市</td>
</c:if>
<c:if test="${sessionScope.isIndustry == false}">
<td>${sessionScope.cityNameList.get(i)}</td>
</c:if>
<td>${sessionScope.maxSalaryData.get(i)}</td>
<td>${sessionScope.minSalaryData.get(i)}</td>
</tr>
</c:forEach>
呈现结果:
上海市的各行业平均薪资水平:
计算机行业的热门城市平均薪资水平: