ChartJS 为大型数据集生成刻度会截断刻度数组,即使大多数刻度为空

yws3nbqq  于 2022-11-06  发布在  Chart.js
关注(0)|答案(1)|浏览(204)

我正在使用Angular Chart.js生成包含大量数据的linear图表(通常在3,000点以北)。每个数据点都有一个包含重要信息的关联对象实际上,我希望从一个新的月份开始,在每个点上都有一个刻度,包含月份和年份(即“Jun 22”)。每个月之间的数据量是可变的,因此对于我的用例来说,不可能均匀地分布分笔成交点。
这里的问题是Chart.js不喜欢有超过1000个刻度的图表,即使这些刻度是空的或未定义的,我最多只需要显示大约36个刻度。
我有一个实用程序函数,它返回{index: label}的Map,这将简化每次创建新分笔成交点时过滤整个数据集的工作(例如,它看起来像

{0: 'Jun 22', 405: 'Jul 22', 1295: 'Aug 22', etc...}

使用该Map,我设置了stepSize: 1并修改了回调函数:

callback: (index) => {return theMap[index] || null}

Chart.js抛出一个警告scales.x.ticks.stepSize: 1 would result generating up to 3437 ticks. Limiting to 1000.即使这些数据点中的大多数在Map中没有关联点(因此有一个空刻度),我猜chart.js仍然认为它是一个刻度,然后显示一些奇怪的行为,它实际上显示了哪些刻度。
请参见下面的示例,并注意缺少“7月21日”、“8月21日”和“8月22日”(正确隐藏了“11月-4月”)

有一个简单的解决方法:设置stepSize: 5,然后修改回调以检查步骤的边界:

callback: (label: number, index: number, values) => {
    for (let i = label - 2; i < label + 3; i++) {
        if (this.theMap[i]) return this.theMap[i];
    }
    return null;
}

这会将生成的记号数减少5倍,但不会显示彼此距离小于5个单位的两个记号。
如果有人处理过类似的事情,并知道一个解决方案,以获得一致的分笔成交点生成与大型数据集好奇。

qcbq4gxm

qcbq4gxm1#

这是一个使用时间刻度添加3000个项目的codepen https://codepen.io/stockinail/pen/PoaNjbp。希望我已经很好地理解了您的用例。注意这个示例使用的是CHART.JS 3。使用ticks.source: 'label',我可以强制CHARTJS使用刻度中传递的标签(也要注意parser选项,需要解析刻度的标签)。

scales: {
 x: {
    type: 'time',
    labels: ['Sep 22', 'Oct 22', 'Nov 22', 'Dec 22'],
    ticks: {
      source: 'labels'
    },
    time: {
        unit: 'month',
        displayFormats: {
          month: 'MMM yy'
        },
        parser: 'MMM yy'
    }
 }
}

相关问题