Google图表在没有抛出异常的情况下无效

时间:2015-11-11 14:55:20

标签: javascript jquery ajax charts google-visualization

我们正在使用AJAX显示用户的统计信息 - 每月发送和接收的电子邮件数量(当月和过去12个月)。我正在使用Google图表。当我在没有AJAX的情况下完成它时,它可以工作,但是使用AJAX谷歌图表不起作用 - 整个页面变成空白,控制台中没有例外。这是我的代码:

<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
    $(document).ready(function() {
        var params = {
            "email": "{{ statistics_user_email }}",
            "today_email_statistics_query_job_json": JSON.stringify({{ today_email_statistics_query_job_json|safe }}),
            "this_month_email_statistics_query_job_json": JSON.stringify({{ this_month_email_statistics_query_job_json|safe }}),
            "last_13_months_monthly_email_statistics_query_job_json": JSON.stringify({{ last_13_months_monthly_email_statistics_query_job_json|safe }})
        };

        function try_ajax() {
            $.ajax({
                type: 'POST',
                url: '/ajax/user/email_statistics',
                data: params,
                success: function(reply) {
                    if (reply.wait === true) {
                        // Try again after 4 seconds.
                        setTimeout(try_ajax, 4000);
                    } else if (reply.ready === true) {
                        function drawTitleSubtitle() {
                            var data = new google.visualization.DataTable();
                            data.addColumn('string', 'Month');
                            data.addColumn('number', 'Emails sent');
                            data.addColumn('number', 'Emails received');

                            var rows = [];
                            for (var i = 0; i < reply["last_13_months_monthly_email_statistics"].length; i++) {
                                var row = reply["last_13_months_monthly_email_statistics"][i];
                                rows.push([row["month"], row["sent"], row["received"]]);
                            }
                            data.addRows(rows);

                            var options = {
                                'title': 'How Many Vegan Cheeseburgers I Ate Last Night',
                                'width': 400,
                                'height': 300
                            };

                            var material = new google.charts.Bar(document.getElementById('last-13-month-chart-div'));
                            material.draw(data, options);
                        }

                        $("#today-emails-sent-span").html(reply["today_email_statistics"]["messages_sent"]);
                        $("#today-emails-received-span").html(reply["today_email_statistics"]["messages_received"]);
                        $("#this-month-emails-sent-span").html(reply["this_month_email_statistics"]["messages_sent"]);
                        $("#this-month-emails-received-span").html(reply["this_month_email_statistics"]["messages_received"]);
                        google.load('visualization', '1', {packages: ['corechart', 'bar']});
                        google.setOnLoadCallback(drawTitleSubtitle);
                        $("#please-wait-div").addClass("hidden");
                        $("#email-statistics-div").removeClass("hidden");
                    } else {
                        console.error("AJAX returned unexpected results!", reply);
                    }
                }
            });
        }

        try_ajax();
    });
</script>

当我评论以下几行时,它没有图表:

                        google.load('visualization', '1', {packages: ['corechart', 'bar']});
                        google.setOnLoadCallback(drawTitleSubtitle);

AJAX一次返回此对象:

{"wait": true}

第二次:

{"ready": true, "last_13_months_monthly_email_statistics": [{"received": 23, "sent": 2, "month": "2015-10"}, {"received": 15, "sent": 4, "month": "2015-11"}], "this_month_email_statistics": {"messages_received": 15, "messages_sent": 4}, "today_email_statistics": {"messages_received": 0, "messages_sent": 1}}

我没有包含HTML,但页面上存在所有元素。一切都有效,除了图表,之前我没有使用过AJAX。有什么问题?

顺便说一下,我只加载了本月和上个月的数据,这不是一个bug。将来我们可以展示前12个月。

我尝试在函数drawTitleSubtitle()中使用console.log但似乎根本没有调用。但是在AJAX返回结果之后<body>内没有<html>(第二次调用它)。

JS小提琴 - http://jsfiddle.net/uriwise/Lpsb0tqn/

2 个答案:

答案 0 :(得分:1)

