使用 Vue_ElementUI_Echarts_Typescript 实现饼图统计【最新教程】

element 绘制饼状图(复制代码直接用),付效果图 先上代码 (复制代码直接使用) <template> <div class="home-index-box"> <!--饼状图and环形图--> <div class="graph-pie-warp"> <el-row :gutter="30"> <el-col :span="12"> <div id="home_gathering_source" style="height: 30 阅读详情

效果预览

在这里插入图片描述

组件调用示例:

<el-row class="block-margin--top" :gutter="20">
  <el-col :span="9">
    <div class="col-block col-block--card" style="height: 300px">
      <div class="col-block__title">告警类型分布</div>
      <div class="col-block__content col-block__content--full">
        <PieEcharts height="100%" :center-pie="['25%', '50%']" label-type="center" label-method="grossValue" :chartData="chartData"></PieEcharts>
      </div>
    </div>
  </el-col>
</el-row>

组件示例数据:

/** 饼图数据示例 */
private chartData = [
  {value: 22600, name: '侦察', suffix: '2.26万次 (7.05%)'},
  {value: 10400, name: '可疑', suffix: '1.04万次 (7.05%)'},
  {value: 43200, name: '拒绝服务', suffix: '2.26万次 (7.05%)'},
  {value: 5567, name: '恶意文件', suffix: '5567次 (7.05%)'},
  {value: 6918, name: 'WEB攻击', suffix: '6918次 (7.05%)'},
  {value: 6918, name: '远程控制', suffix: '2.26万次 (7.05%)'},
  {value: 6918, name: '恶意利用', suffix: '2.26万次 (7.05%)'},
  {value: 6918, name: 'APT攻击', suffix: '2.26万次 (7.05%)'},
  {value: 6918, name: '自定义威胁', suffix: '5401次 (7.05%)'},
]

具体代码实现:

Template 代码

<template>
  <div :style="{ height: height, width: width }">
    <div v-show="!showEmpty" v-loading="loading" :class="className" ref="myChart" :style="{ height: height, width: width }"></div>
    <el-empty v-show="showEmpty" style="padding: 0;height: calc(100% - 40px);" :description="emptyDesc" :image-size="100"></el-empty>
  </div>
</template>

Script 代码

<script lang="ts">
import Vue from 'vue';
import * as echarts from 'echarts/core';
import {Component, Emit, Prop, Watch} from 'vue-property-decorator';
import {common} from '@/utils/common';
import {nextTick} from 'vue/types/umd';
import {NdrModule} from '@/store/modules/Ndr';

@Component({})
export default class PieEcharts extends Vue {
  // 图表数据
  @Prop({
    default: () => {
    }
  }) readonly chartData?: any;
  // 图表样式名称
  @Prop({default: 'class-name'}) readonly className?: String;
  // 图表颜色
  @Prop({default: () => ['#3761ee', '#ff905d', '#f94565', '#e7bcf3', '#aa6dfe', '#8378ea', '#1c9dff', '#31c5e9', '#90c577']})
  readonly color?: any;
  // 图表内外半径
  @Prop({default: () => ['50%', '70%']}) readonly radius?: any;
  // 图表位置
  @Prop({default: () => ['36%', '50%']}) readonly centerPie?: any;
  // 图表宽
  @Prop({default: '100%'}) readonly width?: any;
  // 图表高
  @Prop({default: '80%'}) readonly height?: any;
  // 图表标题
  @Prop({default: '数据图表'}) readonly name?: any;
  // 右边子栏是否显示
  @Prop({default: true}) readonly legendShow?: any;
  // 右边子栏是否能点击
  @Prop({default: true}) readonly electedModeShow?: any;
  // 右边子栏位置
  @Prop({default: 'center'}) readonly legendTop?: any;
  // label描述显示位置 显示类型1.outside 2.
  @Prop({default: 'outside'}) readonly labelType?: any;
  // label描述是否显示
  @Prop({default: true}) readonly labelShow?: any;
  // label鼠标移入是否显示信息
  @Prop({default: true}) readonly emphasisEabelShow?: any;
  // label描述的几种显示形式
  @Prop({default: 'default'}) readonly labelMethod?: any;
  // 整体图表类型 类型1 default  //类型2progress
  @Prop({default: 'default'}) readonly typePie?: any;
  // 最小的扇区角度(0 ~ 360),用于防止某个值过小导致扇区太小影响交互
  @Prop({default: 0}) readonly minAngle?: any;
  // 是否显示组件自动计算的占比
  @Prop({default: false}) readonly tipsAppendAutoPercent?: any;
  // 是否显示数量单位
  @Prop({default: ''}) readonly tipsAppendAutoUnit?: string
  // 是否显示悬浮信息
  @Prop({default: true}) readonly showTooltip?: boolean
  /** Loading */
  protected loading: any = false;
  /** 图表是否显示暂无数据 */
  protected showEmpty = false
  /** 中间状态的描述文字 */
  protected emptyDesc: string = '';
  protected chartInstance: any = null;
  protected options: any = {};

