<template> <div style="width: 100%;height: 100%" class="bs-design-wrap bs-custom-component" :class="{'light-theme':customTheme === 'light','auto-theme':customTheme !=='light'}" > <div :id="chatId" style="width: 100%;height: 100%" /> </div> </template> <script> import 'insert-css' import _ from 'lodash' import linkageMixins from 'packages/js/mixins/linkageMixins' import commonMixins from 'packages/js/mixins/commonMixins' import { mapState, mapMutations } from 'vuex' import * as g2Plot from '@antv/g2plot' import plotList, { getCustomPlots } from '../G2Plots/plotList' export default { name: 'PlotCustomComponent', mixins: [commonMixins, linkageMixins], props: { config: { type: Object, default: () => ({}) } }, data () { return { chart: null, hasData: false, plotList } }, computed: { ...mapState('bigScreen', { pageInfo: state => state.pageInfo, customTheme: state => state.pageInfo.pageConfig.customTheme }), chatId () { let prefix = 'chart_' if (this.$route.path === window?.BS_CONFIG?.routers?.previewUrl) { prefix = 'preview_chart_' } if (this.$route.path === window?.BS_CONFIG?.routers?.designUrl) { prefix = 'design_chart_' } if (this.$route.path === window?.BS_CONFIG?.routers?.pageListUrl) { prefix = 'management_chart_' } return prefix + this.config.code } }, created () { this.plotList = [...this.plotList, ...getCustomPlots()] }, mounted () { }, beforeDestroy () { if (this.chart) { this.chart.destroy() } }, methods: { ...mapMutations('bigScreen', ['changeChartConfig']), chartInit () { let config = this.config // key和code相等,说明是一进来刷新,调用list接口 if (this.config.code === this.config.key || this.isPreview) { // 改变样式 config = this.changeStyle(config) // 改变数据 this.changeDataByCode(config).then((res) => { // 初始化图表 this.newChart(res) }).catch(() => {}) } else { // 否则说明是更新,这里的更新只指更新数据(改变样式时是直接调取changeStyle方法),因为更新数据会改变key,调用chart接口 this.changeData(config).then((res) => { // 初始化图表 this.newChart(res) }) } }, /** * 构造chart */ newChart (config) { this.chart = new g2Plot[config.chartType](this.chatId, { renderer: 'svg', // 仪表盘缩放状态下,点击准确 supportCSSTransform: true, ...config.option }) this.chart.render() this.registerEvent() }, /** * 注册事件 */ registerEvent () { // 图表添加事件进行数据联动 let formData = {} // eslint-disable-next-line no-unused-vars this.chart.on('tooltip:change', (...args) => { formData = {} formData = _.cloneDeep(args[0].data.items[0].data) }) // eslint-disable-next-line no-unused-vars this.chart.on('plot:click', (...args) => { this.linkage(formData) }) }, // 将config.setting的配置转化为option里的配置,这里之所以将转化的方法提出来,是因为在改变维度指标和样式的时候都需要转化 transformSettingToOption (config, type) { let option = null config.setting.forEach(set => { if (set.optionField) { const optionField = set.optionField.split('.') option = config.option optionField.forEach((field, index) => { if (index === optionField.length - 1) { // 数据配置时,必须有值才更新 if (set.tabName === type && set.value) { option[field] = set.value } } else { option = option[field] } }) } }) config.option = option return config }, dataFormatting (config, data) { // 数据返回成功则赋值 if (data.success) { data = data.data config = this.transformSettingToOption(config, 'data') // 获取到后端返回的数据,有则赋值 const option = config.option const setting = config.setting if (config.dataHandler) { try { // 此处函数处理data eval(config.dataHandler) } catch (e) { console.error(e) } } config.option.data = data } else { // 数据返回失败则赋前端的模拟数据 config.option.data = this.plotList?.find(plot => plot.name === config.name)?.option?.data } return config }, // 组件的样式改变,返回改变后的config changeStyle (config) { config = this.transformSettingToOption(config, 'custom') // 这里定义了option和setting是为了保证在执行eval时,optionHandler、dataHandler里面可能会用到, const option = config.option const setting = config.setting if (this.config.optionHandler) { try { // 此处函数处理config eval(this.config.optionHandler) } catch (e) { console.error(e) } } if (this.chart) { this.chart.update(config.option) } this.changeChartConfig(config) return config } } } </script> <style lang="scss" scoped> @import '~packages/assets/style/echartStyle'; .light-theme{ background-color: #FFFFFF; color: #000000; } .auto-theme{ background-color: rgba(0,0,0,0); } </style>