Skip to content

Commit e93d0ca

Browse files
committed
Template graph scaffolding
This is still in progress, but just laying out a few more things as I want to keep the ball rolling here. I have the expression inside the new template graph class - next step is just to render it in the jsxgraph view.
1 parent 731a0a6 commit e93d0ca

9 files changed

+205
-39
lines changed

media/js/src/GraphEditor.jsx

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import NonLinearDemandSupplyEditor from './editors/NonLinearDemandSupplyEditor.j
77
import ConsumptionLeisureEditor from './editors/ConsumptionLeisureEditor.jsx';
88
import ConsumptionSavingEditor from './editors/ConsumptionSavingEditor.jsx';
99
import DemandSupplyEditor from './editors/DemandSupplyEditor.jsx';
10+
import TemplateGraphEditor from './editors/TemplateGraphEditor.jsx';
1011
import CommonGraphEditor from './editors/CommonGraphEditor.jsx';
1112
import CommonGraphSettings from './editors/CommonGraphSettings.jsx';
1213
import JXGBoard from './JXGBoard.jsx';
@@ -245,6 +246,13 @@ export default class GraphEditor extends React.Component {
245246
{...commonEditorProps}
246247
{...this.props}
247248
/>;
249+
} else if (this.props.gType === 16) {
250+
// Template Graph: free-form equations
251+
rightSide =
252+
<TemplateGraphEditor
253+
{...commonEditorProps}
254+
{...this.props}
255+
/>;
248256
}
249257

