从另一个函数访问Google可视化。

3
我有以下带过滤、排序和分页的谷歌仪表板。
我将通过编程修改源数据。我需要能够从其包含的函数外部访问谷歌可视化,以便刷新它。
例如:`renderChart_onPageLoad` 包含所有谷歌代码。我需要从函数 `outsideGV` 访问它。通常在 `renderChart_onPageLoad` 内部,我会调用 `table.draw()`,但我无法从函数 `outsideGV` 中获取访问权限。我必须在刷新之间保持任何用户分页、排序和筛选。
FYI...我尝试再次调用 `renderChart_onPageLoad` 函数,但它会清除所有用户输入的分页、排序、过滤信息,并重置可视化结果。
感谢您的反馈。
更新: 在给定页面上可能不止一个变量 `data` 的存在。我为页面上的每个图表都有一个名为 `data` 的变量。
我有许多由相同的 `drawDashboard_` 函数绘制的谷歌表格。是否可以将这些引用收集到全局数组中?
const globalReferences = [];

我希望在每次执行drawDashboard_时填写它。这样做可以在所有变量被创建后收集它们吗?

globalReferences.push({
  "chartID":suffix, //this is my unique identifier for each pass of the function
  "data": data,
  "dashboard": dashboard,
  "categoryPicker": categoryPicker,
  "proxyTable": proxyTable,
  "table": table
});

我可以从这里引用来访问特定的图表吗?

   globalReferences[0].table; 
//get the reference, make some change, and then redraw.

google.charts.load('current', {
  'packages': ['corechart', 'table', 'gauge', 'controls', 'charteditor']
});

var listenerPage = {};
var listenerSort = {};

var sourceData = [
  ['Name', 'RoolNumber', 'Gender', 'Age', 'DonutsEaten'],
  ['Michael', 1, 'Male', 12, 5],
  ['Elisa', 2, 'Female', 20, 7],
  ['Robert', 3, 'Male', 7, 3],
  ['John', 4, 'Male', 54, 2],
  ['Jessica', 5, 'Female', 22, 6],
  ['Aaron', 6, 'Male', 3, 1],
  ['Margareth', 7, 'Female', 42, 8],
  ['Miranda', 8, 'Female', 33, 6]
]

$(document).ready(function() {
  renderChart_onPageLoad();
});

function referenceGV() {

  //ON BUTTON CLICK 
  //1 UPDATD sourceData - Make a change programatically
  //1 REFRESH GV
  //    must retaining all selected user filtering, sorting, paging

}

function renderChart_onPageLoad() {
  google.charts.setOnLoadCallback(function() {
    drawDashboard_A("A");
  });
}

function drawDashboard_A(suffix) {

  var data = google.visualization.arrayToDataTable(sourceData);

  var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard_' + suffix));

  var categoryPicker = new google.visualization.ControlWrapper({
    controlType: 'CategoryFilter',
    containerId: 'categoryPicker_' + suffix,
    options: {
      filterColumnLabel: 'Gender',
      ui: {
        labelStacking: 'vertical',
        allowTyping: false,
        allowMultiple: false
      }
    }
  });

  var proxyTable = new google.visualization.ChartWrapper({
    chartType: 'Table',
    containerId: 'proxyTable_' + suffix,
    options: {
      width: '500px'
    }
  });

  var table = new google.visualization.ChartWrapper({
    chartType: 'Table',
    containerId: 'table_' + suffix,
    options: {
      sort: 'event', // <-- set sort to 'event' for table totaling
      width: '500px',
      allowHtml: true,
      page: 'enable',
      pageSize: '3',
    }
  });

  //This json contains my settings for later
  let json = {
    "tableChart": {
      "hasTable": true,
      "dataView": {
        "columns": [{
            "id": "Name"
          },
          {
            "id": "RoolNumber"
          },
          {
            "id": "Gender"
          },
          {
            "id": "Age"
          },
          {
            "id": "DonutsEaten"
          }
        ]
      },
      "clickGetFunc": clickGetFunc
    },
  };

  function clickGetFunc(result, wrapperDataTable) {
    console.log(result, wrapperDataTable)
  }

  google.visualization.events.addOneTimeListener(proxyTable, 'ready', function() {
    //console.log(suffix + ".addOneTimeListener(proxyTable, 'ready' - sort");

    google.visualization.events.addOneTimeListener(table, 'ready', function() {
      //console.log(suffix + ".addOneTimeListener(table, 'ready' - sort");

      //#region table - sort: 'event'
      google.visualization.events.addListener(table.getChart(), 'sort', function(sender) {
        console.log(suffix + ".addListener(table.getChart(), 'sort' - sorted");

        // sort data table according to sort properties
        var tableData = table.getDataTable();
        var sortIndexes = tableData.getSortedRows({
          column: sender.column,
          desc: !sender.ascending
        });

        // set table sort arrow
        table.setOption('sortAscending', sender.ascending);
        table.setOption('sortColumn', sender.column);

        // set table view & re-draw table
        table.setView({
          rows: sortIndexes
        });
        table.draw();

        //Table ready then fires
      });
      //#endregion

    });
  });

  google.visualization.events.addOneTimeListener(proxyTable, 'ready', function() {
    google.visualization.events.addListener(table, 'ready', function() {
      lib_gcharts_selectedRowCol(table, json.tableChart.clickGetFunc); //(wrapperName, callback)
    });
  });

  google.visualization.events.addListener(proxyTable, 'ready', function() {
    refGV = proxyTable;

    redrawTable(json.tableChart);
  });

  dashboard.bind([categoryPicker], [proxyTable]);
  dashboard.draw(data);

  //This is a table builder which uses json from above.  This is working ok.  Contains no listeners.
  function redrawTable(tableChart) {

    // set defaults for any undefined settings
    let dataView = (tableChart.dataView !== undefined) ? tableChart.dataView : [];

    // update .draw() 'table' or 'chart' references when using a different or additional chart name

    var sourceData = proxyTable.getDataTable().toDataTable().clone();
    //console.log('sourceData', sourceData);

    //#region create data view - this is used as basis for dataResults
    let view = new google.visualization.DataView(sourceData);

    //#region create group view - if required
    let dataResults_forTable;
    dataResults_forTable = view.toDataTable().clone();

    //#endregion

    var finalView_forTable = new google.visualization.DataView(dataResults_forTable);
    //console.log('finalView_forTable', finalView_forTable);

    // set reset sorting, set dataTable & draw chart
    table.setView(null); // reset in case sorting has been used via user click
    table.setDataTable(finalView_forTable); //includes any total row
    table.draw();

  } //END redrawChart()

}



