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

Vue + ECharts 实现多层极坐标环形图

一、ECharts 配置详解

1.1标题配置(中间文本)
title: {text: `老人总数\n${total}`,left: 'center',top: '42%',textStyle: {color: '#fff',fontSize: 16,fontWeight: 'normal',lineHeight: 24,}
}
1.2 极坐标系核心配置
polar: {radius: [40, 100], // 内环到外环半径范围center: ['50%', '50%']
}
  • radius 控制环的内外大小(40~100 像素)

  • center 控制图表居中

angleAxis: {max: 100,clockwise: false,show: false
}

 

  • max: 100:表示角度按百分比计算(满圈)

  • clockwise: false:环形从逆时针方向开始

  • show: false:不显示角度坐标轴

radiusAxis: {type: 'category',show: false
}

 极坐标的径向轴(环的分布方向)设为类别型,也隐藏。

 1.3 系列数据渲染(关键)
series: list.map((item, index) => ({type: 'bar',data: [item.percent],coordinateSystem: 'polar',roundCap: true,barWidth: 10,z: index,itemStyle: {color: item.color},startAngle: index === 0 ? 0 : list[index - 1].percent,endAngle: item.percent
}))
  • type: 'bar' + coordinateSystem: 'polar' => 每一层为一个环形柱条

  • data: [item.percent]:控制每一层占据的弧度(百分比)

  • roundCap: true:每个环条两端为圆头

  • barWidth: 10:每层环的宽度(10px)

  • z: index:设置层级顺序,后渲染的在上层

  • color:颜色来自数据项自定义

二、注意事项以及解释 

什么是“极坐标系”?

我们平时看到的柱状图、折线图,都是用的“直角坐标系” —— 横轴是 X,竖轴是 Y。

极坐标系 是用“圆形”来表示数据的 —— 数据不是向上长,而是沿着圆圈展开

你可以想象一块披萨:每一块就是一个“角度”,表示一个数据的占比

极坐标的两个坐标轴:

angleAxis —— 控制“角度”,也就是每个环条占多少角度

angleAxis: {max: 100,clockwise: false,show: false,
}
max: 100:表示整个圆为100%,用百分比来画。clockwise: false:从左边开始画环,并逆时针转。show: false:这个角度轴不显示出来(不然就一堆数字很丑)。

radiusAxis —— 控制“半径”,决定这一条环是在哪一圈

radiusAxis: {type: 'category',show: false,
}
type: 'category':代表我这里每一层圆都是“分类”用的,不是数值。show: false:同样不显示。

想象多层披萨:

  • 第一层是小圈圈(内层)

  • 第二层是稍微大一点的圈(外层)

  • 第三层更大...

这就是“多层圆”,而 radiusAxis 决定它是在第几层。

怎么形成“多层圆”?

series: list.map((item, index) => ({type: 'bar',data: [item.percent],coordinateSystem: 'polar',roundCap: true,barWidth: 10,z: index,itemStyle: { color: item.color },
}))
list.map(...):我们有 4 种老人类型,就会画 4 个“圆圈圈”。data: [item.percent]:这个值决定这个甜甜圈占圆圈的多少角度(比如 30%)。barWidth: 10:每个圈的“厚度”是 10 像素。
为什么每一圈自动往外排?
因为 echarts 极坐标下,每画一个柱子,它会自动从里往外排列,每个 series 代表一层:
series 0 → 最里面那圈
series 1 → 第二圈
series 2 → 第三圈
series 3 → 最外圈

3、全部代码 

