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

从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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:31:35