Vue3 + hook + Apexcharts实现可视化图表渲染的封装 - 第二节 - 图表的全屏功能(Vuex)

目录

Vue3 + hook + Apexcharts实现可视化图表渲染的封装 - 第一节 - 基础封装
Vue3 + hook + Apexcharts实现可视化图表渲染的封装 - 第二节 - 图表的全屏功能 (当前所在)

摘要

上一节中,我们用Vue3 + hook + Apexcharts封装了图表渲染的基础代码。这节我们将在那个基础上进行图表的全屏查看功能。上一级代码中的 renderCharts 函数中有通过 getScatterDatainterceptFn 对图表数据进行截取,当图表数据有几万条时,像条形图、散点图这些如果一次性渲染出来就会导致页面卡顿,从而影响页面的其他功能。这时我们就可以在初始的时候渲染部分的数据,全屏的时候再渲染全部的数据。

正文

  1. 怎么自定义全屏图表?
  2. 当同一个页面中有多个图表时,在全屏某个图表时怎么获取正确的渲染?

实现思路

自定义全屏图表按钮
效果

在这里插入图片描述

右上角中有个全屏图表按钮,Apexcharts中提供了自定义工具栏的功能

代码实现
// 导入全屏按钮的图标
import fullScreenImg from '@/assets/images/fullScreen.webp'
// 在图表中配置
chart: {
	toolbar: {
		tools: {
			download: true,
			selection: false,
			zoom: false,
			zoomin: false,
			zoomout: false,
			pan: false,
			reset: false,
			customIcons: [{
				icon: `<img src="${fullScreenImg}" width="16" height="16">`,
				index: -1,
				title: '全屏',
				class: 'custom-icon',
				click: (chart, options) => {}
			}]
		},
}

// 设置全局的css
.vue-apexcharts .custom-icon {
	margin-right: 6px;
	transform: translateY(2px);
}
渲染正确的图表
实现过程
  1. 在全局的store中记录当前页面的全部图表的 chartInfo ,包括 chartObj 初始化的某些图表配置项、option 渲染图表后需要根据数据设置的配置项, 以及 data 当前渲染图表所需的数据。
  2. 为了区分对应的图表数据,全局的 chartInfo 为一个 Map 对象,通过 ID 可获取对应当前全屏对应的图表的数据。需要在 ApexChart 的父级中设置一个唯一的 ID
<div id="ChartID">
	<ApexChart>
</div>
  1. 何时设置数据? ,在图表渲染时,也就是调用 renderChart 时,图表的数据更新会触发 updated 事件,在这个时候可以设置当前图表的信息。
<div id="ChartID">
	<ApexChart @updated="onChartUpdated">
</div>
  1. 创建全局的全屏图表弹窗,通过全局的store去控制。当我点击某个图表的全屏按钮时会在上面自定义全屏按钮里的 click 中将对应的当前的图表父元素的 IDchartType 记录下来。
customIcons: [{
	click: (chart, options) => {
		store.dispatch('chart/setChartType', options.config.chart.type)
		store.dispatch('chart/setChartId', chart.el.parentElement.id)
		store.dispatch('chart/visibleDialog', true)
	}
}]
代码实现

store/chart.js

const state = {
	visible: false,
	chartType: 'line',
	chartId: '',
	chartInfo: {},
}

const mutations = {
	VISIBLE_DIALOG: (state, view) => {
		state.visible = view
	},
	SET_CHART_TYPE: (state, view) => {
		state.chartType = view
	},
	SET_CHART_ID: (state, view) => {
		state.chartId = view
	},
	SET_CHART_INFO: (state, view) => {
		if (!view) {
			state.chartInfo = {}
			return
		}
		const { id, chartObj, option, data } = view
		state.chartInfo[id] = { chartObj, option, data }
	},
}

const actions = {
	visibleDialog({ commit }, view) {
		commit('VISIBLE_DIALOG', view)
	},
	setChartType({ commit }, view) {
		commit('SET_CHART_TYPE', view)
	},
	setChartId({ commit }, view) {
		commit('SET_CHART_ID', view)
	},
	setChartInfo({ commit }, view) {
		commit('SET_CHART_INFO', view)
	},
}

export default {
	namespaced: true,
	state,
	mutations,
	actions,
}

utils/chart.js

import _ from 'lodash'
import store from '@/store'

export const setChartDialogInfo = (id, chartObj, data, ...rest) => {
	const obj = _.cloneDeep(chartObj)
	obj.options.responsive = []
	obj.options.chart.toolbar.tools.customIcons = []
	const option = obj.updateOptions(data, ...rest)

	store.dispatch('chart/setChartInfo', {id, chartObj: obj, option, data})
}

hook/useRenderChart.js

其他代码请访问第一节:Vue3 + hook + Apexcharts实现可视化图表渲染的封装 - 第一节 - 基础封装

const useRenderChart = (chartList) => {
	.....其他代码
	
	const count = ref(0)
	// 监听图表更新,设置ChartDialog弹框的信息
	const configChartDialog = () => {
		if (!chartList[count.value]) return
		const { chartObj, data, key } = chartList[count.value]
		setChartDialogInfo(key, chartObj, data)
		count.value++

		if (count.value === chartList.length) {
			count.value = 0
		}
	}
	
	return {
		configChartDialog
	}
}

ApexChart组件中使用

<ApexChart
	:ref="el => setRefMap(el, index)"
	:type="item.type"
	:options="item.chartObj.options"
	:series="item.chartObj.series"
	@updated="configChartDialog"
/>

全屏弹框组件components/ChartDialog

<template>
	<el-dialog
		class="chart-dialog"
		:title="$t('common.chart')"
		v-model="visible"
		:fullscreen="true"
		center
		@close="handleClose"
	>
		<ApexChart
			v-loading="loading"
			:key="chartId"
			ref="chartRef"
			:height="height"
			:type="chartType"
			:options="chartObj.options || {}"
			:series="chartObj.series || []"
			@updated="onChartUpdated"
		/>
	</el-dialog>
</template>

<script setup>
import ApexChart from 'vue3-apexcharts'

const store = useStore()

const visible = computed(() => store.state.chart.visible)
const chartType = computed(() => store.state.chart.chartType)
const chartId = computed(() => store.state.chart.chartId)
const chartInfo = computed(() => store.state.chart.chartInfo)
const chartObj = computed(() => chartInfo.value[chartId.value]?.chartObj || {})

const chartRef = ref()
const height = computed(() => window.innerHeight - 140)

const loading = ref(true)
watch(visible, (val) => {
	if (val) {
		nextTick(() => {
			setTimeout(() => {
				chartRef.value.updateOptions(chartInfo.value[chartId.value].option)
				loading.value = false
			}, 500)
		})
	}
})

const handleClose = () => {
	store.dispatch('chart/visibleDialog', false)
	store.dispatch('chart/setChartId', '')
	loading.value = false
}
</script>

总结

因为网上Apexcharts的文章极少,这是自己使用过程中的一下记录。这次记录的是图表的全屏的弹窗功能。下一节开始将记录一些Apexcharts无法满足的需要,但是业务中却需要的图表绘制功能。

  • 22
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3是一种用于构建用户界面的JavaScript框架,它具有快速、灵活、可重用等特点。Webpack则是一种JS的打包工具,可以将多个JS文件打成一个JS文件。Vue-Router是Vue框架中的路由管理器,通过它可以实现前端路由的切换。Axios则是一种基于Promise的 HTTP 库,用于处理前端与后端的数据交互。Vuex则是Vue框架中的状态管理工具,将组件的共享状态抽取出来,以集中管理,便于开发人员管理。这些技术都是前端开发中必不可少的技术,用于优化前端项目的结构,提高开发效率。 在具体的项目开发中,为了提高代码的复用性,通常会对这些技术进行进一步的封装。对于Vue-Router,可以将项目的路由进行封装,创建一个Route.js文件,用于统一管理路由。通过这样的封装,可以使得路由的管理更加清晰。 对于Axios,可以通过封装一个API.js文件,将后端接口进行统一管理,减少代码的重复性。在API.js中可以封装所有后端接口的请求方法,统一处理请求返回的数据。 对于Vuex,则可以将项目的状态进行封装,写一个store.js文件,用于集中管理应用的状态。在store.js中可以设置全局数据,方便在各个组件中进行访问和修改。同时,也可以将状态的变化通过mutations.js文件封装,以保证数据的可靠性。 最后,使用Webpack进行打包。Webpack可以将多个JS文件打成一个JS文件,减少了请求的次数,提高了页面的加载速度。 综上所述,通过对Vue3、Webpack、Vue-Router、Axios、Vuex等技术的封装,可以提高代码的复用性和可维护性,从而加快项目的开发进度。同时,这些技术的结合还能够为项目提供更好的架构,提升用户的使用体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值