The #dt-table_wrapper doesn’t exist in our markup. It’s added by the DataTables as soon as we initialize it.

While we define a few basic rules for small screens, note that the demo won’t be fully responsive. There are a lot of things we can do to make the table and chart look better on small screens. For example, for DataTables there’s a Responsive extension available, but that’s beyond the scope of this tutorial.

With the CSS in place, let’s see how the project looks. We won’t see a big difference yet because we haven’t initialized the libraries:

The JavaScript

Now for the JavaScript window in our pen. When the DOM is ready, the init function is executed; this function triggers other sub-functions:

As you’ll see, each of these sub-functions accomplishes a certain task.

Initializing DataTables

The first step is to convert our table into a “DataTables” table. We can do this with just one line of code: $("#dt-table").DataTable();

If we now look at the table, we’ll notice that it has adopted the capabilities of a DataTables table, ie: we can sort it, search it, and so on. Have a play with it in the following demo:

Now, as you can see, DataTables applies a default sorting to the table. If needed, we can customize this behavior.

Extracting Table Data

The next step is to grab the table data and build the chart. We don’t want all the table data. In fact, if you look back at the finished version of our demo, you’ll notice that the chart only contains data from the first three columns (Country, Population, Density).

With that in mind, in order to retrieve the required data, we’ll take advantage of the DataTables API. The function responsible for this behavior is the following one:

Inside this function, we iterate through the table rows and for each row, we grab the target column data and store them in the associated arrays. Finally, all those arrays are stored inside another array.

Here’s a quick visualization of the master (i.e. dataArray) array:

Before moving on, it’s important to understand one thing. By default, the getTableData function should collect data from all the table rows. But then, if we search the table for something specific, only the rows that match should be collected and processed. To accomplish these things, we pass an argument to the rows function. Specifically, an object with the search: "applied" property value.

Again note that if we don’t pass this object, we’ll always collect data from all the table rows (test it). For more information about the properties that we can pass to this object, be sure to look at this page.

Building the Chart

Now that we have the desired data, we’re ready to build the chart. This will contain two nested charts, one Column chart and one Spline chart.

Don’t be overwhelmed by the code above! Without doubt the best way to understand how it works is to try it. Plus, you should definitely read the documentation. Anyhow, let’s briefly highlight the key concepts:

The x-axis contains all the countries.

We define two y-axes. The first one holds all the population values, while the second one includes all the available densities.

If our chart doesn’t contain any data a message appears. Note that we’re able to customize the message text through the lang object.

With the charts in place, let’s again look at our progress:

Synchronizing the Table and Charts

In the previous section, we built the chart based on the table data, but there’s still no full synchronization between the table and chart. To prove it, go back to the last demo and change the ordering (sorting) of the table, or search for something. You’ll notice that the chart doesn’t react to table changes.

To fix this, we’ll take advantage of the DataTables draw event. This event fires each time the table gets updated. So as soon as we modify the table we should recollect the table data and reconstruct the chart.

Here’s the tricky thing though. The draw event also fires during the table pagination; there’s no reason to rebuild the chart during this process. Ideally, we should prevent this behavior. Thankfully, there’s the page event which helps us accomplish this task.