【问题标题】:Why does jqPlot show an erroroneous pie chart with data retrieved via AJAX?为什么 jqPlot 显示带有通过 AJAX 检索的数据的错误饼图?
【发布时间】:2019-12-10 03:29:08
【问题描述】:

我正在开发一个应用程序,其中我使用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' }
    });
    ...

【问题讨论】:

  • 您对所见错误的描述不清楚。请提供错误绘图(使用 AJAX 数据)和正确绘图(使用手动插入数据)的屏幕截图。当您“手动将数据放入数组”时,请提供您用于绘制饼图的代码(这样我们可以看到您如何插入它并绘制数据,因为有两个不同的结果意味着您以不同的方式执行此操作而不是通过 AJAX 接收 JSON)。

标签: javascript jquery ajax jqplot


【解决方案1】:

如果没有更多信息,很难确定您的问题到底是什么。

然而,导致错误图表的最明显的事情是使用:

for(a in data){

解析JSONobject,实际上是一个array,已经被AJAX返回了success:function

$.ajax({
    success:function(data){

引用"for...in" page on MDN

数组迭代和 for...in
注意:for..in 不应用于迭代索引顺序很重要的数组。

数组索引只是具有整数名称的可枚举属性,在其他方面与一般对象属性相同。 不保证 for...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 }
            });
            ...

【讨论】:

    【解决方案2】:

    感谢帮助我的 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'])]);
        ......
    

    仅适用于 javascript parseInt

    的函数

    我希望这可以对其他人有所帮助。 我失去了很多小时:(

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多