当前位置:   article > 正文

扇区架次数动态展示

扇区架次数动态展示

打开前端Vue项目:kongguan_web,完成前端src/components/echart/SectorFlightChart.vue页面设计,使用ECharts插件实现柱状图和饼状图

  • 在src/components目录下创建echart目录,完成src/components/echart/SectorFlightChart.vue 的页面div设计:
  1. <template xmlns:el-col="http://www.w3.org/1999/html">
  2. <div class="home">
  3. <div id="barFlightChart" class="chart" />
  4. </div>
  5. </template>
  6. ... 接下文 ...
  • 初始化数据,代码如下:
  1. ... 接上文 ...
  2. <script>
  3. import {findATCTime} from "../../api/chartdata/chartdata";
  4. export default {
  5. name: "SectorFlightChart",
  6. data() {
  7. return {
  8. sectorData: [],
  9. barChartData: [],
  10. barChartAxis: [],
  11. sectorCharData: [],
  12. sectorCharOneData: [],
  13. sectorChartAxis: ['K', 'S', 'E', 'P', 'G'],
  14. chartOption: {},
  15. myChart: {},
  16. }
  17. },
  18. mounted() {
  19. this.initChart();
  20. this.loadData();
  21. },
  22. ... 接下文 ...
  • 初始化ECharts,代码如下:
  1. ... 接上文 ...
  2. methods: {
  3. initChart() {
  4. this.myChart = this.$echarts.init(document.getElementById("barFlightChart"));
  5. this.chartOption = {
  6. baseOption: {
  7. timeline: {
  8. axisType: 'category',
  9. // realtime: false,
  10. // loop: false,
  11. autoPlay: true,
  12. // currentIndex: 2,
  13. playInterval: 1000,
  14. // controlStyle: {
  15. // position: 'left'
  16. // },
  17. lineStyle: {color: "#bcc9d7", width: 1},
  18. controlStyle: {showPlayBtn: !1, showPrevBtn: !1, showNextBtn: !1},
  19. checkpointStyle: {color: "#f19326", symbol: "circle", symbolSize: 10, borderWidth: 0},
  20. itemStyle: {normal: {color: "#419ae7"}},
  21. },
  22. title: {
  23. text: "扇区架次数动态循环展示",
  24. subtext: "",
  25. top:18,
  26. left: 26,
  27. textStyle: {
  28. color: "#000000"
  29. },
  30. },
  31. tooltip: {
  32. trigger: "item",
  33. padding: 10,
  34. backgroundColor: "#222",
  35. borderColor: "#777",
  36. borderWidth: 1,
  37. },
  38. angleAxis: {
  39. type: "category",
  40. axisTick: {show: !1},
  41. axisLine: {show: !0, lineStyle: {color: "#d2dde7"}},
  42. axisLabel: {color: "#d2dde7"},
  43. data: ["G区", "K区", "E区", "P区", "S区"],
  44. z: 10
  45. },
  46. radiusAxis: {
  47. min: 0,
  48. axisLine: {show: !1, lineStyle: {color: "#000", opacity: .3}},
  49. axisLabel: {show: !1, color: "#000"},
  50. axisTick: {show: !1},
  51. splitLine: {lineStyle: {color: "#d2dde7"}},
  52. splitArea: {show: !1, areaStyle: {color: "rgb(1, 10, 63)", opacity: .8}}
  53. },
  54. grid: {left: "10%", right: "50%", top: "10%", bottom: "9%", containLabel: !1},
  55. polar: {center: ["75%", "45%"], radius: "50%"},
  56. xAxis: [{
  57. type: 'value',
  58. boundaryGap: [0, 0.01],
  59. splitLine: {
  60. show: false
  61. },
  62. show: false,
  63. axisLine: { //横轴样式
  64. lineStyle: {},
  65. },
  66. position:'top'
  67. }],
  68. yAxis: [{
  69. type: 'category',
  70. data: this.barChartAxis,
  71. inverse:true,
  72. axisLine: { //纵轴样式
  73. lineStyle: {
  74. color: '#73777d'
  75. }
  76. },
  77. axisLabel: {
  78. rotate: -45
  79. }
  80. }],
  81. series: [{
  82. type: "bar",
  83. coordinateSystem: "polar",
  84. name: "扇区",
  85. center: ["75%", "45%"],
  86. stack: "a",
  87. itemStyle: {
  88. normal: {
  89. color: function (t) {
  90. return ["#51b8f9", "#7d92ff", "#5fccc3", "#f19326", "#f258b6"][t.dataIndex]
  91. }, label: {show: !0, position: "top", formatter: "{b}\n{c}"}
  92. }
  93. }
  94. }, {
  95. name: "本日架次数",
  96. type: "bar",
  97. barWidth: 8,
  98. radius: 90,
  99. avoidLabelOverlap: !1,
  100. label: {
  101. normal: {show: !1, position: "outside", formatter: "{c}"},
  102. emphasis: {show: !0, textStyle: {fontSize: "12", fontWeight: "normal"}}
  103. },
  104. labelLine: {normal: {show: !1}},
  105. itemStyle: {normal: {color: "#51b8f9"}, emphasis: {color: "#f19326"}}
  106. }]
  107. }
  108. }
  109. this.myChart.setOption(this.chartOption);
  110. },
  111. ... 接下文 ...
  • 加载整理数据,然后拼装ECharts专用的options对象,代码如下:
  1. //加载数据
  2. loadData() {
  3. findATCTime().then(data => {
  4. if (data.isSuccess) {
  5. this.formatData(data.result);
  6. } else {
  7. this.$message.error("数据获取失败");
  8. }
  9. });
  10. },
  11. //整理数据
  12. formatData(data) {
  13. let timeLineData = [];
  14. let barDataArr = [];
  15. let pieDataArr = [];
  16. let optionArr = [];
  17. for (let i = 0; i < data.length; i++) {
  18. let dayItemData = data[i];
  19. timeLineData.push(i + 1);
  20. let dayFlightSum = 0;
  21. let dayFlightDetail = [];
  22. for (let j = 0; j < dayItemData.length; j++) {
  23. dayFlightDetail.push(dayItemData[j][this.sectorChartAxis[j]]);
  24. dayFlightSum = dayFlightSum + parseInt(dayItemData[j][this.sectorChartAxis[j]]);
  25. }
  26. pieDataArr.push(dayFlightDetail);
  27. barDataArr.push(dayFlightSum);
  28. }
  29. //拼装 echart专用的options对象
  30. for (let i = 0; i < timeLineData.length; i++) {
  31. optionArr.push({
  32. series: [{data: pieDataArr[i]}, {data: barDataArr}],
  33. yAxis: [{data: timeLineData, nameTextStyle: {fontSize: 4, align: "center"},axisLabel:{formatter:'第{value}天'}}]
  34. })
  35. }
  36. this.chartOption.baseOption.timeline.data = timeLineData;
  37. this.chartOption.options = optionArr;
  38. this.refreshChart();
  39. }
  40. refreshChart() {
  41. this.myChart.setOption(this.chartOption);
  42. }
  43. }
  44. }
  45. </script>
  • 页面样式,代码如下:
  1. <style scoped>
  2. .home {
  3. height: 700px;
  4. overflow: auto;
  5. background-color: #ffffff;
  6. border: 1px solid #ebedf2;
  7. border-radius: 10px;
  8. box-shadow: 3px 3px 3px 3px #ebedf2;
  9. }
  10. .home::-webkit-scrollbar {
  11. display: none;
  12. }
  13. .chart {
  14. height: 680px;
  15. }
  16. </style>
  • 加载数据时,会调用src/api/chartdata/chartdata.js中定义的findATCTime方法,向服务端发送GET请求,获取扇区架次数动态统计,chartdata.js的完整代码如下:
  1. import request from '../../utils/request'
  2. const baseUrl = "/api"
  3. /**
  4. * 扇区架次数动态统计
  5. */
  6. export function findATCTime() {
  7. return request({
  8. url: baseUrl + "/atc/findATCTime",
  9. method: "GET"
  10. })
  11. }
  12. /**
  13. * 获取各个扇区通话饱和度
  14. */
  15. export function findCallSaturation() {
  16. return request({
  17. url: baseUrl + "/callSaturation/findCallSaturation",
  18. method: "GET"
  19. })
  20. }
  21. export function annualWarningStatisticsByCategory() {
  22. return request({
  23. url: baseUrl + "/warnFlightHistory/annualWarningStatisticsByCategory",
  24. method: "GET"
  25. })
  26. }
  27. export function getAirPortCount() {
  28. return request({
  29. url: baseUrl + "/company/getAirPortCount",
  30. method: "GET"
  31. })
  32. }
  33. /**
  34. * 获取从青岛起飞航班数前十的航线
  35. * @returns {AxiosPromise}
  36. */
  37. export function findByLimit() {
  38. return request({
  39. url: baseUrl + "/airLine/findByLimit",
  40. method: "GET"
  41. })
  42. }

