diff --git a/src/components/RangeChart.vue b/src/components/RangeChart.vue
new file mode 100644
index 0000000..25fc305
--- /dev/null
+++ b/src/components/RangeChart.vue
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/Editor.vue b/src/pages/Editor.vue
index d76ae09..eb3e378 100644
--- a/src/pages/Editor.vue
+++ b/src/pages/Editor.vue
@@ -3,7 +3,7 @@ import {onMounted, ref} from 'vue'
import { v4 as uuidv4 } from 'uuid'
import {MathPage} from '../support/page'
import {MathStatement} from '../support/parse'
-import {EvaluationResult, hasOwnProperty} from '../support/types'
+import {ChartBox, EvaluationResult, hasOwnProperty} from '../support/types'
import Statement from '../components/Statement.vue'
import VarDeclEditor from './VarDeclEditor.vue'
import ExpressionEditor from './ExpressionEditor.vue'
@@ -11,6 +11,8 @@ import TextBox from '../components/TextBox.vue'
import {RichTextBox} from '../support/types'
import { stepX, stepY } from '../support/const'
import FunctionEditor from '../components/FunctionEditor.vue'
+import RangeChart from '../components/RangeChart.vue'
+import RangeChartEditor from './RangeChartEditor.vue'
const math = new MathPage(uuidv4());
const statements = ref([]);
@@ -185,6 +187,39 @@ const makeNewRichTextBox = () => {
richEditModal.value = true;
};
+const chartBoxKey = ref(uuidv4())
+const chartBoxes = ref([])
+
+const newChartModalOpen = ref(false)
+const openNewChartModal = () => {
+ newChartModalOpen.value = true
+}
+
+const saveNewChartBox = (chartBox: ChartBox) => {
+ chartBoxes.value.push(chartBox)
+ newChartModalOpen.value = false
+}
+
+const editingChartBox = ref()
+const chartEditModalOpen = ref(false)
+const openChartEditModal = (box: ChartBox) => {
+ editingChartBox.value = box
+ chartEditModalOpen.value = true
+}
+
+const saveEditingChartBox = () => {
+ chartEditModalOpen.value = false
+ chartBoxKey.value = uuidv4()
+}
+
+const moveChartBox = (id: number, x: number, y: number) => {
+ chartBoxes.value[id].x = x
+ chartBoxes.value[id].y = y
+}
+const removeChartBox = (id: number) => {
+ chartBoxes.value.splice(id, 1);
+};
+
const richTextStatements = ref([]);
const richEditModal = ref(false);
@@ -290,6 +325,17 @@ const removeRichTextBox = (id: number) => {
+
+
+
+
{
/>
+
+
+
+
+
+
+
+
{
/>
makeNewRichTextBox()"
/>
+ openNewChartModal()"
+ />
diff --git a/src/pages/RangeChartEditor.vue b/src/pages/RangeChartEditor.vue
new file mode 100644
index 0000000..b7e59e1
--- /dev/null
+++ b/src/pages/RangeChartEditor.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+ {{ chartBoxModalError }}
+
+
+
+
+
+
+
+
+
+
+
+
+ saveChartBox()">
+
+
+
diff --git a/src/support/page.ts b/src/support/page.ts
index cb2336e..377c72c 100644
--- a/src/support/page.ts
+++ b/src/support/page.ts
@@ -128,6 +128,16 @@ export class MathPage {
.filter(x => x.isFunctionDeclaration())
}
+ /** Look up a function statement by name, if it exists. */
+ getFunctionByName(name: string): MathStatement|undefined {
+ for ( const fn of this.functions() ) {
+ const node = fn.parse() as math.FunctionAssignmentNode
+ if ( node.name === name ) {
+ return fn
+ }
+ }
+ }
+
/** Evaluate the current state of the page and get the result. */
evaluate(): EvaluationResult {
const evaluations: Record = {}
diff --git a/src/support/types.ts b/src/support/types.ts
index 533e3aa..004c1ce 100644
--- a/src/support/types.ts
+++ b/src/support/types.ts
@@ -111,3 +111,16 @@ export class ImageBox {
}
+export class ChartBox {
+ // eslint-disable-next-line max-params
+ constructor(
+ public fnName: string,
+ public minX: number,
+ public maxX: number,
+ public stepX: number = 1,
+ public x: number = 0,
+ public y: number = 0,
+ ) {}
+}
+
+