React minimal pie chart
Lightweight React SVG pie charts, with versatile options and CSS animation included. < 3kB gzipped. 👏Demo 👏.
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' },
]}
/>;
Why?
Because Recharts is awesome, but when you just need a simple pie/donought chart, 3kB are usually enough.
| Size by Bundlefobia | Benchmark Size * | Loading time on a slow 3g * |
---|
react-minimal-pie-chart v7.0.0 | | 2.3 KB | 46 ms |
rechart v1.8.5 | | 92.6 KB | 1900 ms |
victory-pie v34 | | 50.5 KB | 1100 ms |
* Benchmark carried out with size-limit with a "real-world" setup: see benchmark repo.
Note: what matter here are not absolute values but the relation between magnitudes.
Features
- < 3kB gzipped
- Versatile: Pie, Donut, Loading, Completion charts (see Demo)
- Customizable chart labels
- Customizable CSS animations
- Typescript types included
- No dependencies (except for React's prop-types)
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
Options
Property | Type | Description | Default |
---|
data (required) | Array | Source data which each element is a segment | - |
lineWidth | Number (%) | Line width of each segment. Percentage of chart's radio (100 === full pie) | 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 | Bool | Round line caps of each segment | false |
segmentsStyle | Object | Style object assigned to each segment | - |
segmentsTabIndex | Number | tabindex attribute assigned to segments | - |
label | Boolean, ReactElement, Function | If true set, labels will be drawn automatically. If ReactElement set, the option can be the custom label element. If set a function , the function will be called to render customized label | false |
labelPosition | Number (%) | Label position from origin. Percentage of chart's radio (50 === middle point) | 50 |
labelStyle | Object | Style object assigned to each label | - |
animate | Bool | Animate segments on component mount | false |
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 | - |
injectSvg | Function | Inject <svg> element with the output of the provided function (eg. gradients) | - |
radius | Number (%) | Radius of the pie. Percentage of component's width | 50 |
cx | Number (%) | x-coordinate of center. Percentage of component's width | 50 |
cy | Number (%) | y-coordinate of center. Percentage of component's height | 50 |
viewBoxSize | Array of Numbers | Width and Height of SVG viewBox attribute | [100, 100] |
onBlur | Function | onBlur event handler for each segment: (event, data, dataIndex) => void | - |
onClick | Function | onClick event handler for each segment: (event, data, dataIndex) => void | - |
onFocus | Function | onFocus event handler for each segment: (event, data, dataIndex) => void | - |
onKeyDown | Function | onKeyDown event handler for each segment: (event, data, dataIndex) => void | - |
onMouseOut | Function | onMouseOut event handler for each segment: (event, data, dataIndex) => void | - |
onMouseOver | Function | onMouseOver event handler for each segment: (event, data, dataIndex) => void | - |
About props.data
props.data
expects the following array of entries:
type dataProps = {
value: number;
color: string;
title?: string | number;
key?: string | number;
style?: { [key: string]: string | number };
}[];
Each data entry optionally accepts:
- a
key
property just in case items' indexes weren't enough - a
style
property targeting the corresponding chart segment
Custom labels with label
prop
When label
is a function or ReactElement, the provided entity will be called with the following labelProps
object respectively as argument or as props:
type labelProps = {
key: string;
x: number;
y: number;
dx: number;
dy: number;
textAnchor: string;
data: {
degrees: number;
startOffset: number;
percentage: number;
}[];
dataIndex: number;
color: string;
style: { [key: string]: string | number };
};
label
as function
The provided function is called with labelProps
as argument and is supposed to return the string, number or element rendered as label content.
<PieChart label={(labelProps: labelProps) => string | number | ReactElement} />
label
as React element
The provided React element will get labelProps
object as props
.
<PieChart label={<CustomLabel />} />
See some examples in the demo source.
How to
User interactions with the chart
See demo and its source.
Browsers support
The main requirement of this library is an accurate rendering of SVG Stroke properties.
Here is an updated browsers support list 🔍.
Please consider that a Math.sign
polyfill is needed 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
- Configure Babel to not inject the
_extend
utility in compiled artifact - Add
.browserslistrc
to get rid of some Babel helpers - Handle prop-types / TS types duplication
Contributors
Thanks to you all (emoji key):