I'm trying to build a React native app to visualize ECG graph. Here I'm taking the data from the ESP32 using Bluetooth. ECG digital data from ESP32 is posted for every 2milliseconds. I'm trying to fetch the data from the Bluetooth Socket when ever there is a message in channel so that I wouldn't miss any data point which is crucial for ECG.
I'm using React native chart kit to plot the line chart using the incoming data from hardware which is stored in State variable. As we all know in order to update the state variable we use setState method which also re-renders the chart. But by using this method I'm getting lag in data fetching which also impacts app performance like the screen is getting stuck and cannot navigate to anywhere.
I also tried implementing assigning incoming data to state variable directly which solves my system performance issue but line chart is not updating.
/* listening to the incoming data*/
` initializeRead() {
this.disconnectSubscription = RNBluetoothClassic.onDeviceDisconnected(() => this.disconnect(true));
this.onreadSubscription = RNBluetoothClassic.onDeviceRead(this.state.ConnectedDevice.address, (message) => this.performRead(message));
}
/**
* Clear the reading functionality.
*/
uninitializeRead() {
console.log('Uninitializing SingleLead ECG Read')
if (this.state.isConnected) {
this.state.ConnectedDevice.clear();
}
if (this.onreadSubscription) {
this.onreadSubscription.remove();
}
}
async performRead(message) {
try {
if (this.state.isConnected == true) {
console.log(`SingleLead_Ecg::Polling for available messages, count: ${count}`);
// let data = message.data;
if (message.data.includes("E")) {
this.state.incomingdata[count] = Number(message.data.substring(1)); // direct assigning of incoming data to the state variable
// this.setState({incomingdata: Number(message.data.substring(1))}); // updating State variable using setState
// this.setState((prevState) => ({ incomingdata: [...prevState.incomingdata, message.data.split("E")] }));
count = count + 1;
}
console.log(`SingleLead_Ecg::Read data: ${this.state.incomingdata}`);
}
} catch (err) {
console.log(`performRead error ${err.message}`);
console.log(`connection status: ${this.state.isConnected}`)
}
}`
/* Line chart code*/
` render() {
return (
<View style={{ backgroundColor: '#ffa500', height: '100%' }}>
<Text>Bezier Line Chart</Text>
<LineChart
data={{
// labels: ["January", "February", "March", "April", "May", "June"],
datasets: [
{
data: this.state.incomingdata
}
]
}}
width={Dimensions.get("window").width} // from react-native
height={220}
yAxisSuffix="V"
yAxisInterval={1} // optional, defaults to 1
// yAxisMaxValue={100}
// yAxisMinValue={0}
chartConfig={{
backgroundColor: "#f4a460",
backgroundGradientFrom: "#fb8c00",
backgroundGradientTo: "#ffa726",
decimalPlaces: 0, // optional, defaults to 2dp
color: (opacity = 1) => `rgba(255, 255, 255, ${opacity})`,
labelColor: (opacity = 1) => `rgba(255, 255, 255, ${opacity})`,
style: {
borderRadius: 16
},
// propsForDots: {
// r: "6",
// strokeWidth: "2",
// stroke: "#ffa726"
// }
}}
bezier
style={{
marginVertical: 8,
borderRadius: 16
}}
/>
</View>
)`
I want to update the line chart frequently whenever there is incoming data from Bluetooth device in socket.
I tried implementing setState to update state variable which also re-renders the chart on update but results in performance issue and lag in response.
I also tried implementing direct assigning of incoming data to state variable which solves my performance issue problem and state variable also updating very fast (with in milliseconds).