Get HTML Table Data into Bar Chart

Tags: , , , ,



I’ve been messing around with some database data that I’ve imported into an HTML table. Then I decided that I needed to get that data into a bar chart.

Is there a way I can do this? If so can you show me how to do so?

HTML (warning code snippet doesn’t actually work here, but it does in my application):

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
         pageEncoding="ISO-8859-1"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

    <div>
        <a href="http://localhost:8088">Go Back</a>
    </div>

</head>
<body>

<table id = "tableContent">
    <thead>
    <tr>
        <th>Region</th>
        <th>Total Cases</th>
    </tr>
    </thead>
    <tbody>
    <c:forEach var = "covid_table" items ="${covidapi}">
        <tr>
            <td>${covid_table.getName()}</td>
            <td>${covid_table.getTotal_cases()}</td>
        </tr>
    </c:forEach>
    </tbody>

</table>
</body>
</html>

Here’s the HTML code I used in the working version

New HTML CODE:

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

    <div>
        <a href="http://localhost:8088">Go Back</a>
    </div>

    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>

    <script src="https://code.highcharts.com/highcharts.js"></script>

    <script src="https://code.highcharts.com/modules/data.js"></script>

    <script src="https://code.highcharts.com/modules/exporting.js"></script>

    <script src="https://code.highcharts.com/modules/export-data.js"></script>

    <script type="text/javascript">

        $(function() {

            Highcharts.chart('container', {

                data: {

                    table: 'tableContent'

                },

                chart: {

                    type: 'column'

                },

                title: {

                    text: 'Data extracted from a HTML table in the page'

                },

                yAxis: {

                    allowDecimals: false,

                    title: {

                        text: 'Units'

                    }

                },

                tooltip: {

                    formatter: function() {

                        return '<b>' + this.series.name + '</b><br/>' +

                            this.point.y + ' ' + this.point.name.toLowerCase();

                    }

                }

            });



        });

    </script>

</head>
<body>

<div id="container" style="width: 100%; height: 400px;"> </div>

<table id = "tableContent">
    <thead>
    <tr>
        <th>Region</th>
        <th>Total Cases</th>
    </tr>
    </thead>
    <tbody>
    <c:forEach var = "covid_table" items ="${covidapi}">
        <tr>
            <td>${covid_table.getName()}</td>
            <td>${covid_table.getTotal_cases()}</td>
        </tr>
    </c:forEach>
    </tbody>

</table>
</body>
</html>

Answer

If you have the data from the API, then what you need to change is the presentational layer.

Here’s a small snippet that works with a set of data (it’s a fully JavaScript solution):

const fetchData = async() => {
  const response = await fetch('https://jsonplaceholder.typicode.com/todos')
  const json = await response.json()
  return json
}

const thead1 = document.querySelector('#table > thead')
const tbody1 = document.querySelector('#table > tbody')

const headerHtml = (items) => {
  let html = ''
  html += '<tr><th></th>'
  Object.keys(items[0]).forEach(header => {
    html += `<th>${ header }</th>`
  })
  html += '</tr>'
  return html
}

const bodyHtml = (items) => {
  let html = ''
  items.forEach(item => {
    html += '<tr>'
    html += '<td></td>'
    for (let key in item) {
      html += `<td>${ item[key] }</td>`
    }
    html += '</tr>'
  })
  return html

}

(async function() {
  // get data from the API
  const response = await fetchData()

  // transform data for our requirements
  let transformed = response.reduce((a, c) => {
    if (typeof a[c.userId] === "undefined") a[c.userId] = 0
    a[c.userId] += 1
    return a
  }, {})

  let data = Object.entries(transformed).map(([id, val]) => ({
    id,
    val
  }))

  thead1.innerHTML = headerHtml(data)
  tbody1.innerHTML = bodyHtml(data)

  // create chart:
  Highcharts.chart('container', {
    data: {
      table: 'table'
    },
    chart: {
      type: 'column'
    },
    title: {
      text: 'Data extracted from a HTML table in the page'
    },
    yAxis: {
      allowDecimals: false,
      title: {
        text: 'Units'
      }
    },
    tooltip: {
      formatter: function() {
        return `
          <b>${ this.series.name }</b>
        `
      }
    }
  });

})();
#table {
  border-collapse: collapse;
  border: 1px solid #cacaca;
  width: 200px;
}

#table tr,
#table th,
#table td {
  border: 1px solid #6f6f6f;
}

#table th {
  background: #cacaca;
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/data.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>

<script src="https://code.highcharts.com/modules/export-data.js"></script>
<table id="table">
  <thead>
  </thead>
  <tbody>
  </tbody>
</table>
<hr />
<div id="container"></div>


Source: stackoverflow