绘制温度的平均值

时间:2016-01-04 10:19:07

标签: javascript php mysql math graph

我有许多温度传感器用于监控我的环境。我最近放弃了在RRD中捕获这些图形并使用它来绘制它们以将数据存储在MySQL中并使用Chart.js进行绘图,因为它为绘制外观和感觉提供了更多选项,它还使我可以灵活地移动到不同的图表如果我愿意,将来的图书馆。

我的问题更多的是存储数据的最佳方法。此刻,我每分钟调查温度并存储一切。然后我使用MySQL查询来获取数据:

  1. 最后一小时 - MySQL查询提取最后60个读数(输出60个值)
  2. 最后一天 - MySQL查询平均每小时平均60个读数(输出24个值)
  3. 上周 - MySQL查询平均每日平均读数(输出7个值)
  4. 我真的不确定这是获取每日和每周读数的最佳方法,然后我也希望每月和每年阅读。

    有人能建议更好的方法来处理数据吗?更好的查询,因为它们在数学上非常密集,将每月读数存储在平均读数的另一个表中会更好吗,我应该多久对数据进行平均一次?

    请帮忙! (还不确定在堆栈溢出时将其放入哪个类别):)

1 个答案:

答案 0 :(得分:5)

概述

这不是一件容易的事。您正在查看大量的后端工作和图形。很多图表。所以我为你做了一切。

  

因此,根据我的理解,您需要以下内容:

     
      
  1. 能够平均温度值。
  2.   
  3. 能够按周,月等对数据进行排序/显示数据。
  4.   
  5. 拥有漂亮,现代,互动的图表/图表。
  6.   
  7. 使用干净,高效,有效的方式存储和处理数据。
  8.   

这整个答案都是基于我对Flot的了解以及您将使用它的假设,但是这里的大部分知识和代码都可以应用于几乎所有的javascript图表库。

1。平均值

FlotAveraging Plugin,在图表中放置一条线来表示平均值。这使您可以以图形方式查看温度随时间推移在此平均值附近波动的位置。我想象一下昼夜之间的正弦曲线。这对我来说效果很好,但我确实需要这个平均值的实际数字。

在此处使用此Sum values from an Array链接,如果我们稍微修改代码,我们可以从Flot期望的数据格式中提取平均值。我在下面做了这个。

var myData = [['2013-01-22', 0], ['2013-01-29', 1], ['2013-02-05', 21]];
var myTotal = 0;  // Variable to hold your total
var myAverage = 0; // Variable to hold your average
var myNumber = 0; // Variable to hold the number of items to divide by

for(var i = 0, len = myData.length; i < len; i++) {
    myTotal += myData[i][1];  // Iterate over your first array and then grab the second element add the values up
    myNumber++; // This will give us the number of items we added
}

myAverage = myTotal / myNumber;

document.write(myTotal); // 22 in this instance
document.write(myNumber); // 3 in this instance (useful for knowing how many data points you have)
document.write(myAverage); // 7.3 in this instance

我不确定你的意思

  

我应该多久对数据进行平均一次?

不确定您是想要摆脱数据点还是只想要平均值或......但您并不需要摆脱数据点。平均值在上面完成。如果您迫切希望用较少的数据点节省空间/处理时间,Downsample Plugin Flot可以删除数据点而不会产生明显的差异,正是出于这个原因。

2。显示数据

再次使用基本假设,您将最终使用Flot,此函数内置于Flot。我想你收集的数据有时间戳。通过Flot中的时间图表,您可以使用按钮轻松显示一个月,两个月,最后一天...您想要的任何时间段的数据。此示例显示在此示例中Time Series Interaction

如果您希望在一段时间内获得更好的互动形式,请查看Interactivity ExamplesFlot

3。一个漂亮的图表

这自然是Flot!您可以调整不同区域的颜色,选择是否填充,但实际上它们看起来还不错。

4。存储和使用数据

  

现在,这里有三个结果,但我只会涉及两个。

     
      
  1. 您将数据保存在数据库中。
  2.   
  3. 您恢复使用日志文件。
  4.   
  5. 你实时(没有报道)。
  6.   

概述

本部分试图回答

  

我的问题更多的是存储数据的最佳方法。此刻,我每分钟调查温度并存储一切。然后我使用MySQL查询来获取数据:

     

上一小时 - MySQL查询提取最后60个读数(输出60个值)   最后一天 - MySQL查询平均每小时平均60个读数(输出24个值)   上周 - MySQL查询平均每日平均读数(输出7个值)   我真的不确定这是获取每日和每周读数的最佳方法,然后我也希望每月和每年阅读。

     

