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

【echarts】分割环形图组件

这个组件实现了一个环形饼图,支持以下功能:

 
  1. 自定义颜色、间隙和中心位置
  2. 支持在图表中心显示总计文本
  3. 可以自定义中心文本的样式
  4. 响应式设计,支持自定义宽度和高度
  5. 数据变化时自动更新图表
 

使用时,只需传入 chartData 数据和其他可选配置项即可。

组件代码

<template><div :id="chartId" :style="{ width: width, height: height }"></div>
</template><script setup>
import * as echarts from "echarts";
import { onMounted, onUnmounted, ref, watch } from "vue";const props = defineProps({chartData: {type: Array,required: true,default: () => [],},width: {type: String,default: "100%",},height: {type: String,default: "400px",},chartOptions: {type: Object,default: () => ({}),},sectorGap: {type: Number,default: 2,},gapColor: {type: String,default: "#fff",},chartCenter: {type: Array,default: () => ["50%", "50%"],},colors: {type: Array,default: () => ["#C114D8","#0D4EB5","#FF8620","#119F4D","#3E17E9","#DFA00D","#fb8166","#e062ae","#7262bd","#61a0a8","#bda29a","#444693",],},showCenterText: {type: Boolean,default: true,},// 第一行文本配置centerTitle: {type: String,default: "总数(个)",},centerTitleStyle: {type: Object,default: () => ({fontSize: 16,color: "#666",}),},// 第二行文本配置centerValueStyle: {type: Object,default: () => ({fontSize: 24,fontWeight: "bold",color: "#21252E",}),},
});const chartId = ref(`ring-pie-chart-${Date.now()}`);
let chartInstance = null;// 计算数据总和
const calculateTotal = (data) => {return data.reduce((sum, item) => sum + (item.value || 0), 0);
};const initChart = () => {const chartDom = document.getElementById(chartId.value);chartInstance = echarts.init(chartDom);const formattedData = props.chartData.map((item, index) => ({...item,itemStyle: {color: props.colors[index % props.colors.length],},}));const total = calculateTotal(props.chartData);const series = [{type: "pie",radius: ["50%", "70%"],center: props.chartCenter,data: formattedData,label: {show: true,position: "outside",formatter: "{b}: {c}",},labelLine: {show: true,},itemStyle: {borderWidth: props.sectorGap,borderColor: props.gapColor,},},];// 添加中央文本if (props.showCenterText) {series.push({type: "gauge",startAngle: 90,endAngle: -270,radius: "40%",center: props.chartCenter,pointer: {show: false,},axisLine: {show: false,},axisTick: {show: false,},splitLine: {show: false,},axisLabel: {show: false,},detail: {show: true,formatter: `{title|${props.centerTitle}}\n{value|${total} }`,backgroundColor: "transparent",borderWidth: 0,borderRadius: 4,offsetCenter: [0, 0],rich: {title: {fontSize: props.centerTitleStyle.fontSize,color: props.centerTitleStyle.color,lineHeight: 20,},value: {fontSize: props.centerValueStyle.fontSize,fontWeight: props.centerValueStyle.fontWeight,color: props.centerValueStyle.color,lineHeight: 30,},},},data: [{ value: 0 }],});}const defaultOptions = {color: props.colors,series,};const mergedOptions = {...defaultOptions,...props.chartOptions,series: [...defaultOptions.series.slice(0, 1),...(props.chartOptions.series || []),...defaultOptions.series.slice(1),],};chartInstance.setOption(mergedOptions);
};watch(() => [props.chartData,props.sectorGap,props.gapColor,props.chartCenter,props.colors,props.showCenterText,props.centerTitle,],() => {if (chartInstance) {const formattedData = props.chartData.map((item, index) => ({...item,itemStyle: {color: props.colors[index % props.colors.length],},}));const total = calculateTotal(props.chartData);const seriesOptions = [{data: formattedData,center: props.chartCenter,itemStyle: {borderWidth: props.sectorGap,borderColor: props.gapColor,},},];if (props.showCenterText) {seriesOptions.push({type: "gauge",detail: {formatter: `{title|${props.centerTitle}}\n{value|${total}}`,},});}chartInstance.setOption({color: props.colors,series: seriesOptions,});}},{ deep: true }
);onMounted(() => {initChart();
});onUnmounted(() => {if (chartInstance) {chartInstance.dispose();chartInstance = null;}
});
</script><style scoped>
div {width: 100%;height: 100%;
}
</style>

组件调用

<pieChart :chartData="data" />data=[{name:'其他',value:'20'
},{name:'财务',value:'20'
},{name:'审计',value:'20'
}]

http://www.xdnf.cn/news/866863.html

相关文章:

  • 【Java算法】八大排序
  • 【2025】通过idea把项目到私有仓库(3)
  • [Java 基础]银行账户程序
  • 如何选择合适的embedding模型用于非英文语料
  • 亚马逊站内信规则2025年重大更新:避坑指南与合规策略
  • golang常用库之-go-feature-flag库(特性开关(Feature Flags))
  • [蓝桥杯]密码脱落
  • NTC热敏电阻
  • 【Linux】进程
  • Pytorch模型格式区别( .pt .pth .bin .onnx)
  • nssm配置springboot项目环境,注册为windows服务
  • 【免杀】C2免杀技术(十五)shellcode混淆uuid/ipv6/mac
  • Mac 双系统
  • 深入详解开源工具DCMTK:C++开发的DICOM工具包
  • <el-table>构建树形结构
  • KrillinAI:视频跨语言传播的一站式AI解决方案
  • EasyRTC嵌入式音视频通信SDK音视频功能驱动视频业务多场景应用
  • HOPE800系列变频器安装到快速调试的详细操作说明
  • Delft3D软件介绍及建模原理和步骤;Delft3D数值模拟溶质运移模型建立;地表水环境影响评价报告编写思路
  • CppCon 2015 学习:3D Face Tracking and Reconstruction using Modern C++
  • 前端大数高精度计算解决方案,BigNumber.js
  • 前端面试二之运算符与表达式
  • 组件库二次封装——透传问题
  • UniApp 全生命周期钩子详解
  • 数据标注与大模型的双向赋能:效率与性能的跃升
  • CMake + Ninja 构建程序示例
  • CortexON:开源的多代理AI系统无缝自动化和简化日常任务
  • 【推荐算法】推荐系统核心算法深度解析:协同过滤 Collaborative Filtering
  • 07 APP 自动化- appium+pytest+allure框架封装
  • RabbitMQ 的异步化、解耦和流量削峰三大核心机制