0

How to put AJAX on the Chart.js? Here's my code

 // Chart
var ctx = document.getElementById("AreaChart");
var myLineChart = new Chart(ctx, {
    type: 'line',
    update: ({
        duration: 200,
        easing: 'easeOutBounce'
    }),
    data: {
        labels: ["Jan", "Feb", "Mar", "Apr", "May"],
        datasets: [{
            label: "Harvested",
            lineTension: 0.3,
            backgroundColor: "rgba(2,117,216,0.2)",
            borderColor: "rgba(2,117,216,1)",
            pointRadius: 6,
            pointBackgroundColor: "rgba(2,117,216,1)",
            pointBorderColor: "rgba(255,255,255,0.8)",
            pointHoverRadius: 8,
            pointHoverBackgroundColor: "rgba(2,117,216,1)",
            pointHitRadius: 20,
            pointBorderWidth: 2,
            data: [<?php while($energy = mysqli_fetch_assoc($energy_set)) { echo h($energy['energyPercent'] . ','); } ?>],
        }],
    },

So on the data: [<?php while($energy = mysqli_fetch_assoc($energy_set)) { echo h($energy['energyPercent'] . ','); } ?>]. Here is I can perfectly fetch the data from the MySQL but the problem is it needs to be refreshed to fetch new data. How to put AJAX there?

I watched and read some tutorials in AJAX but in my case, it's kinda hard especially im new to AJAX.

Here's my function ajax(), and I will call it on the HTML ( body onload=ajax()) but where will I put the document.getElementById("myChart") if Im using the <canvas id="myChart" width="100" height="40"></canvas>

Thanks in advance everyone!

Patrick Q
  • 6,373
  • 2
  • 25
  • 34
Cyril
  • 59
  • 7
  • 1
    You would set up an ajax call that alters the `data` value in the chart object. Then in order to redraw a chart you call the render() method again. (it'll take me some time, but I could write up an example... I'm just buried atm, and someone else may do it). – IncredibleHat Mar 02 '18 at 16:12
  • Possible duplicate of [Draw a Chart.js with ajax data and responsive. A few problems and questions](https://stackoverflow.com/questions/19894952/draw-a-chart-js-with-ajax-data-and-responsive-a-few-problems-and-questions) – Patrick Q Mar 02 '18 at 16:16
  • Also this may shed some light as well: [Updating Charts](http://www.chartjs.org/docs/latest/developers/updates.html) – IncredibleHat Mar 02 '18 at 16:19
  • 1
    As this are two questions at one (1. get data via ajax, 2. update chart) here's the solution for the second part: [Dynamically update values of a chartjs chart](https://stackoverflow.com/questions/17354163/dynamically-update-values-of-a-chartjs-chart) – Andreas Mar 02 '18 at 16:20

3 Answers3

0

You can do something like

$.ajax({
    url: "/your/url/to/ajax.php",
    method: "POST",
    data: { id: 1 },
    success: function(response) {
        var label_array = [];
        var data_array= [];

        for(var i in response) {
            label_array.push(response[i].Date);
            data_array.push(response[i].value);
        }
        <Chart.js code>
    } // End Success
})  // End Ajax
Tayyab Khan
  • 283
  • 3
  • 11
  • got the idea, thanks! but I dont know what will I put in the url, what do you mean "your url to ajax.php"? – Cyril Mar 02 '18 at 16:45
0

What you need to do is make the code which generates this data accessible by URL - this is sometimes called creating an endpoint. Usually a lot of these bundled together is called an Application Programming Interface (API). It's a way to get an application to show, update, delete, or create data based on the urls you're requesting and their parameters.

In this case you'd be creating an endpoint like https://yourhost.tld/energy.php perhaps. When you request energy.php, it runs and fetches the data you're getting from $energy_set and returns it as an HTTP response. That can look something like this:

<?php

header('Content-Type: application/json');

$data = [];

while($energy = mysqli_fetch_assoc($energy_set)) {
  $data[] = $energy['energyPercent'];
}

echo json_encode($data);

return;

That's about as barebones as you can get - if you have a lot of endpoints you might want to consider a little framework like Lumen to help you organize your code and make it safer.

So, once you've done that you can start fetching that data from the browser. This can be done a number of ways, but at its simplest will look something like this:

// Using the fetch API - you can use jQuery.ajax instead, for example
fetch('https://yourhost.tld/energy.php')
  .then(function(response) {
    // Remove the chart data
    chart.data.datasets.forEach((dataset) => {
        dataset.data.pop();
    });

    // Add your response data back into the chart
    chart.data.datasets.forEach((dataset) => {
        dataset.data.push(response);
    });
  });

This is really naive - you'd probably want to break the emptying and adding of data out into functions as shown in the documentation. When you know you need to rebuild your chart, you simply call chart.update() after modifying its data. This is outlined here: http://www.chartjs.org/docs/latest/developers/updates.html

As such your final code might function similar to this:

fetch('https://yourhost.tld/energy.php')
  .then(function(response) {
    removeData(chart);

    addData(chart, 'Harvested', response);

    chart.update();
  });

You could also make a habit of returning all chart data in the response, so you can have a generic chart handler:

<?php

header('Content-Type: application/json');

$data = [];

while($energy = mysqli_fetch_assoc($energy_set)) {
  $data[] = $energy['energyPercent'];
}

echo json_encode([
  'label' => 'Harvested',
  'data'  => $data
]);

return;

Then in your JavaScript...

fetch('https://yourhost.tld/energy.php')
  .then(function(response) {
    removeData(chart);

    addData(chart, response.label, response.data);

    chart.update();
  });

If anything's unclear, feel free to ask questions. This convention is simple once you get the hang of it, but seems difficult before you've done it.

I'd also add that while this code is probably close to working, it's not 'best practice'; it's more so intended to illustrate how this works with as little code as possible. It's perfectly fine to use code like this in a prototype or hobby project, but I would look into things like SQL injection and data sanitization before building a bunch of endpoints which use mysqli_fetch_assoc. Take a look at PHP The Right Way if you're interested.

Steve Adams
  • 2,812
  • 22
  • 29
  • Thanks for a wonderful reply! Though I'm still confused, i quite get the idea. I'll study this and will update to you soon! – Cyril Mar 02 '18 at 17:09
  • Sir, can you look at my answer. I finally made it to work on ajax with chart.js but there's a problem :( – Cyril Mar 03 '18 at 01:53
0

I finally made it working with AJAX but the problem is, it's not real-time whenever I change some data in phpMyAdmin, I need to refresh it on the website.

Here's my code: ajax.js

$(document).ready(function() {
$.ajax({
    url: "http://localhost/projectZeus/private/data.php",
    method: "GET",
    async: true,
    success: function(data) {
        console.log(data);
        var energy = [];

        for(var i in data) {
            energy.push(data[i].energyPercent);
        }   

        var chartdata = {
            labels: ["Jan", "Feb", "Mar", "Apr", "May"],
            datasets: [{
                label: "Harvested",
                lineTension: 0.3,
                backgroundColor: "rgba(2,117,216,0.2)",
                borderColor: "rgba(2,117,216,1)",
                pointRadius: 6,
                pointBackgroundColor: "rgba(2,117,216,1)",
                pointBorderColor: "rgba(255,255,255,0.8)",
                pointHoverRadius: 8,
                pointHoverBackgroundColor: "rgba(2,117,216,1)",
                pointHitRadius: 20,
                pointBorderWidth: 2,
                data: energy
            }]
        };

        var ctx = $("#AreaChart");

        var barChart = new Chart(ctx, {
            type: 'line',
            data: chartdata
        });
    },
    error: function(data) {
        console.log(data);
    }
});

});


Here's my code in data.php

<?php
require_once('initialize.php');

header('Content-Type: application/json');
global $db;

$sql = "SELECT energyPercent FROM energy";
$result = mysqli_query($db, $sql);

$data = array();
foreach($result as $row) {
    $data[] = $row;
}
mysqli_free_result($result);

echo json_encode($data);

?>

How can I get it to real-time without refreshing the page? Please help, thanks!

Cyril
  • 59
  • 7
  • You need some sort of control in the HTML document which triggers an event. The event could be on click of this button, the data is fetched and placed into the chart, for example. Something like an "update" button beside the chart. – Steve Adams Mar 03 '18 at 06:28
  • $('#update-chart').on('click', function(event) { /* update the chart data here. Alternatively, just rebuild the entire chart. */ }) – Steve Adams Mar 03 '18 at 06:30
  • Thanks! I'll add this to my another option – Cyril Mar 03 '18 at 09:10