您正在目睹的行为(“drawTitleSubtitle() [...]似乎没有被调用”)主要是由于正在执行的操作的顺序。

由于您正在加载所需的包(google.load(...))并在google.setOnLoadCallback(...)内设置所需的回调($(document).ready()),因此Google Charts API无法引用所需的回调({ {1}})最终加载包时。

您应该定义drawTitleSubtitle(),加载所需的包(drawTitleSubtitle())并在输入google.load(...)之前设置所需的回调google.setOnLoadCallback(...)

$(document).ready()内,$(document).ready()应在从try_ajax()传入所需的Ajax响应时调用drawTitleSubtitle()

答案 1 :(得分:0)

最终我做了Lee所建议的并且在不等待google的情况下调用$(document).ready()函数。这是我的代码:

编辑:我将代码分成3个独立的函数,并在调用它们时传递参数。

<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
    function draw_google_chart(ajax_reply) {
        var data = new google.visualization.DataTable();
        data.addColumn('string', 'Month');
        data.addColumn('number', 'Emails sent');
        data.addColumn('number', 'Emails received');

        var rows = [];
        for (var i = 0; i < ajax_reply["last_13_months_monthly_email_statistics"].length; i++) {
            var row = ajax_reply["last_13_months_monthly_email_statistics"][i];
            rows.push([row["month"], row["sent"], row["received"]]);
        }
        data.addRows(rows);

        var options = {
            'title': 'How Many Vegan Cheeseburgers I Ate Last Night',
            'width': 400,
            'height': 300
        };

        var material = new google.charts.Bar(document.getElementById('last-13-month-chart-div'));
        material.draw(data, options);
    }

    function try_ajax(ajax_params) {
        $.ajax({
            type: 'POST',
            url: '/ajax/user/email_statistics',
            data: ajax_params,
            success: function(ajax_reply) {
                if (ajax_reply.wait === true) {
                    // Try again after 4 seconds.
                    setTimeout(function() {
                        try_ajax(ajax_params);
                    }, 4000);
                } else if (ajax_reply.ready === true) {
                    $("#today-emails-sent-span").html(ajax_reply["today_email_statistics"]["messages_sent"]);
                    $("#today-emails-received-span").html(ajax_reply["today_email_statistics"]["messages_received"]);
                    $("#this-month-emails-sent-span").html(ajax_reply["this_month_email_statistics"]["messages_sent"]);
                    $("#this-month-emails-received-span").html(ajax_reply["this_month_email_statistics"]["messages_received"]);
                    draw_google_chart(ajax_reply);
                    $("#please-wait-div").addClass("hidden");
                    $("#email-statistics-div").removeClass("hidden");
                } else {
                    console.error("AJAX returned unexpected results!", ajax_reply);
                }
            }
        });
    }

    function try_ajax_first_time() {
        $(document).ready(function() {
            var ajax_params = {
                "email": "{{ statistics_user_email }}",
                "today_email_statistics_query_job_json": JSON.stringify({{ today_email_statistics_query_job_json|safe }}),
                "this_month_email_statistics_query_job_json": JSON.stringify({{ this_month_email_statistics_query_job_json|safe }}),
                "last_13_months_monthly_email_statistics_query_job_json": JSON.stringify({{ last_13_months_monthly_email_statistics_query_job_json|safe }})
            };

            try_ajax(ajax_params);
        });
    }

    google.load('visualization', '1', {packages: ['corechart', 'bar']});
    google.setOnLoadCallback(try_ajax_first_time);
</script>

请注意,函数try_ajaxdraw_google_chart始终在$(document).ready()之后调用,从未使用过(因为我需要将HTML元素放在DOM中)。

JS小提琴 - http://jsfiddle.net/uriwise/tp1xhun0/

但是,如果我在google内拨打$(document).ready()个功能,那么它无法正常工作,我会再次获得空白页面。我没有在谷歌的网站上找到这个文件:

$(document).ready(function() {
    google.load('visualization', '1', {packages: ['corechart', 'bar']});
    google.setOnLoadCallback(try_ajax_first_time);
});