ScriptError:脚本已完成,但返回的值不是受支持的返回类型

时间:2017-07-09 16:11:09

标签: javascript charts google-apps-script google-sheets google-visualization

所以我整天都在尝试使用Google Apps脚本和图表API,不幸的是,它已经无处可去。

我做了很多事 - 包括遵循Mogsdad精心编写的教程setSpan。这是我到目前为止的代码 - 包括该教程,但我一直收到错误,说脚本已经完成,但返回的内容与接受的内容不同,或类似的东西。

Dashboard-Code.gs:

/**
 * Serves HTML of the application for HTTP GET requests.
 * From gist.github.com/mogsdad/24518dff348ad14d3929
 *
 * @param {Object} e event parameter that can contain information
 *     about any URL parameters provided.
 */
function doGet(e) {
  var template = HtmlService.createTemplateFromFile('Index');

  // Build and return HTML in IFRAME sandbox mode.
  return template.evaluate()
      .setTitle('Dashboard demo')
      .setSandboxMode(HtmlService.SandboxMode.IFRAME);
}


/**
 * Return all data from first spreadsheet as an array. Can be used
 * via google.script.run to get data without requiring publication
 * of spreadsheet.
 * From gist.github.com/mogsdad/24518dff348ad14d3929
 *
 * Returns null if spreadsheet does not contain more than one row.
 */
function getSpreadsheetData() {
  // This does not work, see https://code.google.com/p/google-apps-script-issues/issues/detail?id=5233
//  var ss = SpreadsheetApp.getActiveSpreadsheet();
//  var data = ss.getSheets()[0].getDataRange().getValues();
  var sheetId = '1-EE_WDD6QYi257_utUf_D0v5e9Gf8Lj5tETPqqllvxk';  // Replace with your spreadsheet ID. (Ick.)
  var data = SpreadsheetApp.openById(sheetId).getSheets()[0].getDataRange().getValues();
  return (data.length > 1) ? data : null;
}

的index.html:

<!-- Use a templated HTML printing scriptlet to import common 

stylesheet. -->
<?!= HtmlService.createHtmlOutputFromFile('Stylesheet').getContent(); ?>
<html>
  <body>
    <h1 id="main-heading">Loading...</h1>
    <div id="dashboard-div">
      <div id="control-div">
        <div id="selector-div">
        </div>
        <div id="selector1-div">
        </div>
      </div>
      <div id="charts-div">

        <div id="table-div">
        </div>
      </div>
    </div>
    <div class="hidden" id="error-message">
    </div>
  </body>
</html>

<!-- Store data passed to template here, so it is available to the
     imported JavaScript. -->
<script>
</script>

<!-- Use a templated HTML printing scriptlet to import JavaScript. -->
<?!= HtmlService.createHtmlOutputFromFile('JavaScript').getContent(); ?>

和JavaScript.html(我决定坚持Mogsdad所说的):

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript"  src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
    google.charts.load('45', {packages: ['corechart']});
    google.charts.setOnLoadCallback(drawChart);
</script>
<script>
  // Load the Visualization API and desired package(s).
  google.load('visualization', '1.0', {'packages':['controls']});
  /**
   * Run initializations on dialog load.
   */
  $(function() {
    // Set a callback to run when the Google Visualization API is loaded.
    // Note: could also be accomplished via google.load options.
    google.setOnLoadCallback(sendQuery);
    // Assign handler functions to dialog elements here, if needed.
    // Call the server here to retrieve any information needed to build
    // the dialog, if necessary.
  });
  /**
   * Issue asynchronous request for spreadsheet data.
   * From gist.github.com/mogsdad/60dcc4116ed74fceb5f9
   */
  function sendQuery() {
    google.script.run
      .withSuccessHandler(drawDashboard)
      .withFailureHandler(function(msg) {
            // Respond to failure conditions here.
            $('#main-heading').text(msg);
            $('#main-heading').addClass("error");
            $('#error-message').show();
          })
      .getSpreadsheetData();
  }
  /**
   * Callback function to generate visualization using data in response parameter.
   * From gist.github.com/mogsdad/60dcc4116ed74fceb5f9
   * 
   * @param {Object[][]}  Two-Dim array of visualization data
   */
  function drawDashboard(response) {
    $('#main-heading').addClass("hidden");
    if (response == null) {
      alert('Error: Invalid source data.')
      return;
    }
    else {
      // Transmogrify spreadsheet contents (array) to a DataTable object
      var data = google.visualization.arrayToDataTable(response,false);
      var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard-div'));


      var table = new google.visualization.ChartWrapper({
        'chartType': 'Table',
        'containerId': 'table-div'
      });

      var categoryPicker = new google.visualization.ControlWrapper({
        'controlType': 'CategoryFilter',
        'containerId': 'selector-div',
        'options': {
          'filterColumnLabel': 'Category'
        }
      });

      var subCategoryPicker = new google.visualization.ControlWrapper({
      'controlType': 'CategoryFilter',
      'containerId': 'selector1-div',
      'options': {
      'filterColumnLabel': 'Category'
      }
      });


      // Set up dependencies between controls and charts
      dashboard.bind([categoryPicker,subCategoryPicker], table);
      // Draw all visualization components of the dashboard
      dashboard.draw(data);
    }
  }  
