1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
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<FieldViewProps, EquationDocument>(EquationDocument) {
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<number>(Array.from(this._plot.options.xAxis.domain));
anchor.yRange = new List<number>(Array.from(this._plot.options.yAxis.domain));
return anchor;
}
@action
scrollFocus = (doc: Doc, smooth: boolean) => {
this.dataDoc.xRange = new List<number>(Array.from(Cast(doc.xRange, listSpec("number"), Cast(this.dataDoc.xRange, listSpec("number"), [-10, 10]))));
this.dataDoc.yRange = new List<number>(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 <div id={`${this._plotId}`} ref={r => r && this.createGraph(r)} style={{ position: "absolute", width: "100%", height: "100%" }}
onPointerDown={e => e.stopPropagation()} />;
}
render() {
TraceMobx();
return (<div
style={{
pointerEvents: !this.isContentActive() ? "all" : undefined,
width: this.props.PanelWidth(),
height: this.props.PanelHeight()
}}
>
{this.theGraph}
<div style={{
display: this.props.isSelected() ? "none" : undefined, position: "absolute", width: "100%", height: "100%",
pointerEvents: "all"
}} />
</div>);
}
}
|