diff --git a/assets/messages.svg b/assets/messages.svg new file mode 100644 index 0000000..f021e69 --- /dev/null +++ b/assets/messages.svg @@ -0,0 +1 @@ + diff --git a/graph.js b/graph.js index 0b75f18..598b8c7 100644 --- a/graph.js +++ b/graph.js @@ -49,49 +49,41 @@ function layoutNodes() { cy_layout.run(); } +const BUTTON_ICONS = { + "source": "github.svg", + "documentation": "book.svg", + "homepage": "home.svg", + "download": "download.svg", + "chat": "messages.svg", + "issue tracker": "check-circle.svg", + "forum": "users.svg", + "examples": "code.svg", + "tutorial": "user.svg", + "installation": "package.svg", + "email": "mail.svg" +} + +const BUTTON_ROWS = [ + ["homepage", "download", "source"], + ["documentation", "installation", "tutorial", "examples"], + ["forum", "issue tracker", "chat", "email"] +]; + function urlButton(type, url) { const button = document.createElement("button"); - let icon = ""; - switch (type) { - case "source": - iconFile = "github.svg"; - break; - case "documentation": - iconFile = "book.svg"; - break; - case "homepage": - iconFile = "home.svg"; - break; - case "download": - iconFile = "download.svg"; - break; - case "issue tracker": - iconFile = "check-circle.svg"; - break; - case "forum": - iconFile = "users.svg"; - break; - case "examples": - iconFile = "code.svg"; - break; - case "tutorial": - iconFile = "user.svg"; - break; - case "installation": - iconFile = "package.svg"; - break; - case "email": - iconFile = "mail.svg"; - break; - default: - iconFile = "link.svg"; - } + let iconFile = BUTTON_ICONS[type]; button.type = "button" - button.classList.add('btn', 'btn-info', 'm-1'); - icon = ``; + button.classList.add('btn', 'btn-sm', 'm-1'); + let icon = ``; button.innerHTML = icon + " " + type; - button.onclick = function() { - window.open(url, "_blank"); + if (url !== undefined) { + button.classList.add('btn-info'); + button.onclick = function() { + window.open(url, "_blank"); + } + } else { + button.classList.add('btn-secondary'); + button.disabled = true; } return button; } @@ -139,13 +131,20 @@ function showNodeDetails(node) { showDetails(null, null); } else { showDetails(node.data(), node.outgoers("edge").map((edge) => { - return {target: edge.target().id(), label: edge.data("label"), source: edge.source().id()}; - })); + return { type: "outgoing", target: edge.target().id(), label: edge.data("label"), source: edge.source().id() }; + }).concat( + node.incomers("edge").map((edge) => { + return { type: "incoming", target: edge.target().id(), label: edge.data("label"), source: edge.source().id() } + }) + ) + ); } } function highlightEdge(edge) { - const details = document.getElementById("details"); + const details_top = document.getElementById("details_top"); + const details_bottom = document.getElementById("details_bottom"); + details_bottom.innerHTML = ""; const headerElement = document.createElement("h2"); headerElement.innerHTML = edge.id(); @@ -159,7 +158,7 @@ function highlightEdge(edge) { targetLink.addEventListener("click",function(e) { edge.unselect(); edge.target().select(); }); targetLink.innerHTML = edge.target().id(); - details.innerHTML = ""; + details_top.innerHTML = ""; const paragraph = document.createElement("p"); paragraph.appendChild(sourceLink); @@ -167,8 +166,8 @@ function highlightEdge(edge) { label.innerHTML = " " + edge.data("label") + " "; paragraph.appendChild(label); paragraph.appendChild(targetLink); - details.appendChild(headerElement); - details.appendChild(paragraph); + details_top.appendChild(headerElement); + details_top.appendChild(paragraph); // Only show the edge and the connected nodes cy.elements().forEach(n => n.style("opacity", 0.2)); edge.style("opacity", 1); diff --git a/index.html b/index.html index b7be718..e86e074 100644 --- a/index.html +++ b/index.html @@ -67,7 +67,10 @@
Highlight simulators

-
+
+
+
+
diff --git a/index.js b/index.js index f48aad0..36a92ec 100644 --- a/index.js +++ b/index.js @@ -8,108 +8,114 @@ var TOOL_DESCRIPTIONS = {}; const selected = []; // If params are null, show a default message -function showDetails(data, outgoers) { +function showDetails(data, connected) { // Show details about the simulator - const details = document.getElementById("details"); + const details_top = document.getElementById("details_top"); + const details_bottom = document.getElementById("details_bottom"); // Basic description if (data === null) { - details.innerHTML = "
"; - details.innerHTML += "

Using this resource

"; - details.innerHTML += ""; - details.innerHTML += "

Contributing

"; - details.innerHTML += `

Contributions are welcome! If you have anything to add or correct in the data, + details_top.innerHTML = "
"; + details_top.innerHTML += "

Using this resource

"; + details_top.innerHTML += ""; + details_top.innerHTML += "

Contributing

"; + details_top.innerHTML += `

Contributions are welcome! If you have anything to add or correct in the data, please follow the link at the end of the tool's details view to edit the data on GitHub. You can also open an issue on the GitHub repository.

`; - details.innerHTML += "

List of simulators

"; - details.innerHTML += "
"; + details_bottom.innerHTML = "
"; + details_bottom.innerHTML += "

List of simulators

"; for (const sim of SIMULATORS) { const quoted_sim = `[id='${sim}']`; - details.innerHTML += ``; + details_bottom.innerHTML += ``; } - details.innerHTML += "
"; - + details_bottom.innerHTML += "
"; + window.history.pushState({}, "", window.location.href.split("?")[0]); + return; } - else { - if (data["features"].includes("simulator")) { - const quoted_sim = `[id='${data.id}']`; - details.innerHTML = `
-

${data["full_name"]}

- -
`; - } else { - details.innerHTML = `

${data["full_name"]}

`; - } - details.innerHTML += "

" + data["description"] + "

"; + details_top.innerHTML = ""; + details_bottom.innerHTML = ""; + let description = document.createElement("div"); + if (data["features"].includes("simulator")) { + const quoted_sim = `[id='${data.id}']`; + description.innerHTML = `
+

${data["full_name"]}

+ +
`; + } else { + description.innerHTML = `

${data["full_name"]}

`; } + description.innerHTML += "

" + data["description"] + "

"; // Relations - if (outgoers !== null) { - if (outgoers.length > 0) { - details.innerHTML += "

Relations

"; + if (connected !== null) { + if (connected.length > 0) { + description.innerHTML += "

Relations

"; const list = document.createElement("ul"); - for (let edge of outgoers) { + for (let edge of connected) { + if (edge["source"] === "simulators") { + continue; + } const listItem = document.createElement("li"); const targetLink = document.createElement("a"); - // targetLink.href = "#"; - // targetLink.addEventListener("click",function(e) { node.unselect(); edge.target().select(); }); - targetLink.innerHTML = edge["target"]; - const label = document.createElement("i"); + targetLink.href = "#"; + if (edge["type"] === "outgoing") { + targetId = edge["target"]; + } else { + targetId = edge["source"]; + } + targetLink.addEventListener("click",function(e) { + console.log("Clicked on " + targetLink.innerHTML); + cy.nodes("[id='" + data.id + "']").unselect(); + cy.nodes("[id='" + targetLink.innerHTML + "']").select(); + }); + targetLink.innerHTML = targetId; + const simName = document.createElement("i"); + simName.innerHTML = data["short_name"]; + const label = document.createElement("span"); label.innerHTML = " " + edge["label"] + " "; - listItem.appendChild(label); - listItem.appendChild(targetLink); - + if (edge["type"] === "outgoing") { + listItem.append(simName); + listItem.append(label); + listItem.appendChild(targetLink); + } else { + listItem.appendChild(targetLink); + listItem.append(label); + listItem.append(simName); + } list.appendChild(listItem); } - details.appendChild(list); + description.appendChild(list); } + details_top.appendChild(description); // URLs link_heading = document.createElement("h3"); link_heading.innerHTML = "Links"; - details.append(link_heading); - if (data["urls"] !== undefined) { - for (let [text, url] of Object.entries(data["urls"])) { - details.appendChild(urlButton(text, url)); + let tool_links = data["urls"]; + details_bottom.appendChild(link_heading); + for (let row_idx=0; row_idx < BUTTON_ROWS.length; row_idx++) { + let row = document.createElement("div"); + row.classList.add("row"); + // Go through elements in BUTTON_ROWS + for (const button_type of BUTTON_ROWS[row_idx]) { + let col = document.createElement("div"); + col.classList.add("col-auto"); + let button = urlButton(button_type, tool_links[button_type]); + col.appendChild(button); + row.appendChild(col); } + details_bottom.appendChild(row); } - // Back to simulators - back_p = document.createElement("p"); - back_p.classList.add("mt-3"); - back_button = document.createElement("a"); - back_button.href = "#"; - back_button.innerHTML = ` - - -  Back to simulators`; - back_button.classList.add("btn", "btn-secondary"); - back_button.onclick = function() { cy.nodes(`[id = '${data.id}']`).unselect(); cy.nodes("#simulators").select(); unhighlightNode(); }; - back_p.appendChild(back_button); - details.appendChild(back_p); - // Edit footer - edit_p = document.createElement("p"); - edit_p.classList.add("mt-3", "text-end"); - edit_link = document.createElement("a"); - edit_link.classList.add("link-secondary"); - edit_link.href = `${REPO_URL}/edit/${GIT_BRANCH}/${DATA_FOLDER}/${data["short_name"].replaceAll(" ", "-")}.yaml`; - edit_link.innerHTML = "Edit this description on GitHub "; - edit_link.innerHTML += ` - - `; - edit_link.target = "_blank"; - edit_p.appendChild(edit_link); - details.appendChild(edit_p); - } // hide filter pane const filterPane = new bootstrap.Offcanvas('#filter_pane');