当前位置: 首页 > news >正文

业务项目中Echarts图表组件的封装实践方案

背景:如果我们的项目是一个可视化类/营销看板类/大屏展示类业务项目,不可避免的会使用到各种图表展示。那在一个项目中如何封装一个图表组件既能够快速复用、UI统一,又可以灵活扩充Echarts的各种复杂配置项配置就变得极为重要。

封装目标

  • 符合当前系统的业务UI(轴线、分隔线、配色、面积色、legend 等等)及场景
  • 可基于基础配置项便捷扩充其他特殊配置项
  • 可支持Echarts原生配置项,不引入过多额外的配置项!!!

封装误区

  • 基于Echarts配置项封装了基础配置项组件,但是组件无法扩充额外的配置项,使用不灵活(即总是需要频繁修改封装组件)
  • 在Echarts的的配置项上又封装了一层,改变了很多的配置项内容,使用成本较高(往往需要查看组件源码才知道要传入什么配置项属性)

封装思路

在这里插入图片描述

Vue项目实践

线图封装

<template><div v-if="notEmpty" :id="id" class="echarts-line"></div><div v-else class="echarts-empty">暂无数据</div>
</template><script>
import echarts from 'echarts';
import deepmerge from 'deepmerge';// 系统自定义区域
const colors = []; // 系统自定义的主题配色export default {name: 'EchartsLine',props: {echartsData: {type: Object,required: true,},},data() {return {lineChart: null,};},computed: {id() {return `echarts_line_${this.echartsData.id}`;},notEmpty() {return this.echartsData && this.echartsData.category.length > 0 && this.echartsData.series.length > 0;},},watch: {echartsData(value) {if (this.lineChart) {this.lineChart.setOption(this.getMergeOptions(value));this.lineChart.resize();}},},mounted() {this.init();},beforeDestroy() {window.removeEventListener('resize', this._listenerResize);},methods: {// [private] 处理轴的类型配置项,支持x轴为类目轴 | y轴为类目轴 | 双数据轴_dealAxisType(type, category) {const categoryAxis = {type: 'category',boundaryGap: true,data: category,};const valueAxis = {type: 'value',};switch (type) {case 'xCategory':return {xAxis: categoryAxis,yAxis: valueAxis,};case 'yCategory':return {yAxis: categoryAxis,xAxis: valueAxis,};case 'doubleValue':return {xAxis: {max: 'dataMax',boundaryGap: true,splitLine: {show: false,},},yAxis: {},};default:return {xAxis: categoryAxis,yAxis: valueAxis,};}},// [private] 获取线图默认配置项,系统整体统一UI_getDefaultOptions(type, category) {return {title: {subtext: '',left: 'center',textStyle: {color: '#98a6ad',fontSize: 16,fontWeight: 'normal',},},legend: {type: 'scroll',bottom: '0',},grid: {top: '30px',bottom: '50px',},color: colors,tooltip: {trigger: 'axis',axisPointer: {type: 'cross',},},...this._dealAxisType(type, category),};},// [private] 监听resize时间_listenerResize() {if (this.lineChart) {this.lineChart.resize();}},/*** [public] getMergeOptions 获取合并后的图表配置项,自定义配置项与默认配置项融合,若自定义配置项与默认配置项冲突则自定义配置项生效* 配置项合并规则:https://www.npmjs.com/package/deepmerge* @param type {String} * @param category {Array}* @param series {Array}* @param echartsConfig {Object}*/getMergeOptions({type = 'xCategory',category,series,echartsConfig = {},}) {// 01. 用户传进来的配置项和默认配置项进行合并const mergeOptions = deepmerge(this._getDefaultOptions(type, category),echartsConfig,);// 02. Series配置项合并【此处为示例】const mergeSeries = [];if (series && series.length > 0) {series.forEach((item) => {mergeSeries.push(deepmerge(item, {type: 'line',}),);});}// 03. 返回合并后的整体配置项 return {...mergeOptions,series: mergeSeries,};},// [public] 交互点,获取图表实例,用于触发图表APIgetEchartsInstance() {if (this.lineChart) {return this.lineChart;}return null;},// [public] 初始化图表init() {this.$nextTick(() => {this.lineChart = echarts.init(document.getElementById(this.id));this.lineChart.setOption(this.getMergeOptions(this.echartsData),);window.addEventListener('resize', this._listenerResize);});},},};
</script><style lang="less" rel="stylesheet/less" scoped>
.echarts-line{height: 350px;
}.echarts-empty{height: 200px;line-height: 200px;text-align: center;
}
</style>