  @Emit('typeClick')
  protected typeClick(data: any) {
    return data;
  }

  /***********************************************************************************************
   * 方法
   * *******************************************************************************************/

  @Watch('chartData')
  onChartDataChanged(newVal: any, oldVal: any) {
    this.showEmpty = Object.keys(this.chartData).length == 0
    this.initChart()
  }

  @Watch('loading')
  protected loadingChange(val: any) {
    this.loading = val;
    this.emptyDesc = val ? '数据加载中' : '暂无数据';
  }

  //初始化图标
  private initChart = () => {
    this.options = {
      color: this.color,
      tooltip: {
        show: this.showTooltip,
        formatter: (params: any) => {
          let ext = '';
          let unit = '';
          if (params.data.unit) {
            unit += params.data.unit;
          }
          if (this.tipsAppendAutoPercent) {
            ext += ` (${params.percent}%)`;
          }
          if (this.tipsAppendAutoUnit) {
            unit += this.tipsAppendAutoUnit;
          }
          let returnData = `
          <div style="padding: 5px 10px;">
            <span style="display:inline-block; width:10px; height:10px; margin-right:5px; border-radius:10px; background-color:${
              params.color
          }"></span>
            <span style="color:${params.color}">${params.name}</span>
            <span style="color:${params.color}">${common.FormatNumberUnit(params.data.value)}${unit}${ext}</span>
          </div>`;
          this.$emit('changeData', params);
          return returnData;
        }
      },
      legend: {
        right: '0%',
        top: this.legendTop,
        orient: '',
        show: this.legendShow,
        selectedMode: this.electedModeShow,
        formatter: (params: any) => {
          let newChartData = this.chartData.map((item: any) => ({name: item.name, suffix: item.suffix}));
          let name = '';
          for (let i = 0; i < newChartData.length; i++) {
            if (newChartData[i].suffix && newChartData[i].name == params) {
              return params + '——' + newChartData[i].suffix;
            } else {
              name = params;
            }
          }
          return params;
        }
      },
      series: [
        {
          name: this.name,
          type: 'pie',
          minAngle: this.minAngle,//最小角度
          radius: this.radius,
          center: this.centerPie,
          avoidLabelOverlap: true,
          labelLine: {
            show: this.labelShow,
            length: 10,
            length2: 15
          },
          label: {
            show: this.labelShow,
            position: this.labelType,
            formatter: (params: any) => {
              let newChartData = this.chartData.map((item: any) => ({
                value: item.value,
                name: item.name,
                suffix: item.suffix
              }));
              let num = 0;
              let ext = '';
              if (params.data.ext) {
                ext += params.data.ext;
              }
              for (let i in newChartData) {
                num += parseInt(newChartData[i].value);
              }
              let title = this.labelType === 'center' ? 'b' : 'c';
              let context = this.labelType === 'center' ? 'a' : 'd';
              // 固定总值显示,正常显示,自我后缀显示
              if (this.labelMethod == 'grossValue') {
                return `{${title}|${common.FormatNumberUnit(num)}}\n{${context}|总数}`;
              } else if (this.labelMethod == 'percent') {
                return `{${title}|${params.data.percent} %}`;
              } else if (this.labelMethod == 'default') {
                return `{${title}|${params.data.name}}\n{${context}|${common.FormatNumberUnit(params.data.value)}${ext}(${params.data.percent})}`;
              }
            },
            rich: {
              a: {
                color: '#666',
                lineHeight: 10
              },
              b: {
                fontSize: 20,
                fontWeight: 700,
                color: '#333',
                display: 'block',
                lineHeight: 20
              },
              c: {
                fontSize: 14,
                fontWeight: 700,
                color: '#333',
                display: 'block',
                lineHeight: 20
              },
              d: {
                fontSize: 12,
                fontWeight: 500,
                color: '#333',
                display: 'block',
                lineHeight: 12
              }
            }
          },
          emphasis: {
            label: {
              show: this.emphasisEabelShow,
              fontSize: '10',
              fontWeight: 'bold'
            }
          },
          z: 2,
          data: this.chartData
        }
      ]
    }
    let that = this;
    if (this.$refs.myChart) {
      this.chartInstance = echarts.init(<any>this.$refs.myChart);
    }
    this.chartInstance.setOption(this.options);
    that.chartInstance.on('click', function (params: any) {
      let typeData: any = params.data;
      if (typeData) {
        that.$emit('typeClick', typeData);
      }
    });
  };

