react-native-horizontal-bar-graphs v1.0.0
react-native-horizontal-bar-graphs
Index
Introduction
react-native-horizontal-bar-graphs allows you to easily draw horizontal bar graphs.
In a mobile environment, vertical bar graphs have many space limitations.
The bars are arranged horizontally to make it mobile-friendly.
react-native-horizontal-bar-graphs provides two types of graphs.
For both graphs, you can draw the graph by passing only 1 or 2 required props.
You can also customize it by passing other additional(optional) props.
react-native-horizontal-bar-graphs는 가로 형태의 막대 그래프를 쉽게 그릴 수 있도록 합니다.
모바일 환경에서 세로형태의 막대 그래프는 공간의 제약이 많습니다.막대를 가로로 배치하여 모바일 환경에 적합하도록 구성했습니다.
react-native-horizontal-bar-graphs는 2가지의 그래프를 제공합니다.
2가지 그래프 모두 1개 또는 2개의 필수 props만 전달하면 그래프를 그릴 수 있습니다.
또한 다른 부가적인 props를 전달하여 커스터마이즈할 수 있습니다.
1. BarGraph
It is a typical bar graph.
One data is rendered as one bar.
Each bar can display a label, value, or percentage.
You should pass 1 required prop.
2. StackedBar
Data is stacked and rendered in one bar.
Information about each data is displayed as a list at the bottom of the bar.
You should pass 2 required props.
Installation
No dependencies. Just install it
npm install react-native-horizontal-bar-graphsor if you use yarn
yarn add react-native-horizontal-bar-graphsHow to use
import {BarGraph, IBarGraphData, StackedBar} from 'react-native-horizontal-bar-graphs';
const BAR_DATA: IBarGraphData[] = [
{
value: 10,
label: 'Label 0',
onPress: (label, value, color) => {
// your onPresss
},
},
{
value: 9,
label: 'Label 1',
},
{
value: 16,
label: 'Label 2',
}
];
// in your component
<BarGraph
graphData={BAR_DATA}
// optional props...
/>
<StackedBar
graphData={BAR_DATA}
totalCnt={100}
// optional props...
/>Props
IBarGraphData
Basic data of graphs.
Used in both <BarGraph/> and <StackedBar/>
| prop | Required | Type | Default | Description |
|---|---|---|---|---|
| label | O | string | Label(name) of data | |
| value | O | number | Number of data | |
| color | X | ColorValue | "coral","cornflowerblue","crimson", "darkcyan", "dodgerblue", "orangered", "forestgreen", "goldenrod", "yellowgreen", "darkviolet" | Color to be rendered to Bar.If you do not specify a color, the colors in DEFAULT_COLORS will be applied in a cycle. (modular operation)NOTE: DEFAULT_COLORS were selected from the Named colors of React Native |
| onPress | X | function(label: string, value: number, color: ColorValue) => void \| Promise<void> | A function that runs when the user touches the bar. label, value, and color are provided as parameters.NOTE: In BarGraph it is triggered when the bar is touchedNOTE: In StackedBar it is triggered when an item in the list is touched.NOTE: BarGraph에서는 막대를 터치할때 트리거됩니다.NOTE: StackedBar에서는 리스트의 아이템을 터치할때 트리거됩니다. |
BarGraph
only 1 required prop
| prop | Required | Type | Default | Description |
| --- | :---: | --- | --- | --- |
| graphData | O | IBarGraphData | | Data to be rendereddetails |
| style | X | StyleProp<ViewStyle> | | Styles for graph containers |
| title | X | string | | Title of graphNOTE: If title is undefined or an empty string (""), it will not be rendered. |
| titlePosition | X | "top" \| "bottom" | "top" | Position of the title |
| titleStyle | X | StyleProp<TextStyle> | {fontWeight: "bold", fontSize: 20, textAlign: "center", marginVertical: 16} | Styles for title |
| barHeight | X | number | 28 | Height of each bar |
| barHolderColor | X | ColorValue | "#EEEEEE" | Placeholder color for bars |
| barDistance | X | number | 12 | Distance between barsNOTE: excluding the first barbarDistance (BarGraph only) |
| barAnimated | X | boolean | true | Whether to animate the bar |
| barAnimateDelay | X | number | 60 | Delay time (ms) at which the animation of the bars begins막대들의 애니메이션이 시작되는 지연 시간 (ms) |
| barLeftStyle | X | "rounded" \| "square" | "rounded" | Left style of bar (both colored and holder).barLeftStyle |
| barRightStyle | X | "rounded" \| "square" | "rounded" | Right style of colored bar.barRightStyle |
| barHolderRightStyle | X | "rounded" \| "square" | "rounded" | Right style of placeholder of bar.barHolderRightStyle |
| showLabel | X | boolean | true | Whether to show each label of graphData |
| labelPosition | X | "top" \| "bottom" | "top" | Position of each label relative to the bar막대를 기준으로 각 label의 포지션 |
| labelStlye | X | StyleProp<TextStyle> | { color: "#999999", fontSize: barHeight / 2 } | Styles for labelNOTE: By default, fontSize is set to barHeight/2.NOTE: When you touch the bar, the text color is highlighted in the same color as the bar. If you don't want it, set enableTouchHighlight to false. |
| showValue | X | boolean | true | Whether to show the value above the bar |
| valuePosition | X | "left" \| "right" | "right" | Position on the bar where the value is renderedvaluePosition (BarGraph only) |
| valueSuffixCnt | X | number | 1000 | Number to attach suffix when value exceeds valueSuffixCntvalueSuffixCnt |
| valueSuffixList | X | string[] | ["k", "m", "b", "t"] | List of suffix attached to value after dividing value by valueSuffixCntvalueSuffixList |
| showDivider | X | boolean | true | Whether to display a divider at certain percentages in the bar's placeholder |
| dividerInterver | X | 4 \| 5 \| 10 \| 20 \| 25 \| 33.3 \| 50 | 20 | A number for what percentage of intervals the dividing lines are rendered.e.g. If set to 20, dividers will be rendered at 20%, 40%, 60%, and 80%.divider가 몇%마다 표시될지 |
| dividerHeight | X | string \| number | "60%" | Height of dividerWhen set to "100%", it is equal to the height of the bar |
| dividerColor | X | ColorValue | "#BBBBBB" | Color of divider |
| dividerWidth | X | number | 1 | Width of each divider |
| percentPosition | X | "left" \| "right" \| "none" | "right" | Position where the percentage corresponding to value is displayed.NOTE: If it is undefined or "none", it is not rendered. |
| percentFixed | X | 0 \| 1 \| 2 | 0 | A number representing the decimal place of a percentage to be rendered.e.g.1 Rendered to 50% when set to 0e.g.2 Rendered to 50.0% when set to 1e.g.3 Rendered to 50.00% when set to 2NOTE: this prop is ignored when PercentLabelComponent is passed퍼센트의 소수점 몇번째 자리까지 표시할지 |
| PercentLabelComponent | X | ({ value, total, color }: { value: number; total: number, color: ColorValue \| undefined }) => ReactElement \| null \| undefined | | A React Component to display percentages.PercentLabelComponent |
| enableTouchHighlight | X | boolean | true | Whether to enable color highlighting when a bar or list item is touched.enableTouchHighlight |
StackedBar
2 required props. Shares many items with props from BarGraph
| prop | Required | Type | Default | Description |
|---|---|---|---|---|
| graphData | O | IBarGraphData | Data to be rendereddetails | |
| totalCnt | O | number | Total number of data.Used as denominator when calculating percentages.데이터의 전체 갯수.퍼센트를 계산할 때 분모로 사용됨. | |
| style | X | StyleProp<ViewStyle> | Styles for graph containers | |
| title | X | string | Title of graphNOTE: If title is undefined or an empty string (""), it will not be rendered. | |
| titlePosition | X | "top" \| "bottom" | "top" | Position of the title |
| titleStyle | X | StyleProp<TextStyle> | {fontWeight: "bold", fontSize: 20, textAlign: "center", marginVertical: 16} | Styles for title |
| barHeight | X | number | 28 | Height of each bar |
| barHolderColor | X | ColorValue | "#EEEEEE" | Placeholder color for bars |
| barAnimated | X | boolean | true | Whether to animate the bar |
| barLeftStyle | X | "rounded" \| "square" | "rounded" | Left style of bar (both colored and holder).barLeftStyle |
| barRightStyle | X | "rounded" \| "square" | "rounded" | Right style of colored bar.barRightStyle |
| barHolderRightStyle | X | "rounded" \| "square" | "rounded" | Right style of placeholder of bar.barHolderRightStyle |
| showDivider | X | boolean | true | Whether to display a divider at certain percentages in the bar's placeholder |
| dividerInterver | X | 4 \| 5 \| 10 \| 20 \| 25 \| 33.3 \| 50 | 20 | A number for what percentage of intervals the dividing lines are renderede.g. If set to 20, dividers will be rendered at 20%, 40%, 60%, and 80%.divider가 몇%마다 표시될지 |
| dividerHeight | X | string \| number | "60%" | Height of dividerWhen set to "100%", it is equal to the height of the bar |
| dividerColor | X | ColorValue | "#BBBBBB" | Color of divider |
| dividerWidth | X | number | 1 | Width of each divider |
| percentPosition | X | "left" \| "right" \| "none" | "right" | Position where the percentage corresponding to value is displayed.NOTE: If it is undefined or "none", it is not rendered. |
| percentFixed | X | 0 \| 1 \| 2 | 0 | A number representing the decimal place of a percentage to be rendered.e.g.1 Rendered to 50% when set to 0e.g.2 Rendered to 50.0% when set to 1e.g.3 Rendered to 50.00% when set to 2NOTE: this prop is ignored when PercentLabelComponent is passed퍼센트의 소수점 몇번째 자리까지 표시할지 |
| PercentLabelComponent | X | ({ value, total, color }: { value: number; total: number, color: ColorValue \| undefined }) => ReactElement \| null \| undefined | A React Component to display percentages.PercentLabelComponent | |
| enableTouchHighlight | X | boolean | true | Whether to enable color highlighting when a bar or list item is touched.enableTouchHighlight |
| showList | X | boolean | true | Whether to render a list of graphData |
| listAnimated | X | boolean | true | Whether to run animations when the list is displayed |
| listContainerStyle | X | StyleProp<ViewStyle> | Style of list container | |
| ListItemComponent | X | (props: IStackedCustomListItemProps) => ReactElement | A React Component that renders custom list items.ListItemComponent (StackedBar Only) |
Demo
barLeftStyle, barRightStyle, barHolderRightStyle
Rounded - Default
| BarGraph | StackedBar |
| :--: | :--: |
| |
|
<BarGraph // same as StackedBar
graphData={BAR_DATA}
barLeftStyle="rounded"
barRightStyle="rounded"
barHolderRightStyle="rounded"
// other props...
/>Square
| BarGraph | StackedBar |
| :--: | :--: |
| |
|
<BarGraph // same as StackedBar
graphData={BAR_DATA}
barLeftStyle="square"
barRightStyle="square"
barHolderRightStyle="square"
// other props...
/>Mixed style 1
| BarGraph | StackedBar |
| :--: | :--: |
| |
|
<BarGraph // same as StackedBar
graphData={BAR_DATA}
barLeftStyle="rounded"
barRightStyle="square"
barHolderRightStyle="rounded"
// other props...
/>Mixed style 2
| BarGraph | StackedBar |
| :--: | :--: |
| |
|
<BarGraph // same as StackedBar
graphData={BAR_DATA}
barLeftStyle="square"
barRightStyle="rounded"
barHolderRightStyle="rounded"
// other props...
/>PercentLabelComponent
recommend using fixed-width styles.value, total, and color are provided to calculate the percentage.
NOTE: Color may be passed undefined.
NOTE: Only the PercentLabelComponent that will be rendered
on the right or left sides of the StackedBar has an undefined color.
NOTE: The color of BarGraph.PercentLabelComponent is not undefined
NOTE: color는
undefined로 전달될 수 있습니다.
NOTE:StackedBar의오른쪽이나 왼쪽에 렌더될PercentLabelComponent만 color가undefined입니다.
NOTE:BarGraph.PercentLabelComponent의 color는undefined가 아닙니다
| BarGraph | StackedBar |
|---|---|
| default | default |
| custom | custom |
<BarGraph // same as StackedBar
graphData={BAR_DATA}
style={[styles.graphContainer]}
PercentLabelComponent={({value, total, color}) => {
return (
<Text
style={{
width: 70, // recommended to use `fixed width styles`
fontSize: 16,
textAlign: 'right',
fontWeight: 'bold',
color: color,
fontStyle: 'italic',
textDecorationLine: 'underline',
}}>
{((value / total) * 100).toFixed(1) + '%'}
</Text>
);
}}
/>enableTouchHighlight
If you don't want this effect, set enableTouchHighlight to false.
(default is true)
| BarGraph | StackedBar |
|---|---|
barDistance (BarGraph only)
| Default | barDistance={24} |
|---|---|
<BarGraph
graphData={BAR_DATA}
barDistance={24} // default : 12
// other props...
/>valuePosition (BarGraph only)
| Default | valuePosition="left" |
|---|---|
<BarGraph
graphData={BAR_DATA}
style={[styles.graphContainer]}
valuePosition="left" // default: "right"
// other props...
/>valueSuffixCnt & valueSuffixList (BarGraph only)
valueSuffixCnt & valueSuffixList are used for simplicity depending on the digits.
Suppose the valueSuffixCnt is 1000, and the valueSuffixList is ["k", "m", "b", "t"].
e.g.1. The number 1234 is expressed as "1.2k". (up to the first decimal place)
e.g.2. The number 20000000 is expressed by "20m".
NOTE: valueSuffixCnt <= 0 means No Suffix.
e.g.1. The number 1234 is expressed as "1,234".
e.g.2. The number 20000000 is expressed by "20,000,000".
ListItemComponent (StackedBar Only)
If you want to use your own custom list items, use this ListItemComponent.
For performance, I strongly recommend wrapping your custom component with React.memo()
| Default | Custom ListItem | Custom ListItem |
| :--: | :--: | :--: |
| |
|
|
| defalut PercentLabelComponent | defalut PercentLabelComponent | custom PercentLabelComponent |
The following props of ListItemComponent are passed:
export interface IStackedCustomListItemProps {
readonly label: string;
readonly value: number;
readonly color: ColorValue;
readonly index: number;
readonly totalCnt: number;
readonly onTouching: (index: number, isTouched: boolean) => void;
readonly PercentLabelComponent: PercentLabelComp;
}onTouching
If you want to use the same color highlight effect as when using
enableTouchHighlight,
implement onPressIn() and onPressOut() of your TouchableComponents
(such as TouchableOpacity or TouchableHighlight) using props.onTouching() as follows:
<TouchableOpacity
// To use `TouchHighlight`, implement `onPressIn` and `onPressOut` as follows:
onPressIn={() => props.onTouching(props.index, true)}
onPressOut={() => props.onTouching(props.index, false)}
onPress={() => {}}>
{...}
</TouchableOpacity>PercentLabelComponent
If you passed your PercentLabelComponent as the props of StackedBar,
the same(your) PercentLabelComponent will be passed as the props of ListItemComponent.
If you did NOT pass a PercentLabelComponent as the props of StackedBar,
the default PercentLabelComponent will be passed as the props of ListItemComponent.
Full sample code of using ListItemComponent
const _ListItem = useCallback<StackedCustomListItem>(
(listProps: IStackedCustomListItemProps) => {
const {
onTouching,
index,
label,
totalCnt,
value,
color,
PercentLabelComponent,
} = listProps;
return (
<TouchableOpacity
// To use `TouchHighlight`, implement `onPressIn` and `onPressOut` as follows:
onPressIn={() => onTouching(index, true)}
onPressOut={() => onTouching(index, false)}
onPress={() => {}}>
<View
style={{
marginVertical: 8,
flexDirection: 'row',
alignItems: 'baseline',
justifyContent: 'space-between',
}}>
<Text style={{fontSize: 18, fontWeight: 'bold', color: color}}>
{label}
</Text>
<View
style={{
width: 70,
flexDirection: 'row',
alignItems: 'baseline',
justifyContent: 'flex-end',
}}>
<Text style={{fontSize: 16, fontWeight: 'bold'}}>{value}</Text>
<Text style={{fontSize: 12}}>{' / ' + totalCnt}</Text>
</View>
<PercentLabelComponent
value={value}
total={totalCnt}
color={color}
/>
</View>
</TouchableOpacity>
);
},
[],
);
// For performance,
// I strongly recommend wrapping your custom component with React.memo()
const ListItem = React.memo(_ListItem);
return (
// return statement in your components
// or return statement of render() in your components
// ...
<StackedBar
graphData={BAR_DATA}
totalCnt={dataTotalCnt + 30}
style={styles.graphContainer}
title="This is Title"
PercentLabelComponent={({value, total, color}) => {
return (
<Text
style={{
width: 70,
fontSize: 16,
textAlign: 'right',
fontWeight: 'bold',
color: color,
fontStyle: 'italic',
textDecorationLine: 'underline',
}}>
{((value / total) * 100).toFixed(1) + '%'}
</Text>
);
}}
listContainerStyle={{marginTop: 16}}
ListItemComponent={ListItem}
/>
);License
MIT license