1

Hello, I have a timeline made with google charts, what I want to do is update it every so often, for example every 5 seconds, I get the data from a json, I tried it this way but it didn't work for me:

setTimeout(function () {
            drawChart();
        }, 5000);

Is there any way to do it?

google.load("visualization", "1", {packages: ["timeline"]});
    google.setOnLoadCallback(drawChart);

    // google.charts.setOnLoadCallback(drawChart);
    function drawChart() {
        $(".timeline").each(function () {
            var obje = {{ devicejson|safe }};
            var elem = $(this),
                id = elem.attr('id');
            var container = document.getElementById(id);
            var chart = new google.visualization.Timeline(container);
            var dataTable = new google.visualization.DataTable();
            dataTable.addColumn({type: 'string', id: 'Role'});
            dataTable.addColumn({type: 'string', id: 'Name'});
            dataTable.addColumn({type: 'date', id: 'Start'});
            dataTable.addColumn({type: 'date', id: 'End'});
            dataTable.addColumn({type: 'string', id: 'TimeEst'});
            dataTable.addColumn({type: 'string', role: 'style'});
            for (n = 0; n < obje.length; ++n) {
                if (obje[n].device_id == id) {
                    dataTable.addRows([
                        ['Department', obje[n].digitaloutput_user_description, new Date('"' + obje[n].startdatetime + '"'), new Date('"' + obje[n].enddatetime + '"'), obje[n].lighstate_user_description, obje[n].color],
                    ]);
                }
            }

            for (n = 0; n < obje.length; ++n) {
                if (obje[n].device_id == id) {
                    console.log(obje[n].color)

                }
            }

            var options = {
                chartArea: {
                    height: '90%',
                    width: '100%',
                    top: 36,
                    right: 12,
                    bottom: 2,
                    left: 12
                },
                height: 100,
                tooltip: {isHtml: true},
                timeline: {
                    showRowLabels: false,
                },
                avoidOverlappingGridLines: false,
                {#hAxis: {format: 'dd-MMM-yyyy HH:mm:ss'}#}

            };

            var formatTime = new google.visualization.DateFormat({
                pattern: 'yyyy-MM-dd HH:mm:ss a'
            });

            var view = new google.visualization.DataView(dataTable);
            view.setColumns([0, 1, {
                role: 'tooltip',
                type: 'string',
                calc: function (dt, row) {
                    // build tooltip
                    var dateBegin = dt.getValue(row, 2);
                    var dateEnd = dt.getValue(row, 3);
                    var oneHour = (60 * 1000);
                    var duration = (dateEnd.getTime() - dateBegin.getTime()) / oneHour;

                    var tooltip = '<div><div class="ggl-tooltip"><span>';
                    tooltip += dt.getValue(row, 0) + ':</span>&nbsp;' + dt.getValue(row, 1) + '</div>';
                    tooltip += '<div class="ggl-tooltip"><div>' + formatTime.formatValue(dateBegin) + ' - ';
                    tooltip += formatTime.formatValue(dateEnd) + '</div>';
                    tooltip += '<div><span>Duration: </span>' + duration.toFixed(0) + ' minutes</div>';
                    tooltip += '<div><span>Estate: </span>' + dt.getValue(row, 5) + '</div></div>';

                    return tooltip;
                },
                p: {html: true}
            }, 2, 3]);

            google.visualization.events.addListener(chart, 'ready', function () {
                var labels = container.getElementsByTagName('text');
                Array.prototype.forEach.call(labels, function (label) {
                    label.setAttribute('font-weight', 'normal');
                });
            });

            chart.draw(view.toDataTable(), options);


        })
        setTimeout(function () {
            drawChart();
        }, 5000);
    }
Saul JP
  • 325
  • 2
  • 11

1 Answers1

0

for starters, the old version of google charts should no longer be used.

replace the old library...

<script src="https://www.google.com/jsapi"></script>

with the new library...

<script src="https://www.gstatic.com/charts/loader.js"></script>

this will only change the load statement.
which can be found in the following snippet...


next, it appears you are loading the data from the server, here...

var obje = {{ devicejson|safe }};

JavaScript runs on the client.
so no matter how many times drawChart is called,
it will always use the same data received from the server on the first page load.

instead, try this...

create two pages, one that returns the data, and the other that draws the chart.
then you can use AJAX to get the data and draw the chart as many times as needed.

create a new page, and all you really need in the new page is the following line of code.

{{ devicejson|safe }}

aside from any header information, and existing code you're using to get the data to the current page.
but you don't want to assign it to a variable in the new page.
just write the data to the page using the above statement.

then you can use AJAX to get the data and draw the chart.

function getData() {
    $.ajax({
      url: 'get_data.url',   // <-- use url to new page here
      dataType: 'JSON'
    }).done(function (data) {
      drawChart(data);
    });
}

then, wait for the chart's ready event, before calling setTimeout.
because we don't know how long it will take to get the data and draw the chart.
so let's wait for the first chart to finish, before trying again.

see following snippet...

google.charts.load('current', {
  packages:['timeline']
}).then(getData);            // <-- load google charts, then get the data

function getData() {
    $.ajax({
      url: 'get_data.url',   // <-- use url to new page here
      dataType: 'JSON'
    }).done(function (data) {
      drawChart(data);       // <-- draw chart with data from new page
    });
}


function drawChart(obje) {
    $(".timeline").each(function () {
        var elem = $(this),
            id = elem.attr('id');
        var container = document.getElementById(id);
        var chart = new google.visualization.Timeline(container);
        var dataTable = new google.visualization.DataTable();
        dataTable.addColumn({type: 'string', id: 'Role'});
        dataTable.addColumn({type: 'string', id: 'Name'});
        dataTable.addColumn({type: 'date', id: 'Start'});
        dataTable.addColumn({type: 'date', id: 'End'});
        dataTable.addColumn({type: 'string', id: 'TimeEst'});
        dataTable.addColumn({type: 'string', role: 'style'});
        for (n = 0; n < obje.length; ++n) {
            if (obje[n].device_id == id) {
                dataTable.addRows([
                    ['Department', obje[n].digitaloutput_user_description, new Date('"' + obje[n].startdatetime + '"'), new Date('"' + obje[n].enddatetime + '"'), obje[n].lighstate_user_description, obje[n].color],
                ]);
            }
        }

        for (n = 0; n < obje.length; ++n) {
            if (obje[n].device_id == id) {
                console.log(obje[n].color)

            }
        }

        var options = {
            chartArea: {
                height: '90%',
                width: '100%',
                top: 36,
                right: 12,
                bottom: 2,
                left: 12
            },
            height: 100,
            tooltip: {isHtml: true},
            timeline: {
                showRowLabels: false,
            },
            avoidOverlappingGridLines: false,
            {#hAxis: {format: 'dd-MMM-yyyy HH:mm:ss'}#}

        };

        var formatTime = new google.visualization.DateFormat({
            pattern: 'yyyy-MM-dd HH:mm:ss a'
        });

        var view = new google.visualization.DataView(dataTable);
        view.setColumns([0, 1, {
            role: 'tooltip',
            type: 'string',
            calc: function (dt, row) {
                // build tooltip
                var dateBegin = dt.getValue(row, 2);
                var dateEnd = dt.getValue(row, 3);
                var oneHour = (60 * 1000);
                var duration = (dateEnd.getTime() - dateBegin.getTime()) / oneHour;

                var tooltip = '<div><div class="ggl-tooltip"><span>';
                tooltip += dt.getValue(row, 0) + ':</span>&nbsp;' + dt.getValue(row, 1) + '</div>';
                tooltip += '<div class="ggl-tooltip"><div>' + formatTime.formatValue(dateBegin) + ' - ';
                tooltip += formatTime.formatValue(dateEnd) + '</div>';
                tooltip += '<div><span>Duration: </span>' + duration.toFixed(0) + ' minutes</div>';
                tooltip += '<div><span>Estate: </span>' + dt.getValue(row, 5) + '</div></div>';

                return tooltip;
            },
            p: {html: true}
        }, 2, 3]);

        google.visualization.events.addListener(chart, 'ready', function () {
            var labels = container.getElementsByTagName('text');
            Array.prototype.forEach.call(labels, function (label) {
                label.setAttribute('font-weight', 'normal');
            });

            setTimeout(getData, 5000);       // <-- get data and draw again in 5 seconds
        });

        chart.draw(view.toDataTable(), options);
    });
}
WhiteHat
  • 59,912
  • 7
  • 51
  • 133