About
RGraph is a JavaScript charts library based on HTML5 SVG and canvas. RGraph is mature (over 15 years old) and has a wealth of features making it an ideal choice to show charts on your website.

More »

 

Download
Get the latest version of RGraph (version 6.17) from the download page. There's also older versions available, minified files and links to cdnjs.com hosted libraries.

More »

 

License
RGraph can be used for free under the GPL or if that doesn't suit your situation there's an inexpensive (£99) commercial license available.

More »

I'm having trouble updating my Line chart with AJAX


Posted by Rainer at 12:22 on Sunday 4th September 2022 [link]
I plan to create a php homepage with multiple canvas or svg, although it doesn't really matter which one.
On the canvas/svg I want to display several charts to be updated in different times.

My idea was to have a php homepage with the canvases, a line script for (each) line, a javascript called by SetInterval for each line that runs an ajax function.
Ajax calling the MySQL function (here a plain loop), returning the data.
The javascript then should call the Line.draw function.

Since there are several lines, which are updated in different time, I thought that would be the best idea.

1. Is there any better way to create such a homepage where you want to update each line by its own without reloading the page ?
2. Is svg a better solution ?

Now comming back to my initial question.
I provided the index.php, the update_rgraph.js and the update_rgraph.php below.
(Many superfluous lines in the files are omitted)

The initial graph is drawn, but there is no update by UpdateRGraph.js.
The values generated by update_rgraph.php are ok and are available in updateRGraph() as I can see on the console.

3. Why don't I get the RGraph.Line object by getElementById ?
4. Where is my mistake ?

Thanks for your support.



-- index.php ----------------------------------------------------------------------------------------------------------------

<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="utf-8">

    <!-- Canvas charts -->
    <script src="js/rgraph/RGraph.common.core.js"></script>
    .
    .
    .

</head>

<body>
    <main>
     <article>
        <?php
         echo "<table width='100%' cellspacing='0' cellpadding='5' border='0'>";
            echo "<tr>";
             echo "<td colspan='2'><canvas id='cvs' width='1000' height='250'>[No canvas support]</canvas></td>";
            echo "</tr>";
         echo "</table>";
        ?>
     </article>
    </main>

    <script type="text/javascript" src="js/update_rgraph.js"></script>

    <script>
     TestRGraph4_Chart = new RGraph.Line({
            id: 'cvs',
            data: [4,6,8,5,9,6,4,8,4,6,15,2], // Initial test data
            options: {
                marginLeft: 35,
                marginRight: 5,
                marginInner: 10,
                tickmarksStyle: 'endcircle',
                xaxisLabels: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
                tooltips:    ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
            }
        }).draw()
    </script>

</body>
</html>

-- update_rgraph.js ------------------------------------------------------------------------------------------------------------------

function updateRGraph()
{
$.ajax
(
    {
     url: "js/update_rgraph.php",
     type: "POST",
     success: function(data)
     {
        console.log(data);                     // loging to Console, only if it does NOT work
        var response = $.parseJSON(data);
        console.log(response);                 // loging to Console, only if it does NOT work
//        const Chart = document.getElementById('TestRGraph4_Chart').data=response.TestData;

        const Chart = document.getElementById('csv');
        Chart.data=response.TestData;
        Chart.draw();
     }
    }
);
} // updateRGraph

updateRGraph();
setInterval(updateRGraph, 10000);

-- update_rgraph.php ------------------------------------------------------------------------------------------------------------

<?php
$TestData = "";

for ($i = 1; $i <= 10; $i++)
{
    $TestData[] = mt_rand(0, 99);
}

$TestDataString = "['" . join("', '", $TestData) . "']";

$response = array
(
    "TestData" => "$TestDataString",
);

print_r(json_encode($response));
?>

--------------------------------------------------------------------------------------------------------------------------------



Posted by Richard at 13:13 on Sunday 4th September 2022 [link]
To answer your points:

> 1. Is there any better way to create such a homepage where you
> want to update each line by its own without reloading the page ?

No - AJAX is the way to go here - so you can draw the page when it loads and then just periodically fetch new data using AJAX and then update your chart(s).

> 3. Why don't I get the RGraph.Line object by getElementById ?

The document.getElementById() function is a built-in browser function that's used to get hold of bits on the page - like <div> tags, <span> tags, <I> tags - or the majority of other tags too. It's not used to get RGraph objects or set the data on them.
> 4. Where is my mistake ?

> 2. Is svg a better solution ?

