Question

I am getting a 'Object Type doesn't match Column Type' error and not sure why... not sure if its something wrong in my code (more than likely) or if it just won't accept the dashboard. I am thinking that my error has to do with the Data Source and how I'm pulling the data from the spreadsheet.

function doGet() {
  var app = UiApp.createApplication().setTitle('DHS: Kurzweil Calendar');

  //Create stack panel
  var stackPanel = app.createStackPanel().setSize('100%', '100%');
  var info = about(app);
  var p1 = app.createVerticalPanel().setId('vrtPanel1').add(info);
  var cal = calendar(app);
  var p2 = app.createVerticalPanel().setId('vrtPanel2').add(cal);
  var form = formBuild(app);
  var p3 = app.createVerticalPanel().setId('vrtPanel3').add(form);

  //add widgets to each stack panel, and name the stack panel
  stackPanel.add(p1, 'About the Lab');
  stackPanel.add(p2, 'Lab Calendar');
  stackPanel.add(p3, 'Lab Scheduling');

  //Add the panel to the application
  app.add(stackPanel);
  return app;
}

function about(app){
  return app.createHTML('<br />' + 
                        '<p>The Kurzweil Lab at Davie High School supports <i>20 independent student workstations</i> and is designed for the specific use of Kurzweil software.  The lab\'s main objective is to support students who have a Read-Aloud accommodation on their Individual Education Plan (IEP).  If a student does not have a Read-Aloud accommodation, but has another accommodation like: Separate Setting, Extended Time, or English as a Second Language (ESL) then they are welcome in the lab as long as the lab is not full.  If the lab reaches capacity and Read-Aloud students need to use Kurzweil, the student(s) without a Read-Aloud accommodation or who are refusing their Read-Aloud accommodation will be asked to go back to their classroom so that the teacher can make other arrangements for that student.</p>' + 
                        '<p>During non-testing situations the Kurzweil Lab can be scheduled by EC teachers to help with study skills, individual projects, or other work that requires the use of a computer lab.</p>', true);
}

function calendar(app){
  // Create Data Source
  var ss = SpreadsheetApp.openById('0Aur3owCpuUY-dGJIOGZ1LXhqT2FNMGVXSGNJazFnUmc');
  var datasource = ss.getSheetByName('Schedule').getRange(1,1,ss.getLastRow(),ss.getLastColumn());

  // Create Charts and Controls
  var dateFilter = Charts.newCategoryFilter()
      .setFilterColumnLabel("Date").build();
  var teacherFilter = Charts.newCategoryFilter()
      .setFilterColumnLabel("Teacher").build();
  var subjectFilter = Charts.newCategoryFilter()
      .setFilterColumnLabel("Subject").build();
  var periodFilter = Charts.newCategoryFilter()
      .setFilterColumnLabel("Period").build();
  var typeFilter = Charts.newCategoryFilter()
      .setFilterColumnLabel("Type").build();
  var tableChart = Charts.newTableChart().build();

  //Create and bind Dashboard
  var dashboard = Charts.newDashboardPanel()
      .setDataTable(datasource)
      .bind([dateFilter, teacherFilter, subjectFilter, periodFilter, typeFilter], [tableChart])
      .build();

  //Create Application
  dashboard.add(app.createVerticalPanel()
                .add(app.createHorizontalPanel()
                     .add(dateFilter).add(teacherFilter).add(subjectFilter).add(periodFilter).add(typeFilter)
                     .setSpacing(70))
                .add(app.createHorizontalPanel()
                     .add(tableChart)
                     .setSpacing(10)));

  //Add the panel to the application
  app.add(dashboard);
  return app;
}
Was it helpful?

Solution

You simply forgot that you changed the way every function that build the UI returns data... If you remember your first post about stackPanels we changed the call to

  var cal = calendar(app);

and then

  var p2 = app.createVerticalPanel().setId('vrtPanel2').add(cal);

So we clearly expect to get a Ui object (a widget) in return.

