Google 图表在没有抛出异常的情况下无法工作
Google chart not working without throwing an exception
我们使用 AJAX 来显示用户的统计信息 - 每月发送和接收的电子邮件数量(当月和前 12 个月)。我正在使用 Google 图表。当我在没有 AJAX 的情况下这样做时它有效,但是在 AJAX Google 图表中不起作用 - 整个页面变为空白并且控制台中没有异常。这是我的代码:
<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 之前有效。有什么问题?
顺便说一句,我只加载了这个月和上个月的数据,这不是错误。将来我们可以显示前 12 个月。
我尝试在函数 drawTitleSubtitle()
中使用 console.log 但它似乎根本没有被调用。但是AJAXreturns结果(第二次调用)后<html>
里面没有<body>
。
JS fiddle - http://jsfiddle.net/uriwise/Lpsb0tqn/
您看到的行为(“drawTitleSubtitle()
[...] 似乎未被调用”)主要是由于执行操作的顺序。
因为您正在加载所需的包 (google.load(...)
) 并在 $(document).ready()
中设置所需的回调 (google.setOnLoadCallback(...)
),Google 图表 API 无法在最终加载包时引用所需的回调 (drawTitleSubtitle()
)。
您应该定义 drawTitleSubtitle()
,加载所需的包 (google.load(...)
) 并在输入 $(document).ready()
之前设置所需的回调 google.setOnLoadCallback(...)
。
在 $(document).ready()
中,try_ajax()
应调用 drawTitleSubtitle()
,同时传递来自 /ajax/user/email_statistics
的所需 Ajax 响应。
最终我按照 Lee 的建议进行了操作,并在没有等待 $(document).ready()
的情况下调用了 google
函数。这是我的代码:
编辑:我将我的代码分成 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_ajax
和 draw_google_chart
总是在 $(document).ready()
之后被调用,而不是之前(因为我需要 HTML 元素在 DOM).
JS fiddle - http://jsfiddle.net/uriwise/tp1xhun0/
但是,如果我在 $(document).ready()
中调用 google
函数,那么它不起作用,我再次得到空白页。我没有在 Google 的网站上找到这个记录:
$(document).ready(function() {
google.load('visualization', '1', {packages: ['corechart', 'bar']});
google.setOnLoadCallback(try_ajax_first_time);
});
我们使用 AJAX 来显示用户的统计信息 - 每月发送和接收的电子邮件数量(当月和前 12 个月)。我正在使用 Google 图表。当我在没有 AJAX 的情况下这样做时它有效,但是在 AJAX Google 图表中不起作用 - 整个页面变为空白并且控制台中没有异常。这是我的代码:
<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 之前有效。有什么问题?
顺便说一句,我只加载了这个月和上个月的数据,这不是错误。将来我们可以显示前 12 个月。
我尝试在函数 drawTitleSubtitle()
中使用 console.log 但它似乎根本没有被调用。但是AJAXreturns结果(第二次调用)后<html>
里面没有<body>
。
JS fiddle - http://jsfiddle.net/uriwise/Lpsb0tqn/
您看到的行为(“drawTitleSubtitle()
[...] 似乎未被调用”)主要是由于执行操作的顺序。
因为您正在加载所需的包 (google.load(...)
) 并在 $(document).ready()
中设置所需的回调 (google.setOnLoadCallback(...)
),Google 图表 API 无法在最终加载包时引用所需的回调 (drawTitleSubtitle()
)。
您应该定义 drawTitleSubtitle()
,加载所需的包 (google.load(...)
) 并在输入 $(document).ready()
之前设置所需的回调 google.setOnLoadCallback(...)
。
在 $(document).ready()
中,try_ajax()
应调用 drawTitleSubtitle()
,同时传递来自 /ajax/user/email_statistics
的所需 Ajax 响应。
最终我按照 Lee 的建议进行了操作,并在没有等待 $(document).ready()
的情况下调用了 google
函数。这是我的代码:
编辑:我将我的代码分成 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_ajax
和 draw_google_chart
总是在 $(document).ready()
之后被调用,而不是之前(因为我需要 HTML 元素在 DOM).
JS fiddle - http://jsfiddle.net/uriwise/tp1xhun0/
但是,如果我在 $(document).ready()
中调用 google
函数,那么它不起作用,我再次得到空白页。我没有在 Google 的网站上找到这个记录:
$(document).ready(function() {
google.load('visualization', '1', {packages: ['corechart', 'bar']});
google.setOnLoadCallback(try_ajax_first_time);
});