ASP.NET Core MVC 如何将筛选器关联到多个Chart.js图表
实现筛选器联动Chart.js图表的方案
前置修复:解决筛选器ID冲突
注意:你现有代码里program下拉框的id和department重复,必须先修改为id="Program"、name="Program",否则后续事件监听会失效。
修正后的program筛选器片段参考:
<div class="program"> <label class="small">:choose a program</label> <select id="Program" name="Program" class="form-control form-control-sm"> <option value="" disabled selected>program</option> @foreach (var x in ViewBag.ListP) { <option value="@x">@x</option> } </select> </div>
步骤1:后端新增图表数据接口
在HomeController中新增接口,接收筛选参数后查询对应图表数据,返回JSON格式:
// 记得加HttpPost注解,接收前端POST请求 [HttpPost] public IActionResult GetChartData(string college, string department, string program) { // 此处替换为你的实际业务查询逻辑,根据传入的三个筛选条件从数据库取数 var chartData = new { // 环形图所需数据 Doughnut = new { Labels = new[] {"KPI1", "KPI2", "KPI3"}, Data = new[] {20, 35, 45}, Colors = new[] {"#3e95cd", "#8e5ea2", "#b91d47"} }, // 柱状图所需数据 Bar = new { Labels = new[] {"专业A", "专业B", "专业C"}, Data = new[] {50, 70, 60} }, // 折线图所需数据 Line = new { Labels = new[] {"2021", "2022", "2023", "2024"}, CscData = new[] {40, 55, 60, 75}, ItData = new[] {30, 45, 70, 65} } }; return Json(chartData); }
步骤2:改造dash.js逻辑实现动态更新
将三个图表实例设为全局变量方便后续调用,新增筛选器监听事件和数据更新逻辑,完整改造后的代码如下:
// 全局存储三个图表实例,避免重复初始化 let doughnutChart, barChart, lineChart; // 页面加载完成后初始化逻辑 document.addEventListener('DOMContentLoaded', function() { // 初始化默认数据的图表 initCharts(); // 给三个筛选器绑定变更事件,任意值变化就触发图表更新 document.getElementById('College').addEventListener('change', updateAllCharts); document.getElementById('Department').addEventListener('change', updateAllCharts); document.getElementById('Program').addEventListener('change', updateAllCharts); }); // 初始化图表方法 function initCharts() { // 环形图初始化 const ctx1 = document.getElementById("target").getContext('2d'); doughnutChart = new Chart(ctx1, { type: "doughnut", data: { labels: KPINAME, datasets: [{ data: kpis, label: "Target", backgroundColor: barColors, fill: false }] }, options: { maintainAspectRatio: false, } }); // 柱状图初始化 const ctx2 = document.getElementById("external").getContext('2d'); barChart = new Chart(ctx2, { type: 'bar', data: { labels: programs, datasets: [{ data: kpi2, label: "KPI2", backgroundColor: "#3e95cd", fill: false }] } }); // 折线图初始化 const ctx3 = document.getElementById("internal").getContext('2d'); lineChart = new Chart(ctx3, { type: 'line', data: { labels: years, datasets: [ { data: kpi2forcsc, label: "KPI2 OF CSC", borderColor: "#3e95cd", fill: false }, { data: kpi2forit, label: "KPI2 OF IT", borderColor: "#b91d47", fill: false } ] } }); } // 统一更新所有图表的方法 function updateAllCharts() { // 读取当前筛选器选中值 const selectedCollege = document.getElementById('College').value; const selectedDepartment = document.getElementById('Department').value; const selectedProgram = document.getElementById('Program').value; // 请求后端拿筛选后的数据 fetch('/Home/GetChartData', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ college: selectedCollege, department: selectedDepartment, program: selectedProgram }) }) .then(response => response.json()) .then(resData => { // 更新环形图 doughnutChart.data.labels = resData.Doughnut.Labels; doughnutChart.data.datasets[0].data = resData.Doughnut.Data; doughnutChart.data.datasets[0].backgroundColor = resData.Doughnut.Colors; doughnutChart.update(); // 更新柱状图 barChart.data.labels = resData.Bar.Labels; barChart.data.datasets[0].data = resData.Bar.Data; barChart.update(); // 更新折线图 lineChart.data.labels = resData.Line.Labels; lineChart.data.datasets[0].data = resData.Line.CscData; lineChart.data.datasets[1].data = resData.Line.ItData; lineChart.update(); }); }
可选优化
如果需要实现下拉框联动(选中学院后仅展示对应学院的系、选中系后仅展示对应系的专业),可以额外给上级筛选器的change事件加逻辑,请求后端返回对应下级选项,动态更新下级筛选器的下拉内容即可。
内容的提问来源于stack exchange,提问作者user17342403
相关产品推荐
相关产品推荐

