如何在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
相关产品推荐
相关产品推荐

