Форматирование номера диаграммы Google Table отображает NaN при использовании форматированного числового значения с запятой

#javascript #html #google-visualization

#javascript #HTML #google-визуализация

Вопрос:

Как часто бывает, когда у Google выходит крупный выпуск их библиотеки диаграмм, что-то ломается. Следующий код был реализован около 3 лет назад и отлично работал в течение нескольких лет, и в течение последнего года он сломался таким образом

Я заполняю таблицу данных и форматирую числа с помощью этого кода

             var formatter = new google.visualization.NumberFormat({pattern:'#,###.##'});

        var cl = jsonChartData.rows[0].c.length;
        for (var c=0;c<cl;c  ) {
            if (jsonChartData.cols[c].type == 'number'){
                formatter.format(popDataTable, c);
            }
        }
  

и это хорошо работает и дает такой результат: v: 6155177.2549019605, f: '6,155,177.25'

И поддерживается документацией здесь, диаграмма таблицы Google, здесь, общие форматеры, и здесь, ICU 58.1

Я заполняю представление, которое передается объекту диаграммы, используя следующий код

             var tabOpt = {
                width: '100%'
                ,allowHtml: true
                ,cssClassNames: {
                    tableRow: 'chartTabRow'
                    ,oddTableRow: 'chartTabRow'
                    ,headerRow: 'chartHeadRow'
                    ,tableCell: 'chartTabRow'
                    ,headerCell: 'chartHeadRow'
                    }
                };
        var wdt = popDataTable;
        wdt.sort([
            {column: colID(wdt, 'sumlev')}
            ,{column: colID(wdt, 'estyear')}
            ,{column: colID(wdt, 'estdata')}
            ,{column: popFactCol, desc:  true}]);
        dView = new google.visualization.DataView(wdt);
        dView.setRows(dView.getFilteredRows([
            {column: colID(dView, 'sumlev'), value: '010'}
            ,{column: colID(dView, 'estdata'), value: popFact}
            ,{column: colID(dView, 'estyear'), value: popFactYear}]));

        var jsonPopParams = {
          "cols":
              [
              {"id":"","label":"Parameter(N)","pattern":"","type":"string"},
              {"id":"","label":"Value","pattern":"","type":"number"}
              ]
              ,
              "rows":
              [
                {"c":
                [
                {"v":"N","f":null},
                {"v":0,"f":null}
                ]
                },
                {"c":
                [
                {"v":"Sum","f":null},
                {"v":0,"f":null}
                ]
                },
                {"c":
                [
                {"v":"Min","f":null},
                {"v":0,"f":null}
                ]
                },
                {"c":
                [
                {"v":"Max","f":null},
                {"v":0,"f":null}
                ]
                },
                {"c":
                [
                {"v":"Range","f":null},
                {"v":0,"f":null}
                ]
                },
               {"c":
                [
                {"v":"Mean","f":null},
                {"v":0,"f":null}
                ]
                },
               {"c":
                [
                {"v":"Median","f":null},
                {"v":0,"f":null}
                ]
                },
               {"c":
                [
                {"v":"Variance","f":null},
                {"v":0,"f":null}
                ]
                },
               {"c":
                [
                {"v":"Standard Dev","f":null},
                {"v":0,"f":null}
                ]
                },
               {"c":
                [
                {"v":"Skewness","f":null},
                {"v":0,"f":null}
                ]
                },
               {"c":
                [
                {"v":"Kurtosis","f":null},
                {"v":0,"f":null}
                ]
                }]
              ,
              "p":null
              };

        jsonPopParams.rows[0].c[1].f = dView.getFormattedValue(0, colID(dView, 'pn'));
        jsonPopParams.rows[1].c[1].f = dView.getFormattedValue(0, colID(dView, 'psum'));
        jsonPopParams.rows[2].c[1].f = dView.getFormattedValue(0, colID(dView, 'pmin'));
        jsonPopParams.rows[3].c[1].f = dView.getFormattedValue(0, colID(dView, 'pmax'));
        jsonPopParams.rows[4].c[1].f = dView.getFormattedValue(0, colID(dView, 'prange'));
        jsonPopParams.rows[5].c[1].f = dView.getFormattedValue(0, colID(dView, 'pmean'));
        jsonPopParams.rows[6].c[1].f = dView.getFormattedValue(0, colID(dView, 'pmedian'));
        jsonPopParams.rows[7].c[1].f = dView.getFormattedValue(0, colID(dView, 'pvariance'));
        jsonPopParams.rows[8].c[1].f = dView.getFormattedValue(0, colID(dView, 'pstndev'));
        jsonPopParams.rows[9].c[1].f = dView.getFormattedValue(0, colID(dView, 'pskew'));
        jsonPopParams.rows[10].c[1].f = dView.getFormattedValue(0, colID(dView, 'pkurt'));

        var tblChart = new google.visualization.Table(document.getElementById(paramDiv));
        wdt = new google.visualization.DataTable(jsonPopParams);
        var tblView = new google.visualization.DataView(wdt);
        tblChart.draw(tblView, tabOpt);
  