业务调用

<v-line-chart class="echarts-item" :echarts-data="chartData"></v-line-chart>
 this.chartData = {id: 'lineChart',category:['test1','test2','test3','test4'],series: [{name: '测试图表',data:[10,20,30,40],}],echartsConfig: { // 所有Echarts原生配置项放在该属性下legend: {show: false,},},
};

参考

  • Echarts官网:https://echarts.apache.org/zh/index.html
  • deepMerge gitHub:https://github.com/TehShrike/deepmerge

业务方案简单封装,不作为公共UI库使用,欢迎讨论其他实现方案

相关文章:

业务项目中Echarts图表组件的封装实践方案

背景&#xff1a;如果我们的项目是一个可视化类/营销看板类/大屏展示类业务项目&#xff0c;不可避免的会使用到各种图表展示。那在一个项目中如何封装一个图表组件既能够快速复用、UI统一&#xff0c;又可以灵活扩充Echarts的各种复杂配置项配置就变得极为重要。 封装目标 符…...

鸿蒙开发之拖拽事件

一、拖拽涉及的方法 Text(this.message).fontSize(50).fontWeight(FontWeight.Bold)//拖拽开始.onDragStart((event: DragEvent) > {console.log(drag event onDragStartevent.getX())})//拖拽进入组件范围&#xff0c;需要监听onDrop配合.onDragEnter((event: DragEvent) …...

C#使用纯OpenCvSharp部署yolov8-pose姿态识别

【源码地址】 github地址&#xff1a;https://github.com/ultralytics/ultralytics 【算法介绍】 Yolov8-Pose算法是一种基于深度神经网络的目标检测算法&#xff0c;用于对人体姿势进行准确检测。该算法在Yolov8的基础上引入了姿势估计模块&#xff0c;通过联合检测和姿势…...

[AutoSar]基础部分 RTE 04 数据类型的定义及使用

目录 关键词平台说明一、数据类型分类二、Adt三、Idt四、Base 数据类型五、units六、compu methods七、data constraint 关键词 嵌入式、C语言、autosar、Rte 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0c;C编译器HighTec (GCC) 一、数据…...

c#调试程序一次启动两个工程(多个工程)

概述 c# - Visual Studio : debug multiple projects at the same time? 以在解决方案中设置多个启动项目(右键单击解决方案&#xff0c;转到设置启动项目&#xff0c;选择多个启动项目)&#xff0c;并为包含在解决方案(无、开始、不调试就开始)。如果您将多个项目设置为开始…...

轻松搭建企业知识库:10款必备工具推荐

随着企业知识的不断积累和团队规模的扩大&#xff0c;如何高效地管理和利用这些知识成为了一个重要的问题。企业知识库作为一种有效的知识管理工具&#xff0c;可以帮助企业将分散的知识整合在一起&#xff0c;方便团队成员快速查找、学习和共享。接下来就分享10款很不错的企业…...

第三天学习记录

第二天 C++随便提一提重点学习编译原理选学离散数学形式语言与自动机理论数据结构C++ 随便提一提 C++面向对象编程。与强调算法的过程性编程(试图使问题满足语言的过程性方法)不同。面向对象编程强调的是数据,它试图让语言来满足问题的要求。其理念是设计与问题本质特征相对…...

内核线程创建-kthread_create

文章参考Linux内核线程kernel thread详解 - 知乎 大概意思就是早期创建内核线程&#xff0c;是交由内核处理&#xff0c;由内核自己完成&#xff08;感觉好像也不太对呢&#xff09;&#xff0c;创建一个内核线程比较麻烦&#xff0c;会导致内核阻塞。因此就诞生了工作队列以及…...

uniappVue3版本中组件生命周期和页面生命周期的详细介绍

一、什么是生命周期&#xff1f; 生命周期有多重叫法&#xff0c;有叫生命周期函数的&#xff0c;也有叫生命周期钩子的&#xff0c;还有钩子函数的&#xff0c;其实都是代表&#xff0c;在 Vue 实例创建、更新和销毁的不同阶段触发的一组钩子函数&#xff0c;这些生命周期函数…...

任务驱动式编程

main /** 模板代码*/#include "gd32f4xx.h" #include "systick.h" #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include "main.h" #include "USART0.h" #include &quo…...

python数据可视化之折线图案例讲解

学习完python基础知识点&#xff0c;终于来到了新的模块——数据可视化。 我理解的数据可视化是对大量的数据进行分析以更直观的形式展现出来。 今天我们用python数据可视化来实现一个2023年三大购物平台销售额比重的折线图。 准备工作&#xff1a;我们需要下载用于生成图表的第…...

QT工具栏开始,退出

QT工具栏开始&#xff0c;退出 //初始化场景QMenuBar *bar menuBar();setMenuBar(bar);QMenu *startbar bar->addMenu("开始");QAction * quitAction startbar->addAction("退出");connect(quitAction , &QAction::triggered,[](){this->c…...

@Async正确使用姿势

Async注解可以使被修饰的方法成为异步方法&#xff0c;简单且方便&#xff0c;这篇文章将教你如何正确的使用它 先谈谈大多数人对Aysnc的认识&#xff1a; 如果直接使用Async&#xff0c;未指定线程池 并且 容器内也没有beanName为taskExecutor的bean&#xff0c;则会使…...

试除法判定质数算法总结

知识概览 质数的定义 在大于1的整数中&#xff0c;如果只包含1和本身这两个约数&#xff0c;就被称为质数&#xff0c;或者叫素数。 质数的判定——试除法 暴力算法 时间复杂度 改进算法 时间复杂度 暴力算法&#xff1a;时间复杂度O(n) 算法模版 bool is_pr…...

vuetify 回到顶部

参考链接 // 回到id#app-content-container 的dom节点顶部 onScroll() {const ele document.querySelector(#app-content-container)// this.$vuetify.goTo(0, duration)this.$vuetify.goTo(#app-content-container, { container: ele })},...

Socket与TCP的关系

前言 相信大家对于TCP已经非常熟悉了&#xff0c;学习过计算机网络的同学对于它的连接和断开流程应该已经烂熟于心了吧。 那么Socket是什么&#xff1f; Socket是应用层与TCP/IP协议簇通信的中间软件抽象层&#xff0c;它是一组接口。在设计模式中&#xff0c;Socket其实就是…...

RKE安装k8s及部署高可用rancher之证书私有证书但是内置的ssl不放到外置的LB中 4层负载均衡

先决条件# Kubernetes 集群 参考RKE安装k8s及部署高可用rancher之证书在外面的LB&#xff08;nginx中&#xff09;-CSDN博客CLI 工具Ingress Controller&#xff08;仅适用于托管 Kubernetes&#xff09; 创建集群k8s [rootnginx locale]# cat rancher-cluster.yml nodes:- …...

使用爬虫爬取热门电影

文章目录 网站存储视频的原理M3U8文件解读网站分析代码实现 网站存储视频的原理 首先我们来了解一下网站存储视频的原理。 一般情况下&#xff0c;一个网页里想要显示出一个视频资源&#xff0c;必须有一个<video>标签&#xff0c; <video src"xxx.mp4"&…...

【unity小技巧】实现没有动画的FPS武器摇摆和摆动效果

文章目录 前言开始完结 前言 添加程序摇摆和摆动是为任何FPS游戏添加一些细节的非常简单的方法。但是并不是所以的模型动画都会配有武器摆动动画效果&#xff0c;在本文中&#xff0c;将实现如何使用一些简单的代码实现武器摇摆和摆动效果&#xff0c;这比设置动画来尝试实现类…...

C语言基础知识(6):UDP网络编程

UDP 是不具有可靠性的数据报协议。细微的处理它会交给上层的应用去完成。在 UDP 的情况下&#xff0c;虽然可以确保发送消息的大小&#xff0c;却不能保证消息一定会到达。因此&#xff0c;应用有时会根据自己的需要进行重发处理。 1.UDP协议的主要特点&#xff1a; &#xf…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

Matlab实现任意伪彩色图像可视化显示

Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中&#xff0c;如何展示好看的实验结果图像非常重要&#xff01;&#xff01;&#xff01; 1、灰度原始图像 灰度图像每个像素点只有一个数值&#xff0c;代表该点的​​亮度&#xff08;或…...