function lib_gcharts_selectedRowCol(chartWrapper, callback, clicks) {
  //console.log('chartWrapper', chartWrapper); console.log('callback', callback)

  //2021-07-26 added clicks functionality (click or dblclick)

  //NEW - Works with paging active
  // initialize page number and size
  var page = 0;
  var pageSize = 10;
  if (chartWrapper.getOption('page') === 'enable') {
    page = chartWrapper.getOption('startPage');
    pageSize = chartWrapper.getOption('pageSize');
  }
  enableCoordinates(callback);

  // remove previous event handlers if they exist 
  if (listenerPage.hasOwnProperty(chartWrapper.getContainerId())) {
    google.visualization.events.removeListener(listenerPage[chartWrapper.getContainerId()]);
    delete listenerPage[chartWrapper.getContainerId()];
  }
  if (listenerSort.hasOwnProperty(chartWrapper.getContainerId())) {
    google.visualization.events.removeListener(listenerSort[chartWrapper.getContainerId()]);
    delete listenerSort[chartWrapper.getContainerId()];
  }

  // page event - assigns chartWrapper.getContainerId() as unique identifier for listener
  listenerPage[chartWrapper.getContainerId()] = google.visualization.events.addListener(chartWrapper.getChart(), 'page', function(sender) {
    //console.log(".addListener(chartWrapper.getChart(), 'page' - paged - enableCoordinates called");
    page = sender.page; // save current page
    enableCoordinates(callback);
  });

  // sort event - assigns chartWrapper.getContainerId() as unique identifier for listener
  listenerSort[chartWrapper.getContainerId()] = google.visualization.events.addListener(chartWrapper.getChart(), 'sort', function() {
    //console.log(".addListener(chartWrapper.getChart(), 'sort' - sorted - enableCoordinates called ")
    page = 0; // reset back to first page
    enableCoordinates(callback);
  });

  function enableCoordinates(callback) {
    //console.log('enableCoordinates', callback);

    var container = document.getElementById(chartWrapper.getContainerId());

    // remove existing enableCoordinates event listeners from all TD elements
    Array.prototype.forEach.call(container.getElementsByTagName('TD'), function(cell) {
      //cell.removeEventListener("dblclick", selectCell, false);//2021-07-21
      cell.removeEventListener(clicks, selectCell, false);
    });

    // add new enableCoordinates event listeners to all TD elements
    Array.prototype.forEach.call(container.getElementsByTagName('TD'), function(cell) {
      //cell.addEventListener('dblclick', selectCell, false);//2021-07-21
      cell.addEventListener(clicks, selectCell, false);
    });
  }

  function selectCell(event) {
    //console.log('sender', sender);

    //2021-07-26 re-write for google crud
    //1. renamed parameter "sender" to "event" for standard reference 
    //Consider building in the functionality for google crud

    //var cell = sender.target;

    //Get selected cell TD element
    var cell = event.target;
    if (event.target.tagName === 'I') {
      cell = event.target.parentNode; //if icon clicked set cell = parentNode for TD element
    }
    var row = cell.closest('tr');

    var wrapperDataTable = chartWrapper.getDataTable();

    var selectedRow = row.rowIndex - 1; // adjust for header row (-1)
    selectedRow = (page * pageSize) + selectedRow; // adjust for page number

    // Original from whitehat - save sorted info
    // This version does not work after a user clicks a column to sort
    //var sortInfo = chartWrapper.getChart().getSortInfo();  
    //if (sortInfo.sortedIndexes !== null) {
    //    selectedRow = sortInfo.sortedIndexes[selectedRow];
    //}  

    // Replaced code to which finds the view row order by .getView then taking the selected row 
    // and returning the number which is in the .getView result
    var sortInfo = chartWrapper.getView(); // save sorted info
    if (sortInfo !== null) {
      selectedRow = sortInfo.rows[selectedRow];
    }
    var selectedCol = cell.cellIndex;

    //var result = "selectedRow: " + selectedRow + " selectedCol: " + selectedCol;
    //var ul = document.getElementById("demo");
    //var li = document.createElement("li");
    //li.innerHTML = result;
    //ul.appendChild(li);

    var selectedValue = wrapperDataTable.getValue(selectedRow, selectedCol);
    var colID = wrapperDataTable.getColumnId(selectedCol);
    var colLabel = wrapperDataTable.getColumnLabel(selectedCol);

    var result = {
      "selectedRow": selectedRow,
      "selectedCol": selectedCol,
      "selectedValue": selectedValue,
      "colID": colID,
      "colLabel": colLabel,
      "event": event, //2021-07-26
      "chartWrapper": chartWrapper //2021-07-9
    };

    callback(result, wrapperDataTable);
  }
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="dashboardA">
  <div id="categoryPicker_A"></div><br />
  <div id="proxyTable_A" style="display:none;"></div>
  <div id="table_A"></div><br /><br />
</div>

<button onclick="referenceGV()">
referenceGV
</button>

1个回答

0

只需要在全局空间中声明变量,类似于你的sourceData...

并且从原始声明中删除var语句。

只需确保不在变量创建之前尝试访问这些变量...

google.charts.load('current', {
  'packages': ['corechart', 'table', 'gauge', 'controls', 'charteditor']
});

var listenerPage = {};
var listenerSort = {};

var sourceData = [
  ['Name', 'RoolNumber', 'Gender', 'Age', 'DonutsEaten'],
  ['Michael', 1, 'Male', 12, 5],
  ['Elisa', 2, 'Female', 20, 7],
  ['Robert', 3, 'Male', 7, 3],
  ['John', 4, 'Male', 54, 2],
  ['Jessica', 5, 'Female', 22, 6],
  ['Aaron', 6, 'Male', 3, 1],
  ['Margareth', 7, 'Female', 42, 8],
  ['Miranda', 8, 'Female', 33, 6]
]

// declare variables here
var data;
var dashboard;
var categoryPicker;
var proxyTable;
var table;


$(document).ready(function() {
  renderChart_onPageLoad();
});

function referenceGV() {

  //ON BUTTON CLICK 
  //1 UPDATD sourceData - Make a change programatically
  //1 REFRESH GV
  //    must retaining all selected user filtering, sorting, paging

}

function renderChart_onPageLoad() {
  google.charts.setOnLoadCallback(function() {
    drawDashboard_A("A");
  });
}

function drawDashboard_A(suffix) {

  // remove var statement from here
  data = google.visualization.arrayToDataTable(sourceData);

  dashboard = new google.visualization.Dashboard(document.getElementById('dashboard_' + suffix));

  categoryPicker = new google.visualization.ControlWrapper({
    controlType: 'CategoryFilter',
    containerId: 'categoryPicker_' + suffix,
    options: {
      filterColumnLabel: 'Gender',
      ui: {
        labelStacking: 'vertical',
        allowTyping: false,
        allowMultiple: false
      }
    }
  });

  proxyTable = new google.visualization.ChartWrapper({
    chartType: 'Table',
    containerId: 'proxyTable_' + suffix,
    options: {
      width: '500px'
    }
  });

  table = new google.visualization.ChartWrapper({
    chartType: 'Table',
    containerId: 'table_' + suffix,
    options: {
      sort: 'event', // <-- set sort to 'event' for table totaling
      width: '500px',
      allowHtml: true,
      page: 'enable',
      pageSize: '3',
    }
  });


嗨,我在上面添加了一个更新部分。我可以使用全局数组来收集引用吗?非常感谢您的帮助! - cmill
1
那应该可以工作,你肯定可以将它们收集到一个数组中,只是可能难以知道你想要使用数组中的哪个索引。另一个选项是使用对象-- var globalReferences = {}; globalReferences.A = { "chartID":suffix, "data": data, "table": table ...}; -- 然后访问-- globalReferences.A.table - WhiteHat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接