Skip to content

Commit

Permalink
security fixes and stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
syedzayyan committed May 21, 2024
1 parent 7282e40 commit 9daceb5
Show file tree
Hide file tree
Showing 13 changed files with 364 additions and 174 deletions.
4 changes: 2 additions & 2 deletions app/tools/scaff_net/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ export default function DisplayGraph() {
/>
</Tabs>
<Tabs title="Network Details">
<ScaffNetDets graph={graph} />
{graph != undefined && <ScaffNetDets graph={graph} />}
</Tabs>
<Tabs title="Whole Network">
<ScaffoldNetworkWholeGraph graph={graph} />
{graph != undefined && <ScaffoldNetworkWholeGraph graph={graph} imageSize={200}/>}
</Tabs>
</TabWrapper>
</div>
Expand Down
41 changes: 41 additions & 0 deletions components/tools/toolComp/ScaffLegend.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';

// Define the ColorLegend component
const ColorLegend = ({ colors }) => {
return (
<div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center' }}>
{colors.map((item, index) => (
<div key={index} style={{ display: 'flex', alignItems: 'center', marginRight: '20px' }}>
<div
style={{
width: '20px',
height: '20px',
backgroundColor: item.color,
marginRight: '5px'
}}
/>
<span>{item.label}</span>
</div>
))}
</div>
);
};

// Example usage of the ColorLegend component
const ScaffEdgeLegend = () => {
const colorArray = [
{ color: '#99ccff', label: 'Fragment' }, // Muted Blue
{ color: '#ff9999', label: 'Generic' }, // Muted Red
{ color: '#99ff99', label: 'GenericBond' }, // Muted Green
{ color: '#666666', label: 'RemoveAttachment' }, // Dark Gray
{ color: '#cccc66', label: 'Other' } // Muted Yellow
];

return (
<div>
<ColorLegend colors={colorArray} />
</div>
);
};

export default ScaffEdgeLegend;
25 changes: 24 additions & 1 deletion components/tools/toolComp/ScaffNetDets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ import React, { useState, useEffect } from "react";
import MoleculeStructure from "./MoleculeStructure";
import Card from "../toolViz/Card";
import TagComponent from "../../ui-comps/Tags";
import ModalComponent from "../../ui-comps/ModalComponent";
import { subgraph } from "graphology-operators";
import ScaffoldNetworkWholeGraph from "./ScaffoldNetworkWholeGraph";

const GraphComponent: React.FC<any> = ({ graph }) => {
const [modalState, setModalState] = useState(false);

// Function to get nodes connected to a specific label in the graph
function getNodesConnectedToLabel(graph, label) {
const nodes = [];
Expand All @@ -25,7 +30,7 @@ const GraphComponent: React.FC<any> = ({ graph }) => {
setDisplayNodesArray(nodesArray);
}
}

// State declarations
const [currentPage, setCurrentPage] = useState(1);
const [nodesArray, setNodesArray] = useState<{ node: any, smiles: string, size: number }[]>([]);
Expand Down Expand Up @@ -73,6 +78,13 @@ const GraphComponent: React.FC<any> = ({ graph }) => {
setCurrentPage(pageNumber);
};

const [subGraph, setGraph] = useState<any>();
function filterNodes(nodeEnquired: string, attr, depthSet: number) {
let filteredGraph = subgraph(graph, [nodeEnquired, ...graph.neighbors(nodeEnquired)]);;
setGraph(filteredGraph);
setModalState(true);
}

return (
<div>
{/* Component for filtering tags */}
Expand All @@ -87,10 +99,21 @@ const GraphComponent: React.FC<any> = ({ graph }) => {
<p>Node ID: {node}</p>
<MoleculeStructure structure={smiles} id={node} />
<p>Scaffold Matches: {size}</p>
<button className="button" onClick={() => filterNodes(node, "attr", 3)}>Neighbour Nodes</button>
</Card>
))}
</div>

<ModalComponent isOpen = {modalState} closeModal={() => setModalState(false)} card = {false}>
<div>
<h2>Neighbouring Nodes</h2>
{modalState &&
<ScaffoldNetworkWholeGraph graph={subGraph} imageSize={300} height={500} />
}
</div>

</ModalComponent>

{/* Pagination buttons */}
<div>
<button className={`tableButton ${currentPage === 1 ? "activeButton" : "inactiveButton"}`} disabled={currentPage === 1} onClick={() => handlePageChange(1)}>
Expand Down
128 changes: 72 additions & 56 deletions components/tools/toolComp/ScaffoldNetworkWholeGraph.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import React, { useEffect, useRef } from 'react';
import * as d3 from 'd3';
import ScaffEdgeLegend from './ScaffLegend';

const ScaffoldNetworkWholeGraph = ({ graph, imageSize = 120 }) => {
const ScaffoldNetworkWholeGraph = ({ graph, imageSize = 120, width = 928, height = 680 }) => {
const svgRef = useRef(null);

useEffect(() => {
const width = 928;
const height = 680;
// Clear previous SVG elements
d3.select(svgRef.current).selectAll("*").remove();

// Create a fake root node
const fakeRoot = { id: 'fakeRoot', children: [] };
const graph_ex = graph.export();
const { nodes, links } = {
nodes: [fakeRoot, ...graph_ex.nodes.map(n => ({ id: n.key, ...n.attributes }))],
links: graph_ex.edges
}
links: graph_ex.edges.map(e => ({
source: e.source,
target: e.target,
...e.attributes
}))
};

// Make all existing root nodes children of the fake root node
nodes.forEach(node => {
Expand All @@ -23,81 +28,92 @@ const ScaffoldNetworkWholeGraph = ({ graph, imageSize = 120 }) => {
}
});

const simulation = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id(d => d.id).distance(50)) // Increase link distance
.force("charge", d3.forceManyBody().strength(-30)) // Decrease repulsion strength
.force("center", d3.forceCenter(width / 2, height / 2)); // Center the graph around the middle of the SVG

const svg = d3.select(svgRef.current)
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto;")
.call(d3.zoom().on("zoom", function (event) {
svg.attr("transform", event.transform);
}));
.call(d3.zoom()
.scaleExtent([0.1, 10])
.on("zoom", (event) => {
svgGroup.attr("transform", event.transform);
})
);

const svgGroup = svg.append("g");

const link = svg.append("g")
const simulation = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id(d => d.id).distance(100)) // Increase link distance
.force("charge", d3.forceManyBody().strength(-300)) // Increase repulsion strength
.force("center", d3.forceCenter(width / 2, height / 2))
.force("collide", d3.forceCollide().radius(imageSize * 0.2)); // Add collision force to prevent overlap

const link = svgGroup.append("g")
.attr("stroke", "#999")
.attr("stroke-opacity", 0.6)
.selectAll("line")
.data(links)
.enter()
.append("line")
.attr("stroke-width", 0.6)
.attr("stroke", d => d.attributes.color) // Set the stroke color dynamically based on data
.attr("stroke-opacity", 0.5);
.enter().append("line")
.attr("stroke-width", d => Math.sqrt(d.value))
.attr("stroke", d => d.color);

const node = svg.append("g")
const node = svgGroup.append("g")
.attr("stroke", "#fff")
.attr("stroke-width", 1.5)
.selectAll("image")
.data(nodes)
.join("image")
.enter().append("image")
.attr("xlink:href", d => d.image) // Function to get image URL
.attr("width", d => d.id === 'fakeRoot' ? 0 : imageSize * 0.2 ) // Adjust image width
.attr("height", d => d.id === 'fakeRoot' ? 0 : imageSize * 0.2 ); // Adjust image height
.attr("width", d => d.id === 'fakeRoot' ? 0 : imageSize * 0.2) // Adjust image width
.attr("height", d => d.id === 'fakeRoot' ? 0 : imageSize * 0.2) // Adjust image height
.call(drag(simulation));

node.append("title")
.text(d => d.smiles);

// Add a drag behavior.
node.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));

