人到中年有点甜
仪表板仅出现在最后一行的原因是因为只有一个仪表板元素。当它执行循环时,它将仪表板附加并移动到每个单元格,循环完成时最终到达最后一行。我们不使用现有的仪表板元素,而是动态添加仪表板元素,每一行一个。在这里,我们使用 html 模板来存储仪表板内容。<!-- template: dashboard template --><script id="template-dashboard" type="text/html"> <div id="dashboard-{{Id}}" style="border: 1px solid #ccc;"> <table class="columns"> <tr> <td> <div id="chart-{{Id}}"></div> <div id="control-{{Id}}" style="padding-left: 2em; min-width: 250px;"></div> </td> </tr> </table> </div></script>然后将内容添加到每个表格单元格,使用行索引作为每个仪表板和控件的 ID。// insert dashboard htmltableCell.insertAdjacentHTML('beforeEnd', renderTemplate('template-dashboard', { Id: rowIndex}));然后我们可以使用 id 引用新创建的元素...// build dashboardvar dashboardContainer = tableCell.appendChild(document.getElementById('dashboard-' + rowIndex));请参阅以下工作片段...google.charts.load('current', { 'packages': ['corechart', 'controls', 'table', 'charteditor']});google.charts.setOnLoadCallback(drawChart);function drawChart() { var tableData = new google.visualization.DataTable(); tableData.addColumn('string', 'Name'); tableData.addColumn('number', 'Salary'); tableData.addColumn('string', 'Chart'); tableData.addColumn('string', 'Test'); tableData.addRows([ ['Mike', { v: 10000, f: '$10,000' }, null, '5thFirst'], ['Jim', { v: 8000, f: '$8,000' }, null, '5thSecond'], ['Alice', { v: 12500, f: '$12,500' }, null, '5thThird'], ['Bob', { v: 7000, f: '$7,000' }, null, '5thForth'] ]); var table = new google.visualization.Table(document.getElementById('table_div')); google.visualization.events.addListener(table, 'ready', function() { // table body Array.prototype.forEach.call(table.getContainer().getElementsByTagName('tbody'), function(tableBody) { // table rows Array.prototype.forEach.call(tableBody.rows, function(tableRow, rowIndex) { // table cells Array.prototype.forEach.call(tableRow.cells, function(tableCell, cellIndex) { // determine cell if (cellIndex === (2)) { // insert dashboard html tableCell.insertAdjacentHTML('beforeEnd', renderTemplate('template-dashboard', { Id: rowIndex })); // build dashboard var dashboardContainer = tableCell.appendChild(document.getElementById('dashboard-' + rowIndex)); var control = new google.visualization.ControlWrapper({ 'controlType': 'ChartRangeFilter', 'containerId': 'control-' + rowIndex, 'options': { 'filterColumnIndex': 0, 'ui': { 'chartOptions': { 'height': 50, 'chartArea': { 'width': '75%' }, 'series': { 0: { 'targetAxisIndex': 0 }, 1: { 'targetAxisIndex': 1 } }, 'vAxes': { 0: { 'title': 'Weight' }, 1: { 'title': 'smA' } } } } }, }); var chart = new google.visualization.ChartWrapper({ 'chartType': 'ComboChart', 'containerId': 'chart-' + rowIndex, 'options': { 'legend': { 'position': 'bottom', 'alignment': 'center', 'textStyle': { 'fontSize': 12 } }, 'explorer': { 'actions': ['dragToZoom', 'rightClickToReset'], 'axis': 'horizontal', 'keepInBounds': true }, 'hAxis': { 'title': 'X' }, 'pointSize': 3, 'series': { 0: { 'targetAxisIndex': 0 }, 1: { 'targetAxisIndex': 1 } }, 'vAxes': { 0: { 'title': 'Weight' }, 1: { 'title': 'smA' } } } }); // build chart data table var chartData = new google.visualization.DataTable(); chartData.addColumn('date', 'timestamp'); chartData.addColumn('number', 'weight'); chartData.addColumn('number', 'smA'); chartData.addRow([new Date(2016, 0, 1), 1, 123]); chartData.addRow([new Date(2016, 1, 1), 6, 42]); chartData.addRow([new Date(2016, 2, 1), 4, 49]); chartData.addRow([new Date(2016, 3, 1), 23, 486]); chartData.addRow([new Date(2016, 4, 1), 89, 476]); chartData.addRow([new Date(2016, 5, 1), 46, 444]); var dashboard = new google.visualization.Dashboard(dashboardContainer); dashboard.bind(control, chart); dashboard.draw(chartData); } }); }); }); }); table.draw(tableData, { showRowNumber: false, width: '100%', height: '100%' });}// render html templatefunction renderTemplate(templateId, templateValues) { var templateText; // html string to return var templateValue; // html value // get template html templateText = document.getElementById(templateId).innerHTML; // replace place holders with values if (templateValues) { for (var propHandle in templateValues) { if (templateValues.hasOwnProperty(propHandle)) { templateValue = ''; if (templateValues[propHandle] !== null) { templateValue = templateValues[propHandle].toString(); } if (templateValue.indexOf('$') > -1) { templateValue = templateValue.replace(new RegExp('\\$', 'g'), '$$$'); } if (templateText.indexOf('{{' + propHandle + '}}') > -1) { templateText = templateText.replace(new RegExp('{{' + propHandle + '}}', 'g'), templateValue); } } } } return templateText.trim();}html,body { height: 100%; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px;}.chart { width: 500px; height: 300px border: 1px solid black; min-height: 200px;}.beige-background { background-color: beige;}<html> <head> <script src="https://www.gstatic.com/charts/loader.js"></script> </head> <body> <div id="table_div"></div> <!-- template: dashboard template --> <script id="template-dashboard" type="text/html"> <div id="dashboard-{{Id}}" style="border: 1px solid #ccc;"> <table class="columns"> <tr> <td> <div id="chart-{{Id}}"></div> <div id="control-{{Id}}" style="padding-left: 2em; min-width: 250px;"></div> </td> </tr> </table> </div> </script> </body></html>