Chart.js繪製折線圖 ( 包含前後端代碼 )

簡介

透過此程式,可以透過 Chart.js 繪製折線圖,並搭配 JSON 及 AJAX 做傳輸的動作,因此可以達成不刷新頁面,就換其他資料表

執行流程

  1. 選擇欲輸出的表單
  2. 選擇時間範圍
  3. 搜尋
  4. 透過 AJAX 發送 GET 請求給 data.php
  5. data.php 回傳 JSON 格式的資料給前端
  6. 在 Ajax Success 的區塊進行畫圖的動作

前端代碼

清除舊圖問題

如果不清除舊圖的話,會出現一種bug,當繪製第二張圖的時候,第一張沒被清掉,導致圖片會一直亂跳

解決方法

先移除Canvas後,再創建Canvas,底下為對應的程式碼

var resetCanvas = function(){
  $('#visualize').remove(); // this is my <canvas> element
  $('#graph-container').append('<canvas id="visualize"><canvas>');
  $("#visualize").width(300).height(150);
};

主要程式碼

主要繪製圖案的區塊在 success: function (response) {} 裡面

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>資料圖表</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.js"></script>
</head>
<body>

    <div style="text-align: center">
        <form id="form_data">
                選擇表單:
                <select id="data_menu" name="data_menu">
                    <option value="humi">濕度</option>
                    <option value="temp">溫度</option>
                    <option value="F1">浮球</option>
                </select>
                時間範圍: <input id="Start_Date" type="date" name="Start_Date">
                ~ <input id="End_Date" type="date" name="End_Date">
                <button type="button" id="search">查詢</button>
        </form>
    </div>
    <div id="graph-container" style="position: relative; height:40vh; width:80vw">
        <canvas id="visualize"></canvas>
    </div>
</body>

<script>

//2019-09-25 16:48:55
//2019-09-25 16:58:37
//清除convas並重建
var resetCanvas = function(){
  $('#visualize').remove(); // this is my <canvas> element
  $('#graph-container').append('<canvas id="visualize"><canvas>');
  $("#visualize").width(300).height(150);
};

$("#search").click(function() {

resetCanvas(); //清除舊圖

const Start_Date = $("#Start_Date").val(); //取得表單設定的起始時間
const End_Date = $("#End_Date").val(); //取得表單設定的結束時間
const data_menu = $("#data_menu").val(); //取得表單設定的資料表名稱

$.ajax({
    type: "GET",
    cache: false,
    url: "/demo/data.php",
    data: { 
        Select_DB : "mix",
        Post_Name : data_menu,
        Start_Time : Start_Date, 
        End_Time : End_Date
    },
    dataType: "json",
    success: function (response) {
        //主要Chart.js繪圖區
        const data = response; //取得data.php回傳的資料
        const all_x_labels = [], all_y_data = [], Background_color = [];
        
        //利用陣列建立x,y座標
        for (let i = 0; i < response.length ;i++) {
            all_x_labels[i] = data[i].time;
            all_y_data[i] = data[i].value;
            Background_color[i] = "#FF0000";
        }

        const ctx = document.getElementById("visualize"),
        visualize = new Chart(ctx, {
                type: "line", 
                data: {
                    labels: all_x_labels, // x軸的刻度
                    datasets: [{
                        label: data_menu, // 顯示該資料的標題
                        data: all_y_data, // y軸資料
                        fill: false, // 不顯示底下的灰色區塊
                      borderColor: "#0066FF", // 設定線的顏色
                        backgroundColor: Background_color, // 設定點的顏色
                        lineTension: 0  // 顯示折線圖,不使用曲線
                    }],
                    
                }, 
                options: {  
                    legend: { 
                        onClick: (e) => e.stopPropagation() 
                    }
                } 
            });
    }
});
});

</script>
</html>

後端代碼

請自行修改以下對應的資料

$SeverAddress = "伺服器位置";
$UserName = "使用者帳號";
$PassWord = "密碼";
$DBname = "資料表名稱";

為了取得 GET 傳送的資料,使用以下代碼進行接收封包

$Start_Time = $_GET['Start_Time'];
$End_Time = $_GET['End_Time'];
$Select_Post = $_GET['Select_DB'];
$Post_Name = $_GET['Post_Name'];

因為這裡使用 JSON 進行回傳的動作,所以先建立一個空陣列,再利用 array_push() 進行陣列堆疊,最後使用json_encode() 將陣列資料輸出成 JSON 格式

$return_arr = array();
array_push($return_arr,$row_array);
json_encode($return_arr)

JSON 資料格式

// 20191002160507
// http://127.0.0.1/demo/data.php?Select_DB=mix&Post_Name=humi&Start_Time=0202-02-02&End_Time=2020-02-02&_=1569999948844

[
  {
    "value": "64.00",
    "time": "2019-09-25 16:49:06"
  },
  {
    "value": "64.00",
    "time": "2019-09-25 16:49:21"
  },
  {
    "value": "63.00",
    "time": "2019-09-25 16:49:32"
  },
  {
    "value": "63.00",
    "time": "2019-09-25 16:49:37"
  },
  {
    "value": "63.00",
    "time": "2019-09-25 16:49:42"
  },
  {
    "value": "63.00",
    "time": "2019-09-25 16:50:19"
  },
  {
    "value": "64.00",
    "time": "2019-09-25 16:50:24"
  },
  {
    "value": "64.00",
    "time": "2019-09-25 16:50:34"
  },
  {
    "value": "64.00",
    "time": "2019-09-25 16:50:40"
  },
  {
    "value": "65.00",
    "time": "2019-09-25 16:50:45"
  },
  {
    "value": "63.00",
    "time": "2019-09-25 16:57:09"
  }
]

主要程式碼

<?php
$SeverAddress = "伺服器位置";
$UserName = "使用者帳號";
$PassWord = "密碼";
$DBname = "資料表名稱";
//取得GET資料
$Start_Time = $_GET['Start_Time'];
$End_Time = $_GET['End_Time'];
$Select_Post = $_GET['Select_DB'];
$Post_Name = $_GET['Post_Name'];
$conn = mysqli_connect($SeverAddress, $UserName, $PassWord, $DBname);
$return_arr = array();
//檢查連結
if (!$conn) {
    die("連接失敗: " . mysqli_connect_error());
}
//搜尋指令
$sql = "SELECT * FROM `$Select_Post` WHERE `name` = '$Post_Name' AND `time` > '$Start_Time' AND `time` < '$End_Time'";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
    // 輸出數據
    $row = mysqli_fetch_assoc($result);
    while($row = mysqli_fetch_assoc($result)) {
        $row_array['value'] = $row['value'];
        $row_array['time'] = $row['time'];
        // 堆疊陣列資料
        array_push($return_arr,$row_array);
    }
    //輸出JSON
    echo json_encode($return_arr);
} 
else {
    echo "0 個查詢結果";
}
mysqli_close($conn);
?>

最終結果

濕度

溫度

浮球

Last modification:October 2nd, 2019 at 04:45 pm