Skip to content
Snippets Groups Projects
Commit 510a72fa authored by Matthias Konitzny's avatar Matthias Konitzny :fire:
Browse files

Working search bar.

Also fixed a bug realted to wrong highlighting if the node focus changes using the display.
parent 7b856b95
No related branches found
No related tags found
1 merge request!3Master into new editor
...@@ -7,11 +7,44 @@ ...@@ -7,11 +7,44 @@
gap: 10px; gap: 10px;
} }
.searchbar-input[type="search"] {
border-style: hidden;
}
.searchbar-input[type="search"]:focus {
outline: none;
}
.searchbar-icon { .searchbar-icon {
cursor: pointer;
font-size: 30px; font-size: 30px;
} }
.searchbar-text { .searchbar-text {
overflow: hidden; overflow: hidden;
transition: width 0.2s ease-in-out; transition: width 0.25s ease-in-out;
}
.searchbar-results {
overflow: hidden;
}
.searchbar-result {
cursor: pointer;
z-index: 99;
pointer-events: all;
}
.searchbar-result:hover {
color: gray;
}
.serach-area {
display: flex;
flex-direction: column;
background-color: transparent;
transition: background-color 0.2s ease-in-out;
border-radius: 30px;
padding-left: 10px;
padding-right: 5px;
} }
\ No newline at end of file
import React, { useEffect, useState } from "react"; import React, { useEffect, useRef, useState } from "react";
import "./searchbar.css"; import "./searchbar.css";
import { NodeData } from "../graph";
interface SearchBarProps { interface SearchBarProps {
minified: boolean; minified: boolean;
searchTerms: string[]; nodeSet: NodeData[];
onSearch?: (term: string) => void; onSearch?: (node: NodeData) => void;
} }
function SearchBar({ minified, searchTerms, onSearch }: SearchBarProps) { function SearchBar({ minified, nodeSet, onSearch }: SearchBarProps) {
const [isMinified, setMinified] = useState(minified); const [isMinified, setMinified] = useState(minified);
const [width, setWidth] = useState<number>(100); const [width, setWidth] = useState<number>(minified ? 0 : 100);
const [inputText, setInputText] = useState(""); const [inputText, setInputText] = useState("");
const inputField = useRef<HTMLInputElement>();
const toggleMinified = () => { const toggleMinified = () => {
setMinified((prev) => !prev); setMinified((prev) => !prev);
...@@ -19,9 +21,12 @@ function SearchBar({ minified, searchTerms, onSearch }: SearchBarProps) { ...@@ -19,9 +21,12 @@ function SearchBar({ minified, searchTerms, onSearch }: SearchBarProps) {
useEffect(() => { useEffect(() => {
if (isMinified) { if (isMinified) {
setWidth(100);
} else {
setWidth(0); setWidth(0);
setInputText("");
inputField.current.value = "";
} else {
setWidth(100);
inputField.current.focus();
} }
}, [isMinified]); }, [isMinified]);
...@@ -29,19 +34,67 @@ function SearchBar({ minified, searchTerms, onSearch }: SearchBarProps) { ...@@ -29,19 +34,67 @@ function SearchBar({ minified, searchTerms, onSearch }: SearchBarProps) {
setInputText(e.target.value.toLowerCase()); setInputText(e.target.value.toLowerCase());
}; };
const labels = nodeSet.map((node) => node.name);
const nodeLoopup = new Map<string, NodeData>();
labels.forEach((label, i) => nodeLoopup.set(label, nodeSet[i]));
const filtered = labels
.filter((el) => {
if (inputText !== "") {
return el.toLowerCase().includes(inputText);
}
})
.slice(0, 3);
const handleNodeClick = (node: string) => {
if (onSearch !== undefined) {
onSearch(nodeLoopup.get(node));
}
};
return ( return (
<div className={"searchbar"}> <div
<div className={"searchbar-icon"} onClick={toggleMinified}> className={"serach-area"}
&#128269; style={{ backgroundColor: isMinified ? "" : "white" }}
>
<div className={"searchbar"}>
<div className={"searchbar-icon"} onClick={toggleMinified}>
&#128269;
</div>
<div
className={"searchbar-text"}
style={{ width: width + "%" }}
>
<form action={"#"}>
<input
ref={inputField}
className={"searchbar-input"}
type={"search"}
placeholder={"Knoten suchen..."}
onInput={handleInput}
onBlur={toggleMinified}
></input>
</form>
</div>
</div> </div>
<div className={"searchbar-text"} style={{ width: width + "%" }}> <div
<form action={"#"}> className={"searchbar-results"}
<input style={{
type={"search"} height: inputText.length > 0 ? filtered.length * 30 : 0,
placeholder={"Suchbegriff eingeben..."} marginBottom: filtered.length > 0 ? 10 : 0,
onInput={handleInput} }}
></input> >
</form> <ul>
{filtered.map((el) => (
<li
key={el}
className={"searchbar-result"}
onMouseDown={() => handleNodeClick(el)}
>
{el}
</li>
))}
</ul>
</div> </div>
</div> </div>
); );
......
...@@ -10,6 +10,7 @@ import { loadGraphJson } from "../datasets"; ...@@ -10,6 +10,7 @@ import { loadGraphJson } from "../datasets";
import NodeInfoBar from "./components/nodeinfo/nodeinfobar"; import NodeInfoBar from "./components/nodeinfo/nodeinfobar";
import FilterMenu from "./components/nodefilter/filtermenu"; import FilterMenu from "./components/nodefilter/filtermenu";
import SearchBar from "./components/searchbar"; import SearchBar from "./components/searchbar";
import { graph } from "../editor/js/editor";
/** /**
* This component manages and renders a 3d-force-graph with additional menus to navigate, filter and view information on nodes. * This component manages and renders a 3d-force-graph with additional menus to navigate, filter and view information on nodes.
...@@ -74,6 +75,7 @@ class Display extends React.Component< ...@@ -74,6 +75,7 @@ class Display extends React.Component<
handleNodeChangeRequest(node: NodeData) { handleNodeChangeRequest(node: NodeData) {
this.rendererRef.current.focusOnNode(node as GraphNode); this.rendererRef.current.focusOnNode(node as GraphNode);
this.rendererRef.current.displayNodeSelection(node as GraphNode);
this.handleNodeClicked(node); this.handleNodeClicked(node);
} }
...@@ -121,7 +123,13 @@ class Display extends React.Component< ...@@ -121,7 +123,13 @@ class Display extends React.Component<
> >
&#10231; &#10231;
</div> </div>
<SearchBar minified={true} searchTerms={["a", "b", "c"]} /> {this.state.graph && (
<SearchBar
minified={true}
nodeSet={this.state.graph.nodes}
onSearch={this.handleNodeChangeRequest}
/>
)}
</div> </div>
{/*{this.graph && (*/} {/*{this.graph && (*/}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment