0

I need to show some data from API in the Chart Reacts (https://canvasjs.com/react-charts/chart-index-data-label/)

This is my API in front:

 //API Gains stats
           fetch(`${API}/api/gains/getstatgains` 
        ,{
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
                'authorization': `Bearer ${tok}`
            }
        })
        .then(results => {
            return results.json();
        })
        .then(res => {
            var statsgains = res.result;
              if(res.success === true){
                // console.log("chart ", res);
                for (var i = 0; i< statsgains.length; i++){
                    this.setState({ gains_label: statsgains[i]._id });
                    this.setState({ gains_used: statsgains[i].total });
                    // console.log("gains utilisés : ", statsgains[i].total);
                    // console.log("gains utilisés : ", statsgains[i]._id);
                }
              }
        })

And this is the Chart code in render():

var { gains_used, gains_label } = this.state;

 //Gains stats
         const options_gains = {
            animationEnabled: true,
            exportEnabled: true,
            theme: "light2", //"light1", "dark1", "dark2"
            title:{
                text: "Simple Column Chart with Index Labels"
            },
            data: [{
                type: "column", //change type to bar, line, area, pie, etc
                //indexLabel: "{y}", //Shows y value on all Data Points
                indexLabelFontColor: "#5A5757",
                indexLabelPlacement: "outside",
                dataPoints: [
                    { x: 20, y: gains_used, indexLabel: gains_label }
                ]
            }]
         }

In Postman I have this result (http://localhost:3001/api/gains/getstatgains):

"success": true,
"message": "SUCCESS",
"result": [
    {
        "_id": "BBBBBBBBB",
        "total": 2
    },
    {
        "_id": "cccccccccc",
        "total": 1
    },
    {
        "_id": "AAAAAAAA",
        "total": 3
    }
]
}

I think I need to make a for loop in data to shows all the result, but in my browser the chart shows only "AAAAAAAA".

4
  • What shape does the data need to be in before sending it to the charts lib? Commented Dec 7, 2019 at 0:54
  • its in the line : { x: 20, y: gains_used, indexLabel: gains_label } Commented Dec 7, 2019 at 0:57
  • I see, so you're just looping through the results and setting the state on last result, so just the last item is your result. Why not swap out the for loop for .map() which returns an array of transformed results? Commented Dec 7, 2019 at 0:59
  • can you give me please an example according to my post ? .map() not workin if i use ir before the return() Commented Dec 7, 2019 at 1:08

1 Answer 1

1

Just added this to explain comment. This would replace your last .then(), the one with the loop.

.then(({ result, success }) => success
    ? result.map(({ _id, total }) => ({ gains_label: _id, gains_used: total }))
    : []
).then(dataPoints => this.setState({ dataPoints }))

Now in render, you can just replace

var { gains_used, gains_label } = this.state;

with:

const { dataPoints } = this.state;

And instead of hard-coding like this:

            data: [{
                type: "column", //change type to bar, line, area, pie, etc
                //indexLabel: "{y}", //Shows y value on all Data Points
                indexLabelFontColor: "#5A5757",
                indexLabelPlacement: "outside",
                dataPoints: [
                    { x: 20, y: gains_used, indexLabel: gains_label }
                ]
            }]

Just do:

            data: [{
                type: "column", //change type to bar, line, area, pie, etc
                //indexLabel: "{y}", //Shows y value on all Data Points
                indexLabelFontColor: "#5A5757",
                indexLabelPlacement: "outside",
                dataPoints
            }]

Edit: to increment x by 10, try:

.then(({ result, success }) => success 
  ? result.map(({ _id, total }) => ({ x: 20, y: total, indexLabel: _id, }))
          .map((obj, i) => ({ ...obj, x: obj.x + (i * 10) }))
  : [] 
).then(dataPoints => this.setState({ dataPoints })) 

Or with reduce:

  .then(({ result, success }) => success
    ? result.reduce((arr, { _id, total }) => ([
      ...arr, {
        x: arr.length ? arr[arr.length - 1].x + 10 : 20,
        y: total, indexLabel: _id } ]), [])
    : [])
  .then(dataPoints => this.setState({ dataPoints })) 
Sign up to request clarification or add additional context in comments.

13 Comments

Replace last .then() in your example with it
What is the output of it now, an array of objects? did you see my edit at the bottom?
i made a console.log like this : .then(({ result, success }) => success ? console.log(result.map(({ _id, total }) => ({ gains_label: _id, gains_used: total, x: 20 })) ) : [] and it shows my data, but the chart is empty !
That makes sense bc your lib expects x, y & indexLabel, but I originally gave gains_label etc. as the final result. Try the updated version
i tried it, no result .. it's result.map(.. not results.map(.. ) no ? because the line : .then(({ result, success }) => success is grey, and why res.success ? thanks
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.