Playwright+TypeScript:如何访问Chart.js画布事件监听器存储的数据?
获取Chart.js画布数据的可行方案
不需要通过模拟鼠标事件间接获取数据,Chart.js会将图表实例直接关联到画布元素或全局实例列表中,以下是几种直接获取数据的方法:
方法1:通过画布元素的chart属性获取实例
Chart.js初始化后通常会把实例挂载到目标canvas元素的chart属性上,直接读取即可拿到完整数据:
const chartData = await page.evaluate(() => { const canvas = document.querySelector("canvas"); // 若有多个画布,建议用更精准的选择器(如id/class) const chart = canvas?.chart; if (!chart) return null; // 返回你需要的核心数据结构 return { labels: chart.data.labels, datasets: chart.data.datasets.map(ds => ({ label: ds.label, data: ds.data })) }; }); console.log(chartData);
方法2:遍历全局Chart实例列表查找
如果画布元素没有chart属性,可以通过Chart.instances全局数组匹配目标画布:
const chartData = await page.evaluate(() => { const canvas = document.querySelector("canvas"); const chart = Chart.instances.find(instance => instance.canvas === canvas); if (!chart) return null; return { labels: chart.data.labels, datasets: chart.data.datasets.map(ds => ({ label: ds.label, data: ds.data })) }; });
方法3:获取鼠标位置对应的数据点(如需交互数据)
如果需要模拟鼠标位置获取对应的数据点(比如悬停时的具体数值),可以用Chart.js内置的getElementsAtEventForMode方法:
const hoverData = await page.evaluate(() => { const canvas = document.querySelector("canvas"); const chart = canvas?.chart; if (!chart) return null; // 传入目标坐标(和你之前模拟的clientX/Y对应) const position = { x: 100, y: 100 }; const elements = chart.getElementsAtEventForMode( position, "nearest", { intersect: true }, false ); if (elements.length === 0) return null; // 提取数据点的详细信息 const targetElement = elements[0]; const datasetIndex = targetElement.datasetIndex; const dataIndex = targetElement.index; return { datasetLabel: chart.data.datasets[datasetIndex].label, value: chart.data.datasets[datasetIndex].data[dataIndex], category: chart.data.labels[dataIndex] }; }); console.log(hoverData);
为什么你之前的方法无效?
你模拟的mousemove事件被自己添加的监听器优先捕获了,并没有触发Chart.js的事件处理逻辑。而且Chart.js的事件回调里的数据是内部处理后的结果,远不如直接读取实例数据高效可靠。
内容的提问来源于stack exchange,提问作者Clara Lee
相关产品推荐
相关产品推荐

