index.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. <template>
  2. <div class="h-full" style="position: relative">
  3. <div class="c-title flex justify-between">
  4. <span>作业计划</span>
  5. <el-button
  6. style="font-size: 16px; position: absolute; right: 45%; top: 5px"
  7. size="mini"
  8. v-if="currentMap != '衡阳市'"
  9. type="text"
  10. @click="back()"
  11. >返回</el-button
  12. >
  13. <el-date-picker
  14. size="mini"
  15. v-model="dateRange"
  16. type="daterange"
  17. range-separator="至"
  18. start-placeholder="开始日期"
  19. end-placeholder="结束日期"
  20. value-format="yyyyMMdd"
  21. style="width: 240px"
  22. @change="init"
  23. >
  24. </el-date-picker>
  25. </div>
  26. <div style="display: flex; justify-content: space-between; height: 100%">
  27. <div id="hy-map" style="width: 100%; height: 100%"></div>
  28. </div>
  29. </div>
  30. </template>
  31. <script>
  32. import * as echarts from "echarts";
  33. const mapEnum = {
  34. 衡阳市: require("./衡阳市.json"),
  35. 常宁市: require("./常宁市.json"),
  36. 衡东县: require("./衡东县.json"),
  37. 衡南县: require("./衡南县.json"),
  38. 衡山县: require("./衡山县.json"),
  39. 衡阳县: require("./衡阳县.json"),
  40. 耒阳市: require("./耒阳市.json"),
  41. 南岳区: require("./南岳区.json"),
  42. 祁东县: require("./祁东县.json"),
  43. 石鼓区: require("./石鼓区.json"),
  44. 雁峰区: require("./雁峰区.json"),
  45. 蒸湘区: require("./蒸湘区.json"),
  46. 珠晖区: require("./珠晖区.json"),
  47. };
  48. import { getWorkNumStatistics } from "@/api/powerdistribution/home";
  49. import moment from "moment";
  50. export default {
  51. name: "map",
  52. data() {
  53. return {
  54. dateRange: [
  55. moment().endOf("day").format("YYYYMMDD"),
  56. moment().endOf("day").format("YYYYMMDD"),
  57. ],
  58. loading: true,
  59. currentMap: "衡阳市",
  60. dataMap: {},
  61. };
  62. },
  63. mounted() {
  64. this.init();
  65. },
  66. methods: {
  67. async init() {
  68. await this.getData();
  69. },
  70. async getData() {
  71. const params = {
  72. startDate: this.dateRange[0],
  73. endDate: this.dateRange[1],
  74. };
  75. const data = await getWorkNumStatistics(params);
  76. Object.keys(mapEnum).forEach((key) => {
  77. (data || []).map((ite) => {
  78. if (key.includes(ite.submitOrgNm)) {
  79. this.dataMap[key] = ite.workNum ?? 0;
  80. }
  81. });
  82. });
  83. this.currentMap = "衡阳市";
  84. this.initMap();
  85. },
  86. back() {
  87. this.currentMap = "衡阳市";
  88. this.initMap();
  89. },
  90. async initMap(json = require("./衡阳市.json")) {
  91. var data = [],
  92. geoCoordMap = {};
  93. json.features.forEach((v) => {
  94. geoCoordMap[v.properties.name] = v.properties.center;
  95. data.push({
  96. name: v.properties.name,
  97. value: this.dataMap[v.properties.name] ?? 0,
  98. });
  99. });
  100. var convertData = function (data) {
  101. var res = [];
  102. for (var i = 0; i < data.length; i++) {
  103. var geoCoord = geoCoordMap[data[i].name];
  104. if (geoCoord) {
  105. res.push({
  106. name: data[i].name,
  107. value: geoCoord.concat(data[i].value),
  108. });
  109. }
  110. }
  111. return res;
  112. };
  113. const chartDom = document.querySelector("#hy-map");
  114. const myChart = echarts.init(chartDom);
  115. echarts.registerMap("HK", json);
  116. let option = {
  117. tooltip: {
  118. trigger: "item",
  119. alwaysShowContent: true,
  120. formatter: (params) => {
  121. let str = "";
  122. Object.keys(this.dataMap).forEach((key) => {
  123. str +=
  124. key +
  125. "-作业数量 " +
  126. `<span class="orange">${this.dataMap[key] || 0}</span> <br/>`;
  127. });
  128. const v = Array.isArray(params.value)
  129. ? params.value[2]
  130. : params.value;
  131. return this.currentMap == "衡阳市"
  132. ? str
  133. : params.name +
  134. "-作业数量 " +
  135. `<span class="orange">${v || 0}</span> <br/>`;
  136. },
  137. },
  138. // visualMap: {
  139. // show: false,
  140. // seriesIndex: [0],
  141. // inRange: {
  142. // color: ["#02367C", "#3a92fe"],
  143. // },
  144. // },
  145. // visualMap: {
  146. // show: true,
  147. // min: 0,
  148. // max: 20000,
  149. // left: "10%",
  150. // bottom: "10%",
  151. // calculable: true,
  152. // seriesIndex: [0],
  153. // inRange: {
  154. // color: ["#04387b", "#467bc0"], // 蓝绿
  155. // },
  156. // },
  157. geo: [
  158. {
  159. show: true,
  160. map: "HK",
  161. zoom: 1.1,
  162. roam: false,
  163. itemStyle: {
  164. normal: {
  165. borderColor: "#48B6ED",
  166. borderWidth: 5,
  167. },
  168. },
  169. },
  170. ],
  171. series: [
  172. {
  173. type: "map",
  174. mapType: "HK", //自定义扩展图表类型
  175. zoom: 1.1,
  176. roam: false,
  177. label: {
  178. normal: {
  179. show: true,
  180. formatter: "{b}: {c}",
  181. textStyle: {
  182. color: "#fff",
  183. },
  184. },
  185. emphasis: {
  186. show: true,
  187. textStyle: {
  188. color: "#fff",
  189. },
  190. },
  191. },
  192. itemStyle: {
  193. normal: {
  194. areaColor: "#02367C",
  195. borderColor: "#004096",
  196. borderWidth: 1,
  197. },
  198. emphasis: {
  199. areaColor: "#004096",
  200. },
  201. },
  202. select: {
  203. label: {
  204. // 选中区域的label(文字)样式
  205. color: "#fff",
  206. },
  207. itemStyle: {
  208. areaColor: "#02367C", // 选中的区域颜色
  209. },
  210. },
  211. data: data,
  212. },
  213. {
  214. name: "Top 5",
  215. type: "effectScatter",
  216. coordinateSystem: "geo",
  217. data: convertData(
  218. data.sort(function (a, b) {
  219. return b.value - a.value;
  220. })
  221. // .slice(0, 10)
  222. ),
  223. symbolSize: function (val) {
  224. return 6;
  225. },
  226. showEffectOn: "render",
  227. rippleEffect: {
  228. brushType: "stroke",
  229. },
  230. hoverAnimation: true,
  231. label: {
  232. show: false,
  233. normal: {
  234. formatter: "{b}",
  235. position: "left",
  236. show: false,
  237. },
  238. },
  239. itemStyle: {
  240. normal: {
  241. color: (params) => {
  242. const [x, y, v] = params.value;
  243. return v ? "#44936c" : "gray";
  244. }, //标志颜色,
  245. shadowBlur: 2,
  246. },
  247. },
  248. zlevel: 1,
  249. },
  250. ],
  251. };
  252. myChart.setOption(option);
  253. window.addEventListener("resize", () => {
  254. myChart.resize();
  255. });
  256. myChart.on("click", (params) => {
  257. this.currentMap = params.name;
  258. this.initMap(mapEnum[params.name]);
  259. });
  260. myChart.dispatchAction({
  261. type: "showTip",
  262. seriesIndex: 0,
  263. dataIndex: 3,
  264. });
  265. },
  266. },
  267. };
  268. </script>
  269. <style lang="scss" scoped>
  270. .c-title {
  271. border-left: 4px solid #00a4ff;
  272. padding-left: 10px;
  273. color: #00a4ff;
  274. }
  275. .orange {
  276. color: orange !important;
  277. }
  278. </style>