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를 전달하여 커스터마이즈할 수 있습니다.
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.
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.
No dependencies. Just install it
npm install react-native-horizontal-bar-graphs
or if you use yarn
yarn add react-native-horizontal-bar-graphs
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...
/>
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에서는 리스트의 아이템을 터치할때 트리거됩니다. |
only 1 required prop
prop | Required | Type | Default | Description |
---|---|---|---|---|
graphData | O | IBarGraphData |
Data to be rendered details |
|
style | X | StyleProp<ViewStyle> |
Styles for graph containers | |
title | X | string |
Title of graph NOTE: 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 bars NOTE: excluding the first bar barDistance (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 label NOTE: 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 rendered valuePosition (BarGraph only) |
valueSuffixCnt | X | number |
1000 |
Number to attach suffix when value exceeds valueSuffixCnt valueSuffixCnt |
valueSuffixList | X | string[] |
["k", "m", "b", "t"] |
List of suffix attached to value after dividing value by valueSuffixCnt valueSuffixList |
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 divider When 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 0 e.g.2 Rendered to 50.0% when set to 1 e.g.3 Rendered to 50.00% when set to 2 NOTE: 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 |
2 required props. Shares many items with props from BarGraph
prop | Required | Type | Default | Description |
---|---|---|---|---|
graphData | O | IBarGraphData |
Data to be rendered details |
|
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 graph NOTE: 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 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 divider When 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 0 e.g.2 Rendered to 50.0% when set to 1 e.g.3 Rendered to 50.00% when set to 2 NOTE: 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) |
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...
/>
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>
);
}}
/>
If you don't want this effect, set enableTouchHighlight
to false
.
(default is true
)
BarGraph | StackedBar |
---|---|
Default | barDistance={24} |
---|---|
<BarGraph
graphData={BAR_DATA}
barDistance={24} // default : 12
// other props...
/>
Default | valuePosition="left" |
---|---|
<BarGraph
graphData={BAR_DATA}
style={[styles.graphContainer]}
valuePosition="left" // default: "right"
// other props...
/>
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"
.
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}
/>
);
MIT license