← Components/Data Visualization

RadialProgress

radialprogress-1779378412992.tsx
'use client'
import { useEffect, useState } from 'react'

interface Metric {
  label: string
  value: number
  max: number
  color: string
  unit: string
}

const metrics: Metric[] = [
  { label: 'CPU Usage', value: 72, max: 100, color: '#C9A84C', unit: '%' },
  { label: 'Memory', value: 4.8, max: 8, color: '#6366f1', unit: 'GB' },
  { label: 'Network', value: 420, max: 1000, color: '#22c55e', unit: 'MB/s' },
  { label: 'Uptime', value: 99.9, max: 100, color: '#06b6d4', unit: '%' },
]

function Ring({ metric, size = 100, animated }: { metric: Metric; size?: number; animated: boolean }) {
  const r = (size - 16) / 2
  const circ = 2 * Math.PI * r
  const pct = animated ? metric.value / metric.max : 0
  const offset = circ * (1 - pct)

  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12 }}>
      <div style={{ position: 'relative', width: size, height: size }}>
        <svg width={size} height={size} style={{ transform: 'rotate(-90deg)' }}>
          <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="rgba(255,255,255,0.06)" strokeWidth="8" />
          <circle
            cx={size/2} cy={size/2} r={r} fill="none"
            stroke={metric.color} strokeWidth="8"
            strokeDasharray={circ} strokeDashoffset={offset}
            strokeLinecap="round"
            style={{ transition: 'stroke-dashoffset 1.2s cubic-bezier(0.4, 0, 0.2, 1)' }}
          />
        </svg>
        <div style={{
          position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column',
          alignItems: 'center', justifyContent: 'center',
        }}>
          <div style={{ color: metric.color, fontSize: 18, fontWeight: 800, lineHeight: 1 }}>
            {metric.value}{metric.unit.length <= 1 ? metric.unit : ''}
          </div>
          <div style={{ color: '#555', fontSize: 10 }}>{metric.unit.length > 1 ? metric.unit : ''}</div>
        </div>
      </div>
      <div style={{ color: '#aaa', fontSize: 12, fontWeight: 500 }}>{metric.label}</div>
    </div>
  )
}

export default function RadialProgress() {
  const [animated, setAnimated] = useState(false)
  useEffect(() => { setTimeout(() => setAnimated(true), 100) }, [])

  return (
    <div style={{ background: '#0A0A0A', padding: 48 }}>
      <div style={{ background: '#111', border: '1px solid rgba(255,255,255,0.06)', borderRadius: 16, padding: '32px 40px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 32 }}>
          <h3 style={{ color: '#F5F5F0', fontWeight: 700, fontSize: 16, margin: 0 }}>System Metrics</h3>
          <span style={{ display: 'flex', alignItems: 'center', gap: 6, color: '#22c55e', fontSize: 13 }}>
            <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#22c55e', display: 'inline-block' }} />
            All systems operational
          </span>
        </div>
        <div style={{ display: 'flex', gap: 40, justifyContent: 'center', flexWrap: 'wrap' }}>
          {metrics.map(m => <Ring key={m.label} metric={m} size={110} animated={animated} />)}
        </div>
      </div>
    </div>
  )
}

Component info

CategoryData Visualization
Frameworkreact
TierFREE
Views0
Copies0

About

Animated radial progress rings with multiple metrics and SVG stroke animation

More from Data Visualization

'use client'
import { useState } from 'react'

const SEGMENTS = [
  { label: 'Buttons', value: 12, color: '#C9A84C' },
  { label: 'Forms', value: 10, color: '#6366f1' },
  { label: 'Navigation', value: 8, color: '#22c55e' },
  { label: 'Dashboard', v
DonutChart
Data Visualization