// Set the position attributes of links and nodes each time the simulation ticks.
simulation.on("tick", () => {
link
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y) // Reverse the y-coordinate for source
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y); // Reverse the y-coordinate for target
.attr("y2", d => d.target.y);

node
.attr("x", d => d.x)
.attr("y", d => d.y); // Reverse the y-coordinate for nodes
.attr("x", d => d.x - imageSize * 0.1) // Center the image
.attr("y", d => d.y - imageSize * 0.1); // Center the image
});

// Reheat the simulation when drag starts, and fix the subject position.
function dragstarted(event) {
if (!event.active) simulation.alphaTarget(0.3).restart();
event.subject.fx = event.subject.x;
event.subject.fy = event.subject.y;
}
function dragged(event) {
event.subject.fx = event.x;
event.subject.fy = event.y;
}
function dragended(event) {
if (!event.active) simulation.alphaTarget(0);
event.subject.fx = null;
event.subject.fy = null;
}
function drag(simulation) {
function dragstarted(event) {
if (!event.active) simulation.alphaTarget(0.3).restart();
event.subject.fx = event.subject.x;
event.subject.fy = event.subject.y;
}

function dragged(event) {
event.subject.fx = event.x;
event.subject.fy = event.y;
}

function dragended(event) {
if (!event.active) simulation.alphaTarget(0);
event.subject.fx = null;
event.subject.fy = null;
}

// When this cell is re-run, stop the previous simulation. (This doesn’t
// really matter since the target alpha is zero and the simulation will
// stop naturally, but it’s a good practice.)
// // invalidation.then(() => simulation.stop());
return d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
}

}, [graph]);
}, [graph, imageSize]); // Ensure the effect runs only when `graph` or `imageSize` changes

