从JSON数组动态生成Chart.js OHLC金融图表的问题求助
动态生成Chart.js OHLC金融图表遇到的问题
问题场景
通过Ajax从Django模型接口/api/stockArray/获取JSON数据,已成功实现静态OHLC图表、动态折线图/柱状图,但动态生成OHLC图表时,始终触发chartjs-adapter-date-fns.bundle抛出的「无效时间值」RangeError。同时发现静态多组OHLC数据可正常显示,单组数据则图表空白。
当前前端代码如下:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js" integrity="sha512-ElRFoEQdI5Ht6kZvyzXhYG9NqjtkmlkfYk0wr6wHxU9JEHakS7UJZNeml5ALk+8IKlU6jDgMabC3vkumRokgJA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script> <script src="../static/stocks/js/chart.js" type="text/javascript"></script> <canvas id="myChart" width="300" height="175"></canvas> <script> let priceArray = [] const endpoint2 = '/api/stockArray/' $.ajax({ method: 'GET', url: endpoint2, success: function(stockArray){ priceArray = stockArray setChart(priceArray) } }) function setChart() { let testClose = priceArray.map(e => e.data_close) let testLabels = priceArray.map(e => new Date(e.data_date).setHours(0, 0, 0, 0)) let testOpen = priceArray.map(e => e.data_open) let testHigh = priceArray.map(e => e.low) let testLow = priceArray.map(e => e.high) const data = { labels: [], datasets: [{ type: 'ohlc', label: 'Stocks', backgroundColor: '#ffffff', borderColor: '#000000', data: [ { x: testLabels, o: testOpen, h: testHigh, l: testLow, c: testClose, } ] }] } const config = { data, options: { scales: { x: { type: 'timeseries', time: { unit: 'day' } }, y: { beginAtZero: true, max: 3 } } } }; new Chart( document.getElementById('myChart'), config ); } </script>
已尝试的日期处理方式
三种生成X轴刻度的方式均报错,对应日志值如下:
testLabels = priceArray.map(e => new Date(e.data_date).setHours(0, 0, 0, 0))→[1450328400000, 1450846800000...]testLabels2 = priceArray.map(e => new Date(e.data_date))→[Thu Dec 17 2015 19:00:00 GMT-0500 (Eastern Standard Time), Wed Dec 23 2015 19:00:00 GMT-0500 (Eastern Standard Time)...]testLabels3 = priceArray.map(e => e.data_date)→['2015-12-18', '2015-12-24'...]
静态数据对比现象
- 多组静态数据可正常显示:
data: [ { x: new Date ('2022-08-10').setHours(0, 0, 0, 0), o: 1.00, h: 1.35, l: 0.90, c: 1.20, }, { x: new Date ('2022-08-11').setHours(0, 0, 0, 0), o: 1.00, h: 1.35, l: 0.90, c: 1.20, } ]
- 单组静态数据图表空白:
data: [ { x: new Date ('2022-08-10').setHours(0, 0, 0, 0), o: 1.00, h: 1.35, l: 0.90, c: 1.20, } ]
解决方案
1. 修正OHLC数据集格式(核心错误)
当前代码将所有数据的x/o/h/l/c打包成单个对象,完全不符合Chart.js OHLC数据集的要求。正确做法是为每个数据点创建独立的OHLC对象:
function setChart(priceArray) { // 遍历数据,生成标准OHLC格式数组 const ohlcData = priceArray.map(item => ({ x: new Date(item.data_date), // 直接用Date对象,适配器自动解析 o: item.data_open, h: item.data_high, // 修正之前高低值搞反的错误 l: item.data_low, c: item.data_close })); const data = { datasets: [{ type: 'ohlc', label: 'Stocks', backgroundColor: '#ffffff', borderColor: '#000000', data: ohlcData // 直接使用处理后的数组 }] }; const config = { data, options: { scales: { x: { type: 'timeseries', time: { unit: 'day' } }, y: { beginAtZero: false, // 金融数据无需从0开始,避免图表压缩 // 移除固定max值,让Chart.js自动计算合理范围 } } } }; new Chart(document.getElementById('myChart'), config); }
2. 日期处理优化
- 直接使用
new Date(item.data_date)生成Date对象即可,chartjs-adapter-date-fns能正确解析ISO格式日期字符串(如'2015-12-18') - 无需调用
setHours(0,0,0,0),适配器会自动处理时间部分
3. 单组数据空白问题说明
OHLC图表依赖至少两个数据点来渲染蜡烛形态(通过高低开收的对比展示波动),单组数据无法形成有效蜡烛,因此空白是正常行为。如需支持单数据点,可:
- 添加一个相邻日期的占位数据(如复制当前数据并修改日期)
- 动态切换为折线图展示单数据点
4. 其他注意事项
- 检查数据字段映射:之前代码中
testHigh取了e.low、testLow取了e.high,属于字段映射错误,必须修正 - 确保Ajax返回的
priceArray是有效数组,无空值或无效日期 setChart函数需接收传入的priceArray参数,避免依赖全局变量引发异常
内容的提问来源于stack exchange,提问作者fitted_sheet
相关产品推荐
相关产品推荐