No, I would stick with canvas - but that's because I think that it's simpler and more straight-forward than SVG. But this is just a personal preference. I don't think that SVG gives you enough benefits to use over canvas.

I'm going to assume that your AJAX query is functioning OK and it's getting back data from your PHP script (your console.log() calls should show you whether it does or not) - and here's an updated jQuery $.ajax() function call:

========================

$.ajax ({
     url: "js/update_rgraph.php",
     type: "POST",
     success: function(data)
     {
        console.log(data); // Log to Console

        var response = $.parseJSON(data);

        console.log(response); // Log to Console

        // Update the TestRGraph4_chart object with new
        // data that was fetched (it should be an array like
        // this: [1,5,4,2,6,7,8] )
        TestRGraph4_Chart.original_data[0] = response.TestData;

        // Redraw the canvas
        RGraph.redraw();
     }
    }
);

========================

That should work ('should' being the operative word!).

PS In your PHP file, this:

print_r(json_encode($response));

Would that be better as a regular print()...?

print(json_encode($response));

Posted by Rainer at 14:42 on Sunday 4th September 2022 [link]
I changed the print to your suggestion, which works well, so I keep it.

Then I tried your AJAX suggestion and at least I see something updating.
(BTW, the initial test data is still drawn correctly).

After the update, the xAxis only shows 0 below the yLine and 1 above.
It's as if the boundaries have completely crashed.

Any idea?

Posted by Rainer at 16:38 on Sunday 4th September 2022 [link]
I changed the print to your suggestion, which works well, so I keep it.

Then I tried your AJAX solution and at least I see something updating.
(BTW, the initial test data is still drawn correctly).

After the update, the xAxis only shows 0 below the yLine and 1 above.
It's as if the boundaries have completely crashed.

Any idea?

In the $ajax response is the last command RGraph.redraw();
Shouldn't that be TestRGraph4_Chart.redraw();
Or how does the system know which to redraw ?

Posted by Richard at 17:00 on Sunday 4th September 2022 [link]
I've put an example of a chart that uses AJAX here:

[REMOVED]

If you view-source you'll be able to get the code. I had to change a few things (for example the URL of the AJAX script and how it's handled) and the AJAX script only outputs a comma-separated sequence of numbers like this: 1,8,6,3,5,4,8 so the AJAX success handler wraps it in brackets and eval()s it to turn it into an array which can be given to RGraph, but you should be able to get the idea from this page.


> In the $ajax response is the last command RGraph.redraw();
> Shouldn't that be TestRGraph4_Chart.redraw();
> Or how does the system know which to redraw ?

Indeed the system knows! RGraph keeps a record of the charts that have been drawn and the canvas tags that they are drawn on so that it can redraw them when the RGraph.redraw() function is called.

Posted by Rainer at 22:58 on Sunday 4th September 2022 [link]
It took me some time to find the problem.
Returning the data with
$response = array
(
    "TestData" => "$TestDataString",
);
returns a string, not an array of data.
Therefore the trace function could not interpret the data correctly and didn't show the Line.

1. Is there any function to split the string into a correct array of data ?


The point is, I would like to return i.e. the temperature and the datetime when the value was recorded to be used as tooltips.

2. What would be the best way to return multiple values and get them split to display them?


After I had the php page working, I'm looking for a way to display the temerature of the last 24h where the
xAxis scale is fixed and the momentary temp is shown with a little gap between the actual time and the time 24h ago.
Also one that doesn't always clear the canvas before drawing.
3. Is there Line mode available or any better idea ?
Any suggestion.





Posted by Richard at 10:41 on Monday 5th September 2022 [link]
> 1. Is there any function to split the string into a
> correct array of data ?

IIRC The RGraph.stringsToNumbers() function will do this for you - though I think that the Line chart already uses this function for you.

> 2. What would be the best way to return multiple values and
> get them split to display them?

I'd probably go with JSON - return a JSON string and that can provide pretty much anything that a JavaScript object can. For example have you server-side PHP script return something like this:

{data: [1,2,3], labels: ['Monday','Tuesday','Wednesday']}


> After I had the php page working, I'm looking for a way to
> display the temerature of the last 24h where the
> xAxis scale is fixed and the momentary temp is shown with a
> little gap between the actual time and the time 24h ago.
> Also one that doesn't always clear the canvas before drawing.
>
> 3. Is there Line mode available or any better idea ?

You could show two lines - one of the previous days/weeks temperatures and then a red (for example) line showing the current weeks/days temperature.

[Replies are now closed]