agentscape
Version:
Agentscape is a library for creating agent-based simulations. It provides a simple API for defining agents and their behavior, and for defining the environment in which the agents interact. Agentscape is designed to be flexible and extensible, allowing
93 lines (80 loc) • 2.64 kB
text/typescript
/* 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()
}
}