Added support for scroll to end in Bar chart and negative values in stack bbar chart

This commit is contained in:
Abhinandan Kushwaha 2022-02-04 15:48:18 +05:30
parent 6ce00c6fab
commit c625ec9199
5 changed files with 47 additions and 19 deletions

View File

@ -22,6 +22,8 @@
| showLine | Boolean | To show a Line chart over the Bar chart with the same data | false |
| lineConfig | lineConfigType | Properties of the Line chart shown over the Bar chart (lineConfigType) is described below | defaultLineConfig |
| autoShiftLabels | Boolean | When set to true, automatically shifts the X axis labels for negative values | false |
| 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 |
---

View File

@ -1,6 +1,6 @@
{
"name": "react-native-gifted-charts",
"version": "1.0.1",
"version": "1.0.2",
"description": "The most complete library for Bar, Line, Area, Pie and Donut charts in React Native. Allows 2D, 3D, gradient, animations and live data updates.",
"main": "src/index.tsx",
"files": [
@ -58,7 +58,8 @@
"pie",
"donut",
"area",
"line"
"line",
"react native"
],
"jest": {
"preset": "react-native"

View File

@ -33,6 +33,7 @@ type Props = {
horizontal: Boolean;
intactTopLabel: Boolean;
barBorderRadius?: number;
xAxisThickness: number;
};
type itemType = {
value?: number;
@ -51,7 +52,7 @@ type itemType = {
stacks?: Array<any>;
};
const RenderStackBars = (props: Props) => {
const {item, containerHeight, maxValue, spacing, rotateLabel} = props;
const {item, containerHeight, maxValue, spacing, rotateLabel,xAxisThickness} = props;
const disablePress = props.disablePress || false;
const renderLabel = (label: String, labelTextStyle: any) => {
return (
@ -60,7 +61,6 @@ const RenderStackBars = (props: Props) => {
{
width:
(item.stacks[0].barWidth || props.barWidth || 30) + spacing / 2,
left: -6,
position: 'absolute',
bottom: rotateLabel ? -40 : -25,
},
@ -87,18 +87,16 @@ const RenderStackBars = (props: Props) => {
let position = 0;
for (let i = 0; i < index; i++) {
position +=
(props.item.stacks[i].value * (containerHeight || 200)) /
(Math.abs(props.item.stacks[i].value) * (containerHeight || 200)) /
(maxValue || 200);
}
return position;
};
const getTotalHeight = () => {
return props.item.stacks.reduce((acc, stack) => acc + stack.value, 0);
};
const totalHeight = props.item.stacks.reduce((acc, stack) => acc + Math.abs(stack.value) * (containerHeight || 200) / (maxValue || 200), 0)
const static2DSimple = (item: itemType) => {
// console.log('comes to static2DSimple', item);
const cotainsNegative = item.stacks.some(item => item.value < 0)
return (
<>
<View
@ -108,6 +106,11 @@ const RenderStackBars = (props: Props) => {
width: item.stacks[0].barWidth || props.barWidth || 30,
height: '100%',
},
cotainsNegative && {
transform: [
{translateY: totalHeight + xAxisThickness / 2},
{rotate:'180deg'}
]}
]}>
{item.stacks.map((stackItem, index) => {
return (
@ -121,7 +124,7 @@ const RenderStackBars = (props: Props) => {
bottom: getPosition(index) + (stackItem.marginBottom || 0),
width: '100%',
height:
(stackItem.value * (containerHeight || 200)) /
(Math.abs(stackItem.value) * (containerHeight || 200)) /
(maxValue || 200) -
(stackItem.marginBottom || 0),
backgroundColor: stackItem.color || 'black',
@ -147,15 +150,13 @@ const RenderStackBars = (props: Props) => {
style={[
{
position: 'absolute',
top: (item.barWidth || props.barWidth || 30) * -1,
top: cotainsNegative ? 0 : (item.barWidth || props.barWidth || 30) * -1,
height: item.barWidth || props.barWidth || 30,
width: item.barWidth || props.barWidth || 30,
justifyContent:
props.horizontal && !props.intactTopLabel
? 'center'
: 'flex-end',
justifyContent: 'center',
alignItems: 'center',
},
cotainsNegative && {transform: [{translateY: totalHeight * 2}]},
props.horizontal &&
!props.intactTopLabel && {transform: [{rotate: '270deg'}]},
item.topLabelContainerStyle,
@ -174,7 +175,7 @@ const RenderStackBars = (props: Props) => {
// overflow: 'visible',
marginBottom: 60,
width: item.stacks[0].barWidth || props.barWidth || 30,
height: getTotalHeight(),
height: totalHeight,
marginRight: spacing,
},
]}>

View File

@ -19,6 +19,7 @@ import RenderStackBars from './RenderStackBars';
import Rule from '../Components/lineSvg';
import {bezierCommand, svgPath} from '../utils';
import Svg, {Circle, Path, Rect, Text as CanvasText} from 'react-native-svg';
import { useRef } from 'react';
type PropTypes = {
width?: number;
@ -117,6 +118,8 @@ type PropTypes = {
yAxisLabelPrefix?: String;
yAxisLabelSuffix?: String;
autoShiftLabels?: Boolean;
scrollToEnd?: Boolean;
scrollAnimation?: Boolean
};
type lineConfigType = {
curved?: Boolean;
@ -167,6 +170,7 @@ type itemType = {
};
export const BarChart = (props: PropTypes) => {
const scrollRef = useRef();
const [points, setPoints] = useState('');
const showLine = props.showLine || false;
const defaultLineConfig = {
@ -224,6 +228,8 @@ export const BarChart = (props: PropTypes) => {
const data = useMemo(() => props.data || [], [props.data]);
const spacing = props.spacing === 0 ? 0 : props.spacing ? props.spacing : 20;
const labelWidth = props.labelWidth || 0;
const scrollToEnd = props.scrollToEnd || false;
const scrollAnimation = props.scrollAnimation === false ? false : true;
let totalWidth = spacing;
let maxItem = 0, minItem = 0;
@ -238,6 +244,9 @@ export const BarChart = (props: PropTypes) => {
if (stackSum > maxItem) {
maxItem = stackSum;
}
if(stackSum < minItem){
minItem = stackSum;
}
totalWidth +=
(stackItem.stacks[0].barWidth || props.barWidth || 30) + spacing;
// console.log('totalWidth for stack===', totalWidth);
@ -261,9 +270,15 @@ export const BarChart = (props: PropTypes) => {
maxItem = maxItem + (10 - (maxItem % 10));
maxItem /= 10 * (props.roundToDigits || 1);
maxItem = parseFloat(maxItem.toFixed(props.roundToDigits || 1));
if(minItem !== 0){
minItem *= 10 * (props.roundToDigits || 1);
minItem = minItem - (10 + (minItem % 10));
minItem /= 10 * (props.roundToDigits || 1);
minItem = parseFloat(minItem.toFixed(props.roundToDigits || 1));
}
} else {
maxItem = maxItem + (10 - (maxItem % 10));
if(minItem!==0){
if(minItem !== 0){
minItem = minItem - (10 + (minItem % 10))
}
}
@ -1083,6 +1098,12 @@ export const BarChart = (props: PropTypes) => {
]}>
{props.hideAxesAndRules !== true && renderHorizSections()}
<ScrollView
ref={scrollRef}
onContentSizeChange={()=>{
if(scrollRef.current && scrollToEnd){
scrollRef.current.scrollToEnd({animated: scrollAnimation});
}
}}
style={[
{
marginLeft: yAxisLabelWidth,
@ -1123,6 +1144,7 @@ export const BarChart = (props: PropTypes) => {
containerHeight={containerHeight}
maxValue={maxValue}
spacing={spacing}
xAxisThickness={xAxisThickness}
barWidth={props.barWidth}
opacity={opacity}
disablePress={props.disablePress}

View File

@ -420,9 +420,11 @@ export const PieChart = (props: propTypes) => {
borderTopWidth: isThreeD
? innerCircleBorderWidth * 5
: innerCircleBorderWidth,
borderLeftWidth: 0.001,
borderLeftWidth: 0.5,
borderLeftColor:innerCircleColor,
borderBottomWidth: 0,
borderRightWidth: 0.001,
borderRightWidth: 0.5,
borderRightColor:innerCircleColor,
},
]}>
{props.centerLabelComponent ? props.centerLabelComponent() : null}