Skip to content

Commit edbf392

Browse files
committed
getting started on the list + deleting storybook
1 parent 615fc11 commit edbf392

10 files changed

Lines changed: 4081 additions & 16320 deletions

File tree

.storybook/package.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

.storybook/preview.js

Lines changed: 0 additions & 9 deletions
This file was deleted.

package.json

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,14 @@
1111
"build": "webpack",
1212
"test": "jest",
1313
"format": "yarn prettier --write .",
14-
"lint": "yarn eslint .",
15-
"storybook": "start-storybook -p 6006",
16-
"build-storybook": "build-storybook"
14+
"lint": "yarn eslint ."
1715
},
1816
"devDependencies": {
19-
"@babel/core": "^7.20.2",
20-
"@mdx-js/react": "^1.6.22",
21-
"@storybook/addon-actions": "^6.5.13",
22-
"@storybook/addon-docs": "^6.5.13",
23-
"@storybook/addon-essentials": "^6.5.13",
24-
"@storybook/addon-interactions": "^6.5.13",
25-
"@storybook/addon-links": "^6.5.13",
26-
"@storybook/builder-webpack5": "^6.5.13",
27-
"@storybook/manager-webpack5": "^6.5.13",
28-
"@storybook/svelte": "^6.5.13",
29-
"@storybook/testing-library": "^0.0.13",
3017
"@tsconfig/svelte": "^3.0.0",
3118
"@types/jest": "^29.2.3",
3219
"@types/node": "*",
3320
"@typescript-eslint/eslint-plugin": "^5.41.0",
3421
"@typescript-eslint/parser": "^5.41.0",
35-
"babel-loader": "^8.3.0",
3622
"eslint": "^8.26.0",
3723
"eslint-config-prettier": "^8.5.0",
3824
"jest": "^29.2.2",
@@ -51,7 +37,9 @@
5137
"yaml": "^2.1.3"
5238
},
5339
"dependencies": {
40+
"css-loader": "^6.7.3",
5441
"function-plot": "^1.23.1",
55-
"obsidian": "0.16.3"
42+
"obsidian": "0.16.3",
43+
"style-loader": "^3.3.1"
5644
}
5745
}

src/app/CreatePlotModal.ts

Lines changed: 83 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import type { FunctionPlotDatum } from "function-plot/dist/types";
22
import { Editor, Modal, Setting } from "obsidian";
3-
import { DEFAULT_PLOT_OPTIONS } from "../common/defaults";
3+
import {
4+
DEFAULT_FUNCTION_OPTIONS,
5+
DEFAULT_PLOT_OPTIONS,
6+
FUNCTION_CASES,
7+
} from "../common/defaults";
48
import type { PlotOptions, rendererType, Line } from "../common/types";
59
import type ObsidianFunctionPlot from "../main";
610
import { createPlot, renderPlotAsInteractive } from "../common/utils";
@@ -36,12 +40,14 @@ export default class CreatePlotModal extends Modal {
3640
this.plot.options.data = this.options.functions.map(
3741
(line): FunctionPlotDatum => {
3842
// use polyline by default
39-
const lineProperties: Line = {graphType: "polyline"};
43+
const lineProperties: Line = { graphType: "polyline" };
4044

4145
line.split("@").forEach((property) => {
4246
const tup = property.split("=");
43-
const value = tup[1].trim()
44-
lineProperties[tup[0].trim()] = value.startsWith("[") ? JSON.parse(value) : value;
47+
const value = tup[1].trim();
48+
lineProperties[tup[0].trim()] = value.startsWith("[")
49+
? JSON.parse(value)
50+
: value;
4551
});
4652

4753
return lineProperties;
@@ -55,8 +61,16 @@ export default class CreatePlotModal extends Modal {
5561
}
5662
}
5763

64+
computeStates(cases, options) {
65+
const states = [];
66+
for (const [test] of cases) {
67+
states.push(test(options));
68+
}
69+
return states;
70+
}
71+
5872
async onOpen() {
59-
this.options = Object.assign({}, DEFAULT_PLOT_OPTIONS);
73+
this.options = JSON.parse(JSON.stringify(DEFAULT_PLOT_OPTIONS)); // deepcopy to avoid side effects
6074

6175
const { contentEl } = this;
6276
contentEl.empty();
@@ -102,26 +116,29 @@ export default class CreatePlotModal extends Modal {
102116
});
103117
});
104118

