mapComponent.tsx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. import * as echarts from 'echarts';
  2. import styles from './mapComponent.less';
  3. import React, { useEffect, useRef } from 'react';
  4. // import chinaMap from '../../mapJson/zaozhuang.json';
  5. import border from '../../../public/assets/decoration_six.png';
  6. import * as datav from '@jiaminghi/data-view-react';
  7. interface propsData {
  8. userData: object;
  9. areaList: any;
  10. mapJson: object;
  11. }
  12. /**
  13. * 地图组件
  14. * @constructor
  15. */
  16. const MapComponent: React.FC<propsData> = (props) => {
  17. const chartRef: any = useRef();
  18. const { userData, areaList, mapJson } = props;
  19. // const data: any = chinaMap; //地图的数据来自之前引入的json文件
  20. const data: any = mapJson; //地图的数据来自之前引入的json文件
  21. const geoCoordMap = {
  22. 济南市: [117, 36.65],
  23. 青岛市: [120.33, 36.07],
  24. 淄博市: [118.05, 36.78],
  25. 枣庄市: [117.57, 34.86],
  26. 东营市: [118.49, 37.46],
  27. 烟台市: [121.39, 37.52],
  28. 潍坊市: [119.1, 36.62],
  29. 济宁市: [116.59, 35.38],
  30. 泰安市: [117.13, 36.18],
  31. 威海市: [122.1, 37.5],
  32. 日照市: [119.46, 35.42],
  33. 临沂市: [118.35, 35.05],
  34. 德州市: [116.29, 37.45],
  35. 聊城市: [115.97, 36.45],
  36. 滨州市: [118.03, 37.36],
  37. 菏泽市: [115.47, 35.25],
  38. };
  39. // 处理数据结构
  40. const convertData = (mapData: string | any[]) => {
  41. const res = [];
  42. for (let i = 0; i < mapData.length; i++) {
  43. const geoCoord = geoCoordMap[mapData[i].name];
  44. if (geoCoord) {
  45. res.push({
  46. name: mapData[i].name,
  47. value: geoCoord.concat(mapData[i].value),
  48. });
  49. }
  50. }
  51. return res;
  52. };
  53. useEffect(() => {
  54. const myChart = echarts.init(chartRef.current);
  55. echarts.registerMap('shandong', data); //此步不可省略,要想展示一个地图,先需要注册,巨坑(官方根本无文档,全靠瞎猜,气死我了快)
  56. // 点位
  57. // const points = [];
  58. // // 线
  59. // const lineData = [];
  60. // for(let i=0;i<Object.keys(geoCoordMap).length;i++){
  61. // points.push({
  62. // name:Object.keys(geoCoordMap)[i],
  63. // value:geoCoordMap[Object.keys(geoCoordMap)[i]]
  64. // })
  65. // lineData.push({
  66. // name:`济南 -> ${Object.keys(geoCoordMap)[i]}`,
  67. // value: 40,
  68. // coords: [
  69. // [117, 36.65],
  70. // geoCoordMap[Object.keys(geoCoordMap)[i]]
  71. // ]
  72. // })
  73. // }
  74. // const colors = ['#46bee9'];
  75. const options = {
  76. geo: {
  77. show: true,
  78. map: 'shandong',
  79. roam: false,
  80. zoom: 1.2,
  81. label: {
  82. normal: {
  83. show: false,
  84. },
  85. emphasis: {
  86. show: false,
  87. },
  88. },
  89. itemStyle: {
  90. normal: {
  91. areaColor: '#091632',
  92. borderColor: '#1773c3',
  93. shadowColor: '#1773c3',
  94. shadowBlur: 20,
  95. },
  96. },
  97. },
  98. series: [
  99. {
  100. name: 'light',
  101. type: 'scatter',
  102. coordinateSystem: 'geo',
  103. data: convertData(areaList),
  104. symbolSize: function (val: number[]) {
  105. return val[2];
  106. },
  107. label: {
  108. normal: {
  109. formatter: '{b}',
  110. position: 'right',
  111. show: true,
  112. },
  113. emphasis: {
  114. show: true,
  115. },
  116. },
  117. itemStyle: {
  118. normal: {
  119. color: '#ddb926',
  120. },
  121. },
  122. },
  123. {
  124. type: 'map',
  125. map: 'shandong',
  126. zoom: 1.2,
  127. label: {
  128. normal: {
  129. show: false,
  130. },
  131. emphasis: {
  132. show: false,
  133. textStyle: {
  134. color: '#fff',
  135. },
  136. },
  137. },
  138. roam: false,
  139. itemStyle: {
  140. normal: {
  141. areaColor: '#031525',
  142. borderColor: '#3B5077',
  143. borderWidth: 1,
  144. },
  145. emphasis: {
  146. areaColor: '#0f2c70',
  147. },
  148. },
  149. data: [],
  150. },
  151. // {
  152. // type: 'effectScatter',
  153. // coordinateSystem: 'geo',
  154. // showEffectOn: 'render',
  155. // rippleEffect: {
  156. // period: 5,
  157. // scale: 5,
  158. // brushType: 'fill'
  159. // },
  160. // hoverAnimation: true,
  161. // label: {
  162. // formatter: '{b}',
  163. // position: 'right',
  164. // offset: [15, 0],
  165. // color: (param: { dataIndex: number; }) => colors[param.dataIndex % colors.length],
  166. // show: true
  167. // },
  168. // itemStyle: {
  169. // color: (param: { dataIndex: number; }) => {
  170. // return colors[param.dataIndex % colors.length];
  171. // },
  172. // shadowBlur: 10,
  173. // shadowColor: '#333',
  174. // opacity: 0.75
  175. // },
  176. // emphasis: {
  177. // itemStyle: {
  178. // opacity: 1, //线条宽度
  179. // }
  180. // },
  181. // data: points
  182. // },
  183. // {
  184. // name: '济南',
  185. // type: 'lines',
  186. // zlevel: 2,
  187. // symbol: ['none', 'arrow'],
  188. // symbolSize: 7,
  189. // effect: {
  190. // show: true,
  191. // period: 4,
  192. // trailLength: 0.02,
  193. // symbol: 'circle',
  194. // symbolSize: 4,
  195. // color: '#46bee9'
  196. // },
  197. // lineStyle: {
  198. // width: 0.5, //线条宽度
  199. // opacity: 0.5, //尾迹线条透明度
  200. // curveness: .3, //尾迹线条曲直度
  201. // shadowBlur: 10,
  202. // color: '#46bee9'
  203. // },
  204. // emphasis: {
  205. // lineStyle: {
  206. // width: 2, //线条宽度
  207. // }
  208. // },
  209. // data: lineData
  210. // }
  211. ],
  212. };
  213. myChart.setOption(options, true);
  214. // 组件卸载
  215. return () => {
  216. myChart.clear();
  217. };
  218. }, []);
  219. return (
  220. <div className={styles.container}>
  221. <div ref={chartRef} className={styles.mapContent} />
  222. <div className={styles.content_num}>
  223. <div style={{ position: 'relative' }}>
  224. <img
  225. src={border}
  226. alt="装饰线条"
  227. style={{ width: '200px', height: '95px', transform: 'rotateY(180deg)' }}
  228. />
  229. <div className={styles.content}>
  230. <datav.DigitalFlop
  231. config={userData}
  232. className={styles.content_value}
  233. style={{ width: '200px', height: '50px' }}
  234. />
  235. <div className={styles.content_title}>用户数</div>
  236. </div>
  237. </div>
  238. </div>
  239. </div>
  240. );
  241. };
  242. export default MapComponent;