Search code examples
javascriptgoogle-visualization

Google charts: Uncaught TypeError: google.loader.writeLoadTag is not a function


Suddenly google charts is not working anymore, but I did not change any of the code.

I get this error in chrome:

jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['corechart']}]}:54 Uncaught TypeError: google.loader.writeLoadTag is not a function

Uncaught TypeError: google.visualization.DataTable is not a constructor
    at draw_stats (raven.js:3121)
    at show_stats (raven.js:3121)
    at HTMLDocument.<anonymous> (home.html:1279)
    at j (raven.js:3121)
    at Object.fireWith [as resolveWith] (raven.js:3121)
    at Function.ready (raven.js:3121)
    at HTMLDocument.J (raven.js:3121)

I load google charts like this (since like forever without problems):

<!-- google charts api -->
<script src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1','packages':['corechart']}]}"></script>

And the chart itself is a bit of a longer code, mixed with PHP and ajax (but it works :)):

function draw_stats(trainer_name) {

    // get data from input field
    var chart_data = $('#chart_data_' + trainer_name).val();

    chart_data = chart_data.replace(/'/g, '"');

    if (chart_data > '' && google != undefined && google > '')  {

        $("#loadingSpinner").prependTo(".home_stats_graph").show();
        $('.home_stats_container').show();
        var data = new google.visualization.DataTable();
        // get norm value
        var norm_data;
        $.ajax({
            url: "inc/run.php",
            data: {
                typ: "norm_val",
                tname: trainer_name
            },
            type: "GET",
            context: document.body,
            success: function(norm_data) {
                norm_data = parseFloat(norm_data);
                if (isNaN(norm_data)) {
                    norm_data = 0;
                }
                data.addColumn('date', '');
                data.addColumn('number', $('#trans_reaktionszeit').val());
                data.addColumn({
                    type: 'string',
                    role: 'style'
                });
                data.addColumn({
                    type: 'number',
                    role: 'annotation'
                });
                data.addColumn({
                    type: 'string',
                    role: 'tooltip',
                    'p': {
                        'html': true
                    }
                });
                data.addColumn('number', $('#trans_vergleichsdaten').val());
                chart_data = $.parseJSON(chart_data);
                $.each(chart_data, function(i, item) {
                    var date = new Date(item[0] * 1000);
                    item = new Array(date, item[1], 'point {size: ' + item[4] + '}', item[1], item[5], norm_data);
                    data.addRow(item);
                });
                var chart_color = $('html').css('background-color');
                if (chart_color != 'rgb(38, 34, 40)') {
                    var chart_font_color = '#000000';
                    var chart_line_color = 'black';
                } else {
                    var chart_font_color = '#ffffff';
                    var chart_line_color = 'yellow';
                }
                $('#blue_legend').css('background', chart_line_color);
                var font_fam = '<?=$gui->mainFont;?>';
                var options = {
                    series: {
                        1: {
                            visibleInLegend: false
                        }
                    },
                    colors: [chart_line_color, 'transparent'],
                    lineWidth: 0,
                    pointSize: 5,
                    width: '100%',
                    'chartArea': {
                        'top': '10',
                        'width': '85%',
                        'height': '85%'
                    },
                    vAxis: {
                        minValue: 0,
                        viewWindow: {
                            min: 0
                        },
                        textStyle: {
                            color: chart_font_color,
                            fontName: font_fam
                        },
                        title: $('#trans_reaktionszeit').val(),
                        titleTextStyle: {
                            color: chart_font_color,
                            fontName: font_fam
                        }
                    },
                    hAxis: {
                        format: $('#gg_haxis_format').val(),
                        textStyle: {
                            color: chart_font_color,
                            fontName: font_fam
                        }
                    },
                    legend: {
                        position: 'none',
                        textStyle: {
                            color: chart_font_color,
                            fontName: font_fam
                        }
                    },
                    displayAnnotations: true,
                    displayTooltips: true,
                    titleTextStyle: {
                        color: chart_font_color, // any HTML string color ('red', '#cc00cc')
                        fontName: font_fam, // i.e. 'Times New Roman'
                        fontSize: 22, // 12, 18 whatever you want (don't specify px)
                    },
                    backgroundColor: chart_color,
                    curveType: "function",
                    tooltip: {
                        textStyle: {
                            fontName: font_fam
                        },
                        isHtml: true
                    },

                };
                var chart = new google.visualization.ScatterChart(document.getElementById("popup_stats_container_" + trainer_name));


                chart.draw(data, options);
                $("#loadingSpinner").hide();
            }
        });
    }
}

The problem was reported by many users... Happend also on firefox:

Some more error details can be found on sentry: https://sentry.io/share/issue/87b5b61669e04ea0b097951c53d46520/


Solution

  • The long deprecated jsapi loader is now being redirected to the new loader at www.gstatic.com/charts/loader.js, which includes support for the autoload parameter, though if you plan to keep using this parameter, you will have to properly encode your autoload structure using encodeURI() and JSON.stringify().

    const autoloadParam = encodeURI(JSON.stringify(autoloadStruct));
    

    However, the problem reported here involves something else. Some places that use Google Charts appear to have built-in dependencies on some internal variables and functions of the jsapi loader, in particular, the google.loader.writeLoadTag. We are unlikely to support google.loader.writeLoadTag in the new loader.

    It might be best to just convert to using the new loader, which is documented here. Instead of the autoload parameter, just add calls to google.charts.load(), and google.charts.setOnLoadCallback();