javascriptrestchartsc3.jsmethod-call

Using API to create a gauge chart


I'm creating a dashboard for a group project. I've been tasked with creating a gauge that displays the air quality (EPA Health Concern level).

I've used an API (ClimaCell) to get the value. The response is working fine, and it gives the value that I need (the epaHealthConcern value). I've created the chart that I want, colour coded and labelled etc.

However, I can't seem to work out how I get the value into the chart data so that it presents in the gauge. Is there a way I can just use the API URL within the chart? Or can I run the API call within the data section of the chart? It can only be a whole number from 0-5, it shouldn't be this hard!

Code -

    <div id="chart" style="width:100%">


    <script>

function printvalue(AirQuality) {
console.log(AirQuality)
}

const options = {method: 'GET'};

var AirQuality = 

fetch('https://data.climacell.co/v4/timelineslocation=6015453161ce500007685a3e&fields=epaHealthConcern&timesteps=current&units=metric&timezone=Europe/London&apikey=XXXXXXXXXXXXXXXXXX', options)

.then(response => response.json())
.then(data => (data.data.timelines[0].intervals[0].values.epaHealthConcern))
.then(AirQuality => printvalue(AirQuality))
.catch(err => console.error(err));

var chart = c3.generate({
 bindto: '#chart',
 data: {
    columns: [
        ['EPA Concern Level', AirQuality]
    ],
    type: 'gauge',
    onclick: function (d, i) { console.log("onclick", d, i); },
    onmouseover: function (d, i) { console.log("onmouseover", d, i); },
    onmouseout: function (d, i) { console.log("onmouseout", d, i); }
},
gauge: {
    label: {
        format: function(value, ratio) {
            return value;
        },
        show: false
    },
min: -1, 
max: 5, 
units: ' %',
width: 39 
},
color: {
    pattern: ['#006400','#006400', '#8ad106', '#ffff00', '#ffa500', '#ff8c00', '#ff0000'],
    threshold: {
        values: [0, 1, 2, 3, 4, 5]
    }
},
size: {
    height: 180
}
});


</script>

</div>

Solution

  • You're generating the chart before the data is returned from the endpoint. This means that by the time you have returned the epaHealthConcern the chart has finished rendering.

    What you can do is wrap your generate-graph script into a function and then call that from the .then() where you're currently calling printvalue()

    .then(AirQuality => {
       //GENERATE THE CHART HERE AFTER WE HAVE GOT THE DATA
       generateChart(AirQuality);
    }).catch(err => console.error(err));
    
    let generateChart = (airData) => {
       c3.generate({
       //ADD C3 CONFIG HERE
       )}
    }

    That should do the trick.