Skip to content

Commit 004ab1a

Browse files
committed
scroll working, sliders todo
1 parent 4e355c1 commit 004ab1a

13 files changed

Lines changed: 193 additions & 56 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ jobs:
99
build:
1010
name: Build ⚙️
1111
runs-on: ubuntu-latest
12+
1213
steps:
1314
- uses: actions/checkout@v2
1415

@@ -20,7 +21,7 @@ jobs:
2021
run: yarn install
2122

2223
- name: set development version
23-
run: node .github/version-bump.mjs "dev-$(git rev-parse --short HEAD)"
24+
run: node .github/version-bump.mjs "$(git rev-parse --short HEAD)"
2425

2526
- name: build
2627
run: yarn build

src/app/CreatePlotModal.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default class CreatePlotModal extends Modal {
1818
async onOpen() {
1919
this.titleEl.setText("Create a Plot");
2020
this.modalEl.addClass("fplt-modal");
21+
this.contentEl.addClass("fplt-modal-content")
2122
// attach svelte PlotModal component
2223
new PlotModal({
2324
target: this.contentEl,

src/app/SettingsTab.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
Setting,
66
ValueComponent,
77
} from "obsidian";
8-
import type ObsidianFunctionPlot from "../main.js";
8+
import type ObsidianFunctionPlot from "../main";
99
import { DEFAULT_PLUGIN_SETTINGS, rendererOptions } from "../common/defaults";
1010
import type { PluginSettings, rendererType } from "../common/types";
1111

src/common/defaults.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,19 @@ export const FALLBACK_FUNCTION_INPUTS: Partial<FunctionInputs> = {
6565
},
6666
};
6767

68+
export const DEFAULT_CONSTANT_INPUTS = {
69+
min: -10,
70+
max: 10,
71+
step: 1,
72+
value: 1,
73+
}
74+
6875
/**
6976
* The default options for a plot.
7077
*/
7178
export const DEFAULT_PLOT_INPUTS: PlotInputs = {
72-
target: null, // set by rendering function
7379
renderer: null, // has initial state controlled by plugin.settings.defaultRenderer
80+
constants: {},
7481
title: null,
7582
xAxis: {
7683
label: null,

src/common/types.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import type { Chart } from "function-plot";
22
import type { EventEmitter } from "events";
3-
import type {
4-
FunctionPlotDatum,
5-
FunctionPlotOptions,
6-
} from "function-plot/dist/types";
3+
import type { FunctionPlotDatum } from "function-plot/dist/types";
74

85
export type rendererType = "interactive" | "image";
96

@@ -35,13 +32,19 @@ export interface FunctionInputs {
3532
closed?: boolean;
3633
skipTip?: boolean;
3734
}
35+
export interface ConstantInputs {
36+
min: number;
37+
max: number;
38+
step: number;
39+
value: number;
40+
}
3841
/**
3942
* An interface specifying the options for a plot.
4043
*/
4144
export interface PlotInputs {
4245
data: FunctionInputs[];
4346
renderer: rendererType;
44-
target: FunctionPlotOptions["target"];
47+
constants: { [_: string]: ConstantInputs };
4548
xAxis?: {
4649
label?: string;
4750
domain?: {

src/common/utils.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ import type {
1515
FunctionPlotOptions,
1616
} from "function-plot/dist/types";
1717

18+
// TODO make change to returned object reflect in input
1819
export function toFunctionPlotOptions(
19-
options: PlotInputs
20+
options: PlotInputs,
21+
target: HTMLElement
2022
): FunctionPlotOptions {
2123
function functionInputsToFunctionPlotDatum(
2224
inputs: FunctionInputs
@@ -34,8 +36,7 @@ export function toFunctionPlotOptions(
3436
: undefined,
3537
offset:
3638
inputs.fnType === "vector" &&
37-
(inputs.offset?.x !== undefined ||
38-
inputs.offset?.y !== undefined) //TODO work here offset is [undef, undef]
39+
(inputs.offset?.x !== undefined || inputs.offset?.y !== undefined) //TODO work here offset is [undef, undef]
3940
? [inputs.offset.x ?? 0, inputs.offset.y ?? 0]
4041
: undefined,
4142
r: inputs.fnType === "polar" ? inputs.r : undefined,
@@ -47,7 +48,7 @@ export function toFunctionPlotOptions(
4748
inputs.range.max ?? FALLBACK_FUNCTION_INPUTS.range.max,
4849
]
4950
: undefined,
50-
nSamples: inputs.nSamples,
51+
nSamples: Math.min(inputs.nSamples, 999),
5152
closed: inputs.closed,
5253
skipTip: inputs.skipTip,
5354
};
@@ -68,7 +69,8 @@ export function toFunctionPlotOptions(
6869
}
6970

7071
const output: FunctionPlotOptions = {
71-
target: options.target,
72+
//id: options.id, //used by funcitonplot to identify the plot for updating
73+
target: target,
7274
data: options.data
7375
.filter(hasFunction)
7476
.map(functionInputsToFunctionPlotDatum),
@@ -137,14 +139,16 @@ export function insertParagraphAtCursor(
137139
* @param plugin A reference to the plugin (accessed for settings)
138140
* @returns The chart object of the created plot
139141
*/
140-
export function renderPlot(options: PlotInputs, plugin: ObsidianFunctionPlot) {
141-
if (options.target === null) return;
142+
export function renderPlot(
143+
options: PlotInputs,
144+
target: HTMLElement,
145+
plugin: ObsidianFunctionPlot
146+
) {
147+
if (target === null) return;
142148
const stylingPlugin = createStylingPlugin(plugin);
143-
console.log("reloading plot");
144-
console.log(toFunctionPlotOptions(options));
145149
try {
146150
functionPlot(
147-
Object.assign({}, toFunctionPlotOptions(options), {
151+
Object.assign({}, toFunctionPlotOptions(options, target), {
148152
plugins: [stylingPlugin],
149153
})
150154
);
@@ -182,7 +186,7 @@ export async function insertPlotAsImage(
182186
options: PlotInputs
183187
) {
184188
const target = document.createElement("div");
185-
renderPlot(Object.assign(options, { target }), plugin);
189+
renderPlot(options, target, plugin);
186190
const dataURL = await toPng(target);
187191
if (dataURL === "data:,") {
188192
new Error("Data URL is empty");
@@ -226,8 +230,8 @@ export function parseYAMLCodeBlock(content: string): PlotInputs {
226230
.filter((line) => line.length > 0);
227231

228232
return {
229-
target: null,
230233
renderer: null,
234+
constants: {},
231235
title: header.title ?? DEFAULT_PLOT_INPUTS.title,
232236
xAxis: {
233237
label: header.xLabel ?? DEFAULT_PLOT_INPUTS.xAxis.label,

src/components/Plot/Plot.svelte

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script lang="ts">
2+
import { onDestroy } from "svelte";
3+
import type { Writable } from "svelte/store";
4+
import type { PlotInputs } from "../../common/types";
5+
import { renderPlot } from "../../common/utils";
6+
import type ObsidianFunctionPlot from "../../main";
7+
import SettingItem from "../Primitives/SettingItem.svelte";
8+
import Slider from "../Primitives/Slider.svelte";
9+
10+
export let optionsStore: Writable<PlotInputs>, plugin: ObsidianFunctionPlot;
11+
12+
let target: HTMLElement;
13+
14+
const unsubscribe = optionsStore.subscribe((options) => {
15+
renderPlot(options, target, plugin);
16+
});
17+
18+
onDestroy(() => {
19+
unsubscribe();
20+
});
21+
</script>
22+
23+
<div>
24+
<div class="fplot-plot" bind:this={target} />
25+
<div class="fplt-constants">
26+
{#each Object.entries($optionsStore.constants) as [key, constant]}
27+
<SettingItem name={key}>
28+
<Slider
29+
bind:value={constant.value}
30+
min={constant.min}
31+
max={constant.max}
32+
step={constant.step}
33+
/>
34+
</SettingItem>
35+
{/each}
36+
</div>
37+
</div>

src/components/PlotModal/Function.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
{/if}
3030

3131
{#if datum.fnType === "polar"}
32-
<TextInput placeholder="θ(r)=" bind:value={datum.r} />
32+
<TextInput placeholder="r(theta)=" bind:value={datum.r} />
3333
{/if}
3434

3535
{#if datum.fnType === "vector"}

0 commit comments

Comments
 (0)