业务项目中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] 交互点,获取图表实例,用于触发图表API
    getEchartsInstance() {
      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库使用,欢迎讨论其他实现方案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/294642.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vmware workstation的三种网络模式通俗理解

一、前言 workstations想必很多童鞋都在用&#xff0c;经常会用来在本机创建不同的虚拟机来做各种测试&#xff0c;那么对于它支持的网络模式&#xff0c;在不同的测试场景下应该用哪种网络模式&#xff0c;你需要做下了解&#xff0c;以便可以愉快的继续测&#xff08;搬&…

1.5C语言 双曲正弦函数(*) 优化麦克劳林公式

一.传统算法 #include<stdio.h> #include<math.h> int jc(int x); int main(){double x,eps,y0.0;scanf("%lf%lf",&x,&eps);int de1,i1;double item1.0;while(fabs(item)>eps){itempow(x,i)/jc(de);i2;yitem;}printf("%.6f\n",y); …

H5 - - - - - 获取图片exif相关信息

1. EXIF是什么 【可交换图像文件格式】&#xff1a;&#xff08;英语&#xff1a;Exchangeable image file format&#xff0c;官方简称Exif&#xff09;,是专门为数码相机的照片设定的&#xff0c;可以记录数码照片的属性信息和拍摄数据。 2. EXIF 相关标识 { ApertureValu…

科研上新 | 第6期:优化LLM数学推理;深度学习建模基因表达调控;基于深度学习的近实时海洋碳汇估算

编者按&#xff1a;欢迎阅读“科研上新”栏目&#xff01;“科研上新”汇聚了微软亚洲研究院最新的创新成果与科研动态。在这里&#xff0c;你可以快速浏览研究院的亮点资讯&#xff0c;保持对前沿领域的敏锐嗅觉&#xff0c;同时也能找到先进实用的开源工具。 本期内容速览 …

redisson作为分布式锁的底层实现

1. redisson如何实现尝试获取锁的逻辑 如何实现在一段的时间内不断的尝试获取锁 其实就是搞了个while循环&#xff0c;不断的去尝试获取锁资源。但是因为latch的存在会在给定的时间内处于休眠状态。这个事件&#xff0c;监听的是解锁动作&#xff0c;如果解锁动作发生。会调用…

webrtc报文记录

tcp.port 10443 || tcp.port 6080 || udp.port 8000 https://download.csdn.net/download/dualvencsdn/88706745

flutter学习-day23-使用extended_image处理图片的加载和操作

文章目录 1. 介绍2. 属性介绍3. 使用 1. 介绍 在 Flutter 的开发过程中&#xff0c;经常会遇到图片的显示和加载处理&#xff0c;通常显示一个图片&#xff0c;都有很多细节需要处理&#xff0c;比如图片的加载、缓存、错误处理、图片的压缩、图片的格式转换等&#xff0c;如果…

面试算法97:子序列的数目

题目 输入字符串S和T&#xff0c;请计算字符串S中有多少个子序列等于字符串T。例如&#xff0c;在字符串"appplep"中&#xff0c;有3个子序列等于字符串"apple" 分析 为了解决这个问题&#xff0c;每步从字符串S中取出一个字符判断它是否和字符串T中的…

《MySQL系列-InnoDB引擎04》MySQL表相关介绍

文章目录 第四章 表1 索引组织表2 InnoDB逻辑存储结构2.1 表空间2.2 段2.3 区2.4 页2.5 行2.6 拓展&#xff1a;MySQL的varchar(n)能存储几个字符&#xff1f;占多少字节&#xff1f; 3 InnoDB行记录格式4 文件格式5 约束5.1 数据完整性5.2 约束的创建和查找5.3 约束和索引的区…

决策树--分类决策树

1、介绍 ① 定义 分类决策树通过树形结构来模拟决策过程&#xff0c;决策树由结点和有向边组成。结点有两种类型&#xff1a;内部结 点和叶结点。内部结点表示一个特征或属性&#xff0c;叶子节点表示一个类。 ② 生成过程 用决策树分类&#xff0c;从根结点开始&#xff…

UI5与后端的文件交互(三)

文章目录 前言一、开发Action1. 修改Table2. BDEF中新增Action3. 新建结构&#xff0c;用于接收uuid以及附件数据4. 实现Method逻辑 二、UI5项目修改1. 添加表格行2. 事件处理函数3. 点击文件名时的事件 三、测试 前言 这系列文章详细记录在Fiori应用中如何在前端和后端之间使…

GB∕T 33171-2016 城市交通运行状况评价规范

免登陆免积分下载地址 标准号&#xff1a;GB/T 33171-2016 中文标准名称&#xff1a;城市交通运行状况评价规范 英文标准名称&#xff1a;Specification for urban traffic performance evaluation 中国标准分类号&#xff08;CCS&#xff09;R85 国际标准分类号&#xff08;…

python的课后练习总结3(字典)

1&#xff0c;创建空字典 空字典的创建 名字 { } 1&#xff0c;字典的查 变量名 {星期一:上课,星期二:休息,星期三:吃晚饭} print(变量名[星期一]) &#xff08;1&#xff09;get( ) 语法&#xff1a; 字典序列名.get(键&#xff0c;随便写) 如果键存在&#xff0c;返回值…

CTFHub | 存储型

0x00 前言 CTFHub 专注网络安全、信息安全、白帽子技术的在线学习&#xff0c;实训平台。提供优质的赛事及学习服务&#xff0c;拥有完善的题目环境及配套 writeup &#xff0c;降低 CTF 学习入门门槛&#xff0c;快速帮助选手成长&#xff0c;跟随主流比赛潮流。 0x01 题目描述…

linux 浅练一下哈

1.新建用户test不建家目录不允许登录&#xff0c;uid为10086_____________________ useradd -u 10086 -M -s /sbin/nologin 2.将 /opt 文件夹中所有文件的属主&#xff0c;属组改成&#xff0c;test_______________________ chown -R test.test /opt chown -R …

年度最整洁的海盗3.0版本

在修改海盗3.0客户端源码的时候&#xff0c;一直都存在这样的一个问题&#xff1a; 客户端在某些特定的情况下&#xff0c;会报内存错误导致程序崩溃。 经过调试&#xff0c;发现是那个MindPower3D的dll&#xff0c;在跳转地图等情况下卸载清理内存的时候&#xff0c;会偶发出…

科普:嵌入式多核并行仿真

自信息技术革命以来&#xff0c;计算机一直被应用在各种复杂的数据处理中&#xff0c;如火箭弹道&#xff0c;高能物理和生物学数据等。随着嵌入式领域的多样化需求的不断丰富&#xff0c;多核CPU的应用也越来越广泛&#xff1a;嵌入式系统通常需要同时处理多个任务和实时数据&…

网络调试 UDP1,开发板用静态地址-入门5

https://www.bilibili.com/video/BV1zx411d7eC?p11&vd_source109fb20ee1f39e5212cd7a443a0286c5 1, 开发板连接路由器 1.1&#xff0c;烧录无OS UDP例程 1.2&#xff0c;Mini USB连接电脑 1.3&#xff0c;开发板LAN接口连接路由器 2. Ping开发板与电脑之间通信* 2.1 根据…

自动化测试流程(超详细总结)

今天就通过这篇文章给大家深度解析一下自动化测试的流程。 自动化测试的流程和功能测试其实挺相似的&#xff0c;整个流程也是按照需求分析及测试计划阶段、测试设计阶段、测试执行和测试总结阶段&#xff0c;总结下来就是下面一张图&#xff0c;ppt中纯手绘&#xff0c;效果不…