105-
new Setting(settings)
106-
.setName("Bounds")
107-
.setDesc("Bounds must be written in this format: minX, maxX, minY, maxY.")
108-
.addText((text) => {
109-
text.setPlaceholder(DEFAULT_PLOT_OPTIONS.bounds.join(", "));
110-
text.onChange(async () => {
111-
let bounds = text
112-
.getValue()
113-
.split(",")
114-
.map((c) => parseFloat(c));
115-
const n = bounds.filter((v) => !isNaN(v)).length;
116-
if (n === 0) {
117-
bounds = DEFAULT_PLOT_OPTIONS.bounds;
118-
}
119-
if (n >= 4 || n === 0) {
120-
this.options.bounds = bounds as PlotOptions["bounds"];
121-
this.reloadPreview();
122-
}
123-
});
119+
const placeholders = ["X min", "X max", "Y min", "Y max"];
120+
121+
const bounds = new Setting(settings).setName("Bounds");
122+
123+
placeholders.forEach((placeholder, i) => {
124+
bounds.addText((text) => {
125+
text
126+
.setPlaceholder(placeholder)
127+
.onChange((value) => {
128+
if (value && !isNaN(+value)) {
129+
this.options.bounds[i] = +value;
130+
this.reloadPreview();
131+
} else {
132+
console.log(
133+
`resetting ${i} to default ${DEFAULT_PLOT_OPTIONS.bounds[i]}`
134+
);
135+
this.options.bounds[i] = DEFAULT_PLOT_OPTIONS.bounds[i];
136+
this.reloadPreview();
137+
}
138+
})
139+
.inputEl.classList.add("function-plot-numberinput");
124140
});
141+
});
125142

126143
new Setting(settings).setName("Disable Zoom").addToggle((com) => {
127144
com.setValue(this.options.disableZoom);
@@ -139,21 +156,48 @@ export default class CreatePlotModal extends Modal {
139156
});
140157
});
141158

142-
new Setting(settings)
159+
const functionsSetting = new Setting(settings)
143160
.setName("Functions")
144-
.setDesc(
145-
"Specify functions to plot. Must be in format: <name>(x) = <expression>."
146-
)
147-
.addTextArea((com) => {
148-
com.onChange(async (value) => {
149-
if (!value.trim()) return;
150-
this.options.functions = value
151-
.split("\n")
152-
.map((f) => f.trim() || undefined);
153-
// maybe check if there are valid functions
154-
this.reloadPreview();
161+
.setDesc("Functions to plot.");
162+
functionsSetting.settingEl.setAttribute("style", "display: block");
163+
const functionsControlEl = functionsSetting.controlEl;
164+
functionsControlEl.classList.value = "function-plot-functions-container";
165+
const functionsList = functionsControlEl.createDiv({
166+
attr: { class: "function-plot-functions-list" },
167+
});
168+
169+
functionsControlEl.createDiv(
170+
{ attr: { class: "function-plot-functions-add" } },
171+
(el) => {
172+
new Setting(el).addButton((btn) => {
173+
btn
174+
.setButtonText("Add function")
175+
.setIcon("plus")
176+
.onClick(async () => {
177+
const id = Math.random().toString(36).substring(2, 9);
178+
const options = Object.assign(
179+
JSON.parse(JSON.stringify(DEFAULT_FUNCTION_OPTIONS)),
180+
{ id }
181+
);
182+
const prevStates = this.computeStates(FUNCTION_CASES, options);
183+
184+
new Setting(functionsList).addDropdown((com) => {
185+
com
186+
.addOptions({
187+
linear: "linear",
188+
vector: "vector",
189+
polar: "polar",
190+
points: "points",
191+
})
192+
.setValue(options.fnType)
193+
.onChange((value) => {
194+
options.fnType = value;
195+
});
196+
});
197+
});
155198
});
156-
});
199+
}
200+
);
157201

158202
new Setting(contentEl)
159203
/*.addDropdown((com) => {
@@ -169,12 +213,12 @@ export default class CreatePlotModal extends Modal {
169213
.setButtonText("Plot")
170214
.setCta()
171215
.onClick(async () => {
172-
await this.handlePlotCreate(this.options);
216+
await this.handleFinalPlotCreate(this.options);
173217
});
174218
});
175219
}
176220

177-
async handlePlotCreate(options: PlotOptions) {
221+
async handleFinalPlotCreate(options: PlotOptions) {
178222
// render and insert chosen plot using renderer
179223
switch (this.renderer) {
180224
case "interactive":

src/common/defaults.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
import type { rendererType, PlotOptions, PluginSettings } from "./types";
22

3+
export const DEFAULT_FUNCTION_OPTIONS = {
4+
fnType: 'linear',
5+
fn: '',
6+
vector: ['',''],
7+
r: '',
8+
points: '',
9+
color: null,
10+
offset: ['', ''],
11+
closed: false,
12+
graphType: 'interval',
13+
range: ['', ''],
14+
nSamples: '',
15+
skipTip: false
16+
}
17+
18+
export const FUNCTION_CASES = [
19+
[options => options.fnType == 'vector', () => {/*set fn field to two values*/ }, () => {/*revert to one field*/}]
20+
]
321
/**
422
* The options displayed for renderers
523
*/
@@ -40,6 +58,4 @@ export const DEFAULT_PLUGIN_SETTINGS: PluginSettings = {
4058
gridColor: "var(--interactive-hover)",
4159

4260
defaultRenderer: "interactive",
43-
44-
telemetry: true,
4561
};

