封装echarts组件,即插即用(附源码)

news2024/11/25 16:22:20

前言:最近一个项目刚收工,分享一个常用的封装echarts的组件。

一、直接上组件代码

<template>
  <el-card class="echart-card" shadow="hover">
    <template v-slot:header>
      <div class="card-header">
        <div class="card-header-title">
          <component
            class="icon"
            :is="headerIcon"
            theme="filled"
            size="16"
            :strokeWidth="3"
            fill="#333"
          />
          <span :class="titleStyle === 'small' ? 'title' : 'titleBig'" style="fontWeight:'bold">{{
            title
          }}</span>
        </div>
        <div class="card-header-right">
          <slot name="header-right"></slot>
        </div>
      </div>
    </template>
    <div class="echarts" ref="chartContainer" :id="`echarts${index}`" :style="style"></div>
  </el-card>
</template>
<script setup>
import debounce from "lodash/debounce";
import {
  onMounted,
  ref,
  reactive,
  computed,
  watch,
  onBeforeUnmount,
  nextTick,
} from "vue";
// import { useStore } from 'vuex';
// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
import * as echarts from "echarts/core";
import { GraphicComponent } from "echarts/components";
// 引入柱状图图表,图表后缀都为 Chart
import theme from "./theme.json";
import {
  BarChart,
  CandlestickChart,
  FunnelChart,
  GaugeChart,
  LineChart,
  PieChart,
  RadarChart,
  ScatterChart,
  GraphChart,
  LinesChart,
  TreemapChart
} from "echarts/charts";
// 引入提示框,标题,直角坐标系组件,组件后缀都为 Component
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  ToolboxComponent,
  MarkPointComponent,
  MarkLineComponent,
} from "echarts/components";
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import { CanvasRenderer } from "echarts/renderers";

// 注册必须的组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  BarChart,
  LineChart,
  PieChart,
  RadarChart,
  GaugeChart,
  CandlestickChart,
  ScatterChart,
  CanvasRenderer,
  LegendComponent,
  ToolboxComponent,
  MarkPointComponent,
  MarkLineComponent,
  FunnelChart,
  GraphicComponent,
  GraphChart,
  LinesChart,
  TreemapChart
]);

const props = defineProps({
  // 图表下标 同个页面有多个图表时,必填
  index: {
    type: Number,
    default: 0,
  },
  title: {
    type: String,
    default: "标题",
  },
  headerIcon: {
    type: String,
    default: "icon-full-screen",
  },
  style: {
    type: Object,
    default: () => {
      return {
        width: "100%",
        height: "380px",
      };
    },
  },
  options: {
    type: Object,
    default: () => {
      return {};
    },
  },
  grid: {
    type: Object,
    default: () => {
      return {
        top: "10px",
        left: 0,
        right: "1px",
        bottom: 0,
        containLabel: true,
      };
    },
  },
  titleStyle: {
    type: String,
    default: "small",
  },
});

let chart = null;
const chartContainer =ref(null)
let timer = ref(null);
//组件挂载完成后执行的钩子函数
onMounted(() => {
  window.addEventListener(
    "resize",
    debounce(() => {
      chart.resize(); //页面大小变化后Echarts也更改大小
    }, 200)
  );
});
//组件卸载之前执行的钩子函数
onBeforeUnmount(() => {
  clearTimeout(timer);
  timer = null;
});
const initChart = () => {
  if(chartContainer.value){
    if(chart){
      chart.dispose()
    }
     echarts.registerTheme("wonderland", theme);
  // chart = echarts.init(document.getElementById("echarts" + props.index), theme);
  chart = echarts.init(chartContainer.value, theme);
  // 绘制图表
  chart.setOption({
    grid: props.grid,
    ...props.options,
  });
  }
 
  
};

