Skip to content

Commit 90ee882

Browse files
committed
基础逻辑
1 parent cedfbdf commit 90ee882

3 files changed

Lines changed: 117 additions & 17 deletions

File tree

src/App.vue

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,48 @@
11
<template>
22
<Navbar />
33
<div id="content">
4-
<div id="editor" @click="graphData.push({ fn: 'sin(x)' })">{{ graphData }}</div>
4+
<div id="editor">
5+
<div v-for="dataItem in graphData" class="plot-data">
6+
<select
7+
v-model="dataItem.fnType"
8+
@change="
9+
getFnType(dataItem.fnType).notAllowedInIntervel &&
10+
!dataItem.graphType &&
11+
(dataItem.graphType = 'polyline')
12+
"
13+
>
14+
<option :value="undefined">{{ fnTypeArr[0].label }}</option>
15+
<option v-for="type in fnTypeArr.slice(1)" :value="type.value">
16+
{{ type.label }}
17+
</option>
18+
</select>
19+
20+
<select v-model="dataItem.graphType">
21+
<option
22+
v-if="!getFnType(dataItem.fnType).notAllowedInIntervel"
23+
:value="undefined"
24+
>
25+
{{ graphTypeArr[0].label }}
26+
</option>
27+
<option v-for="type in graphTypeArr.slice(1)" :value="type.value">
28+
{{ type.label }}
29+
</option>
30+
</select>
31+
<div class="input-wrapper">
32+
<input
33+
v-for="input in inputArr.filter(({ value }) => {
34+
const inputs = getFnType(dataItem.fnType).inputs;
35+
if (inputs.includes(value)) return true;
36+
else delete dataItem[value];
37+
})"
38+
type="text"
39+
v-model="dataItem[input.value]"
40+
/>
41+
</div>
42+
</div>
43+
<div class="add-data" @click="graphData.push({})">+ 添加</div>
44+
{{ graphData }}
45+
</div>
546
<Graph :graphData="graphData" />
647
</div>
748
</template>
@@ -10,11 +51,12 @@
1051
import Navbar from "./components/nav.vue";
1152
import Graph from "./components/graph.vue";
1253
import type { FunctionPlotDatum } from "function-plot";
13-
14-
import { reactive, ref, watch } from "vue";
15-
const graphData = ref([{ fn: 'x^2' }]);
16-
const cnt = ref(0);
17-
watch(graphData, () => cnt.value++,{deep:true});
54+
import { reactive } from "vue";
55+
import { fnTypeArr, graphTypeArr, inputArr } from "./consts";
56+
import type { FnType, ValueLabel } from "./consts";
57+
const graphData = reactive<FunctionPlotDatum[]>([{ fn: "x^2" }]);
58+
const getFnType = (fnType?: string) =>
59+
<FnType>fnTypeArr.find(({ value }) => value === (fnType || "linear"));
1860
</script>
1961

2062
<style>

src/components/graph.vue

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
<template>
22
<div id="graph" ref="shellRef">
3-
{{ width }},{{ height }},{{ cnt }}
3+
{{ width }},{{ height }}
44
<div id="graphRender" ref="plotRef"></div>
55
</div>
66
</template>
77

88
<script setup lang="ts">
9-
import { onMounted, onUnmounted, ref, watch, watchEffect } from "vue";
9+
import { onMounted, onUnmounted, ref, watch } from "vue";
1010
import functionPlot from "function-plot";
1111
import type { FunctionPlotDatum } from "function-plot";
1212
const { graphData } = defineProps<{ graphData: FunctionPlotDatum[] }>();
1313
const shellRef = ref<HTMLDivElement | null>(null);
1414
const plotRef = ref<HTMLDivElement | null>(null);
1515
const width = ref(0),
1616
height = ref(0);
17-
const cnt = ref(0);
1817
const handleResize = () => {
1918
if (shellRef.value) {
2019
width.value = shellRef.value.clientWidth;
@@ -27,25 +26,19 @@ onMounted(() => {
2726
watch(
2827
[width, height, () => graphData],
2928
() => {
30-
cnt.value++
31-
if (plotRef.value && width.value && height.value) {
29+
if (plotRef.value && width.value && height.value)
3230
functionPlot({
3331
data: JSON.parse(JSON.stringify(graphData)),
3432
target: plotRef.value,
3533
width: width.value,
3634
height: height.value,
3735
});
38-
cnt.value++;
39-
}
4036
},
4137
{ immediate: true, deep: true }
4238
);
4339
});
4440
onUnmounted(() => window.removeEventListener("resize", handleResize));
45-
watch(
46-
() => graphData,
47-
() => cnt.value++
48-
);
41+
4942
</script>
5043

5144
<style>

src/consts.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
export type ValueLabel = {
2+
value: string;
3+
label: string;
4+
};
5+
6+
export type FnType = ValueLabel & {
7+
inputs: string[];
8+
coord?: ValueLabel[];
9+
notAllowedInIntervel?: boolean;
10+
};
11+
12+
export const inputArr = [
13+
{ value: "fn", label: "函数" },
14+
{ value: "r", label: "半径" },
15+
{ value: "x", label: "x" },
16+
{ value: "y", label: "y" },
17+
{ value: "text", label: "文本" },
18+
] as const satisfies ValueLabel[];
19+
20+
export const graphTypeArr = [
21+
{ value: "interval", label: "默认" },
22+
{ value: "polyline", label: "多边形" },
23+
// { value: "text", label: "text" },
24+
{ value: "scatter", label: "散点" },
25+
] as const satisfies ValueLabel[];
26+
27+
export const fnTypeArr = [
28+
{
29+
value: "linear",
30+
label: "一般",
31+
inputs: ["fn"],
32+
},
33+
{
34+
value: "implicit",
35+
label: "隐函数",
36+
inputs: ["fn"],
37+
},
38+
{
39+
value: "parametric",
40+
label: "参数方程",
41+
inputs: ["x", "y"],
42+
notAllowedInIntervel: true,
43+
},
44+
{
45+
value: "polar",
46+
label: "极坐标",
47+
inputs: ["r"],
48+
notAllowedInIntervel: true,
49+
},
50+
{
51+
value: "points",
52+
label: "点",
53+
inputs: ["x", "y"],
54+
notAllowedInIntervel: true,
55+
},
56+
{
57+
value: "vector",
58+
label: "向量",
59+
inputs: [],
60+
coord: [
61+
{ value: "vector", label: "向量大小" },
62+
{ value: "offset", label: "起点" },
63+
],
64+
},
65+
] as const satisfies FnType[];

0 commit comments

Comments
 (0)