Skip to content

Commit 262868e

Browse files
committed
graph prototype
1 parent 32b0a8c commit 262868e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+877
-289
lines changed

astro.config.mjs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import starlightTypeDoc, { typeDocSidebarGroup } from 'starlight-typedoc';
44
import starlightLinksValidator from 'starlight-links-validator';
55
import remarkMath from 'remark-math';
66
import rehypeMathjax from 'rehype-mathjax';
7+
import starlightSiteGraph from 'starlight-site-graph';
8+
import svelte from '@astrojs/svelte';
79

810
// https://astro.build/config
911
export default defineConfig({
@@ -22,11 +24,15 @@ export default defineConfig({
2224
sidebar: [
2325
{
2426
label: 'Guides',
25-
autogenerate: { directory: 'guides' },
27+
autogenerate: {
28+
directory: 'guides',
29+
},
2630
},
2731
{
2832
label: 'Examples',
29-
autogenerate: { directory: 'examples' },
33+
autogenerate: {
34+
directory: 'examples',
35+
},
3036
},
3137
typeDocSidebarGroup,
3238
],
@@ -52,7 +58,6 @@ export default defineConfig({
5258
excludePrivate: true,
5359
excludeProtected: true,
5460
excludeInternal: true,
55-
5661
plugin: ['typedoc-plugin-mdn-links'],
5762
},
5863
tsconfig: 'obsidian-js-engine-plugin/tsconfig.json',
@@ -61,8 +66,11 @@ export default defineConfig({
6166
collapsed: true,
6267
},
6368
}),
69+
// starlightSiteGraph({}),
6470
],
71+
customCss: ['./src/styles/custom.css'],
6572
}),
73+
svelte(),
6674
],
6775
markdown: {
6876
remarkPlugins: [remarkMath],

bun.lockb

1.6 KB
Binary file not shown.

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@
1212
},
1313
"dependencies": {
1414
"@astrojs/starlight": "0.25.4",
15+
"@astrojs/svelte": "^5.7.0",
1516
"astro": "4.13.2",
16-
"starlight-links-validator": "^0.9.1",
17+
"d3": "^7.9.0",
18+
"pixi.js": "^8.3.2",
1719
"rehype-mathjax": "^6.0.0",
1820
"remark-math": "^6.0.0",
1921
"sharp": "^0.33.4",
22+
"starlight-links-validator": "^0.9.1",
23+
"starlight-site-graph": "^0.0.1",
2024
"starlight-typedoc": "^0.14.0",
25+
"svelte": "5.0.0-next.210",
2126
"typedoc": "^0.26.5",
2227
"typedoc-plugin-markdown": "^4.2.3",
2328
"typedoc-plugin-mdn-links": "^3.2.7",

src/components/Graph.astro

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
3+
---
4+
5+
<script src="./Graph.ts"></script>
6+
7+
<div id="graph-mount-point"></div>

src/components/Graph.ts

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import * as d3 from 'd3';
2+
import { Application, Container, Graphics, Text } from 'pixi.js';
3+
import { testData } from './TestData';
4+
5+
const width = 400;
6+
const height = 400;
7+
const element = document.getElementById('graph-mount-point')!;
8+
9+
const app = new Application();
10+
await app.init({
11+
antialias: true,
12+
backgroundAlpha: 0,
13+
resolution: 1,
14+
resizeTo: element,
15+
});
16+
17+
element.appendChild(app.canvas);
18+
19+
interface Node extends d3.SimulationNodeDatum {
20+
id: string;
21+
graphics?: Container;
22+
text?: Text;
23+
}
24+
25+
const simulation = d3
26+
.forceSimulation<Node>(testData.nodes)
27+
.force(
28+
'link',
29+
d3.forceLink(testData.links).id((d: any) => d.id),
30+
)
31+
.force('charge', d3.forceManyBody())
32+
.force('center', d3.forceCenter(width / 2, height / 2));
33+
34+
console.log(simulation.nodes());
35+
36+
const links = new Graphics();
37+
app.stage.addChild(links);
38+
39+
for (const node of simulation.nodes()) {
40+
const nodeGraphics = new Container();
41+
const nodeDot = new Graphics();
42+
nodeDot.setStrokeStyle({
43+
color: 0xffffff,
44+
width: 1.5,
45+
});
46+
nodeDot.circle(0, 0, 5);
47+
nodeDot.fill(0xffffff);
48+
49+
const nodeText = new Text({
50+
text: node.id,
51+
style: {
52+
fill: 0xffffff,
53+
fontSize: 12,
54+
},
55+
});
56+
nodeText.anchor.set(0.5, 0.5);
57+
58+
nodeGraphics.addChild(nodeDot);
59+
nodeGraphics.addChild(nodeText);
60+
61+
node.graphics = nodeGraphics;
62+
node.text = nodeText;
63+
app.stage.addChild(nodeGraphics);
64+
}
65+
66+
d3.select(app.canvas).call(
67+
// @ts-ignore
68+
d3
69+
.drag()
70+
.container(app.canvas)
71+
.subject(event => {
72+
const invZoom = zoom.invert([event.x, event.y]);
73+
return simulation.find(invZoom[0], invZoom[1], 10);
74+
})
75+
.on('start', dragstarted)
76+
.on('drag', dragged)
77+
.on('end', dragended),
78+
);
79+
80+
let zoom: d3.ZoomTransform = d3.zoomIdentity;
81+
82+
d3.select(app.canvas).call(
83+
// @ts-ignore
84+
d3.zoom().on('zoom', ({ transform }: { transform: d3.ZoomTransform }) => {
85+
zoom = transform;
86+
app.stage.updateTransform({
87+
scaleX: transform.k,
88+
scaleY: transform.k,
89+
x: transform.x,
90+
y: transform.y,
91+
});
92+
}),
93+
);
94+
95+
app.ticker.add(() => {
96+
for (const node of simulation.nodes()) {
97+
node.text!.scale.set(1 / zoom.k);
98+
node.text!.position.set(0, 10);
99+
}
100+
101+
for (const node of simulation.nodes()) {
102+
node.graphics!.position.set(node.x!, node.y!);
103+
}
104+
105+
links.clear();
106+
links.alpha = 0.5;
107+
108+
for (const link of testData.links) {
109+
links
110+
// @ts-ignore
111+
.moveTo(link.source.x!, link.source.y!)
112+
// @ts-ignore
113+
.lineTo(link.target.x!, link.target.y!)
114+
.fill()
115+
.stroke({
116+
color: 0xffffff,
117+
width: 1 / zoom.k,
118+
});
119+
}
120+
});
121+
122+
let dragX = 0;
123+
let dragY = 0;
124+
125+
function dragstarted(event: any) {
126+
if (!event.subject) return;
127+
128+
if (!event.active) simulation.alphaTarget(0.3).restart();
129+
event.subject.fx = event.subject.x;
130+
event.subject.fy = event.subject.y;
131+
dragX = event.x;
132+
dragY = event.y;
133+
}
134+
135+
function dragged(event: any) {
136+
if (!event.subject) return;
137+
138+
dragX += event.dx / zoom.k;
139+
dragY += event.dy / zoom.k;
140+
141+
event.subject.fx = dragX;
142+
event.subject.fy = dragY;
143+
}
144+
145+
function dragended(event: any) {
146+
if (!event.subject) return;
147+
148+
if (!event.active) simulation.alphaTarget(0);
149+
event.subject.fx = null;
150+
event.subject.fy = null;
151+
}

0 commit comments

Comments
 (0)