簡體   English   中英

如何使用來自mySQL數據庫的數據填充Google折線圖。 (單個文件/內聯解決方案)

[英]How can I populate Google line chart with data from mySQL database. (single file / Inline solution)

我有一個帶有溫度和濕度傳感器的MCU(ESP8266)。 MCU通過MQTT將測量數據發送到運行在Synology NAS上的MQTT代理。 MQTT客戶端(Node.js)也在NAS上運行,該客戶端將接收到的數據寫入NAS上的MySQL數據庫。 最后但並非最不重要的一點是,網絡服務器和PHP服務器也在NAS上運行。

現在,我想建立一個網站,以折線圖的形式顯示數據庫中的數據。

問題:

  • 如何使用來自mySQL數據庫的數據填充Google折線圖?
  • 可以使用一個文件(.php)來執行此操作嗎?
  • 如何管理日期范圍選擇?
  • 如何選擇/取消選擇圖表上的線?

這是我對問題的回答。

由於我對所使用的編程語言沒有太大的了解,因此我不得不在網絡上搜索,閱讀和測試許多資源,以將結果復制在一起:-)以后我會對其進行擴展,但是對我來說它運行良好。

我想在這里介紹這個解決方案,以幫助其他人入門。 但是,肯定有很多方法可以改進代碼。 如果有人願意,我很樂意提供建議。 在Github上完成文件。 https://github.com/DIYDave/MySQL-and-Google-Line-Chart

  1. PHP。 從數據庫讀取數據,然后向javascript返回JSON字符串
<?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
}
?> 
  1. 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>
  1. Javascript。 Google圖表。 接受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);
  1. 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); } } }); 

    };

  2. Javascript。 Flatpickr。 很酷的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

結果: 屏幕截圖

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM