Compare commits

...

8 commits

Author SHA1 Message Date
Kritagya Bhattarai
4d5d1538c9
Merge pull request #8 from CalfMoon/dependabot/npm_and_yarn/esbuild-0.28.1
chore(deps-dev): bump esbuild from 0.25.5 to 0.28.1
2026-06-16 17:17:39 +05:45
dependabot[bot]
b3dfbb089b
chore(deps-dev): bump esbuild from 0.25.5 to 0.28.1
Bumps [esbuild](https://github.com/evanw/esbuild) from 0.25.5 to 0.28.1.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG-2025.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.25.5...v0.28.1)

---
updated-dependencies:
- dependency-name: esbuild
  dependency-version: 0.28.1
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-16 11:29:59 +00:00
Kritagya Bhattarai (CalfMoon)
99cb882ff3 Merge branch 'modularize' 2026-03-31 11:47:39 +05:45
Kritagya Bhattarai (CalfMoon)
aa5f5cb5e5 fix: recalculate size when manual size is deleted 2026-03-31 11:26:08 +05:45
Kritagya Bhattarai (CalfMoon)
dbdf7d2a90 fix(calc): add assignment of value after calculations 2026-03-31 11:22:04 +05:45
Kritagya Bhattarai (CalfMoon)
8ba7f85b55 update README 2026-03-31 01:10:39 +05:45
Kritagya Bhattarai (CalfMoon)
a36f1c9ed0 refactor: move calculation functions to new class 2026-03-31 00:42:56 +05:45
Kritagya Bhattarai (CalfMoon)
cd5f4c97c9 refactor: modularize settings file 2026-03-31 00:38:57 +05:45
10 changed files with 436 additions and 333 deletions

View file

@ -1,8 +1,15 @@
# Node Factor # Node Factor
This plugin helps you customize the factors that effect node size in obsidian graph view. This plugin helps you customize the factors that effect node size in obsidian graph view.
The factors include, letter count, forward & backward weight, and forward tree weight. The factors include:
- Letter count in a file.
- Weight of links coming forward and/or backward out of a file.
- Whether we should count every descendant coming forward out of a file or just the children.
- You can manually add size for certain files too.
## Demo
<img src="./screenshots/1.jpeg"> <img src="./screenshots/1.jpeg">
<img src="./screenshots/2.jpeg"> <img src="./screenshots/2.jpeg">
## Installation ## Installation
1. Search for "Node Factor" in Obsidian's community plugin browser. 1. Search for "Node Factor" in Obsidian's community plugin browser.
2. Install it. 2. Install it.
@ -15,9 +22,12 @@ The factors include, letter count, forward & backward weight, and forward tree w
| Backward link weight multiplier | Weight of single link coming backward out of a node | 1 | | Backward link weight multiplier | Weight of single link coming backward out of a node | 1 |
| Character per weight | Given number of letters give 1 weight | 0 | | Character per weight | Given number of letters give 1 weight | 0 |
| Manually Set Weight | Manually set weight of any file, weight set here overrides everything else | empty set | | Manually Set Weight | Manually set weight of any file, weight set here overrides everything else | empty set |
## Author ## Author
CalfMoon: [Email](kritagyabhattarai@proton.me), [Github](https://github.com/CalfMoon) CalfMoon: [Email](kritagyabhattarai@proton.me), [Github](https://github.com/CalfMoon)
## Bug Reports ## Bug Reports
This project is still new and might have a few bugs. For bug reports use this repo's Issues section. This project is still new and might have a few bugs. For bug reports use this repo's Issues section.
## License ## License
MIT, see [LICENSE](LICENSE). MIT, see [LICENSE](LICENSE).

232
package-lock.json generated
View file

@ -1,20 +1,20 @@
{ {
"name": "node-factor", "name": "node-factor",
"version": "2.1.0", "version": "3.0.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "node-factor", "name": "node-factor",
"version": "2.1.0", "version": "3.0.0",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"obsidian": "latest" "obsidian": "*"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "9.30.1", "@eslint/js": "9.30.1",
"@types/node": "^16.11.6", "@types/node": "^16.11.6",
"esbuild": "0.25.5", "esbuild": "0.28.1",
"eslint": "^9.39.4", "eslint": "^9.39.4",
"eslint-plugin-obsidianmd": "0.1.9", "eslint-plugin-obsidianmd": "0.1.9",
"globals": "^14.0.0", "globals": "^14.0.0",
@ -48,9 +48,9 @@
} }
}, },
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
"integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@ -65,9 +65,9 @@
} }
}, },
"node_modules/@esbuild/android-arm": { "node_modules/@esbuild/android-arm": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
"integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -82,9 +82,9 @@
} }
}, },
"node_modules/@esbuild/android-arm64": { "node_modules/@esbuild/android-arm64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
"integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -99,9 +99,9 @@
} }
}, },
"node_modules/@esbuild/android-x64": { "node_modules/@esbuild/android-x64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
"integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -116,9 +116,9 @@
} }
}, },
"node_modules/@esbuild/darwin-arm64": { "node_modules/@esbuild/darwin-arm64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
"integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -133,9 +133,9 @@
} }
}, },
"node_modules/@esbuild/darwin-x64": { "node_modules/@esbuild/darwin-x64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
"integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -150,9 +150,9 @@
} }
}, },
"node_modules/@esbuild/freebsd-arm64": { "node_modules/@esbuild/freebsd-arm64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
"integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -167,9 +167,9 @@
} }
}, },
"node_modules/@esbuild/freebsd-x64": { "node_modules/@esbuild/freebsd-x64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
"integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -184,9 +184,9 @@
} }
}, },
"node_modules/@esbuild/linux-arm": { "node_modules/@esbuild/linux-arm": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
"integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -201,9 +201,9 @@
} }
}, },
"node_modules/@esbuild/linux-arm64": { "node_modules/@esbuild/linux-arm64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
"integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -218,9 +218,9 @@
} }
}, },
"node_modules/@esbuild/linux-ia32": { "node_modules/@esbuild/linux-ia32": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
"integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -235,9 +235,9 @@
} }
}, },
"node_modules/@esbuild/linux-loong64": { "node_modules/@esbuild/linux-loong64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
"integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@ -252,9 +252,9 @@
} }
}, },
"node_modules/@esbuild/linux-mips64el": { "node_modules/@esbuild/linux-mips64el": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
"integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
"cpu": [ "cpu": [
"mips64el" "mips64el"
], ],
@ -269,9 +269,9 @@
} }
}, },
"node_modules/@esbuild/linux-ppc64": { "node_modules/@esbuild/linux-ppc64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
"integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@ -286,9 +286,9 @@
} }
}, },
"node_modules/@esbuild/linux-riscv64": { "node_modules/@esbuild/linux-riscv64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
"integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@ -303,9 +303,9 @@
} }
}, },
"node_modules/@esbuild/linux-s390x": { "node_modules/@esbuild/linux-s390x": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
"integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@ -320,9 +320,9 @@
} }
}, },
"node_modules/@esbuild/linux-x64": { "node_modules/@esbuild/linux-x64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
"integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -337,9 +337,9 @@
} }
}, },
"node_modules/@esbuild/netbsd-arm64": { "node_modules/@esbuild/netbsd-arm64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
"integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -354,9 +354,9 @@
} }
}, },
"node_modules/@esbuild/netbsd-x64": { "node_modules/@esbuild/netbsd-x64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
"integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -371,9 +371,9 @@
} }
}, },
"node_modules/@esbuild/openbsd-arm64": { "node_modules/@esbuild/openbsd-arm64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
"integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -388,9 +388,9 @@
} }
}, },
"node_modules/@esbuild/openbsd-x64": { "node_modules/@esbuild/openbsd-x64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
"integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -404,10 +404,27 @@
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/@esbuild/openharmony-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
"integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": { "node_modules/@esbuild/sunos-x64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
"integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -422,9 +439,9 @@
} }
}, },
"node_modules/@esbuild/win32-arm64": { "node_modules/@esbuild/win32-arm64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
"integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -439,9 +456,9 @@
} }
}, },
"node_modules/@esbuild/win32-ia32": { "node_modules/@esbuild/win32-ia32": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
"integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -456,9 +473,9 @@
} }
}, },
"node_modules/@esbuild/win32-x64": { "node_modules/@esbuild/win32-x64": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
"integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -1876,9 +1893,9 @@
} }
}, },
"node_modules/esbuild": { "node_modules/esbuild": {
"version": "0.25.5", "version": "0.28.1",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
"integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"license": "MIT", "license": "MIT",
@ -1889,31 +1906,32 @@
"node": ">=18" "node": ">=18"
}, },
"optionalDependencies": { "optionalDependencies": {
"@esbuild/aix-ppc64": "0.25.5", "@esbuild/aix-ppc64": "0.28.1",
"@esbuild/android-arm": "0.25.5", "@esbuild/android-arm": "0.28.1",
"@esbuild/android-arm64": "0.25.5", "@esbuild/android-arm64": "0.28.1",
"@esbuild/android-x64": "0.25.5", "@esbuild/android-x64": "0.28.1",
"@esbuild/darwin-arm64": "0.25.5", "@esbuild/darwin-arm64": "0.28.1",
"@esbuild/darwin-x64": "0.25.5", "@esbuild/darwin-x64": "0.28.1",
"@esbuild/freebsd-arm64": "0.25.5", "@esbuild/freebsd-arm64": "0.28.1",
"@esbuild/freebsd-x64": "0.25.5", "@esbuild/freebsd-x64": "0.28.1",
"@esbuild/linux-arm": "0.25.5", "@esbuild/linux-arm": "0.28.1",
"@esbuild/linux-arm64": "0.25.5", "@esbuild/linux-arm64": "0.28.1",
"@esbuild/linux-ia32": "0.25.5", "@esbuild/linux-ia32": "0.28.1",
"@esbuild/linux-loong64": "0.25.5", "@esbuild/linux-loong64": "0.28.1",
"@esbuild/linux-mips64el": "0.25.5", "@esbuild/linux-mips64el": "0.28.1",
"@esbuild/linux-ppc64": "0.25.5", "@esbuild/linux-ppc64": "0.28.1",
"@esbuild/linux-riscv64": "0.25.5", "@esbuild/linux-riscv64": "0.28.1",
"@esbuild/linux-s390x": "0.25.5", "@esbuild/linux-s390x": "0.28.1",
"@esbuild/linux-x64": "0.25.5", "@esbuild/linux-x64": "0.28.1",
"@esbuild/netbsd-arm64": "0.25.5", "@esbuild/netbsd-arm64": "0.28.1",
"@esbuild/netbsd-x64": "0.25.5", "@esbuild/netbsd-x64": "0.28.1",
"@esbuild/openbsd-arm64": "0.25.5", "@esbuild/openbsd-arm64": "0.28.1",
"@esbuild/openbsd-x64": "0.25.5", "@esbuild/openbsd-x64": "0.28.1",
"@esbuild/sunos-x64": "0.25.5", "@esbuild/openharmony-arm64": "0.28.1",
"@esbuild/win32-arm64": "0.25.5", "@esbuild/sunos-x64": "0.28.1",
"@esbuild/win32-ia32": "0.25.5", "@esbuild/win32-arm64": "0.28.1",
"@esbuild/win32-x64": "0.25.5" "@esbuild/win32-ia32": "0.28.1",
"@esbuild/win32-x64": "0.28.1"
} }
}, },
"node_modules/escape-string-regexp": { "node_modules/escape-string-regexp": {

View file

@ -15,7 +15,7 @@
"devDependencies": { "devDependencies": {
"@eslint/js": "9.30.1", "@eslint/js": "9.30.1",
"@types/node": "^16.11.6", "@types/node": "^16.11.6",
"esbuild": "0.25.5", "esbuild": "0.28.1",
"eslint": "^9.39.4", "eslint": "^9.39.4",
"eslint-plugin-obsidianmd": "0.1.9", "eslint-plugin-obsidianmd": "0.1.9",
"globals": "^14.0.0", "globals": "^14.0.0",

67
src/calculator.ts Normal file
View file

@ -0,0 +1,67 @@
import { App } from "obsidian";
import { NodeFactorSettings, ObsidianNode } from "types";
export default class Calculations {
private app: App;
private settings: NodeFactorSettings;
constructor(app: App, settings: NodeFactorSettings) {
this.app = app;
this.settings = settings;
}
calcNodeWeight(node: ObsidianNode): number {
const settings = this.settings;
let weight = 0;
const manualFileData = settings.manual.find(
(manualFileData) => manualFileData.id == node.id,
);
if (manualFileData != null) {
return manualFileData.weight;
}
weight += Object.keys(node.reverse).length * settings.bwdMultiplier;
if (settings.fwdTree) {
weight +=
this.fwdNodeTreeSize(node, new Set()) * settings.fwdMultiplier;
} else {
weight += Object.keys(node.forward).length * settings.fwdMultiplier;
}
if (settings.lettersPerWt != 0) {
weight += this.letterCount(node) / settings.lettersPerWt;
}
return Math.round(weight);
}
private letterCount(node: ObsidianNode): number {
const file = this.app.vault.getFileByPath(node.id);
if (file == null || file.extension != "md") return 0;
return file.stat.size;
}
private fwdNodeTreeSize(
node: ObsidianNode,
antiLoopSet: Set<string>,
): number {
let size = 0;
antiLoopSet.add(node.id);
Object.entries(node.forward).forEach(([key, value]) => {
// @ts-ignore
const childNode: ObsidianNode = value.target;
// Prevents looping if A -> B -> C -> D -> B
if (!antiLoopSet.has(key)) {
size++;
const childSize = this.fwdNodeTreeSize(childNode, antiLoopSet);
size += childSize;
}
});
return size;
}
}

View file

@ -1,7 +1,8 @@
import { Plugin } from "obsidian"; import { Plugin } from "obsidian";
import { ObsidianNode, NodeFactorSettings, DEFAULT_SETTINGS } from "./types"; import { ObsidianNode, NodeFactorSettings, DEFAULT_SETTINGS } from "types";
import NodeFactorSettingTab from "./settings"; import NodeFactorSettingTab from "settings";
import Calculator from "calculator";
export default class NodeFactor extends Plugin { export default class NodeFactor extends Plugin {
settings: NodeFactorSettings; settings: NodeFactorSettings;
@ -56,12 +57,14 @@ export default class NodeFactor extends Plugin {
// if graph view is initially opened when opening obsidian // if graph view is initially opened when opening obsidian
clearTimeout(this.timeoutId); clearTimeout(this.timeoutId);
this.timeoutId = setTimeout(() => { this.timeoutId = setTimeout(() => {
const calculator = new Calculator(this.app, this.settings);
nodes.forEach((node, _i) => { nodes.forEach((node, _i) => {
let weight = 0; let weight = 0;
if (this.sizeCache.get(node.id) != undefined) { if (this.sizeCache.get(node.id) != undefined) {
weight = this.sizeCache.get(node.id) as number; weight = this.sizeCache.get(node.id) as number;
} else { } else {
weight = this.calcNodeWeight(node); weight = calculator.calcNodeWeight(node);
this.sizeCache.set(node.id, weight); this.sizeCache.set(node.id, weight);
} }
node.weight = weight; node.weight = weight;
@ -69,60 +72,6 @@ export default class NodeFactor extends Plugin {
}, 500); }, 500);
} }
private calcNodeWeight(node: ObsidianNode): number {
const settings = this.settings;
let weight = 0;
const manualFileData = settings.manual.find(
(manualFileData) => manualFileData.id == node.id,
);
if (manualFileData != null) {
return manualFileData.weight;
}
weight += Object.keys(node.reverse).length * settings.bwdMultiplier;
if (settings.fwdTree) {
weight +=
this.fwdNodeTreeSize(node, new Set()) * settings.fwdMultiplier;
} else {
weight += Object.keys(node.forward).length * settings.fwdMultiplier;
}
if (settings.lettersPerWt != 0) {
weight += this.letterCount(node) / settings.lettersPerWt;
}
return Math.round(weight);
}
private letterCount(node: ObsidianNode): number {
const file = this.app.vault.getFileByPath(node.id);
if (file == null || file.extension != "md") return 0;
return file.stat.size;
}
private fwdNodeTreeSize(
node: ObsidianNode,
antiLoopSet: Set<string>,
): number {
let size = 0;
antiLoopSet.add(node.id);
Object.entries(node.forward).forEach(([key, value]) => {
// @ts-ignore
const childNode: ObsidianNode = value.target;
// Prevents looping if A -> B -> C -> D -> B
if (!antiLoopSet.has(key)) {
size++;
const childSize = this.fwdNodeTreeSize(childNode, antiLoopSet);
size += childSize;
}
});
return size;
}
recalculateSize() { recalculateSize() {
this.sizeCache.clear(); this.sizeCache.clear();
this.updateGraph(); this.updateGraph();

View file

@ -1,167 +0,0 @@
import {
App,
ButtonComponent,
Notice,
PluginSettingTab,
SearchComponent,
Setting,
SliderComponent,
} from "obsidian";
import NodeFactor from "./main";
import FileSuggest from "./file-suggest";
import { FileData } from "./types";
export default class NodeFactorSettingTab extends PluginSettingTab {
plugin: NodeFactor;
constructor(app: App, plugin: NodeFactor) {
super(app, plugin);
this.plugin = plugin;
}
display(): void {
const { containerEl } = this;
containerEl.empty();
new Setting(containerEl)
.setName("Programatically set size")
.setHeading();
new Setting(containerEl)
.setName("Forward link weight multiplier")
.setDesc("Multiplier for forward links weight (0 to disable).")
.addSlider((slider) => {
slider
.setLimits(0, 20, 1)
.setDynamicTooltip()
.setValue(this.plugin.settings.fwdMultiplier)
.onChange(async (value) => {
this.plugin.settings.fwdMultiplier = value;
await this.plugin.saveSettings();
this.plugin.recalculateSize();
});
});
new Setting(containerEl)
.setName("Travel forward tree")
.setDesc(
"Travel forward and add all other nodes to determine final node size.",
)
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.fwdTree)
.onChange(async (value) => {
this.plugin.settings.fwdTree = value;
await this.plugin.saveSettings();
this.plugin.recalculateSize();
});
});
new Setting(containerEl)
.setName("Backward link weight multiplier")
.setDesc("Multiplier for backward links weight (0 to disable).")
.addSlider((slider) => {
slider
.setLimits(0, 20, 1)
.setDynamicTooltip()
.setValue(this.plugin.settings.bwdMultiplier)
.onChange(async (value) => {
this.plugin.settings.bwdMultiplier = value;
await this.plugin.saveSettings();
this.plugin.recalculateSize();
});
});
new Setting(containerEl)
.setName("Character per weight")
.setDesc(
"Add 1 weight to node size per no of given character (0 to disable).",
)
.addSlider((slider) => {
slider
.setLimits(0, 5000, 100)
.setDynamicTooltip()
.setValue(this.plugin.settings.lettersPerWt)
.onChange(async (value) => {
this.plugin.settings.lettersPerWt = value;
await this.plugin.saveSettings();
this.plugin.recalculateSize();
});
});
new Setting(containerEl).setName("Manually set size").setHeading();
let selectedWeight: SliderComponent;
let selectedFile: SearchComponent;
let submitButton: ButtonComponent;
new Setting(containerEl)
.setName("Add new weight")
.setDesc("Weight added here overrides everything else.")
.addSearch((search) => {
new FileSuggest(this.app, search.inputEl);
selectedFile = search;
search
.setPlaceholder("Enter file name")
.onChange(async (value) => {
submitButton.setDisabled(value.length === 0);
});
})
.addSlider((slider) => {
selectedWeight = slider;
slider.setLimits(0, 100, 5).setDynamicTooltip().setValue(0);
})
.addButton((button) => {
submitButton = button;
button
.setDisabled(true)
.setButtonText("Add")
.setTooltip("Click to add")
.onClick(async () => {
const enteredFileData: FileData = {
id: selectedFile.getValue(),
weight: selectedWeight.getValue(),
};
selectedWeight.setValue(0);
selectedFile.setValue("");
const fileExists = this.plugin.settings.manual.find(
(foundFile) => foundFile.id == enteredFileData.id,
);
if (fileExists) {
new Notice(
"That file's size has already been entered," +
" remove it first to change weight.",
);
return;
}
this.plugin.settings.manual.push(enteredFileData);
await this.plugin.saveSettings();
new Notice("Manual size added");
// Rerender display
this.display();
this.plugin.recalculateSize();
});
});
// Display all manually added weights
this.plugin.settings.manual.forEach((value: FileData) => {
new Setting(containerEl)
.setName(value.id)
.setDesc(`Weight: ${String(value.weight)}`)
.addButton((button) => {
button
.setIcon("trash")
.setTooltip("Remove manually added size")
.onClick(async () => {
this.plugin.settings.manual.remove(value);
await this.plugin.saveSettings();
this.display();
});
});
});
}
}

26
src/settings/index.ts Normal file
View file

@ -0,0 +1,26 @@
import { App, PluginSettingTab } from "obsidian";
import NodeFactor from "main";
import ManualSetting from "./manual";
import ProgrameticalSetting from "./programetical";
export default class NodeFactorSettingTab extends PluginSettingTab {
private plugin: NodeFactor;
constructor(app: App, plugin: NodeFactor) {
super(app, plugin);
this.plugin = plugin;
}
display(): void {
const { plugin, containerEl, app } = this;
containerEl.empty();
new ProgrameticalSetting(plugin, containerEl).display();
new ManualSetting(app, plugin, containerEl, () =>
this.display(),
).display();
}
}

115
src/settings/manual.ts Normal file
View file

@ -0,0 +1,115 @@
import {
App,
ButtonComponent,
Notice,
SearchComponent,
Setting,
SliderComponent,
} from "obsidian";
import NodeFactor from "main";
import { FileData } from "types";
import FileSuggest from "./file-suggest";
export default class ManualSetting {
private app: App;
private plugin: NodeFactor;
private containerEl: HTMLElement;
private refreshDisplay: () => void;
constructor(
app: App,
plugin: NodeFactor,
containerEl: HTMLElement,
refreshDisplay: () => void,
) {
this.app = app;
this.plugin = plugin;
this.containerEl = containerEl;
this.refreshDisplay = refreshDisplay;
}
display(): void {
new Setting(this.containerEl).setName("Manually set size").setHeading();
let selectedWeight: SliderComponent;
let selectedFile: SearchComponent;
let submitButton: ButtonComponent;
const addWt = new Setting(this.containerEl)
.setName("Add new weight")
.setDesc("Weight added here overrides everything else.");
addWt.addSearch((search) => {
new FileSuggest(this.app, search.inputEl);
selectedFile = search;
search.setPlaceholder("Enter file name");
search.onChange(async (value) => {
submitButton.setDisabled(value.length === 0);
});
});
addWt.addSlider((slider) => {
selectedWeight = slider;
slider.setLimits(0, 100, 5);
slider.setDynamicTooltip();
slider.setValue(0);
});
addWt.addButton((button) => {
submitButton = button;
button.setDisabled(true);
button.setButtonText("Add");
button.setTooltip("Click to add new manual size");
button.onClick(async () => {
const enteredFileData: FileData = {
id: selectedFile.getValue(),
weight: selectedWeight.getValue(),
};
selectedWeight.setValue(0);
selectedFile.setValue("");
const fileExists = this.plugin.settings.manual.find(
(foundFile) => foundFile.id == enteredFileData.id,
);
if (fileExists != undefined) {
new Notice(
"That file's size has already been entered," +
" remove it first to change weight.",
);
return;
}
this.plugin.settings.manual.push(enteredFileData);
await this.plugin.saveSettings();
new Notice("New size added manually");
this.refreshDisplay();
this.plugin.recalculateSize();
});
});
// Display all manually added weights & option to remove them
this.plugin.settings.manual.forEach((value: FileData) => {
const manualDisplay = new Setting(this.containerEl)
.setName(value.id)
.setDesc(`Weight: ${String(value.weight)}`);
manualDisplay.addButton((button) => {
button.setIcon("trash");
button.setTooltip("Remove manually added size");
button.onClick(async () => {
this.plugin.settings.manual.remove(value);
await this.plugin.saveSettings();
this.refreshDisplay();
this.plugin.recalculateSize();
});
});
});
}
}

View file

@ -0,0 +1,85 @@
import { Setting } from "obsidian";
import NodeFactor from "main";
export default class ProgrameticalSetting {
private plugin: NodeFactor;
private containerEl: HTMLElement;
constructor(plugin: NodeFactor, containerEl: HTMLElement) {
this.plugin = plugin;
this.containerEl = containerEl;
}
display(): void {
new Setting(this.containerEl)
.setName("Programatically set size")
.setHeading();
const fwdLinkWt = new Setting(this.containerEl)
.setName("Forward link weight multiplier")
.setDesc("Multiplier for forward links weight (0 to disable).");
fwdLinkWt.addSlider((slider) => {
slider.setLimits(0, 20, 1);
slider.setDynamicTooltip();
slider.setValue(this.plugin.settings.fwdMultiplier);
slider.onChange(async (value) => {
this.plugin.settings.fwdMultiplier = value;
await this.plugin.saveSettings();
this.plugin.recalculateSize();
});
});
const travelFwdTree = new Setting(this.containerEl)
.setName("Travel forward tree")
.setDesc(
"Travel forward and add all other nodes to determine final node size.",
);
travelFwdTree.addToggle((toggle) => {
toggle.setValue(this.plugin.settings.fwdTree);
toggle.onChange(async (value) => {
this.plugin.settings.fwdTree = value;
await this.plugin.saveSettings();
this.plugin.recalculateSize();
});
});
const bwdLinkWt = new Setting(this.containerEl)
.setName("Backward link weight multiplier")
.setDesc("Multiplier for backward links weight (0 to disable).");
bwdLinkWt.addSlider((slider) => {
slider.setLimits(0, 20, 1);
slider.setDynamicTooltip();
slider.setValue(this.plugin.settings.bwdMultiplier);
slider.onChange(async (value) => {
this.plugin.settings.bwdMultiplier = value;
await this.plugin.saveSettings();
this.plugin.recalculateSize();
});
});
const charWt = new Setting(this.containerEl)
.setName("Character per weight")
.setDesc(
"Add 1 weight to node size per no of given character (0 to disable).",
);
charWt.addSlider((slider) => {
slider.setLimits(0, 5000, 100);
slider.setDynamicTooltip();
slider.setValue(this.plugin.settings.lettersPerWt);
slider.onChange(async (value) => {
this.plugin.settings.lettersPerWt = value;
await this.plugin.saveSettings();
this.plugin.recalculateSize();
});
});
}
}