You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在VS2019 MVC应用中用Chart.js实现按日期的考勤打卡时间图表

问题:MVC中用Chart.js渲染考勤时间维度图表

我正在使用Visual Studio 2019开发MVC应用,想要渲染一个以考勤日期为X轴、打卡时间为Y轴的员工考勤图表,已获取该员工的相关数据列表。当前使用Chart.js v3.7.1,但尝试后无法实现需求,请求帮助。


原Action代码

[HttpGet]
public ActionResult BarChart()
{
    try
    {
        List<object> iData = new List<object>();
        DataTable dt = new DataTable();
        using (OracleConnection con = new OracleConnection(AppSetting.OraConnectionString()))
        {
            string str = @"SELECT to_char(cast(EAE_DATE as date),'dd-MON-yy') AS EAE_DATE ,to_char(cast(IN_TIME as date),'hh24:mi:ss') AS IN_TIME,to_char(cast(OUT_TIME as date),'hh24:mi:ss') AS OUT_TIME FROM EMPLOYEE_DAILY_ATTENDANCE_EXL WHERE EAE_EM_ID = 904 AND EAE_YEAR=2022 AND EAE_MONTH=11 ORDER BY EAE_DATE";

            OracleDataAdapter da = new OracleDataAdapter(str, con);
            da.Fill(dt);
            foreach (DataColumn dc in dt.Columns)
            {
                List<object> x = new List<object>();
                x = (from DataRow drr in dt.Rows select drr[dc.ColumnName]).ToList();
                iData.Add(x);
            }
            ViewBag.Date_List = iData[0];
            ViewBag.InTime_List = iData[1];
            ViewBag.OutTime_List = iData[2];

        }

        return View();
    }
    catch (Exception)
    {
        throw;
    }
}

原View代码

@{
    ViewBag.Title = "BarChart";
}
<div style="text-align: center">
    <canvas id="barcanvas"></canvas>
</div>

<meta name="viewport" content="width=device-width" />
<title>Attendance Punctuality</title>
@* I have installed Chart.js from ManageNugetPackages so not using the cdn *@
   
<script>
    var DayDate =@Html.Raw(Json.Encode(ViewBag.Date_List));
    var InTime =@Html.Raw(Json.Encode(ViewBag.InTime_List));
    var OutTime =@Html.Raw(Json.Encode(ViewBag.OutTime_List));
    var ChartData =
        { labels: DayDate,
          datasets: [{
                            label: 'In Time',
                            backgroundColor: "#aad2ed",
                            borderWidth: 2,
                            data: InTime,
                            borderColor: '#0062ff',
                            fill: false,
                        },
                        {
                            label: 'Out Time',
                            backgroundColor: "#f7bd83",
                            borderWidth: 2,
                            data: OutTime,
                            borderColor: '#F78511',
                            fill: false,
                      }]
        };
            window.onload = function () {
                var ctx1 = document.getElementById("barcanvas").getContext("2d");
                window.myBar = new Chart(ctx1,
                    { type: 'line',       //line,pie,bar,doughnut
                        data: ChartData,
                        showDatapoints: true,
                        legend: { position: 'bottom' },
                        options:
                            {
                                title: { display: true, text: "Attendance Trial Graph"},
                                responsive: true,
                                maintainAspectRatio: true
                            }
                    });
            }
</script>

解决方案:修改后的代码及说明

1. 优化后端Action代码

