Данные диаграммы, экспортированные в веб-приложение скрипта приложения, имеют нулевое значение - PullRequest
0 голосов
/ 04 июня 2018

У меня есть Google Sheet, для которого я использую базу данных для проектов, над которыми работает моя команда.Я хочу использовать эти данные для создания разных экранов на сайте Google.Например, я смог добавить выпадающий список, в котором показаны все активные проекты.Когда проект выбран, возвращается и отображается таблица HTML.

Теперь я пытаюсь добавить диаграмму Ганта к клиентскому HTML, данные которого взяты из того же Google Sheet.Я многое экстраполировал из того, что мне удалось сделать, чтобы отобразить команды, и использовал документацию gviz в качестве ресурса для информации о графике.Большая часть моего кода работает хорошо, но у меня возникают проблемы при отправке данных диаграммы со стороны листов в клиентский HTML.

В коде построения моего графика у меня есть оператор Logger.log, который показывает, что chartData - это Array и что он содержит данные, которые я ожидаю:

function buildChart(project) {
  var detailsSheet = ss.getSheetByName("Details");
  var details = detailsSheet.getRange(2, 1, detailsSheet.getLastRow(), detailsSheet.getLastColumn()).getValues();

  // get the list of teams working on the selected project
  var teams = getTeamsFromProjects(project, details);  // Works, not shown.

  // get the list of teams, without the category
  var sendTeams = new Array();
  for (l in teams) {
    var lRow = teams[l];
    sendTeams.push(lRow[0]);
  }

  // get the projects that the teams are working on
  var projectList = getProjectsFromTeams(sendTeams, details);  // Works, not shown.

  var chartData = getChartDataFromProjects(projectList, details); // Works, not shown.
  Logger.log(chartData);  // this shows that my data is there, in an array

  return chartData;
}

В HTML веб-приложения у меня есть console.log("HTML: " + HTML), который правильно показывает возвращенный HTML (из функции .gs, displayTeams(), и выглядит правильно. Также в HTML у меня есть console.log("chart data: " + chartData), который должен отображать возвращаемый массив.Тем не менее, консоль говорит, что chartData имеет значение NULL.

Мой вопрос: почему chartData возвращается (или, по крайней мере, записывается в журнал консоли веб-приложения) как NULL, когда я могу видеть изApps Script Logger.log() заявление - непосредственно перед возвратом - что данные правильно являются массивом?

Некоторые из моих соответствующих HTML-файлов:

<!DOCTYPE html>
<html>
  <style>
    table, th, td {
      border: 5px solid White;
    }
    th {
      font-weight: bold;
    }
  </style>

  <head>
    <base target="_top">
    <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
    </script>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js">
    </script>
    <script>
      // get the list of Open Projects for the Drop Down
      $(function() {
        google.script.run.withSuccessHandler(buildProjectList)
          .getProjects();
      });

      function buildProjectList(options) {
        var list = $('#projectList');
        list.empty();
        for (var i = 0; i < options.length; i++) {
          list.append('<option value="' + options[i] + '">' + options[i] + '</option>');
        }
      }

      // function called when a Project is selected from the Drop Down
      function showResults() {
        var selectedProject = $('#projectList').val();
        google.script.run.withSuccessHandler(displayTeams)
          .buildTeams(selectedProject);
        google.script.run.withSuccessHandler(drawChart)
          .buildChart(selectedProject); //THIS IS MY PROBLEM STATEMENT
      }

      // add the teams to the div
      function displayTeams(html) {
        console.log(“html: “ + html);
        $('div.results_div').html(html);
      }

      // add the chart to the div (I HOPE)
      google.charts.load('current', {'packages':['gantt']});

      function drawChart(chartData) {
        console.log("chart data: " + chartData); // chartData is missing here
        var data = new google.visualization.DataTable();
        data.addColumn('string', 'Task ID');
        data.addColumn('string', 'Task Name');
        data.addColumn('string', 'Resource');
        data.addColumn('date', 'Start Date');
        data.addColumn('date', 'End Date');
        data.addColumn('number', 'Duration');
        data.addColumn('number', 'Percent Complete');
        data.addColumn('string', 'Dependencies');

        data.addRows(chartData);

        var options = {
          height: 400,
          gantt: {
            trackHeight: 30
          }
        }

        var chart = new google.visualization.Gantt(document.getElementByClassName("chart_div"));

        chart.draw(data, options);
      }
    </script>
  </head>
  <body>
    Select a Project from this list<br><br>

    Projects:<br>
      <select onchange='showResults();' id="projectList" name="project"></select>
      <br>
    <div class="results_div"></div>
    <br>
    <div class="chart_div"></div>
  </body>
</html>

1 Ответ

0 голосов
/ 04 июня 2018

Возможно, вы отправляете несовместимые типы данных: согласно документации клиент-сервер , запросы с Date s не будут выполняться.

Мой предпочтительный метод для google.script.run связи - 1) отправлять все Date с в виде миллисекунд через Date().getTime(), так как это также позволит избежать проблем с часовыми поясами и различий в размерах строк, зависящих от браузера.Затем в клиенте вы можете переназначить свои входные данные обратно в объект Date, вызвав new Date(milliseconds_value), то есть

function successHandler(rectangularArrayData) {
  // Array indices of column values that need to be converted back to Date objects.
  const dateIndices = [0, 3, 8 /**, etc... */];
  // In general, pass your received data into a transformation function. This particular
  // example assumes you only need to remap milliseconds to Date objects.
  const chartData = rectangularArrayData.map(function (row) {
    return row.map(function (col, index) {
      // If this column index should be a date, make it a Date from the milliseconds input.
      // Otherwise, do nothing to it.
      return (dateIndices.indexOf(index) === -1) ? col : new Date(col);
    });
  });
  ...
}

и 2) сериализовав их в строку JSON перед отправкой.Иногда вы просто отправляете слишком сложный объект и конвертируете его в строку с помощью (JSON.stringify) до того, как return поможет убедиться, что он не поврежден в проводе.В клиенте ваш обработчик успеха должен просто восстановить его с помощью JSON.parse().

Есть пара других вещей, которые вы делаете (например, опрометчивый и непереносимый for...in итерация Array s , с использованием new Array() вместо [] или выполнением нескольких сравнений для проверки определенной переменной для одного из нескольких текстовых значений вместо использования метода Array#indexOf), который можно улучшить, но они выходят за рамки вашего вопроса, а не являются источником вашей проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...