  //更改图标样式
  private updateCharts = () => {
    if (this.typePie == 'progress') {
      let round = <any>{
        type: 'pie',
        radius: this.radius,
        center: this.centerPie,
        hoverAnimation: false,
        animation: false,
        itemStyle: {
          color: '#ff905d'
        },
        z: 0,
        label: {
          show: false
        },
        stillShowZeroSum: true,
        data: [0]
      };
      this.options.series.unshift(round);
    }
    this.initChart();
  };
  private screenAdapter = () => {
    this.initChart();
    this.chartInstance.resize();
  };

  protected async initData() {
    await this.initChart()
    await this.updateCharts();
  }

  async mounted() {
    await this.initData()
    this.showEmpty = Object.keys(this.chartData).length == 0
    window.addEventListener('resize', this.screenAdapter);
  }
}
</script>

SCSS 代码

.col-block {
  padding: 15px 25px;
  border-radius: 15px;
  overflow: hidden;
  &--inner-padding {
    padding: 15px 20px;
  }
  &.normal-gray-border {
    border: 1px solid $gray-dash-border-color;
    //box-shadow: none;
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.03);
  }

  &--card {
    background-color: #fff;
    box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1);
    .text-hover {
      cursor: pointer;
      &:hover {
        color: $blue-color;
      }
    }
  }

  &--no-padding {
    padding: 0;
    border-radius: 0;
  }

  &__title {
    margin-bottom: 5px;
    align-items: center;
    font-size: 16px;
    font-weight: bolder;
    display: flex;
    justify-content: space-between;
    &--normal-font {
      font-weight: normal;
    }
  }

  &__content {
    height: fit-content;
    margin-bottom: 5px;

    &--full {
      height: calc(100% - 10px);
    }

    &--full-b20 {
      height: calc(100% - 20px);
    }

    &--full-b30 {
      height: calc(100% - 30px);
    }

    &--left {
      float: left;

    }

    &--right {
      float: right;
    }

    &--between {
      display: flex;
      justify-content: space-between;
    }

    &__text {
      line-height: 55px;
      width: calc(100% - 55px);
      overflow: hidden;
      height: 55px;

      &__append-text {
        margin-left: 5px;
      }
    }

    &__icon {
      height: 55px;
      width: 55px;
      &--align-center {
        align-self: center;
      }
    }
  }

  &__content--pie-center {
    height: 100%; position: relative;
    .pie-center-title {
      position: absolute; text-align: center; top: 20px; width: 100%; z-index: 99;
      .big-font-count {
        font-size: 18px;
        font-weight: bold;
      }
    }
  }

  &__footer {
    margin-top: 10px;
    display: flex;
    justify-content: space-between;

    span {
      &:first-child {
        //margin-right: 15%;
      }

      display: inline-block;
    }
  }
}

总结:

至此,我们的组件编码就已经完成了,小伙伴们可以尝试着跑起来了。

本专栏会定期更新 Vue_ElementUI_Echarts_Typescript 有关的实例教程,希望感兴趣的小伙伴们多多关注~ 有问题在评论区留言吧~ 谢谢

SpringBoot+Vue仓库管理系统设计与实现 仓储管理系统(WMS)作为企业供应链管理的核心系统,通过信息化手段实现商品流转全流程跟踪。基于SpringBoot和Vue.js的现代化技术架构,系统采用前后端分离设计,整合MyBatis、Redis等技术组件,重点解决高并发库存扣减、复杂报表性能优化等工程难题。在业务层面实现了采购入库、销售出库、库存调拨的闭环管理,技术层面运用乐观锁、Lua脚本确保数据一致性。这类系统广泛应用于零售、电商、制造业等领域,特别适合作为计算机专业毕业设计项目,既能掌握主流技术栈,又能深入理解企业级应用开发要点。项目中采用的R 阅读详情

相关推荐

SpringBoot+Vue构建大学生就业招聘系统实战

现代Web开发中,前后端分离架构已成为主流技术方案。SpringBoot作为Java生态的微服务框架,通过自动配置和起步依赖简化后端开发;Vue.js则以其响应式特性和组件化设计提升前端开发效率。这种技术组合特别适合构建企业级应用,如招聘管理系统。系统采用MyBatis-Plus实现高效数据访问,结合ElementUI组件库快速搭建管理界面。关键技术点包括基于TF-IDF算法的智能职位推荐、分片上传实现大文件处理,以及通过全文索引优化简历搜索性能。这类系统在高校计算机专业毕业设计中具有典型性,涉及用户认证、

