Donut Chart

Circular proportional chart with a hollow center (variant of pie chart).

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`

}

    

/>

  

)

;

}

Scan to open this page on your phonereact-ui-library.com/components/DonutChart

</>

react-ui-library

100+ accessible, themeable components that work seamlessly across iOS, Android, and Web.

A Platform Blocks product.