在本教程中,您将学习如何利用DataTables.js和Highcharts.js JavaScript库来可视化数据。
这就是我们要构建的内容(查看大版本以获得更好的体验):
所需的图书馆
出于本示例的目的,我们将不得不在笔中加载以下库:
- jQuery的
- DataTables.js
- Highcharts.js
考虑到这一点,如果您查看“ 设置”标签下的内容,将会看到我包含了一个外部CSS文件:
同样,我还包括了四个外部JavaScript文件:
注意:我们必须将jQuery添加到我们的项目中,因为DataTables.js是jQuery插件。 但是,请记住,Highcharts.js是纯JavaScript库,因此不需要jQuery。
HTML
首先,我们用container
类定义一个元素,其中包含两个子元素:
- 具有26行的表格。 第一行引用表格标题
th
,其他25行携带国家/地区详细信息。 该示例的数据源是worldometers.info 。 - 一个空的
div
,它将保存图表。
这是HTML结构:
<div class="container">
<table id="dt-table">
<thead>
<tr>
<th>Country</th>
<th>Population (2017)</th>
<th>Density (P/Km²)</th>
<th>Med. Age</th>
</tr>
</thead>
<tbody>
<tr>
<td>China</td>
<td>1,409,517,397</td>
<td>150</td>
<td>37</td>
</tr>
<!-- 24 more rows here -->
</tbody
</table>
<div id="chart"></div>
</div>
值得一提的是,为简单起见,我们指定了上述硬编码表数据。 但是,在实际项目中,表可能是动态创建的。
准备好标记,并添加背景色以使内容更清晰,该项目如下所示:
CSS
至此,我们定义了一些基本样式,如下所示:
.container {
display: flex;
flex-wrap: wrap;
align-items: center;
padding: 0 10px;
}
#dt-table_wrapper {
width: 35%;
margin-right: 2%;
}
#chart {
width: 63%;
}
table {
text-align: left;
}
@media screen and (max-width: 1200px) {
#dt-table_wrapper,
#chart {
width: 100%;
}
#dt-table_wrapper {
margin-right: 0;
}
}
重要的是要了解:
-
#dt-table_wrapper
在我们的标记中不存在。 初始化后,它就会由DataTables添加。 - 虽然我们为小屏幕定义了一些基本规则,但请注意,该演示不会完全响应。 我们可以做很多事情来使表格和图表在小屏幕上看起来更好。 例如,对于DataTables,有一个响应式扩展可用,但这超出了本教程的范围。
放置好CSS之后,让我们看看项目的外观。 我们还没有看到太大的区别,因为我们还没有初始化库:
JavaScript
现在进入笔中JavaScript窗口。 当DOM准备就绪时,将执行init
函数。 此功能触发其他子功能:
function init() {
const table = $("#dt-table").DataTable();
const tableData = getTableData(table);
createHighcharts(tableData);
setTableEvents(table);
}
就像您将看到的那样,这些子功能中的每一个都完成特定的任务。
初始化数据表
第一步是将表转换为“ DataTables”表。 我们只需一行代码即可完成此操作: $("#dt-table").DataTable();
现在,如果看表,我们会注意到它已经采用了DataTables表的功能,即:我们可以对其进行排序,搜索等。 在下面的演示中玩一下:
现在,您可以看到,DataTables对表应用了默认排序。 如果需要,我们可以自定义此行为。
提取表数据
下一步是获取表数据并构建图表。 我们不希望所有表数据。 实际上,如果您回顾一下本演示的最终版本,您会注意到该图表仅包含前三列(“国家/地区”,“人口”,“密度”)中的数据。
考虑到这一点,为了检索所需的数据,我们将利用DataTables API 。 负责此行为的函数如下:
function getTableData(table) {
const dataArray = [],
countryArray = [],
populationArray = [],
densityArray = [];
// loop table rows
table.rows({ search: "applied" }).every(function() {
const data = this.data();
countryArray.push(data[0]);
populationArray.push(parseInt(data[1].replace(/\,/g, "")));
densityArray.push(parseInt(data[2].replace(/\,/g, "")));
});
// store all data in dataArray
dataArray.push(countryArray, populationArray, densityArray);
return dataArray;
}
在此函数内部,我们遍历表行,对于每一行,我们获取目标列数据并将其存储在关联的数组中。 最后,所有这些数组都存储在另一个数组中。
这是主数组(即dataArray
)的快速可视化:
在继续之前,了解一件事很重要。 默认情况下, getTableData
函数应从所有表行收集数据。 但是,如果我们在表中搜索特定内容,则仅应收集和处理匹配的行。 为了完成这些事情,我们将一个参数传递给rows
函数。 具体来说,是具有search: "applied"
属性值的对象。
再次注意,如果不传递该对象,我们将始终从所有表行收集数据(对其进行测试)。 有关可以传递给该对象的属性的更多信息,请务必查看此页面 。
建立图表
现在我们有了所需的数据,我们准备构建图表。 这将包含两个嵌套图表,一个柱形图和一个样条图 。
这是相应的功能:
function createHighcharts(data) {
Highcharts.setOptions({
lang: {
thousandsSep: ","
}
});
Highcharts.chart("chart", {
title: {
text: "DataTables to Highcharts"
},
subtitle: {
text: "Data from worldometers.info"
},
xAxis: [
{
categories: data[0],
labels: {
rotation: -45
}
}
],
yAxis: [
{
// first yaxis
title: {
text: "Population (2017)"
}
},
{
// secondary yaxis
title: {
text: "Density (P/Km²)"
},
min: 0,
opposite: true
}
],
series: [
{
name: "Population (2017)",
color: "#0071A7",
type: "column",
data: data[1],
tooltip: {
valueSuffix: " M"
}
},
{
name: "Density (P/Km²)",
color: "#FF404E",
type: "spline",
data: data[2],
yAxis: 1
}
],
tooltip: {
shared: true
},
legend: {
backgroundColor: "#ececec",
shadow: true
},
credits: {
enabled: false
},
noData: {
style: {
fontSize: "16px"
}
}
});
}
不要被上面的代码所淹没! 毫无疑问,了解其工作原理的最佳方法就是尝试一下。 另外,您绝对应该阅读文档 。 无论如何,让我们简要介绍一下关键概念:
- x轴包含所有国家。
- 我们定义两个y轴。 第一个包含所有人口值,而第二个包含所有可用密度。
- 如果我们的图表不包含任何数据,则会显示一条消息。 请注意,我们能够通过
lang
对象自定义消息文本。
有了图表后,让我们再次看一下我们的进度:
同步表格和图表
在上一节中,我们基于表格数据构建了图表,但是表格与图表之间仍然没有完全同步。 为了证明这一点,请返回上一个演示并更改表的排序(排序),或搜索某些内容。 您会注意到图表对表的更改没有React。
为了解决这个问题,我们将利用DataTables draw
事件。 每次更新表时都会触发此事件。 因此,一旦我们修改了表格,就应该重新收集表格数据并重建图表。
这是棘手的事情。 在分页时也会触发draw
事件; 在此过程中没有理由重建图表。 理想情况下,我们应该防止这种行为。 值得庆幸的是,有一个page
事件可以帮助我们完成此任务。
这是实现所需功能的代码:
let draw = false;
function setTableEvents(table) {
// listen for page clicks
table.on("page", () => {
draw = true;
});
// listen for updates and adjust the chart accordingly
table.on("draw", () => {
if (draw) {
draw = false;
} else {
const tableData = getTableData(table);
createHighcharts(tableData);
}
});
}
现在表格和图表都已同步,如果我们进行“错误”搜索,我们将看到以下消息:
我们项目的最终版本:
浏览器支持
这两个插件都具有强大的浏览器支持( DataTables支持 , Highcharts支持 ),因此您可以期望该演示在所有最新的浏览器中都能正常运行。
再次提醒您,此演示并未针对小屏幕进行优化。
最后,像往常一样,我们使用Babel将ES6代码编译为ES5。
结论
就是这样! 我们通过结合两个流行且功能强大JavaScript库,使数据可视化。
现在您已经熟悉了该过程,请继续并详细说明最终演示的功能。 例如,尝试将自定义过滤器添加到表中。
与往常一样,如果您有任何疑问或想在本教程的下一步中看到其他内容,请在下面的评论中告诉我。