谷歌可视化:绘制图表后,JS执行在哪里重新开始?

时间:2017-06-12 15:51:50

标签: javascript asynchronous event-handling google-visualization

使用Google Visualizations https://jsfiddle.net/brisray/qsgewt2d/的小项目 - 尽我所能,但我对此有疑问。

绘制图形后,我假设控制权将传回" mainFunction"。这是一个循环遍历创建查询的对象数组的函数,然后调用绘制表和图表的其他函数。我希望为该函数添加更多代码,以便为我想做的其他事情调用其他函数。

我发现它不会那样工作。循环后的简单JS警报显示在确认警报之前没有完成任何绘图。

我错过了什么吗?也许处理完最后一个数组后触发的事件处理程序并绘制最后一个初始图形?与绘图的异步性质有关。

代码和我编写的方式是否存在根本性的错误?

无论发生什么,我都看不到,所以会感激一些帮助。

var SCOB_metrics = (function() {

  // Create the object array that is global to the namespace
  var graphArray = [];
  // Create objects and push them to the array
  // Object properties are: ID, sheet, GID, datatable, graphtype, rotated 

  createObject('MSDC', '1RCZiWWsEKPs6-1ULXeHjWmaXUEHCaRPtKT9U_6FzCJ4', '1835225366', 'MSDC_data', 'Column', false);
  createObject('StudentPop', '1RCZiWWsEKPs6-1ULXeHjWmaXUEHCaRPtKT9U_6FzCJ4', '3256521', 'StudentPop_data', 'Column', false);
  createObject('EnrolTrends', '1RCZiWWsEKPs6-1ULXeHjWmaXUEHCaRPtKT9U_6FzCJ4', '1037635451', 'EnrolTrends_data', 'Column', false);

  google.charts.load('current');
  google.charts.setOnLoadCallback(mainFunction);

  function mainFunction() {
    for (i = 0; i < graphArray.length; i++) {
      makeQuery(graphArray[i]);
    }
    // Now everthing is drawn, set up the listener for the drawingArea div
    // so that the graphs can be updated if needed
    var theParent = document.querySelector("#drawingArea");
    theParent.addEventListener("change", whichDrop, false);
  }

  function makeQuery(myObject) {
    // Create the querystring and send it 
    var queryStr = "https://docs.google.com/spreadsheets/d/" + myObject.sheet + "/gviz/tq?gid=" + myObject.GID + "&headers=1";
    var query = new google.visualization.Query(queryStr);
    /* You can't send a variable though the normal query.send method
    query.send(handleQueryResponse);
    so do this */
    query.send(function(response) {
      visuals(response, myObject);
    });
  }

  function whichDrop(e) {
    // Find which dropdown was changed, get it's value, find the index of the graphArray.ID it belongs to and redraw the graph
    if (e.target !== e.currentTarget) {
      var changedItem = e.target.id;
    }
    e.stopPropagation();
    var findID = changedItem.substr(0, changedItem.length - 4);
    arrayIndex = graphArray.findIndex(x => x.ID == findID);
    var e = document.getElementById(changedItem);
    var chosenGraph = e.options[e.selectedIndex].value;
    graphArray[arrayIndex].graphtype = chosenGraph;
    drawGraphs(graphArray[arrayIndex]);
  }

  function visuals(response, myObject) {
    // Create the data table and draw both the table and graph
    myObject.datatable = response.getDataTable();
    drawTables(myObject);
    drawGraphs(myObject);
  }

  function drawTables(myObject) {
    // Draw the table
    var tableArea = myObject.ID + "_table_div";
    var cssClassNames = {
      'headerRow': 'header-css',
      'headerCell': 'border-css'
    };
    theTables = new google.visualization.ChartWrapper({
      chartType: 'Table',
      containerId: tableArea,
      dataTable: myObject.datatable,
      options: {
        'allowHtml': true,
        'cssClassNames': cssClassNames
      }
    });
    theTables.draw();
  }

  function drawGraphs(myObject) {
    // Draw the graph
    var graphArea = myObject.ID + "_graph_div";
    var chartType = myObject.graphtype + "Chart";
    theGraphs = new google.visualization.ChartWrapper({
      chartType: chartType,
      containerId: graphArea,
      dataTable: myObject.datatable,
      // May have to use IF or SWITCH statements depending on chartType
      options: {
        height: 400,
        hAxis: {
          maxTextLines: 4, // maximum number of lines to wrap to
          maxAlternation: 4, // maximum layers of labels (setting this higher than 1 allows labels to stack over/under each other)
          minTextSpacing: 1, // minimum space in pixels between adjacent labels
        },
        textStyle: {
          fontSize: 9
        }
      }
    });
    theGraphs.draw();
  }

  function transposeDataTable(myObject) {
    // Transpose the datatable 
    dataTable = myObject.datatable;
    // Toggle rotated boolean
    myObject.rotated = !myObject.rotated;
    // Rotate the datatable
    var rows = []; //the row tip becomes the column header and the rest become
    for (var rowIdx = 0; rowIdx < dataTable.getNumberOfRows(); rowIdx++) {
      var rowData = [];
      for (var colIdx = 0; colIdx < dataTable.getNumberOfColumns(); colIdx++) {
        rowData.push(dataTable.getValue(rowIdx, colIdx));
      }
      rows.push(rowData);
    }
    var newTB = new google.visualization.DataTable();
    newTB.addColumn('string', dataTable.getColumnLabel(0));
    newTB.addRows(dataTable.getNumberOfColumns() - 1);
    var colIdx = 1;
    for (var idx = 0; idx < (dataTable.getNumberOfColumns() - 1); idx++) {
      var colLabel = dataTable.getColumnLabel(colIdx);
      newTB.setValue(idx, 0, colLabel);
      colIdx++;
    }
    for (var i = 0; i < rows.length; i++) {
      var rowData = rows[i];
      console.log(rowData[0]);
      newTB.addColumn('number', rowData[0]); //assuming the first one is always a header
      var localRowIdx = 0;

      for (var j = 1; j < rowData.length; j++) {
        newTB.setValue(localRowIdx, (i + 1), rowData[j]);
        localRowIdx++;
      }
    }
    return newTB;
  }

  function createObject(ID, sheet, GID, datatable, graphtype, rotated) {
    // Create the data objects and push them to the graphArray array 
    graphArray.push({
      ID: ID,
      sheet: sheet,
      GID: GID,
      datatable: datatable,
      graphtype: graphtype,
      rotated: rotated,
    });
  }
})();