You can simply change the end of the function calendar(app){ like below :

  ...
  dashboard.add(app.createVerticalPanel()
                .add(app.createHorizontalPanel()
                     .add(dateFilter).add(teacherFilter).add(subjectFilter).add(periodFilter).add(typeFilter)
                     .setSpacing(70))
                .add(app.createHorizontalPanel()
                     .add(tableChart)
                     .setSpacing(10)));

  //Add the panel to the application
  return dashboard;// return the dashboard itself, not the app.
}

EDIT : this was definitely to simple to be true... my answer was correct but obviously didn't include the issues with the dashboard building.

After a few researches (I've never used Charts service before) I came to this code that produces no errors but I'm definitely not sure it returns what you wanted...

Nevertheless it should help you to find your way. (don't blame me if it doesn't look right ;-)

function calendar(app){
  // Create Data Source
  var ss = SpreadsheetApp.openById('0Aur3owCpuUY-dGJIOGZ1LXhqT2FNMGVXSGNJazFnUmc');
  var sh = ss.getSheetByName('Schedule');
  var datasource = sh.getRange(1,2,sh.getLastRow(),sh.getLastColumn()).getValues();
  Logger.log(datasource)
  var dataTable = Charts.newDataTable();
  for( var j in datasource[0] ){
  dataTable.addColumn(Charts.ColumnType.STRING, datasource[0][j]);
  }
  for( var i = 1; i < datasource.length; ++i ){
  dataTable.addRow(datasource[i].map(String));
  }
var dashboard = Charts.newDashboardPanel().setDataTable(dataTable);  // Create Charts and Controls
  var dateFilter = Charts.newCategoryFilter()
      .setFilterColumnLabel("Date").setDataTable(dataTable).build();
  var teacherFilter = Charts.newCategoryFilter()
      .setFilterColumnLabel("Teacher").setDataTable(dataTable).build();
  var subjectFilter = Charts.newCategoryFilter()
      .setFilterColumnLabel("Subject").setDataTable(dataTable).build();
  var periodFilter = Charts.newCategoryFilter()
      .setFilterColumnLabel("Period").setDataTable(dataTable).build();
  var typeFilter = Charts.newCategoryFilter()
      .setFilterColumnLabel("Type").setDataTable(dataTable).build();
  var tableChart = Charts.newTableChart().setDimensions(1000, 600).setDataTable(dataTable).build();

  //Create and bind Dashboard
  var dashboard = Charts.newDashboardPanel()
      .setDataTable(dataTable)
      .bind([dateFilter, teacherFilter, subjectFilter, periodFilter, typeFilter], [tableChart])
      .build();

  //Create Application
  var dashBoardPanel = app.createVerticalPanel()
  dashBoardPanel.add(app.createHorizontalPanel()
                     .add(dateFilter).add(teacherFilter).add(subjectFilter).add(periodFilter).add(typeFilter)
                     .setSpacing(30));
  dashBoardPanel.add(tableChart);

  //Add the panel to the application
  return dashBoardPanel;
}

EDIT 2 : to get the first column as a date you have to slightly modify the for loops that populate the dataTables so that you can convert to string only from the second column.

I did it like this :

function calendar(app){
      // Create Data Source
      var ss = SpreadsheetApp.openById('0Aur3owCpuUY-dGJIOGZ1LXhqT2FNMGVXSGNJazFnUmc');
      var sh = ss.getSheetByName('Schedule');
      var datasource = sh.getRange(1,1,sh.getLastRow(),sh.getLastColumn()).getValues();
      Logger.log(datasource)
      var dataTable = Charts.newDataTable();
      dataTable.addColumn(Charts.ColumnType.DATE, datasource[0][1]);
      for( var j=2 ;j< datasource[0].length ;++j ){
        dataTable.addColumn(Charts.ColumnType.STRING, datasource[0][j]);
      }
      for( var i = 1; i < datasource.length; ++i ){
        var datarow = [];
        datarow.push(datasource[i][1]);
        for( var j=2 ;j< datasource[0].length ;++j ){
          datarow.push(datasource[i][j].toString());
        }
        dataTable.addRow(datarow);
      }
         var dashboard = Charts.newDashboardPanel().setDataTable(dataTable);  // Create Charts and Controls
          ...

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top