LayerAnalysis.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <template>
  2. <div class="gradient-text title">图层分析</div>
  3. <div class="box">
  4. <div v-for="(item, index) in dataList" :key="index" :class="item.checked ? 'box-item box-item-active' : 'box-item'" @click="handleClick(item)">
  5. {{ item.name + '(' + item.value + ')' }}
  6. </div>
  7. </div>
  8. <div>各区县分布统计</div>
  9. <div style="background-color: #d7d7d7; width: 1200px">
  10. <Chart :option="chartOption1" style="width: 1200px; height: 500px" />
  11. </div>
  12. <div>避难场所</div>
  13. <div style="background-color: #d7d7d7; width: 1200px">
  14. <Chart :option="chartOption2" style="width: 1200px; height: 500px" />
  15. </div>
  16. </template>
  17. <script lang="ts" setup>
  18. import { PointType } from '@/api/globalMap/type';
  19. import {
  20. getCountPointInfo,
  21. getCountPointInfoAreaList,
  22. getEmergencyExpertType,
  23. getEmergencyShelterType,
  24. getHospitalType,
  25. getRescueMateriaType,
  26. getSchoolType,
  27. getWaterloggedRoadsType
  28. } from '@/api/globalMap/layerAnalysis';
  29. import { option4, option5 } from './echartOptions';
  30. import BigNumber from 'bignumber.js';
  31. interface Props {
  32. pointType: PointType[];
  33. }
  34. const props = withDefaults(defineProps<Props>(), {});
  35. let dataList = ref([]);
  36. let chartOption1 = reactive(option4);
  37. let chartOption2 = reactive(option5);
  38. // 得到选中的标签的类型
  39. const getOption = (data, key = 'dataType') => {
  40. if (!data) {
  41. return;
  42. }
  43. let path = [];
  44. data.forEach((item) => {
  45. if (item.checked) {
  46. path.push(item[key]);
  47. }
  48. });
  49. return path.toString();
  50. };
  51. watch(
  52. () => props.pointType,
  53. () => {
  54. if (!props.pointType || props.pointType.length === 0) {
  55. return;
  56. }
  57. getCountPointInfo({ option: getOption(props.pointType, 'path') }).then((res) => {
  58. res.data.list.forEach((item) => {
  59. item.checked = true;
  60. });
  61. dataList.value = res.data.list;
  62. });
  63. },
  64. {
  65. immediate: true,
  66. deep: true
  67. }
  68. );
  69. watch(
  70. dataList,
  71. () => {
  72. const checkedData = dataList.value.filter((item) => {
  73. return item.checked;
  74. });
  75. if (!dataList.value || dataList.value.length === 0 || checkedData.length === 0) {
  76. chartOption1.yAxis.data = [];
  77. chartOption1.series[0].data = [];
  78. chartOption2.series[0].data = [];
  79. return;
  80. }
  81. // 各区县
  82. getCountPointInfoAreaList({ option: getOption(checkedData) }).then((res) => {
  83. const data = res.data.list;
  84. if (data.length > 0) {
  85. // 使用reduce方法合并相同area的num
  86. const mergedArray = data.reduce((acc, current) => {
  87. // 检查累加器(acc)中是否已有当前area
  88. const existing = acc.find((item) => item.area === current.area);
  89. if (existing) {
  90. // 如果存在,则累加num
  91. existing.num = BigNumber(existing.num).plus(current.num).toNumber();
  92. } else {
  93. // 如果不存在,则添加到累加器
  94. acc.push(current);
  95. }
  96. return acc;
  97. }, []);
  98. let yData = [];
  99. let seriesData = [];
  100. mergedArray.forEach((item) => {
  101. yData.push(item.area);
  102. seriesData.push(item.num);
  103. });
  104. chartOption1.yAxis.data = yData;
  105. chartOption1.series[0].data = seriesData;
  106. }
  107. });
  108. // 类型统计
  109. if (checkedData.length === 1) {
  110. let methodList = {
  111. '1': getEmergencyExpertType,
  112. '2': getRescueMateriaType,
  113. '3': getEmergencyShelterType,
  114. '4': getWaterloggedRoadsType,
  115. '5': getSchoolType,
  116. '6': getHospitalType
  117. };
  118. let method = methodList[dataList.value[0].dataType];
  119. if (!method) return;
  120. method().then((res) => {
  121. chartOption2.series[0].data = res.rows;
  122. });
  123. } else {
  124. chartOption2.series[0].data = checkedData;
  125. }
  126. },
  127. {
  128. immediate: true,
  129. deep: true
  130. }
  131. );
  132. const handleClick = (item) => {
  133. item.checked = !item.checked;
  134. };
  135. </script>
  136. <style lang="scss" scoped>
  137. .title {
  138. font-size: 60px;
  139. position: absolute;
  140. top: 12px;
  141. left: 210px;
  142. }
  143. .box {
  144. display: flex;
  145. flex-wrap: wrap;
  146. font-size: 38px;
  147. .box-item {
  148. background-color: #ffffff;
  149. color: #000;
  150. padding: 10px 20px;
  151. border-radius: 10px;
  152. cursor: pointer;
  153. margin-right: 20px;
  154. &:hover {
  155. background-color: #00aaff;
  156. color: #fff;
  157. }
  158. }
  159. .box-item-active {
  160. background-color: #00aaff;
  161. color: #fff;
  162. }
  163. }
  164. </style>