效果图如下:
代码如下:
安装依赖:
npm install echarts --save
npm install echarts-liquidfill --save
引入依赖:
import echarts from 'echarts'
import 'echarts-liquidfill'
具体封装的组件,可以直接引进vue项目中使用,可能有些参数没有进行封装,请自行封装
<template>
<div>
<div class="echarts-liquidfill">
<!-- 用于渲染ECharts图表的DOM元素 -->
<div ref="chartContainer" :style="{ width: size, height: size }"></div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue' // 引入Vue的响应式API
import * as echarts from 'echarts' // 引入ECharts库
import 'echarts-liquidfill' // 引入液体填充图表类型
// 定义组件的props
const props = defineProps({
/*水波图比例,占比 传几个值为对应几条波浪*/
percentage: {
type: Array,
default: () => [0.84, 0.84], // 默认值
},
/*水球的大小,宽和高 */
size: {
type: String,
default: '210px', // 默认大小
},
/*波浪颜色 第一个值为顶端(从上往下看) 第二个值为底部 从上往下开始渐变,从40%开始渐变*/
color: {
type: Array,
default: () => ['rgba(22, 197, 255, 0.4)', 'rgba(22, 119, 255, 0.4)'], // 默认颜色
},
/*是否显示水波图标题,默认显示*/
titleShow: {
type: Boolean,
default: true, // 默认显示标题
},
/*水波图标题*/
title: {
type: String,
default: '全部问题解决率', // 默认标题
},
/*水波图中心比例,默认为空,和percentage只显示一个,优先此项,此项不用填小数,可以直接填数字,percentage为空不显示水波*/
labelNumber: {
type: String,
default: '', // 默认不显示中心比例
},
/*百度比例数字的大小*/
percentSize: {
type: Number,
default: 36, // 默认百分比字体大小
},
/*单位字体大小*/
unitSize: {
type: Number,
default: 36, // 默认单位字体大小
},
padding: {
type: Array,
default: () => [0, 0, 0, 0], // 默认内边距
},
})
const chartContainer = ref(null) // 创建图表容器的引用
// 组件挂载后绘制水球图
onMounted(() => {
drawWaterball(props.percentage)
})
// 监听percentage的变化,重新绘制水球图
watch(
() => props.percentage,
(newValue) => {
drawWaterball(newValue)
},
)
// 绘制水球图的函数
const drawWaterball = (percentage) => {
const chart = echarts.init(chartContainer.value) // 初始化ECharts实例
const option = {
series: [
{
type: 'liquidFill', // 图表类型为液体填充
data: props.percentage, // 百分比的值,取值范围为0到1
itemStyle: {
opacity: 1, // 透明度
color:
new echarts.graphic.LinearGradient(0, 0, 0, 1, [ // 渐变色
{
offset: 0.4,
color: props.color[0], // 顶端颜色
},
{
offset: 1,
color: props.color[1], // 底部颜色
},
]),
},
radius: '85%', // 水球图的半径,可以根据需要调整
label: {
position: ['50%', '50%'], // 百分数的位置
formatter(param) {
return [`{a|${props.labelNumber || (param.value * 100).toFixed(0)}}`, '{b|%}'].join('') // 格式化标签
},
rich: {
a: {
fontSize: props.percentSize, // 百分比字体大小
color: '#000000', // 字体颜色
fontFamily: 'PingFang SC', // 字体
fontWeight: 600, // 字体粗细
},
b: {
fontSize: props.unitSize, // 单位字体大小
color: '#000000', // 字体颜色
fontFamily: 'PingFang SC', // 字体
fontWeight: 600, // 字体粗细
padding: props.padding, // 内边距
},
},
},
backgroundStyle: {
color: new echarts.graphic.RadialGradient(0.5, 0.5, 0.7, [ // 背景渐变色
{
offset: 0,
color: 'rgba(229, 247, 255, 1)', // 渐变起始颜色
},
{
offset: 0.5,
color: 'rgba(229, 247, 255, 1)', // 中间颜色
},
{
offset: 1,
color: 'rgba(84, 226, 241, 0.6)', // 渐变结束颜色
},
]),
},
outline: {
borderDistance: 5, // 边框距离
itemStyle: {
borderWidth: 0, // 边框宽度
borderColor: props.color, // 边框颜色
shadowBlur: 30, // 阴影模糊度
shadowColor: 'rgba(84, 226, 241, 0.6)', // 阴影颜色
},
},
},
],
title: {
show: props.titleShow, // 是否显示标题
text: props.title, // 标题文本
x: '47.5%', // 标题X位置
y: '60%', // 标题Y位置
z: 10, // 标题层级
textAlign: 'center', // 文本对齐方式
textStyle: {
color: '#666666', // 标题颜色
fontWeight: 'normal', // 标题字体粗细
fontSize: 14, // 标题字体大小
},
},
}
chart.setOption(option) // 设置图表选项
}
</script>
<style lang="scss" scoped>
.echarts-liquidfill {
width: 100%; // 宽度100%
height: 100%; // 高度100%
display: flex; // 使用flex布局
justify-content: center; // 水平居中
align-items: center; // 垂直居中
}
</style>