<template><div class="elderly-chart"><div ref="chartRef" class="chart"></div><div class="info"><div v-for="(item, index) in reversedList" :key="index" class="info-item"><div class="info-color" :style="{ backgroundColor: item.color }"></div><div class="info-text">{{ item.name }}</div><div class="info-number">{{ item.number }}人</div><div class="info-percent">{{ item.percent }}%</div></div></div></div></template><script setup>import { ref, onMounted } from 'vue'import * as echarts from 'echarts'const chartRef = ref(null)const list = [{ name: '介助', number: 344, percent: 27, color: '#F2E93D' },{ name: '介护', number: 304, percent: 37, color: '#4CE1D6' },{ name: '失能', number: 98, percent: 7, color: '#C3A6FD' },{ name: '自理', number: 485, percent: 93, color: '#2F7CF6' },]const reversedList = ref([...list].reverse())onMounted(() => {const chart = echarts.init(chartRef.value)const total = 1231const option = {backgroundColor: 'transparent',title: {text: `老人总数\n${total}`,left: 'center',top: '42%',textStyle: {color: '#fff',fontSize: 16,fontWeight: 'normal',lineHeight: 24,},},polar: {radius: [40, 100], // 保持内外半径范围不变center: ['50%', '50%'],},angleAxis: {max: 100,  // 设置最大值为100,角度为百分比clockwise: false,show: false,},radiusAxis: {type: 'category',show: false,},series: list.map((item, index) => ({type: 'bar',data: [item.percent],coordinateSystem: 'polar',roundCap: true,barWidth: 10,z: index, // 控制层级itemStyle: {color: item.color,},// 动态设置每个环的占据角度startAngle: index === 0 ? 0 : list[index - 1].percent,  // 每个环的起始角度endAngle: item.percent,  // 每个环的结束角度})),}chart.setOption(option)window.addEventListener('resize', () => {chart.resize()})})</script><style scoped>.elderly-chart {display: flex;align-items: center;justify-content: center;background: #0B1E38;padding: 20px;}.chart {width: 300px;height: 300px;position: relative;}.info {margin-left: 30px;display: flex;flex-direction: column;justify-content: center;}.info-item {display: flex;align-items: center;margin-bottom: 12px;}.info-color {width: 10px;height: 10px;border-radius: 50%;margin-right: 8px;}.info-text {color: #fff;width: 50px;}.info-number {color: #fff;margin-left: 10px;width: 60px;}.info-percent {color: #fff;margin-left: 10px;}</style>

相关文章:

  • 通过AWS Console连接服务器,简化运维过程
  • 企业出海降本:如何将应用从 AWS EC2 快速无缝迁移至DigitalOcean Droplet
  • 揭开应用程序的神秘面纱:深入了解 AWS X-Ray
  • 【docker】启动临时MongoDB容器、挂载数据卷运行数据库服务,并通过备份文件恢复MongoDB数据库备份数据
  • SQLMesh增量模型实战指南:时间范围分区
  • nginx 核心功能
  • 鸟笼效应——AI与思维模型【84】
  • 组件轮播与样式结构重用实验
  • Android开发——实现一个计算器
  • 利用3DMAX + Corona Renderer打造现代住宅逼真效果!
  • DotNet 入门:(一) 环境安装
  • MarkItDown:如何高效将各类文档转换为适合 LLM 处理的 Markdown 格式
  • 进程优先级以及切换调度
  • 得物 小程序 6宫格 分析
  • C++/SDL 进阶游戏开发 —— 双人塔防(代号:村庄保卫战 16)
  • opencv 直方图均衡化
  • AimRT 从零到一:官方示例精讲 —— 三、Executor示例.md
  • 【AI News | 20250429】每日AI进展
  • OpenCV 图形API(71)图像与通道拼接函数-----从图像(GMat)中裁剪出一个矩形区域的操作函数 crop()
  • gitee 如何修改提交代码的邮箱
  • 新造古镇丨上海古镇朱家角一年接待164万境外游客,凭啥?
  • 西班牙遭遇史上最严重停电,已进入国家紧急状态
  • 瞄准“美丽健康”赛道,上海奉贤如何打造宜居宜业之城?
  • 国家发改委答澎湃:将指导限购城市针对长期摇号家庭和无车家庭等重点群体定向增发购车指标
  • 央视曝光假进口保健品:警惕!保税仓发货不等于真进口
  • 新希望去年归母净利润4.74亿同比增逾九成,营收降27%