index.vue 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. <template>
  2. <div
  3. style="width: 100%; height: 100%"
  4. class="bs-design-wrap bs-bar"
  5. >
  6. <div
  7. :id="`chart${config.code}`"
  8. style="width: 100%; height: 100%"
  9. />
  10. </div>
  11. </template>
  12. <script>
  13. import 'insert-css'
  14. import * as echarts from 'echarts'
  15. import commonMixins from 'packages/js/mixins/commonMixins.js'
  16. import paramsMixins from 'packages/js/mixins/paramsMixins'
  17. import linkageMixins from 'packages/js/mixins/linkageMixins'
  18. import { get } from 'packages/js/utils/http'
  19. export default {
  20. name: 'MapCharts',
  21. mixins: [paramsMixins, commonMixins, linkageMixins],
  22. props: {
  23. id: {
  24. type: String,
  25. default: ''
  26. },
  27. config: {
  28. type: Object,
  29. default: () => ({})
  30. }
  31. },
  32. data () {
  33. return {
  34. charts: null,
  35. hasData: false
  36. }
  37. },
  38. computed: {
  39. Data () {
  40. return JSON.parse(JSON.stringify(this.config))
  41. }
  42. },
  43. watch: {
  44. Data: {
  45. handler (newVal, oldVal) {
  46. if (newVal.w !== oldVal.w || newVal.h !== oldVal.h) {
  47. this.$nextTick(() => {
  48. this.charts.resize()
  49. })
  50. }
  51. },
  52. deep: true
  53. }
  54. },
  55. mounted () {
  56. this.chartInit()
  57. },
  58. beforeDestroy () {
  59. this.charts?.clear()
  60. },
  61. methods: {
  62. buildOption (config, data) {
  63. const dataList = []
  64. data?.data?.forEach(item => {
  65. dataList.push({ name: item[config.customize.name], value: [item[config.customize.xaxis], item[config.customize.yaxis], item[config.customize.value]] })
  66. })
  67. config.option = {
  68. ...config.option,
  69. data: dataList
  70. }
  71. return config
  72. },
  73. async newChart (options) {
  74. this.charts = echarts.init(
  75. document.getElementById(`chart${this.config.code}`)
  76. )
  77. const option = {
  78. // 背景颜色
  79. backgroundColor: this.config.customize.backgroundColor,
  80. geo: {
  81. map: this.config.customize.scope,
  82. label: {
  83. // 通常状态下的样式
  84. normal: {
  85. show: this.config.customize.mapName,
  86. textStyle: {
  87. color: '#fff'
  88. }
  89. },
  90. // 鼠标放上去的样式
  91. emphasis: {
  92. textStyle: {
  93. color: '#fff'
  94. }
  95. }
  96. },
  97. // 地图区域的样式设置
  98. itemStyle: {
  99. normal: {
  100. borderColor: this.config.customize.mapLineColor,
  101. borderWidth: 1,
  102. areaColor: this.config.customize.areaColor,
  103. shadowColor: 'fffff',
  104. shadowOffsetX: -2,
  105. shadowOffsetY: 2,
  106. shadowBlur: 10
  107. },
  108. // 鼠标放上去高亮的样式
  109. emphasis: {
  110. areaColor: '#389BB7',
  111. borderWidth: 0
  112. }
  113. }
  114. },
  115. // 提示浮窗样式
  116. tooltip: {
  117. show: false,
  118. trigger: 'item',
  119. alwaysShowContent: false,
  120. backgroundColor: this.config.customize.tooltipBackgroundColor,
  121. borderColor: this.config.customize.borderColor,
  122. hideDelay: 100,
  123. triggerOn: 'mousemove',
  124. enterable: true,
  125. textStyle: {
  126. color: '#DADADA',
  127. fontSize: '12',
  128. width: 20,
  129. height: 30,
  130. overflow: 'break'
  131. },
  132. showDelay: 100
  133. },
  134. series: this.config.customize.scatter
  135. ? [
  136. // {
  137. // type: 'effectScatter',
  138. // coordinateSystem: 'geo',
  139. // effectType: 'ripple',
  140. // showEffectOn: 'render',
  141. // rippleEffect: {
  142. // period: 10,
  143. // scale: 10,
  144. // brushType: 'fill'
  145. // },
  146. // hoverAnimation: true,
  147. // itemStyle: {
  148. // normal: {
  149. // color: 'rgba(255, 235, 59, .7)',
  150. // shadowBlur: 10,
  151. // shadowColor: '#333'
  152. // }
  153. // },
  154. // tooltip: {
  155. // formatter(params) {
  156. // return `<p style="text-align:center;line-height: 30px;height:30px;font-size: 14px;border-bottom: 1px solid #7A8698;">${
  157. // params.name
  158. // }</p>
  159. // <div style="line-height:22px;margin-top:5px">GDP<span style="margin-left:12px;color:#fff;float:right">${
  160. // params.data?.value[2] || '--'
  161. // }</span></div>`
  162. // },
  163. // show: true
  164. // },
  165. // zlevel: 1,
  166. // data: [
  167. // { name: '西藏自治区', value: [91.23, 29.5, 1] },
  168. // { name: '黑龙江省', value: [128.03, 47.01, 1007] },
  169. // { name: '北京市', value: [116.4551, 40.2539, 5007] }
  170. // ]
  171. // }
  172. {
  173. type: 'scatter',
  174. coordinateSystem: 'geo',
  175. symbol: 'pin',
  176. legendHoverLink: true,
  177. symbolSize: [60, 60],
  178. showEffectOn: 'render',
  179. rippleEffect: {
  180. brushType: 'stroke'
  181. },
  182. hoverAnimation: true,
  183. zlevel: 1,
  184. // 这里渲染标志里的内容以及样式
  185. label: {
  186. show: true,
  187. formatter (value) {
  188. return value.data.value[2]
  189. },
  190. color: this.config.customize.scatterColor
  191. },
  192. // 标志的样式
  193. itemStyle: {
  194. normal: {
  195. color: this.config.customize.scatterBackgroundColor,
  196. shadowBlur: 2,
  197. shadowColor: 'D8BC37'
  198. }
  199. },
  200. data: options.data
  201. }
  202. ]
  203. : [
  204. {
  205. type: 'map',
  206. map: this.config.customize.scope,
  207. geoIndex: 0,
  208. roam: false,
  209. zoom: 1.5,
  210. center: [105, 36],
  211. showLegendSymbol: false, // 存在legend时显示
  212. data: options.data,
  213. tooltip: {
  214. formatter (params) {
  215. return `<p style="text-align:center;line-height: 30px;height:30px;font-size: 14px;border-bottom: 1px solid #7A8698;">${
  216. params.name
  217. }</p>
  218. <div style="line-height:22px;margin-top:5px">GDP<span style="margin-left:12px;color:#fff;float:right">${
  219. params.data?.value[2] || '--'
  220. }</span></div>`
  221. },
  222. show: true
  223. }
  224. }
  225. ]
  226. }
  227. if (this.config.customize.visual) {
  228. option.visualMap = {
  229. show: true,
  230. min: this.config.customize.range[0],
  231. max: this.config.customize.range[1],
  232. seriesIndex: [0],
  233. inRange: {
  234. color: this.config.customize.rangeColor
  235. }
  236. }
  237. }
  238. const mapUrl = `${window.BS_CONFIG?.httpConfigs?.baseURL}/static/chinaMap/${this.config.customize.level}/${this.config.customize.dataMap}`
  239. const map = await get(decodeURI(mapUrl), {}, true)
  240. echarts.registerMap(this.config.customize.scope, map)
  241. this.charts.setOption(option)
  242. // this.charts.on('click', (params) => {
  243. // get(
  244. // `${window.BS_CONFIG?.httpConfigs?.baseURL}/static/chinaMap/province/${params.name}.json`,
  245. // {},
  246. // true
  247. // ).then((res) => {
  248. // option.geo.map = params.name
  249. // echarts.registerMap(params.name, res)
  250. // this.charts.setOption(option, true)
  251. // })
  252. // })
  253. }
  254. }
  255. }
  256. </script>
  257. <style lang="scss" scoped>
  258. @import '~packages/assets/style/echartStyle';
  259. .light-theme {
  260. background-color: #ffffff;
  261. color: #000000;
  262. }
  263. .auto-theme {
  264. background-color: rgba(0, 0, 0, 0);
  265. }
  266. </style>