mysql - 如何使用 mySQL 数据库中的数据填充 Google 折线图。(单个文件/内联解决方案)
问题描述
我有一个带有温度和湿度传感器的 MCU(ESP8266)。MCU 通过 MQTT 将测量数据发送到在我的 Synology NAS 上运行的 MQTT 代理。NAS 上还运行一个 MQTT 客户端 (Node.js),它将接收到的数据写入 NAS 上的 MySQL 数据库。最后但同样重要的是,网络服务器和 PHP 服务器也在 NAS 上运行。
现在我想制作一个网站,将数据库中的数据显示为折线图。
问题:
- 如何使用 mySQL 数据库中的数据填充 Google 折线图?
- 可以使用一个文件 (.php) 来执行此操作吗?
- 如何管理日期范围选择?
- 如何选择/取消选择图表上的线条?
解决方案
这是我对我的问题的回答。
由于我对所使用的编程语言一无所知,因此我不得不搜索、阅读和测试网络上的大量资源以将结果一起复制 :-) 我将来会对其进行一些扩展,但对我来说它完美无缺.
我想在这里介绍这个解决方案以帮助其他人入门。但是,肯定有很多方法可以改进代码。如果有人愿意,我会很乐意提出建议。Github 上的完整文件。 https://github.com/DIYDave/MySQL-and-Google-Line-Chart
- php。从 db 中读取数据并将 JSON 字符串返回给 javascript
<?php
function getData(){
// Connect to MySQL (db Hostname/IP, user, password, database)
$link = new mysqli( '192.168.10.10', 'user', 'password', 'mymqttdb' );
if ( $link->connect_errno ) {
die( "Failed to connect to MySQL: (" . $link->connect_errno . ") " . $link->connect_error );
}
$start = $_GET['startDate']; // Get parameter from URL
$ende = $_GET['endDate']; // Get parameter from URL
if (!isset($endDate )){ // No end date? then actual for end
$endDate = date('Y-m-d H:i', time());
}
if (!isset($startDate )){ // No start date? then actual -1 day for start
$startDate = date('Y-m-d H:i', strtotime('-1 day', strtotime($ende)));
}
// Query in SQL ! add your own columns and database table name!
$query= "SELECT `DateTime`,`temperature`,`humidity` FROM `Chickenhouse` WHERE `DateTime` BETWEEN" . "'" . $startDate ."'" . "AND" . "'" . $endDate ."'";
$result = $link->query($query); // make db query
$rows = array();
$table = array();
$table['cols'] = array
(
array('label' => 'Date Time', 'type' => 'datetime'),
array('label' => 'Temperatur (°C)', 'type' => 'number'), // Select your label for the index
array('label' => 'Luftfeuchtigkeit (%)', 'type' => 'number') // Select your label for the index
);
while($row = mysqli_fetch_array($result)) // got to all the lines of the query result
{
$sub_array = array();
$date1 = new DateTime($row['DateTime']);
$date2 = "Date(".date_format($date1, 'Y').", ".((int) date_format($date1, 'm') - 1).", ".date_format($date1, 'd').", ".date_format($date1, 'H').", ".date_format($date1, 'i').", ".date_format($date1, 's').")";
$sub_array[] = array("v" => (string)$date2);
$sub_array[] = array("v" => $row["temperature"]);
$sub_array[] = array("v" => $row["humidity"]);
$rows[] = array("c" => $sub_array);
}
$table['rows'] = $rows;
$lineCount = count($rows); // Number of array fields (lines) to show in browser
return array(json_encode($table), $lineCount); // Make JSON from array and give it to the java script together with linecount
}
?>
- CSS 和 HTML。或多或少只是用于格式化和设置占位符。
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.2.3/flatpickr.css">
<style>
*{font-family:Arial;}
.page-wrapper{ width:90%; margin:0 auto; }
input { border: 2px solid whitesmoke;border-radius: 12px; padding: 12px 10px; text-align: center; font-size: 16px; font-weight: bold; width: 250px;background: cornflowerblue; color: yellow;}
button { border: none; border-radius: 10px; text-align: center; padding: 12px 10px; cursor: pointer; font-weight: bold; background: cornflowerblue; color: white;}
</style>
</head>
<body>
<div class="page-wrapper"> </div>
<input type="text" style="float:left" id="rangeDate" placeholder="Select Timespan" data-input>
<br>
<p id="LineCount" > </p>
<div id="line_chart" style="width: 100%; height: 800px"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.2.3/flatpickr.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
- Javascript。谷歌图表。接受 JSON 数据并将其显示为折线图。这里有很多可能的选择。此处的详细信息:https ://developers.google.com/chart/interactive/docs/gallery/linechart
// Setup and show Google line chart
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart(){
var data = new google.visualization.DataTable(<?php echo getData()[0]?>); // Call PHP-Function an receive JSON
document.getElementById("LineCount").innerHTML= " " + <?php echo getData()[1]?> + " Records loaded"; // Get record count
var options = {
series: {
0:{color: 'red', visibleInLegend: true, targetAxisIndex: 0},
1:{color: 'blue', visibleInLegend: true, targetAxisIndex: 1}
},
vAxes: {
// Adds labels to each axis; they don't have to match the axis names.
0: {title: 'Temp (°C)' }, // , 'minValue': 0, 'maxValue': 30
1: {title: 'Feuchte(%)'}
},
title:'Chickenhouse',
legend:{position:'top'},
chartArea:{width:'75%', height:'65%'},
//curveType: 'function',
hAxis: {
title: 'Datum', titleTextStyle: {color: '#333'},
format: 'd.M HH:mm',
slantedText:true, slantedTextAngle:80
},
explorer: {
actions: ['dragToPan', 'dragToZoom', 'rightClickToReset'], // 'dragToZoom'
axis: 'horizontal',
keepInBounds: true,
maxZoomIn: 28.0,
maxZoomOut: 1.0,
zoomDelta: 1.5
},
colors: ['#D44E41'],
};
var date_formatter = new google.visualization.DateFormat({ // Tooltip format
pattern: "dd.MM.yyyy - HH:mm"
});
date_formatter.format(data, 0);
var chart = new google.visualization.LineChart(document.getElementById('line_chart'));
chart.draw(data, options);
Javascript。通过单击图例选择显示的线条。
// Select / deselect lines by clicking on the label var columns = []; var series = {}; for (var i = 0; i < data.getNumberOfColumns(); i++) { columns.push(i); if (i > 0) { series[i - 1] = {}; } } google.visualization.events.addListener(chart, 'select', function () { var sel = chart.getSelection(); // if selection length is 0, we deselected an element if (sel.length > 0) { // if row is undefined, we clicked on the legend if (sel[0].row === null) { var col = sel[0].column; if (columns[col] == col) { // hide the data series columns[col] = { label: data.getColumnLabel(col), type: data.getColumnType(col), calc: function () { return null; } }; // grey out the legend entry series[col - 1].color = '#CCCCCC'; } else { // show the data series columns[col] = col; series[col - 1].color = null; } var view = new google.visualization.DataView(data); view.setColumns(columns); chart.draw(view, options); } } });
};
Javascript。扁平拾取器。很酷的 JavaScript 应用程序来选择日期和时间。也可以选择我在这里使用的日期范围。 https://flatpickr.js.org/
// Flatpickr to select date range
$("#rangeDate").flatpickr({
enableTime: false,
mode: 'range',
time_24hr: true,
dateFormat: "Y-m-d",
maxDate: "today",
defaulDate: "today",
onClose: function test(selectedDates, dateStr, instance){
arDateTime = dateStr.split(" to ");
dateTimeStart = arDateTime[0] + " 00:00" ;
dateTimeEnd = arDateTime[1] + " 23:59" ;
strNeu = "?startDate=" + dateTimeStart + "&endDate=" + dateTimeEnd;
window.location = strNeu;
},
});
Github 上的完整文件。 https://github.com/DIYDave/MySQL-and-Google-Line-Chart
结果: 截图
推荐阅读
- javascript - 未处理的拒绝 (TypeError):conversations.map 不是函数
- amazon-web-services - AWS DMS 迁移挑战
- ssh - vscode 连接到 ssh 机器内部的 ssh 机器
- r - 如何在ggplot2中的绘图之外的特定位置添加文本
- c++ - C++中的字符数组
- angular - Angular 服务调用方法显示未定义错误
- java - 如何在`spring-data-jpa`中设置默认实体监听器使用java代码?
- javascript - 我只想在 reactjs 中更改单击按钮(onClick)的变体或背景。我怎样才能实现它?
- c - 在c中的链接列表中设置可以使用多少项目的限制
- python - AttributeError:“SVC”对象没有属性“best_estimator_”