如何在单个SVG环形进度组件中展示两个不同数值?
双环形进度条实现方案
核心需求是实现双同心环形进度组件,分别展示两个共享最大值的不同类型数值,以下是从SVG结构、样式到Angular逻辑的完整改造方案:
1. 重构SVG结构(新增第二个进度环)
原代码仅含单个进度路径,需添加第二个进度元素并绑定独立模板变量,同时简化复杂的transform,改用中心旋转使逻辑更清晰:
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200"> <!-- 背景环:固定灰色底层 --> <path class="progress-bg" d="M100,20 A80,80 0 1,1 20,100 A80,80 0 1,1 100,20" transform="rotate(-135 100 100)"/> <!-- 第一个进度环:绑定模板变量#progress1 --> <path #progress1 class="progress-bar progress-bar-1" d="M100,20 A80,80 0 1,1 20,100 A80,80 0 1,1 100,20" transform="rotate(-135 100 100)"/> <!-- 第二个进度环:绑定模板变量#progress2 --> <path #progress2 class="progress-bar progress-bar-2" d="M100,20 A80,80 0 1,1 20,100 A80,80 0 1,1 100,20" transform="rotate(-135 100 100)"/> </svg>
2. 配置关键CSS样式
环形进度依赖stroke绘制,必须关闭fill属性,同时设置线条宽度、圆角端点以匹配示例图效果:
.progress-bg { fill: none; stroke: #e5e5e5; stroke-width: 12; stroke-linecap: round; } .progress-bar { fill: none; stroke-width: 12; stroke-linecap: round; /* 默认隐藏全部进度,后续通过JS控制显示长度 */ stroke-dasharray: 0 502.65; /* 502.65为半径80的圆周长:2×π×80≈502.65 */ } .progress-bar-1 { stroke: #2196F3; /* 第一个进度环颜色 */ } .progress-bar-2 { stroke: #FF9800; /* 第二个进度环颜色 */ }
3. Angular逻辑控制进度
获取两个进度元素,根据数值占比计算进度长度,动态设置stroke-dasharray属性:
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; @Component({ selector: 'app-double-progress-ring', templateUrl: './double-progress-ring.component.html', styleUrls: ['./double-progress-ring.component.css'] }) export class DoubleProgressRingComponent implements AfterViewInit { @ViewChild('progress1') progress1!: ElementRef<SVGPathElement>; @ViewChild('progress2') progress2!: ElementRef<SVGPathElement>; // 模拟业务数值,最大值统一设为100 maxValue = 100; valueType1 = 65; // 第一类数值 valueType2 = 40; // 第二类数值 // 预计算环形周长,避免重复计算 private readonly circumference = 2 * Math.PI * 80; ngAfterViewInit(): void { this.updateProgress(this.progress1.nativeElement, this.valueType1); this.updateProgress(this.progress2.nativeElement, this.valueType2); } private updateProgress(element: SVGPathElement, value: number): void { // 计算当前数值对应的进度长度 const progressLength = (value / this.maxValue) * this.circumference; // 通过stroke-dasharray控制显示/隐藏长度 element.style.strokeDasharray = `${progressLength} ${this.circumference}`; } }
关键注意事项
- 周长准确性:必须使用环形实际周长(2πr)计算进度比例,原代码固定值300会导致进度失真。
- 起始位置:通过
rotate(-135 100 100)将进度起始点设在左上方,与示例图一致,调整角度可修改起始位置。 - 层级处理:后绘制的进度环会覆盖先绘制的,若需无遮挡显示,可调整
stroke-width或设置stroke-dashoffset错开起始位置。
内容的提问来源于stack exchange,提问作者user19673728
相关产品推荐
相关产品推荐