Устанавливая точку останова и выполняя пошаговое выполнение каждой инструкции, я вижу, что для форматированного значения заполняется объект JSON jsonPopParams.

Так, например, pmean имеет форматированное значение '6,155,177.25'

При визуализации диаграммы любое значение, имеющее запятую в форматировании, отображает NaN.

Я создал рабочий сокращенный пример в JS Fiddle здесь:

Там я протестировал три сценария

  • форматированное значение не имеет запятых и 2 десятичных знака ###.## при view.getFormattedValue использовании и выдает 6 155 177,25. Это, конечно, обходной путь

  • форматированное значение имеет запятые и 2 десятичных знака, #,###.## используя view.getFormattedValue , и выдает NaN, что он делает прямо сейчас

  • форматированное значение содержит запятые и 2 десятичных знака, но использует view.getValue и выдает 6 155 177,255 позиции младшего порядка по умолчанию должны быть равны 3… это работает, но не в соответствии со спецификацией.

Поэтому я не уверен, что

1) Раньше я делал это неправильно, и мне это сходило с рук, а теперь Google устранил основную причину, и теперь мой неправильный код больше не работает

или

2) Google что-то сломал, и теперь мой правильный код больше не работает.

Надеюсь, вторая пара глаз со свежим взглядом все же сможет увидеть.

Любая помощь будет оценена. Спасибо

Комментарии:

1. Обновлен пример кода и JSFiddle для присвоения правильному элементу .f форматированного значения. jsonPopParams.rows[5].c[1].f = dView.getFormattedValue(0, colID(dView, 'pmean'));

Ответ №1:

проблема, похоже, в этих строках…

 jsonPopParams.rows[0].c[1].v = dView.getFormattedValue(0, colID(dView, 'pn'));
jsonPopParams.rows[1].c[1].v = dView.getFormattedValue(0, colID(dView, 'psum'));
....  
  

свойство value ( v ) устанавливается с форматированным значением ( f )

так что это должно быть либо…

 jsonPopParams.rows[0].c[1].f = dView.getFormattedValue(0, colID(dView, 'pn'));
  

или…

 jsonPopParams.rows[0].c[1].v = dView.getValue(0, colID(dView, 'pn'));
  

или обоих…

 jsonPopParams.rows[0].c[1].v = dView.getValue(0, colID(dView, 'pn'));
jsonPopParams.rows[0].c[1].f = dView.getFormattedValue(0, colID(dView, 'pn'));
  

когда здесь создается DataTable…

 var tblChart = new google.visualization.Table(document.getElementById(paramDiv));
wdt = new google.visualization.DataTable(jsonPopParams);
....  
  

вместо чисел используются строки,

поскольку тип столбца — number -> {"id":"","label":"Value","pattern":"","type":"number"}
NaN , возвращается

Комментарии:

1. Да, это именно так. Что имеет смысл: числовое значение преобразуется в v (число), а форматированное значение — в f (строка). В меньших числах нет запятых, и поэтому число в виде строки может быть преобразовано в целое число. Более новая версия библиотеки должна обеспечивать лучшую безопасность типов. Я не помню 3 года назад, но присвоение v было рабочим ответом. Спасибо