draw.tsx 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. import { defineComponent, watch, shallowReactive, nextTick, ref, onUnmounted } from 'vue';
  2. // 声明类型
  3. const PropsType = {
  4. cdata: {
  5. type: Array,
  6. require: true
  7. }
  8. } as const
  9. // 定义主体
  10. export default defineComponent({
  11. props: PropsType,
  12. setup(props) {
  13. // 定时器
  14. // let intervalId = 0
  15. // 地图选择
  16. // let preSelectMapIndex = 0
  17. // ref
  18. const chartRef = ref()
  19. // 配置项
  20. let options = shallowReactive({})
  21. // 设置点的位置(经纬度)
  22. const geoCoordMap = {
  23. 厦门市: [118.11022, 24.490474, 20],
  24. 福州市: [119.206239, 26.275302, 20],
  25. 泉州市: [118.589421, 24.908853, 20],
  26. 漳州市: [117.561801, 24.510897, 20],
  27. 龙岩市: [116.82978, 25.391603, 20],
  28. 莆田市: [119.007558, 25.591011, 20],
  29. 三明市: [117.435001, 26.465444, 20],
  30. 南平市: [118.178459, 27.535627, 20],
  31. 宁德市: [119.527082, 27.15924, 20],
  32. }
  33. const seriesData = [
  34. {
  35. name: '厦门市',
  36. },
  37. {
  38. name: '福州市',
  39. },
  40. {
  41. name: '泉州市',
  42. },
  43. {
  44. name: '漳州市',
  45. },
  46. {
  47. name: '龙岩市',
  48. },
  49. {
  50. name: '莆田市',
  51. },
  52. {
  53. name: '三明市',
  54. },
  55. {
  56. name: '南平市',
  57. },
  58. {
  59. name: '宁德市',
  60. },
  61. ]
  62. const convertData = function (data) {
  63. const scatterData = [];
  64. for (let i = 0; i < data.length; i++) {
  65. const geoCoord = geoCoordMap[data[i].name];
  66. if (geoCoord) {
  67. scatterData.push({
  68. name: data[i].name,
  69. value: geoCoord.concat(data[i].value),
  70. });
  71. }
  72. }
  73. return scatterData;
  74. }
  75. // 重新随机选中地图区域
  76. // const reSelectMapRandomArea = () => {
  77. // const length = 9;
  78. // nextTick(() => {
  79. // const map = chartRef.value;
  80. // let index = Math.floor(Math.random() * length);
  81. // while (index === preSelectMapIndex || index >= length) {
  82. // index = Math.floor(Math.random() * length);
  83. // }
  84. // if (map.dispatchAction) {
  85. // map.dispatchAction({
  86. // type: 'mapUnSelect',
  87. // seriesIndex: 0,
  88. // dataIndex: preSelectMapIndex,
  89. // });
  90. // map.dispatchAction({
  91. // type: 'showTip',
  92. // seriesIndex: 0,
  93. // dataIndex: index,
  94. // });
  95. // map.dispatchAction({
  96. // type: 'mapSelect',
  97. // seriesIndex: 0,
  98. // dataIndex: index,
  99. // });
  100. // preSelectMapIndex = index;
  101. // }
  102. // });
  103. // }
  104. // const handleMapRandomSelect = () => {
  105. // nextTick(() => {
  106. // const map = chartRef.value;
  107. // setTimeout(() => {
  108. // reSelectMapRandomArea();
  109. // }, 0);
  110. // // 移入区域,清除定时器、取消之前选中并选中当前
  111. // if (map.on) {
  112. // map.on('mouseover', function (params) {
  113. // clearInterval(intervalId);
  114. // if (map.dispatchAction) {
  115. // map.dispatchAction({
  116. // type: 'mapUnSelect',
  117. // seriesIndex: 0,
  118. // dataIndex: preSelectMapIndex,
  119. // });
  120. // map.dispatchAction({
  121. // type: 'mapSelect',
  122. // seriesIndex: 0,
  123. // dataIndex: params.dataIndex,
  124. // });
  125. // preSelectMapIndex = params.dataIndex;
  126. // }
  127. // });
  128. // }
  129. // // 移出区域重新随机选中地图区域,并开启定时器
  130. // if (map.on) {
  131. // map.on('globalout', function () {
  132. // reSelectMapRandomArea();
  133. // startInterval();
  134. // });
  135. // startInterval();
  136. // }
  137. // });
  138. // }
  139. // 开启定时器
  140. // const startInterval = () => {
  141. // // 应通过接口获取配置时间,暂时写死5s
  142. // const time = 2000;
  143. // intervalId = setInterval(() => {
  144. // reSelectMapRandomArea();
  145. // }, time);
  146. // }
  147. // 监听
  148. watch(
  149. () => props.cdata,
  150. (val: any) => {
  151. options = {
  152. showLegendSymbol: true,
  153. tooltip: {
  154. trigger: 'item',
  155. textStyle: {
  156. fontSize: 14,
  157. lineHeight: 22,
  158. },
  159. position: point => {
  160. // 固定在顶部
  161. return [point[0] + 50, point[1] - 20];
  162. },
  163. // 如果需要自定义 tooltip样式,需要使用formatter
  164. /*
  165. formatter: params => {
  166. return `<div style=""> ... </div>`
  167. }
  168. */
  169. },
  170. visualMap: {
  171. min: 0,
  172. max: 10,
  173. show: false,
  174. seriesIndex: 0,
  175. // 颜色
  176. inRange: {
  177. color: ['rgba(41,166,206, .5)', 'rgba(69,117,245, .9)'],
  178. },
  179. },
  180. // 底部背景
  181. geo: {
  182. show: true,
  183. aspectScale: 0.85, //长宽比
  184. zoom: 1.2,
  185. top: '10%',
  186. left: '16%',
  187. map: '福建',
  188. roam: false,
  189. itemStyle: {
  190. normal: {
  191. areaColor: 'rgba(0,0,0,0)',
  192. shadowColor: 'rgba(7,114,204, .8)',
  193. shadowOffsetX: 5,
  194. shadowOffsetY: 5,
  195. },
  196. emphasis: {
  197. areaColor: '#00aeef',
  198. },
  199. },
  200. },
  201. series: [
  202. {
  203. name: '相关指数',
  204. type: 'map',
  205. aspectScale: 0.85, //长宽比
  206. zoom: 1.2,
  207. mapType: '福建', // 自定义扩展图表类型
  208. top: '10%',
  209. left: '16%',
  210. itemStyle: {
  211. normal: {
  212. color: 'red',
  213. areaColor: 'rgba(19,54,162, .5)',
  214. borderColor: 'rgba(0,242,252,.3)',
  215. borderWidth: 1,
  216. shadowBlur: 7,
  217. shadowColor: '#00f2fc',
  218. },
  219. emphasis: {
  220. areaColor: '#4f7fff',
  221. borderColor: 'rgba(0,242,252,.6)',
  222. borderWidth: 2,
  223. shadowBlur: 10,
  224. shadowColor: '#00f2fc',
  225. },
  226. },
  227. label: {
  228. formatter: params => `${params.name}`,
  229. show: true,
  230. position: 'insideRight',
  231. textStyle: {
  232. fontSize: 14,
  233. color: '#efefef',
  234. },
  235. emphasis: {
  236. textStyle: {
  237. color: '#fff',
  238. },
  239. },
  240. },
  241. data: val,
  242. },
  243. {
  244. type: 'effectScatter',
  245. coordinateSystem: 'geo',
  246. symbolSize: 7,
  247. effectType: 'ripple',
  248. legendHoverLink: false,
  249. showEffectOn: 'render',
  250. rippleEffect: {
  251. period: 4,
  252. scale: 2.5,
  253. brushType: 'stroke',
  254. },
  255. zlevel: 1,
  256. itemStyle: {
  257. normal: {
  258. color: '#99FBFE',
  259. shadowBlur: 5,
  260. shadowColor: '#fff',
  261. },
  262. },
  263. data: convertData(seriesData),
  264. },
  265. ],
  266. }
  267. // 重新选择区域
  268. // handleMapRandomSelect();
  269. },
  270. {
  271. immediate: true,
  272. deep: true
  273. }
  274. )
  275. // 销毁
  276. // onUnmounted(() => {
  277. // clearInterval(intervalId)
  278. // })
  279. return () => {
  280. const height = "360px"
  281. const width = "330px"
  282. return <div>
  283. <echart ref={chartRef} options={options} height={height} width={width} />
  284. </div>
  285. }
  286. }
  287. })