为什么jqPlot显示了一个错误的饼图,其中包含通过AJAX检索的数据
Why does jqPlot show an erroroneous pie chart with data retrieved via AJAX?
我正在开发一个应用程序,在该应用程序中,我使用jqPlot使用通过AJAX检索的一些数据绘制饼图。然而,我注意到,生成的饼图是错误的。当我手动将数据放入数组时,饼图是正确的。
这是我代码的一部分。
$.ajax({
url:'http://localhost/mijson.php',
dataType:'json',
async:false,
success:function(data){
for(a in data){
var div_pintar = "<div id='divgrafica"+a+"' class='myChart'></div>";
$("#espacio_graficas").append(div_pintar);
var datos_tmp = [];
datos_tmp.push(['Ok',data[a]['ok']]);
datos_tmp.push(['Fail',data[a]['fail']]);
$.jqplot('divgrafica'+a, [datos_tmp], {
title:data[a]['label'] ,
seriesDefaults:{
renderer:$.jqplot.PieRenderer,
trendline:{ show: true },
},
legend:{ show: true }
});
...
我得到的JSON是:
[{"label":"FECHA","requer":56,"ok":28,"fail":28},
{"label":"TTM Y FECHA","requer":35,"ok":8,"fail":27}]
总之,它显示了一个饼图,例如,有两个值,但加起来是14%。
如果我使用ajaxDataRenderer
:,也会发生同样的情况
...
plo12 = $.jqplot('pieChart2', jsonurl,{
title: 'AJAX JSON Data Renderer',
dataRenderer: ajaxDataRenderer,
seriesDefaults: {
renderer: $.jqplot.PieRenderer,
rendererOptions: {
showDataLabels: true
}
},
legend: { show: true, location: 'e' }
});
...
如果没有更多信息,很难确定您的问题到底是什么。
然而,最明显的会导致错误图表的是使用:
for(a in data){
解析AJAX success:function
:返回的JSON object
,实际上是array
$.ajax({
success:function(data){
引用MDN上的"for…in"页面:
数组迭代和for。。。在
注意:对于。。in不应用于迭代索引顺序很重要的数组数组索引只是具有整数名称的可枚举属性,在其他方面与常规Object属性相同。不能保证。。。in将以任何特定顺序返回索引,将返回所有可枚举属性,包括具有非整数名称的属性和继承的属性。
因为迭代的顺序取决于实现,所以在数组上迭代可能不会以一致的顺序访问元素。因此,在访问顺序很重要的数组上迭代时,最好使用带有数字索引的for循环(或Array.forEach或for…of循环)。
在这种情况下,顺序很重要,因为无论使用何种浏览器,都应该希望图表的显示顺序相同。因此,您应该以确定性的方式处理数组的成员。
更重要的是:
仅在自己的属性上迭代
如果只想考虑附加到对象本身的属性,而不想考虑其原型,请使用
getOwnPropertyNames
或执行hasOwnProperty
检查(也可以使用propertyIsEnumerable
)。或者,如果您知道不会有任何外部代码干扰,您可以使用check方法扩展内置原型。
每个数组都有与其原型相关联的属性,而不仅仅是数组的成员。在没有任何限制的情况下,使用for(a in data){}
在处理过程中包括这些内容,几乎可以保证会导致错误显示。
另一种编码方法是使用forEach()
:
$.ajax({
url:'http://localhost/mijson.php',
dataType:'json',
async:false,
success:function(data){
data.forEach(function(curObject, a) {
var div_pintar = "<div id='divgrafica"+a+"' class='myChart'></div>";
$("#espacio_graficas").append(div_pintar);
var datos_tmp = [];
datos_tmp.push(['Ok',data[a]['ok']]);
datos_tmp.push(['Fail',data[a]['fail']]);
$.jqplot('divgrafica'+a, [datos_tmp], {
title:data[a]['label'] ,
seriesDefaults:{
renderer:$.jqplot.PieRenderer,
trendline:{ show: true },
},
legend:{ show: true }
});
...
注意:我通常会将所有的data[a]
引用更改为curObject
,但不这样做会起作用(数组索引作为a
传入),并且对代码的更改量最小。进行额外的更改应该会使代码稍微快一点,因为不必多次进行数组查找。
有了这些更改,并使用更具描述性的index
而不是a
,代码看起来像:
$.ajax({
url:'http://localhost/mijson.php',
dataType:'json',
async:false,
success:function(data){
data.forEach(function(curObject, index) {
var div_pintar = "<div id='divgrafica"+index+"' class='myChart'></div>";
$("#espacio_graficas").append(div_pintar);
var datos_tmp = [];
datos_tmp.push(['Ok',curObject['ok']]);
datos_tmp.push(['Fail',curObject['fail']]);
$.jqplot('divgrafica'+index, [datos_tmp], {
title:curObject['label'] ,
seriesDefaults:{
renderer:$.jqplot.PieRenderer,
trendline:{ show: true },
},
legend:{ show: true }
});
...
感谢Makyen的帮助,尽管他的回答很好,但错误仍然存在。经过16个多小时的尝试,我找到了解决方案,非常非常简单。
.....
var div_pintar = "<div id='divgrafica"+index+"' class='myChart'></div>";
$("#espacio_graficas").append(div_pintar);
var datos_tmp = [];
datos_tmp.push(['Ok',parseInt(datos[a]['ok'])]);
datos_tmp.push(['Fail',parseInt(datos[a]['fail'])]);
......
仅使用javascriptparseInt中的函数
我希望这能对其他人有所帮助。我损失了很多小时:(
- php函数的XMLHttpRequest响应不包含任何数据
- 在“加载更多”按钮函数中包含 JSON 数据
- 测试两个变量是否包含一些数据 JavaScript
- 从chrome扩展创建一个包含POST数据的链接
- 如何删除包含包含某些数据的单元格的表行
- 筛选包含大数据的html表(超过12K行)
- WebGL错误-错误:WebGL:bindBuffer:buffer已包含元素数据
- AngularFire $createUser 的承诺不返回包含用户数据的对象
- Javascript对象保留包含旧数据
- 绘制图表.js包含 ajax 数据和响应式.一些问题和疑问
- 打开包含帖子数据的弹出窗口
- 主干 - 实例化视图包含旧数据
- 角度:在包含外部数据的ng重复上搜索过滤器
- AngularJS - 刷新包含新数据的列表
- 在包含 JSON 数据的表中实现无限滚动
- 加载包含本地数据的手动表失败
- 使用 jQuery 生成一个包含 XML 数据的表
- CSRF - 伪造的 POST 可以包含任意数据吗?
- Ajax 请求在 URL 中包含奇数数据
- 将图片保存到包含画布数据保管箱