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

如何在ASP.NET Core Razor Pages中分类存储过程结果集并用Chart.js生成图表

基于存储过程结果生成Chart.js动态柱状图方案

现有存储过程

以下是用于获取员工统计数据的SQL存储过程:

CREATE PROCEDURE [dbo].[sp_DistinctFunction]
                 @CustomerName NVARCHAR(MAX)                                                    
                 AS
BEGIN
                 SET NOCOUNT ON;
                 SELECT [function]as FuncName, EmployeeGroup as EmpGrp, Count(BadgeNo) as EmpCount
                 FROM EmployeeData
                 WHERE CustomerName = @CustomerName  Group By [function], EmployeeGroup
END
GO

该存储过程会根据传入的客户名称,返回按**职能(FuncName)和员工组(EmpGrp)**分组的员工数量统计结果,结果集样式如下:
结果集示例

需求目标

为每个EmployeeGroup生成以function为维度的柱状图,目标样式参考:
目标图表示例

实现步骤

1. 后端获取并转换数据

首先通过后端代码调用存储过程,将结果集转换为前端可处理的JSON格式。以C#为例,核心代码如下:

// 定义数据模型
public class EmployeeStats
{
    public string FuncName { get; set; }
    public string EmpGrp { get; set; }
    public int EmpCount { get; set; }
}

// 调用存储过程并转换数据
List<EmployeeStats> statsList = new List<EmployeeStats>();
using (SqlConnection conn = new SqlConnection("你的数据库连接字符串"))
{
    SqlCommand cmd = new SqlCommand("sp_DistinctFunction", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("@CustomerName", "目标客户名称");
    
    conn.Open();
    SqlDataReader reader = cmd.ExecuteReader();
    while (reader.Read())
    {
        statsList.Add(new EmployeeStats
        {
            FuncName = reader["FuncName"].ToString(),
            EmpGrp = reader["EmpGrp"].ToString(),
            EmpCount = Convert.ToInt32(reader["EmpCount"])
        });
    }
}
// 序列化为JSON返回前端
string jsonData = Newtonsoft.Json.JsonConvert.SerializeObject(statsList);

2. 前端处理数据并渲染图表

前端需要将扁平化的JSON数据整理为Chart.js所需的结构,再初始化图表:

// 假设后端返回的JSON数据已赋值给data变量
const groupedData = {};
const allFuncs = new Set();

// 按员工组分装数据,收集所有职能名称
data.forEach(item => {
    allFuncs.add(item.FuncName);
    if (!groupedData[item.EmpGrp]) {
        groupedData[item.EmpGrp] = {};
    }
    groupedData[item.EmpGrp][item.FuncName] = item.EmpCount;
});

// 转换为Chart.js要求的格式
const labels = Array.from(allFuncs);
const datasets = Object.entries(groupedData).map(([groupName, funcCounts]) => {
    // 为每个职能匹配对应员工组的数量,无数据则填0
    const chartData = labels.map(func => funcCounts[func] || 0);
    return {
        label: groupName,
        data: chartData,
        backgroundColor: `rgba(${Math.floor(Math.random()*255)}, ${Math.floor(Math.random()*255)}, ${Math.floor(Math.random()*255)}, 0.6)`,
        borderColor: `rgba(${Math.floor(Math.random()*255)}, ${Math.floor(Math.random()*255)}, ${Math.floor(Math.random()*255)}, 1)`,
        borderWidth: 1
    };
});

// 初始化柱状图
const ctx = document.getElementById('employeeChart').getContext('2d');
new Chart(ctx, {
    type: 'bar',
    data: {
        labels: labels,
        datasets: datasets
    },
    options: {
        responsive: true,
        scales: {
            y: {
                beginAtZero: true,
                title: {
                    display: true,
                    text: '员工数量'
                }
            },
            x: {
                title: {
                    display: true,
                    text: '职能'
                }
            }
        },
        plugins: {
            legend: {
                position: 'top',
            },
            title: {
                display: true,
                text: '各员工组职能分布统计'
            }
        }
    }
});

3. 页面基础结构

在HTML中添加用于渲染图表的canvas元素,并引入Chart.js库:

<div style="width: 80%; margin: 2rem auto;">
    <canvas id="employeeChart"></canvas>
</div>
<!-- 引入Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

关键注意点

  • 数据补全:必须确保每个员工组的数据集包含所有职能的统计值,没有对应数据时填0,避免图表显示错位
  • 样式自定义:示例中用随机颜色区分员工组,也可以替换为固定配色方案
  • 响应式适配:Chart.js默认支持响应式,可通过修改options调整图表的尺寸、布局等细节

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 01:52:50