watch(
  () => props.options, //监听
  () => {
    nextTick(() => {
      initChart();
    });
  },
  {
    deep: true,
    immediate: true,
  }
);
</script>
<style lang="scss" scoped>
.echart-card {
  border-radius: 10px;
  .card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;

    &-title {
      display: flex;
      align-content: center;
      align-items: center;
      color: #606266;

      .icon {
        display: flex;
        padding-right: 5px;
      }
    }
  }

  .echarts {
    margin: 0 auto;
    background-color: #928f8f;
  }
}
</style>

二、theme.json统一风格

{
  "color": ["#007FC6", "#00A0F9", "#2BC7E2", "#EA7C13", "#FFB56E", "#FFE8D1"],
  "backgroundColor": "rgba(255,255,255,0)",
  "textStyle": {},
  "title": {
    "textStyle": {
      "color": "#666666"
    },
    "subtextStyle": {
      "color": "#999999"
    }
  },
  "line": {
    "itemStyle": {
      "borderWidth": "2"
    },
    "lineStyle": {
      "width": "3"
    },
    "symbolSize": "8",
    "symbol": "emptyCircle",
    "smooth": false
  },
  "radar": {
    "itemStyle": {
      "borderWidth": "2"
    },
    "lineStyle": {
      "width": "3"
    },
    "symbolSize": "8",
    "symbol": "emptyCircle",
    "smooth": false
  },
  "bar": {
    "itemStyle": {
      "barBorderWidth": 0,
      "barBorderColor": "#cccccc"
    }
  },
  "pie": {
    "itemStyle": {
      "borderWidth": 0,
      "borderColor": "#cccccc"
    }
  },
  "scatter": {
    "itemStyle": {
      "borderWidth": 0,
      "borderColor": "#cccccc"
    }
  },
  "boxplot": {
    "itemStyle": {
      "borderWidth": 0,
      "borderColor": "#cccccc"
    }
  },
  "parallel": {
    "itemStyle": {
      "borderWidth": 0,
      "borderColor": "#cccccc"
    }
  },
  "sankey": {
    "itemStyle": {
      "borderWidth": 0,
      "borderColor": "#cccccc"
    }
  },
  "funnel": {
    "itemStyle": {
      "borderWidth": 0,
      "borderColor": "#cccccc"
    }
  },
  "gauge": {
    "itemStyle": {
      "borderWidth": 0,
      "borderColor": "#cccccc"
    }
  },
  "candlestick": {
    "itemStyle": {
      "color": "#84a2fe",
      "color0": "transparent",
      "borderColor": "#84a2fe",
      "borderColor0": "#22c3aa",
      "borderWidth": "1"
    }
  },
  "graph": {
    "itemStyle": {
      "borderWidth": 0,
      "borderColor": "#cccccc"
    },
    "lineStyle": {
      "width": "1",
      "color": "#cccccc"
    },
    "symbolSize": "8",
    "symbol": "emptyCircle",
    "smooth": false,
    "color": ["#84a2fe", "#22c3aa", "#7bd9a5", "#d0648a", "#08a17e", "#f2b3c9"],
    "label": {
      "color": "#ffffff"
    }
  },
  "map": {
    "itemStyle": {
      "areaColor": "#eeeeee",
      "borderColor": "#999999",
      "borderWidth": 0.5
    },
    "label": {
      "color": "#28544e"
    },
    "emphasis": {
      "itemStyle": {
        "areaColor": "rgba(34,195,170,0.25)",
        "borderColor": "#22c3aa",
        "borderWidth": 1
      },
      "label": {
        "color": "#349e8e"
      }
    }
  },
  "geo": {
    "itemStyle": {
      "areaColor": "#eeeeee",
      "borderColor": "#999999",
      "borderWidth": 0.5
    },
    "label": {
      "color": "#28544e"
    },
    "emphasis": {
      "itemStyle": {
        "areaColor": "rgba(34,195,170,0.25)",
        "borderColor": "#22c3aa",
        "borderWidth": 1
      },
      "label": {
        "color": "#349e8e"
      }
    }
  },
  "categoryAxis": {
    "axisLine": {
      "show": true,
      "lineStyle": {
        "color": "#cccccc"
      }
    },
    "axisTick": {
      "show": false,
      "lineStyle": {
        "color": "#333"
      }
    },
    "axisLabel": {
      "show": true,
      "color": "#999999"
    },
    "splitLine": {
      "show": true,
      "lineStyle": {
        "color": ["#eeeeee"]
      }
    },
    "splitArea": {
      "show": false,
      "areaStyle": {
        "color": ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"]
      }
    }
  },
  "valueAxis": {
    "axisLine": {
      "show": true,
      "lineStyle": {
        "color": "#cccccc"
      }
    },
    "axisTick": {
      "show": false,
      "lineStyle": {
        "color": "#333"
      }
    },
    "axisLabel": {
      "show": true,
      "color": "#999999"
    },
    "splitLine": {
      "show": true,
      "lineStyle": {
        "color": ["#eeeeee"]
      }
    },
    "splitArea": {
      "show": false,
      "areaStyle": {
        "color": ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"]
      }
    }
  },
  "logAxis": {
    "axisLine": {
      "show": true,
      "lineStyle": {
        "color": "#cccccc"
      }
    },
    "axisTick": {
      "show": false,
      "lineStyle": {
        "color": "#333"
      }
    },
    "axisLabel": {
      "show": true,
      "color": "#999999"
    },
    "splitLine": {
      "show": true,
      "lineStyle": {
        "color": ["#eeeeee"]
      }
    },
    "splitArea": {
      "show": false,
      "areaStyle": {
        "color": ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"]
      }
    }
  },
  "timeAxis": {
    "axisLine": {
      "show": true,
      "lineStyle": {
        "color": "#cccccc"
      }
    },
    "axisTick": {
      "show": false,
      "lineStyle": {
        "color": "#333"
      }
    },
    "axisLabel": {
      "show": true,
      "color": "#999999"
    },
    "splitLine": {
      "show": true,
      "lineStyle": {
        "color": ["#eeeeee"]
      }
    },
    "splitArea": {
      "show": false,
      "areaStyle": {
        "color": ["rgba(250,250,250,0.05)", "rgba(200,200,200,0.02)"]
      }
    }
  },
  "toolbox": {
    "iconStyle": {
      "borderColor": "#999999"
    },
    "emphasis": {
      "iconStyle": {
        "borderColor": "#666666"
      }
    }
  },
  "legend": {
    "textStyle": {
      "color": "#999999"
    }
  },
  "tooltip": {
    "axisPointer": {
      "lineStyle": {
        "color": "#cccccc",
        "width": 1
      },
      "crossStyle": {
        "color": "#cccccc",
        "width": 1
      }
    }
  },
  "timeline": {
    "lineStyle": {
      "color": "#84a2fe",
      "width": 1
    },
    "itemStyle": {
      "color": "#84a2fe",
      "borderWidth": 1
    },
    "controlStyle": {
      "color": "#84a2fe",
      "borderColor": "#84a2fe",
      "borderWidth": 0.5
    },
    "checkpointStyle": {
      "color": "#84a2fe",
      "borderColor": "#3cebd2"
    },
    "label": {
      "color": "#84a2fe"
    },
    "emphasis": {
      "itemStyle": {
        "color": "#84a2fe"
      },
      "controlStyle": {
        "color": "#84a2fe",
        "borderColor": "#84a2fe",
        "borderWidth": 0.5
      },
      "label": {
        "color": "#84a2fe"
      }
    }
  },
  "visualMap": {
    "color": ["#d0648a", "#22c3aa", "#adfff1"]
  },
  "dataZoom": {
    "backgroundColor": "rgba(255,255,255,0)",
    "dataBackgroundColor": "rgba(222,222,222,1)",
    "fillerColor": "rgba(114,230,212,0.25)",
    "handleColor": "#cccccc",
    "handleSize": "100%",
    "textStyle": {
      "color": "#999999"
    }
  },
  "markPoint": {
    "label": {
      "color": "#ffffff"
    },
    "emphasis": {
      "label": {
        "color": "#ffffff"
      }
    }
  }
}

 可以直接将以上两个代码复制到组件文件夹里面

