Vue 封装echarts饼状图(Pie)组件

news2024/9/23 13:16:29

目的:减少重复代码,便于维护

效果显示:

组件代码

<template>
    <div class="ldw-data-content-box">
        <div class="ldw-chilren-box">
            <div class="title">
                <div>{{ title }}</div>
                <div class="btn">
                    <slot></slot>
                </div>
            </div>
            <div v-if="row" class="ldw-row-class">
                <div class="canvas-box">
                    <div :id="'canvas-box'+number" style="width: 100%;height:100%;"></div>
                </div>
                <div class="quan-quan-box" style="justify-content: space-evenly;">
                    <div class="ldw-quan-quan" style="width:100%;" v-for="(item,index) in data" :key="index">
                        <div class="ldw-quan-box" :style="{background:item.ldwColor.length?`linear-gradient(0deg,${item.ldwColor[0]},${item.ldwColor[1]})`:''}"></div>
                        <div class="ldw-text-text ldw-w" :style="'width:'+item.w+'px'">{{item.name}}</div>
                        <div>:</div>
                        <div>{{ item.value }}</div>
                    </div>
                </div>
            </div>
            <div style="width:100%;flex:1;display: flex;flex-flow: column;" v-else>
                <div style="width:100%;flex:1;">
                    <div :id="'canvas-box'+number" style="width: 100%;height:100%;"></div>
                </div>
                <div :style="{'height':h+'px','marginTop':top+'px','margin':'0 auto'}" :class="column?'flex-column':'flex-center-sp flex flex-center-cz flex-col'">
                    <div class="ldw-quan-quan" :class="column?'flex-center-sp':''" v-for="(item,index) in data" :key="index">
                        <div class="ldw-quan-box" :style="{background:item.ldwColor.length?`linear-gradient(0deg,${item.ldwColor[0]},${item.ldwColor[1]})`:''}"></div>
                        <div v-if="column">{{item.name}}</div>
                        <div v-else class="ldw-text-text ldw-w" :style="'width:'+item.w+'px'">{{item.name}}</div>
                        <div>:</div>
                        <div>{{ item.value }}</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
var echarts = require("echarts");
const total = function(data){
    return data.reduce((prev,cur)=>{
        return prev+cur.value
    },0)
}
export default {
    props:{
        title:"",
        data:{
            require:true,
            type:Array,
            default:()=>[]
        },
        w:{
            type:String,
            default:"auto"
        },
        column:{
            type:Boolean,
            default:true
        },
        row:{
            type:Boolean,
            default:false
        },
        listH:{
            type:Number,
            default:56
        },
        label:{
            type:Boolean,
            default:false
        }
    },
    data(){
        return{
            bg:["#0090FF","#31CFB8","#E55240"],
            number:null,
            top:0,
            h:56,
            myChart:null
        }
    },
    watch: {
        data: {
            //深度监听,可监听到对象、数组的变化
            handler(val, oldVal) {
                if (val != null) {
                    this.setOption();
                }
                
            },
            deep: true, //true 深度监听
        },
        listH:{
            //深度监听,可监听到对象、数组的变化
            handler(val, oldVal) {
                this.h  = val
            },
        }
    },
    created(){
        this.h = this.listH
        this.number = Math.random(1000)+1;
    },
    mounted(){
        this.initData()
    },
    methods:{
        initData(){
            let canvas = document.getElementById(`canvas-box${this.number}`)
            this.myChart = echarts.init(canvas);
            this.setClick()
            this.setOption()
        },
        setClick(){
            let that = this
            this.myChart.on("click", function(params) {
                that.$emit('eClick',params)
            });
        },
        setOption(){
            let option = {
                title: {
                    text:'总计',//主标题文本
                    subtext:""+total(this.data),//副标题文本
                    left:'center',
                    top:'40%',
                    textStyle:{
                        fontSize: 16,
                        color:'#6c7a89',
                        align:'center'
                    },
                    subtextStyle:{
                        fontFamily : "微软雅黑",
                        fontSize: 26,
                        color:'#060606',
                        fontWeight:600
                    }
                },
                tooltip: {
                    trigger: 'item'
                },
                legend: {
                    show:false
                },
                series: [
                    {
                        name:this.title,
                        type: 'pie',
                        radius: ['55%', '80%'],
                        avoidLabelOverlap: false,
                        label: this.labelFn(this.label),
                        labelLine: this.labelLineFn(this.label),
                        data: this.colorFormat(this.data)
                    }
                ]
            };

            this.myChart.setOption(option)
        },
        resize(){
            this.myChart.resize()
        },
        labelColor(){
            arr.forEach((item)=>{
                if(item.ldwColor){
                    item.itemStyle = {
                        color:{
                        }
                    }
                }
            })
            return arr
        },
        colorFormat(arr){
            arr.forEach((item)=>{
                if(item.ldwColor){
                    item.itemStyle = {
                        color:{
                            type: 'linear',
                            x: 0,
                            y: 0,
                            x2: 0,
                            y2: 1,
                            colorStops: [{
                                offset: 0, color: item.ldwColor[0] // 0% 处的颜色
                            }, {
                                offset: 1, color: item.ldwColor[1] // 100% 处的颜色
                            }],
                            global: false // 缺省为 false
                        }
                    }
                }
            })
            return arr
        },
        labelFn(state){
            if(state){
                return {
                    color: 'inherit',
                    fontWeight:"bold",
                    fontSize:12,
                    padding:[0,-60],
                    formatter:(params)=>{
                        return `${params.name}\n${(params.value/total(this.data)*100).toFixed(1)}%\n\n`
                    }
                }
            }else{
                return {
                    show:false
                }
            }
        },
        labelLineFn(state){
            if(state){
                return {
                    smooth: 0.2,
                    length: 10,
                    length2: 70
                }
            }else{
                return {
                    show:false
                }
            }
        }
    }
}
</script>

