Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/toomuchdesign/react-minimal-pie-chart
π° Lightweight but versatile SVG pie/donut charts for React. < 2kB gzipped.
https://github.com/toomuchdesign/react-minimal-pie-chart
pie-chart react-components recharts svg-path typescript
Last synced: about 10 hours ago
JSON representation
π° Lightweight but versatile SVG pie/donut charts for React. < 2kB gzipped.
- Host: GitHub
- URL: https://github.com/toomuchdesign/react-minimal-pie-chart
- Owner: toomuchdesign
- License: mit
- Created: 2017-03-13T11:35:57.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2024-04-06T19:23:50.000Z (7 months ago)
- Last Synced: 2024-04-14T19:52:12.765Z (7 months ago)
- Topics: pie-chart, react-components, recharts, svg-path, typescript
- Language: TypeScript
- Homepage: https://toomuchdesign.github.io/react-minimal-pie-chart/index.html
- Size: 4.84 MB
- Stars: 366
- Watchers: 4
- Forks: 79
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.md
Awesome Lists containing this project
- awesome-list - react-minimal-pie-chart
README
# React minimal pie chart
[![Build Status][ci-badge]][ci]
[![Npm version][npm-version-badge]][npm]
[![Coveralls][coveralls-badge]][coveralls]
[![Bundle size][bundlephobia-badge]][bundlephobia]Lightweight React **SVG pie charts**, with **versatile options** and **CSS animation** included. **~2kB** gzipped. [π Demo π][storybook].
## Why?
Because [Recharts][recharts-github] 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 (_v8.4.0_) | [![Bundle size: React minimal pie chart][bundlephobia-badge]][bundlephobia] | 1.93 KB | ~39 ms |
| [rechart][recharts-github] (_v1.8.5_) | [![Bundle size: Recharts][recharts-bundlephobia-badge]][recharts-bundlephobia] | 96.9 KB | ~1900 ms |
| [victory-pie][victory-pie-github] (_v34.1.3_) | [![Bundle size: Victory pie][victory-pie-bundlephobia-badge]][victory-pie-bundlephobia] | 50.5 KB | ~1100 ms |
| [react-apexcharts][react-apexcharts-github] (_v1.3.7_) | [![Bundle size: React apec charts][react-apexcharts-bundlephobia-badge]][react-apexcharts-bundlephobia] | 114.6 KB | ~2300 ms |
| [react-vis][react-vis-github] (_v1.11.7_) | [![Bundle size: React vis][react-vis-bundlephobia-badge]][react-vis-bundlephobia] | 78.3 KB | ~1600 ms |\* Benchmark carried out with [size-limit](https://github.com/ai/size-limit) with a "real-world" setup: see [benchmark repo](https://github.com/toomuchdesign/react-pie-charts-size). (What matter here are not absolute values but the relation between magnitudes)
## Features
- **< 2kB** gzipped
- Versatile: **Pie**, **Donut**, **Loading**, **Completion** charts (see [Demo][storybook])
- Customizable chart **labels** and **CSS animations**
- Written in **Typescript**
- No dependencies## Installation
```console
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
```js
import { PieChart } from 'react-minimal-pie-chart';;
```## Options
| Property | Type | Description | Default |
| --------------------- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| [**data**][data-props-docs] | `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][svg-css])*. | - |
| **segmentsTabIndex** | `number` | [`tabindex` attribute](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/tabindex) assigned to segments | - |
| [**label**][label-props-docs] | `(labelRenderProps) => string \| number \| ReactElement` | A function returning a label value or the [SVG element][svg-elements] 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][svg-css])*. | - |
| **animate** | `boolean` | Animate segments on component mount | - |
| **animationDuration** | `number` | Animation duration in ms | 500 |
| **animationEasing** | `string` | A [CSS easing function](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-timing-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][svg-elements] (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:
```ts
import type { PieChartProps } from 'react-minimal-pie-chart';
```### About `data` prop
`data` prop expects an array of chart entries as follows:
```typescript
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**:
- **`key`**: custom value to be used as [segments element keys](https://reactjs.org/docs/lists-and-keys.html)
- **`title`**: [`title` element](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title) rendered as segment's child
### Custom labels with `label` render prop
`label` prop accepts a function returning the **string, number or element** rendered as label for each segment:
```js
number | string | React.ReactElement | undefined | null
}
/>
```The function receives `labelRenderProps` object as single **argument**:
```typescript
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:
```js
label={({ dataEntry }) => dataEntry.value}
```Render segment's percentage as labels:
```js
label={({ dataEntry }) => `${Math.round(dataEntry.percentage)} %`}
```See examples in the [demo source](https://github.com/toomuchdesign/react-minimal-pie-chart/blob/v8.2.0/stories/index.tsx#L81).
## How to
### User interactions with the chart
See [demo](https://toomuchdesign.github.io/react-minimal-pie-chart/index.html?path=/story/example-interaction--click-mouseover-mouseout-callbacks) and relative source [here](https://github.com/toomuchdesign/react-minimal-pie-chart/blob/v8.0.0/stories/InteractionStory.tsx) and [here](https://github.com/toomuchdesign/react-minimal-pie-chart/blob/v8.0.0/stories/InteractionTabStory.tsx).
### Custom tooltip
See [demo](https://toomuchdesign.github.io/react-minimal-pie-chart/index.html?path=/story/example-misc--tooltip-integration) and [relative source](https://github.com/toomuchdesign/react-minimal-pie-chart/blob/master/stories/components/Tooltip.tsx).
## Browsers support
Here is an updated [browsers support list π](https://github.com/toomuchdesign/react-minimal-pie-chart/issues/129).
The main requirement of this library is an accurate rendering of [SVG Stroke properties](https://www.w3schools.com/graphics/svg_stroking.asp).
Please consider that [`Math.sign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign) and [`Object.assign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) polyfills are required to support legacy browsers.
## Misc
### How svg arc paths work?
- http://xahlee.info/js/svg_circle_arc.html
- https://codepen.io/lingtalfi/pen/yaLWJG### How SVG animations work?
This library uses the `stroke-dasharray` + `stroke-dashoffset` animation strategy [described here](https://css-tricks.com/svg-line-animation-works/).
## 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](https://github.com/kentcdodds/all-contributors#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
π»
[ci-badge]: https://github.com/toomuchdesign/react-minimal-pie-chart/actions/workflows/ci.yml/badge.svg
[ci]: https://github.com/toomuchdesign/react-minimal-pie-chart/actions/workflows/ci.yml
[coveralls-badge]: https://coveralls.io/repos/github/toomuchdesign/react-minimal-pie-chart/badge.svg?branch=master
[coveralls]: https://coveralls.io/github/toomuchdesign/react-minimal-pie-chart?branch=master
[npm]: https://www.npmjs.com/package/react-minimal-pie-chart
[npm-version-badge]: https://img.shields.io/npm/v/react-minimal-pie-chart.svg
[bundlephobia-badge]: https://badgen.net/bundlephobia/minzip/react-minimal-pie-chart
[bundlephobia]: https://bundlephobia.com/result?p=react-minimal-pie-chart
[recharts-bundlephobia-badge]: https://badgen.net/bundlephobia/minzip/recharts
[recharts-bundlephobia]: https://bundlephobia.com/result?p=recharts
[recharts-github]: https://github.com/recharts/recharts
[victory-pie-bundlephobia-badge]: https://badgen.net/bundlephobia/minzip/victory-pie
[victory-pie-bundlephobia]: https://bundlephobia.com/result?p=victory-pie
[victory-pie-github]: https://github.com/FormidableLabs/victory
[react-apexcharts-bundlephobia-badge]: https://badgen.net/bundlephobia/minzip/apexcharts
[react-apexcharts-bundlephobia]: https://bundlephobia.com/result?p=apexcharts
[react-apexcharts-github]: https://github.com/apexcharts/apexcharts.js
[react-vis-bundlephobia-badge]: https://badgen.net/bundlephobia/minzip/react-vis
[react-vis-bundlephobia]: https://bundlephobia.com/result?p=react-vis
[react-vis-github]: https://github.com/uber/react-vis
[storybook]: https://toomuchdesign.github.io/react-minimal-pie-chart/index.html
[data-props-docs]: #about-data-prop
[label-props-docs]: #custom-labels-with-label-render-prop
[svg-elements]: https://developer.mozilla.org/en-US/docs/Web/SVG/Element
[svg-css]: https://css-tricks.com/svg-properties-and-css/#aa-properties-shared-between-css-and-svg