三、使用该组件

        <EchartsCom
          title="协议流量趋势图"
          :index="11"
          :titleStyle="'big'"
          headerIcon="icon-chart-line"
          :style="{ height: '250px' }"
          :options="{
            tooltip: trendSeries.tooltip,
            series: trendSeries.series,
            xAxis: trendSeries.xAxis,
            yAxis: trendSeries.yAxis,
            grid: trendSeries.grid,
          }"
        ></EchartsCom>

 可以很清楚的看到,其实主要就是传echarts的配置。

配置代码(就以折线图举例):

const trendSeries = ref({
        grid: { top: '15%', bottom: '5%', left: '10%', right: '18%', containLabel: true },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'line',
          },
        },
        series: {
          type: 'line',
          data: [120, 132, 101, 134, 90, 230, 210],
          symbol: 'circle',
          lineStyle: {
            normal: {
              color: '#008FFF',
            },
          },
          symbolSize: 10,

          itemStyle: {
            normal: {
              color: '#fff',
              borderColor: '#008FFF',
            },
            borderRadius: [30, 30, 0, 0],
            shadowColor: 'rgb(255,255,255)',
            shadowBlur: 4,
          },
          smooth: false,
        },
        xAxis: {
          name: '时间',
          type: 'category',
          data: [
            '2024-04-18',
            '2024-04-19',
            '2024-04-20',
            '2024-04-21',
            '2024-04-22',
            '2024-04-23',
            '2024-04-24',
          ],
          splitLine: {
            show: false,
          },
          axisLabel: {
            color: '#002745',
          },
        },
        yAxis: {
          name: '单位(次)',
          type: 'value',
          minInterval: 1,
          splitLine: {
            show: true,
            lineStyle: {
              width: 2,
              type: 'dashed',
            },
          },
          axisLine: {
            show: false,
          },
          axisLabel: {
            show: true,
            formatter(v) {
              v = v.toString();
              if (v >= 100000000000) {
                return v.substring(0, 5) / 10 + '亿';
              } else if (v >= 10000000000) {
                return v.substring(0, 4) / 10 + '亿';
              } else if (v >= 1000000000) {
                return v.substring(0, 3) / 10 + '亿';
              } else if (v >= 100000000) {
                return v.substring(0, 2) / 10 + '亿';
              } else if (v >= 10000000) {
                return v.substring(0, 4) + '万';
              } else if (v >= 1000000) {
                return v.substring(0, 3) + '万';
              } else if (v >= 100000) {
                return v.substring(0, 2) + '万';
              } else if (v >= 10000) {
                return v.substring(0, 2) / 10 + '万';
              } else if (v >= 1000) {
                return v;
              } else {
                return v;
              }
            },
          },
        },
      });

