Reputation: 537
I have an chart which displays static data just fine.
Using this template https://github.com/creativetimofficial/black-dashboard-react/blob/master/src/variables/charts.js
On my main page [dash.js] I have an API call, (which I tested presents the data I expect by using console.log()
.
I will be looking to have this data working dynamically so I have created it using useEffect
and useState
.
For reference;
const [chrtState, setChrtState] = useState({
loading: false,
chartos: null,
});
useEffect(() => {
setChrtState({loading: true});
const apiUrl = `http://example.com/api/request/`;
axios
.get(apiUrl, {
withCredentials: true,
})
.then(res => {
setChrtState({loading: false, repos: res.data.characters});
});
}, [setChrtState]);
const setCanvas = name => {
const apiUrl = `http://example.com/api/request/`;
axios
.get(apiUrl, {
withCredentials: true,
})
.then(res => {
setChrtState({loading: false, chartos: res.data.characters});
//console.log(res.data.characters);
});
};
return (
<Line
data={chartExample1[bigChartData + bigChartTime]}
options={chartExample1.options}
apiprops={chrtState.chartos}
/>
);
Note: the data
parameter is used to select a specific chart-type (e.g. data1, data2, etc), this part works fine and isn't related to the APIdata as such.
I am struggling to work out how to pass the API data to the chart.js
I tried using some other examples of how to pass props but it is proving very confusing for me given that it is already passing data1: (canvas)
etc.
data1
(line 77) in charts.js, as follows; apiprops: (props) => {
const {repos} = props;
console.log(repos);
},
but nothing was printed to the console for this.
I tried adding the data to canvas
but this is already passing information used to render the height, width and style of the of the chart.
I have tried to add the API to the charts.js file, however when I add import axios from 'axios';
to the top of this page it throws out a syntax error. But I think it makes more sense to pull the API elsewhere and pass as a prop anyway. (please let me know if you disagree).
I am very much still building my knowledge of reactjs so thank you for any help and guidance on this!
For reference, my end goal will be to pass the API data to the chart and then process each dictionary into the labels
and the datasets.data
- the API passes in this order
{
"characters": [
{
"label": 123,
"data": 321
},
{
"label": 456,
"data": 654
}
]
}
Upvotes: 0
Views: 1755
Reputation: 20825
I understood that you are trying to inject your API values into the existing functions in charts.js. First, you need to separate the API values into two arrays: labels and data. You can do that with reduce
const values = res.data.characters.reduce(
(acc, character) => ({
labels: [...acc.labels, character.label],
data: [...acc.data, character.data],
}),
{ labels: [], data: [] }
);
setChrtState({ loading: false, repos: values });
To inject them into the functions, you'll need to modify the functions a little using currying
data1: ({labels, data}) => (canvas) => {
...
return {
labels,
datasets: [
{
...
data,
},
],
};
},
and finally, call the function when passing the data prop to the Line
component
<Line
data={chartExample1[bigChartData + bigChartTime](chrtState.repos)}
Although looking at those functions they seem to have the same code, is just the data is changing, you could use a single function.
UPDATE
this would be the complete version of the component
const [chrtState, setChrtState] = useState({
loading: true,
repos: null,
});
useEffect(() => {
setChrtState({ loading: true });
const apiUrl = `http://example.com/api/request/`;
axios
.get(apiUrl, {
withCredentials: true,
})
.then((res) => {
const values = res.data.characters.reduce(
(acc, character) => ({
labels: [...acc.labels, character.label],
data: [...acc.data, character.data],
}),
{ labels: [], data: [] }
);
setChrtState({ loading: false, repos: values });
});
}, [setChrtState]);
if (chrtState.loading) {
return <span>Loading</span>;
}
return (
<Line
data={chartExample1[bigChartData + bigChartTime](chrtState.repos)}
options={chartExample1.options}
/>
);
Upvotes: 1