<style scoped>
.ldw-data-content-box{
    width:100%;
    height:100%;
    display: flex;
}

.ldw-data-content-box>.ldw-chilren-box{
    width:100%;
    height:100%;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-flow: column;
    overflow: hidden;
}
.ldw-data-content-box>.ldw-chilren-box>.title{
    font-size: 18px;
    color:#000;
    text-align: center;
    padding:24px 0;
    width:100%;
    position: relative;
}

.ldw-bg-box{
    background: rgba(255,255,255,0.5);
    border: 1px solid #F4FDFE;
    border-radius: 20px;
}

.ldw-text-text{
	display: inline-block;
	text-align: justify;
	line-height: 0;
	margin-left: 20px;
}

.ldw-text-text::after{
	content:"";
	display: inline-block;
	width:100%;
	overflow:hidden;
	height:0;
}

.ldw-quan-quan{
    width:100%;
    display: flex;
    align-items: center;
}

.ldw-w{
    margin-top:6px;
    position: relative;
}

.ldw-quan-box{
    width: 13px;
    height: 13px;
    border-radius: 2px;
    margin-right: 20px;
}

.flex-column{
    width:100%;
    display: flex;
    justify-content: space-around;
}

.flex-column .ldw-w{
    width: auto;
}

.flex-column .ldw-quan-box{
    margin-right: 10px;
}

.btn{
    position: absolute;
    right: 50px;
    top:50%;
    transform: translateY(-50%);
}

.ldw-row-class{
    display: flex;
    width: 100%;
    justify-content: center;
    align-items: center;
    flex: 1;
    padding:0 20px;
}

.canvas-box{
    text-align: center;
    width:65%;
    height: 100%;
}

.quan-quan-box{
    width:35%;
    height: 100%;
    display: flex;
    flex-flow: column;
    justify-content: center;
    align-items: center;
}

.m-m-m{
    margin: 0 auto;
}
</style>

调用代码

<template>
    <div class="root flex flex-col border-box">
        <div  style="width: 400px; height: 400px;"  >
            <Pie  :title="'统计'"  :data="list" ></Pie>
        </div>
    </div>
</template>

<script>
    import Pie from '@/components/echarts/pieInfo.vue'

    export default{
        name:'',
        created() {
        },
        mounted() {
            this.list = this.chartData
        },
        components: {Pie},
        data() {
            return {
                list:[],
                chartData:
                [
                    {value:100, type:'一季度'},
                    {value:105, type:'二季度'},
                    {value:201, type:'三季度'},
                    {value:167, type:'四季度'},
                ]
            }
        },
        methods:{
        }
    }
