Embedding a line chart inside a google chart table inside an html page

Viewed 603

I have a table(taken from google charts) and a line chart(also taken from there) and I want to embed it inside the table. I know there is a way to embed an html page inside a table by raising the flag "allow html" but didn't manage to find the exact syntax to do so. I want it to look like this(used sparkline here): This is my html for table:

<html>
  <head>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
      google.charts.load('current', {'packages':['table']});
      google.charts.setOnLoadCallback(drawTable);

      function drawTable() {
        var data = new google.visualization.DataTable();
        data.addColumn('string', 'Name');
        data.addColumn('number', 'Salary');
        data.addColumn('boolean', 'Full Time Employee');
        data.addRows([
          ['Mike',  {v: 10000, f: '$10,000'}, true, **HTML LINE CHART1 HERE**],
          ['Jim',   {v:8000,   f: '$8,000'},  false, **HTML LINE CHART2 HERE**],
          ['Alice', {v: 12500, f: '$12,500'}, true,**HTML LINE CHART3 HERE**],
          ['Bob',   {v: 7000,  f: '$7,000'},  true,**HTML LINE CHART4 HERE**]
        ]);

        var table = new google.visualization.Table(document.getElementById('table_div'));

        table.draw(data, {showRowNumber: true, width: '100%', height: '100%'});
      }
    </script>
  </head>
  <body>
    <div id="table_div"></div>
  </body>
</html>

The html for line chart:

  <html>
  <head>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
      google.charts.load('current', {'packages':['corechart']});
      google.charts.setOnLoadCallback(drawChart);

      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Year', 'Sales', 'Expenses'],
          ['2004',  1000,      400],
          ['2005',  1170,      460],
          ['2006',  660,       1120],
          ['2007',  1030,      540]
        ]);

        var options = {
          title: 'Company Performance',
          curveType: 'function',
          legend: { position: 'bottom' }
        };

        var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));

        chart.draw(data, options);
      }
    </script>
  </head>
  <body>
    <div id="curve_chart" style="width: 900px; height: 500px"></div>
  </body>
</html>

And I want the second html to appear for example instrad of the boolean column. Thanks!!!

2 Answers

recommend drawing the table first.
then on the table's 'ready' event,
add a chart to each table cell.

see following working snippet...

once the ready event fires, we get the table chart container.
then find each row and cell.
we add the line chart's container to the last cell, and draw the chart.

the data from the table chart is used to draw each line chart.
the rows from the table data are looped, up until the row for the chart that is being drawn.

google.charts.load('current', {
  packages: ['corechart', 'table']
}).then(function () {
  var data = new google.visualization.DataTable();
  data.addColumn('string', 'Name');
  data.addColumn('number', 'Salary');
  data.addColumn('string', 'Chart');
  data.addRows([
    ['Mike', {v: 10000, f: '$10,000'}, null],
    ['Jim', {v: 8000, f: '$8,000'}, null],
    ['Alice', {v: 12500, f: '$12,500'}, null],
    ['Bob', {v: 7000, f: '$7,000'}, null]
  ]);

  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 if last cell
          if (cellIndex === (tableRow.cells.length - 1)) {
            // add chart continer
            var chartContainer = tableCell.appendChild(document.createElement('div'));
            chartContainer.className = 'chart';

            // build chart data table
            var dataChart = new google.visualization.DataTable();
            dataChart.addColumn('number', 'x');
            dataChart.addColumn('number', 'y');
            for (var i = 0; i <= rowIndex; i++) {
              dataChart.addRow([i, data.getValue(i, 1)]);
            }

            // draw chart
            var chart = new google.visualization.LineChart(chartContainer);
            chart.draw(dataChart, {
              chartArea: {
                left: 24,
                top: 16,
                right: 24,
                bottom: 16,
                height: '100%',
                width: '100%'
              },
              height: '100%',
              legend: 'none',
              pointSize: 6,
              width: '100%'
            });
          }
        });
      });
    });
  });

  table.draw(data, {showRowNumber: true, width: '100%', height: '100%'});
});
html, body {
  height: 100%;
  margin: 0px 0px 0px 0px;
  padding: 0px 0px 0px 0px;
}

.chart {
  min-height: 200px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="table_div"></div>

What you want to achieve is a bit tricky but doable. One way I can think of is to create first the line charts, get the image URI, and using "allowHtml" in the Table chart, embed an "" tag with the "src" attribute pointing to the image URI of the chart for that user.

Example:

Your line in your table chart:

['Mike', {v: 10000, f: '$10,000'}, true, **HTML LINE CHART1 HERE**]

changes to:

['Mike', {v: 10000, f: '$10,000'}, true, '<img src="'+ chart.getImageURI()+ '">']

where chart is the line chart for each user, and using the option allowHtml: true. Oh and for HTML set the column data type to 'string'.

References:

Related