我正在使用基于HTML5的库chartjs来动态绘制Bootstrap模式体内的图表。一切都很好,我可以看到已经传递了正确的数据和标签数组,并且已经创建了canvas HTML节点,但是我收到了这个错误:
Uncaught TypeError: Cannot read property 'offsetWidth' of undefined
我想也许我太早称这个功能了:
new Chart(--> HTML node <--).get(0).getContext("2d").Bar(--> data <--);
所以我把它放在setTimeout()块中以便在追加画布HTML节点2秒后调用该函数,但是我仍然收到该错误并且无法看到图表。
以下是完整的代码(github,Dropbox),这是我调用图表库的部分:
document.getElementById("modalBody").appendChild(canvasElement);
setTimeout(function () {
var ctx = document.getElementsByTagName("canvas")[0];
var myNewChart = new Chart(ctx).get(0).getContext("2d").Bar(finalData);
return finalData;
}, 2000);
答案 0 :(得分:2)
我设法让这个工作在Plunkr。
我为contextualizeForType2()
和contextualizeForType3()
所做更改的基础知识如下:
new Chart(ctx.getContext('2d')).Bar(finalData);
行后面有var ctx = ...
。但是,由于尚未显示模态,因此它的高度和宽度均为0. shown.bs.modal
事件。在该事件处理程序内部是您创建图表的位置。棘手的部分是因为你有两个不同的问题重用相同的模态。所以我添加了一个额外的.typeX
命名空间,当模态被隐藏时,我会取消注册我的事件。 我知道第二点令人困惑,但希望代码清除它:
var ctx = document.getElementsByTagName("canvas")[0];
$('#myModal').on({
'shown.bs.modal.type2': function() {
new Chart(ctx.getContext("2d")).Bar(finalData);
},
'hidden.bs.modal.type2': function() {
this.off('.type2');
}
});
这意味着一旦模态被隐藏,当为另一种类型显示相同的模态时,这两个函数不会再次运行。此外,由于每次单击按钮时都添加了新的处理程序,因此您无法创建超出需要的图表。
我有a further play并发现我可以将代码重构为一个可以从contextualizeForType2()
和contextualizeForType3()
调用的函数,并传入finalData
。这样做的好处是可以将所有画布和图表初始化代码保留在一个位置,从而简化了大型函数并使其更易于维护。
功能是:
function showModalChart(data) {
var canvasElement = document.createElement("CANVAS");
canvasElement.setAttribute("width", "400");
canvasElement.setAttribute("height", "400");
document.getElementById("modalBody").appendChild(canvasElement);
var ctx = document.getElementsByTagName("canvas")[0];
$('#myModal').off('.modalchart').on('shown.bs.modal.modalchart', function () {
new Chart(ctx.getContext('2d')).Bar(data);
});
}