250258
return (

media/js/src/GraphMapping.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ const exportGraph = function(state) {
104104

105105
area_a_name: state.gAreaAName,
106106
area_b_name: state.gAreaBName,
107-
area_c_name: state.gAreaCName
107+
area_c_name: state.gAreaCName,
108+
109+
expression: state.gExpression
108110
};
109111

110112
if (state.gType === 3 || state.gType === 12) {
@@ -215,7 +217,9 @@ const convertGraph = function(json) {
215217

216218
gAreaAName: json.area_a_name,
217219
gAreaBName: json.area_b_name,
218-
gAreaCName: json.area_c_name
220+
gAreaCName: json.area_c_name,
221+
222+
gExpression: json.expression
219223
};
220224
};
221225

@@ -315,7 +319,9 @@ const importGraph = function(json, obj, callback=null) {
315319

316320
gAreaAName: json.area_a_name,
317321
gAreaBName: json.area_b_name,
318-
gAreaCName: json.area_c_name
322+
gAreaCName: json.area_c_name,
323+
324+
gExpression: json.expression
319325
};
320326

321327
// When importing a graph for display, save the initial state of
@@ -572,6 +578,8 @@ const defaultGraph = {
572578
gAreaBName: 'B',
573579
gAreaCName: 'C',
574580

581+
gExpression: 'x',
582+
575583
// Use a hard-coded proof-of-concept assessment spreadsheet for
576584
// now. Eventually, this will be defined using a Google
577585
// Spreadsheet, or some react-spreadsheet component with its data

media/js/src/JXGBoard.jsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,9 @@ export default class JXGBoard extends React.Component {
262262
'gCobbDouglasAlpha', 'gCobbDouglasAlphaInitial', 'gNName',
263263
'gFunctionChoice', 'gAreaConfiguration',
264264
'gAreaConfigurationInitial', 'gIsAreaDisplayed', 'gAreaAName',
265-
'gAreaBName', 'gAreaCName', 'gNeedsSubmit', 'submission',
265+
'gAreaBName', 'gAreaCName',
266+
'gExpression',
267+
'gNeedsSubmit', 'submission',
266268
'shadow'
267269
];
268270

@@ -704,6 +706,8 @@ JXGBoard.propTypes = {
704706
gAreaBName: PropTypes.string,
705707
gAreaCName: PropTypes.string,
706708

709+
gExpression: PropTypes.string,
710+
707711
id: PropTypes.string.isRequired,
708712
locked: PropTypes.bool
709713
};

media/js/src/Viewer.jsx

+5
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ class Viewer extends Component {
130130
gAreaBName={this.state.gAreaBName}
131131
gAreaCName={this.state.gAreaCName}
132132

133+
gExpression={this.state.gExpression}
134+
133135
updateDisplayIntersection={this.updateDisplayIntersection.bind(this)}
134136
updateGraph={this.handleGraphUpdate.bind(this)}
135137
saveGraph={this.handleSaveGraph.bind(this)}
@@ -268,6 +270,8 @@ class Viewer extends Component {
268270
gAreaBName={this.state.gAreaBName}
269271
gAreaCName={this.state.gAreaCName}
270272

273+
gExpression={this.state.gExpression}
274+
271275
assessment={this.state.assessment}
272276
submission={this.state.submission}
273277
updateGraph={this.handleGraphUpdate.bind(this)}
@@ -410,6 +414,7 @@ class Viewer extends Component {
410414
}
411415

412416
handleGraphUpdate(obj) {
417+
console.log('handleGraphUpdate', obj);
413418
this.setState(obj);
414419
}
415420
updateDisplayIntersection(checked) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { MathComponent } from 'mathjax-react';
4+
5+
import EditableControl from '../form-components/EditableControl.js';
6+
import { handleFormUpdate } from '../utils.js';
7+
8+
export default class TemplateGraphEditor extends React.Component {
9+
render() {
10+
const func1 = String.raw`MP_N = (1 - \alpha)AK^\alpha N^{-\alpha}`;
11+
const func2 = String.raw`MP_K = \alpha AK^{\alpha - 1} N^{1 - \alpha}`;
12+
13+
return (
14+
<>
15+
<div className="d-flex flex-wrap">
16+
<div className="row">
17+
<div className="col">
18+
<label className="form-check-label me-2"
19+
htmlFor="gExpression">
20+
<MathComponent tex={`y = `} />
21+
</label>
22+
<EditableControl
23+
id="gExpression"
24+
name="Expression"
25+
value={this.props.gExpression}
26+
valueEditable={true}
27+
isInstructor={this.props.isInstructor}
28+
disabled={this.props.disabled}
29+
updateGraph={this.props.updateGraph} />
30+
</div>
31+
</div>
32+
</div>
33+
34+
<h3 className="mt-3">
35+
NLDS Function
36+
</h3>
37+
38+
<div className="row">
39+
<div className="form-check">
40+
<input className="form-check-input"
41+
aria-label={func1}
42+
type="radio"
43+
name="gFunctionChoice"
44+
id="gFunctionChoice1"
45+
onChange={handleFormUpdate.bind(this)}
46+
value={0}
47+
checked={this.props.gFunctionChoice === 0} />
48+
<label className="form-check-label"
49+
htmlFor="gFunctionChoice1">
50+
<MathComponent tex={func1} />
51+
</label>
52+
</div>
53+
</div>
54+
<div className="row">
55+
<div className="form-check">
56+
<input className="form-check-input"
57+
aria-label={func2}
58+
type="radio"
59+
name="gFunctionChoice"
60+
id="gFunctionChoice2"
61+
onChange={handleFormUpdate.bind(this)}
62+
value={1}
63+
checked={this.props.gFunctionChoice === 1} />
64+
<label className="form-check-label"
65+
htmlFor="gFunctionChoice2">
66+
<MathComponent tex={func2} />
67+
</label>
68+
</div>
69+
</div>
70+
</>
71+
);
72+
}
73+
}
74+
75+
TemplateGraphEditor.propTypes = {
76+
gType: PropTypes.number,
77+
updateGraph: PropTypes.func.isRequired,
78+
79+
isInstructor: PropTypes.bool.isRequired,
80+
81+
disabled: PropTypes.bool
82+
};

media/js/src/form-components/EditableControl.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export default class EditableControl extends React.Component {
2020
name={this.props.id}
2121
className="form-control"
2222
type="text"
23-
maxLength="60"
23+
maxLength={this.props.maxLength || 60}
2424
disabled={this.props.disabled}
2525
value={this.props.value}
2626
onChange={handleFormUpdate.bind(this)} />
@@ -37,5 +37,6 @@ EditableControl.propTypes = {
3737
isInstructor: PropTypes.bool.isRequired,
3838
value: PropTypes.string,
3939
valueEditable: PropTypes.bool.isRequired,
40-
disabled: PropTypes.bool
40+
disabled: PropTypes.bool,
41+
maxLength: PropTypes.number
4142
};

media/js/src/graphs/TemplateGraph.js

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {Graph} from './Graph.js';
22

33
export class TemplateGraph extends Graph {
44
make() {
5+
// TODO: parse and render this.options.gExpression
56
}
67
}
78

package-lock.json

+79-22
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)