#reactjs #json #api #graph
#reactjs #json #API #График
Вопрос:
Я практикуюсь React.js и я пытаюсь отобразить диаграмму статистики покемонов, используя библиотеку Rechart.
Я объявляю состояние в виде объекта JSON в состоянии моего компонента. Затем я вызываю API, чтобы предоставить правильную статистику, соответствующую выбранному покемону в моем состоянии.
Вот моя проблема, если я помещаю жесткие значения в свой объект JSON, график отображается правильно с этими значениями при запуске приложения. Но когда значения меняются при вызове API, я получаю это предупреждение в веб-консоли, когда график пытается прочитать мои разные данные:
Warning: Received NaN for the `x1` attribute. If this is expected, cast the value to a string.
in line (created by PolarRadiusAxis)
in g (created by Layer)
in Layer (created by PolarRadiusAxis)
in PolarRadiusAxis (at CompetenceChartPokemon.js:159)
in svg (created by Surface)
in Surface (created by RadarChart)
in div (created by RadarChart)
in RadarChart (at CompetenceChartPokemon.js:149)
Warning: Received NaN for the `y1` attribute. If this is expected, cast the value to a string.
in line (created by PolarRadiusAxis)
in g (created by Layer)
in Layer (created by PolarRadiusAxis)
in PolarRadiusAxis (at CompetenceChartPokemon.js:159)
in svg (created by Surface)
in Surface (created by RadarChart)
in div (created by RadarChart)
in RadarChart (at CompetenceChartPokemon.js:149)
... same error for each of the axis
И мой график полностью пуст, я просто вижу строки, которые представляют каждую ось графика.
Чтобы решить эту проблему, я убрал рендеринг своего графика из своей функции рендеринга, действительно, мой вызов API является асинхронным, и поэтому я думаю, что мои данные, возможно, не все были получены во время вызова для создания графика.
Но когда я отображаю свое состояние в виде JSON в веб-консоли, оно имеет правильные значения. Мне сказали, что запуск console.log() может занять много времени, и поэтому он покажет мне правильные значения в моей консоли, в то время как у более быстрого вызова graph еще не было всех этих данных, но мне это кажется странным.
Я поместил часть своего кода здесь,
import React, { Component, Fragment } from "react";
import Axios from "axios";
import {
Radar,
RadarChart,
PolarGrid,
PolarAngleAxis,
PolarRadiusAxis
} from "recharts";
class CompetenceChartPokemon extends Component {
constructor(props) {
super(props);
this.state = {
statistic: [
{
subject: "Hp",
pokemonStat: 100 //I've put hard value for the 3 first stat to see if they were displaying at launch of app and they are displaying
},
{
subject: "Attack",
pokemonStat: 123
},
{
subject: "Defense",
pokemonStat: 345
},
{
subject: "Special Attack",
pokemonStat: 0
},
{
subject: "Special Defense",
pokemonStat: 0
},
{
subject: "Speed",
pokemonStat: 0
}
],
pokemonChosen: false,
pokemonLoading: true,
pokemonColorAPI: "",
pokemonIdAPI: "",
pokemonNameAPI: "",
};
}
handlePokemonNameChange = (e) => {
this.setState({ pokemonName: e.target.value });
this.setState({ pokemonChosen: true });
}
searchPokemon = () => {
this.setState({ pokemonLoading: true });
Axios.get(`http://localhost:5000/getPokemon/pokemonStat/${this.state.pokemonName}`)
.then(res => {
if (res.status === 200 amp;amp; res != null) {
let copyJSONArray = this.state.statistic.slice();
res.data.stats.map((stat, index) => {
copyJSONArray[index] = stat.base_stat;
})
this.setState({ statistic: copyJSONArray });
this.setState({ pokemonIdAPI: res.data.id }); // here I get id of pokemon for a second API call which will give me color of pokemon (info not available in first call)
this.setState({ pokemonNameAPI: res.data.name });
console.log(res);
Axios.get(`http://localhost:5000/getPokemon/pokemonNameFr/${this.state.pokemonIdAPI}`)
.then(response => {
if (response.status === 200 amp;amp; response != null) {
this.setState({ pokemonColorAPI: response.data.color.name });
} else {
console.log('problem in second call');
}
})
.catch(error => {
console.log(error);
});
this.setState({ pokemonLoading: false });
} else {
console.log('problem in first call');
}
})
.catch(error => {
console.log(error);
});
console.log(this.state.statistic); //this state is filling correctly here
}
renderGraph() {
let color = "";
if (this.state.pokemonColorAPI === "black") {
color = "#1D2525";
}
if (this.state.pokemonColorAPI === "blue") {
color = "#2350B8";
}
if (this.state.pokemonColorAPI === "brown") {
color = "#904F17";
}
if (this.state.pokemonColorAPI === "gray") {
color = "#999999";
}
if (this.state.pokemonColorAPI === "green") {
color = "#438A3B";
}
if (this.state.pokemonColorAPI === "pink") {
color = "#FFB7CE";
}
if (this.state.pokemonColorAPI === "purple") {
color = "#8D5E9B"
}
if (this.state.pokemonColorAPI === "red") {
color = "#BB4B49";
}
if (this.state.pokemonColorAPI === "white") {
color = "#F0EEFF";
}
if (this.state.pokemonColorAPI === "yellow") {
color = "#FFF380";
}
if (this.state.pokemonNameAPI === undefined) {
return null;
} else {
return (<React.Fragment>
{console.log(this.state.statistic)}
<RadarChart
cx={300}
cy={250}
outerRadius={150}
width={500}
height={500}
data={this.state.statistic}
>
<PolarGrid />
<PolarAngleAxis dataKey="subject" />
<PolarRadiusAxis />
<Radar
name={this.state.pokemonName}
dataKey="pokemonStat"
stroke="#8884d8"
fill="#8884d8"
fillOpacity={0.6}
/>
</RadarChart>
</React.Fragment>
)
}
}
render() {
return (
<div className="DisplayOnePokemon">
<div className="TitleSection">
<h1>Pokemon Stats</h1>
<input type="text" onChange={this.handlePokemonNameChange} value={this.state.pokemonName} />
<button onClick={this.searchPokemon}>Search Pokemon stats graph</button>
</div>
<div className="DisplaySection">
{((!this.state.pokemonChosen) amp;amp; (this.state.pokemonLoading == false)) ? (
<h1>Please choose a Pokemon</h1>
) : (
<div>{this.renderGraph()}</div>
)}
</div>
</div >
);
}
}
Вот ссылка на документацию графика, который я пытаюсь использовать https://recharts.org/en-US/examples/SimpleRadarChart , Я не понимаю, что я делаю не так по сравнению с примером, приведенным в документе.
Любая помощь будет с благодарностью принята 🙂
Ответ №1:
Я, наконец, заставил его работать, проблема заключалась в том, что мое объявление состояния JSON в моем конструкторе заменило его массивом и создало JSON const в моем методе renderGraph, который принимает значения из моего массива, сработало.