2、后端的实现,打开后端项目:BigData-KongGuan

  • 编写实体类com/qrsoft/entity/Atc.java(前面任务时,已经创建过)
  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. @TableName("atc_number")
  5. public class Atc implements Serializable {
  6. @TableId(value = "id",type = IdType.AUTO)
  7. private Integer id;
  8. @TableField(value = "ACID")
  9. private String acId;
  10. @TableField(value = "ATC_TIME")
  11. private String atcTime;
  12. @TableField(value = "EXECUTE_DATE")
  13. private String executeDate;
  14. @TableField(value = "PLAN_SECTOR_NAME")
  15. private String planSectorName;
  16. @TableField(exist = false)
  17. private String count;
  18. }
  • 编写数据访问类com/qrsoft/mapper/AtcMapper.java,添加findATCTime()方法和findATCTime2()方法,AtcMapper类的完整代码如下:
  1. import com.qrsoft.entity.Atc;
  2. import org.apache.ibatis.annotations.Mapper;
  3. import org.apache.ibatis.annotations.Select;
  4. import java.util.List;
  5. @Mapper
  6. public interface AtcMapper extends BaseMapper<Atc> {
  7. @Select("select PLAN_SECTOR_NAME,COUNT(*) as count from atc_number GROUP BY PLAN_SECTOR_NAME;")
  8. List<Atc> findSectorSortie();
  9. @Select("select EXECUTE_DATE from atc_number group by EXECUTE_DATE order by EXECUTE_DATE desc limit 19;")
  10. List<String> findATCTime();
  11. @Select("select PLAN_SECTOR_NAME,count(*) as count from atc_number where EXECUTE_DATE = #{executeTime} and PLAN_SECTOR_NAME = #{sectorName}")
  12. Atc findATCTime2(String executeTime,String sectorName);
  13. }
  • 编写Service类com/qrsoft/service/AtcService.java,添加findATCTime()方法,AtcService类的完整代码如下:
  1. package com.qrsoft.service;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  4. import com.qrsoft.common.Result;
  5. import com.qrsoft.common.ResultConstants;
  6. import com.qrsoft.entity.Atc;
  7. import com.qrsoft.entity.MultiRadar;
  8. import com.qrsoft.mapper.AtcMapper;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.stereotype.Service;
  11. import java.util.ArrayList;
  12. import java.util.HashMap;
  13. import java.util.List;
  14. @Service
  15. public class AtcService extends ServiceImpl<AtcMapper, Atc> {
  16. @Autowired
  17. private MultiRadarService multiRadarService;
  18. /**
  19. * 查询所有扇区航班架次
  20. */
  21. public Result findSectorSortie() {
  22. List<Atc> sectorSortie = baseMapper.findSectorSortie();
  23. return new Result(ResultConstants.SUCCESS, ResultConstants.C_SUCCESS, sectorSortie);
  24. }
  25. /**
  26. * 根据扇区号查询架次
  27. * @param planSectorName
  28. */
  29. public Result findLocusCount(String planSectorName) {
  30. QueryWrapper<MultiRadar> queryWrapper = new QueryWrapper<>();
  31. queryWrapper.eq("section",planSectorName);
  32. int count = multiRadarService.count(queryWrapper);
  33. return new Result(ResultConstants.SUCCESS, ResultConstants.C_SUCCESS, count);
  34. }
  35. /**
  36. * 扇区架次数动态统计(饼状图)
  37. */
  38. public Result findATCTime() {
  39. List<String> sectorName = new ArrayList<>();
  40. sectorName.add("K");
  41. sectorName.add("S");
  42. sectorName.add("E");
  43. sectorName.add("P");
  44. sectorName.add("G");
  45. List<String> executeTime = baseMapper.findATCTime();
  46. List list = new ArrayList();
  47. for (int i = 0; executeTime.size() > i; i++) {
  48. ArrayList<Object> objects = new ArrayList<>();
  49. for (int j = 0; sectorName.size() > j; j++) {
  50. Atc atcTime2 = baseMapper.findATCTime2(executeTime.get(i), sectorName.get(j));
  51. HashMap<String, Object> map = new HashMap<>();
  52. if (atcTime2.getPlanSectorName() != null) {
  53. map.put(atcTime2.getPlanSectorName(), atcTime2.getCount());
  54. }else {
  55. map.put(sectorName.get(j),0);
  56. }
  57. objects.add(map);
  58. }
  59. list.add(objects);
  60. }
  61. return new Result(ResultConstants.SUCCESS, ResultConstants.C_SUCCESS, list);
  62. }
  63. }
  • 编写扇区操作的控制器类com/qrsoft/controller/AtcController.java,添加findATCTime()方法,AtcController类的完整代码如下:
  1. package com.qrsoft.controller;
  2. import com.qrsoft.common.Result;
  3. import com.qrsoft.service.AtcService;
  4. import io.swagger.annotations.Api;
  5. import io.swagger.annotations.ApiOperation;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.web.bind.annotation.GetMapping;
  8. import org.springframework.web.bind.annotation.RequestMapping;
  9. import org.springframework.web.bind.annotation.RequestParam;
  10. import org.springframework.web.bind.annotation.RestController;
  11. @Api(tags = "扇区操作类")
  12. @RestController
  13. @RequestMapping("/api/atc")
  14. public class AtcController {
  15. @Autowired
  16. private AtcService service;
  17. /**
  18. * 获取各扇区航班数
  19. */
  20. @ApiOperation(value = "获取各扇区航班数")
  21. @GetMapping("/findSectorSortie")
  22. public Result findSectorSortie(){
  23. return service.findSectorSortie();
  24. }
  25. /**
  26. * 根据扇区名称获取该扇区航班数
  27. * @param planSectorName
  28. */
  29. @ApiOperation(value = "根据扇区名称获取该扇区航班数")
  30. @GetMapping("/findLocusCount")
  31. public Result findLocusCount(@RequestParam String planSectorName){
  32. return service.findLocusCount(planSectorName);
  33. }
  34. /**
  35. * 扇区架次数动态统计(饼状图)
  36. */
  37. @ApiOperation(value = "扇区架次数动态统计(饼状图)")
  38. @GetMapping("/findATCTime")
  39. public Result findATCTime(){
  40. return service.findATCTime();
  41. }
  42. }

