import functionPlot from "function-plot"; import { action, computed, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { Doc, DocListCast } from '../../../fields/Doc'; import { documentSchema } from '../../../fields/documentSchemas'; import { List } from '../../../fields/List'; import { createSchema, listSpec, makeInterface } from '../../../fields/Schema'; import { Cast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; import { Docs } from '../../documents/Documents'; import { ViewBoxBaseComponent } from '../DocComponent'; import { FieldView, FieldViewProps } from './FieldView'; const EquationSchema = createSchema({}); type EquationDocument = makeInterface<[typeof EquationSchema, typeof documentSchema]>; const EquationDocument = makeInterface(EquationSchema, documentSchema); @observer export class FunctionPlotBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FunctionPlotBox, fieldKey); } public static GraphCount = 0; _plot: any; _plotId = ""; _plotEle: any; constructor(props: any) { super(props); this._plotId = "graph" + FunctionPlotBox.GraphCount++; } componentDidMount() { this.props.setContentView?.(this); reaction(() => [DocListCast(this.dataDoc.data).lastElement()?.text, this.layoutDoc.width, this.layoutDoc.height, this.dataDoc.xRange, this.dataDoc.yRange], () => this.createGraph()); } getAnchor = () => { const anchor = Docs.Create.TextanchorDocument({ annotationOn: this.rootDoc }); anchor.xRange = new List(Array.from(this._plot.options.xAxis.domain)); anchor.yRange = new List(Array.from(this._plot.options.yAxis.domain)); return anchor; } @action scrollFocus = (doc: Doc, smooth: boolean) => { this.dataDoc.xRange = new List(Array.from(Cast(doc.xRange, listSpec("number"), Cast(this.dataDoc.xRange, listSpec("number"), [-10, 10])))); this.dataDoc.yRange = new List(Array.from(Cast(doc.yRange, listSpec("number"), Cast(this.dataDoc.xRange, listSpec("number"), [-1, 9])))); return 0; } createGraph = (ele?: HTMLDivElement) => { this._plotEle = ele || this._plotEle; const width = this.props.PanelWidth(); const height = this.props.PanelHeight(); const fn = StrCast(DocListCast(this.dataDoc.data).lastElement()?.text, "x^2").replace(/\\frac\{(.*)\}\{(.*)\}/, "($1/$2)"); try { this._plot = functionPlot({ target: "#" + this._plotEle.id, width, height, xAxis: { domain: Cast(this.dataDoc.xRange, listSpec("number"), [-10, 10]) }, yAxis: { domain: Cast(this.dataDoc.xRange, listSpec("number"), [-1, 9]) }, grid: true, data: [ { fn, // derivative: { fn: "2 * x", updateOnMouseMove: true } } ] }); } catch (e) { console.log(e); } } @computed get theGraph() { return
r && this.createGraph(r)} style={{ position: "absolute", width: "100%", height: "100%" }} onPointerDown={e => e.stopPropagation()} />; } render() { TraceMobx(); return (
{this.theGraph}
); } }