Skip to content

Commit 1dfd0b3

Browse files
committed
Refactor frontend
1 parent 41b0df6 commit 1dfd0b3

4 files changed

Lines changed: 127 additions & 117 deletions

File tree

api.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const BACKEND_URL = "https://syar2tbuna.execute-api.us-east-1.amazonaws.com/"
2+
const DATA_ENDPOINT = "dev/data"
3+
4+
function getData() {
5+
return fetch(`${BACKEND_URL}${DATA_ENDPOINT}`)
6+
.then(response => {
7+
if (response.ok) {
8+
return response.json()
9+
} throw new Error(response.statusText)
10+
})
11+
.catch(error => { throw new Error(error.message) });
12+
}

graph.js

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
const graphElem = document.getElementById('idea-graph');
2+
const Graph = ForceGraph3D()(graphElem)
3+
displayGraph();
4+
5+
window.onclick = function (event) {
6+
if (event.target == document.getElementById("modal-idea-detail")) {
7+
document.getElementById("modal-idea-detail").style.display = "none";
8+
}
9+
}
10+
11+
async function displayGraph() {
12+
let newData
13+
try {
14+
newData = await getData()
15+
Graph.graphData(newData)
16+
.nodeLabel('name')
17+
.onNodeHover(node => graphElem.style.cursor = node ? 'pointer' : null)
18+
.onNodeClick(node => {
19+
// Aim at node from outside it
20+
const distance = 40;
21+
const distRatio = 1 + distance / Math.hypot(node.x, node.y, node.z);
22+
23+
Graph.cameraPosition(
24+
{ x: node.x * distRatio, y: node.y * distRatio, z: node.z * distRatio }, // new position
25+
node, // lookAt ({ x, y, z })
26+
3000 // ms transition duration
27+
);
28+
displayDetail(node);
29+
});
30+
}
31+
catch (error) {
32+
console.log(error)
33+
}
34+
}
35+
36+
function displayDetail(node) {
37+
const modal = document.getElementById("modal-idea-detail");
38+
const detailName = document.getElementById("detail-name");
39+
const detailTags = document.getElementById("detail-tags");
40+
const detailCreator = document.getElementById("detail-creator");
41+
const detailDescription = document.getElementById("detail-description");
42+
43+
detailName.textContent = node.name;
44+
detailTags.textContent = [...node.tags].join(', ');
45+
detailCreator.textContent = node.creator;
46+
detailDescription.textContent = node.description;
47+
48+
modal.style.top = event.pageY;
49+
modal.style.left = event.pageX;
50+
modal.style.display = 'block';
51+
}
52+
53+
function onAddItemClick() {
54+
const modal = document.getElementById("modal-idea-new");
55+
modal.style.display = "block";
56+
}
57+
58+
function onModalSubmitClick(event, form) {
59+
event.preventDefault();
60+
const modal = document.getElementById("modal-idea-new");
61+
modal.style.display = "none";
62+
63+
const ideaName = form["idea-name"];
64+
const ideaTags = form["tags"];
65+
const ideaDescription = form["description"];
66+
const creatorName = form["creator-name"];
67+
68+
const { nodes, links } = Graph.graphData();
69+
const id = nodes.length;
70+
71+
const newIdea = {
72+
id: id,
73+
name: ideaName.value,
74+
tags: new Set(ideaTags.value.split(",").map(tag => tag.trim().toLowerCase())),
75+
creator: creatorName.value,
76+
description: ideaDescription.value,
77+
};
78+
const newLinks = matchTags(newIdea, nodes)
79+
80+
Graph.graphData({
81+
nodes: [...nodes, { ...newIdea }],
82+
links: [...links, ...newLinks]
83+
});
84+
85+
form.reset();
86+
}
87+
88+
function onModalCloseClick(modal) {
89+
modal.parentElement.style.display = 'none';
90+
}
91+
92+
function matchTags(newIdea, nodes) {
93+
var newLinks = [];
94+
for (idea of nodes) {
95+
var intersection = new Set([...idea.tags].filter(x => newIdea.tags.has(x)));
96+
if (intersection.size != 0) {
97+
newLinks = [...newLinks, { source: newIdea.id, target: idea.id }]
98+
}
99+
}
100+
}

index.html

Lines changed: 13 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1+
<!DOCTYPE html>
2+
<html lang="en-US">
3+
14
<head>
25
<link rel="stylesheet" href="styles.css">
36
<script src="https://unpkg.com/3d-force-graph"></script>
47
</head>
58

69
<body>
7-
<div id="idea-web"></div>
8-
<button id="btn-add" onclick="onAddItemClick()">Add Idea</button>
10+
<div id="idea-graph"></div>
11+
12+
<button id="button-add" onclick="onAddItemClick()">Add Idea</button>
13+
914
<div id="modal-idea-new">
10-
<button class="exit-button" onclick="onModalCloseClick(this)">X</button>
15+
<button class="button-modal-close" onclick="onModalCloseClick(this)">X</button>
1116
<form id="form-idea-new" onsubmit="onModalSubmitClick(event, this)">
1217
Idea Name:<br>
1318
<input type="text" name="idea-name">
@@ -26,122 +31,15 @@
2631
</div>
2732

