Skip to content

Commit

Permalink
Merge pull request #157 from amosproj/feat/split-view
Browse files Browse the repository at this point in the history
Feat/split view
  • Loading branch information
iremozs authored Jun 25, 2024
2 parents 1455a12 + 16bd135 commit 7a0b809
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 15 deletions.
4 changes: 2 additions & 2 deletions Project/backend/codebase/graph_creator/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,8 @@ async def get_graph_data_for_visualization(
raise HTTPException(
status_code=400, detail="A graph needs to be created for this job first!"
)
return netx_services.graph_data_for_visualization(
g_job.id, node=node, adj_depth=adj_depth
return await netx_services.graph_data_for_visualization(
graph_job=g_job, node=node, adj_depth=adj_depth
)


Expand Down
4 changes: 4 additions & 0 deletions Project/backend/codebase/graph_creator/schemas/graph_vis.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from datetime import datetime

from pydantic import BaseModel, Field


Expand All @@ -19,6 +21,8 @@ class GraphEdge(BaseModel):


class GraphVisData(BaseModel):
document_name: str
graph_created_at: datetime
nodes: list[GraphNode]
edges: list[GraphEdge]

Expand Down
30 changes: 21 additions & 9 deletions Project/backend/codebase/graph_creator/services/netx_graphdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import numpy as np
import pandas as pd

from graph_creator.models.graph_job import GraphJob
from graph_creator.schemas.graph_vis import GraphVisData, GraphNode, GraphEdge

# Scale range for min-max scaling the node sizes
Expand Down Expand Up @@ -96,19 +97,20 @@ def delete_graph(self, graph_job_id: uuid.UUID):
if os.path.exists(file_location):
os.remove(file_location)

def graph_data_for_visualization(
self, graph_job_id: uuid.UUID, node: str = None, adj_depth: int = 1
async def graph_data_for_visualization(
self, graph_job: GraphJob, node: str = None, adj_depth: int = 1
) -> GraphVisData:
"""
Given a graph travers it and return a json format of all the nodes and edges they have
ready for visualization to FE
"""
graph = self.load_graph(graph_job_id)

graph = self.load_graph(graph_job.id)

if node:
return self._graph_bfs_edges(graph, node, adj_depth)
return self._graph_bfs_edges(graph, graph_job, node, adj_depth)

return self._all_graph_data_for_visualization(graph)
return self._all_graph_data_for_visualization(graph, graph_job)

@staticmethod
def _get_graph_file_path_local_storage(graph_job_id: uuid.UUID) -> str:
Expand All @@ -125,7 +127,9 @@ def _get_graph_file_path_local_storage(graph_job_id: uuid.UUID) -> str:
return os.path.join(graphs_directory, f"{graph_job_id}.gml")

@staticmethod
def _graph_bfs_edges(graph: nx.Graph, node: str, adj_depth: int) -> GraphVisData:
def _graph_bfs_edges(
graph: nx.Graph, graph_job: GraphJob, node: str, adj_depth: int
) -> GraphVisData:
nodes_data = []
edges_data = []
visited = set()
Expand Down Expand Up @@ -164,10 +168,15 @@ def _graph_bfs_edges(graph: nx.Graph, node: str, adj_depth: int) -> GraphVisData
)
)

return GraphVisData(nodes=nodes_data, edges=edges_data)
return GraphVisData(document_name=graph_job.name,
graph_created_at=graph_job.updated_at,
nodes=nodes_data,
edges=edges_data)

@staticmethod
def _all_graph_data_for_visualization(graph: nx.Graph) -> GraphVisData:
def _all_graph_data_for_visualization(
graph: nx.Graph, graph_job: GraphJob
) -> GraphVisData:
nodes_data = []
edges_data = []

Expand Down Expand Up @@ -196,4 +205,7 @@ def _all_graph_data_for_visualization(graph: nx.Graph) -> GraphVisData:
)
)

