UNPKG

@garvae/react-pie-donut-chart

Version:

Lightweight library allows you to create "pie" and "donut" charts easily

445 lines (436 loc) 12.6 kB
/* eslint-disable @typescript-eslint/naming-convention */ import { CSSProperties, ReactNode, RefObject, } from 'react'; /** * Chart container ref */ export type PieDonutChartPropRef = RefObject<HTMLElement>; /** * Chart size */ export type PieDonutChartPropSize = number ; /** * Chart data item type (chart segment) * @typedef { Object } DataItem * * The color of the chart segment. Must be CSS type 'color' * Default generated automatically * @property { string } color * @default undefined * * Order of segments in a chart * Default generated automatically * @property { number } order * @default undefined * * The unique ID of the chart segment * Default generated automatically * @property { string } segmentId * @default undefined * * REQUIRED. Segment value * @property { number } value */ export type DataItem = { color?: string; id?: string; order?: number; value: number; }; /** * Chart elements [class~] props * @typedef { Object } PieDonutChartPropsClassNames * * * --------------- Optional --------------- * * * Chart background className. * Background - svg element the same size as the chart, * and it is rendered if 'colorSegmentsBackground' property is provided * @property { string } chartBackground * @default undefined * * Center circle (donut hole) className * @property { string } chartCenter * @default undefined * * Chart segment className * @property { string } chartSegment * @default undefined * * Chart segment background className * @property { string } chartSegmentsBackground * @default undefined * * Chart children className * @property { string } children * @default undefined * * Chart segments group <g> element className * @property { string } svgGroupSegments * @default undefined * * Chart segments group <g> element className. * This background is another <g> element under the chart segments group <g> element * @property { string } svgGroupSegmentsBackground * @default undefined * * Chart text group <g> element className * @property { string } svgGroupText * @default undefined * * Chart text <foreignObject> element className. * <foreignObject> is something like element-wrapper for the text container * @property { string } svgObjectText * @default undefined * * Text <div> container className * @property { string } text * @default undefined * */ export type PieDonutChartPropsClassNames = { chartBackground?: string; chartCenter?: string; chartSegment?: string; chartSegmentsBackground?: string; children?: string; svgGroupSegments?: string; svgGroupSegmentsBackground?: string; svgGroupText?: string; svgObjectText?: string; text?: string; }; /** * Chart elements [color~] props * @typedef { Object } PieDonutChartPropsColors * * * --------------- Optional --------------- * * * Color of the chart background. * Background is svg element same size with chart. * Not renders if this param was not passed * @property { string } chartBackground * @default undefined * * Center circle (donut hole) color * @property { string } chartCenter * @default '#ffffff' * * Focused segments outline (stroke) color * @property { string } segmentFocusedOutline * @default '#287bc8' * * Background color of the chart segments background element. * "Segments background" is an svg element same size with chart. * > 1. Not renders if this param was not passed * > 2. This is not the segments background. This is background of element under all segments. * > Sounds complicated, I know... But it needed if you want to create a chart with gaps between segments * > and to color this space (gap) between segments. When the chart is "Pie" type this param works same like * > 'colorChartBackground' prop, but if chart is "Donut" type then current param will color * > only the circle under the segments but not the whole chart * @property { string } segmentsBackground * @default undefined * * The color of the text. * By default, it will be same color with selected segment (if any segment is selected) * or same color with the biggest value in the "data" array. * @property { string } text * @default undefined * */ export type PieDonutChartPropsColors = { chartBackground?: string; chartCenter?: string; segmentFocusedOutline?: string; segmentsBackground?: string; text?: string; }; /** * Type of chart props * @typedef { Object } PieDonutChartProps * * * --------------- REQUIRED --------------- * * * Chart data * REQUIRED. Chart data * @property { Array<DataItem> } data; * * Ref to the parent `HTMLElement` * REQUIRED if "size" was not provided, and not allowed if "size" was provided * @property { RefObject<HTMLElement> } parentRef; * * Chart size * REQUIRED if "parentRef" was not provided, and not allowed if "parentRef" was provided * @property { number } size; * * * --------------- Optional --------------- * * * The speed (in milliseconds) of the animation when the values of the chart element change * @property { number } animationSpeed * @default 200 * * The name of the chart center class. * The "chart center" is the svg element above the main chart. It's kind of like a text background. * "Chart center" will not be shown without "chartCenterSize" parameter. * > Don't use it if you just want to create a donut-type chart, * > it's better to pass the parameter "donutThickness" instead * @property { number } chartCenterSize * @default undefined * * "Children" to render in the center of the chart. * @property { ReactNode | string | number } children * @default undefined * * Main <SVG> className * @property { string } className * @default undefined * * Chart elements classNames * @property { PieDonutChartPropsClassNames } classNames * @default undefined * * Chart elements colors * @property { PieDonutChartPropsColors } colors * @default undefined * * Prevents unnecessary re-renders. * Debounce is disabled when 'resizeReRenderDebounceTime' = 0 * or when the value of the "size" property is set * @property { number } resizeReRenderDebounceTime * @default 50 * * The thickness of the donut segments. * You should pass this prop if you want to create a donut chart. * @property { number } donutThickness * @default undefined * * The font size. * By default, it calculates automatically to fit the size of the whole chart (outer radius) if the chart is "Pie" type. * If the chart is "Donut" type this param calculates automatically to fit the size of "donut hole" (inner radius). * @property { number } fontSize * @default undefined * * Gap between segments * @property { number } gap * @default undefined * * The ratio of the "scale" of the segment when it's hovered, selected or focused * @property { number } hoverScaleRatio * @default 1.05 * * Enables or disables "scale" of the segment when it's hovered, active or focused * @property { boolean } isScaleOnHover * @default true * * Enables or disables segment selection on click on it * @property { boolean } isSelectOnClick * @default true * * Enables or disables segment selection on "enter" key press on it * @property { boolean } isSelectOnKeyEnterDown * @default true * * Enables or disables the display of the value of the selected segment in the center of the chart * @property { boolean } isSelectedValueShownInCenter * @default true * * Chart maximum size. * @property { number } maxSize * @default undefined * * Chart minimum size * @property { number } minSize * @default undefined * * Your own styles for hovered, selected or focused segments * @property { CSSProperties } stylesHoveredSegment * @default undefined * * Callback for segment "onClick" event * @property { (segmentId: string) => void } onSegmentClick * @default undefined * * Callback for segment "onKeydown" event * > Fires only for the "enter" key * @property { (segmentId: string) => void } onSegmentKeyEnterDown * @default undefined * * Selected segment ID * > In most cases you don't need it. But if you want to control this state manually - welcome =) * @property { string } selected * @default undefined * * The width of the "outline" (stroke) of the focused segment. * By default, it automatically resizes based on chart size and has a ratio of 0.0066. * This means that this stroke width = <chart_size> * 0.0066 * @property { number } widthSegmentFocusedOutline * @default 4 * * Enables or disables chart navigation with a "tab". * Default - accessible - you can navigate the chart with the keyboard ("tab" button) * And in most cases there is no reason to change it. * @property { number } tabIndex * @default 0 * * Text to show in the center of the chart. * By default, it shows the total value of the provided "data" * or the value of the selected segment or the value of the focused segment * @property { string } text * @default undefined * */ export type PieDonutChartProps = { animationSpeed?: number; chartCenterSize?: number; children?: ReactNode | string | number; className?: string; classNames?: PieDonutChartPropsClassNames, colors?: PieDonutChartPropsColors, data: DataItem[]; donutThickness?: number; fontSize?: number; gap?: number; hoverScaleRatio?: number; isScaleOnHover?: boolean; isSelectOnClick?: boolean; isSelectOnKeyEnterDown?: boolean; isSelectedValueShownInCenter?: boolean; maxSize?: number; minSize?: number; onSegmentClick?: (segmentId: string) => void; onSegmentKeyEnterDown?: (segmentId: string) => void; resizeReRenderDebounceTime?: number; selected?: string; stylesHoveredSegment?: CSSProperties; tabIndex?: number; text?: string; widthSegmentFocusedOutline?: number; } & ( { parentRef?: never; size: PieDonutChartPropSize; } | { parentRef: PieDonutChartPropRef; size?: never; } ); /** * * This lightweight library allows you to create "pie" and "donut" charts easily. 100% Tests-covered * * The chart component has very flexible settings. It can accept a passed size * or automatically adjust to the size of the parent component. * Moreover, this component is accessible. * * More information about all props you can find in the repo: https://github.com/garvae/react-pie-donut-chart * * * Component accept props type of 'PieDonutChartProps'. * @component * @param { PieDonutChartProps } props * * You can import 'PieDonutChartProps' type if you need: * ```typescript jsx * import { PieDonutChartProps } from 'PieDonutChart'; * ``` * * Returns <svg> chart. * @returns {JSX.Element} * * * * @example - basic usage. More examples: https://github.com/garvae/react-pie-donut-chart * * ```typescript jsx * import PieDonutChart, { DataItem } from '@garvae/react-pie-donut-chart'; * import React from 'react'; * * const DATA: DataItem[] = [ * { * color: '#287BC8', * id: '001', * order: 1, * value: 10, * }, * { * color: '#D64045', * id: '002', * order: 2, * value: 40, * }, * { * color: '#daf6ec', * id: '003', * order: 3, * value: 30, * }, * { * color: '#9ED8DB', * id: '004', * order: 4, * value: 20, * }, * { * color: '#2B2D42', * id: '005', * order: 5, * value: 50, * }, * ]; * * // "Pie" type chart variant with "parentRef" prop (auto-resize) * const ChartPieAutoResize = () => { * const ref = React.useRef<HTMLDivElement>(null); * * return ( * <div * ref={ref} * style={{ height: '300px', width: '300px' }} * > * <PieDonutChart * data={DATA} * parentRef={ref} * /> * </div> * ); * }; * * // "Pie" type chart variant with "size" prop (no auto-resize) * const ChartPieWithFixedSize = () => { * return ( * <PieDonutChart * data={DATA} * size={300} * /> * ); * }; * * // "Donut" type chart variant with "size" prop (no auto-resize) * const ChartDonutWithFixedSize = () => { * return ( * <PieDonutChart * data={DATA} * gap={10} * size={300} * /> * ); * }; * ``` * * @author Garvae - https://github.com/garvae */ declare function PieDonutChart(props: PieDonutChartProps): JSX.Element; exports.PieDonutChart = PieDonutChart; export = PieDonutChart; /* eslint-enable @typescript-eslint/naming-convention */