Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit

* refactor: stricter functionProp util types

* refactor: shorten getRevealValue util function

* refactor: simplify makePropsWithDefaults function

Git stats


Failed to load latest commit information.
Latest commit message
Commit time
Apr 15, 2020
Oct 30, 2022
Oct 30, 2022

React minimal pie chart

Build Status Npm version Coveralls Bundle size

Lightweight React SVG pie charts, with versatile options and CSS animation included. < 2kB gzipped. πŸ‘ Demo πŸ‘.

React minimal pie chart preview


Because Recharts is awesome, but when you just need a simple pie/donought chart, 3kB 2kB are usually enough.

by Bundlefobia
Benchmark Size * Loading time
on a slow 3g *
react-minimal-pie-chart (v8.4.0) Bundle size: React minimal pie chart 1.93 KB ~39 ms
rechart (v1.8.5) Bundle size: Recharts 96.9 KB ~1900 ms
victory-pie (v34.1.3) Bundle size: Victory pie 50.5 KB ~1100 ms
react-apexcharts (v1.3.7) Bundle size: React apec charts 114.6 KB ~2300 ms
react-vis (v1.11.7) Bundle size: React vis 78.3 KB ~1600 ms

* Benchmark carried out with size-limit with a "real-world" setup: see benchmark repo. (What matter here are not absolute values but the relation between magnitudes)


  • < 2kB gzipped
  • Versatile: Pie, Donut, Loading, Completion charts (see Demo)
  • Customizable chart labels and CSS animations
  • Written in Typescript
  • No dependencies


npm install react-minimal-pie-chart

If you don't use a package manager, react-minimal-pie-chart exposes also an UMD module ready for the browser.

Minimum supported Typescript version: >= 3.8


import { PieChart } from 'react-minimal-pie-chart';

    { title: 'One', value: 10, color: '#E38627' },
    { title: 'Two', value: 15, color: '#C13C37' },
    { title: 'Three', value: 20, color: '#6A2135' },


Property Type Description Default
data DataEntry[] Source data. Each entry represents a chart segment []
lineWidth number (%) Line width of each segment. Percentage of chart's radius 100
startAngle number Start angle of first segment 0
lengthAngle number Total angle taken by the chart (can be negative to make the chart clockwise!) 360
totalValue number Total value represented by the full chart -
paddingAngle number Angle between two segments -
rounded boolean Round line caps of each segment -
segmentsShift number
(segmentIndex) => number
Translates segments radially. If number set, provide shift value relative to viewBoxSize space. If function, return a value for each segment.
(radius prop might be adjusted to prevent segments from overflowing chart's boundaries)
segmentsStyle CSSObject
(segmentIndex) => CSSObject
Style object assigned to each segment. If function, return a value for each segment. (Warning: SVG only supports its own CSS props). -
segmentsTabIndex number tabindex attribute assigned to segments -
label (labelRenderProps) => string | number | ReactElement A function returning a label value or the SVG element to be rendered as label -
labelPosition number (%) Label position from origin. Percentage of chart's radius (50 === middle point) 50
labelStyle CSSObject
(segmentIndex) => CSSObject
Style object assigned to each label. If function set, return style for each label. (Warning: SVG only supports its own CSS props). -
animate boolean Animate segments on component mount -
animationDuration number Animation duration in ms 500
animationEasing string A CSS easing function ease-out
reveal number (%) Turn on CSS animation and reveal just a percentage of each segment -
background string Segments' background color -
children ReactElement (svg) Elements rendered as children of SVG element (eg. SVG defs and gradient elements) -
radius number (user units) Radius of the pie (relative to viewBoxSize space) 50
center [number, number] x and y coordinates of center (relative to viewBoxSize space) [50, 50]
viewBoxSize [number, number] width and height of SVG viewBox attribute [100, 100]
onBlur (e, segmentIndex) => void onBlur event handler for each segment -
onClick (e, segmentIndex) => void onClick event handler for each segment -
onFocus (e, segmentIndex) => void onFocus event handler for each segment -
onKeyDown (e, segmentIndex) => void onKeyDown event handler for each segment -
onMouseOut (e, segmentIndex) => void onMouseOut event handler for each segment -
onMouseOver (e, segmentIndex) => void onMouseOver event handler for each segment -

Prop types are exposed for convenience:

import type { PieChartProps } from 'react-minimal-pie-chart';

About data prop

data prop expects an array of chart entries as follows:

type Data = {
  color: string;
  value: number;
  key?: string | number;
  title?: string | number;
  [key: string]: any;

Each entry accepts any custom property plus the following optional ones:

Custom labels with label render prop

label prop accepts a function returning the string, number or element rendered as label for each segment:

  label={(labelRenderProps: LabelRenderProps) =>
    number | string | React.ReactElement | undefined | null

The function receives labelRenderProps object as single argument:

type LabelRenderProps = {
  x: number;
  y: number;
  dx: number;
  dy: number;
  textAnchor: string;
  dataEntry: {[dataIndex]
    // entry relative to the label extended with:
    startAngle: number;
    degrees: number;
    percentage: number;
  dataIndex: number;
  style: React.CSSProperties;

Label prop, common scenarios

Render entries' values as labels:

label={({ dataEntry }) => dataEntry.value}

Render segment's percentage as labels:

label={({ dataEntry }) => `${Math.round(dataEntry.percentage)} %`}

See examples in the demo source.

How to

User interactions with the chart

See demo and relative source here and here.

Custom tooltip

See demo and relative source.

Browsers support

Here is an updated browsers support list πŸ”.

The main requirement of this library is an accurate rendering of SVG Stroke properties.

Please consider that Math.sign and Object.assign polyfills are required to support legacy browsers.


How svg arc paths work?

How SVG animations work?

This library uses the stroke-dasharray + stroke-dashoffset animation strategy described here.


  • Consider moving storybook deployment to CI
  • Consider using transform to mutate segments/labels positions
  • Consider abstracting React bindings to re-use business logic with other frameworks
  • Provide a way to supply svg element with any extra prop
  • Find a better solution to assign default props


Thanks to you all (emoji key):

Andrea Carraro

πŸ’» πŸ“– πŸš‡ ⚠️ πŸ‘€

Stephane Rufer

πŸ› πŸ’»

JΓΈrgen Aaberg


Tobiah Rex


Edward Xiao


David Konsumer

πŸ’» πŸ“– πŸ’‘ πŸ€”



Emmanouil Konstantinidis






Oscar Mendoza

πŸ› πŸ’»


πŸ› πŸ€”

Vianney Stroebel

πŸ› πŸ€”

Maxime Zielony

πŸ› πŸ’»

Raz Kedem




Jamie Talbot


Oscar Yixuan Chen




Roman Kushyn


Divjot Singh