3、实现前端的报表展示

  • 回顾前面已经完成的src/components/echart/SectorFlightChart.vue页面,在页面中绑定数据的核心代码为:
  1. //加载数据
  2. loadData() {
  3. findATCTime().then(data => {
  4. if (data.isSuccess) {
  5. this.formatData(data.result);
  6. } else {
  7. this.$message.error("数据获取失败");
  8. }
  9. });
  10. },
  11. //整理数据
  12. formatData(data) {
  13. let timeLineData = [];
  14. let barDataArr = [];
  15. let pieDataArr = [];
  16. let optionArr = [];
  17. for (let i = 0; i < data.length; i++) {
  18. let dayItemData = data[i];
  19. timeLineData.push(i + 1);
  20. let dayFlightSum = 0;
  21. let dayFlightDetail = [];
  22. for (let j = 0; j < dayItemData.length; j++) {
  23. dayFlightDetail.push(dayItemData[j][this.sectorChartAxis[j]]);
  24. dayFlightSum = dayFlightSum + parseInt(dayItemData[j][this.sectorChartAxis[j]]);
  25. }
  26. pieDataArr.push(dayFlightDetail);
  27. barDataArr.push(dayFlightSum);
  28. }
  29. //拼装 echart专用的options对象
  30. for (let i = 0; i < timeLineData.length; i++) {
  31. optionArr.push({
  32. series: [{data: pieDataArr[i]}, {data: barDataArr}],
  33. yAxis: [{data: timeLineData, nameTextStyle: {fontSize: 4, align: "center"},axisLabel:{formatter:'第{value}天'}}]
  34. })
  35. }
  36. this.chartOption.baseOption.timeline.data = timeLineData;
  37. this.chartOption.options = optionArr;
  38. this.refreshChart();
  39. }
  40. ,
  41. //重新绑定数据
  42. refreshChart() {
  43. this.myChart.setOption(this.chartOption);
  44. }
  • 在src/views/Home/Index.vue引入SectorFlightChart组件,代码如下:
  1. ... 略 ...
  2. import AirLine from "../../components/AirLine";
  3. import Section from "../../components/Section";
  4. import Delay from "../../components/Delay";
  5. import WarnStatistice from "../../components/WarnStatistice";
  6. import SectorFlightChart from "../../components/echart/SectorFlightChart";
  7. import {hasPermission} from "../../utils/permission";
  8. export default {
  9. data() {
  10. return {
  11. };
  12. },
  13. mounted() {
  14. },
  15. components: {AirLine,Section,Delay,WarnStatistice,SectorFlightChart},
  16. methods: {
  17. isShow(permission){
  18. return hasPermission(permission);
  19. }
  20. }
  21. ... 略 ...
  • 在src/views/Home/Index.vue添加“扇区架次动态展示”组件,代码如下:
  1. <el-row :gutter="30" v-show="isShow('/section/detail')">
  2. <el-col :span="16" align="center">
  3. <SectorFlightChart/>
  4. </el-col>
  5. // ... 略 ...
  6. </el-row>

注意:在上面代码中【 v-show="isShow('/section/detail')" 】属性的作用是判断当前登录的用户是否有权限显示当前内容,如果当前登录的用户没有权限,则不会显示当前内容,新用户的权限需要到MySQL数据库中进行设置。

这里有两种方式,可以显示当前内容:

1)去掉【 v-show="isShow('/section/detail')" 】属性,即不判断是否有权限显示。