效果展示:

如果想用饼图、柱状图之类的就可以直接传相应的配置即可,这样可以灵活控制每个图的不用样式。

之前我封装过几个组件都是把echarts的配置写进组件里面,但是后面发现如果一个页面需要七八个echarts图表,并且样式都是不一样的,那么就比较适用该文介绍的封装方法。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[网络协议篇] UDP协议

文章目录 1. 简介2. 特点3. UDP数据报结构4. 基于UDP的应用层协议5. UDP安全性问题6. 使用udp传输数据的系统就一定不可靠吗&#xff1f;7. 基于UDP的主机探活 python实现 1. 简介 User Datagram Protocol&#xff0c;用户数据报协议&#xff0c;基于IP协议提供面向无连接的网…

郑州地铁携手百望云,以数电票平台升级打造坚实便民惠民服务能力

随着城市的快速发展&#xff0c;地铁成为很多大城市市民出行的主力工具。为民众出行提供安全、便捷、合规的出行服务&#xff0c;成为相关机构的重点工作。 近日&#xff0c;郑州地铁集团有限公司&#xff08;以下简称“郑州地铁”&#xff09;与百望云达成合作&#xff0c;开…

免杀对抗—特征码修改花指令资源修改加壳保护

前言 今天主要是讲这个特征码定位以及这个花指令&#xff0c;资源修改这个东西其实有点投机取巧啦&#xff0c;至于这个加壳之前也讲过了&#xff0c;直接工具搞就行。那么什么是特征码定位呢&#xff0c;众所周知&#xff0c;杀软是通过特征码来检测我们的exe是否是后门的&am…