</script>

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

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

相关文章

JavaScript进阶(事件+获取元素+操作元素)

目录 事件基础 事件组成 执行事件的步骤 获取元素 根据ID获取元素 根据标签名获取元素 获取ol中的小li 类选择器&#xff08;html5新增的I9以上支持&#xff09; 获取body和html 操作元素 innerText和innerHtml 表单标签 样式属性操作 操作元素总结 事件基础 事…

【C++】STL 容器 - list 双向链表容器 ① ( 容器特点 | 容器操作时间复杂度 | 构造函数 )

文章目录 一、 list 双向链表容器简介1、容器特点2、容器操作时间复杂度3、遍历访问5、头文件 二、 list 双向链表容器 构造函数1、默认无参构造函数2、创建包含 n 个相同元素的 list 双向链表3、使用初始化列表构造 list 双向链表4、使用另外一个 list 容器 构造 list 双向链表…

图解机器学习神器:Scikit-Learn

算法进阶 ​​本文详解 Scikit-learn 工具库的用法&#xff0c;覆盖机器学习基础知识、SKLearn讲解、SKLearn三大核心API、SKLearn高级API等内容。 https://www.showmeai.tech/article-detail/203 我们在上一篇SKLearn入门与简单应用案例 [1] 里给大家讲到了 SKLearn 工具的基…

reactive和TypeScript标注数据类型-ts使用方法

一、vite项目中<script setup lang"ts"> : lang"ts" 是表明支持ts校验&#xff08;ts 全称typescript,是es6语法&#xff0c;是javascript的超集强类型编程语言&#xff0c;类似java&#xff0c;定义变量类型后&#xff0c;赋值类型不一致&#xff0…

Redis 内存爆了?使用 Python 分析一下哪些 Key 占用空间比较大

大家好,我是水滴~~ 在这篇文章中,我们将探讨如何使用Python来分析Redis中哪些Key占用空间较大,以便识别和优化内存使用。 《Python入门核心技术》专栏总目录・点这里 文章目录 1. 前言2. 代码与解析2.1 安装依赖2.2 完整代码2.3 代码解析3. Excel 分析4. 总结1. 前言 Redi…

(2023|CVPR,Corgi,偏移扩散,参数高斯分布,弥合差距)用于文本到图像生成的偏移扩散

Shifted Diffusion for Text-to-image Generation 公众&#xff1a;EDPJ&#xff08;添加 VX&#xff1a;CV_EDPJ 或直接进 Q 交流群&#xff1a;922230617 获取资料&#xff09; 目录 0. 摘要 1. 简介 2. 方法 2.1 偏移扩散 3. 实验 3.1 无监督文本到图像生成 3.2 无…

免费IDEA插件推荐-Apipost-Helper

IDEA插件市场中的API调试插件不是收费&#xff08;Fast Request &#xff09;就是不好用&#xff08;apidoc、apidocx等等&#xff09;今天给大家介绍一款国产的API调试插件&#xff1a;Apipost-Helper&#xff0c;完全免费且好看好用&#xff01; 这款插件由Apipost团队开发的…

C++ 比 C语言的新增的特性 1

1. C是C的增强 1.1 C是静态类型的语言&#xff0c;具有严格的数据类型检查 1.1.1 c 因为const修饰的变量不允许修改&#xff0c;但是只给了警告&#xff0c;不严谨 const int a10;a20; //报错int *p&a;*p20;//a的值&#xff1f; test1.c:6:9: warning: initialization dis…

第十六节TypeScript 类

