import { observer } from "mobx-react"; import * as React from "react"; import { Doc } from "../../../../fields/Doc"; import { Chart as ChartJS, CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend, InteractionItem, PointElement, LineElement, } from 'chart.js'; import { Bar, getDatasetAtEvent, getElementAtEvent, Line } from 'react-chartjs-2'; import { ChartJSOrUndefined } from "react-chartjs-2/dist/types"; import { action, computed, observable } from "mobx"; import { Cast, StrCast } from "../../../../fields/Types"; export interface ChartBoxProps { rootDoc: Doc; pairs: {x: number, y:number}[]; } export interface ChartJsData { labels: number[]; datasets: { label: string; data: number[]; backgroundColor: string[]; }[] } ChartJS.register( CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend, PointElement, LineElement ); const primaryColor = 'rgba(53, 162, 235, 0.5)'; const selectedColor = 'rgba(255, 99, 132, 0.5)'; @observer export class ChartBox extends React.Component { private _chartRef: any = React.createRef>(); @observable private _prevColor: string | undefined= undefined; @observable private _prevIndex: { dIndex: number, index: number} | undefined = undefined; @observable private _chartJsData: ChartJsData | undefined= undefined; @computed get currView() { if (this.props.rootDoc._dataVizView) { return StrCast(this.props.rootDoc._currChartView); } else { return "table"; } } constructor(props: any) { super(props); if (!this.props.rootDoc._currChartView) { this.props.rootDoc._currChartView = "bar"; } } @computed get options() { return { responsive: true, plugins: { legend: { position: 'top' as const, }, title: { display: true, text: 'Bar Chart', }, }, } } @action generateChartJsData() { if (this.props.rootDoc._chartData) { // parse the string into a json object this._chartJsData = JSON.parse(StrCast(this.props.rootDoc._chartData)); this._prevColor = StrCast(this.props.rootDoc._prevColor); this._prevIndex = JSON.parse(StrCast(this.props.rootDoc._prevIndex)); return; } const labels = this.props.pairs.map(p => p.x); const dataset = { label: 'Dataset 1', data: this.props.pairs.map(p => p.y), backgroundColor: this.props.pairs.map(p => primaryColor), } const data = { labels, datasets: [dataset] }; this._chartJsData = data; } componentDidMount() { this.generateChartJsData(); } @action onClickChangeChart = (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); console.log(e.currentTarget.value); this.props.rootDoc._currChartView = e.currentTarget.value.toLowerCase(); } @action onClick = (e: any) => { e.preventDefault(); if (getDatasetAtEvent(this._chartRef.current, e).length == 0) return; if (!this._chartJsData) return; if (this._prevIndex && this._prevColor) { this._chartJsData.datasets[this._prevIndex.dIndex].backgroundColor[this._prevIndex.index] = this._prevColor; } const currSelected = getElementAtEvent(this._chartRef.current, e); const index = { datasetIndex: currSelected[0].datasetIndex, index: currSelected[0].index }; this._prevIndex = { dIndex: index.datasetIndex, index: index.index }; this._prevColor = this._chartJsData.datasets[index.datasetIndex].backgroundColor[index.index]; this._chartJsData.datasets[index.datasetIndex].backgroundColor[index.index] = selectedColor; this._chartRef.current.update(); // stringify this._chartJsData const strData = JSON.stringify(this._chartJsData); this.props.rootDoc._chartData = strData; this.props.rootDoc._prevColor = this._prevColor; this.props.rootDoc._prevIndex = JSON.stringify(this._prevIndex); } render() { if (this.props.pairs && this._chartJsData) { return (
{this.props.rootDoc._currChartView == "line" ? ( this.onClick(e)} />) : ( this.onClick(e)} />) }
) } else { return
} } }