老外说“奶茶”不叫“milk tea”?!那叫什么?柯桥英语口语学习生活日语培训

奶茶的英文怎么说&#xff1f; 其实&#xff0c;“奶茶”在英文中有多种表达方式&#xff0c;但最常见且准确的应该是“tea with milk”。这种表达方式直接描述了奶茶的本质——茶与牛奶的结合。当然&#xff0c;你也可以用“milky tea”来表达&#xff0c;但相对来说&#xf…

探索自然之美:SpringBoot驱动的安康旅游网站开发

第一章 绪论 1.1 研究现状 时代的发展&#xff0c;我们迎来了数字化信息时代&#xff0c;它正在渐渐的改变着人们的工作、学习以及娱乐方式。计算机网络&#xff0c;Internet扮演着越来越重要的角色&#xff0c;人们已经离不开网络了&#xff0c;大量的图片、文字、视频冲击着我…

基于SpringBoot的酒店管理系统的设计与实现

摘要 酒店管理系统的设计旨在提供快捷高效的住宿资源管理方案&#xff0c;帮助管理员实现对酒店内房间、客户信息、订单的全方位管理&#xff0c;同时为用户提供便捷的预订和查询功能。本系统基于Spring Boot框架&#xff0c;结合前端框架和数据库设计&#xff0c;构建一个用户…

基于双目立体视觉的图像匹配与测距

基于双目立体视觉的图像匹配与测距 Image-matching-and-ranging-based-on-binocular-stereo-vision 摘要 双目立体视觉是计算机视觉范畴的核心之一&#xff0c;它利用双目相机来获得目标物体的图像&#xff0c;经过物体图像处理之后得到目标物体所在场景环境的三维信息&…

邮件系统改造升级,让办公更智能、更高效!

在当今的商业环境中&#xff0c;电子邮件扮演着至关重要的角色&#xff0c;它是企业沟通的桥梁和信息传递的枢纽。然而&#xff0c;随着企业规模的扩大和业务需求的增长&#xff0c;传统的电子邮件系统可能会变得力不从心&#xff0c;无法满足日益增长的沟通需求。因此&#xf…

【C#】WPF 依赖属性,PasswordBox中的Password属性绑定

1. 关于依赖属性 <TextBox x:Name"sourceTBox" /> <TextBlock x:Name"tb" Text"{Binding Text,ElementNamesourceTBox}" />源对象&#xff1a; TextBox目标对象&#xff1a; TextBlock目标属性&#xff1a; TextBlock -> Text …

多个立方体盒子组成

效果&#xff1a; 知识了解&#xff1a; 在同一水平上&#xff0c;盒子经纬度计算&#xff1a;经度有误差&#xff0c;纬度没有误差 纬度计算&#xff1a;lat50/111320 约等于0.000449 经度计算&#xff1a;lon50/111320*cos(纬度) 约等于0.000519 一个立方体&#xff1a; // 添…

微信小程序性能优化 ==== 合理使用 setData 纯数据字段

目录 1. setData 的流程 2. 数据通信 3. 使用建议 3.1 data 应只包括渲染相关的数据 3.2 控制 setData 的频率 3.3 选择合适的 setData 范围 3.4 setData 应只传发生变化的数据 3.5 控制后台态页面的 setData 纯数据字段 组件数据中的纯数据字段 组件属性中的纯数据…