2 个答案:

答案 0 :(得分:0)

我认为您正在寻找准备好的&#39;事件。 https://developers.google.com/chart/interactive/docs/events#the-ready-event

答案 1 :(得分:0)

我放弃了我想要做的事情,即逐步浏览各种图表类型列表,看看哪些是最适合我想要显示的内容。

我想看的一件事是创建各种图表的PNG。但是,我犯了&#34;准备好&#34;事件处理程序再次。

在我绘制图表之前,我使用了

google.visualization.events.addListener(theGraphs,&#39; ready&#39;,function(){         document.getElementById(imgLink).innerHTML =&#39; Printable Graph&#39 ;;           });

但我得到了#34;无法阅读财产&#39; getImageURI&#39; of null&#34;错误。

大概是因为循环这些图的绘制在,它运行得太快,事件处理程序无法捕获?

我尝试在使用

绘制图表后删除事件处理程序

google.visualization.events.removeListener(theGraphs);

甚至

google.visualization.events.removeAllListeners(theGraphs);

我曾经想过做一些事情,比如试图计算触发事件的次数,并将其与调用函数的次数进行比较,但是为了更简单但可能不是添加setTimeout的最佳方法功能

setTimeout(function(){       document.getElementById(imgLink).innerHTML =&#39; Printable Graph&#39 ;;     },100);     theGraphs.draw();

可能不是最优雅的解决方案,但只有1/10秒的延迟导致了我已经离开的问题。

https://jsfiddle.net/brisray/z49jw264/706/

setTimeout(function() {
  document.getElementById(imgLink).innerHTML = '<a target="_blank" href="' + theGraphs.getChart().getImageURI() + '">Printable Graph</a>';
}, 100);
theGraphs.draw();