/* eslint-disable @typescript-eslint/no-explicit-any */ import ChartJS, { type ChartConfiguration } from 'chart.js/auto' import { Color } from '../numbers' export interface DatasetOptions { label: string color?: Color } export interface ChartConstructor { root: HTMLElement datasets: DatasetOptions[] axisLabels?: { x: string, y: string } title?: string width?: number } /** * Creates an X-Y scatter plot. */ export default class ScatterPlot { private chart: ChartJS<'scatter'> private width: number constructor(opts: ChartConstructor) { const axisLabels = opts.axisLabels ?? { x: 'time', y: 'Y' } const title = opts.title ?? 'Scatter Plot' this.width = opts.width ?? 400 const canvas = document.createElement('canvas') const draggable = document.createElement('drag-pane') draggable.setAttribute('heading', title ) draggable.setAttribute('key', title) draggable.appendChild(canvas) opts.root.appendChild(draggable) canvas.width = this.width const datasets = opts.datasets.map((dataset) => { const borderColor = dataset.color?.toRGB() ?? Color.fromName('blue').toRGB() return { label: dataset.label, data: [], backgroundColor: 'rgba(54, 162, 235, 0.2)', borderColor, borderWidth: 1 } }) const chartOptions: ChartConfiguration<'scatter'> = { type: 'scatter', data: { datasets }, options: { scales: { x: { title: { display: true, text: axisLabels.x } }, y: { title: { display: true, text: axisLabels.y }, beginAtZero: true } } } } this.chart = new ChartJS(canvas, chartOptions) } /** * Pushes an array of data point arrays to the chart. * * The ith array of points corresponds to the ith dataset * defined for the chart. */ public pushData(data: {x: number, y: number}[][]): void { // this.chart.data.datasets[0].data.push(...data) data.forEach( (data, index) => { this.chart.data.datasets[index].data.push(...data) }) this.chart.update() } }