</script>

我不需要数字滤波器,我需要的是与级联下拉列表+表类似的东西。

我很感激任何指针。我哪里错了?我不认为问题出在JS.html文件中 - 这可能与从Google表格中获取数据有关。

1 个答案:

答案 0 :(得分:2)

首先,不需要两个图表库,jsapi&amp; loader.js

根据release notes ...

  

通过jsapi加载程序保留的Google图表版本不再一致更新。请从现在开始使用新的gstatic loader.js

接下来,回调被设置为不存在的函数......

这里 - &gt; google.charts.setOnLoadCallback(drawChart);

建议类似以下设置...

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script>
  // Load the Visualization API and desired package(s).
  google.charts.load('45', {
    callback: sendQuery,
    packages: ['controls', 'corechart']
  });

  /**
   * Issue asynchronous request for spreadsheet data.
   * From gist.github.com/mogsdad/60dcc4116ed74fceb5f9
   */
  function sendQuery() {
    google.script.run
      .withSuccessHandler(drawDashboard)
      .withFailureHandler(function(msg) {
            // Respond to failure conditions here.
            $('#main-heading').text(msg);
            $('#main-heading').addClass("error");
            $('#error-message').show();
          })
      .getSpreadsheetData();
  }

  /**
   * Callback function to generate visualization using data in response parameter.
   * From gist.github.com/mogsdad/60dcc4116ed74fceb5f9
   * 
   * @param {Object[][]}  Two-Dim array of visualization data
   */
  function drawDashboard(response) {
    $('#main-heading').addClass("hidden");
    if (response == null) {
      alert('Error: Invalid source data.')
      return;
    }
    else {
      // Transmogrify spreadsheet contents (array) to a DataTable object
      var data = google.visualization.arrayToDataTable(response,false);
      var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard-div'));

      var table = new google.visualization.ChartWrapper({
        'chartType': 'Table',
        'containerId': 'table-div'
      });

      var categoryPicker = new google.visualization.ControlWrapper({
        'controlType': 'CategoryFilter',
        'containerId': 'selector-div',
        'options': {
          'filterColumnLabel': 'Category'
        }
      });

      var subCategoryPicker = new google.visualization.ControlWrapper({
        'controlType': 'CategoryFilter',
        'containerId': 'selector1-div',
        'options': {
          'filterColumnLabel': 'Category'
        }
      });


      // Set up dependencies between controls and charts
      dashboard.bind([categoryPicker,subCategoryPicker], table);
      // Draw all visualization components of the dashboard
      dashboard.draw(data);
    }
  }  
</script>

编辑

使用查询类的工作示例 - &gt; google.visualization.Query

google.charts.load('45', {
  callback: sendQuery,
  packages: ['controls', 'corechart']
});

function sendQuery() {
  var url = 'https://docs.google.com/spreadsheets/d/1-EE_WDD6QYi257_utUf_D0v5e9Gf8Lj5tETPqqllvxk/edit#gid=0';
  new google.visualization.Query(url).send(function (response) {
    if (response.isError()) {
      console.log('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
    } else {
      drawDashboard(response.getDataTable());
    }
  });
}

function drawDashboard(data) {
  $('#main-heading').addClass("hidden");
  var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard-div'));

  var table = new google.visualization.ChartWrapper({
    chartType: 'Table',
    containerId: 'table-div'
  });

  var categoryPicker = new google.visualization.ControlWrapper({
    controlType: 'CategoryFilter',
    containerId: 'selector-div',
    options: {
      filterColumnLabel: 'Category'
    }
  });

  var subCategoryPicker = new google.visualization.ControlWrapper({
    controlType: 'CategoryFilter',
    containerId: 'selector1-div',
    options: {
      filterColumnLabel: 'Category'
    }
  });

  dashboard.bind([categoryPicker,subCategoryPicker], table);
  dashboard.draw(data);
}
.hidden {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<h1 id="main-heading">Loading...</h1>
<div id="dashboard-div">
  <div id="control-div">
    <div id="selector-div">
    </div>
    <div id="selector1-div">
    </div>
  </div>
  <div id="charts-div">

    <div id="table-div">
    </div>
  </div>
</div>
<div class="hidden" id="error-message">
</div>