Donut Chart
Examples
(6)Properties
(60)Playground
Loading demo…
import
{
DonutChart
}
from
'@platform-blocks/charts'
;
import
{
DEPARTMENT_ALLOCATIONS
}
from
'./data'
;
const
formatBudget
=
(
value
:
number
)
=>
`$${Intl.NumberFormat('en-US', { maximumFractionDigits: 0 }).format(value)}M`
;
export
function
Demo
(
)
{
return
(
<DonutChart
title
=
"Annual Expense Allocation"
subtitle
=
"FY26 operating plan"
size
=
{
300
}
data
=
{
DEPARTMENT_ALLOCATIONS
}
padAngle
=
{
1.8
}
legend
=
{
{
position
:
'bottom'
}
}
centerLabel
=
{
(
)
=>
'Budget'
}
centerSubLabel
=
{
(
)
=>
'Allocation by function'
}
centerValueFormatter
=
{
(
value
)
=>
formatBudget
(
value
)
}
/>
)
;
}
Loading demo…
import
{
DonutChart
}
from
'@platform-blocks/charts'
;
import
{
SEGMENTS
}
from
'./data'
;
export
function
Demo
(
)
{
return
(
<DonutChart
title
=
"Team allocation"
size
=
{
260
}
data
=
{
SEGMENTS
}
/>
)
;
}
Loading demo…
import
{
DonutChart
}
from
'@platform-blocks/charts'
;
import
type
{
DonutChartDataPoint
}
from
'@platform-blocks/charts'
;
import
{
ARR_SEGMENTS
,
GROWTH_CONTRIBUTION
}
from
'./data'
;
const
formatMillions
=
(
value
:
number
)
=>
`${Intl.NumberFormat('en-US', { maximumFractionDigits: 0 }).format(value)}M`
;
const
getRingId
=
(
slice
?:
DonutChartDataPoint
|
null
)
=>
(
slice as
any
)
?
.
ringId as
string
|
undefined
;
export
function
Demo
(
)
{
return
(
<DonutChart
title
=
"ARR Mix by Segment"
subtitle
=
"FY26 to date"
size
=
{
320
}
ringGap
=
{
16
}
rings
=
{
[
{
id
:
'arr'
,
label
:
'Annual Recurring Revenue'
,
data
:
ARR_SEGMENTS
,
padAngle
:
1.8
,
showInLegend
:
true
,
}
,
{
id
:
'growth'
,
label
:
'YoY Growth Contribution'
,
data
:
GROWTH_CONTRIBUTION
,
thicknessRatio
:
0.16
,
padAngle
:
1.2
,
showInLegend
:
false
,
}
,
]
}
primaryRingIndex
=
{
0
}
legendRingIndex
=
{
0
}
centerLabel
=
{
(
total
,
_data
,
focused
)
=>
{
if
(
focused
)
{
return
focused
.
label
;
}
return
'Total ARR'
;
}
}
centerSubLabel
=
{
(
total
,
_data
,
focused
)
=>
{
if
(
!
focused
)
return
'YoY growth vs. FY25'
;
return
getRingId
(
focused
)
===
'growth'
?
'Growth contribution'
:
'Segment share'
;
}
}
centerValueFormatter
=
{
(
value
,
_total
,
focused
)
=>
{
if
(
focused
&&
getRingId
(
focused
)
===
'growth'
)
{
return
`${value.toFixed(0)}%`
;
}
return
`$${formatMillions(value)}`
;
}
}
legend
=
{
{
position
:
'bottom'
}
}
/>
)
;
}
Loading demo…
import
{
DonutChart
}
from
'@platform-blocks/charts'
;
import
{
POWER_BY_SUBSYSTEM
}
from
'./data'
;
const
formatMegawatts
=
(
value
:
number
)
=>
`${value.toFixed(1)} MW`
;
export
function
Demo
(
)
{
return
(
<DonutChart
title
=
"Data Center Power Draw"
subtitle
=
"May 2025 peak load"
size
=
{
320
}
data
=
{
POWER_BY_SUBSYSTEM
}
padAngle
=
{
2
}
legend
=
{
{
position
:
'right'
,
align
:
'start'
}
}
padding
=
{
{
top
:
140
,
right
:
168
,
bottom
:
72
,
left
:
72
}
}
centerLabel
=
{
(
)
=>
'Power load'
}
centerSubLabel
=
{
(
)
=>
'Across campus subsystems'
}
centerValueFormatter
=
{
(
value
)
=>
formatMegawatts
(
value
)
}
labels
=
{
{
show
:
true
,
position
:
'outside'
,
showPercentage
:
true
,
showValue
:
true
,
valueFormatter
:
(
{
value
}
)
=>
formatMegawatts
(
value
)
,
leaderLine
:
{
width
:
1.5
}
,
}
}
/>
)
;
}
Loading demo…
import
{
View
,
Text
}
from
'react-native'
;
import
{
DonutChart
}
from
'@platform-blocks/charts'
;
import
{
REGION_HEADCOUNT
,
WORK_STYLE
,
remoteRatio
}
from
'./data'
;
const
formatHeadcount
=
(
value
:
number
)
=>
Intl
.
NumberFormat
(
'en-US'
,
{
maximumFractionDigits
:
0
}
)
.
format
(
value
)
;
export
function
Demo
(
)
{
return
(
<DonutChart
title
=
"Employee Distribution"
subtitle
=
"Geography and work style"
size
=
{
320
}
ringGap
=
{
18
}
rings
=
{
[
{
id
:
'region'
,
label
:
'Regional distribution'
,
data
:
REGION_HEADCOUNT
,
padAngle
:
2.2
,
thicknessRatio
:
0.3
,
showInLegend
:
false
,
}
,
{
id
:
'work-style'
,
label
:
'Work style mix'
,
data
:
WORK_STYLE
,
thicknessRatio
:
0.18
,
padAngle
:
1.5
,
showInLegend
:
true
,
}
,
]
}
primaryRingIndex
=
{
0
}
legendRingIndex
=
{
1
}
renderCenterContent
=
{
(
{
focusedSlice
,
primaryRing
,
total
}
)
=>
{
const
isWorkStyle
=
focusedSlice
?
.
ringId
===
'work-style'
;
const
headline
=
focusedSlice
?
focusedSlice
.
label
:
'Headcount'
;
const
valueText
=
focusedSlice
?
isWorkStyle
?
`${Math.round((focusedSlice.percentage || 0) * 100)}%`
:
formatHeadcount
(
focusedSlice
.
value
)
:
formatHeadcount
(
primaryRing
?
.
total
??
total
)
;
const
helperText
=
focusedSlice
?
isWorkStyle
?
'of workforce'
:
'global headcount'
:
`Remote ${Math.round(remoteRatio * 100)}%`
;
return
(
<View
style
=
{
{
alignItems
:
'center'
,
justifyContent
:
'center'
}
}
>
<Text
style
=
{
{
fontSize
:
12
,
fontWeight
:
'600'
,
textTransform
:
'uppercase'
,
color
:
'#868E96'
,
marginBottom
:
2
,
}
}
>
{
headline
}
</Text
>
<Text
style
=
{
{
fontSize
:
26
,
fontWeight
:
'700'
,
color
:
'#212529'
,
}
}
>
{
valueText
}
</Text
>
<Text
style
=
{
{
fontSize
:
12
,
color
:
'#495057'
,
marginTop
:
4
,
}
}
>
{
helperText
}
</Text
>
</View
>
)
;
}
}
labels
=
{
{
show
:
true
,
rings
:
[
'work-style'
]
,
position
:
'outside'
,
showPercentage
:
true
,
leaderLine
:
{
width
:
1.4
}
,
}
}
legend
=
{
{
position
:
'bottom'
}
}
/>
)
;
}
Loading demo…
import
{
DonutChart
}
from
'@platform-blocks/charts'
;
import
{
FULFILLMENT_PARTNERS
}
from
'./data'
;
const
formatOrders
=
(
value
:
number
)
=>
`${value.toFixed(2)}M`
;
export
function
Demo
(
)
{
return
(
<DonutChart
title
=
"Marketplace Fulfillment Mix"
subtitle
=
"Orders fulfilled in Q3"
size
=
{
300
}
data
=
{
FULFILLMENT_PARTNERS
}
padAngle
=
{
1.6
}
isolateOnClick
legend
=
{
{
position
:
'bottom'
}
}
centerLabel
=
{
(
)
=>
'Orders'
}
centerSubLabel
=
{
(
)
=>
'Fulfilled volume by partner'
}
centerValueFormatter
=
{
(
value
)
=>
`${formatOrders(value)} total`
}
/>
)
;
}
</>
react-ui-library
100+ accessible, themeable components that work seamlessly across iOS, Android, and Web.
A Platform Blocks product.
Quick Links
Resources