基于Chart.js实现的“减肥曲线”应用

近期因为疫情,不能到处活动,也少了一些应酬,饮食和运动都受自己控制,是一个很好的减肥机会。

之前自己的体重一直记录在华为运动健康APP上,但是这个系统不能生成一个比较直观的曲线来呈现我的减肥数据趋势,所以就想自己动手写一个。

需求:支持体重数据录入和删除,数据记录在S端,数据在C端以曲线的形势呈现。

架构:后端NodeJs + JSON数据保存, 前端使用Chart.js库来进行数据的呈现。

手机端查看到的体重曲线
  • 前台index.html
  • 前台app.js
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="app.js">    </script>
    <title>Weight</title>
</head>
<body>
    <h2>Welcome to My Weight Recoder Page!</h2>
    <canvas id="myChart" width="50px" height="50px"></canvas>
    <!-- <div class="chart-container" style="position: relative; height:40vh; width:80vw">
        <canvas id="myChart"></canvas>
    </div> -->

    <div>
        日期:
        <input type="text" name="date" id="date">
        <script>
            var today = new Date();
            document.getElementById("date").value = today.getFullYear() + "." + (today.getMonth() + 1) + "." + today.getDate();
        </script>
    </div>

    <div>
        体重:
        <input type="text" name="weight" id="weight">
    </div>

    <div>
        操作:
        <button id="add">添加数据</button>
        <button id="delete">删除数据</button>
    </div>

    <div id="datashow"></div>

    <!-- 创建图表  -->
    <script>
        const myChart = new Chart(
            document.getElementById("myChart").getContext('2d'),
            config
        );
    </script>
    <!-- jquery实现的ajax post-->
    <script>
        $(document).ready(function () {
            PostData({option:"update"});
            console.log("document ready callback!");

            $("#add").click(function () {
                //verification 
                if(DataVerification($("#date").val(), $("#weight").val())) {
                    console.log("Error Weight Data!")
                    alert("input error!")
                    return;
                }
                var para = {option:"add",date:$("#date").val(),weight:$("#weight").val()};
                console.log(para);
                PostData(para);
            });

            $("#delete").click(function () {
                var para = {option:"delete"};
                console.log(para);
                PostData(para);
            });
        })
    </script>

</body>
</html>
app.js
// for Chart.js
const labels = [
    '2022.2.9'
    ];

const data = {
    labels: labels,
    datasets: [{
        label: 'Weight(Kg)',
        backgroundColor: 'rgb(255, 99, 132)',
        borderColor: 'rgb(255, 99, 132)',
        data: [82],
        tension: 0.2
    }]
};

const config = {
    type: 'line',
    data: data,
    options: {
        responsive: true,
        scales: {
            // y: {
            //     suggestedMin: 70,
            //     suggestedMax: 86
            // }
        }
    }
};

const OK = 0;
const ERR = -1;

/**
 * 
 * @param {*} data from server
 * {"date":["2022.1.9","2022.1.5","2022.1.6"],"weight":[85,"65","83"]}
 * @returns 
 */

function AddData(chart, data) {
    chart.data.labels.splice(0,  chart.data.labels.length);
    chart.data.datasets[0].data.splice(0, chart.data.datasets[0].data.length);
    for (let index = 0; index < data.date.length; index++) {
        chart.data.labels.push(data.date[index]);
        chart.data.datasets[0].data.push(data.weight[index]);
    }

    chart.update('active');

    return OK;
}

// 数据结构设计
// {
//     "option": "add", /* add , delete, update*/
//     "date":"2022.1.9",
//     "weight":"83.2"
// }
//请求数据
function PostData(para) {
    $.post("/update", para,
        function (data, textStatus, jqXHR) {
            $("#datashow").text(JSON.stringify(data));
            //update Chart
            AddData(myChart, data);
           //console.log(JSON.stringify(config));
        },
        "json"
    );    

    return OK;
}

function DataVerification(date, weight) {

    if (("" == date) || (null == date) || (date.length > 10) || (date.length < 8) || ("") == weight || (null == weight)) {
        return ERR;
    }

    var w = parseFloat(weight);
    if (NaN == w) {
        return ERR;
    }

    // more verification item need to be added: to do 

    return OK;
}

看下最终的效果,不得不说曲线减肥法好处多多,能够很明显地知道自己当前的体重趋势,及时地控制摄入或者加大运动量,因为当前只有我一个人用,还是按照单用户来做做server端,但已经预留了接口,可以修改支持多用户。

Related Posts

发表回复