Skip to content

Commit

Permalink
MSA viz inclusive of changes suggested
Browse files Browse the repository at this point in the history
  • Loading branch information
triksi254 committed Oct 15, 2024
1 parent 9699846 commit c635138
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 10,214 deletions.
Binary file modified frontend/bun.lockb
Binary file not shown.
10,079 changes: 0 additions & 10,079 deletions frontend/package-lock.json

This file was deleted.

2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"react-aria-components": "^1.3.3",
"react-dom": "^18.3.1",
"react-icons": "^5.3.0",
"react-router": "^6.26.1",
"react-router": "^6.27.0",
"react-router-dom": "^6.26.1",
"react-time-ago": "^7.3.3",
"react-to-text": "^2.0.1"
Expand Down
2 changes: 1 addition & 1 deletion frontend/public/mockServiceWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* - Please do NOT serve this file on production.
*/

const PACKAGE_VERSION = '2.4.10'
const PACKAGE_VERSION = '2.4.9'
const INTEGRITY_CHECKSUM = '26357c79639bfa20d64c0efca2a87423'
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
const activeClientIds = new Set()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
import React, { useEffect, useRef } from 'react';
import '@nightingale-elements/nightingale-msa';
import { Region, SequencesMSA } from '@nightingale-elements/nightingale-msa';
import React, { useEffect, useRef } from "react";
import "@nightingale-elements/nightingale-msa";
import type { Region, SequencesMSA } from "@nightingale-elements/nightingale-msa";

interface NightingaleMSAWrapperProps {
sequences: SequencesMSA;
features: Array<Region>;
}
type Props = {
sequences: SequencesMSA;
features?: Region[];
};

// Define the type for the custom element
interface NightingaleMSAElement extends HTMLElement {
data: SequencesMSA;
features: Array<Region>;
}
type NightingaleMSAElement = {
data: SequencesMSA;
features?: Region[];
} & HTMLElement;

const NightingaleMSAWrapper: React.FC<NightingaleMSAWrapperProps> = ({ sequences, features }) => {
const msaRef = useRef<NightingaleMSAElement>(null);
const NightingaleMSAWrapper = ({ sequences, features }: Props) => {
const msaRef = useRef<NightingaleMSAElement>(null);

useEffect(() => {
if (msaRef.current) {
msaRef.current.data = sequences;
msaRef.current.features = features;
}
}, [sequences, features]);
useEffect(() => {
if (msaRef.current) {
msaRef.current.data = sequences;
if (features) {
msaRef.current.features = features.map(feature => ({
...feature,
}));
}
}
}, [sequences, features]);

return <nightingale-msa ref={msaRef}></nightingale-msa>;
return <nightingale-msa ref={msaRef}></nightingale-msa>;
};

export default NightingaleMSAWrapper;
21 changes: 2 additions & 19 deletions frontend/src/pages/NewAnalysis.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import { useEffect, useState } from "react";
import {
FaArrowRightToBracket,
Expand Down Expand Up @@ -145,8 +144,6 @@ const parseTable = (

const NewAnalysis = () => {
const navigate = useNavigate();
/** msa state */
const [msaData, setMsaData] = useState("");

/** state */
const [inputType, setInputType] = useState<(typeof inputTypes)[number]["id"]>(
Expand Down Expand Up @@ -198,21 +195,11 @@ const NewAnalysis = () => {

/** submit analysis */
const onSubmit = (data: FormData) => {
let dataToSubmit = { ...data };

if (inputType === "list" && inputFormat === "msa") {
// Process MSA data
setMsaData(listInput);
dataToSubmit.msaData = listInput;
}

console.debug(data);
toast("Analysis submitted", "success");
navigate("/analysis/d4e5f6", { state: { msaData: dataToSubmit.msaData } });
navigate("/analysis/d4e5f6");
};



/** clear inputs when selected input format changes */
useEffect(() => {
setListInput("");
Expand Down Expand Up @@ -407,10 +394,6 @@ const NewAnalysis = () => {
onChange={setAnalysisType}
name="analysisType"
/>
/** msa submittedData new state **/
{inputType === "list" && inputFormat === "msa" && (
<input type="hidden" name="msaData" value={msaData} />
)}

{["homology-domain", "homology"].includes(analysisType) && (
<Flex direction="column" hAlign="left">
Expand Down Expand Up @@ -497,4 +480,4 @@ const NewAnalysis = () => {
);
};

export default NewAnalysis;
export default NewAnalysis;
47 changes: 46 additions & 1 deletion frontend/src/pages/Testbed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ import Tooltip from "@/components/Tooltip";
import { useTheme } from "@/util/hooks";
import { formatDate, formatNumber } from "@/util/string";
import tableData from "../../fixtures/table.json";
import type { SequencesMSA, Region } from "@nightingale-elements/nightingale-msa";
import NightingaleMSAWrapper from "@/components/nightingale-wrapper/NightingaleMSAWrapper";

/** util func to log change to components for testing */
const logChange = (...args: unknown[]) => {
Expand Down Expand Up @@ -121,9 +123,42 @@ for (let times = 0; times < 10; times++) {
const edge = sample(edges)!;
edges.push({ ...edge, id: uniqueId(), source: id, target: id });
}

type ExtendedRegion = Region & {
type: string;
start: number;
end: number;
};
/** test and example usage of formatting, elements, components, etc. */
const TestbedPage = () => {
const mockSequences: SequencesMSA = [
{ name: "Seq1", sequence: "ATGCATGCATGC" },
{ name: "Seq2", sequence: "ATGC-TGCATGC" },
{ name: "Seq3", sequence: "ATGCATGC-TGC" },
];

const mockFeatures: ExtendedRegion[] = [
{
type: "domain",
start: 1,
end: 6,
residues: { from: 1, to: 6 },
sequences: { from: 0, to: 2 },
mouseOverFillColor: "rgba(255, 0, 0, 0.5)",
fillColor: "rgba(255, 0, 0, 0.3)",
borderColor: "rgb(255, 0, 0)",
},
{
type: "motif",
start: 8,
end: 12,
residues: { from: 8, to: 12 },
sequences: { from: 0, to: 2 },
mouseOverFillColor: "rgba(255, 0, 0, 0.5)",
fillColor: "rgba(255, 0, 0, 0.3)",
borderColor: "rgb(255, 0, 0)",
},
];

return (
<>
<Meta title="Testbed" />
Expand All @@ -140,6 +175,16 @@ const TestbedPage = () => {
<Network nodes={nodes} edges={edges} />
</Section>

<Section>
<Heading level={2} icon={<FaBars />}>
MSA Visualization
</Heading>
<NightingaleMSAWrapper sequences={mockSequences} features={mockFeatures} />

</Section>



{/* regular html elements and css classes for basic formatting */}
<Section>
<Heading level={2} icon={<FaBrush />}>
Expand Down
124 changes: 35 additions & 89 deletions frontend/src/pages/analysis/Outputs.tsx
Original file line number Diff line number Diff line change
@@ -1,95 +1,41 @@
import {
FaArrowRightFromBracket,
FaBarsStaggered,
FaFeatherPointed,
} from 'react-icons/fa6';
import { useLocation } from 'react-router-dom';
import { LuShapes } from 'react-icons/lu';
import { TbBinaryTree } from 'react-icons/tb';
import Heading from '@/components/Heading';
import Section from '@/components/Section';
import Tabs, { Tab } from '@/components/Tabs';
import DomainArch from '@/pages/analysis/outputs/DomainArch';
import Homology from '@/pages/analysis/outputs/Homology';
import Phylogeny from '@/pages/analysis/outputs/Phylogeny';
import Summary from '@/pages/analysis/outputs/Summary';
import NightingaleMSAWrapper from '@/components/nightingale-wrapper/NightingaleMSAWrapper';
import { Region, SequencesMSA } from '@nightingale-elements/nightingale-msa';

interface ExtendedRegion extends Region {
start: number;
end: number;
type: string;
description: string;
}
FaArrowRightFromBracket,
FaBarsStaggered,
FaFeatherPointed,
} from "react-icons/fa6";
import { LuShapes } from "react-icons/lu";
import { TbBinaryTree } from "react-icons/tb";
import Heading from "@/components/Heading";
import Section from "@/components/Section";
import Tabs, { Tab } from "@/components/Tabs";
import DomainArch from "@/pages/analysis/outputs/DomainArch";
import Homology from "@/pages/analysis/outputs/Homology";
import Phylogeny from "@/pages/analysis/outputs/Phylogeny";
import Summary from "@/pages/analysis/outputs/Summary";

const Outputs = () => {

const location = useLocation();
const msaData = location.state?.msaData;


/** parsing Input msaData **/
const parseSequences = (data: string): SequencesMSA => {
const lines = data.split('\n');
return lines
.map(line => {
const [name, sequence] = line.split(/\s+/);
if (name && sequence) {
return { name, sequence };
}
return null;
})
.filter((seq): seq is { name: string; sequence: string } => seq !== null);
};

const sequences: SequencesMSA = msaData ? parseSequences(msaData) : [];

// Define features based on your requirements
const features: ExtendedRegion[] = [
{
type: "domain",
start: 1,
end: 10,
description: "Domain 1",
residues: { from: 1, to: 10 },
sequences: { from: 0, to: sequences.length - 1 },
mouseOverFillColor: "rgba(255, 0, 0, 0.5)",
fillColor: "rgba(255, 0, 0, 0.3)",
borderColor: "rgba(255, 0, 0, 1)",
},
// Add more features as needed
];

return (
<Section>
<Heading level={2} icon={<FaArrowRightFromBracket />}>
Outputs
</Heading>

<Tabs syncWithUrl="output-tab">
<Tab text="Summary" icon={<FaFeatherPointed />}>
<Summary />
</Tab>
<Tab text="Domain Arch." icon={<FaBarsStaggered />}>
<DomainArch />
</Tab>
<Tab text="Phylogeny" icon={<TbBinaryTree />}>
<Phylogeny />
</Tab>
<Tab text="Homology" icon={<LuShapes />}>
<Homology />
</Tab>
<Tab text="MSA Visualization" icon={<FaBarsStaggered />}>
{sequences.length > 0 ? (
<NightingaleMSAWrapper sequences={sequences} features={features} />
) : (
<p>No valid MSA data available</p>
)}
</Tab>
</Tabs>
</Section>
);
return (
<Section>
<Heading level={2} icon={<FaArrowRightFromBracket />}>
Outputs
</Heading>

<Tabs syncWithUrl="output-tab">
<Tab text="Summary" icon={<FaFeatherPointed />}>
<Summary />
</Tab>
<Tab text="Domain Arch." icon={<FaBarsStaggered />}>
<DomainArch />
</Tab>
<Tab text="Phylogeny" icon={<TbBinaryTree />}>
<Phylogeny />
</Tab>
<Tab text="Homology" icon={<LuShapes />}>
<Homology />
</Tab>
</Tabs>
</Section>
);
};

export default Outputs;
11 changes: 7 additions & 4 deletions frontend/src/vite-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
/** no type def libraries for these libraries */
declare module "cytoscape-cola";
declare module "cytoscape-spread";
// custom-elements.d.ts

declare namespace JSX {
interface IntrinsicElements {
'nightingale-msa': any;
type IntrinsicElements = {
"nightingale-msa": React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement>,
HTMLElement
>;
};
}
}

0 comments on commit c635138

Please sign in to comment.