1、打开前端Vue项目kongguan_web,完成前端src/components/echart/AirPortCountChart.vue页面设计
- 在AirPortCountChart.vue页面添加div设计
<template>
<div class="home">
<div id="barAirChart" class="chart" style="margin-left: 30px;height: 645px"/>
</div>
</template>
... 接下文 ...
- 初始化报表数据 data
... 接上文 ...
<script>
import {getAirPortCount} from '../../api/chartdata/chartdata'
export default {
name: "AirPortCountChart",
data() {
return {
chartOption: {},
myChart: {},
}
},
mounted() {
this.initChart();
this.loadData();
},
... 接下文 ...
- 初始化chart
... 接上文 ...
methods: {
initChart() {
this.myChart = this.$echarts.init(document.getElementById("barAirChart"));
this.chartOption = {
title: {
text: "机场当前负荷统计",
subtext: "",
top: 18,
left: 26,
textStyle: {
color: "#000000"
},
},
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
grid: {
left: '3%',
right: '8%',
bottom: '3%',
top:'15%',
containLabel: true
},
xAxis: [
{
type: 'category',
axisTick: {
alignWithLabel: true
},
axisLabel: {
interval: 0,
rotate: 45
}
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '起飞',
type: 'bar',
stack: '机场负荷',
barWidth: 23,
emphasis: {
focus: 'series'
},
},
{
name: '降落',
type: 'bar',
stack: '机场负荷',
barWidth: 23,
emphasis: {
focus: 'series'
},
}
]
}
this.myChart.setOption(this.chartOption);
},
... 接下文 ...
- 加载数据,并对数据进行格式化,然后绘制报表
调用api/chartdata/chartdata.js中的getAirPortCount()方法从后端获取数据,调用formatData(data)方法格式化数据,refreshChart刷新报表。
... 接上文 ...
loadData() {
getAirPortCount().then(data => {
if (data.isSuccess) {
this.formatData(data.result);
} else {
this.$message.error("数据获取失败");
}
})
},
formatData(data) {
let xAixArr = [];
let adepArr = [];
let adesArr = [];
for (let i = 0; i < data.length; i++) {
xAixArr.push(data[i].airCname);
adepArr.push(data[i].adepCount);
adesArr.push(data[i].adesCount);
}
this.chartOption.xAxis[0].data = xAixArr;
this.chartOption.series[0].data = adepArr;
this.chartOption.series[1].data = adesArr;
this.refreshChart();
},
refreshChart() {
this.myChart.setOption(this.chartOption);
}
}
}
</script>
... 接下文 ...
- 页面样式
<style scoped>
.home {
height: 700px;
overflow: auto;
background-color: #ffffff;
border: 1px solid #ebedf2;
border-radius: 10px;
box-shadow: 3px 3px 3px 3px #ebedf2;
}
.home::-webkit-scrollbar {
display: none;
}
.chart {
height: 700px;
}
</style>
- 加载数据时,会调用src/api/chartdata/chartdata.js中定义的getAirPortCount()方法,向服务端发送GET请求,获取 机场当前负荷统计 数据,chartdata.js的完整代码如下:
import request from '../../utils/request'
const baseUrl = "/api"
/**
* 扇区架次数动态统计
*/
export function findATCTime() {
return request({
url: baseUrl + "/atc/findATCTime",
method: "GET"
})
}
/**
* 获取各个扇区通话饱和度
*/
export function findCallSaturation() {
return request({
url: baseUrl + "/callSaturation/findCallSaturation",
method: "GET"
})
}
/**
* 年度告警分类统计
*/
export function annualWarningStatisticsByCategory() {
return request({
url: baseUrl + "/warnFlightHistory/annualWarningStatisticsByCategory",
method: "GET"
})
}
/**
* 机场当前负荷统计
*/
export function getAirPortCount() {
return request({
url: baseUrl + "/company/getAirPortCount",
method: "GET"
})
}
/**
* 获取从青岛起飞航班数前十的航线
* @returns {AxiosPromise}
*/
export function findByLimit() {
return request({
url: baseUrl + "/airLine/findByLimit",
method: "GET"
})
}
2、打开后端项目BigData-KongGuan,完成后端服务开发
- 创建控制器类com/qrsoft/controller/CompanyController.java,添加getAirPortCount()方法响应前端发送的GET请求,CompanyController.java的完整代码如下:
package com.qrsoft.controller;
import com.qrsoft.common.Result;
import com.qrsoft.service.AftnService;
import com.qrsoft.service.CompanyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "航空公司航班数,和航班延误数")
@RestController
@RequestMapping("/api/company")
public class CompanyController {
@Autowired
private CompanyService service;
@Autowired
private AftnService aftnService;
/**
* 查询指挥航空公司航班数,和航班延误数
*/
@ApiOperation(value = "查询指挥航空公司航班数,和航班延误数")
@GetMapping("/findCompanyDelay")
public Result findCompanyDelay(){
return service.findCompanyDelay();
}
@ApiOperation(value = "查询指挥航空公司架次数占比")
@GetMapping("/findCompanyByCompanyAll")
public Result findCompanyByCompanyAll(){
return service.findCompanyByCompanyAll();
}
@ApiOperation(value = "机场当前负荷统计")
@GetMapping("/getAirPortCount")
public Result getAirPortCount(){
return aftnService.getAirPortCount();
}
}
- 这里会依赖AftnService类,所以需要创建com.qrsoft.service.AftnService类,内容如下:
package com.qrsoft.service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qrsoft.common.Result;
import com.qrsoft.common.ResultConstants;
import com.qrsoft.entity.Aftn;
import com.qrsoft.mapper.AftnMapper;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class AftnService extends ServiceImpl<AftnMapper, Aftn> {
public Result getAirPortCount() {
List<Aftn> aftnList = baseMapper.getAftnList();
return new Result(ResultConstants.SUCCESS, ResultConstants.C_SUCCESS, aftnList);
}
}
- 还会依赖Aftn报文数据操作和存储的实体类,创建com.qrsoft.entity.Aftn类
package com.qrsoft.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("kg_aftn")
//报文
public class Aftn implements Serializable {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@TableField(value = "send_time")
private String sendTime;
@TableField(value = "area_source")
private String areaSource;
@TableField(value = "plan_source")
private String planSource;
@TableField(value = "acid")
private String acid;
@TableField(value = "adep")
private String adep;
@TableField(value = "ades")
private String ades;
@TableField(value = "stod")
private String stod;
@TableField(value = "stoa")
private String stoa;
@TableField(value = "aftn_status")
private String aftnStatus;
@TableField(value = "execute_date")
private String executeDate;
@TableField(value = "ssr_code")
private String ssrCode;
@TableField(value = "fly_type")
private String flyType;
@TableField(value = "aircraft_type")
private String aircraftType;
@TableField(value = "tail_flow")
private String tailFlow;
@TableField(value = "plan_height")
private String planHeight;
@TableField(value = "plan_speed")
private String planSpeed;
@TableField(exist = false)
private String airCname;
@TableField(exist = false)
private Integer adepCount;
@TableField(exist = false)
private Integer adesCount;
}
- 创建Mapper数据访问类com.qrsoft.mapper.AftnMapper接口,用于获于机场飞机起降数量等操作
package com.qrsoft.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qrsoft.entity.Aftn;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Mapper
public interface AftnMapper extends BaseMapper<Aftn> {
//获取机场飞机起飞的数量
@Select("select kg_airport.AIRPORT_CNAME as airCname,count(*) as adepCount\n" +
"from kg_airport INNER JOIN kg_aftn on kg_airport.AIRPORT_CODE4 = kg_aftn.adep\n" +
"GROUP BY kg_aftn.adep;")
List<Aftn> getAftnByAdep();
//获取机场飞机降落的数量
@Select("select kg_airport.AIRPORT_CNAME as airCname,count(*) as adesCount\n" +
"from kg_airport INNER JOIN kg_aftn on kg_airport.AIRPORT_CODE4 = kg_aftn.ades\n" +
"GROUP BY kg_aftn.ades")
List<Aftn> getAftnByAdes();
@Select("SELECT\n" +
"adep.airCname,adep.adepCount,ades.adesCount\n" +
"FROM\n" +
"(\n" +
"SELECT\n" +
"kg_airport.AIRPORT_CNAME AS airCname,\n" +
"count(*) AS adesCount \n" +
"FROM\n" +
"kg_airport\n" +
"INNER JOIN kg_aftn ON kg_airport.AIRPORT_CODE4 = kg_aftn.ades \n" +
"GROUP BY\n" +
"kg_aftn.ades \n" +
") AS ades right JOIN (\n" +
"SELECT\n" +
"kg_airport.AIRPORT_CNAME AS airCname,\n" +
"count(*) AS adepCount \n" +
"FROM\n" +
"kg_airport\n" +
"INNER JOIN kg_aftn ON kg_airport.AIRPORT_CODE4 = kg_aftn.adep \n" +
"GROUP BY\n" +
"kg_aftn.adep \n" +
") AS adep ON ades.airCname = adep.airCname")
List<Aftn> getAftnList();
}
3、前后端整合,实现设计效果
- 打开前端Vue项目,在src/views/Home/Index.vue引入AirPortCountChart组件
... 略 ...
import AirLine from "../../components/AirLine";
import Section from "../../components/Section";
import WarnStatistice from "../../components/WarnStatistice";
import Delay from "../../components/Delay";
import {hasPermission} from "../../utils/permission";
import SectorFlightChart from "../../components/echart/SectorFlightChart";
import SectorCallChart from "../../components/echart/SectorCallChart";
import YearWarningChart from "../../components/echart/YearWarningChart";
import AirPortCountChart from "../../components/echart/AirPortCountChart";
export default {
data() {
return {
};
},
mounted() {
},
components: {AirLine, Section, WarnStatistice, Delay,SectorFlightChart,SectorCallChart,YearWarningChart,AirPortCountChart},
methods: {
isShow(permission){
return hasPermission(permission);
}
}
... 略 ...
- 在src/views/Home/Index.vue添加“机场当前负荷统计”组件AirPortCountChart,代码如下(在代码中找到相应的标签,然后进行修改):
<el-row :gutter="30" v-show="isShow('/section/warning')">
<el-col :span="12" align="center">
<AirPortCountChart/>
</el-col>
<el-col :span="12" align="center">
<WarnStatistice/>
</el-col>
</el-row>
- src/views/Home/Index.vue的完整代码如下:
<template>
<div class="index">
<el-row :gutter="30" v-show="isShow('/flight/airline')">
<el-col :span=24 align="center">
<AirLine/>
</el-col>
</el-row>
<el-row :gutter="30" v-show="isShow('/flight/section')">
<el-col :span="24" align="center">
<Section/>
</el-col>
</el-row>
<el-row :gutter="30" v-show="isShow('/flight/delay')">
<el-col :span="16" align="center">
<Delay/>
</el-col>
<el-col :span="8" align="center">
<YearWarningChart/>
</el-col>
</el-row>
<el-row :gutter="30" v-show="isShow('/section/warning')">
<el-col :span="12" align="center">
<AirPortCountChart/>
</el-col>
<el-col :span="12" align="center">
<WarnStatistice/>
</el-col>
</el-row>
<el-row :gutter="30" v-show="isShow('/section/detail')">
<el-col :span="16" align="center">
<SectorFlightChart/>
</el-col>
<el-col :span="8" align="center">
<SectorCallChart/>
</el-col>
</el-row>
</div>
</template>
<script>
import AirLine from "../../components/AirLine";
import Section from "../../components/Section";
import Delay from "../../components/Delay";
import WarnStatistice from "../../components/WarnStatistice";
import SectorFlightChart from "../../components/echart/SectorFlightChart";
import SectorCallChart from "../../components/echart/SectorCallChart";
import YearWarningChart from "../../components/echart/YearWarningChart";
import AirPortCountChart from "../../components/echart/AirPortCountChart";
import {hasPermission} from "../../utils/permission";
export default {
data() {
return {
};
},
mounted() {
},
components: {AirLine,Section,Delay,WarnStatistice,SectorFlightChart,SectorCallChart,YearWarningChart,AirPortCountChart},
methods: {
isShow(permission){
return hasPermission(permission);
}
}
};
</script>
<style scoped>
.index {
height: 100%;
overflow: auto;
padding-left: 44px;
padding-right: 44px
}
.index::-webkit-scrollbar {
display: none;
}
.caseClass {
background: url('../../assets/images/index-bg.png') no-repeat;
background-size: cover;
margin-top: 20px;
height: 284px;
}
.el-button {
background: transparent;
}
</style>
- 确保Hadoop、Spark、Kafka、Redis、MySQL等服务均已经正常启动,如果没有正常启动,请参照前面的安装部署任务,完成这些服务的启动。
例如:查看MySQL是否正常启动。
- 启动后端项目 BigData-KongGuan,如图启动src/main/java/com/qrsoft/BigDataKongGuanApplication.java类
- 启动前端项目 kongguan_web,代码如下
kongguan_web@0.1.0 dev /root/kongguan_web
vue-cli-service serve --open
- 报表的最终展示效果如下图左侧红色框内所示: