Skip to content

Commit 3d30151

Browse files
committed
adjusted styling, incorporated pr
1 parent e385ae5 commit 3d30151

17 files changed

+147
-139
lines changed

.github/changelog.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const { readFileSync, writeFileSync, existsSync } = require("fs");
2+
3+
const [name, body] = process.argv.slice(2);
4+
5+
let changelog = "";
6+
7+
if (existsSync("./CHANGELOG.md")) {
8+
changelog = readFileSync("./CHANGELOG.md", "utf8");
9+
}
10+
11+
changelog = `## ${name}\n\n${body}\n\n${changelog}`;
12+
13+
writeFileSync("./CHANGELOG.md", changelog);

.github/release-notes.js

-13
This file was deleted.

.github/workflows/release.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ jobs:
3737
- name: Run version-bump
3838
run: node .github/version-bump.js ${{ github.event.release.tag_name }}
3939

40-
# build release notes
41-
- name: Update release notes
42-
run: node .github/release-notes.js ${{ github.event.release.tag_name }} ${{ github.event.release.body }}
40+
# build changelog
41+
- name: Update changelog
42+
run: node .github/changelog.js ${{ github.event.release.tag_name }} ${{ github.event.release.body }}
4343

4444
# build now, so that no side-effects when build fails and release get deleted
4545
- name: Build

CHANGELOG.md

Whitespace-only changes.

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ TL;DR:
1010

1111
Because obsidian keeps an index of versions of the plugin and their respective minimum version requirements for obsidian itself, the `minAppVersion` field in `manifest.json` and the version of the dependency `obsidian` in `package.json` should be kept equal. The version should also reflect the lowest version of api under which the plugin will work. The dependency version in `package.json` is pinned to a single version.
1212

13-
Oh, and also: This project uses yarn, although it doesn't matter if you use another package manager so long as you don't commit the log and lock files to VCS. Just be sure to let us know of your choice of package manager if you encounter a problem.
13+
This project recently switched to using pnpm as a package manager, although it doesn't matter if you use another package manager so long as you don't commit the log and lock files to VCS. Just be sure to let us know of your choice of package manager if you encounter a problem.

src/common/types.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { Chart } from "function-plot";
22
import type { EventEmitter } from "events";
33
export type rendererType = "interactive" | "image";
4+
import type { Selection as d3Selection } from "d3";
45

56
/**
67
* Input types: values that should be set to a default by the plugin are required, values that should be set to a default by functionplot are marked optional. Values that are not set by either are marked optional but default values Omit<> them.
@@ -9,7 +10,10 @@ export type rendererType = "interactive" | "image";
910
/**
1011
* A sum-type of Chart and EventEmitter because TypeScript can't figure this out on it's own.
1112
*/
12-
export type chartType = Chart & EventEmitter;
13+
export type chartType = {
14+
root: d3Selection<SVGElement, unknown, HTMLElement, unknown>;
15+
} & Omit<Chart, "root"> &
16+
EventEmitter;
1317

1418
//Custom utility type:
1519
export type DeepNonNullable<T> = {

src/common/utils.ts

+1-20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Editor, parseYaml } from "obsidian";
22
import type ObsidianFunctionPlot from "../main";
3-
import type { Selection } from "d3";
43
import type {
54
FunctionInputs,
65
PlotInputs,
@@ -19,7 +18,6 @@ import type {
1918
FunctionPlotOptions,
2019
} from "function-plot/dist/types";
2120
import { FunctionPlot } from "../fnplot";
22-
import type { Chart } from "function-plot";
2321

2422
export function gcd(a: number, b: number): number {
2523
return !b ? a : gcd(b, a % b);
@@ -86,7 +84,7 @@ export function toFunctionPlotOptions(
8684
}
8785

8886
const output: FunctionPlotOptions = {
89-
//id: options.id, //used by funcitonplot to identify the plot for updating
87+
//id: options.id, //used by functionplot to identify the plot for updating
9088
target: target,
9189
data: options.data
9290
.filter(hasFunction)
@@ -106,23 +104,6 @@ export function toFunctionPlotOptions(
106104
options.yAxis.domain.max ?? FALLBACK_PLOT_INPUTS.yAxis.domain.max,
107105
],
108106
},
109-
plugins: [(chart: Chart) => {
110-
if(!options.legends) return;
111-
chart.root.append("text").attr("class", "top-left-legend");
112-
let text_color = "#00ff00";
113-
let legends: {name: string, color: string}[] = [];
114-
chart.options.data?.forEach((datum, index, arr) => {
115-
legends.push({name: (options.data[index].name) || "", color: datum.color || ""});
116-
})
117-
const tll: any = chart.root.select(".top-left-legend");
118-
console.log(legends);
119-
tll.selectAll("tspan").remove();
120-
legends.forEach((legend, index, arr) => {
121-
tll.attr("y", (chart.meta.margin?.top || 20) / 2)
122-
.attr("x", chart.meta.margin?.left || 10)
123-
tll.append("tspan").attr('fill', legend.color).text("█ " + legend.name + "\n");;
124-
})
125-
}],
126107
grid: options.grid ?? undefined,
127108
disableZoom: options.disableZoom ?? undefined,
128109
};

src/components/Plot/Constant.svelte

+6-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
if (!target) return;
2626
const rect = target.getBoundingClientRect();
2727
mousePos = { x: rect.right, y: rect.bottom };
28+
console.log(mousePos);
2829
}
2930
</script>
3031

@@ -65,10 +66,14 @@
6566
div {
6667
background: var(--color-base-30);
6768
border-radius: 0.5em;
68-
padding: 0 0.5rem;
69+
padding: 0.5rem;
6970
display: flex;
7071
flex-direction: row;
7172
gap: 0.5rem;
7273
align-items: center;
74+
p {
75+
margin: 0;
76+
}
77+
// flex: 1;
7378
}
7479
</style>

src/components/PlotModal/Function.svelte

+19-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import MenuDown from "svelte-material-icons/MenuDown.svelte";
1212
import Delete from "svelte-material-icons/Delete.svelte";
1313
14-
export let datum: FunctionInputs, unmount: () => void;
14+
export let datum: FunctionInputs, unmount: () => void, legends: boolean;
1515
1616
let showFloater = false;
1717
let mousePos = { x: 0, y: 0 };
@@ -33,14 +33,16 @@
3333
<option value="vector">vector</option>
3434
</Dropdown>
3535

36-
<TextInput placeholder="Name" width="10ch" bind:value={datum.name} />
36+
{#if legends}
37+
<TextInput placeholder="Name" bind:value={datum.name} />
38+
{/if}
3739

3840
{#if datum.fnType === "linear"}
39-
<TextInput placeholder="f(x)=" width="20ch" bind:value={datum.fn} />
41+
<TextInput placeholder="f(x)=" bind:value={datum.fn} />
4042
{/if}
4143

4244
{#if datum.fnType === "polar"}
43-
<TextInput placeholder="r(theta)=" width="20ch" bind:value={datum.r} />
45+
<TextInput placeholder="r(theta)=" bind:value={datum.r} />
4446
{/if}
4547

4648
{#if datum.fnType === "vector"}
@@ -114,7 +116,7 @@
114116
<style lang="scss">
115117
.functionplot-item-data {
116118
display: inline-grid;
117-
grid-template-columns: repeat(6, min-content);
119+
grid-template-columns: min-content 1fr repeat(3, min-content);
118120
column-gap: 0.5em;
119121
place-items: center start;
120122
width: 100%;
@@ -124,6 +126,18 @@
124126
}
125127
}
126128
129+
.functionplot-item-data:has(input[placeholder="Name"]) {
130+
grid-template-columns: min-content 1fr 2fr repeat(4, min-content);
131+
}
132+
133+
.functionplot-item-data:has(input[placeholder="Δx"]) {
134+
grid-template-columns: min-content auto repeat(3, min-content);
135+
}
136+
137+
.functionplot-item-data:has(input[placeholder="Name"]):has(input[placeholder="Δx"]) {
138+
grid-template-columns: min-content max-content auto repeat(4, min-content);
139+
}
140+
127141
.functionplot-nums-inputs {
128142
display: flex;
129143
flex-direction: row;

src/components/PlotModal/PlotModal.svelte

+2-1
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@
159159
<div class="fplt-list">
160160
{#each options.data as datum}
161161
<Function
162+
legends={options.legends}
162163
bind:datum
163164
unmount={() => {
164165
options.data = options.data.filter(
@@ -213,7 +214,7 @@
213214
}
214215
215216
.fplt-options-wrapper {
216-
max-width: 25em;
217+
max-width: 30em;
217218
min-width: 25em;
218219
padding: 3px;
219220
}

src/components/Primitives/OptionsFloater.svelte

+4-29
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
<script lang="ts">
2-
import { onMount } from "svelte";
3-
42
export let show = false,
53
mousePos: { x: number; y: number },
6-
color: string | undefined;
7-
8-
let abs: { x: number; y: number } = { x: 0, y: 0 };
4+
color: string | undefined = undefined;
95
106
function clickOutside(node: Node) {
117
function handleClick(event: MouseEvent) {
@@ -24,32 +20,10 @@
2420
},
2521
};
2622
}
27-
28-
onMount(() => {
29-
const floater = document.querySelector(
30-
"#fplt-floater-modal"
31-
) as HTMLElement;
32-
const boundingRect = document
33-
.querySelector(".fplt-container")
34-
?.getBoundingClientRect();
35-
const floaterRect = floater?.getBoundingClientRect();
36-
37-
if (!floater || !floaterRect || !boundingRect) {
38-
show = false;
39-
return;
40-
}
41-
42-
const x = Math.min(mousePos.x, boundingRect.right - floaterRect.width);
43-
const y = Math.min(mousePos.y, boundingRect.bottom - floaterRect.height);
44-
45-
abs = { x: x - boundingRect.left, y: y - boundingRect.top };
46-
});
47-
48-
$: abs = abs;
4923
</script>
5024

5125
<div
52-
style="transform: translateX({abs.x}px) translateY({abs.y}px)"
26+
style="transform: translateX({mousePos.x}px) translateY({mousePos.y}px)"
5327
id="fplt-floater-modal"
5428
class="modal"
5529
use:clickOutside
@@ -78,10 +52,11 @@
7852
overflow-y: auto;
7953
overflow-x: hidden;
8054
81-
position: absolute;
55+
position: fixed;
8256
margin: 0;
8357
left: 0;
8458
top: 0;
59+
z-index: 9999;
8560
}
8661
8762
.fplt-fn-indicator {
+9-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
<script lang="ts">
22
export let value: string | undefined,
33
placeholder = "",
4-
id = "",
5-
width = "initial";
4+
id = "";
65
</script>
76

8-
<input
9-
type="text"
10-
{id}
11-
style="width: {width} "
12-
spellcheck="false"
13-
{placeholder}
14-
bind:value
15-
/>
7+
<input type="text" {id} spellcheck="false" {placeholder} bind:value />
8+
9+
<style>
10+
input {
11+
width: inherit;
12+
max-width: 40ch;
13+
}
14+
</style>

src/fnplot.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { FunctionPlotOptions } from "function-plot/dist/types";
22
import type { PlotInputs } from "./common/types";
33
import createStylingPlugin from "./plugins/styling";
4+
import createLegendsPlugin from "./plugins/legends";
45
import { toFunctionPlotOptions } from "./common/utils";
56
import type ObsidianFunctionPlot from "./main";
67
import functionPlot, { Chart } from "function-plot";
@@ -46,7 +47,10 @@ export class FunctionPlot {
4647
{},
4748
toFunctionPlotOptions(this.options_, this.target_),
4849
{
49-
plugins: [createStylingPlugin(this.plugin)],
50+
plugins: [
51+
createStylingPlugin(this.plugin),
52+
createLegendsPlugin(this.options_),
53+
],
5054
width: 550,
5155
height: 350,
5256
}
@@ -57,6 +61,7 @@ export class FunctionPlot {
5761
);
5862
}
5963
if (this.chart !== undefined) {
64+
this.chart.removeAllListeners("after:draw");
6065
this.chart.build();
6166
console.log("redrew chart");
6267
} else {

src/main.ts

-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ export default class ObsidianFunctionPlot extends Plugin {
5656
_ctx: MarkdownPostProcessorContext /* eslint-disable-line no-unused-vars, @typescript-eslint/no-unused-vars */
5757
) => {
5858
const options = parseCodeBlock(source);
59-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
6059
new Plot({
6160
target: el,
6261
props: {

src/plugins/legends.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* eslint-disable @typescript-eslint/no-unsafe-call */
2+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
3+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
4+
import type { PlotInputs, chartType } from "../common/types";
5+
6+
// TODO dont show legends for functions with empty name
7+
export default function createLegendsPlugin(options: PlotInputs) {
8+
return function legendsPlugin(instance: chartType) {
9+
console.log("applying legends plugin");
10+
if (!options.legends) return;
11+
instance.root.append("text").attr("class", "top-left-legend");
12+
const legends: { name: string; color: string }[] = [];
13+
instance.options.data?.forEach((datum, index) => {
14+
legends.push({
15+
name: options.data[index].name ?? "",
16+
color: datum.color ?? "",
17+
});
18+
});
19+
const tll = instance.root.select(".top-left-legend");
20+
console.log(legends);
21+
tll.selectAll("tspan").remove();
22+
legends.forEach((legend) => {
23+
tll
24+
.attr("y", (instance.meta.margin?.top ?? 20) / 2)
25+
.attr("x", instance.meta.margin?.left ?? 10);
26+
tll
27+
.append("tspan")
28+
.attr("fill", legend.color)
29+
.text("█ " + legend.name + "\n");
30+
});
31+
};
32+
}

0 commit comments

Comments
 (0)