return <svg ref={svgRef} height="600px" width="100%"/>;
return (
<>
<ScaffEdgeLegend />
<svg ref={svgRef} height="600px" width="100%" />
</>

);
};

export default ScaffoldNetworkWholeGraph;
4 changes: 3 additions & 1 deletion components/ui-comps/CornerMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import TargetContext from '../../context/TargetContext';
import SideBar from "./SideBar/SideBar";
import ModalComponent from './ModalComponent';
import { SideBarDropDownItem, SideBarItem, SideBarLink } from './SideBar/SideBarItems';
import ThemeContext from '../../context/ThemeContext';


export default function CornerMenu() {
Expand All @@ -13,6 +14,7 @@ export default function CornerMenu() {

const { ligand } = useContext(LigandContext);
const { target } = useContext(TargetContext);
const { theme } = useContext(ThemeContext);


function saveWork(e) {
Expand Down Expand Up @@ -45,7 +47,7 @@ export default function CornerMenu() {
{target.pre_processed && (
<>
<div onClick={() => setModalState(true)}>
<SideBarItem>Save Work <img height="30px" width="30px" src="/save_disk.svg"></img></SideBarItem>
<SideBarItem>Save Work <img height="30px" width="30px" src="/save_disk.svg" style = {{filter : theme === "dark" ? "invert(1)" : ""}}></img></SideBarItem>
</div>
<div style={{ height: "40px" }}></div>

Expand Down
10 changes: 8 additions & 2 deletions components/ui-comps/ModalComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ interface ModalComponentProps {
closeModal: () => void;
width?: string;
height?: string;
card?: boolean;
}

const ModalComponent: FC<ModalComponentProps> = ({
Expand All @@ -14,6 +15,7 @@ const ModalComponent: FC<ModalComponentProps> = ({
closeModal,
width = "80",
height = "80",
card = true
}) => {
const handleOverlayClick = (
e: React.MouseEvent<HTMLDivElement, MouseEvent>,
Expand Down Expand Up @@ -55,8 +57,12 @@ const ModalComponent: FC<ModalComponentProps> = ({
}
.modal {
display: grid;
grid-template-columns: repeat(3, 1fr);
${card &&
`
display: grid;
grid-template-columns: repeat(3, 1fr);
`
}
height: ${height}vh;
width: ${width}vw;
margin: 10%;
Expand Down
2 changes: 1 addition & 1 deletion components/ui-comps/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const Navbar = () => {
<nav className="navbar">
<div className="logo">
<a href="/">
WORK IN PROGRESS
QSAR IN THE BROWSER
</a>
</div>
<ul className="navLinks">
Expand Down
5 changes: 4 additions & 1 deletion components/ui-comps/SideBar/SideBarItems.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useState } from "react";
import { useContext, useState } from "react";
import ThemeContext from "../../../context/ThemeContext";

export function SideBarItem({ children }) {
return (
Expand All @@ -12,6 +13,7 @@ export function SideBarItem({ children }) {

export function SideBarDropDownItem({ name_of, children, disabled = false }) {
const [isOpen, setIsOpen] = useState(false);
const { theme } = useContext(ThemeContext);

return (
<div className="sidebar-dropdown-link">
Expand All @@ -28,6 +30,7 @@ export function SideBarDropDownItem({ name_of, children, disabled = false }) {
opacity: 1,
width: '30px', // Set the width of the icon
height: '30px',
filter : theme === "dark" ? "invert(1)" : "",
}}
>
</img>
Expand Down
Loading

0 comments on commit 9daceb5

Please sign in to comment.