已导入jqWidgets脚本但jqxChart无数据渲染,求排查遗漏配置
我帮你排查了代码里的几个关键问题,这些就是导致图表无法正常渲染的核心原因,咱们一个个来修复:
1. JSON字符串未转换为JavaScript对象
你定义的incidentData是一个JSON格式的字符串,但jqx.dataAdapter的localdata参数需要接收的是JavaScript数组/对象,直接传字符串的话,适配器无法正确解析数据结构。
修复方式:
要么用JSON.parse()把字符串转成数组:
var incidentData = JSON.parse('[{"date":"2020-11-06T00:00:00Z",...}]');
要么直接把incidentData定义成数组(更直观):
var incidentData = [{"date":"2020-11-06T00:00:00Z","active":0,"expired":6},...];
2. X轴的minValue/maxValue用了无效的Razor语法
你在xAxis配置里写的'@data.Min(m=>m.date).ToString("dd-mm-yyyy")'是ASP.NET Razor的后端语法,纯前端JavaScript根本无法识别,浏览器会把它当成普通字符串,导致日期解析失败,X轴无法正常生成。
修复方式:
从已加载的数据源中提取真实的最小和最大日期:
// 从适配器的records里取出所有日期对象 var dates = incidentAdapter.records.map(item => item.date); // 计算最小和最大日期 var minDate = new Date(Math.min(...dates)); var maxDate = new Date(Math.max(...dates));
然后把xAxis里的minValue和maxValue替换成这两个变量:
xAxis: { // ...其他配置 minValue: minDate, maxValue: maxDate, // ... }
另外注意:你写的dd-mm-yyyy里,mm代表的是分钟,月份应该用MM,不过直接传递Date对象给min/maxValue会更可靠,不需要手动转格式。
3. 日期字段的解析格式不匹配原始数据
你的datafields里给date字段设置了format: 'dd.MMM.yyyy',但原始数据的日期是ISO 8601格式(比如2020-11-06T00:00:00Z),这个格式不匹配会导致dataAdapter无法把字符串转成Date对象,进而整个图表的数据绑定失效。
修复方式:
要么去掉format属性(jqWidgets默认能识别ISO格式的日期字符串),要么设置正确的解析格式:
datafields: [ { name: 'date', type: 'date' }, // 去掉format即可 { name: 'active', type: 'number' }, { name: 'expired', type: 'number' }, ],
4. 额外优化:替换无效的描述文本
你在description里写的@data.Sum(s=>s.active+s.expired)也是Razor语法,同样无法在前端运行,你可以用JavaScript计算出对应的数值:
description: `Recorded ${incidentAdapter.records.reduce((sum, item) => sum + item.active + item.expired, 0)} incidents in ${incidentAdapter.records.length} days`,
修复后的完整代码
<div id="jqxIncidentChart" class="chart"></div> <script> document.addEventListener('DOMContentLoaded', (event) => { // 直接定义为JavaScript数组 var incidentData = [{"date":"2020-11-06T00:00:00Z","active":0,"expired":6},{"date":"2020-11-07T00:00:00Z","active":0,"expired":5},{"date":"2020-11-08T00:00:00Z","active":0,"expired":6},{"date":"2020-11-09T00:00:00Z","active":0,"expired":7},{"date":"2020-11-10T00:00:00Z","active":0,"expired":5},{"date":"2020-11-11T00:00:00Z","active":0,"expired":59},{"date":"2020-11-12T00:00:00Z","active":0,"expired":16},{"date":"2020-11-13T00:00:00Z","active":0,"expired":11},{"date":"2020-11-14T00:00:00Z","active":0,"expired":104},{"date":"2020-11-15T00:00:00Z","active":0,"expired":18},{"date":"2020-11-16T00:00:00Z","active":0,"expired":22},{"date":"2020-11-24T00:00:00Z","active":0,"expired":9},{"date":"2020-11-28T00:00:00Z","active":0,"expired":48},{"date":"2020-11-17T00:00:00Z","active":0,"expired":9},{"date":"2020-11-20T00:00:00Z","active":0,"expired":22},{"date":"2020-11-18T00:00:00Z","active":0,"expired":19},{"date":"2020-11-23T00:00:00Z","active":0,"expired":11},{"date":"2020-11-21T00:00:00Z","active":0,"expired":10},{"date":"2020-11-22T00:00:00Z","active":0,"expired":6},{"date":"2020-11-19T00:00:00Z","active":0,"expired":6},{"date":"2020-11-26T00:00:00Z","active":0,"expired":9},{"date":"2020-11-27T00:00:00Z","active":0,"expired":3},{"date":"2020-11-25T00:00:00Z","active":0,"expired":5}]; var incidentDataSource = { datatype: "json", datafields: [ { name: 'date', type: 'date' }, { name: 'active', type: 'number' }, { name: 'expired', type: 'number' }, ], localdata: incidentData, sortcolumn: 'date', sortdirection: 'asc' }; var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; var incidentAdapter = new $.jqx.dataAdapter(incidentDataSource, { async: false, autoBind: true, loadError: function (xhr, status, error) { alert('Error loading data : ' + error); } }); // 计算最小和最大日期 var dates = incidentAdapter.records.map(item => item.date); var minDate = new Date(Math.min(...dates)); var maxDate = new Date(Math.max(...dates)); var incidentChartSettings = { title: "Incidents over time", // 用JS计算描述文本 description: `Recorded ${incidentAdapter.records.reduce((sum, item) => sum + item.active + item.expired, 0)} incidents in ${incidentAdapter.records.length} days`, enableAnimations: true, showLegend: true, padding: { left: 5, top: 5, right: 5, bottom: 5 }, titlePadding: { left: 30, top: 0, right: 0, bottom: 10 }, source: incidentAdapter, width: 300, height:300, xAxis: { formatFunction: function (value) { return value.getDate() + '-' + months[value.getMonth()] + '-' + value.getFullYear(); }, dataField: 'date', type: 'date', valuesOnTicks: true, baseUnit: 'month', minValue: minDate, maxValue: maxDate, tickMarks: { visible: true, interval: 10 }, unitInterval: 1, gridLines: { visible: true, step: 1, color: '#9b6f71' }, labels: { angle: -45, rotationPoint: 'topright', offset: { x: 0, y: -25 } } }, valueAxis: { visible: true, title: { text: 'Incidents per day<br/>' }, tickMarks: { color: '#8e0a14' }, }, colorScheme: 'scheme04', seriesGroups: [{ type: 'line', toolTipFormatSettings: { decimalPlaces: 0, thousandsSeparator: ',', }, series: [ { displayText: 'Active', dataField: 'active' }, { displayText: 'Expired', dataField: 'expired' }, ] }] }; $('#jqxIncidentChart').jqxChart(incidentChartSettings); }); </script>
最后别忘了确认你已经正确引入了jQuery和jqWidgets的核心脚本与样式,比如:
<link rel="stylesheet" href="jqwidgets/styles/jqx.base.css" /> <script src="scripts/jquery.min.js"></script> <script src="jqwidgets/jqxcore.js"></script> <script src="jqwidgets/jqxdata.js"></script> <script src="jqwidgets/jqxchart.js"></script>
内容的提问来源于stack exchange,提问作者Walter Verhoeven

