DonutChart
donutchart-1779393693148.tsx
'use client'
const DATA = [
{ label: 'React', value: 45, color: '#6d28d9' },
{ label: 'Vue', value: 25, color: '#2563eb' },
{ label: 'Angular', value: 20, color: '#0891b2' },
{ label: 'Svelte', value: 10, color: '#db2777' },
]
export default function DonutChart({ data = DATA, size = 180, thickness = 40 }) {
const total = data.reduce((s, d) => s + d.value, 0)
const r = (size - thickness) / 2
const circumference = 2 * Math.PI * r
let offset = 0
const segments = data.map(d => {
const length = (d.value / total) * circumference
const seg = { ...d, offset: circumference - offset, length }
offset += length
return seg
})
return (
<div style={{ display: 'flex', alignItems: 'center', gap: '24px' }}>
<svg width={size} height={size} style={{ flexShrink: 0 }}>
<circle cx={size/2} cy={size/2} r={r} fill="none" stroke="#f1f5f9" strokeWidth={thickness} />
{segments.map(seg => (
<circle key={seg.label}
cx={size/2} cy={size/2} r={r} fill="none"
stroke={seg.color} strokeWidth={thickness}
strokeDasharray={seg.length + ' ' + circumference}
strokeDashoffset={seg.offset}
strokeLinecap="round"
style={{ transform: 'rotate(-90deg)', transformOrigin: 'center', transition: 'stroke-dasharray 0.5s' }}
/>
))}
<text x={size/2} y={size/2 - 6} textAnchor="middle" fontSize="22" fontWeight="800" fill="#1e293b">{total}%</text>
<text x={size/2} y={size/2 + 14} textAnchor="middle" fontSize="11" fill="#94a3b8">Total</text>
</svg>
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
{data.map(d => (
<div key={d.label} style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<div style={{ width: '10px', height: '10px', borderRadius: '2px', background: d.color, flexShrink: 0 }} />
<span style={{ fontSize: '13px', color: '#374151' }}>{d.label}</span>
<span style={{ fontSize: '13px', fontWeight: 700, color: '#1e293b', marginLeft: 'auto' }}>{d.value}%</span>
</div>
))}
</div>
</div>
)
}Component info
CategoryData Visualization
Frameworkreact
TierFREE
Views0
Copies0
About
SVG donut chart with legend and animated segments
More from Data Visualization
'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', unRadialProgress
Data Visualization
'use client';
import { useState, useEffect } from 'react';
export default function MetricGauge({ value = 73, max = 100, label = "Performance Score", unit = "%" }) {
const [animated, setAnimated] = useState(0);
useEffect(() => {
const timer MetricGauge
Data Visualization
'use client';
import { useState, useEffect } from 'react';
export default function SplitTestWidget() {
const [animating, setAnimating] = useState(false);
const tests = [
{ name: 'CTA Button Color', varA: { label: 'Blue', value: 3.2, users: 4SplitTestWidget
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', vDonutChart
Data Visualization