1、简介 TypeScript是面向对象的JavaScript。 类描述了所创建的对象共同的属性与方法。 2、类的定义 class class_name { // 类作用域 } 定义类的关键字是class&#xff0c;后面紧跟类名&#xff0c;类可以包含以下几个模块&#xff1a; 字段 – 字段是类里面声明的变量。字…

微信小程序-textarea组件字数实时更新

一、前言 本文实现的是在小程序中&#xff0c;textarea文本框输入文字后&#xff0c;实时显示文字的字数&#xff0c;获取更好的用户输入体验以及提示。 下图是实现的效果 二、代码实现 2-1、wxml代码 <view style"padding: 30rpx;"><view style"…

【网络安全 | 网络协议】结合Wireshark讲解TCP三次握手

TCP三次握手在Wireshark数据包中是如何体现的&#xff1f;在此之前&#xff0c;先熟悉TCP三次握手的流程。 TCP三次握手流程 TCP&#xff08;传输控制协议&#xff09;是一种面向连接的、可靠的传输层协议。在建立 TCP 连接时&#xff0c;需要进行三次握手&#xff0c;防止因为…

IntelliJ IDEA快捷键及调试

文章目录 一、IntelliJ IDEA 常用快捷键一览表1-IDEA的日常快捷键第1组&#xff1a;通用型第2组&#xff1a;提高编写速度&#xff08;上&#xff09;第3组&#xff1a;提高编写速度&#xff08;下&#xff09;第4组&#xff1a;类结构、查找和查看源码第5组&#xff1a;查找、…

【Spring】15 MessageSourceAware 接口

文章目录 1. 简介2. 功能3. 使用3.1 创建并实现接口3.2 配置 Bean 信息3.3 资源文件3.4 创建启动类3.5 启动 4. 应用场景总结 Spring 框架为开发者提供了丰富的扩展点&#xff0c;其中之一是 Bean 生命周期中的回调接口。本文将专注介绍一个与国际化相关的接口 MessageSourceAw…

正则表达式:元字符

一、什么事元字符 正则是由一系列的元字符组成的&#xff0c;所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符&#xff0c;元字符是构成正则表达式的基本元件。 二、元字符的分类 1.特殊单字符 效果&#xff1a; ①.任意字符&#xff08;换行符除外&#xff09;&…

【基础篇】一、认识JVM

文章目录 1、虚拟机2、Java虚拟机3、JVM的整体结构4、Java代码的执行流程5、JVM的三大功能6、JVM的分类7、JVM的生命周期 1、虚拟机 虚拟机&#xff0c;Virtual Machine&#xff0c;一台虚拟的计算机&#xff0c;用来执行虚拟计算机指令。分为&#xff1a; 系统虚拟机&#x…

“React学习之旅:从入门到精通的点滴感悟“

在探索和学习React的过程中&#xff0c;我逐渐领悟到了前端开发的魅力与挑战。React&#xff0c;作为Facebook推出的开源JavaScript库&#xff0c;以其独特的思维方式和强大的功能&#xff0c;引领着前端开发的潮流。在这篇文章中&#xff0c;我将分享我的React学习心得&#x…

MATLAB信号处理与应用 读书笔记 一

完成了基本操作&#xff0c;今天组数也正常&#xff0c;需要对应解决fsctrl文件中的信号处理相关 重点关注4傅里叶变换&#xff0c;6FIR滤波器&#xff0c;10信号处理中的应用字符的链接[aa,bb]&#xff1b; N18;N216; n0:N-1;k10:N1-1;k20:N2-1; w2*pi*(0:2047)/2048; Xw(1-…

简易的555函数信号发生器电路图

函数信号发生器是一种信号发生装置&#xff0c;能产生某些特定的周期性时间函数波形&#xff08;正弦波、方波、三角波、锯齿波和脉冲波等&#xff09;信号&#xff0c;频率范围可从几个微赫到几十兆赫。除供通信、仪表和自动控制系统测试用外&#xff0c;还广泛用于其他非电测…

摸索若依框架是如何实现权限过滤的

摸索若依框架是如何实现权限过滤的 这篇文章&#xff0c;我也是作为一个优秀开源框架的学习者&#xff0c;在这里摸索这套框架是如何实现权限过滤的&#xff0c;这个封装对于入行Java半年之余的我来说&#xff0c;理解起来有些困难&#xff0c;所以&#xff0c;文章只是作为一个…

Word-表格法对齐公式(手把手教学,公式格式从此不再愁)

新建word文件 1&#xff09;鼠标点击【插入】—>【表格】,选择31列的表格 2&#xff09;鼠标置于中间表格&#xff0c;快捷键输入Alt&#xff0c;进入公式编辑器中&#xff0c;输入任意字母&#xff0c;如&#xff1a;A&#xff0c;点击居中即可。 3&#xff09;第三列表…