diff --git a/index.html b/index.html
index a3cc64d..963d43e 100644
--- a/index.html
+++ b/index.html
@@ -96,6 +96,11 @@
Node sizes indicate the number of declarations in the file.
+
+
+
+
@@ -161,9 +166,12 @@
let pause = document.getElementById('pause');
let graph = graphologyLibrary.gexf.parse(graphology.Graph, gexf);
let rev_graph = graphologyLibrary.operators.reverse(graph);
+ let searchInput = document.getElementById("search-input");
+ let searchSuggestions = document.getElementById("suggestions");
// interaction state
var state = {
+ searchQuery: "",
hoveredNode: undefined,
hoveredDescendants: undefined,
hoveredPath: undefined,
@@ -289,14 +297,15 @@
node_data.y = 0.1*r * Math.sin(theta * 2 * Math.PI);
}
- var force_atlas_settings = {
- barnesHutOptimize: false,
- strongGravityMode: false,
- gravity: 0.05,
- scalingRatio: 10,
- slowDown: 10,
- edgeWeightInfluence: 1,
- };
+ var force_atlas_settings =graphologyLibrary.layoutForceAtlas2.inferSettings(graph);
+
+// barnesHutOptimize: false,
+// strongGravityMode: false,
+// gravity: 0.05,
+// scalingRatio: 10,
+// slowDown: 10,
+// edgeWeightInfluence: 1,
+// };
// run the optimizer a little
graphologyLibrary.layoutForceAtlas2.assign(graph, {
@@ -395,6 +404,60 @@
},
});
+ // Feed the datalist autocomplete values:
+
+ searchSuggestions.innerHTML = graph.nodes().map(node=>"")).join("\n");
+ // Actions:
+
+ function setSearchQuery(query) {
+ state.searchQuery = query;
+ if (searchInput.value !== query)
+ searchInput.value = query;
+
+ if (query) {
+ const lcQuery = query.toLowerCase();
+ const suggestions = graph.nodes().map(n=>({
+ id: n,
+ label: graph.getNodeAttribute(n, "label")
+ })).filter(({label})=>label.toLowerCase().includes(lcQuery));
+ // If we have a single perfect match, them we remove the suggestions, and
+ // we consider the user has selected a node through the datalist
+ // autocomplete:
+
+ if (suggestions.length === 1 && suggestions[0].label === query) {
+ state.selectedNode = suggestions[0].id;
+ state.suggestions = undefined;
+ // Move the camera to center it on the selected node:
+
+ const nodePosition = renderer.getNodeDisplayData(state.selectedNode);
+ renderer.getCamera().animate(nodePosition, {
+ duration: 500
+ });
+ }// Else, we display the suggestions list:
+ else {
+ state.selectedNode = undefined;
+ state.suggestions = new Set(suggestions.map(({id})=>id));
+ }
+ }// If the query is empty, then we reset the selectedNode / suggestions state:
+ else {
+ state.selectedNode = undefined;
+ state.suggestions = undefined;
+ }
+ // Refresh rendering:
+
+ renderer.refresh();
+ }
+
+ searchInput.addEventListener("input", ()=>{
+ setSearchQuery(searchInput.value || "");
+ }
+ );
+ searchInput.addEventListener("blur", ()=>{
+ setSearchQuery("");
+ }
+ );
+
+
let statusElem = document.getElementById('statusWrapper');
let statusMsgElem = document.getElementById('statusMessage');
let setStatus = function(html) {