Reputation: 55
I'm having trouble creating a chart with the Victory-Native library (click here to visit documentation for it)
I'm trying to create a dynamic chart. I'm storing it's data in the state and want to modify if once the "Get Data" button is pressed. However, I ran into an issue that after 5 hours of trying, I cannot solve myself.
I'm still new to React and trying to figure out what's going on so code probably looks like complete gibberish.
Instead of rerendering the line, the chart renders the line but kills my Y-axis domain.
This is the chart with correct domains and as it should look (when you feed static data to it):
Note: at this point, data[5] is still null and not being displayed
Once the blue "GET DATA" button is pressed, it requests the value that gets returned and placed into data[5]. However, this completely kills the Y-axis instead of re-rendering the line. What am I doing wrong? I want the line just to continue normaly with the domain that I set in the code.
This is what happens and shouldn't happen:
How can I make the chart render new value correctly?
Code:
import React, {Component} from 'react';
import {AppRegistry, View, Button, Text} from 'react-native';
import { VictoryChart, VictoryLine, VictoryTheme } from "victory-native";
class testChart extends Component {
constructor(props) {
super(props);
this.state = {
data: [
{data: 0, times: 0},
{data: 42, times: 1},
{data: 11, times: 2},
{data: 54, times: 3},
{data: 22, times: 4},
{data: null, times: null}
]
};
}
getDataBtn = () => {
const that = this;
fetch('http://192.168.1.111/getData').then(function(response){
let dataRsp = JSON.stringify(response.text());
let strData = dataRsp.substring(dataRsp.indexOf('Data:'), dataRsp.indexOf('.'));
var numData = strData.replace( /^\D+/g, ''); // ekstrakcija stevilk iz stringa
that.state.data[5].data = numData;
that.state.data[5].times = 5;
that.setState({data: that.state.data});
that.setState({text: JSON.stringify(that.state.data)});
});
}
render() {
return(
<View>
<Button color='blue' title='Get Data' onPress={() => this.getDataBtn()} />
<Text>Current DATA object value: {JSON.stringify(this.state.data)}</Text>
<VictoryChart theme={VictoryTheme.material} domain={{x: [0, 10], y: [0, 100]}}>
<VictoryLine
data={this.state.data}
x='times'
y='data'
/>
</VictoryChart>
</View>
);
}
}
AppRegistry.registerComponent('test', () => testChart);
Upvotes: 2
Views: 2465
Reputation: 1010
I fixed this issue by adding a key to the view. Try wrapping it in a view and adding the key with a new value each time the chart data changes. The solution I found was in GitHub.
Upvotes: 2
Reputation: 1033
You shouldn't access state or modify it in any other way as follows:
that.state.data[5].data = numData;
that.state.data[5].times = 5;
If you want to store this data instead of state and want to be accessible within all class functions, than you should use a private variable like this.data = 5
etc.
On the other hand, calling setState within the same scope will fail in a specific error thrown by React stating that there is a ongoing state change, you can't change it.
etc.
You can use this.setState({data: [], text: ''})
kind of approach or you can set the state in the callback of the first setState function.
Hope that helps!
Upvotes: 1
Reputation: 4868
I think its probably due to fact that numData
is a string
rather than an int
. Try doing the following instead
that.state.data[5].data = parseInt(numData);
Upvotes: 3