return GraphVisData(nodes=nodes_data, edges=edges_data)
return GraphVisData(document_name=graph_job.name,
graph_created_at=graph_job.updated_at,
nodes=nodes_data,
edges=edges_data)
37 changes: 37 additions & 0 deletions Project/frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Project/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"dependencies": {
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@mui/icons-material": "^5.15.20",
"@mui/material": "^5.15.19",
"@react-sigma/core": "4.0.2",
"@sigma/edge-curve": "*",
Expand All @@ -27,6 +28,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-filepond": "^7.1.2",
"react-icons": "^5.2.1",
"react-router-dom": "^6.23.1",
"react-sigma": "*",
"sigma": "3.0.0-beta.16",
Expand Down
33 changes: 32 additions & 1 deletion Project/frontend/src/components/Graph/index.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.graph_container {
.main_graph_container {
flex: 1;
display: flex;
flex-direction: column;
gap: 50px;
Expand All @@ -10,6 +11,36 @@
/* overflow: hidden; */
}

.graph_container {
flex: 1;
display: flex;
flex-direction: row;
gap: 50px;
text-align: center;
justify-content: flex-start;
height: 100vh;
width: 100vw;
}

.graph_info {
width: 25%;
padding: 20px;
overflow-y: auto;
}

.graph_info h1 {
margin-bottom: 30px;
text-decoration: underline;
}

.graph_info p {
margin-bottom: 30px;
}

.search_container {
position: relative;
}

.sigma_container {
background: var(--mui-palette-primary-main);
}
Expand Down
69 changes: 66 additions & 3 deletions Project/frontend/src/components/Graph/index_visjs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { Network } from 'vis-network/standalone/esm/vis-network';
import { useParams } from 'react-router-dom';
import './index.css';
import { VISUALIZE_API_PATH } from '../../constant';
import SearchIcon from '@mui/icons-material/Search';
import TextField from '@mui/material/TextField';
import { InputAdornment } from '@mui/material';

const VisGraph = ({ graphData, options }) => {
const containerRef = useRef(null);
Expand Down Expand Up @@ -203,6 +206,25 @@ const GraphVisualization = () => {
},
};

const searchGraph = (event) => {
if (event.key === 'Enter') {
// Perform the search
}
};

const searchBarStyle = {
padding: '8px',
width: '100%',
marginBottom: '10px',
fontSize: '16px',
};

const answerAreaStyle = {
padding: '8px',
width: '100%',
fontSize: '16px',
};

if (isLoading) {
return <div className="loading_spinner_graph">Loading graph...</div>;
}
Expand All @@ -211,9 +233,17 @@ const GraphVisualization = () => {
return <div className="error_container">Sorry, an error has occurred!</div>;
}

const formattedDate = new Date(
graphData.graph_created_at,
).toLocaleDateString();

const formattedTime = new Date(
graphData.graph_created_at,
).toLocaleTimeString();

return (
<section className="graph_container">
<h1>Graph Visualization</h1>
<section className="main_graph_container">
<h1>Graph Visualization </h1>
<select onChange={(e) => setLayout(e.target.value)} value={layout}>
<option value="barnesHut">Barnes Hut</option>
<option value="forceAtlas2Based">Force Atlas 2 Based</option>
Expand All @@ -223,7 +253,40 @@ const GraphVisualization = () => {
<option value="grid">Grid</option>
<option value="random">Random</option>
</select>
<VisGraph graphData={graphData} options={options} />
<section className="graph_container">
<div className="graph_info">
<h1>Graph Information</h1>
<p>
Document Name: <br /> {graphData.document_name}
<br /> <br />
Created at: <br /> {formattedDate} {formattedTime}
</p>
<TextField
className="search_text_field"
placeholder="Search for keywords"
style={searchBarStyle}
onKeyDown={searchGraph}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<SearchIcon />
</InputAdornment>
),
}}
/>
<TextField
className="answer_text_field"
placeholder="Answer to your search will be displayed here!"
style={answerAreaStyle}
multiline
rows={8}
InputProps={{
readOnly: true,
}}
/>
</div>
<VisGraph graphData={graphData} options={options} />
</section>
</section>
);
};
Expand Down

0 comments on commit 7a0b809

Please sign in to comment.