2833
<div id="modal-idea-detail">
29-
<button class="exit-button" onclick="onModalCloseClick(this)">X</button>
34+
<button class="button-modal-close" onclick="onModalCloseClick(this)">X</button>
3035
<b><span id="detail-name"></span></b><br>
3136
<span id="detail-creator"></span><br><br>
3237
<span id="detail-description"></span><br><br>
3338
Topics: <span id="detail-tags"></span>
3439
</div>
40+
</body>
3541

36-
<script>
37-
displayGraph();
38-
39-
async function displayGraph() {
40-
const web = document.getElementById('idea-web');
41-
let newData
42-
try {
43-
newData = await getData()
44-
const Graph = ForceGraph3D()
45-
(web)
46-
.graphData(newData)
47-
.nodeLabel('name')
48-
.onNodeHover(node => web.style.cursor = node ? 'pointer' : null)
49-
.onNodeClick(node => {
50-
// Aim at node from outside it
51-
const distance = 40;
52-
const distRatio = 1 + distance / Math.hypot(node.x, node.y, node.z);
53-
54-
Graph.cameraPosition(
55-
{ x: node.x * distRatio, y: node.y * distRatio, z: node.z * distRatio }, // new position
56-
node, // lookAt ({ x, y, z })
57-
3000 // ms transition duration
58-
);
59-
detailDisplay(node);
60-
});
61-
}
62-
catch (error) {
63-
console.log(error)
64-
}
65-
}
66-
67-
function getData() {
68-
return fetch('https://syar2tbuna.execute-api.us-east-1.amazonaws.com/dev/data')
69-
.then(response => {
70-
if (response.ok) {
71-
return response.json()
72-
} throw new Error(response.statusText)
73-
})
74-
.catch(error => { throw new Error(error.message) });
75-
}
76-
77-
function onAddItemClick() {
78-
const modal = document.getElementById("modal-idea-new");
79-
modal.style.display = "block";
80-
}
81-
82-
function onModalSubmitClick(event, form) {
83-
event.preventDefault();
84-
const modal = document.getElementById("modal-idea-new");
85-
const ideaName = form["idea-name"];
86-
const ideaTags = form["tags"];
87-
const ideaDescription = form["description"];
88-
const creatorName = form["creator-name"];
89-
90-
const { nodes, links } = Graph.graphData();
91-
const id = nodes.length;
92-
93-
const newIdea = {
94-
id: id,
95-
name: ideaName.value,
96-
tags: new Set(ideaTags.value.split(",").map(tag => tag.trim().toLowerCase())),
97-
creator: creatorName.value,
98-
description: ideaDescription.value,
99-
};
100-
101-
modal.style.display = "none";
102-
form.reset();
103-
104-
var newLinks = [];
105-
106-
for (idea of nodes) {
107-
var intersection = new Set([...idea.tags].filter(x => newIdea.tags.has(x)));
108-
if (intersection.size != 0) {
109-
newLinks = [...newLinks, { source: newIdea.id, target: idea.id }]
110-
}
111-
}
112-
113-
Graph.graphData({
114-
nodes: [...nodes, { ...newIdea }],
115-
links: [...links, ...newLinks]
116-
});
117-
}
118-
119-
function detailDisplay(node) {
120-
const modal = document.getElementById("modal-idea-detail");
121-
const detailName = document.getElementById("detail-name");
122-
const detailTags = document.getElementById("detail-tags");
123-
const detailCreator = document.getElementById("detail-creator");
124-
const detailDescription = document.getElementById("detail-description");
125-
126-
detailName.textContent = node.name;
127-
detailTags.textContent = [...node.tags].join(', ');
128-
detailCreator.textContent = node.creator;
129-
detailDescription.textContent = node.description;
130-
131-
modal.style.top = event.pageY;
132-
modal.style.left = event.pageX;
133-
modal.style.display = 'block';
134-
}
135-
136-
function onModalCloseClick(modal) {
137-
modal.parentElement.style.display = 'none';
138-
}
139-
140-
window.onclick = function (event) {
141-
if (event.target == document.getElementById("modal-idea-detail")) {
142-
document.getElementById("modal-idea-detail").style.display = "none";
143-
}
144-
}
42+
<script src="api.js"></script>
43+
<script src="graph.js"></script>
14544

146-
</script>
147-
</body>
45+
</html>

styles.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ body {
33
font-family: Arial, Helvetica, sans-serif;
44
}
55

6-
#btn-add {
6+
#button-add {
77
position: fixed;
88
bottom: 10px;
99
right: 10px;
@@ -30,7 +30,7 @@ textarea {
3030
height: 75px;
3131
}
3232

33-
.exit-button {
33+
.button-modal-close {
3434
position: absolute;
3535
right: 5px;
3636
top: 5px;

0 commit comments

Comments
 (0)