index.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <template>
  2. <div
  3. v-loading="config.loading"
  4. element-loading-text="图表加载中"
  5. style="width: 100%;height: 100%"
  6. class="bs-design-wrap bs-custom-component"
  7. :class="{'light-theme':customTheme === 'light','auto-theme':customTheme !=='light'}"
  8. >
  9. <div
  10. :id="chatId"
  11. style="width: 100%;height: 100%"
  12. />
  13. <!-- <span style="color:#ffffff">{{config.option.data}}</span>-->
  14. </div>
  15. </template>
  16. <script>
  17. import 'insert-css'
  18. import cloneDeep from 'lodash/cloneDeep'
  19. import linkageMixins from 'data-room-ui/js/mixins/linkageMixins'
  20. import commonMixins from 'data-room-ui/js/mixins/commonMixins'
  21. import { mapState, mapMutations } from 'vuex'
  22. import * as g2Plot from '@antv/g2plot'
  23. import plotList, { getCustomPlots } from '../G2Plots/plotList'
  24. import { settingToTheme } from 'data-room-ui/js/utils/themeFormatting'
  25. import _ from 'lodash'
  26. export default {
  27. name: 'PlotCustomComponent',
  28. mixins: [commonMixins, linkageMixins],
  29. props: {
  30. config: {
  31. type: Object,
  32. default: () => ({})
  33. }
  34. },
  35. data () {
  36. return {
  37. chart: null,
  38. hasData: false,
  39. plotList
  40. }
  41. },
  42. computed: {
  43. ...mapState('bigScreen', {
  44. pageInfo: state => state.pageInfo,
  45. customTheme: state => state.pageInfo.pageConfig.customTheme,
  46. activeCode: state => state.activeCode
  47. }),
  48. chatId () {
  49. let prefix = 'chart_'
  50. if (this.$route.path === window?.BS_CONFIG?.routers?.previewUrl) {
  51. prefix = 'preview_chart_'
  52. }
  53. if (this.$route.path === window?.BS_CONFIG?.routers?.designUrl) {
  54. prefix = 'design_chart_'
  55. }
  56. if (this.$route.path === window?.BS_CONFIG?.routers?.pageListUrl) {
  57. prefix = 'management_chart_'
  58. }
  59. return prefix + this.config.code
  60. }
  61. },
  62. created () {
  63. this.plotList = [...this.plotList, ...getCustomPlots()]
  64. },
  65. watch: {
  66. // 监听主题变化手动触发组件配置更新
  67. 'config.option.theme': {
  68. handler (val) {
  69. if (val) {
  70. this.changeStyle(this.config, true)
  71. }
  72. }
  73. }
  74. },
  75. mounted () {
  76. },
  77. beforeDestroy () {
  78. if (this.chart) {
  79. this.chart.destroy()
  80. }
  81. },
  82. methods: {
  83. ...mapMutations('bigScreen', ['changeChartConfig', 'changeActiveItemConfig', 'changeChartLoading']),
  84. chartInit () {
  85. let config = this.config
  86. // key和code相等,说明是一进来刷新,调用list接口
  87. if (this.config.code === this.config.key || this.isPreview) {
  88. // 改变样式
  89. config = this.changeStyle(config)
  90. // 改变数据
  91. config.loading = true
  92. this.changeChartLoading(config)
  93. this.changeDataByCode(config).then((res) => {
  94. // 初始化图表
  95. config.loading = false
  96. this.changeChartLoading(config)
  97. this.newChart(res)
  98. }).catch(() => {
  99. })
  100. } else {
  101. config.loading = true
  102. this.changeChartLoading(config)
  103. // 否则说明是更新,这里的更新只指更新数据(改变样式时是直接调取changeStyle方法),因为更新数据会改变key,调用chart接口
  104. this.changeData(config).then((res) => {
  105. config.loading = false
  106. this.changeChartLoading(config)
  107. // 初始化图表
  108. this.newChart(res)
  109. })
  110. }
  111. },
  112. /**
  113. * 构造chart
  114. */
  115. newChart (config) {
  116. this.chart = new g2Plot[config.chartType](this.chatId, {
  117. renderer: 'svg',
  118. // 仪表盘缩放状态下,点击准确
  119. supportCSSTransform: true,
  120. ...config.option
  121. })
  122. this.chart.render()
  123. this.registerEvent()
  124. },
  125. /**
  126. * 注册事件
  127. */
  128. registerEvent () {
  129. // 图表添加事件进行数据联动
  130. let formData = {}
  131. // eslint-disable-next-line no-unused-vars
  132. this.chart.on('tooltip:change', (...args) => {
  133. formData = {}
  134. formData = cloneDeep(args[0].data.items[0].data)
  135. })
  136. // eslint-disable-next-line no-unused-vars
  137. this.chart.on('plot:click', (...args) => {
  138. this.linkage(formData)
  139. })
  140. },
  141. // 将config.setting的配置转化为option里的配置,这里之所以将转化的方法提出来,是因为在改变维度指标和样式的时候都需要转化
  142. transformSettingToOption (config, type) {
  143. let option = null
  144. config.setting.forEach(set => {
  145. if (set.optionField) {
  146. const optionField = set.optionField.split('.')
  147. option = config.option
  148. optionField.forEach((field, index) => {
  149. if (index === optionField.length - 1) {
  150. // 数据配置时,必须有值才更新
  151. if ((set.tabName === type && type === 'data' && set.value) || (set.tabName === type && type === 'custom')) {
  152. option[field] = set.value
  153. }
  154. } else {
  155. option = option[field]
  156. }
  157. })
  158. }
  159. })
  160. config.option = { ...config.option, ...option }
  161. return config
  162. },
  163. dataFormatting (config, data) {
  164. // 数据返回成功则赋值
  165. if (data.success) {
  166. data = data.data
  167. config = this.transformSettingToOption(config, 'data')
  168. // 获取到后端返回的数据,有则赋值
  169. const option = config.option
  170. const setting = config.setting
  171. if (config.dataHandler) {
  172. try {
  173. // 此处函数处理data
  174. eval(config.dataHandler)
  175. } catch (e) {
  176. console.error(e)
  177. }
  178. }
  179. config.option.data = data
  180. } else {
  181. // 数据返回失败则赋前端的模拟数据
  182. config.option.data = this.plotList?.find(plot => plot.name === config.name)?.option?.data || config?.option?.data
  183. }
  184. return config
  185. },
  186. // 组件的样式改变,返回改变后的config
  187. changeStyle (config, isUpdateTheme) {
  188. config = { ...this.config, ...config }
  189. config = this.transformSettingToOption(config, 'custom')
  190. // 这里定义了option和setting是为了保证在执行eval时,optionHandler、dataHandler里面可能会用到,
  191. const option = config.option
  192. const setting = config.setting
  193. if (this.config.optionHandler) {
  194. try {
  195. // 此处函数处理config
  196. eval(this.config.optionHandler)
  197. } catch (e) {
  198. console.error(e)
  199. }
  200. }
  201. // 只有样式改变时更新主题配置,切换主题时不需要保存
  202. if (!isUpdateTheme) {
  203. config.theme = settingToTheme(_.cloneDeep(config), this.customTheme)
  204. }
  205. this.changeChartConfig(config)
  206. if (config.code === this.activeCode) {
  207. this.changeActiveItemConfig(config)
  208. }
  209. if (this.chart) {
  210. this.chart.update(config.option)
  211. }
  212. return config
  213. }
  214. }
  215. }
  216. </script>
  217. <style lang="scss" scoped>
  218. @import '../assets/style/echartStyle';
  219. .light-theme{
  220. background-color: #FFFFFF;
  221. color: #000000;
  222. }
  223. .auto-theme{
  224. background-color: transparent;
  225. }
  226. </style>