有人能建议更好的方法来处理数据吗?更好的查询,因为它们在数学上非常密集,将每月读数存储在平均读数的另一个表中会更好吗

在我个人看来,存储数据的最佳方法是图表库所需的确切格式。但是,如果你不是实时的,那么你几乎可以使用最简单的东西,而且由于你不能非常快地加载数百万个数据点,所以它不应该是重要的。差。

我假设您确实使用了RRDtool的日志,现在是MySQL。对于每日和每周阅读的最佳方法,我不认为这与MySQL有关。后端的工作是收集,存储和呈现数据。前端,a.k.a。Flot将为您排序这些数据,并提供每日和每周读数,如第二部分所述。这样可以避免这些复杂的查询。

我对更好地处理数据的建议是让后端不能处理带有查询的数据和单独的平均文件等,而只是将它呈现给Flot,让Flot处理数据只显示您想要的数据。现在让后端绘制数据图表......

Flot将采用以下格式的数据:

[[timestamp, data], [timestamp, data]]

所以,让我们去那儿。

1。的MySQL / PHP

好的,所以你不能再回到原木了。或者你从未使用它们,无论哪个。

您必须使用正确的时间戳将MySQL值格式化为正确的格式。嗯。现在,我不知道你是如何存储时间戳的,所以让我们假设你每分钟都在研究数据的知识(crontab?)。我们不知道您何时开始轮询这些数据,因此我们将不得不及时倒退。

首先,获取数据。

我很快发现了这个Export MySQl Table To File。下面的代码将从MySQL表中获取数据并将其写入文件。便利。我假设每个值都有一个新的行。

<?php
$pdo = new PDO(...);
$results = $pdo->query("SELECT * FROM myTable INTO OUTFILE 'data.txt'");
$dummy = $result->fetchAll(); 
?>

右。我们将数据存储在文件中,现在用于时间戳。

<?php
$time = time() * 1000;
$file = fopen("data.txt", "w+");
foreach(file("data.txt") as $line) {
    if ($file > 0) {
        $write = ", [" . $time . ", " . $line . "]";
        fwrite($file, $write);
    } else {
        $write = "[" . $time . ", " . $line . "]";
        fwrite($file, $write);
    }
    $time = $time - 60000;
}
fclose($file);
?>

好的,让我逐行解释。

javascript库将以毫秒为单位预期纪元时间,但PHP会在几秒钟内显示,因此将其乘以一千。

接下来,我们要将您的数据输出写入文件。这很容易在Flot中定义,并在以后为您提供更多灵活性。因此我们提前打开文件,以便在每次解析新行时将其打开。

然后我们逐行浏览并以适当的格式将数据写入文件,并在前面添加时间戳。这假定刚刚收集了数据。

然后,每次迭代都会返回一分钟(60000毫秒),以便及时向后工作。 Flot会为您处理此问题。

然后,我们关闭文件。

在此之后,Flot可以从文件中读取数据。做得很好。

2。 PHP /日志

好的,这很有意思。您恢复使用我完全假设它的RRDtool日志格式。

我将使用下面的代码引导您完成它。

<?php
$file = fopen("log.txt", "r");
$tempOneFile = fopen("tempOne.txt", "w+");
$tempTwoFile = fopen("tempTwo.txt", "w+");
while ($first = fscanf($file, "%s\t%s\t%s\n")) {
    list ($timestamp, $temperatureone, $temperaturetwo) = $first;
    $time = $timestamp * 1000;
    if ($file > 0) {
        $one = ", [" . $time . ", " . $temperatureone . "]";
        $two = ", [" . $time . ", " . $temperaturetwo . "]";
        $fwrite($tempOneFile, $one);
        $fwrite($tempOneFile, $two);
    } else {
        $one = "[" . $time . ", " . $temperatureone . "]";
        $two = "[" . $time . ", " . $temperaturetwo . "]";
        $fwrite($tempOneFile, $one);
        $fwrite($tempOneFile, $two);
    }
}
fclose($file);
?>

确定。因此可能有更好的方法来处理数据,但我个人喜欢用正确格式的数据创建文件。它易于阅读,并且如您所愿,它非常灵活。

这是针对日志文件的。

3。实时/的NodeJS

起初令人生畏,从PHP / MySQL转向实时javascript和网络套接字等等。但它并没有那么糟糕。基本上,您通过Web套接字流式传输数据。但是我不会覆盖这个,因为它不是你需要的温度。

结论

我希望这个极长的答案涵盖你的问题。下一步实际上是将您的数据转换为Flot的图表。在整个答案中,我对数据的格式做了很多假设。如果某些东西不起作用,请不要害怕评论,不同,你不能弄清楚如何使用它或类似的东西。谢谢!

相关问题