Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

react-minimal-pie-chart

toomuchdesign375kMIT9.1.0TypeScript support: included

Lightweight but versatile SVG pie/donut charts for React

react, pie, donough, arc, chart, typescript

readme

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

Why?

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

| | Size
by Bundlefobia | Benchmark Size * | Loading time
on a slow 3g * | | :----------------------------------------------------: | :-----------------------------------------------------------------------------------------------------: | :---------------: | :-----------------------------: | | react-minimal-pie-chart (v9.0.0) | Bundle size: React minimal pie chart | 1.99 KB | ~40 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)

Features

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

Installation

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.

https://unpkg.com/react-minimal-pie-chart/dist/index.js

Minimum supported Typescript version: >= 3.8

Usage

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

<PieChart
  data={[
    { title: 'One', value: 10, color: '#E38627' },
    { title: 'Two', value: 15, color: '#C13C37' },
    { title: 'Three', value: 20, color: '#6A2135' },
  ]}
/>;

Options

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
or:
(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
or:
(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
or:
(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 -
| .oOo.oOo.oOo.oOo.oOo.oOo.oOo. |

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:

<PieChart
  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: {
    ...props.data[dataIndex]
    // props.data 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.

Misc

How svg arc paths work?

How SVG animations work?

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

Todo's

  • 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

Contributors

Thanks to you all (emoji key):


Andrea Carraro

💻 📖 🚇 ⚠️ 👀

Stephane Rufer

🐛 💻

Jørgen Aaberg

💻

Tobiah Rex

🐛

Edward Xiao

🐛

David Konsumer

💻 📖 💡 🤔

Ori

🤔

Emmanouil Konstantinidis

🐛

yuruc

💻

luca-esse

🐛

Oscar Mendoza

🐛 💻

damien-git

🐛 🤔

Vianney Stroebel

🐛 🤔

Maxime Zielony

🐛 💻

Raz Kedem

🐛

Blocksmith

🐛

Jamie Talbot

🐛

Oscar Yixuan Chen

🐛

RuiRocha1991

🐛

Roman Kushyn

🐛

Divjot Singh

💻

changelog

react-minimal-pie-chart

9.1.0

Minor Changes

  • a0ce709: Support react v19

9.0.0

Major Changes

  • 3bfb426: UMD export removed
  • 3bfb426: Package compiled in ES6. Consuming JS engines should be able to interpret features like arrow functions and const.
  • 3bfb426: svg-partial-circle unbundled and imported via plain import

8.4.1

Patch Changes

  • d1887ba: Move @types/svg-path-parser to dev dependencies

8.4.0

Minor Changes

  • Improve labelRenderProps by using TS generics
  • Expose chart PieChartProps types
  • Rely on useEffect only to trigger initial animation

8.3.0

Minor Changes

  • Support React 18

8.2.0

Minor Changes

  • Decrease bundle size of about 2%

8.1.0

Minor Changes

  • Widen peerDependencies to include React 17

8.0.1

Patch Changes

  • Change extractPercentage implementation to address a rounding issue in stroke-dashoffset evaluation (#133)

8.0.0

Major Changes

  • Chart component exposed as named export instead of default.
  • Minimum react and react-dom peerDependency versions increased to ^16.8.0
  • Minimum typescript version increased to ^3.8.0 (due to import type)
  • label prop works as render prop; drop support for boolean and Element values
  • segmentsShift prop expressed as absolute viewBox units instead of radius' percentage
  • Event handlers signature updated to: (event, segmentIndex) => void
  • rx and ry props replaced by center array prop
  • center and radius props expressed as absolute viewBox units instead of percentage of it
  • prop-types dependency and static PropTypes declarations dropped
  • Dropped support for `data[].style property
  • Replaced extendedData startOffset prop with startAngle
  • injectSVG dropped in favour of native children prop
  • requestAnimationFrame existence check removed
  • Removed Object.assign polyfill

Minor Changes

  • Gzipped size reduced from 2.6kb to 1.9 kb (-27%)
  • segmentsStyle and labelStyle accept both value or function

Patch Changes

  • Default labels vertically aligned with dominant-baseline: central (#149)

How to migrate to version 8.0.0

  • Update import declaration to: import {PieChart} from 'react-minimal-pie-chart'
  • Make sure that installed react and react-dom version is >= 16.8.0
  • In case typescript is used, ensure that installed version is >= 3.8
  • Migrate label prop to provide a render function (see docs about labels)
  • Replace existing rx ry props with center
  • Review existing center and segmentsShift values (now expressed as viewBox values)
  • Update onBlur, onClick, onFocus, onKeyDown, onMouseOut, onMouseOver, segmentsShift function props to new signatures
  • Move existing injectSVG prop return value to children prop
  • Use segmentsStyle as function instead of data[].style prop
  • Mind that the root element is now the SVG itself
  • Provide an Object.assign polyfill to support legacy browser (eg. IE)

7.3.1

Patch Changes

  • Fix event handler types expecting wrong event as first argument
  • Fix label prop type declaration when receiving a function (#154)
  • Fix wrong label position when segmentsShift enabled (#155)

7.3.0

Minor Changes

  • Allow segmentsShift as function to return undefined

Minor Changes

  • Improve sumValues performance

7.2.0

Minor Changes

  • Add segmentsShift prop to move segments radially and render exploded charts

7.1.1

Patch Changes

  • Fix regression introduced in 7.1.0 consisting of reveal prop being stuck after initial animation

7.1.0

Minor Changes

  • Add onBlur, onFocus, onKeyDown callbacks
  • Add segmentsTabIndex to append a tabindex prop to segment paths

Patch Changes

  • Fix regression bug consisting of stroke-dasharray and stroke-dashoffset attributes being evaluated and appended even when there is no animation

7.0.0

Warning

This release introduced a regression bug. Please upgrade to V7.1.0

Major Changes

  • Remove src from distribution
  • EventHandler expects void as return type

Minor Changes

  • Introduce Typescript natively
  • Remove prop-types from private components

6.0.1

Patch Changes

  • Fix chart cy being evaluated from viewBoxSize width instead of height

6.0.0

Major Changes

  • ratio property removed in favour of viewBoxSize

5.0.2

Patch Changes

  • fix NaN being rendered as SVG path attribute when data.value sum equals 0 and totalValue is undefined

5.0.1

Patch Changes

  • fix reveal direction with negative lengthAngle

5.0.0

Major Changes

  • reveal works same direction as lengthAngle
  • Labels vertically aligned using dominant-baseline instead of alignment-baseline

4.2.0

Minor Changes

  • Add background prop to draw segment's background

Patch Changes

  • Fix props.data types

4.1.1

Patch Changes

  • Transpile bundled svg-partial-circle

4.1.0

Minor Changes

  • Provide custom segment style via props.data[i].style

4.0.0

Major Changes

  • ReactMinimalPieChart extends React.Component instead of React.PureComponent
  • Improve paddingAngle implementation to respect the proportions between rendered slices
  • Add TypeScript types

Minor Changes

  • Compile with Babel v7
  • Update Storybook demo to v5
  • Add sideEffect flag

Patch Changes

  • Replace export { default } from syntax not supported by TS

3.5.0

  • Add support for labels with props: label, labelPosition and labelStyle
  • Minor internal refactoring

3.4.1

  • Fix chart to render data.title value as <title> inside <path> element

3.4.0

  • Support injectSvg function property to inject any element into rendered <svg> element

3.3.0

  • Support data.title property to render <title> inside <path> element

3.2.0

  • Add UMD export

3.1.0

  • Add segments interaction callbacks: onClick, onMouseOver, onMouseOut
  • Add segmentsStyle prop
  • Setup up Prettier

3.0.2

  • Prevent initial animation when component is unmounted

3.0.1

  • Update react/react-dom peer dependency version to accept versions 15 and 16

3.0.0

  • Make SVG element display: block to remove undesired spacing

2.0.0

  • Compile with Rollup.js to bundle with a transpiled version of svg-partial-circle v0.2.0

1.1.0

  • Migrate React's prop types to external prop-types package
  • Swap react-addons-test-utils with react-test-renderer as enzyme required dependencies

1.0.0

  • Enable negative lengthAngle to configure clockwise and counterclockwise charts
  • Add rx and ry props to set custom chart center coordinates
  • Add ratio prop
  • Add radius prop
  • Re-evaluate segments size when paddingAngle is > 0
  • Make counterclockwise charts by default
  • Make <ReactMinimalPieChart> a pure component
  • Add eslint parsing

0.0.2

  • Incorporate svg-partial-circle lib

0.0.1

  • Fix bad imports

0.0.0

  • Initial release