使用 Highcharts 库和 InfluxDB 可视化您的时间序列数据

导航至

How to visualize your time series data with the Highcharts Library and InfluxDB

如果您正在 InfluxDB 之上构建物联网应用程序,您可能会使用图形库来处理您的可视化需求。今天,我们将了解图表库 Highcharts,以使用 InfluxDB Cloud 可视化我们的时间序列数据。但是,我也鼓励您了解 Giraffe,这是一个基于 React 的可视化库,为 InfluxDB 2.0 UI 中的数据可视化提供支持。(如果您正在寻找关于使用 Chart.js 和 InfluxDB 可视化时间序列数据的教程,请点击链接。)

要求

要遵循本教程,您需要确保您已启动并运行 InfluxDB 实例。本教程假设您已注册 免费层级 InfluxDB Cloud 帐户,但您也可以安装 InfluxDB v2 OSS

我最近发布了一篇关于 influxdb-client-js 库入门指南,该库支持 Node、浏览器和 Deno 环境。它涵盖了如何使用 influxdb-client-js 库查询和写入数据到 InfluxDB。在本教程中,我们将使用 Highcharts 写入、查询和可视化来自 Hanalei、Hilo、Honolulu 和 Kahului 的海洋潮汐数据。从这个 repo 运行您自己的项目。

使用 Highcharts 可视化时间序列数据的首要步骤

引入 Highcharts 库是我们的第一步。我将以下 script 标签添加到 index.html 文件的 head 部分。

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

对于 index.html 文件的 body,您需要一个容器 div,其 id 为 'container',以便我们稍后在脚本文件中定位它,如下所示

<div id="container"></div>

Highcharts 图形将在此容器中呈现。

在我们的服务器文件中,我们已经设置了一个端点来查询来自海洋潮汐数据库的数据(见下文),因此我们需要在脚本文件中获取数据并将其设置为我们的 Highcharts 构造函数。您必须首先实例化 queryApi,并使用 Flux 和 queryRows 方法查询 InfluxDB,如JavaScript 和 InfluxDB 2.0 入门中所述。

app.get('/api/v1/tide/:place', (request, response) => {
    const { place } = request.params;
    console.log(place)
    const results = []
    queryApi.queryRows(`from(bucket:"ocean_tides") |> range(start:0) |> filter(fn: (r) => r.location =~ /(?i)(${place})/)`, {
        next(row, tableMeta) {
            const o = tableMeta.toObject(row)
                // console.log(
                //     `${o._time} ${o._measurement} in '${o.location}': ${o._field}=${o._value}`
                // )
            results.push(o)
        },
        error(error) {
            console.error(error)
            console.log('\nFinished ERROR queryRows')
        },
        complete() {
            response.status(200).json(results)
            console.log('\nFinished SUCCESS queryRows')
        },
    })
});

在脚本文件中,这个简单的 fetch 函数检索基于传入的位置名称的数据。

const fetchData = (place) => {
  return fetch(`/api/v1/tide/${place}`)
    .then(res => {
      if (res.status !== 200) {
        console.log(res);
      }
      return res;
    })
    .then(res => res.json())
    .catch(error => console.log(error));
}

Promise.all() 用于获取四个不同位置的所有数据。接下来,修改结果以适应 Highcharts 文档中引用的所需格式。

return Promise.all([
            fetchData('hilo'),
            fetchData('hanalei'),
            fetchData('honolulu'),
            fetchData('kahului')
         ])
        .then(parsedRes => {
          const mutatedArray = parsedRes.map( arr => {
            return Object.assign({}, {
              name: arr[0].location,
              data: arr.map( obj => Object.assign({}, {
                x: (moment(obj._time).unix())*1000,
                y:obj._value
              }))
            });
          });
        })
        .catch(error => console.log(error));

现在我们已经成功查询和获取了数据,我们可以构建我们的图形。

