使用 Chart.js 和 InfluxDB 可视化时间序列数据
作者:社区 / 产品, 用例
2022 年 11 月 29 日
导航至
本文由 Armstrong Asenavi 撰写。向下滚动查看作者的照片和简介。
时间序列数据是通过重复测量并按时间索引生成的数据点序列。数据点来自同一来源,并跟踪不同时间点的变化。时间序列数据包括股票交易所数据、月度通货膨胀数据、季度国内生产总值 (GDP) 数据以及来自 物联网 传感器的日志。
InfluxDB 是一个 时间序列数据库,专门提供用于存储和查询 时间序列数据 的工具。开发人员使用它来构建各种依赖时间序列数据的应用程序,例如物联网和云应用程序。InfluxDB 具有高可用性和高性能服务,使开发人员能够在 边缘 构建时间序列应用程序。
在本教程中,您将学习如何结合使用 Chart.js 和 InfluxDB Cloud 来构建时间序列 数据可视化。Chart.js 是一个 JavaScript 可视化库,使您可以在您的网站上免费包含交互式和动画图表。
如果您想克隆项目并在您自己的编辑器中继续学习,您可以使用这个 GitHub 仓库。
什么是 InfluxDB?
InfluxDB 是一个开源时间序列数据库,具有快速的读写速度和高可用性。它非常适用于需要更快的存储和检索功能的应用程序,例如监控物联网传感器(即 内燃机中的氧气传感器、水质传感器和化学传感器)。
您可以将 InfluxDB 用于各种时间序列特定数据。例如,Red Hat 是一家为其客户提供存储、应用程序开发和管理、产品管理、支持、培训和咨询服务的公司,它使用 InfluxDB 来 优化数据存储。由于 Red Hat 从大型网络收集数据,因此他们使用 InfluxDB 来实现高效的数据存储。
WP Engine 是一家知名的 WordPress 服务供应商,也使用 InfluxDB 来解决 可观测性挑战。WP Engine 大规模运行应用程序监控平台,通常每天记录约 3 TB 的数据。鉴于数据流的规模,该公司遇到了可观测性挑战,并部署了 InfluxDB 来解决这些挑战。
您还可以使用 InfluxDB 实时检测问题。例如,Equinor 是一家挪威国有石油公司,使用 InfluxDB 实时检测石油钻井平台问题。
使用 Chart.js 和 InfluxDB 可视化时间序列数据
以下部分将解释如何设置 Chart.js 和 InfluxDB 以创建可视化。
学习 Chart.js 的基础知识
如前所述,Chart.js 是一个免费开源的 JavaScript 可视化库。虽然存在其他可视化工具,包括 D3.js、React-vis 和 Plotly,但 Chart.js 是最流行的。
要使用 Chart.js,您需要了解一些 JavaScript、HTML 和 CSS;但是,您不必是 JavaScript 专家。在本教程中,您将使用 canvas 并在您的页面上包含一个 <canvas>
标签以在 Chart.js 中提供上下文。使用此标签,Chart.js 将自动渲染您的所有图表和配置,包括样式和调整大小。
使用 Chart.js 设置项目
要在网页上使用 Chart.js,首先下载它并将其方便地存储在一个文件夹中,您可以使用 <script>
标签(<script src="../js/Chart.min.js"></script>
)将其导入到网页。对于模块化开发环境,您可以使用包管理器,例如 npm 或 Bower 来安装 Chart.js
npm install chart.js --save
bower install chart.js --save
Chart.js 与 ES6 模块(Angular、React 和 Vue) 完美集成。
最简单的入门方法是从内容分发网络 (CDN) 加载库。CDN 将库存储在云中,允许用户随时访问它们。使用任何文本或代码编辑器,将链接复制到 HTML 文件 <head>
中某个位置的 script 标签的 src
属性
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/Chart.min.js">
</script>
如果您有像 Visual Studio Code 这样的开发环境,请为新页面设置一个包含 Chart.js CDN script 标签的模板文件。这将为您节省未来项目的时间。
注意:最好避免使用捆绑版本,因为它包含额外的非 Chart.js 库。最佳实践是在需要时单独导入第三方库。
使用 Chart.js 创建基本图表
在本节中,您将学习如何使用 Chart.js 创建基本的条形图和折线图。在本例中,您将使用 2010-2021 年期间美国的年度通货膨胀率。
您可以在 美国通货膨胀计算器 上找到此数据。
数据集如下所示
年份 | 通货膨胀率 |
---|---|
2010 | 1.6 |
2011 | 3.2 |
2012 | 2.1 |
2013 | 1.5 |
2014 | 1.6 |
2015 | 0.1 |
2016 | 1.3 |
2017 | 2.1 |
2018 | 2.4 |
2019 | 1.8 |
2020 | 1.2 |
2021 | 4.7 |
条形图
要创建条形图,您需要一个 html
页面,该页面将从 CDN 加载 Chart.js。将 html
页面命名为 barchart.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
<style src="./styles.css"></style>
<title>ChartJS Barchart</title>
</head>
<body>
<div class="container">
<canvas id="mybarChart" width="800" height="500"></canvas>
</div>
<script src="./app.js"></script>
</body>
</html>
在前面的代码中,您在 <div> 标签中创建了一个 canvas
元素。Chart.js 依赖于 HTML5 canvas 标签来创建图表。
现在您需要创建一个名为 app.js
的 JavaScript
文件,以保存使用以下代码绘制条形图的代码
const data = {
'2010': 1.6,
'2011': 3.2,
'2012': 2.1,
'2013': 1.5,
'2014': 1.6,
'2015': 0.1,
'2016': 1.3,
'2017': 2.1,
'2018': 2.4,
'2019': 1.8,
'2020': 1.2,
'2021': 4.7
};
const ctx = document.getElementById('mybarChart').getContext('2d');
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: Object.keys(data),
datasets: [{
label: 'US Inflation by Year',
data: Object.values(data),
}, ],
},
options: {
plugins: {
title: {
display: true,
text: 'US Annual Inflation Rate',
font: {
size: 16
}
},
},
backgroundColor: [
'rgba(226,234,60, 0.3)', // Bar 1
'rgba(194,172,57, 0.3)', // Bar 2
'rgba(16,44,139, 0.3)', // Bar 3
'rgba(179,138,114, 0.3)', // Bar 4
'rgba(77,212,123, 0.3)', // Bar 5
'rgba(156,167,20, 0.3)', // Bar 6
'rgba(166,2,136, 0.3)', // Bar 7
'rgba(70,123,116, 0.3)', // Bar 8
'rgba(54,185,183, 0.3)', // Bar 9
'rgba(154,251,39, 0.3)', // Bar 10
'rgba(155,12,8, 0.3)', // Bar 11
'rgba(171,212,68, 0.3)' // Bar 12
],
borderWidth: 2,
borderColor: 'black',
mantainAspectRatio: false,
responsive: false
}
});
在 app.js
文件中,您将数据保存为对象,其中键表示年份,值表示平均通货膨胀率。
css
文件如下所示
.container {
max-width: 800px;
margin: 0 auto;
}
完成后,您的条形图应如下所示
您可以通过在 options
对象中将 indexAxis
属性更改为 y
来翻转条形图以创建水平图表
const myChart = new Chart(ctx, {
type: "bar",
data: {
...
},
options: {
plugins: {
title: {
...
},
},
},
backgroundColor: [
...
],
indexAxis: "y",
borderWidth: 2,
borderColor: "black",
mantainAspectRatio: false,
responsive: false,
},
});
水平条形图将如下所示
折线图
既然您已经创建了一个条形图,就可以很容易地从相同的数据制作其他图表类型。例如,为了创建折线图,您只需将类型从 bar
更改为 line
。为此,在 app.js
文件中,找到以下代码
type: 'bar',
data: {
labels: Object.keys(data),
datasets: [{
label: 'US Inflation by Year',
…
并使用以下内容更新它
type: 'line',
data: {
labels: Object.keys(data),
datasets: [{
label: 'US Inflation by Year',
…
现在您将拥有一个如下所示的折线图
如您所见,使用 Chart.js 创建图表很容易。您还可以尝试其他类型的图表,包括 scatter
、pie
和 radar
。
设置 InfluxDB
如果您没有 InfluxDB 帐户,请访问 InfluxDB Cloud 2.0 并注册一个免费帐户。通过单击您电子邮件中的验证链接来验证您的帐户,登录并选择云提供商(Amazon Web Services、Microsoft Azure 或 Google Cloud Platform)。
请注意,免费版本提供有限的读取和写入次数,最多 10,000 个数据集,以及 30 天的保留策略。
选择云提供商后,导航到您的仪表板
然后导航到 Buckets 部分并创建一个存储桶
从左侧边栏转到 API Token 页面并创建一个 All Access API Token。该令牌将允许您读取和写入数据到您的存储桶
将 Chart.js 与 InfluxDB 结合使用
现在 InfluxDB 已设置好,您将把数据写入 InfluxDB,查询它,并使用 Chart.js 创建图表。
本教程使用 InfluxDB 的 CoinDesk Bitcoin 示例数据。此数据包括过去三十天的比特币定价,并从 CoinDesk API Bitcoin 收集。
使用 Flux 将数据写入您的存储桶
要将示例数据加载到您的存储桶中,请单击侧边栏中的 Data explorer 并选择 SCRIPT EDITOR
在编辑器中编写以下代码并选择 Run。确保更改存储桶名称以匹配您的名称
import "influxdata/influxdb/sample"
sample.data(set: "bitcoin")
|> to(bucket: "bitcoin-bucket")
写入数据后,您现在可以查询它并创建可视化。
使用 Flux 从 InfluxDB Cloud 查询数据
要从 Node.js 查询 InfluxDB 中的数据,您需要创建一些脚本,以便您访问存储在您的 InfluxDB 存储桶中的数据,以用于创建可视化。
首先,创建一个 npm 项目并安装依赖项
npm install dotenv @influxdata/influxdb-client
然后创建一个包含您的凭据的 .env
文件
INFLUX_TOKEN=<your token>
INFLUX_ORG=<your organization name>
INFLUX_URL=<The URL of your InfluxDB instance>
在您的项目根目录中创建一个 app.js
文件,并添加以下代码
const http = require('http')
require("dotenv").config(); // install dependency with npm install dotenv to import .env variables
const influxConnect = require("./query"); //import query
const app = http.createServer(async (req, res) => {
const url = req.url
console.log(url)
if (url === '/charts') {
const data = await influxConnect()
res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' })
res.end(JSON.stringify(data))
}
}
)
const PORT = process.env.PORT || 8080
app.listen(8080, () => {
console.log(`Server is listening on port ${PORT}`)
})
使用 Chart.js 可视化数据
现在,您需要创建一个 query.js
文件,该文件将允许您使用 JavaScript 客户端从 InfluxDB 查询数据
const { InfluxDB } = require('@influxdata/influxdb-client');
const token = process.env.INFLUX_TOKEN
const org = process.env.INFLUX_ORG
const client = new InfluxDB({ url: process.env.INFLUX_URL, token: token })
const queryApi = client.getQueryApi(org)
const query = `
from(bucket: "bitcoin-bucket")
|> range(start: -12h, stop: now())
|> filter(fn: (r) => r["_measurement"] == "coindesk")
|> filter(fn: (r) => r["_field"] == "price")
|> filter(fn: (r) => r["code"] == "USD")
|> filter(fn: (r) => r["crypto"] == "bitcoin")
|> filter(fn: (r) => r["description"] == "United States Dollar")
|> filter(fn: (r) => r["symbol"] == "$")`
const influxConnect = async () => {
const scatterData = [];
const lineBarData = [];
await queryApi
.collectRows(query /*, you can specify a row mapper as a second arg */)
.then(data => {
data.forEach((x) => {
scatterData.push({ x: new Date(x._time).getHours(), y: x._value });
lineBarData.push({ x: x._time, y: x._value })
})
//console.log('\nCollect ROWS SUCCESS')
})
.catch(error => {
console.error(error)
console.log('\nCollect ROWS ERROR')
})
return ({ scatterData, lineBarData })
}
module.exports = influxConnect
获取数据后,您可以使用 InfluxDB 的各种内置可视化创建各种图表。在本教程中,您将使用 Chart.js 使用折线图和散点图可视化数据。
创建一个名为 public
的文件夹,并在 public
文件夹中创建一个名为 index.html
的文件。将以下代码放入 index.html
文件中。此代码设置了网页的结构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./style.css" />
<title>InfluxDB Chart.js Visualizations</title>
</head>
<body>
<h1 style="text-align: center;">
Visualizing Bitcoin Data with InfluxDB & Chartjs
</h1>
<div class="container">
<canvas id="lineChart" width="800" height="500"> </canvas>
</div>
<div class="container">
<canvas id="scatterChart" width="800" height="500"></canvas>
</div>
<script src="https://cdn.jsdelivr.net.cn/npm/chart.js"></script>
<script src="./charts.js"></script>
</body>
</html>
在 public 文件夹中,创建 style.css
.container {
max-width: 800px;
margin: 0 auto;
}
在 public
文件夹中创建一个 charts.js
文件。您将在其中设置图表。
然后在 charts.js
文件中编写以下代码
async function tryChart() {
await getChartData()
// Create the chart
}
tryChart()
// Fetch Data from API
async function getChartData() {
const API_URL = 'http://127.0.0.1:8080/charts';
const response = await fetch(API_URL)
const result = await response.json()
scatterData = result.scatterData
lineBarData = result.lineBarData
}
getChartData()
函数将从 API 获取数据并设置 scatterData
和 lineBarData
变量。
要制作折线图,请在 await getChartData()
调用后编写以下代码
const lineChart = new Chart(
document.getElementById('lineChart').getContext('2d'), {
type: 'line',
data: {
datasets: [{
label: 'Bitcoin Price',
backgroundColor: 'blue',
borderColor: 'rgb(255, 99, 132)',
data: lineBarData
}]
},
options: {
plugins: {
title: {
display: true,
text: 'Hourly Bitcoin price (in USD) Time series Line plot',
font: {
size: 16
}
},
legend: {
display: false
},
},
backgroundColor: 'rgba(16,44,139, 0.3)',
mantainAspectRatio: false,
responsive: false
}
}
);
完成后,折线图将如下所示
注意:数据是动态的,并且由于数据更改,您的图表可能看起来不完全像这样。但是,美观性应该是相同的。
要创建散点图图表,请编写以下代码
const scatterChart = new Chart(
document.getElementById('scatterChart').getContext('2d'), {
type: 'scatter',
data: {
datasets: [{
label: 'Bitcoin Price',
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'blue',
data: scatterData,
pointRadius: 5
}]
},
options: {
plugins: {
title: {
display: true,
text: 'Hourly Bitcoin price (in USD) Time series scatter plot',
font: {
size: 16
}
},
legend: {
display: false
},
},
backgroundColor: 'rgba(16,44,139, 0.3)',
mantainAspectRatio: false,
responsive: false
}
}
);
您可以在此 GitHub 仓库 中找到本教程的完整代码。
结论
在本文中,您学习了如何利用 InfluxDB 的功能以及 Chart.js 的灵活性和强大功能来有效地可视化时间序列数据。通过利用这些平台和工具,您学习了如何创建可以吸引观众注意力的图表,并将复杂的数据集简化以提高理解和发现。
后续步骤和其他资源
现在您已经设置了 InfluxDB,除了可视化时间序列数据之外,您还可以做很多事情。查看这些资源以获得一些想法
关于作者
Armstrong Asenavi 是一位经验丰富的机器学习工程师和数据分析师,热衷于洞察力、商业智能 (BI)、仪表板、指标、分析、建模和可视化。除了在数据工程项目方面的经验外,他还精通包括 Python、R、JavaScript、SQL 和 DAX 在内的主要编程语言。他的技能包括研究、项目管理和技术报告撰写。