diff --git a/docs/BarChart/BarChartProps.md b/docs/BarChart/BarChartProps.md index 22f3bc7..1cec3c3 100644 --- a/docs/BarChart/BarChartProps.md +++ b/docs/BarChart/BarChartProps.md @@ -27,6 +27,7 @@ | scrollToEnd | Boolean | When set to true, the chart automatically scrolls to the rightmost bar | false | | scrollAnimation | Boolean | When set to true, scroll animation is visible when the chart automatically scrolls to the rightmost bar | true | | initialSpacing | number | distance of the first bar from the Y axis | 40 | +| renderTooltip | Function | tooltip component appearing above the bar when it is pressed, takes item and index as parameters | null | --- diff --git a/package.json b/package.json index 59d3bf7..ed1993e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-gifted-charts", - "version": "1.2.22", + "version": "1.2.23", "description": "The most complete library for Bar, Line, Area, Pie, Donut and Stacked Bar charts in React Native. Allows 2D, 3D, gradient, animations and live data updates.", "main": "src/index.tsx", "files": [ diff --git a/src/BarChart/RenderBars.tsx b/src/BarChart/RenderBars.tsx index 1a18a77..fdbc33b 100644 --- a/src/BarChart/RenderBars.tsx +++ b/src/BarChart/RenderBars.tsx @@ -65,6 +65,10 @@ type Props = { barMarginBottom?: number; onPress?: Function; xAxisTextNumberOfLines: number; + renderTooltip: Function; + initialSpacing: number; + selectedIndex: number; + setSelectedIndex: Function; }; type itemType = { value?: number; @@ -114,6 +118,10 @@ const RenderBars = (props: Props) => { label, labelTextStyle, xAxisTextNumberOfLines, + renderTooltip, + initialSpacing, + selectedIndex, + setSelectedIndex, } = props; const barMarginBottom = @@ -318,139 +326,172 @@ const RenderBars = (props: Props) => { ); }; + const barHeight = + (item.value >= 0 && (!isThreeD || isAnimated) && item.topLabelComponent + ? (item.topLabelComponentHeight || 30) + + (Math.abs(item.value) * (containerHeight || 200)) / (maxValue || 200) + : (Math.abs(item.value) * (containerHeight || 200)) / (maxValue || 200)) - + barMarginBottom; + return ( - { - item.onPress - ? item.onPress() - : props.onPress - ? props.onPress(item, index) - : null; - }} - style={[ - { - // overflow: 'visible', - marginBottom: 60 + barMarginBottom, - width: item.barWidth || props.barWidth || 30, - height: - (item.value >= 0 && - (!isThreeD || isAnimated) && - item.topLabelComponent - ? (item.topLabelComponentHeight || 30) + - (Math.abs(item.value) * (containerHeight || 200)) / - (maxValue || 200) - : (Math.abs(item.value) * (containerHeight || 200)) / - (maxValue || 200)) - barMarginBottom, - marginRight: spacing, - }, - item.value < 0 && { - transform: [ - { - translateY: - (Math.abs(item.value) * (containerHeight || 200)) / - (maxValue || 200), - }, - {rotateZ: '180deg'}, - ], - }, - // !isThreeD && !item.showGradient && !props.showGradient && - // { backgroundColor: item.frontColor || props.frontColor || 'black' }, - side !== 'right' && {zIndex: data.length - index}, - ]}> - {props.showVerticalLines && ( - - )} - {props.showXAxisIndices && ( - - )} - {isThreeD ? ( - isAnimated ? ( - + { + if (renderTooltip) { + setSelectedIndex(index); + } + item.onPress + ? item.onPress() + : props.onPress + ? props.onPress(item, index) + : null; + }} + style={[ + { + // overflow: 'visible', + marginBottom: 60 + barMarginBottom, + width: item.barWidth || props.barWidth || 30, + height: barHeight, + marginRight: spacing, + }, + item.value < 0 && { + transform: [ + { + translateY: + (Math.abs(item.value) * (containerHeight || 200)) / + (maxValue || 200), + }, + {rotateZ: '180deg'}, + ], + }, + // !isThreeD && !item.showGradient && !props.showGradient && + // { backgroundColor: item.frontColor || props.frontColor || 'black' }, + side !== 'right' && {zIndex: data.length - index}, + ]}> + {props.showVerticalLines && ( + - ) : ( - - ) - ) : item.showGradient || props.showGradient ? ( - isAnimated ? ( + )} + {isThreeD ? ( + isAnimated ? ( + + ) : ( + + ) + ) : item.showGradient || props.showGradient ? ( + isAnimated ? ( + + ) : ( + static2DWithGradient(item) + ) + ) : isAnimated ? ( { roundedBottom={props.roundedBottom || false} roundedTop={props.roundedTop || false} gradientColor={props.gradientColor} + noGradient frontColor={props.frontColor || 'black'} containerHeight={containerHeight} maxValue={maxValue} @@ -478,70 +520,52 @@ const RenderBars = (props: Props) => { barBorderRadius={props.barBorderRadius || 0} /> ) : ( - static2DWithGradient(item) - ) - ) : isAnimated ? ( - - ) : ( - + + )} + {isAnimated + ? renderAnimatedLabel(label, labelTextStyle, item.value) + : renderLabel(label, labelTextStyle, item.value)} + + {renderTooltip && selectedIndex === index && ( + + {renderTooltip(item, index)} + )} - {isAnimated - ? renderAnimatedLabel(label, labelTextStyle, item.value) - : renderLabel(label, labelTextStyle, item.value)} - + ); }; diff --git a/src/BarChart/RenderStackBars.tsx b/src/BarChart/RenderStackBars.tsx index ff121f0..fc97a8e 100644 --- a/src/BarChart/RenderStackBars.tsx +++ b/src/BarChart/RenderStackBars.tsx @@ -39,6 +39,11 @@ type Props = { barBackgroundPattern?: Function; patternId?: String; xAxisTextNumberOfLines: number; + renderTooltip: Function; + initialSpacing: number; + selectedIndex: number; + setSelectedIndex: Function; + activeOpacity: number; }; type itemType = { value?: number; @@ -63,6 +68,7 @@ const RenderStackBars = (props: Props) => { barBackgroundPattern, patternId, item, + index, containerHeight, maxValue, spacing, @@ -71,6 +77,11 @@ const RenderStackBars = (props: Props) => { label, labelTextStyle, xAxisTextNumberOfLines, + renderTooltip, + initialSpacing, + selectedIndex, + setSelectedIndex, + activeOpacity, } = props; const disablePress = props.disablePress || false; const renderLabel = (label: String, labelTextStyle: any) => { @@ -123,7 +134,15 @@ const RenderStackBars = (props: Props) => { const cotainsNegative = item.stacks.some(item => item.value < 0); return ( <> - { + setSelectedIndex(index); + if(item.onPress){ + item.onPress(); + } + }} style={[ { position: 'absolute', @@ -142,7 +161,8 @@ const RenderStackBars = (props: Props) => { { /> )} - + {item.topLabelComponent && ( { }; return ( - - {props.showVerticalLines && ( + <> + + {props.showVerticalLines && ( + + )} + {props.showXAxisIndices && ( + + )} + {static2DSimple(item)} + {renderLabel(label || '', labelTextStyle)} + + {renderTooltip && selectedIndex === index && ( + bottom: totalHeight + 60, + left: + (item.barWidth || props.barWidth || 30) * index + initialSpacing, + zIndex: 1000, + }}> + {renderTooltip(item, index)} + )} - {props.showXAxisIndices && ( - - )} - {static2DSimple(item)} - {renderLabel(label || '', labelTextStyle)} - + ); }; diff --git a/src/BarChart/index.tsx b/src/BarChart/index.tsx index 1bb700e..b6d54ae 100644 --- a/src/BarChart/index.tsx +++ b/src/BarChart/index.tsx @@ -133,6 +133,7 @@ type PropTypes = { patternId?: String; barMarginBottom?: number; onPress?: Function; + renderTooltip?: Function; }; type lineConfigType = { initialSpacing?: number; @@ -192,6 +193,7 @@ type itemType = { export const BarChart = (props: PropTypes) => { const scrollRef = useRef(); const [points, setPoints] = useState(''); + const [selectedIndex, setSelectedIndex] = useState(-1); const showLine = props.showLine || false; const initialSpacing = props.initialSpacing === 0 ? 0 : props.initialSpacing || 40; @@ -1329,6 +1331,11 @@ export const BarChart = (props: PropTypes) => { {props.hideAxesAndRules !== true && renderHorizSections()} { + if (props.renderTooltip) { + setSelectedIndex(-1); + } + }} onContentSizeChange={() => { if (scrollRef.current && scrollToEnd) { scrollRef.current.scrollToEnd({animated: scrollAnimation}); @@ -1383,7 +1390,7 @@ export const BarChart = (props: PropTypes) => { xAxisThickness={xAxisThickness} barWidth={props.barWidth} opacity={opacity} - disablePress={props.disablePress} + disablePress={item.disablePress || props.disablePress} rotateLabel={rotateLabel} showVerticalLines={showVerticalLines} verticalLinesThickness={verticalLinesThickness} @@ -1408,6 +1415,11 @@ export const BarChart = (props: PropTypes) => { item.labelTextStyle || props.xAxisLabelTextStyle } xAxisTextNumberOfLines={xAxisTextNumberOfLines} + renderTooltip={props.renderTooltip} + initialSpacing={initialSpacing} + selectedIndex={selectedIndex} + setSelectedIndex={setSelectedIndex} + activeOpacity={props.activeOpacity || 0.2} /> ); }) @@ -1470,6 +1482,10 @@ export const BarChart = (props: PropTypes) => { } onPress={props.onPress} xAxisTextNumberOfLines={xAxisTextNumberOfLines} + renderTooltip={props.renderTooltip} + initialSpacing={initialSpacing} + selectedIndex={selectedIndex} + setSelectedIndex={setSelectedIndex} /> ))}