src/common/types.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export interface Line {
1919
graphType?: "polyline" | "interval" | "scatter";
2020
nSamples?: number;
2121
range?: [number, number];
22-
closed?: boolean
23-
color?: string
22+
closed?: boolean;
23+
color?: string;
2424
}
2525

2626
/**
@@ -53,6 +53,19 @@ export interface PluginSettings {
5353
gridColor: string;
5454

5555
defaultRenderer: rendererType;
56+
}
5657

57-
telemetry: boolean;
58+
export interface FunctionOptions {
59+
fnType: "linear" | "polar" | "vector" | "points";
60+
fn: string;
61+
vector: [number, number] | null;
62+
r: string;
63+
points: Array<[number, number]>;
64+
color: unknown;
65+
offset: [number, number];
66+
closed: boolean;
67+
graphType: "interval" | "polyline" | "scatter";
68+
range: [number, number];
69+
nSamples: number;
70+
skipTip: false;
5871
}

src/components/Function.svelte

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<script lang="ts">
2+
import type { FunctionOptions } from "../common/types";
3+
4+
export let options: FunctionOptions;
5+
</script>
6+
7+
<div class="functionplot-item-function">
8+
<select bind:value={options.fnType}>
9+
<option value="linear">linear</option>
10+
<option value="polar">polar</option>
11+
<!--<option value="points">points</option>-->
12+
<option value="vector">vector</option>
13+
</select>
14+
{#if options.fnType === "linear"}
15+
<input type="text" placeholder="f(x)=" bind:value={options.fn} />
16+
{/if}
17+
{#if options.fnType === "polar"}
18+
<input type="text" placeholder="θ(r)" bind:value={options.r} />
19+
{/if}
20+
{#if options.fnType === "vector"}
21+
<div class="functionplot-vector-inputs">
22+
<input type="text" placeholder="Δx" bind:value={options.vector[0]} />
23+
<input type="text" placeholder="Δy" bind:value={options.vector[1]} />
24+
</div>
25+
{/if}
26+
27+
</div>
28+
29+
<style lang="scss">
30+
.functionplot-item-function {
31+
display: flex;
32+
flex-direction: row;
33+
align-items: center;
34+
justify-content: space-around;
35+
padding: 0.5em;
36+
input {
37+
width: 30px;
38+
}
39+
}
40+
41+
.functionplot-vector-inputs {
42+
display: flex;
43+
flex-direction: row;
44+
width: min-content;
45+
input {
46+
width: 4em;
47+
}
48+
}
49+
</style>

src/main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
DEFAULT_PLOT_OPTIONS,
88
DEFAULT_PLUGIN_SETTINGS,
99
} from "./common/defaults";
10+
import './styles.scss'
1011

1112
export default class ObsidianFunctionPlot extends Plugin {
1213
settings: PluginSettings;

src/styles.scss

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
1-
.obsfplt-rendertarget {
2-
color: var(--text-normal);
3-
width: 100%;
4-
height: 100%;
5-
border-radius: 0.5em;
1+
.function-plot-numberinput {
2+
width: 4.5em;
63
}
74

8-
.obsfplt-error {
9-
border-radius: 1em;
10-
background: black;
11-
opacity: 0.5;
5+
.function-plot-functions-container {
6+
width: 100%;
7+
height: min-content;
8+
overflow-y: scroll;
9+
overflow-x: hidden;
10+
padding: 0 1em;
11+
display: flex;
12+
flex-direction: column;
13+
align-items: center;
14+
}
1215

13-
p {
14-
opacity: 1;
15-
font-size: 0.7em;
16-
padding: 1em;
17-
}
16+
.function-plot-functions-add {
17+
width: 100%;
18+
display: flex;
19+
flex-direction: row;
20+
justify-content: space-around;
21+
align-items: center;
22+
margin: 1em 0;
1823
}

0 commit comments

Comments
 (0)