UNPKG

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

116 lines (96 loc) 3.32 kB
/* eslint-disable @typescript-eslint/no-explicit-any */ import ChartJS, { ChartConfiguration, ChartConfigurationCustomTypesPerDataset } from 'chart.js/auto' import { Color } from '../numbers' export interface DatasetOptions { label: string color?: Color } export interface ChartConstructor { root: HTMLElement datasets: DatasetOptions[] maxDataSize?: number axisLabels?: { x: string, y: string } title?: string width?: number } /** * Creates a time series chart. * The x-axis is time and the y-axis is a number. */ export default class TimeSeries { // private data: {x: number, y: number}[] = [] private chart: ChartJS<'line', number[], any> private width: number private maxDataSize: number constructor(opts: ChartConstructor) { const axisLabels = opts.axisLabels ?? { x: 'time', y: 'Y' } const title = opts.title ?? 'Time Series' this.maxDataSize = opts.maxDataSize ?? Infinity 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: ChartConfigurationCustomTypesPerDataset<'line', number[], any>['data']['datasets'] = opts.datasets.map((dataset) => { const borderColor = dataset.color?.toRGB() ?? Color.fromName('blue').toRGB() return { type: 'line', label: dataset.label, data: [], fill: false, borderColor, tension: 0.1 } }) const chartOptions: ChartConfiguration<'line', number[], any> = { type: 'line', data: { labels: [], datasets }, options: { scales: { x: { title: { display: true, text: axisLabels.x } }, y: { title: { display: true, text: axisLabels.y }, beginAtZero: true } } } } this.chart = new ChartJS<'line', number[], any>(canvas, chartOptions) } /** * Pushes data to the chart. * The data should be an array of numbers, where each array corresponds to a dataset * in the order they were added. */ public pushData(data: number[]): void { let didShift = false this.chart.data.datasets.forEach( dataset => { if (dataset.data.length > this.maxDataSize) { dataset.data.shift() didShift = true } }) if (didShift) { this.chart.data.labels.shift() } this.chart.data.datasets.forEach((dataset, i) => { dataset.data.push(data[i]) }) this.chart.data.labels.push('') this.chart.update() } }