1.0.0 • Published 11 days ago

react-native-horizontal-bar-graphs v1.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
11 days ago

react-native-horizontal-bar-graphs

Index

  1. Introduction
  2. Installation
  3. How to use
  4. Props
  5. Demo
  6. License

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

samp_bar_no_anim samp_bar_anim

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

samp_stack_no_anim samp_stack_anim

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/>

propRequiredTypeDefaultDescription
labelOstringLabel(name) of data
valueOnumberNumber of data
colorXColorValue"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
onPressXfunction(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

propRequiredTypeDefaultDescription
graphDataOIBarGraphDataData to be rendereddetails
totalCntOnumberTotal number of data.Used as denominator when calculating percentages.데이터의 전체 갯수.퍼센트를 계산할 때 분모로 사용됨.
styleXStyleProp<ViewStyle>Styles for graph containers
titleXstringTitle of graphNOTE: If title is undefined or an empty string (""), it will not be rendered.
titlePositionX"top" \| "bottom""top"Position of the title
titleStyleXStyleProp<TextStyle>{fontWeight: "bold", fontSize: 20, textAlign: "center", marginVertical: 16}Styles for title
barHeightXnumber28Height of each bar
barHolderColorXColorValue"#EEEEEE"Placeholder color for bars
barAnimatedXbooleantrueWhether to animate the bar
barLeftStyleX"rounded" \| "square""rounded"Left style of bar (both colored and holder).barLeftStyle
barRightStyleX"rounded" \| "square""rounded"Right style of colored bar.barRightStyle
barHolderRightStyleX"rounded" \| "square""rounded"Right style of placeholder of bar.barHolderRightStyle
showDividerXbooleantrueWhether to display a divider at certain percentages in the bar's placeholder
dividerInterverX4 \| 5 \| 10 \| 20 \| 25 \| 33.3 \| 5020A 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가 몇%마다 표시될지
dividerHeightXstring \| number"60%"Height of dividerWhen set to "100%", it is equal to the height of the bar
dividerColorXColorValue"#BBBBBB"Color of divider
dividerWidthXnumber1Width of each divider
percentPositionX"left" \| "right" \| "none""right"Position where the percentage corresponding to value is displayed.NOTE: If it is undefined or "none", it is not rendered.
percentFixedX0 \| 1 \| 20A 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퍼센트의 소수점 몇번째 자리까지 표시할지
PercentLabelComponentX({ value, total, color }: { value: number; total: number, color: ColorValue \| undefined }) => ReactElement \| null \| undefinedA React Component to display percentages.PercentLabelComponent
enableTouchHighlightXbooleantrueWhether to enable color highlighting when a bar or list item is touched.enableTouchHighlight
showListXbooleantrueWhether to render a list of graphData
listAnimatedXbooleantrueWhether to run animations when the list is displayed
listContainerStyleXStyleProp<ViewStyle>Style of list container
ListItemComponentX(props: IStackedCustomListItemProps) => ReactElementA React Component that renders custom list items.ListItemComponent (StackedBar Only)

Demo

barLeftStyle, barRightStyle, barHolderRightStyle

Rounded - Default | BarGraph | StackedBar | | :--: | :--: | | bar_percent_default | stacked_rrr |

<BarGraph // same as StackedBar
  graphData={BAR_DATA}
  barLeftStyle="rounded"
  barRightStyle="rounded"
  barHolderRightStyle="rounded"
  // other props...
/>

Square | BarGraph | StackedBar | | :--: | :--: | | bar_sss | stack_sss |

<BarGraph // same as StackedBar
  graphData={BAR_DATA}
  barLeftStyle="square"
  barRightStyle="square"
  barHolderRightStyle="square"
  // other props...
/>

Mixed style 1 | BarGraph | StackedBar | | :--: | :--: | |bar_rsr | stack_rsr |

<BarGraph // same as StackedBar
  graphData={BAR_DATA}
  barLeftStyle="rounded"
  barRightStyle="square"
  barHolderRightStyle="rounded"
  // other props...
/>

Mixed style 2 | BarGraph | StackedBar | | :--: | :--: | | bar_srr | stack_srr |

<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아닙니다

BarGraphStackedBar
defaultbar_percent_defaultdefaultstack_percent_default
custombar_percent_customcustomstack_percent_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)

BarGraphStackedBar
bar_highlightstack_highlight

barDistance (BarGraph only)

DefaultbarDistance={24}
bar_distancebar_distance_24
<BarGraph
  graphData={BAR_DATA}
  barDistance={24} // default : 12
  // other props...
/>

valuePosition (BarGraph only)

DefaultvaluePosition="left"
bar_val_rightbar_val_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 | | :--: | :--: | :--: | | stack_list_dd | stack_list_cd | stack_list_cc | | 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

1.0.0

11 days ago

0.2.1

16 days ago

1.0.6

28 days ago

0.1.5

28 days ago

0.1.0

30 days ago

0.0.1

30 days ago