-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgraphDataManager.js
More file actions
146 lines (132 loc) · 3.98 KB
/
graphDataManager.js
File metadata and controls
146 lines (132 loc) · 3.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import piml from 'piml';
const TAG_COLOR = '#4b5563'; // Gray for tags
const POST_COLOR = '#f87171'; // Red/Primary for posts
const APP_COLOR = '#34d399'; // Emerald for apps
const PROJECT_COLOR = '#60a5fa'; // Blue for projects
export const fetchGraphData = async () => {
const nodes = [];
const links = [];
const tagMap = new Map(); // Tag -> NodeID
// Helper to add tag node and link
const addTagLink = (itemId, tag) => {
if (!tag) return;
const normalizedTag = tag.trim().toLowerCase();
// If tag node doesn't exist, create it
if (!tagMap.has(normalizedTag)) {
const tagNodeId = `tag-${normalizedTag}`;
tagMap.set(normalizedTag, tagNodeId);
nodes.push({
id: tagNodeId,
name: tag, // Keep original case for display
group: 'tag',
color: TAG_COLOR,
val: 1, // Base size
});
}
// Link item to tag
links.push({
source: itemId,
target: tagMap.get(normalizedTag),
});
// Increase tag node size (popularity)
const tagNode = nodes.find((n) => n.id === tagMap.get(normalizedTag));
if (tagNode) {
tagNode.val += 0.5;
}
};
try {
// 1. Fetch Posts
const postsRes = await fetch('/posts/posts.json');
if (postsRes.ok) {
const posts = await postsRes.json();
posts.forEach((post) => {
const id = `post-${post.slug}`;
nodes.push({
id,
slug: post.slug,
name: post.title,
group: 'post',
color: POST_COLOR,
val: 2,
desc: post.description,
});
// Link Tags
if (post.tags && Array.isArray(post.tags)) {
post.tags.forEach((tag) => addTagLink(id, tag));
}
// Link Category
if (post.category) {
addTagLink(id, post.category);
}
});
}
// 2. Fetch Apps
const appsRes = await fetch('/apps/apps.json');
if (appsRes.ok) {
const appsData = await appsRes.json();
// Apps are grouped by category key
Object.entries(appsData).forEach(([category, catData]) => {
if (catData.apps && Array.isArray(catData.apps)) {
catData.apps.forEach((app) => {
const id = `app-${app.slug}`;
nodes.push({
id,
slug: app.slug,
to: app.to, // Some apps might have custom paths
name: app.title,
group: 'app',
color: APP_COLOR,
val: 2,
desc: app.description,
});
// Link Category as Tag
addTagLink(id, category);
// Apps might not have tags, but we can treat 'App' as a tag
addTagLink(id, 'App');
});
}
});
}
// 3. Fetch Projects
const projectsRes = await fetch('/projects/projects.piml');
if (projectsRes.ok) {
const pimlText = await projectsRes.text();
const parsed = piml.parse(pimlText);
let projectList = [];
if (parsed.projects && Array.isArray(parsed.projects)) {
projectList = parsed.projects;
} else if (Array.isArray(parsed)) {
projectList = parsed;
}
projectList.forEach((proj) => {
const id = `project-${proj.slug}`;
nodes.push({
id,
slug: proj.slug,
name: proj.title,
group: 'project',
color: PROJECT_COLOR,
val: 3, // Projects are big
desc: proj.description,
});
// Technologies -> Tags
if (proj.technologies) {
const techs =
typeof proj.technologies === 'string'
? proj.technologies.split(',')
: proj.technologies;
if (Array.isArray(techs)) {
techs.forEach((t) => addTagLink(id, t));
}
}
// Type -> Tag
if (proj.type) {
addTagLink(id, proj.type);
}
});
}
} catch (error) {
console.error('Failed to build knowledge graph:', error);
}
return { nodes, links };
};