center-map.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. <template>
  2. <div class="centermap">
  3. <div class="mapwrap" v-if="pageflag">
  4. <dv-border-box-12>
  5. <div class="loading" v-if="loading"><a-spin /></div>
  6. <div class="quanguo" @click="getData('china')" v-if="code !== 'china'">
  7. 返回
  8. </div>
  9. <Echart id="CenterMap" :options="options" ref="CenterMap" />
  10. </dv-border-box-12>
  11. </div>
  12. <Reacquire v-else @onclick="getData('china')" style="line-height:200px" />
  13. </div>
  14. </template>
  15. <script>
  16. import xzqCode from '@/utils/map/xzqCode'
  17. import * as echarts from 'echarts'
  18. import { GETNOBASE } from '@/utils/request'
  19. import { queryMapSaleData } from '@/api/bigScreen.js'
  20. import getDate from '@/libs/getDate.js'
  21. export default {
  22. props: {
  23. curYear: {
  24. type: [Number, String],
  25. default: ''
  26. }
  27. },
  28. data () {
  29. return {
  30. options: {},
  31. code: 'china', // china 代表中国 其他地市是行政编码
  32. echartBindClick: false,
  33. isSouthChinaSea: false, // 是否要展示南海群岛 修改此值请刷新页面
  34. pageflag: true,
  35. timer: null,
  36. loading: false
  37. }
  38. },
  39. watch:{
  40. curYear (a,b){
  41. this.getData('china')
  42. }
  43. },
  44. mounted () {
  45. this.getData('china')
  46. },
  47. beforeDestroy () {
  48. this.clearData()
  49. },
  50. methods: {
  51. clearData () {
  52. if (this.timer) {
  53. clearInterval(this.timer)
  54. this.timer = null
  55. }
  56. },
  57. // 轮询
  58. switper () {
  59. if (this.timer) {
  60. return
  61. }
  62. const looper = (a) => {
  63. this.getData('china')
  64. }
  65. this.timer = setInterval(looper, 30000)
  66. },
  67. getData (code) {
  68. this.loading = !this.timer
  69. queryMapSaleData(getDate.getBeDateByYear(this.curYear)).then((res) => {
  70. console.log('地图', res)
  71. if (res.status == 200) {
  72. this.getGeojson('china', res.data.dataList)
  73. // this.mapclick()
  74. this.$emit('onData', res.data)
  75. this.switper()
  76. } else {
  77. this.$Message.warning(res.msg)
  78. }
  79. this.loading = false
  80. })
  81. },
  82. /**
  83. * @description: 获取geojson
  84. * @param {*} name china 表示中国 其他省份行政区编码
  85. * @param {*} mydata 接口返回列表数据
  86. * @return {*}
  87. */
  88. async getGeojson (name, mydata) {
  89. this.code = name
  90. // 如果要展示南海群岛并且展示的是中国的话
  91. let geoname = name
  92. if (this.isSouthChinaSea && name == 'china') {
  93. geoname = 'chinaNanhai'
  94. }
  95. // 如果有注册地图的话就不用再注册 了
  96. let mapjson = echarts.getMap(name)
  97. if (mapjson) {
  98. mapjson = mapjson.geoJSON
  99. } else {
  100. mapjson = await GETNOBASE(`../../map-geojson/${geoname}.json`).then((res) => {
  101. return res
  102. })
  103. echarts.registerMap(name, mapjson)
  104. }
  105. const cityCenter = {}
  106. const arr = mapjson.features
  107. console.log(mapjson)
  108. // 根据geojson获取省份中心点
  109. arr.map((item) => {
  110. cityCenter[item.properties.name] =
  111. item.properties.centroid || item.properties.center
  112. })
  113. const newData = []
  114. const retData = []
  115. mydata.map((item) => {
  116. if (cityCenter[item.provinceName]) {
  117. newData.push({
  118. name: item.provinceName,
  119. value: cityCenter[item.provinceName].concat(item.resultAmount)
  120. })
  121. }
  122. retData.push({
  123. name: item.provinceName,
  124. value: item.resultAmount
  125. })
  126. })
  127. this.init(name, retData, newData)
  128. },
  129. init (name, data, data2) {
  130. // console.log(data2);
  131. const top = 45
  132. const zoom = 1.05
  133. const option = {
  134. backgroundColor: 'rgba(0,0,0,0)',
  135. tooltip: {
  136. show: false
  137. },
  138. legend: {
  139. show: false
  140. },
  141. visualMap: {
  142. left: 20,
  143. bottom: 20,
  144. pieces: [
  145. { gte: 10000000, label: '1000万元以上' }, // 不指定 max,表示 max 为无限大(Infinity)。
  146. { gte: 5000000, lte: 9999999, label: '500万元-1000万元' },
  147. { gte: 1000000, lte: 4999999, label: '100万元-500万元' },
  148. { gte: 500000, lte: 999999, label: '50万元-100万元' },
  149. { gte: 100000, lte: 499999, label: '10万元-50万元' },
  150. { lte: 99999, label: '1-10万元' } // 不指定 min,表示 min 为无限大(-Infinity)。
  151. ],
  152. inRange: {
  153. // 渐变颜色,从小到大
  154. color: [
  155. '#255a7e',
  156. '#3483b4',
  157. '#43a9e8',
  158. '#0389ff',
  159. '#ffaa00',
  160. '#ff5500'
  161. ]
  162. },
  163. textStyle: {
  164. color: '#fff'
  165. }
  166. },
  167. geo: {
  168. map: name,
  169. roam: false,
  170. selectedMode: false, // 是否允许选中多个区域
  171. zoom: zoom,
  172. top: top,
  173. // aspectScale: 0.78,
  174. show: false
  175. },
  176. series: [
  177. {
  178. name: 'MAP',
  179. type: 'map',
  180. map: name,
  181. // aspectScale: 0.78,
  182. data: data,
  183. selectedMode: false, // 是否允许选中多个区域
  184. zoom: zoom,
  185. geoIndex: 1,
  186. top: top,
  187. tooltip: {
  188. show: true,
  189. formatter: function (params) {
  190. if (params.data) {
  191. return params.name + ':' + (params.data['value'] / 10000).toFixed(2) + '万元'
  192. } else {
  193. return params.name
  194. }
  195. },
  196. backgroundColor: 'rgba(0,0,0,.6)',
  197. borderColor: 'rgba(147, 235, 248, .8)',
  198. textStyle: {
  199. color: '#FFF'
  200. }
  201. },
  202. label: {
  203. show: false,
  204. color: '#000',
  205. formatter: function (val) {
  206. // console.log(val)
  207. if (val.data !== undefined) {
  208. return val.name.slice(0, 2)
  209. } else {
  210. return ''
  211. }
  212. },
  213. rich: {}
  214. },
  215. emphasis: {
  216. label: {
  217. show: false
  218. },
  219. itemStyle: {
  220. areaColor: '#389BB7',
  221. borderWidth: 1
  222. }
  223. },
  224. itemStyle: {
  225. borderColor: 'rgba(147, 235, 248, .8)',
  226. borderWidth: 1,
  227. areaColor: {
  228. type: 'radial',
  229. x: 0.5,
  230. y: 0.5,
  231. r: 0.8,
  232. colorStops: [
  233. {
  234. offset: 0,
  235. color: 'rgba(147, 235, 248, 0)' // 0% 处的颜色
  236. },
  237. {
  238. offset: 1,
  239. color: 'rgba(147, 235, 248, .2)' // 100% 处的颜色
  240. }
  241. ],
  242. globalCoord: false // 缺为 false
  243. },
  244. shadowColor: 'rgba(128, 217, 248, .3)',
  245. shadowOffsetX: -2,
  246. shadowOffsetY: 2,
  247. shadowBlur: 10
  248. }
  249. },
  250. {
  251. data: data2,
  252. type: 'effectScatter',
  253. coordinateSystem: 'geo',
  254. symbolSize: function (val) {
  255. return 4
  256. },
  257. legendHoverLink: true,
  258. showEffectOn: 'render',
  259. rippleEffect: {
  260. // period: 4,
  261. scale: 6,
  262. color: 'rgba(255,255,255, 1)',
  263. brushType: 'fill'
  264. },
  265. tooltip: {
  266. show: true,
  267. formatter: function (params) {
  268. if (params.data) {
  269. return params.name + ':' + params.data['value'][2]
  270. } else {
  271. return params.name
  272. }
  273. },
  274. backgroundColor: 'rgba(0,0,0,.6)',
  275. borderColor: 'rgba(147, 235, 248, .8)',
  276. textStyle: {
  277. color: '#FFF'
  278. }
  279. },
  280. label: {
  281. formatter: (param) => {
  282. return param.name.slice(0, 2)
  283. },
  284. fontSize: 11,
  285. offset: [0, 2],
  286. position: 'bottom',
  287. textBorderColor: '#fff',
  288. textShadowColor: '#000',
  289. textShadowBlur: 10,
  290. textBorderWidth: 0,
  291. color: '#FFF',
  292. show: true
  293. },
  294. // colorBy: "data",
  295. itemStyle: {
  296. color: 'rgba(255,255,255,1)',
  297. borderColor: 'rgba(2255,255,255,2)',
  298. borderWidth: 4,
  299. shadowColor: '#000',
  300. shadowBlur: 10
  301. }
  302. }
  303. ]
  304. // 动画效果
  305. // animationDuration: 1000,
  306. // animationEasing: 'linear',
  307. // animationDurationUpdate: 1000
  308. }
  309. this.options = option
  310. },
  311. mapclick () {
  312. if (this.echartBindClick) return
  313. // 单击切换到级地图,当mapCode有值,说明可以切换到下级地图
  314. this.$refs.CenterMap.chart.on('click', (params) => {
  315. // console.log(params);
  316. const xzqData = xzqCode[params.name]
  317. if (xzqData) {
  318. this.getData(xzqData.adcode)
  319. } else {
  320. this.$message.info('暂无下级地市!')
  321. }
  322. })
  323. this.echartBindClick = true
  324. }
  325. }
  326. }
  327. </script>
  328. <style lang="less" scoped>
  329. .centermap {
  330. .mapwrap {
  331. height: 508px;
  332. width: 100%;
  333. // padding: 0 0 10px 0;
  334. box-sizing: border-box;
  335. position: relative;
  336. .quanguo {
  337. position: absolute;
  338. right: 20px;
  339. top: 15px;
  340. width: 80px;
  341. height: 28px;
  342. border: 1px solid #00aaff;
  343. border-radius: 10px;
  344. color: #00aaff;
  345. text-align: center;
  346. line-height: 26px;
  347. letter-spacing: 6px;
  348. cursor: pointer;
  349. box-shadow: 0 2px 4px rgba(0, 237, 237, 0.5), 0 0 6px rgba(0, 237, 237, 0.4);
  350. z-index: 10000;
  351. }
  352. .loading{
  353. position:absolute;
  354. z-index: 1000;
  355. left:0;
  356. top:0;
  357. width:100%;
  358. height:100%;
  359. background:rgba(0,0,0,0.5);
  360. display:flex;
  361. align-items: center;
  362. justify-content: center;
  363. }
  364. }
  365. }
  366. </style>