react-native-horizontal-bar-graphs
v1.0.0
Published
react-native horizontal bar graphs
Downloads
50
Maintainers
Readme
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-graphs
or if you use yarn
yarn add react-native-horizontal-bar-graphs
How 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 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 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 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 |
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 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) |
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