[HttpGet]
public ActionResult BarChart()
{
    try
    {
        List<object> dateList = new List<object>();
        List<object> inTimeList = new List<object>();
        List<object> outTimeList = new List<object>();
        
        using (OracleConnection con = new OracleConnection(AppSetting.OraConnectionString()))
        {
            string str = @"SELECT EAE_DATE, IN_TIME, OUT_TIME 
                          FROM EMPLOYEE_DAILY_ATTENDANCE_EXL 
                          WHERE EAE_EM_ID = 904 AND EAE_YEAR=2022 AND EAE_MONTH=11 
                          ORDER BY EAE_DATE";

            OracleDataAdapter da = new OracleDataAdapter(str, con);
            DataTable dt = new DataTable();
            da.Fill(dt);
            
            foreach (DataRow row in dt.Rows)
            {
                // 将考勤日期转为标准格式字符串
                DateTime eaeDate = Convert.ToDateTime(row["EAE_DATE"]);
                dateList.Add(eaeDate.ToString("yyyy-MM-dd"));
                
                // 拼接考勤日期与打卡时间,生成完整DateTime对象并转为ISO格式
                DateTime inTime = DateTime.ParseExact(row["IN_TIME"].ToString(), "HH:mm:ss", null);
                DateTime fullInTime = new DateTime(eaeDate.Year, eaeDate.Month, eaeDate.Day, inTime.Hour, inTime.Minute, inTime.Second);
                inTimeList.Add(fullInTime.ToString("o"));
                
                DateTime outTime = DateTime.ParseExact(row["OUT_TIME"].ToString(), "HH:mm:ss", null);
                DateTime fullOutTime = new DateTime(eaeDate.Year, eaeDate.Month, eaeDate.Day, outTime.Hour, outTime.Minute, outTime.Second);
                outTimeList.Add(fullOutTime.ToString("o"));
            }
            
            ViewBag.Date_List = dateList;
            ViewBag.InTime_List = inTimeList;
            ViewBag.OutTime_List = outTimeList;
        }

        return View();
    }
    catch (Exception)
    {
        throw;
    }
}

2. 修改前端View代码

@{
    ViewBag.Title = "BarChart";
}
<div style="text-align: center; height: 500px;">
    <canvas id="attendanceChart"></canvas>
</div>

<meta name="viewport" content="width=device-width" />
<title>Attendance Punctuality</title>

<script src="~/Scripts/chart.min.js"></script>
<script>
    const dayDates = @Html.Raw(Json.Encode(ViewBag.Date_List));
    const inTimes = @Html.Raw(Json.Encode(ViewBag.InTime_List)).map(time => new Date(time));
    const outTimes = @Html.Raw(Json.Encode(ViewBag.OutTime_List)).map(time => new Date(time));

    const ctx = document.getElementById('attendanceChart').getContext('2d');
    new Chart(ctx, {
        type: 'scatter', // 散点图更适合日期-时间维度展示,需连线可改为'line'
        data: {
            datasets: [
                {
                    label: '上班打卡',
                    data: dayDates.map((date, index) => ({
                        x: new Date(date),
                        y: inTimes[index]
                    })),
                    backgroundColor: '#0062ff',
                    pointRadius: 6
                },
                {
                    label: '下班打卡',
                    data: dayDates.map((date, index) => ({
                        x: new Date(date),
                        y: outTimes[index]
                    })),
                    backgroundColor: '#F78511',
                    pointRadius: 6
                }
            ]
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                title: {
                    display: true,
                    text: '员工考勤时间图表'
                },
                legend: {
                    position: 'bottom'
                }
            },
            scales: {
                x: {
                    type: 'time',
                    time: {
                        unit: 'day',
                        displayFormats: {
                            day: 'dd-MMM-yy'
                        }
                    },
                    title: {
                        display: true,
                        text: '考勤日期'
                    }
                },
                y: {
                    type: 'time',
                    time: {
                        unit: 'hour',
                        displayFormats: {
                            hour: 'HH:mm'
                        }
                    },
                    title: {
                        display: true,
                        text: '打卡时间'
                    }
                }
            }
        }
    });
</script>

关键修改说明

  • 后端数据处理:不再将日期、时间转为纯字符串,而是拼接成完整DateTime对象后转为ISO格式,确保前端能解析为标准时间对象。
  • 前端图表配置:将X、Y轴均设置为time类型,指定时间单位与显示格式;使用散点图(或折线图)展示日期与打卡时间的对应关系,数据格式符合Chart.js时间轴要求。
  • 细节优化:调整图表容器高度,明确引入Chart.js脚本路径,简化数据处理逻辑。

内容的提问来源于stack exchange,提问作者Farhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 08:47:19