You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 21:01:04