mapComponent.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import * as echarts from 'echarts';
  2. import styles from './mapComponent.less';
  3. import React, { useEffect, useRef } from 'react';
  4. interface propsData {
  5. userData: number;
  6. deviceData: number;
  7. areaList: any;
  8. mapData: any;
  9. }
  10. /**
  11. * 地图组件
  12. * @constructor
  13. */
  14. const MapComponent: React.FC<propsData> = (props) => {
  15. const chartRef: any = useRef();
  16. const { userData, deviceData, areaList, mapData } = props;
  17. const geoCoordMap = {
  18. 济南市: [117, 36.65],
  19. 青岛市: [120.33, 36.07],
  20. 淄博市: [118.05, 36.78],
  21. 枣庄市: [117.57, 34.86],
  22. 东营市: [118.49, 37.46],
  23. 烟台市: [121.39, 37.52],
  24. 潍坊市: [119.1, 36.62],
  25. 济宁市: [116.59, 35.38],
  26. 泰安市: [117.13, 36.18],
  27. 威海市: [122.1, 37.5],
  28. 日照市: [119.46, 35.42],
  29. 临沂市: [118.35, 35.05],
  30. 德州市: [116.29, 37.45],
  31. 聊城市: [115.97, 36.45],
  32. 滨州市: [118.03, 37.36],
  33. 菏泽市: [115.47, 35.25],
  34. };
  35. // 处理数据结构
  36. const convertData = (item: string | any[]) => {
  37. const res = [];
  38. for (let i = 0; i < item.length; i++) {
  39. const geoCoord = geoCoordMap[item[i].name];
  40. if (geoCoord) {
  41. res.push({
  42. name: item[i].name,
  43. value: geoCoord.concat(item[i].value),
  44. });
  45. }
  46. }
  47. return res;
  48. };
  49. useEffect(() => {
  50. // 初始化统计图对象
  51. const myChart = echarts.init(chartRef.current);
  52. if (mapData && mapData.map_json) {
  53. const data = JSON.parse(mapData.map_json);
  54. echarts.registerMap('map', data);
  55. const options = {
  56. geo: {
  57. show: true,
  58. map: 'map',
  59. roam: false,
  60. zoom: 1.2,
  61. label: {
  62. show: false,
  63. },
  64. itemStyle: {
  65. areaColor: '#091632',
  66. borderColor: '#1773c3',
  67. shadowColor: '#1773c3',
  68. shadowBlur: 20,
  69. },
  70. },
  71. series: [
  72. {
  73. name: 'light',
  74. type: 'scatter',
  75. coordinateSystem: 'geo',
  76. data: convertData(areaList),
  77. symbolSize: function (val: number[]) {
  78. return val[2];
  79. },
  80. label: {
  81. formatter: '{b}',
  82. position: 'right',
  83. show: true,
  84. },
  85. itemStyle: {
  86. color: '#ddb926',
  87. },
  88. },
  89. {
  90. type: 'map',
  91. map: 'map',
  92. zoom: 1.2,
  93. label: {
  94. show: false,
  95. color: '#fff',
  96. },
  97. roam: false,
  98. itemStyle: {
  99. areaColor: '#031525',
  100. borderColor: '#3B5077',
  101. borderWidth: 1,
  102. },
  103. data: [],
  104. },
  105. ],
  106. };
  107. myChart.setOption(options);
  108. }
  109. // 组件卸载
  110. return () => {
  111. myChart.clear();
  112. };
  113. }, []);
  114. return (
  115. <div className={styles.container}>
  116. <div ref={chartRef} className={styles.mapContent} />
  117. <div className={styles.content_num}>
  118. <div className={styles.content}>
  119. <div style={{ display: 'flex' }}>
  120. <div className={styles.content_title}>用户数</div>
  121. <div className={styles.content_value}>{userData}</div>
  122. </div>
  123. <div style={{ display: 'flex' }}>
  124. <div className={styles.content_title}>设备数</div>
  125. <div className={styles.content_value}>{deviceData}</div>
  126. </div>
  127. </div>
  128. </div>
  129. </div>
  130. );
  131. };
  132. export default MapComponent;