Highcharts.chart('container', {
            colors: ['#508991', '#175456', '#09BC8A', '#78CAD2'],
            chart: {
              backgroundColor: {
                  linearGradient: [0, 600, 0, 0],
                  stops: [
                    [0, 'rgb(255, 255, 255)'],
                    [1, 'rgb(161, 210, 206)']
                  ]
              },
              type: 'spline'
            },
            title: {
              text: 'Hawaii Ocean Tides',
              style: {
                'color': '#175456',
              }
            },
            xAxis: {
              type: 'datetime'
            },
            yAxis: {
              title: {
                text: 'Height (ft)'
              }
            },
            plotOptions: {
              series: {
                turboThreshold: 2000,
              }
            },
            series: mutatedArray
          });

让我们分解一下这段代码。chart() 方法接受两个参数

  1. 要在其中呈现图表的目标元素。
  2. 一个选项对象,您可以在其中指定各种属性,例如样式、标题、图例、系列、类型、plotOptions 等。选项包括
    • colors: [array] – colors 属性接受十六进制代码数组,该数组将表示图表的默认配色方案。如果所有颜色都用完了,任何需要的新颜色都将导致再次循环遍历数组。
    • chart: {object} – chart 属性接受一个对象,其中包含各种附加属性,包括类型、zoomtype、动画、事件、描述和许多样式属性。在此示例中,我为背景赋予了线性渐变,并将类型指定为 spline
    • title: {object} – 这表示图表的主标题,并且可以额外赋予样式对象以使其更加生动。
    • xAxis: {object} – 在这种情况下,因为我使用的是时间序列数据,我知道 x 轴将始终是时间,因此我可以将类型指定为“datetime”,并且比例将自动调整为适当的时间单位。但是,这里还有许多其他选项,包括样式、标签、自定义刻度线位置以及对数或线性类型。
    • yAxis: {object} – 与 xAxis 属性类似,y 轴接受一个对象,并且可以访问许多选项来自定义图表 y 轴的设计和样式。在这种情况下,我仅指定了 y 轴标题,并推迟到 Highcharts 自动刻度线位置。
    • plotOptions: {object} – plotOptions 属性是每个系列类型的配置对象的包装器对象。也可以为系列数组中给定的单个系列项目覆盖每个系列的配置对象。在这里,我使用了 plotOptions.series 属性来覆盖默认的 turboThreshold 1000,并将其更改为 2000。这允许绘制更多的数据点(超过默认的 1000 个)。根据文档,系列配置选项在三个不同的级别访问。如果要定位图表中的所有系列,则可以使用 plotOptions.series 对象。对于特定类型的系列,您将访问该类型的 plotOptions。例如,要定位图表类型为“line”的 plotOptions,您将访问 plotOptions.line 对象。最后,特定系列的选项在 series 属性中给出(请参阅下一个要点)。
    • series: [array] 或 {object} – 这是您将传入数据的地方。您可以额外定义要传入的数据类型,为其命名,并为其定义其他 plotOptions。

这是最终结果!

使用 Highcharts 和 InfluxDB 可视化海洋潮汐物联网数据<figcaption> 使用 Highcharts 和 InfluxDB 可视化海洋潮汐物联网数据</figcaption>

使用 Highcharts 库和 InfluxDB 可视化时间序列数据的后续步骤

Highcharts 图形库是一个深入的库,具有看似无穷无尽的可视化可能性。我强烈建议您查看 Highcharts 文档演示以获得灵感。如果您正在使用 InfluxDB v2 并且需要帮助,请在我们的社区站点Slack 频道中寻求帮助。如果您正在开发一个很酷的物联网应用程序或在 InfluxDB 之上监控您的应用程序,我们很乐意听到您的消息,因此请务必分享您的故事!此外,请在评论部分分享您的想法、疑虑或问题。我们很乐意获得您的反馈并帮助您解决遇到的任何问题!

延伸阅读

虽然这篇文章旨在全面概述如何使用 Highcharts 可视化来自 InfluxDB 的时间序列数据,但以下资源也可能让您感兴趣

  1. JavaScript 和 InfluxDB 2.0 入门:这篇文章描述了如何开始使用 JavaScript 客户端库。
  2. 写入示例:来自 JavaScript 客户端库 repo 的这段代码重点介绍了如何将数据写入 InfluxDB。
  3. 查询示例:来自 JavaScript 客户端库 repo 的这段代码重点介绍了如何从 InfluxDB 查询数据。