2)需要使用有权限的用户登录才能显示,或到数据库中分配权限。

参照任务“动态航线图”进行设置。

例如我们前面使用的用户admin,该用户没有权限显示,所以使用admin用户登录系统时是不会显示当前内容的,如果要进行权限设置,可以进入MySQL安装节点(node3节点),然后进入数据库,为admin用户授权。

[root@node3 ~]# mysql -uroot -p123456
mysql> use kongguan;

先查看角色表中,“管理员”的ID:

修改sys_auth表,添加一个【/section/detail】权限:

mysql> insert into sys_auth(auth_name,auth_code,menu_url) values('show detail','/section/detail','/section/detail');

修改role_auth表,将权限授权给“管理员”角色:

mysql>insert into role_auth(role_id,auth_id) values(3,198);

  • src/views/Home/Index.vue的完整代码如下:
  1. <template>
  2. <div class="index">
  3. <el-row :gutter="30" v-show="isShow('/flight/airline')">
  4. <el-col :span=24 align="center">
  5. <AirLine/>
  6. </el-col>
  7. </el-row>
  8. <el-row :gutter="30" v-show="isShow('/flight/section')">
  9. <el-col :span="24" align="center">
  10. <Section/>
  11. </el-col>
  12. </el-row>
  13. <el-row :gutter="30" v-show="isShow('/flight/delay')">
  14. <el-col :span="16" align="center">
  15. <Delay/>
  16. </el-col>
  17. <el-col :span="8" align="center">
  18. <year-warning-chart/>
  19. </el-col>
  20. </el-row>
  21. <el-row :gutter="30" v-show="isShow('/section/warning')">
  22. <el-col :span="12" align="center">
  23. <air-port-count-chart/>
  24. </el-col>
  25. <el-col :span="12" align="center">
  26. <WarnStatistice/>
  27. </el-col>
  28. </el-row>
  29. <el-row :gutter="30" v-show="isShow('/section/detail')">
  30. <el-col :span="16" align="center">
  31. <SectorFlightChart/>
  32. </el-col>
  33. <el-col :span="8" align="center">
  34. <sector-call-chart/>
  35. </el-col>
  36. </el-row>
  37. </div>
  38. </template>
  39. <script>
  40. import AirLine from "../../components/AirLine";
  41. import Section from "../../components/Section";
  42. import WarnStatistice from "../../components/WarnStatistice";
  43. import Delay from "../../components/Delay";
  44. import {hasPermission} from "../../utils/permission";
  45. import SectorFlightChart from "../../components/echart/SectorFlightChart";
  46. export default {
  47. data() {
  48. return {
  49. };
  50. },
  51. mounted() {
  52. },
  53. components: {AirLine, Section, WarnStatistice, Delay,SectorFlightChart},
  54. methods: {
  55. isShow(permission){
  56. return hasPermission(permission);
  57. }
  58. }
  59. };
  60. </script>
  61. <style scoped>
  62. .index {
  63. height: 100%;
  64. overflow: auto;
  65. padding-left: 44px;
  66. padding-right: 44px
  67. }
  68. .index::-webkit-scrollbar {
  69. display: none;
  70. }
  71. .caseClass {
  72. background: url('../../assets/images/index-bg.png') no-repeat;
  73. background-size: cover;
  74. margin-top: 20px;
  75. height: 284px;
  76. }
  77. .el-button {
  78. background: transparent;
  79. }
  80. </style>
  • 确保Hadoop、Spark、Kafka、Redis、MySQL等服务均已经正常启动,如果没有正常启动,请参照前面的安装部署任务,完成这些服务的启动。

例如:查看MySQL是否正常启动。

  • 启动后端项目 BigData-KongGuan

  • 启动前端项目 kongguan_web

  • 报表的最终展示效果如下图所示:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/294760
推荐阅读
相关标签
  

闽ICP备14008679号