From d9a0399e8f8d18b95d19834fff78ba8eeedfa90b Mon Sep 17 00:00:00 2001 From: Abhinandan-Kushwaha Date: Fri, 22 Apr 2022 18:54:21 +0530 Subject: [PATCH] Added the properties activatePointersOnLongPress and activatePointersDelay in the pointerConfig prop for Line and Area charts --- App.js | 42 ++- docs/LineChart/LineChartProps.md | 35 ++- package.json | 2 +- src/LineChart/index.tsx | 493 ++++++++++++++----------------- 4 files changed, 277 insertions(+), 295 deletions(-) diff --git a/App.js b/App.js index 7ca6ad5..ce316df 100644 --- a/App.js +++ b/App.js @@ -657,6 +657,19 @@ const App = () => { {value: -16, label: 'Wed'}, {value: 40, label: 'Thu'}, ]; + const barData2 = [ + { + value: 25, + label: 'Mon', + }, + {value: 20, label: 'Tue'}, + {value: -13, label: 'Wed'}, + {value: 30, label: 'Thu'}, + {value: -6, label: 'Wed'}, + {value: 30, label: 'Thu'}, + {value: -6, label: 'Wed'}, + {value: 30, label: 'Thu'}, + ]; const sdata = [ { @@ -1213,18 +1226,27 @@ const App = () => { endOpacity={0.3} /> */} - diff --git a/docs/LineChart/LineChartProps.md b/docs/LineChart/LineChartProps.md index f5146dd..029cc77 100644 --- a/docs/LineChart/LineChartProps.md +++ b/docs/LineChart/LineChartProps.md @@ -273,24 +273,29 @@ The pointerConfig object has following fields- ```js type Pointer = { - height?: number; - width?: number; - radius?: number; - color?: ColorValue; - pointerComponent?: Function; - showPointerStrip?: boolean; - pointerStripWidth?: number; - pointerStripHeight?: number; - pointerStripColor?: ColorValue; - pointerStripUptoDataPoint?: boolean; - pointerLabelComponent?: Function; - shiftPointerLabelX?: number; - shiftPointerLabelY?: number; - pointerLabelWidth?: number; - pointerVanishDelay?: number; + height?: number; // default: 0 + width?: number; // default: 0 + radius?: number; // default: 5 + color?: ColorValue; // default: 'red' + pointerComponent?: Function; // default: null + showPointerStrip?: boolean; // default: true + pointerStripWidth?: number; // default: containerHeight + pointerStripHeight?: number; // default: 1 + pointerStripColor?: ColorValue; // default: 'black' + pointerStripUptoDataPoint?: boolean; // default: false + pointerLabelComponent?: Function; // default: null + shiftPointerLabelX?: number; // default: 0 + shiftPointerLabelY?: number; // default: 0 + pointerLabelWidth?: number; // default: 40 + pointerVanishDelay?: number; // default: 150 + activatePointersOnLongPress?: boolean; // default: false + activatePointersDelay?: number; // default: 150 }; ``` +**Note** If you are using the `pointerConfig` prop, the scroll will be disabled automatically. This is because, it's difficult to achive both scrolling line and scrolling pointer simultaneously. So if you want to retain the scroll behaviour even after passing the `pointerConfig` prop, then set the property `activatePointersOnLongPress` to true inside the pointerConfig object. This will make the pointers visible only after long press. So, before the long press, user can can scroll the line. Once long pressed, scolling will be disabled until the release of the long press. + + The above properties can be understood with this labelled diagram- diff --git a/package.json b/package.json index 9c6814a..0fd1f80 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-gifted-charts", - "version": "1.2.3", + "version": "1.2.4", "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/LineChart/index.tsx b/src/LineChart/index.tsx index d9cf6ac..041d641 100644 --- a/src/LineChart/index.tsx +++ b/src/LineChart/index.tsx @@ -335,6 +335,8 @@ type Pointer = { shiftPointerLabelY?: number; pointerLabelWidth?: number; pointerVanishDelay?: number; + activatePointersOnLongPress?: boolean; + activatePointersDelay?: number; }; export const LineChart = (props: propTypes) => { @@ -345,6 +347,8 @@ export const LineChart = (props: propTypes) => { pointerShiftX: 0, pointerShiftY: 0, }); + const [responderStartTime, setResponderStartTime] = useState(0); + const [responderActive, setResponderActive] = useState(false); const [points, setPoints] = useState(''); const [points2, setPoints2] = useState(''); const [points3, setPoints3] = useState(''); @@ -1279,7 +1283,9 @@ export const LineChart = (props: propTypes) => { shiftPointerLabelX: 0, shiftPointerLabelY: 0, pointerLabelWidth: 40, - pointerVanishDelay: 200, + pointerVanishDelay: 150, + activatePointersOnLongPress: false, + activatePointersDelay: 150, }; const pointerConfig = props.pointerConfig || null; const pointerHeight = @@ -1343,8 +1349,23 @@ export const LineChart = (props: propTypes) => { pointerConfig && pointerConfig.pointerVanishDelay ? props.pointerConfig.pointerVanishDelay : defaultPointerConfig.pointerVanishDelay; - - const disableScroll = props.disableScroll || pointerConfig || false; + const activatePointersOnLongPress = + pointerConfig && pointerConfig.activatePointersOnLongPress + ? props.pointerConfig.activatePointersOnLongPress + : defaultPointerConfig.activatePointersOnLongPress; + const activatePointersDelay = + pointerConfig && pointerConfig.activatePointersDelay + ? props.pointerConfig.activatePointersDelay + : defaultPointerConfig.activatePointersDelay; + const disableScroll = + props.disableScroll || + (pointerConfig + ? activatePointersOnLongPress + ? responderActive + ? true + : false + : true + : false); const showScrollIndicator = props.showScrollIndicator || false; const hideOrigin = props.hideOrigin || false; @@ -2312,6 +2333,152 @@ export const LineChart = (props: propTypes) => { ); }; + const lineSvgComponent = ( + points: any, + currentLineThickness: number | undefined, + color: string, + fillPoints: any, + startFillColor: string, + endFillColor: string, + startOpacity: number, + endOpacity: number, + strokeDashArray: Array | undefined | null, + ) => { + return ( + + {strokeDashArray && + strokeDashArray.length === 2 && + typeof strokeDashArray[0] === 'number' && + typeof strokeDashArray[1] === 'number' ? ( + + ) : ( + + )} + + {/*********************** For Area Chart ************/} + + {areaChart && ( + + + + + )} + {areaChart && ( + + )} + + {/******************************************************************/} + + {renderSpecificVerticalLines(data)} + {renderSpecificVerticalLines(data2)} + {renderSpecificVerticalLines(data3)} + {renderSpecificVerticalLines(data4)} + {renderSpecificVerticalLines(data5)} + + {/*** !!! Here it's done thrice intentionally, trying to make it to only 1 breaks things !!! ***/} + {!hideDataPoints1 + ? renderDataPoints( + data, + dataPointsShape1, + dataPointsWidth1, + dataPointsHeight1, + dataPointsColor1, + dataPointsRadius1, + textColor1, + textFontSize1, + startIndex1, + endIndex1, + ) + : null} + {!hideDataPoints2 + ? renderDataPoints( + data2, + dataPointsShape2, + dataPointsWidth2, + dataPointsHeight2, + dataPointsColor2, + dataPointsRadius2, + textColor2, + textFontSize2, + startIndex2, + endIndex2, + ) + : null} + {!hideDataPoints3 + ? renderDataPoints( + data3, + dataPointsShape3, + dataPointsWidth3, + dataPointsHeight3, + dataPointsColor3, + dataPointsRadius3, + textColor3, + textFontSize3, + startIndex3, + endIndex3, + ) + : null} + {!hideDataPoints4 + ? renderDataPoints( + data4, + dataPointsShape4, + dataPointsWidth4, + dataPointsHeight4, + dataPointsColor4, + dataPointsRadius4, + textColor4, + textFontSize4, + startIndex4, + endIndex4, + ) + : null} + {!hideDataPoints5 + ? renderDataPoints( + data5, + dataPointsShape5, + dataPointsWidth5, + dataPointsHeight5, + dataPointsColor5, + dataPointsRadius5, + textColor5, + textFontSize5, + startIndex5, + endIndex5, + ) + : null} + + ); + }; + const renderLine = ( points: any, currentLineThickness: number | undefined, @@ -2329,6 +2496,10 @@ export const LineChart = (props: propTypes) => { onMoveShouldSetResponder={evt => (pointerConfig ? true : false)} onResponderGrant={evt => { if (!pointerConfig) return; + setResponderStartTime(evt.timeStamp); + if (activatePointersOnLongPress) { + return; + } let x = evt.nativeEvent.locationX; let factor = (x - initialSpacing) / spacing; factor = Math.round(factor); @@ -2338,7 +2509,7 @@ export const LineChart = (props: propTypes) => { initialSpacing + spacing * factor - (pointerRadius || pointerWidth / 2) - - 3; + 2; setPointerX(z); let item = data[factor]; let y = @@ -2351,6 +2522,14 @@ export const LineChart = (props: propTypes) => { }} onResponderMove={evt => { if (!pointerConfig) return; + if ( + activatePointersOnLongPress && + evt.timeStamp - responderStartTime < activatePointersDelay + ) { + return; + } else { + setResponderActive(true); + } let x = evt.nativeEvent.locationX; let factor = (x - initialSpacing) / spacing; factor = Math.round(factor); @@ -2360,7 +2539,7 @@ export const LineChart = (props: propTypes) => { initialSpacing + spacing * factor - (pointerRadius || pointerWidth / 2) - - 3; + 2; setPointerX(z); let item = data[factor]; let y = @@ -2372,6 +2551,8 @@ export const LineChart = (props: propTypes) => { setPointerItem(item); }} onResponderRelease={evt => { + setResponderStartTime(0); + setResponderActive(false); setTimeout(() => setPointerX(0), pointerVanishDelay); }} style={{ @@ -2381,137 +2562,17 @@ export const LineChart = (props: propTypes) => { width: totalWidth, zIndex: 20, }}> - - {strokeDashArray && - strokeDashArray.length === 2 && - typeof strokeDashArray[0] === 'number' && - typeof strokeDashArray[1] === 'number' ? ( - - ) : ( - - )} - - {/*********************** For Area Chart ************/} - - {areaChart && ( - - - - - )} - {areaChart && ( - - )} - - {/******************************************************************/} - - {renderSpecificVerticalLines(data)} - {renderSpecificVerticalLines(data2)} - {renderSpecificVerticalLines(data3)} - {renderSpecificVerticalLines(data4)} - {renderSpecificVerticalLines(data5)} - - {/*** !!! Here it's done thrice intentionally, trying to make it to only 1 breaks things !!! ***/} - {!hideDataPoints1 - ? renderDataPoints( - data, - dataPointsShape1, - dataPointsWidth1, - dataPointsHeight1, - dataPointsColor1, - dataPointsRadius1, - textColor1, - textFontSize1, - startIndex1, - endIndex1, - ) - : null} - {!hideDataPoints2 - ? renderDataPoints( - data2, - dataPointsShape2, - dataPointsWidth2, - dataPointsHeight2, - dataPointsColor2, - dataPointsRadius2, - textColor2, - textFontSize2, - startIndex2, - endIndex2, - ) - : null} - {!hideDataPoints3 - ? renderDataPoints( - data3, - dataPointsShape3, - dataPointsWidth3, - dataPointsHeight3, - dataPointsColor3, - dataPointsRadius3, - textColor3, - textFontSize3, - startIndex3, - endIndex3, - ) - : null} - {!hideDataPoints4 - ? renderDataPoints( - data4, - dataPointsShape4, - dataPointsWidth4, - dataPointsHeight4, - dataPointsColor4, - dataPointsRadius4, - textColor4, - textFontSize4, - startIndex4, - endIndex4, - ) - : null} - {!hideDataPoints5 - ? renderDataPoints( - data5, - dataPointsShape5, - dataPointsWidth5, - dataPointsHeight5, - dataPointsColor5, - dataPointsRadius5, - textColor5, - textFontSize5, - startIndex5, - endIndex5, - ) - : null} - + {lineSvgComponent( + points, + currentLineThickness, + color, + fillPoints, + startFillColor, + endFillColor, + startOpacity, + endOpacity, + strokeDashArray, + )} {pointerX ? renderPointer() : null} ); @@ -2536,6 +2597,10 @@ export const LineChart = (props: propTypes) => { onMoveShouldSetResponder={evt => (pointerConfig ? true : false)} onResponderGrant={evt => { if (!pointerConfig) return; + setResponderStartTime(evt.timeStamp); + if (activatePointersOnLongPress) { + return; + } let x = evt.nativeEvent.locationX; let factor = (x - initialSpacing) / spacing; factor = Math.round(factor); @@ -2545,7 +2610,7 @@ export const LineChart = (props: propTypes) => { initialSpacing + spacing * factor - (pointerRadius || pointerWidth / 2) - - 3; + 2; setPointerX(z); let item = data[factor]; let y = @@ -2558,6 +2623,14 @@ export const LineChart = (props: propTypes) => { }} onResponderMove={evt => { if (!pointerConfig) return; + if ( + activatePointersOnLongPress && + evt.timeStamp - responderStartTime < activatePointersDelay + ) { + return; + } else { + setResponderActive(true); + } let x = evt.nativeEvent.locationX; let factor = (x - initialSpacing) / spacing; factor = Math.round(factor); @@ -2567,7 +2640,7 @@ export const LineChart = (props: propTypes) => { initialSpacing + spacing * factor - (pointerRadius || pointerWidth / 2) - - 3; + 2; setPointerX(z); let item = data[factor]; let y = @@ -2579,6 +2652,8 @@ export const LineChart = (props: propTypes) => { setPointerItem(item); }} onResponderRelease={evt => { + setResponderStartTime(0); + setResponderActive(false); setTimeout(() => setPointerX(0), pointerVanishDelay); }} style={{ @@ -2589,137 +2664,17 @@ export const LineChart = (props: propTypes) => { zIndex: -1, // backgroundColor: 'wheat', }}> - - {strokeDashArray && - strokeDashArray.length === 2 && - typeof strokeDashArray[0] === 'number' && - typeof strokeDashArray[1] === 'number' ? ( - - ) : ( - - )} - - {/*********************** For Area Chart ************/} - - {areaChart && ( - - - - - )} - {areaChart && ( - - )} - - {/******************************************************************/} - - {renderSpecificVerticalLines(data)} - {renderSpecificVerticalLines(data2)} - {renderSpecificVerticalLines(data3)} - {renderSpecificVerticalLines(data4)} - {renderSpecificVerticalLines(data5)} - - {/*** !!! Here it's done thrice intentionally, trying to make it to only 1 breaks things !!! ***/} - {!hideDataPoints1 - ? renderDataPoints( - data, - dataPointsShape1, - dataPointsWidth1, - dataPointsHeight1, - dataPointsColor1, - dataPointsRadius1, - textColor1, - textFontSize1, - startIndex1, - endIndex1, - ) - : null} - {!hideDataPoints2 - ? renderDataPoints( - data2, - dataPointsShape2, - dataPointsWidth2, - dataPointsHeight2, - dataPointsColor2, - dataPointsRadius2, - textColor2, - textFontSize2, - startIndex2, - endIndex2, - ) - : null} - {!hideDataPoints3 - ? renderDataPoints( - data3, - dataPointsShape3, - dataPointsWidth3, - dataPointsHeight3, - dataPointsColor3, - dataPointsRadius3, - textColor3, - textFontSize3, - startIndex3, - endIndex3, - ) - : null} - {!hideDataPoints4 - ? renderDataPoints( - data4, - dataPointsShape4, - dataPointsWidth4, - dataPointsHeight4, - dataPointsColor4, - dataPointsRadius4, - textColor4, - textFontSize4, - startIndex4, - endIndex4, - ) - : null} - {!hideDataPoints5 - ? renderDataPoints( - data5, - dataPointsShape5, - dataPointsWidth5, - dataPointsHeight5, - dataPointsColor5, - dataPointsRadius5, - textColor5, - textFontSize5, - startIndex5, - endIndex5, - ) - : null} - + {lineSvgComponent( + points, + currentLineThickness, + color, + fillPoints, + startFillColor, + endFillColor, + startOpacity, + endOpacity, + strokeDashArray, + )} {pointerX ? renderPointer() : null} );