weixin_34161032的博客 687

使用 Vue_ElementUI_Echarts_Typescript 实现漂亮的带进度条的TOP统计图【最新教程】

简介:本文会教你如何使用 Vue_ElementUI_Echarts_Typescript 实现漂亮的带进度条的TOP统计图。

天河书阁 - VicRestart 2820

Vue-Element UI集成ECharts实现数据统计分析页代码部分(如果帮助到你,感谢关注点赞)

关于《Vue-Element UI集成ECharts实现数据统计分析页》文章的具体代码实现。(如果帮助到你,感谢关注点赞)

DMA 定制固件教程:小白跟做即得单人固件,超详细纯喂饭教程,100% 成功秘籍!FPGA仿真1:1、中断逻辑和TLP核心都在。

DMA 定制固件教程 小白跟着操作做可以做出的单人固件。DMA仿真技术io、中断逻辑,从零仿真。图文链接教程:https://docs.qq.com/doc/DQ01lVGtHelROVHNv

qq_15741349的博客 3万+

WRF后处理总结:wrf-python与NCL在WRF后处理中的基本应用——变量提取、计算与可视化

判断需要提取的变量与诊断量确定后,使用getvar函数进行提取。可使用ncdump-h命令查看wrfout中的变量,wrf中的诊断量分类也可从官方文档处查阅。判断绘图类型所需的可视化绘图类型,决定了你在WRF后处理中的计算步骤。1D点线图:ll_to_xy interpline2D填色图:interplevel3D剖面图:vinterp vertcross绘图、美化色标、XY轴、标签的设置等等。

weixin_43750300的博客 1万+

C# 原生数字孪生的尝试

本文介绍了使用C#实现数字孪生的基本思路。首先从爱普生官网下载机器人3D模型,然后通过Blender创建并导出带动画的FBX模型。在WPF项目中,使用HelixToolkit.SharpDX等插件加载模型,通过Viewport3DX进行3D渲染。关键点是通过动画控制器接收真实设备信号来驱动模型动画,实现物理实体与虚拟模型的同步。文中提供了完整的代码实现,包括模型导入、动画播放控制等核心功能。该方法为构建数字孪生系统提供了一种可行的技术方案。

qq_33529095的博客 1333

STM32CUBEMX 使用教程5 — DMA配置 & 串口结合DMA实现数据搬运

DMA(Direct Memory Access),直接存储器访问(或数据搬运),是STM32中很实用的一个外设。DMA 传输数据方式不需要 CPU 参与控制传输,也不用中断处理的方式进行数据搬运处理,纯粹通过硬件为 RAM 与 I/O 设备之间开辟一条直接传送数据的通路,使 CPU 的效率大大提高。

weixin_43866583的博客 1500

从网口变压器到TVS管:手把手设计通过4KV浪涌的以太网电路

本文详细解析工业级以太网接口4KV浪涌防护设计,从网口变压器选型到TVS管布局,提供通过IEC61000-4-5标准测试的完整方案。重点介绍Bob Smith电路优化和PCB设计技巧,帮助工程师有效应对雷电感应和设备开关瞬态干扰,确保工业设备稳定运行。

study的专栏 286

基于Python的专利数据爬虫开发指南:从入门到实战

本文将详细介绍如何使用Python开发一个高效的专利数据爬虫系统,涵盖最新技术栈如Playwright、异步IO、反反爬策略等。文章包含完整代码实现、性能优化技巧及法律合规建议,帮助读者构建可投入生产的专利数据采集解决方案。专利数据是技术创新的重要指标,包含技术细节、申请人信息、法律状态等宝贵信息。企业竞争情报分析技术趋势预测研发方向决策知识产权战略制定。

2201_76125261的博客 1588

YOLOv13改进策略【小目标改进】| Shape-NWD:融合改进,结合Shape-IoU和NWD 更好地适应小目标特性

Bw−wgt2h−hgt2weight2Bweight2w−wgt​2h−hgt​2​其中weight2weight = 2weight2。

Limiiiing的博客 588

Qt Installer Framework 简单使用

qt installer framework 简单使用

qq_42815643的博客 2576

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

上一篇: 信息系统项目管理师教程(第4版) - 什么是立项管理文件?
下一篇: javascript 引用类型参数须知
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天河书阁 VicRestart

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值