index.vue 8.2 KB

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