Hadoop-001-本地虚拟机环境搭建

一、安装VMware 官方下载VMware&#xff1a; https://vmware.mdsoft.top/?bd_vid5754305114651491003 二、下载镜像文件 阿里云镜像仓库&#xff1a; https://mirrors.aliyun.com/centos/ 本文档使用 CentOS-7-x86_64-DVD-1810-7.6.iso 搭建虚拟机 三、搭建虚拟机 1、编辑…

vue3 腾讯地图 InfoWindow 弹框

1、vue项目index.html引入地图js 2、页面使用 <script setup lang"ts"> import { useMapStore } from //store;defineOptions({ name: PageMap }); const emits defineEmits([update:area, update:address, update:latitude, update:longitude]); const prop…

【Java】SpringBoot实现MySQL数据库的增删查改

目录 1. 项目介绍 2. 相关代码 2.1 项目配置 2.2 SQL语句 2.3 数据访问层 2.4 业务逻辑层 2.5 Web表现层 3. 结果展示 4. 源码获取 1. 项目介绍 SpringBoot是一个轻量级框架&#xff0c;简化了Spring应用的开发和配置。相比较SSM框架&#xff0c;极大的简化了SSM中XM…

Android Navigation传递复杂参数(自定义)

打开要添加参数的navigation文件 使用Design视图 点击右侧Arguments的添加("")按钮 根据自定义类所继承的序列化接口选择这两项其中的一个 选择或者在搜索框检索你的类&#xff0c;然后点击OK&#xff0c;回到前一界面点击ADD即可 其他的操作就跟基本类型用法一样了

C++中指针类型、引用类型、值类型

定义&#xff1a; 1. 带 * 的声明&#xff1a;指针类型 声明方式&#xff1a;MyClass* obj; 是一个 指针类型&#xff0c;表示 obj 是一个指针&#xff0c;可以指向 MyClass 类型的对象。 指针特点&#xff1a; 指针存储的是对象的地址&#xff0c;可以为空&#xff08;null…

新的Midjourney就是一个增强版的Photoshop,你现在可以轻松的用它换衣服、换发型了

好久没有聊 Midjourney 了&#xff0c;昨晚他们发布了一项引人注目的新功能&#xff1a;AI 图像编辑&#xff0c;一个基于网页的加强版的 Photoshop 呼之欲出&#xff0c;让我大为震撼&#xff0c;也让用户们赞叹不已。 基于现有图像进行参考&#xff0c;进而生成新的图片&…

谈一谈 Netty 的内存管理 —— 且看 Netty 如何实现 Java 版的 Jemalloc

本文基于 Netty 4.1.112.Final 版本进行讨论 在之前的 Netty 系列中&#xff0c;笔者是以 4.1.56.Final 版本为基础和大家讨论的&#xff0c;那么从本文开始&#xff0c;笔者将用最新版本 4.1.112.Final 对 Netty 的相关设计展开解析&#xff0c;之所以这么做的原因是 Netty 的…

学习--四元数介绍

2022年的草稿箱里的一篇 四元数由William Rowan Hamilton发现 定义与复数类似&#xff0c;有三个虚部 q a b i c j d k qabicjdk qabicjdk 其中 i 2 j 2 k 2 i j k − 1 i^2j^2k^2ijk-1 i2j2k2ijk−1 四元数的模长&#xff1a; 四维的长度 加减法&#xff1a; 对应分…

十年编程路,一生踏征途

时光荏苒流逝&#xff0c;白驹匆匆过隙&#xff0c;不知不觉间&#xff0c;我已经在程序开发这条道路上走过了整整十年。从最初的求学&#xff0c;到如今成为一名较为资深的职业开发者&#xff0c;这一路充满了挑战、学习、成长与感动。在这1024程序员节的特殊时刻&#xff0c;…