index.vue 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. <template>
  2. <div
  3. style="width: 100%; height: 100%"
  4. class="bs-design-wrap bs-bar"
  5. >
  6. <el-button class="button" v-if="this.level=='province'&&config.customize.down" @click="jumpTo(config)" type='text' > 返回上一级</el-button>
  7. <div
  8. :id="`chart${config.code}`"
  9. style="width: 100%; height: 100%"
  10. />
  11. </div>
  12. </template>
  13. <script>
  14. import 'insert-css'
  15. import * as echarts from 'echarts'
  16. import commonMixins from 'data-room-ui/js/mixins/commonMixins.js'
  17. import paramsMixins from 'data-room-ui/js/mixins/paramsMixins'
  18. import linkageMixins from 'data-room-ui/js/mixins/linkageMixins'
  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. level:'',
  37. option:{}
  38. }
  39. },
  40. computed: {
  41. Data () {
  42. return JSON.parse(JSON.stringify(this.config))
  43. }
  44. },
  45. watch: {
  46. Data: {
  47. handler (newVal, oldVal) {
  48. if (newVal.w !== oldVal.w || newVal.h !== oldVal.h) {
  49. this.$nextTick(() => {
  50. this.charts.resize()
  51. })
  52. }
  53. },
  54. deep: true
  55. }
  56. },
  57. mounted () {
  58. this.chartInit()
  59. },
  60. beforeDestroy () {
  61. this.charts?.clear()
  62. },
  63. methods: {
  64. chartInit () {
  65. const config = this.config
  66. // key和code相等,说明是一进来刷新,调用list接口
  67. if (this.config.code === this.config.key || this.isPreview) {
  68. // 改变数据
  69. this.changeDataByCode(config).then((res) => {
  70. // 改变样式
  71. // config = this.changeStyle(res)
  72. this.newChart(config)
  73. }).catch(() => {})
  74. } else {
  75. // 否则说明是更新,这里的更新只指更新数据(改变样式时是直接调取changeStyle方法),因为更新数据会改变key,调用chart接口
  76. this.changeData(config).then((res) => {
  77. // 初始化图表
  78. this.newChart(res)
  79. })
  80. }
  81. },
  82. dataFormatting (config, data) {
  83. const dataList = []
  84. data?.data?.forEach(item => {
  85. dataList.push({ name: item[config.customize.name], value: [item[config.customize.xaxis], item[config.customize.yaxis], item[config.customize.value]] })
  86. })
  87. config.option = {
  88. ...config.option,
  89. data: dataList
  90. }
  91. return config
  92. },
  93. async jumpTo(config){
  94. this.level='country'
  95. const mapUrl =`${window.BS_CONFIG?.httpConfigs?.baseURL}/static/chinaMap/country/中华人民共和国.json`
  96. const map = await this.$dataRoomAxios.get(decodeURI(mapUrl), {}, true)
  97. this.option.geo.map = '中华人民共和国';
  98. this.changeData({...config,customize:{...config.customize,level:'country',scope:'中国'}})
  99. echarts.registerMap('中华人民共和国', map);
  100. this.charts.setOption(this.option, true);
  101. },
  102. async newChart (config) {
  103. this.charts = echarts.init(
  104. document.getElementById(`chart${this.config.code}`)
  105. )
  106. this.option = {
  107. // 背景颜色
  108. backgroundColor: config.customize.backgroundColor,
  109. graphic: [
  110. ],
  111. geo: {
  112. map: config.customize.scope,
  113. zlevel: 10,
  114. show:true,
  115. layoutCenter: ['50%', '50%'],
  116. roam: true,
  117. layoutSize: "100%",
  118. zoom: 1,
  119. label: {
  120. // 通常状态下的样式
  121. normal: {
  122. show: config.customize.mapName,
  123. textStyle: {
  124. color: '#fff'
  125. }
  126. },
  127. // 鼠标放上去的样式
  128. emphasis: {
  129. textStyle: {
  130. color: '#fff'
  131. }
  132. }
  133. },
  134. // 地图区域的样式设置
  135. itemStyle: {
  136. normal: {
  137. borderColor: config.customize.mapLineColor,
  138. borderWidth: 1,
  139. areaColor: config.customize.areaColor,
  140. shadowColor: 'fffff',
  141. shadowOffsetX: -2,
  142. shadowOffsetY: 2,
  143. shadowBlur: 10
  144. },
  145. // 鼠标放上去高亮的样式
  146. emphasis: {
  147. areaColor: '#389BB7',
  148. borderWidth: 0
  149. }
  150. }
  151. },
  152. // 提示浮窗样式
  153. tooltip: {
  154. show: false,
  155. trigger: 'item',
  156. alwaysShowContent: false,
  157. backgroundColor: config.customize.tooltipBackgroundColor,
  158. borderColor: config.customize.borderColor,
  159. hideDelay: 100,
  160. triggerOn: 'mousemove',
  161. enterable: true,
  162. textStyle: {
  163. color: '#DADADA',
  164. fontSize: '12',
  165. width: 20,
  166. height: 30,
  167. overflow: 'break'
  168. },
  169. showDelay: 100
  170. },
  171. series: config.customize.scatter
  172. ? [
  173. // {
  174. // type: 'effectScatter',
  175. // coordinateSystem: 'geo',
  176. // effectType: 'ripple',
  177. // showEffectOn: 'render',
  178. // rippleEffect: {
  179. // period: 10,
  180. // scale: 10,
  181. // brushType: 'fill'
  182. // },
  183. // hoverAnimation: true,
  184. // itemStyle: {
  185. // normal: {
  186. // color: 'rgba(255, 235, 59, .7)',
  187. // shadowBlur: 10,
  188. // shadowColor: '#333'
  189. // }
  190. // },
  191. // tooltip: {
  192. // formatter(params) {
  193. // return `<p style="text-align:center;line-height: 30px;height:30px;font-size: 14px;border-bottom: 1px solid #7A8698;">${
  194. // params.name
  195. // }</p>
  196. // <div style="line-height:22px;margin-top:5px">GDP<span style="margin-left:12px;color:#fff;float:right">${
  197. // params.data?.value[2] || '--'
  198. // }</span></div>`
  199. // },
  200. // show: true
  201. // },
  202. // zlevel: 1,
  203. // data: [
  204. // { name: '西藏自治区', value: [91.23, 29.5, 1] },
  205. // { name: '黑龙江省', value: [128.03, 47.01, 1007] },
  206. // { name: '北京市', value: [116.4551, 40.2539, 5007] }
  207. // ]
  208. // }
  209. {
  210. type: 'scatter',
  211. coordinateSystem: 'geo',
  212. symbol: 'pin',
  213. legendHoverLink: true,
  214. symbolSize: [60, 60],
  215. showEffectOn: 'render',
  216. rippleEffect: {
  217. brushType: 'stroke'
  218. },
  219. hoverAnimation: true,
  220. zlevel: 1,
  221. // 这里渲染标志里的内容以及样式
  222. label: {
  223. show: true,
  224. formatter (value) {
  225. return value.data.value[2]
  226. },
  227. color: config.customize.scatterColor
  228. },
  229. // 标志的样式
  230. itemStyle: {
  231. normal: {
  232. color: config.customize.scatterBackgroundColor,
  233. shadowBlur: 2,
  234. shadowColor: 'D8BC37'
  235. }
  236. },
  237. data: config.option?.data
  238. }
  239. ]
  240. : [
  241. {
  242. type: 'map',
  243. map: config.customize.scope,
  244. geoIndex: 0,
  245. roam: false,
  246. zoom: 1.5,
  247. center: [105, 36],
  248. showLegendSymbol: false, // 存在legend时显示
  249. data: config.option?.data,
  250. tooltip: {
  251. formatter (params) {
  252. return `<p style="text-align:center;line-height: 30px;height:30px;font-size: 14px;border-bottom: 1px solid #7A8698;">${
  253. params.name
  254. }</p>
  255. <div style="line-height:22px;margin-top:5px">GDP<span style="margin-left:12px;color:#fff;float:right">${
  256. params.data?.value[2] || '--'
  257. }</span></div>`
  258. },
  259. show: true
  260. }
  261. }
  262. ]
  263. }
  264. if (config.customize.visual) {
  265. this.option.visualMap = {
  266. show: true,
  267. min: config.customize.range[0],
  268. max: config.customize.range[1],
  269. seriesIndex: [0],
  270. inRange: {
  271. color: config.customize.rangeColor
  272. }
  273. }
  274. }
  275. const mapUrl = `${window.BS_CONFIG?.httpConfigs?.baseURL}/static/chinaMap/${config.customize.level}/${config.customize.dataMap}`
  276. const map = await this.$dataRoomAxios.get(decodeURI(mapUrl), {}, true)
  277. echarts.registerMap(config.customize.scope, map)
  278. this.charts.setOption(this.option)
  279. this.charts.on('click', async(params)=> {
  280. if(params.name=='') return
  281. if(config.customize.down===false||this.level==='province') return
  282. this.level='province'
  283. const mapUrl =`${window.BS_CONFIG?.httpConfigs?.baseURL}/static/chinaMap/province/${params.name}.json`
  284. const map = await this.$dataRoomAxios.get(decodeURI(mapUrl), {}, true)
  285. this.changeData({...config,customize:{...config.customize,level:'province',scope:params.name}})
  286. this.option.geo.map = params.name
  287. echarts.registerMap(params.name, map);
  288. this.charts.setOption(this.option, true);
  289. });
  290. }
  291. }
  292. }
  293. </script>
  294. <style lang="scss" scoped>
  295. @import '../../assets/style/echartStyle';
  296. .light-theme {
  297. background-color: #ffffff;
  298. color: #000000;
  299. }
  300. .auto-theme {
  301. background-color: rgba(0, 0, 0, 0);
  302. }
  303. .bs-design-wrap{
  304. position: relative;
  305. padding: 0 16px;
  306. .button{
  307. position: absolute;
  308. z-index: 999;
  309. }
  310. }
  311. </style>