Added pointerConfig in Line Area Charts to allow smooth magic scroll

This commit is contained in:
Abhinandan-Kushwaha 2022-04-06 04:03:55 +05:30
parent b0ca0f20b0
commit 031e670e6e
6 changed files with 383 additions and 47 deletions

143
App.js
View File

@ -583,7 +583,7 @@ const App = () => {
},
];
const TrianglePattern = () => {
const MyPattern = () => {
return (
<Pattern
id="DiagonalLines"
@ -598,7 +598,7 @@ const App = () => {
);
};
const MyPattern = () => {
const nn = () => {
return (
<Pattern
id="DiagonalLines"
@ -681,16 +681,40 @@ const App = () => {
{value: 0.72, label: '14'},
{value: 0.85, label: '15'},
];
// const lineData = [
// {value: 0, dataPointText: '0'},
// {value: 20, dataPointText: '20'},
// {value: 18, dataPointText: '18'},
// {value: 40, dataPointText: '40'},
// {value: 36, dataPointText: '36'},
// {value: 60, dataPointText: '60'},
// {value: 54, dataPointText: '54'},
// {value: 85, dataPointText: '85'}
// ];
const lineData = [
{value: 0, dataPointText: '0'},
{value: 20, dataPointText: '20'},
{value: 18, dataPointText: '18'},
{value: 40, dataPointText: '40'},
{value: 36, dataPointText: '36'},
{value: 60, dataPointText: '60'},
{value: 54, dataPointText: '54'},
{value: 85, dataPointText: '85'},
{value: 36, dataPointText: '36'},
{value: 60, dataPointText: '60'},
{value: 54, dataPointText: '54'},
{value: 85, dataPointText: '85'},
{value: 36, dataPointText: '36'},
{value: 60, dataPointText: '60'},
{value: 54, dataPointText: '54'},
{value: 85, dataPointText: '85'},
{value: 36, dataPointText: '36'},
{value: 60, dataPointText: '60'},
{value: 54, dataPointText: '54'},
{value: 85, dataPointText: '85'},
{value: 36, dataPointText: '36'},
{value: 60, dataPointText: '60'},
{value: 54, dataPointText: '54'},
{value: 85, dataPointText: '85'},
{value: 36, dataPointText: '36'},
{value: 60, dataPointText: '60'},
{value: 54, dataPointText: '54'},
{value: 85, dataPointText: '85'},
{value: 36, dataPointText: '36'},
{value: 60, dataPointText: '60'},
{value: 54, dataPointText: '54'},
{value: 85, dataPointText: '85'},
];
// const lineData = [
// {value: 0, dataPointText: '0'},
@ -776,6 +800,19 @@ const App = () => {
{value: 1387, label: 'active', labelTextStyle: {textAlign: 'left'}},
];
const ldt = [
{value: -10},
{value: 25},
{value: 24},
{value: 45},
{value: 60},
{value: -34},
{value: 24},
{value: 45},
{value: 60},
{value: -34},
];
return (
<View
style={{
@ -794,7 +831,14 @@ const App = () => {
yAxisTextStyle={{fontWeight:'bold',marginRight:-110,zIndex:10000,textAlign:'left'}}
spacing={30}
/> */}
<BarChart data={dtt} barWidth={40} spacing={30} />
{/* <BarChart
data={ldt}
maxValue={80}
stepValue={20}
noOfSections={4}
minValue={-60}
noOfSectionsBelowXAxis={3}
/> */}
{/* <LineChart
areaChart
curved
@ -836,33 +880,48 @@ const App = () => {
color="#0BA5A4"
/>
</View> */}
{/* <LineChart
// curved={true}
// isAnimated={true}
// animateTogether
pressEnabled={true}
showStripOnPress={true}
showTextOnPress={true}
data={lineData}
disableScroll={true}
// data2={lineData2}
height={250}
showVerticalLines
spacing={44}
initialSpacing={0}
color1="skyblue"
color2="orange"
textColor1="green"
dataPointsHeight={6}
dataPointsWidth={6}
dataPointsHeight2={6}
dataPointsWidth2={6}
dataPointsColor1="blue"
dataPointsColor2="red"
textShiftY={-2}
textShiftX={-5}
textFontSize={13}
/> */}
<LineChart
curved={true}
isAnimated={true}
// animateTogether
pressEnabled={true}
showStripOnPress={true}
showTextOnPress={true}
data={lineData}
disableScroll={true}
pointerConfig={{
radius: 5,
// pointerStripHeight:120,
pointerLabelComponent: () => {
return (
<View>
<Text>{'1234'}</Text>
</View>
);
},
}}
// data2={lineData2}
hideDataPoints
height={250}
// showVerticalLines
// spacing={44}
initialSpacing={0}
color1="skyblue"
color2="orange"
textColor1="green"
dataPointsHeight={6}
dataPointsWidth={6}
dataPointsHeight2={6}
dataPointsWidth2={6}
dataPointsColor1="blue"
dataPointsColor2="red"
textShiftY={-2}
textShiftX={-5}
textFontSize={13}
hideRules
spacing={10}
areaChart
/>
{/* <LineChart
isAnimated={true}
curved
@ -908,7 +967,7 @@ const App = () => {
endOpacity={0.3}
/> */}
<BarChart
{/* <BarChart
width={340}
rotateLabel
barWidth={12}
@ -916,7 +975,7 @@ const App = () => {
noOfSections={4}
barBorderRadius={6}
stackData={stackData}
/>
/> */}
{/* <BarChart
// isAnimated={true}

BIN
demos/rainbow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
demos/scrollLine.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

View File

@ -254,6 +254,38 @@ type referenceConfigType = {
---
## pointerConfig
pointerConfig is an object, when passed as a prop, creates a magical effect. It lets the user scroll over chart to move the pointer along the chart. Here is an example-
<img src='../../demos/scrollLine.gif' alt='' height=400 width=500/>
To enable such kind of csroll effect, just pass the prop pointerConfig.
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;
};
```
The above properties can be understood with this labelled diagram-
<img src='../../demos/rainbow.png' alt='' height=400 width=500/>
### onPress and strip related props
Line or Area charts can be made interactive by allowing users to press on the chart and highlight that particular data point. For example-

View File

@ -1,6 +1,6 @@
{
"name": "react-native-gifted-charts",
"version": "1.0.15",
"version": "1.0.16",
"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": [

View File

@ -107,6 +107,7 @@ type propTypes = {
areaChart?: Boolean;
disableScroll?: Boolean;
pointerConfig?: Pointer;
showScrollIndicator?: Boolean;
//Indices
@ -309,8 +310,28 @@ type sectionType = {
value: string;
};
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;
};
export const LineChart = (props: propTypes) => {
const scrollRef = useRef();
const [pointerX, setPointerX] = useState(0);
const [pointerY, setPointerY] = useState(0);
const [points, setPoints] = useState('');
const [points2, setPoints2] = useState('');
const [points3, setPoints3] = useState('');
@ -1221,7 +1242,87 @@ export const LineChart = (props: propTypes) => {
const backgroundColor = props.backgroundColor || 'transparent';
const disableScroll = props.disableScroll || false;
const defaultPointerConfig = {
height: 0,
width: 0,
radius: 5,
color: 'red',
pointerComponent: null,
showPointerStrip: true,
pointerStripHeight: containerHeight,
pointerStripWidth: 1,
pointerStripColor: 'black',
pointerStripUptoDataPoint: false,
pointerLabelComponent: null,
shiftPointerLabelX: 0,
shiftPointerLabelY: 0,
pointerLabelWidth: 40,
pointerVanishDelay: 200,
};
const pointerConfig = props.pointerConfig || null;
const pointerHeight =
pointerConfig && pointerConfig.height
? props.pointerConfig.height
: defaultPointerConfig.height;
const pointerWidth =
pointerConfig && pointerConfig.width
? props.pointerConfig.width
: defaultPointerConfig.width;
const pointerRadius =
pointerConfig && pointerConfig.radius
? props.pointerConfig.radius
: defaultPointerConfig.radius;
const pointerColor =
pointerConfig && pointerConfig.color
? props.pointerConfig.color
: defaultPointerConfig.color;
const pointerComponent =
pointerConfig && pointerConfig.pointerComponent
? props.pointerConfig.pointerComponent
: defaultPointerConfig.pointerComponent;
const showPointerStrip =
pointerConfig && pointerConfig.showPointerStrip
? props.pointerConfig.showPointerStrip
: defaultPointerConfig.showPointerStrip;
const pointerStripHeight =
pointerConfig && pointerConfig.pointerStripHeight
? props.pointerConfig.pointerStripHeight
: defaultPointerConfig.pointerStripHeight;
const pointerStripWidth =
pointerConfig && pointerConfig.pointerStripWidth
? props.pointerConfig.pointerStripWidth
: defaultPointerConfig.pointerStripWidth;
const pointerStripColor =
pointerConfig && pointerConfig.pointerStripColor
? props.pointerConfig.pointerStripColor
: defaultPointerConfig.pointerStripColor;
const pointerStripUptoDataPoint =
pointerConfig && pointerConfig.pointerStripUptoDataPoint
? props.pointerConfig.pointerStripUptoDataPoint
: defaultPointerConfig.pointerStripUptoDataPoint;
const pointerLabelComponent =
pointerConfig && pointerConfig.pointerLabelComponent
? props.pointerConfig.pointerLabelComponent
: defaultPointerConfig.pointerLabelComponent;
const shiftPointerLabelX =
pointerConfig && pointerConfig.shiftPointerLabelX
? props.pointerConfig.shiftPointerLabelX
: defaultPointerConfig.shiftPointerLabelX;
const shiftPointerLabelY =
pointerConfig && pointerConfig.shiftPointerLabelY
? props.pointerConfig.shiftPointerLabelY
: defaultPointerConfig.shiftPointerLabelY;
const pointerLabelWidth =
pointerConfig && pointerConfig.pointerLabelWidth
? props.pointerConfig.pointerLabelWidth
: defaultPointerConfig.pointerLabelWidth;
const pointerVanishDelay =
pointerConfig && pointerConfig.pointerVanishDelay
? props.pointerConfig.pointerVanishDelay
: defaultPointerConfig.pointerVanishDelay;
const disableScroll = props.disableScroll || pointerConfig || false;
const showScrollIndicator = props.showScrollIndicator || false;
const hideOrigin = props.hideOrigin || false;
@ -1947,6 +2048,63 @@ export const LineChart = (props: propTypes) => {
});
};
const renderPointer = () => {
return (
<View
style={{
position: 'absolute',
height: pointerHeight || pointerRadius * 2,
width: pointerWidth || pointerRadius * 2,
backgroundColor: pointerColor,
borderRadius: pointerRadius || 0,
left: pointerX,
top: pointerY,
}}>
{pointerComponent ? pointerComponent() : null}
{showPointerStrip && (
<View
style={{
position: 'absolute',
left: pointerRadius || pointerWidth / 2,
top: pointerStripUptoDataPoint
? pointerRadius || pointerStripHeight / 2
: -pointerY + 8,
height: pointerStripUptoDataPoint
? containerHeight - pointerY - 10
: pointerStripHeight,
width: pointerStripWidth,
backgroundColor: pointerStripColor,
marginTop: pointerStripUptoDataPoint
? 0
: containerHeight - pointerStripHeight,
}}
/>
)}
{pointerLabelComponent && (
<View
style={{
position: 'absolute',
left:
(pointerRadius || pointerWidth / 2) - 20 + shiftPointerLabelX,
top:
(pointerStripUptoDataPoint
? pointerRadius || pointerStripHeight / 2
: -pointerY + 8) -
pointerLabelWidth / 2 +
shiftPointerLabelY,
marginTop: pointerStripUptoDataPoint
? 0
: containerHeight - pointerStripHeight,
width: pointerLabelWidth,
}}>
{pointerLabelComponent()}
</View>
)}
</View>
);
};
const renderLine = (
points: any,
currentLineThickness: number | undefined,
@ -1960,13 +2118,55 @@ export const LineChart = (props: propTypes) => {
) => {
return (
<View
onStartShouldSetResponder={evt => (pointerConfig ? true : false)}
onMoveShouldSetResponder={evt => (pointerConfig ? true : false)}
onResponderGrant={evt => {
if (!pointerConfig) return;
let x = evt.nativeEvent.locationX;
let factor = x / (initialSpacing + spacing);
factor = Math.round(factor);
let z =
initialSpacing +
spacing * factor -
(pointerRadius || pointerWidth / 2) -
3;
setPointerX(z);
let item = data[factor];
let y =
containerHeight -
(item.value * containerHeight) / maxValue -
(pointerRadius || pointerHeight / 2) +
10;
setPointerY(y);
}}
onResponderMove={evt => {
if (!pointerConfig) return;
let x = evt.nativeEvent.locationX;
let factor = x / (initialSpacing + spacing);
factor = Math.round(factor);
let z =
initialSpacing +
spacing * factor -
(pointerRadius || pointerWidth / 2) -
3;
setPointerX(z);
let item = data[factor];
let y =
containerHeight -
(item.value * containerHeight) / maxValue -
(pointerRadius || pointerHeight / 2) +
10;
setPointerY(y);
}}
onResponderRelease={evt => {
setTimeout(() => setPointerX(0), pointerVanishDelay);
}}
style={{
position: 'absolute',
height: containerHeight + 10 + horizSectionsBelow.length * stepHeight,
bottom: 60, //stepHeight * -0.5 + xAxisThickness,
bottom: 60,
width: totalWidth,
zIndex: -1,
// backgroundColor: 'rgba(200,150,150,0.6)'
zIndex: 20,
}}>
<Svg>
{strokeDashArray &&
@ -2099,6 +2299,7 @@ export const LineChart = (props: propTypes) => {
)
: null}
</Svg>
{pointerX ? renderPointer() : null}
</View>
);
};
@ -2118,6 +2319,49 @@ export const LineChart = (props: propTypes) => {
// console.log('animatedWidth is-------->', animatedWidth);
return (
<Animated.View
onStartShouldSetResponder={evt => (pointerConfig ? true : false)}
onMoveShouldSetResponder={evt => (pointerConfig ? true : false)}
onResponderGrant={evt => {
if (!pointerConfig) return;
let x = evt.nativeEvent.locationX;
let factor = x / (initialSpacing + spacing);
factor = Math.round(factor);
let z =
initialSpacing +
spacing * factor -
(pointerRadius || pointerWidth / 2) -
3;
setPointerX(z);
let item = data[factor];
let y =
containerHeight -
(item.value * containerHeight) / maxValue -
(pointerRadius || pointerHeight / 2) +
10;
setPointerY(y);
}}
onResponderMove={evt => {
if (!pointerConfig) return;
let x = evt.nativeEvent.locationX;
let factor = x / (initialSpacing + spacing);
factor = Math.round(factor);
let z =
initialSpacing +
spacing * factor -
(pointerRadius || pointerWidth / 2) -
3;
setPointerX(z);
let item = data[factor];
let y =
containerHeight -
(item.value * containerHeight) / maxValue -
(pointerRadius || pointerHeight / 2) +
10;
setPointerY(y);
}}
onResponderRelease={evt => {
setTimeout(() => setPointerX(0), pointerVanishDelay);
}}
style={{
position: 'absolute',
height: containerHeight + 10 + horizSectionsBelow.length * stepHeight,
@ -2257,6 +2501,7 @@ export const LineChart = (props: propTypes) => {
)
: null}
</Svg>
{pointerX ? renderPointer() : null}
</Animated.View>
);
};