123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- import { defineComponent, onMounted, ref, onUnmounted, computed, watch, toRefs } from 'vue'
- import * as echarts from 'echarts'
- import { bind, clear } from 'size-sensor'
- import { map, groupBy, debounce } from 'lodash'
- import { NAME, GROUP, VALUE, OPTION, CONFIG_ERROR, BAR_OPTION } from './const'
- import { Encode } from './method'
- import './common.less'
- /**
- * 组件提供默认option, 也支持自定义
- * dataset为数据集,传入时需要指定绑定字段,默认为name,value;当存在多维数据时需要指定group
- * dataset example
- * [
- * { name: '邮件营销', value: 120, group: '周一' },
- { name: '邮件营销', value: 110, group: '周二' },
- { name: '邮件营销', value: 99, group: '周三' },
- { name: '联盟广告', value: 11, group: '周一' },
- { name: '联盟广告', value: 21, group: '周二' },
- { name: '联盟广告', value: 31, group: '周三' },
- { name: '视频广告', value: 91, group: '周一' },
- { name: '视频广告', value: 41, group: '周二' },
- { name: '视频广告', value: 41, group: '周三' }
- ]
- */
- export default defineComponent({
- name: 'CipCharts',
- props: {
- options: {
- type: Object,
- default: () => OPTION
- },
- dataset: {
- type: Array,
- default: () => []
- },
- bindProps: {
- type: Object,
- default: () => ({
- name: NAME,
- value: VALUE,
- group: GROUP
- })
- }
- },
- emits: ['chart-init'],
- setup (props, { emit }) {
- const chartRef = ref()
- let charts = null
- const { dataset, options, bindProps } = toRefs(props)
- const groupData = computed(() => {
- return groupBy(dataset.value, bindProps.value.group ?? GROUP)
- })
- // 判断是否存在group
- const isSingleGroup = computed(() => {
- return Object.keys(groupData.value)[0] === 'undefined'
- })
- // 获取dataset
- const _dataset = computed(() => {
- const keys = Object.keys(groupData.value)
- const _name = bindProps.value.name
- const _value = bindProps.value.value
- if (isSingleGroup.value) return dataset.value.map(item => ({ ...item, [VALUE]: item[_value], name: item[_name] }))
- const result = keys.map(currentKey => {
- const currentData = groupData.value[currentKey].reduce((obj, item) => {
- obj[item[_name]] = item[_value]
- return obj
- }, {})
- return {
- name: currentKey,
- ...currentData
- }
- })
- return result
- })
- // 获取dimensions
- const dimensions = computed(() => {
- const groups = [...new Set(map(dataset.value, bindProps.value.name))]
- return (groups?.length && !isSingleGroup.value) ? [NAME, ...groups] : [NAME, VALUE]
- })
- // 判断series是否存在,不存在则给默认值;series中如何存在data,则data的优先级高
- const series = computed(() => {
- const EncodeInstance = new Encode(props.bindProps)
- if (options.value.series?.length) return EncodeInstance.checkEncode(options.value.series)
- else {
- const generateSeries = Array.from({ length: dimensions.value.length - 1 }).map(() => ({
- ...BAR_OPTION
- }))
- return generateSeries.length > 1 ? generateSeries : EncodeInstance.checkEncode(generateSeries)
- }
- })
- // 处理option数据
- const chartsOption = computed(() => {
- // const legend = Object.assign({}, options.value.legend || {}, {
- // show: !isSingleGroup.value
- // })
- return Object.assign({},
- OPTION,
- options.value,
- // { legend },
- isHasDataset.value ? {} : {
- dataset: {
- dimensions: dimensions.value,
- source: _dataset.value
- }
- }, { series: series.value })
- })
- // 判断option中是否存在dataset, 存在在则使用option配置
- const isHasDataset = computed(() => {
- return 'dataset' in options.value
- })
- // 图表resize
- const bindResize = () => {
- chartRef.value && bind(chartRef.value, debounce(() => {
- charts && charts.resize()
- }, 500))
- }
- // 组合echats的options
- onMounted(() => {
- charts = echarts.init(chartRef.value)
- try {
- console.log(chartsOption.value, 'chartsOption')
- charts.setOption(chartsOption.value)
- bindResize()
- emit('chart-init', charts)
- } catch (error) {
- console.error(CONFIG_ERROR)
- }
- })
- // 销毁实例
- onUnmounted(() => {
- if (charts) {
- charts.dispose()
- charts = null
- chartRef.value && clear(chartRef.value)
- }
- })
- watch([options, dataset], () => {
- try {
- charts.clear()
- charts.setOption(chartsOption.value)
- } catch (error) {
- console.error(CONFIG_ERROR)
- }
- }, {
- deep: true
- })
- return () => <div ref={chartRef} class="cip-chart-wrapper"></div>
- }
- })
|