Skip to content

Commit df66dc4

Browse files
author
Selcuk
committed
Tree and MSA combined view is developed.
1 parent 566cf6c commit df66dc4

2 files changed

Lines changed: 1215 additions & 0 deletions

File tree

src/app/msa_tree_combined/page.tsx

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
'use client';
2+
3+
import React, { useMemo, useState, useEffect } from 'react';
4+
import RootContainer from '@/components/RootContainer';
5+
import CombinedTreeAlignment from '@/components/CombinedTreeAlignment';
6+
import receptors from '../../../public/receptors.json';
7+
8+
interface Receptor {
9+
geneName: string;
10+
class: string;
11+
numOrthologs: number;
12+
lca: string;
13+
gpcrdbId: string;
14+
tree: string;
15+
alignment: string;
16+
conservationFile: string;
17+
snakePlot: string;
18+
svgTree: string;
19+
name: string;
20+
}
21+
22+
export default function MsaTreeCombinedPage() {
23+
const [receptorName, setReceptorName] = useState<string>('5HT1A');
24+
const [receptor, setReceptor] = useState<Receptor | null>(null);
25+
const [newick, setNewick] = useState<string>('');
26+
const [alignmentFasta, setAlignmentFasta] = useState<string>('');
27+
const [loading, setLoading] = useState<boolean>(false);
28+
29+
// Fixed settings
30+
const showSupport = false;
31+
const mirror = false;
32+
const fontSize = 14;
33+
const rowSpacing = 13;
34+
35+
// Load receptor data when receptor name changes
36+
useEffect(() => {
37+
const found = receptors.find((r: Receptor) => r.geneName === receptorName);
38+
setReceptor(found ?? null);
39+
}, [receptorName]);
40+
41+
// Load alignment and tree files when receptor changes
42+
useEffect(() => {
43+
if (!receptor) return;
44+
45+
setLoading(true);
46+
47+
// Load both files in parallel
48+
Promise.all([
49+
fetch(receptor.tree).then(res => res.text()),
50+
fetch(receptor.alignment).then(res => res.text())
51+
])
52+
.then(([treeData, alignmentData]) => {
53+
setNewick(treeData.trim());
54+
setAlignmentFasta(alignmentData);
55+
})
56+
.catch(error => {
57+
console.error('Error loading files:', error);
58+
})
59+
.finally(() => {
60+
setLoading(false);
61+
});
62+
}, [receptor]);
63+
64+
65+
66+
const trimmed = useMemo(() => newick.trim(), [newick]);
67+
68+
return (
69+
<RootContainer>
70+
<div className="container mx-auto max-w-[1200px] px-4 py-6">
71+
<div className="space-y-6">
72+
<div className="rounded-lg bg-card p-6 text-card-foreground shadow-md">
73+
<h1 className="text-xl font-semibold mb-4">Phylogenetic Tree + Alignment Viewer</h1>
74+
<div className="space-y-4">
75+
<div className="flex items-center gap-4">
76+
<label className="text-sm font-medium">Receptor Gene:</label>
77+
<select
78+
className="rounded border border-input bg-background p-2 min-w-[200px]"
79+
value={receptorName}
80+
onChange={e => setReceptorName(e.target.value)}
81+
>
82+
{receptors.map((r: Receptor) => (
83+
<option key={r.geneName} value={r.geneName}>
84+
{r.geneName} - {r.name}
85+
</option>
86+
))}
87+
</select>
88+
{loading && (
89+
<div className="h-5 w-5 animate-spin rounded-full border-b-2 border-foreground" />
90+
)}
91+
</div>
92+
93+
{receptor && (
94+
<div className="text-sm text-muted-foreground">
95+
<p>Class: {receptor.class} | Orthologs: {receptor.numOrthologs} | LCA: {receptor.lca}</p>
96+
</div>
97+
)}
98+
</div>
99+
</div>
100+
101+
<div className="rounded-lg bg-card p-2 text-card-foreground shadow-md" style={{ height: 600 }}>
102+
{loading ? (
103+
<div className="flex items-center justify-center h-full">
104+
<div className="text-center">
105+
<div className="h-8 w-8 animate-spin rounded-full border-b-2 border-foreground mx-auto mb-2" />
106+
<p className="text-muted-foreground">Loading tree and alignment data...</p>
107+
</div>
108+
</div>
109+
) : trimmed ? (
110+
<CombinedTreeAlignment
111+
newick={trimmed}
112+
alignmentFasta={alignmentFasta}
113+
receptor={receptor}
114+
showSupportOnBranches={showSupport}
115+
mirrorRightToLeft={mirror}
116+
fontSize={fontSize}
117+
leafRowSpacing={rowSpacing}
118+
treeWidthPx={300}
119+
alignmentBoxWidthPx={900}
120+
/>
121+
) : (
122+
<div className="flex items-center justify-center h-full">
123+
<p className="text-muted-foreground">Select a receptor to view its phylogenetic tree and alignment</p>
124+
</div>
125+
)}
126+
</div>
127+
</div>
128+
</div>
129+
</RootContainer>
130+
);
131+
}
132+
133+

0 commit comments

Comments
 (0)