Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
82da20e1
Commit
82da20e1
authored
Oct 15, 2024
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: implement graph of relations
parent
952428c1
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
236 additions
and
2 deletions
+236
-2
package.json
web/package.json
+1
-0
pnpm-lock.yaml
web/pnpm-lock.yaml
+125
-0
MemoDetailSidebar.tsx
web/src/components/MemoDetailSidebar/MemoDetailSidebar.tsx
+8
-1
AddMemoRelationPopover.tsx
...onents/MemoEditor/ActionButton/AddMemoRelationPopover.tsx
+1
-1
MemoRelationForceGraph.tsx
...ponents/MemoRelationForceGraph/MemoRelationForceGraph.tsx
+50
-0
index.ts
web/src/components/MemoRelationForceGraph/index.ts
+5
-0
types.ts
web/src/components/MemoRelationForceGraph/types.ts
+11
-0
utils.ts
web/src/components/MemoRelationForceGraph/utils.ts
+35
-0
No files found.
web/package.json
View file @
82da20e1
...
...
@@ -34,6 +34,7 @@
"mermaid"
:
"^11.2.1"
,
"react"
:
"^18.3.1"
,
"react-dom"
:
"^18.3.1"
,
"react-force-graph-2d"
:
"^1.25.6"
,
"react-hot-toast"
:
"^2.4.1"
,
"react-i18next"
:
"^15.0.2"
,
"react-leaflet"
:
"^4.2.1"
,
...
...
web/pnpm-lock.yaml
View file @
82da20e1
...
...
@@ -83,6 +83,9 @@ importers:
react-dom
:
specifier
:
^18.3.1
version
:
18.3.1(react@18.3.1)
react-force-graph-2d
:
specifier
:
^1.25.6
version
:
1.25.6(react@18.3.1)
react-hot-toast
:
specifier
:
^2.4.1
version
:
2.4.1(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
...
...
@@ -1170,6 +1173,9 @@ packages:
'
@vue/compiler-sfc'
:
optional
:
true
'
@tweenjs/tween.js@25.0.0'
:
resolution
:
{
integrity
:
sha512-XKLA6syeBUaPzx4j3qwMqzzq+V4uo72BnlbOjmuljLrRqdsd3qnzvZZoxvMHZ23ndsRS4aufU6JOZYpCbU6T1A==
}
'
@types/babel__core@7.20.5'
:
resolution
:
{
integrity
:
sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==
}
...
...
@@ -1402,6 +1408,10 @@ packages:
abort-controller-x@0.4.3
:
resolution
:
{
integrity
:
sha512-VtUwTNU8fpMwvWGn4xE93ywbogTYsuT+AUxAXOeelbXuQVIwNmC5YLeho9sH4vZ4ITW8414TTAOG1nW6uIVHCA==
}
accessor-fn@1.5.1
:
resolution
:
{
integrity
:
sha512-zZpFYBqIL1Aqg+f2qmYHJ8+yIZF7/tP6PUGx2/QM0uGPSO5UegpinmkNwDohxWtOj586BpMPVRUjce2HI6xB3A==
}
engines
:
{
node
:
'
>=12'
}
acorn-jsx@5.3.2
:
resolution
:
{
integrity
:
sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
}
peerDependencies
:
...
...
@@ -1502,6 +1512,9 @@ packages:
balanced-match@1.0.2
:
resolution
:
{
integrity
:
sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
}
bezier-js@6.1.4
:
resolution
:
{
integrity
:
sha512-PA0FW9ZpcHbojUCMu28z9Vg/fNkwTj5YhusSAjHHDfHDGLxJ6YUKrAN2vk1fP2MMOxVw4Oko16FMlRGVBGqLKg==
}
binary-extensions@2.3.0
:
resolution
:
{
integrity
:
sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
}
engines
:
{
node
:
'
>=8'
}
...
...
@@ -1536,6 +1549,10 @@ packages:
caniuse-lite@1.0.30001662
:
resolution
:
{
integrity
:
sha512-sgMUVwLmGseH8ZIrm1d51UbrhqMCH3jvS7gF/M6byuHOnKyLOBL7W8yz5V02OHwgLGA36o/AFhWzzh4uc5aqTA==
}
canvas-color-tracker@1.3.1
:
resolution
:
{
integrity
:
sha512-eNycxGS7oQ3IS/9QQY41f/aQjiO9Y/MtedhCgSdsbLSxC9EyUD8L3ehl/Q3Kfmvt8um79S45PBV+5Rxm5ztdSw==
}
engines
:
{
node
:
'
>=12'
}
chalk@2.4.2
:
resolution
:
{
integrity
:
sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
}
engines
:
{
node
:
'
>=4'
}
...
...
@@ -1664,6 +1681,9 @@ packages:
resolution
:
{
integrity
:
sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==
}
engines
:
{
node
:
'
>=12'
}
d3-binarytree@1.0.2
:
resolution
:
{
integrity
:
sha512-cElUNH+sHu95L04m92pG73t2MEJXKu+GeKUN1TJkFsu93E5W8E9Sc3kHEGJKgenGvj19m6upSn2EunvMgMD2Yw==
}
d3-brush@3.0.0
:
resolution
:
{
integrity
:
sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==
}
engines
:
{
node
:
'
>=12'
}
...
...
@@ -1705,6 +1725,10 @@ packages:
resolution
:
{
integrity
:
sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==
}
engines
:
{
node
:
'
>=12'
}
d3-force-3d@3.0.5
:
resolution
:
{
integrity
:
sha512-tdwhAhoTYZY/a6eo9nR7HP3xSW/C6XvJTbeRpR92nlPzH6OiE+4MliN9feuSFd0tPtEUo+191qOhCTWx3NYifg==
}
engines
:
{
node
:
'
>=12'
}
d3-force@3.0.0
:
resolution
:
{
integrity
:
sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==
}
engines
:
{
node
:
'
>=12'
}
...
...
@@ -1725,6 +1749,9 @@ packages:
resolution
:
{
integrity
:
sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
}
engines
:
{
node
:
'
>=12'
}
d3-octree@1.0.2
:
resolution
:
{
integrity
:
sha512-Qxg4oirJrNXauiuC94uKMbgxwnhdda9xRLl9ihq45srlJ4Ga3CSgqGcAL8iW7N5CIv4Oz8x3E734ulxyvHPvwA==
}
d3-path@1.0.9
:
resolution
:
{
integrity
:
sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==
}
...
...
@@ -2036,6 +2063,10 @@ packages:
for-each@0.3.3
:
resolution
:
{
integrity
:
sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==
}
force-graph@1.44.2
:
resolution
:
{
integrity
:
sha512-SthMFx+CdvMM4kwN/KoqmNx1//H5smwukOgQi7VsyqxDQU72vFE6/1/TDqb5NG8UnZjjaKEMcusOnAkpV+4zNA==
}
engines
:
{
node
:
'
>=12'
}
foreground-child@3.3.0
:
resolution
:
{
integrity
:
sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==
}
engines
:
{
node
:
'
>=14'
}
...
...
@@ -2043,6 +2074,9 @@ packages:
fraction.js@4.3.7
:
resolution
:
{
integrity
:
sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
}
fromentries@1.3.2
:
resolution
:
{
integrity
:
sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==
}
fs.realpath@1.0.0
:
resolution
:
{
integrity
:
sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
}
...
...
@@ -2200,6 +2234,10 @@ packages:
resolution
:
{
integrity
:
sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
}
engines
:
{
node
:
'
>=0.8.19'
}
index-array-by@1.4.2
:
resolution
:
{
integrity
:
sha512-SP23P27OUKzXWEC/TOyWlwLviofQkCSCKONnc62eItjp69yCZZPqDQtr3Pw5gJDnPeUMqExmKydNZaJO0FU9pw==
}
engines
:
{
node
:
'
>=12'
}
inflight@1.0.6
:
resolution
:
{
integrity
:
sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
}
deprecated
:
This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
...
...
@@ -2359,6 +2397,10 @@ packages:
javascript-natural-sort@0.7.1
:
resolution
:
{
integrity
:
sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==
}
jerrypick@1.1.1
:
resolution
:
{
integrity
:
sha512-XTtedPYEyVp4t6hJrXuRKr/jHj8SC4z+4K0b396PMkov6muL+i8IIamJIvZWe3jUspgIJak0P+BaWKawMYNBLg==
}
engines
:
{
node
:
'
>=12'
}
jiti@1.21.6
:
resolution
:
{
integrity
:
sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==
}
hasBin
:
true
...
...
@@ -2402,6 +2444,10 @@ packages:
resolution
:
{
integrity
:
sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==
}
engines
:
{
node
:
'
>=4.0'
}
kapsule@1.14.6
:
resolution
:
{
integrity
:
sha512-wSi6tHNOfXrIK2Pvv6BhZ9ukzhbp+XZlOOPWSVGUbqfFsnnli4Eq8FN6TaWJv2e17sY5+fKYVxa4DP2oPGlKhg==
}
engines
:
{
node
:
'
>=12'
}
katex@0.16.11
:
resolution
:
{
integrity
:
sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==
}
hasBin
:
true
...
...
@@ -2769,6 +2815,12 @@ packages:
peerDependencies
:
react
:
^18.3.1
react-force-graph-2d@1.25.6
:
resolution
:
{
integrity
:
sha512-qFarXF1pazVtGUoJul7cecqVGdfLoMQiX/98mewULM9YXDXesDfVExBaLkoz9KHN/guWdoSfH2sTUHQA9hpmDw==
}
engines
:
{
node
:
'
>=12'
}
peerDependencies
:
react
:
'
*'
react-hot-toast@2.4.1
:
resolution
:
{
integrity
:
sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==
}
engines
:
{
node
:
'
>=10'
}
...
...
@@ -2795,6 +2847,12 @@ packages:
react-is@18.3.1
:
resolution
:
{
integrity
:
sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
}
react-kapsule@2.4.1
:
resolution
:
{
integrity
:
sha512-dAPhdUHZWbCH46lF2wHSqtJ3bdmNCYiV10v7QBgzYGAVMup/SZt6WHgP0PzURQvinVRKpq6PmsO4af1W37mQdg==
}
engines
:
{
node
:
'
>=12'
}
peerDependencies
:
react
:
'
>=16.13.1'
react-leaflet@4.2.1
:
resolution
:
{
integrity
:
sha512-p9chkvhcKrWn/H/1FFeVSqLdReGwn2qmiobOQGO3BifX+/vV/39qhY8dGqbdcPh1e6jxh/QHriLXr7a4eLFK4Q==
}
peerDependencies
:
...
...
@@ -3139,6 +3197,9 @@ packages:
resolution
:
{
integrity
:
sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==
}
engines
:
{
node
:
'
>=10'
}
tinycolor2@1.6.0
:
resolution
:
{
integrity
:
sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==
}
tinyexec@0.3.0
:
resolution
:
{
integrity
:
sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==
}
...
...
@@ -4290,6 +4351,8 @@ snapshots:
transitivePeerDependencies
:
-
supports-color
'
@tweenjs/tween.js@25.0.0'
:
{}
'
@types/babel__core@7.20.5'
:
dependencies
:
'
@babel/parser'
:
7.25.6
...
...
@@ -4575,6 +4638,8 @@ snapshots:
abort-controller-x@0.4.3
:
{}
accessor-fn@1.5.1
:
{}
acorn-jsx@5.3.2(acorn@8.12.1)
:
dependencies
:
acorn
:
8.12.1
...
...
@@ -4697,6 +4762,8 @@ snapshots:
balanced-match@1.0.2
:
{}
bezier-js@6.1.4
:
{}
binary-extensions@2.3.0
:
{}
brace-expansion@1.1.11
:
...
...
@@ -4733,6 +4800,10 @@ snapshots:
caniuse-lite@1.0.30001662
:
{}
canvas-color-tracker@1.3.1
:
dependencies
:
tinycolor2
:
1.6.0
chalk@2.4.2
:
dependencies
:
ansi-styles
:
3.2.1
...
...
@@ -4869,6 +4940,8 @@ snapshots:
d3-axis@3.0.0
:
{}
d3-binarytree@1.0.2
:
{}
d3-brush@3.0.0
:
dependencies
:
d3-dispatch
:
3.0.1
...
...
@@ -4910,6 +4983,14 @@ snapshots:
dependencies
:
d3-dsv
:
3.0.1
d3-force-3d@3.0.5
:
dependencies
:
d3-binarytree
:
1.0.2
d3-dispatch
:
3.0.1
d3-octree
:
1.0.2
d3-quadtree
:
3.0.1
d3-timer
:
3.0.1
d3-force@3.0.0
:
dependencies
:
d3-dispatch
:
3.0.1
...
...
@@ -4928,6 +5009,8 @@ snapshots:
dependencies
:
d3-color
:
3.1.0
d3-octree@1.0.2
:
{}
d3-path@1.0.9
:
{}
d3-path@3.1.0
:
{}
...
...
@@ -5392,6 +5475,23 @@ snapshots:
dependencies
:
is-callable
:
1.2.7
force-graph@1.44.2
:
dependencies
:
'
@tweenjs/tween.js'
:
25.0.0
accessor-fn
:
1.5.1
bezier-js
:
6.1.4
canvas-color-tracker
:
1.3.1
d3-array
:
3.2.4
d3-drag
:
3.0.0
d3-force-3d
:
3.0.5
d3-scale
:
4.0.2
d3-scale-chromatic
:
3.1.0
d3-selection
:
3.0.0
d3-zoom
:
3.0.0
index-array-by
:
1.4.2
kapsule
:
1.14.6
lodash-es
:
4.17.21
foreground-child@3.3.0
:
dependencies
:
cross-spawn
:
7.0.3
...
...
@@ -5399,6 +5499,8 @@ snapshots:
fraction.js@4.3.7
:
{}
fromentries@1.3.2
:
{}
fs.realpath@1.0.0
:
{}
fsevents@2.3.3
:
...
...
@@ -5552,6 +5654,8 @@ snapshots:
imurmurhash@0.1.4
:
{}
index-array-by@1.4.2
:
{}
inflight@1.0.6
:
dependencies
:
once
:
1.4.0
...
...
@@ -5703,6 +5807,8 @@ snapshots:
javascript-natural-sort@0.7.1
:
{}
jerrypick@1.1.1
:
{}
jiti@1.21.6
:
{}
js-base64@3.7.7
:
{}
...
...
@@ -5734,6 +5840,10 @@ snapshots:
object.assign
:
4.1.5
object.values
:
1.2.0
kapsule@1.14.6
:
dependencies
:
lodash-es
:
4.17.21
katex@0.16.11
:
dependencies
:
commander
:
8.3.0
...
...
@@ -6123,6 +6233,13 @@ snapshots:
react
:
18.3.1
scheduler
:
0.23.2
react-force-graph-2d@1.25.6(react@18.3.1)
:
dependencies
:
force-graph
:
1.44.2
prop-types
:
15.8.1
react
:
18.3.1
react-kapsule
:
2.4.1(react@18.3.1)
react-hot-toast@2.4.1(csstype@3.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
:
dependencies
:
goober
:
2.1.14(csstype@3.1.3)
...
...
@@ -6144,6 +6261,12 @@ snapshots:
react-is@18.3.1
:
{}
react-kapsule@2.4.1(react@18.3.1)
:
dependencies
:
fromentries
:
1.3.2
jerrypick
:
1.1.1
react
:
18.3.1
react-leaflet@4.2.1(leaflet@1.9.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
:
dependencies
:
'
@react-leaflet/core'
:
2.1.0(leaflet@1.9.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
...
...
@@ -6556,6 +6679,8 @@ snapshots:
throttle-debounce@3.0.1
:
{}
tinycolor2@1.6.0
:
{}
tinyexec@0.3.0
:
{}
to-fast-properties@2.0.0
:
{}
...
...
web/src/components/MemoDetailSidebar/MemoDetailSidebar.tsx
View file @
82da20e1
...
...
@@ -3,6 +3,7 @@ import { isEqual } from "lodash-es";
import
{
CheckCircleIcon
,
Code2Icon
,
HashIcon
,
LinkIcon
}
from
"lucide-react"
;
import
{
Memo
,
MemoProperty
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
MemoRelationForceGraph
from
"../MemoRelationForceGraph"
;
interface
Props
{
memo
:
Memo
;
...
...
@@ -21,7 +22,13 @@ const MemoDetailSidebar = ({ memo, className }: Props) => {
className
,
)
}
>
<
div
className=
"flex flex-col justify-start items-start w-full mt-1 px-1 gap-2 h-auto shrink-0 flex-nowrap hide-scrollbar"
>
<
div
className=
"flex flex-col justify-start items-start w-full px-1 gap-2 h-auto shrink-0 flex-nowrap hide-scrollbar"
>
{
memo
.
relations
.
length
>
0
&&
(
<
div
className=
"relative w-full h-36 border rounded-lg bg-zinc-50 dark:bg-zinc-900 dark:border-zinc-800"
>
<
MemoRelationForceGraph
className=
"w-full h-full"
memo=
{
memo
}
/>
<
span
className=
"absolute top-1 left-2 text-xs opacity-60 font-mono"
>
Relations
</
span
>
</
div
>
)
}
<
div
className=
"w-full flex flex-col"
>
<
p
className=
"flex flex-row justify-start items-center w-full gap-1 mb-1 text-sm leading-6 text-gray-400 dark:text-gray-500 select-none"
>
<
span
>
Created at
</
span
>
...
...
web/src/components/MemoEditor/ActionButton/AddMemoRelationPopover.tsx
View file @
82da20e1
...
...
@@ -27,7 +27,7 @@ const AddMemoRelationPopover = (props: Props) => {
const
[
isFetching
,
setIsFetching
]
=
useState
<
boolean
>
(
true
);
const
[
fetchedMemos
,
setFetchedMemos
]
=
useState
<
Memo
[]
>
([]);
const
[
selectedMemos
,
setSelectedMemos
]
=
useState
<
Memo
[]
>
([]);
const
[
embedded
,
setEmbedded
]
=
useState
<
boolean
>
(
tru
e
);
const
[
embedded
,
setEmbedded
]
=
useState
<
boolean
>
(
fals
e
);
const
[
popoverOpen
,
setPopoverOpen
]
=
useState
<
boolean
>
(
false
);
const
filteredMemos
=
fetchedMemos
.
filter
(
...
...
web/src/components/MemoRelationForceGraph/MemoRelationForceGraph.tsx
0 → 100644
View file @
82da20e1
import
{
useColorScheme
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
{
useEffect
,
useRef
,
useState
}
from
"react"
;
import
ForceGraph2D
from
"react-force-graph-2d"
;
import
{
Memo
}
from
"@/types/proto/api/v1/memo_service"
;
import
{
FGMethods
}
from
"./types"
;
import
{
convertMemoRelationsToGraphData
}
from
"./utils"
;
interface
Props
{
memo
:
Memo
;
className
?:
string
;
}
const
MAIN_NODE_COLOR
=
"#14b8a6"
;
const
DEFAULT_NODE_COLOR
=
"#a1a1aa"
;
const
MemoRelationForceGraph
=
({
className
,
memo
}:
Props
)
=>
{
const
{
mode
}
=
useColorScheme
();
const
containerRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
graphRef
=
useRef
<
FGMethods
|
undefined
>
(
undefined
);
const
[
graphSize
,
setGraphSize
]
=
useState
({
width
:
0
,
height
:
0
});
useEffect
(()
=>
{
if
(
!
containerRef
.
current
)
return
;
setGraphSize
(
containerRef
.
current
.
getBoundingClientRect
());
},
[]);
const
onNodeClick
=
()
=>
{
// TODO: Handle node click event
};
return
(
<
div
ref=
{
containerRef
}
className=
{
clsx
(
"dark:opacity-80"
,
className
)
}
>
<
ForceGraph2D
ref=
{
graphRef
}
width=
{
graphSize
.
width
}
height=
{
graphSize
.
height
}
enableZoomInteraction
cooldownTicks=
{
0
}
nodeColor=
{
(
node
)
=>
(
node
.
name
===
memo
.
name
?
MAIN_NODE_COLOR
:
DEFAULT_NODE_COLOR
)
}
nodeRelSize=
{
3
}
linkColor=
{
()
=>
(
mode
===
"light"
?
""
:
"#525252"
)
}
graphData=
{
convertMemoRelationsToGraphData
(
memo
.
relations
)
}
onNodeClick=
{
onNodeClick
}
/>
</
div
>
);
};
export
default
MemoRelationForceGraph
;
web/src/components/MemoRelationForceGraph/index.ts
0 → 100644
View file @
82da20e1
import
MemoRelationForceGraph
from
"./MemoRelationForceGraph"
;
export
*
from
"./utils"
;
export
default
MemoRelationForceGraph
;
web/src/components/MemoRelationForceGraph/types.ts
0 → 100644
View file @
82da20e1
import
{
ForceGraphMethods
,
LinkObject
,
NodeObject
}
from
"react-force-graph-2d"
;
export
interface
NodeType
{
name
:
string
;
}
export
interface
LinkType
{
// ...add more additional properties relevant to the link here.
}
export
interface
FGMethods
extends
ForceGraphMethods
<
NodeObject
<
NodeType
>
,
LinkObject
<
NodeType
,
LinkType
>>
{}
web/src/components/MemoRelationForceGraph/utils.ts
0 → 100644
View file @
82da20e1
import
{
GraphData
,
LinkObject
,
NodeObject
}
from
"react-force-graph-2d"
;
import
{
MemoRelation
}
from
"@/types/proto/api/v1/memo_relation_service"
;
import
{
LinkType
,
NodeType
}
from
"./types"
;
export
const
convertMemoRelationsToGraphData
=
(
memoRelations
:
MemoRelation
[]):
GraphData
<
NodeType
,
LinkType
>
=>
{
const
nodesMap
=
new
Map
<
string
,
NodeObject
<
NodeType
>>
();
const
links
:
LinkObject
<
NodeType
,
LinkType
>
[]
=
[];
// Iterate through memoRelations to populate nodes and links.
memoRelations
.
forEach
((
relation
)
=>
{
const
{
memo
,
relatedMemo
,
type
}
=
relation
;
// Add memo node if not already present.
if
(
!
nodesMap
.
has
(
memo
))
{
nodesMap
.
set
(
memo
,
{
id
:
memo
,
name
:
memo
});
}
// Add related_memo node if not already present.
if
(
!
nodesMap
.
has
(
relatedMemo
))
{
nodesMap
.
set
(
relatedMemo
,
{
id
:
relatedMemo
,
name
:
relatedMemo
});
}
// Create link between memo and relatedMemo.
links
.
push
({
source
:
memo
,
target
:
relatedMemo
,
type
,
// Include the type of relation as a property of the link.
});
});
return
{
nodes
:
Array
.
from
(
nodesMap
.
values
()),
links
,
};
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment