Skip to content

Commit 26b3d2c

Browse files
committed
Logo, add exp info to lineage
1 parent 1869475 commit 26b3d2c

File tree

6 files changed

+166
-105
lines changed

6 files changed

+166
-105
lines changed

immuscreen/public/igSCREEN.png

8.45 KB
Loading

immuscreen/src/app/icres/icresbyregion.tsx

Lines changed: 8 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ import { client } from "../../common/utils"
33
import { DataTable } from "@weng-lab/psychscreen-ui-components"
44
import React, { useState } from "react"
55
import { ApolloError, useQuery } from "@apollo/client"
6-
import { gql } from "@apollo/client"
76
import { ReadonlyURLSearchParams, useSearchParams, useRouter } from "next/navigation"
87
import Grid2 from "@mui/material/Unstable_Grid2/Grid2"
98
import { StyledTab } from "../../common/utils"
10-
import { CircularProgress, Collapse, List, ListItemButton, ListItemIcon, ListItemText, Stack, Tooltip, Typography } from "@mui/material"
9+
import { CircularProgress, Collapse, List, ListItemButton, ListItemText, Stack, Tooltip, Typography } from "@mui/material"
1110
import { Tabs } from "@mui/material"
1211
import { ICRES_ACTIVE_EXPERIMENTS, ICRES_QUERY } from "./queries"
1312
import { experimentInfo } from "../../common/consts"
1413
import { getCellDisplayName } from "../celllineage/utils"
15-
import { ExpandLess, ExpandMore, InfoOutlined, StarBorder } from "@mui/icons-material"
16-
import { CellQueryValue } from "../celllineage/types"
14+
import { ExpandLess, ExpandMore, InfoOutlined } from "@mui/icons-material"
15+
import { ICRE_Data, Experiment_Data } from "./types"
16+
import { ActiveCellTypesList, ActiveExperimentList } from "./utils"
1717

1818
export const IcresByRegion = (props) => {
1919
const searchParams: ReadonlyURLSearchParams = useSearchParams()!
@@ -23,9 +23,6 @@ export const IcresByRegion = (props) => {
2323
setValue(newValue)
2424
}
2525

26-
type ICRE_Data = { accession: string, rdhs: string, celltypes: CellQueryValue[], coordinates: { chromosome: string, start: number, end: number, } }
27-
type Experiment_Data = { grouping: string, description: string, name: string, start: number, value: number }
28-
2926
const { loading: loading_icres, data: data_icres, error: error_icres }: { loading: boolean, data: { iCREQuery: ICRE_Data[] }, error?: ApolloError } = useQuery(ICRES_QUERY, {
3027
variables: {
3128
coordinates: {
@@ -125,42 +122,16 @@ export const IcresByRegion = (props) => {
125122
<Typography variant="body2">
126123
Active Cell Types
127124
</Typography>
128-
<Tooltip title="Activity in cell types determined by aggregated ATAC-seq signal z-score of >1.64 (95th percentile)">
125+
<Tooltip arrow title="Activity in cell types determined by aggregated ATAC-seq signal z-score of >1.64 (95th percentile)">
129126
<InfoOutlined />
130127
</Tooltip>
131128
</Stack>
132129
)
133130
},
134131
value: (row) => row.celltypes.map(x => getCellDisplayName(x)).length,
135132
FunctionalRender: (row) => {
136-
const [open, setOpen] = useState(false)
137-
138-
const celltypes = [... new Set(row.celltypes.map(x => getCellDisplayName(x, true)))].sort()
139-
140-
const handleClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
141-
event.stopPropagation()
142-
setOpen(!open);
143-
};
144-
145133
return (
146-
celltypes.length > 0 ?
147-
<List>
148-
<ListItemButton onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => handleClick(event)}>
149-
<ListItemText primary={"Active in " + celltypes.length + " immune cell types"} />
150-
{open ? <ExpandLess /> : <ExpandMore />}
151-
</ListItemButton>
152-
<Collapse in={open} timeout="auto" unmountOnExit>
153-
<List sx={{ pl: 2 }} component="div" disablePadding>
154-
{
155-
celltypes.map((cell: string) =>
156-
<ListItemText key={cell} primary={"\u2022 " + cell} />
157-
)
158-
}
159-
</List>
160-
</Collapse>
161-
</List>
162-
:
163-
<Typography pl={2}>Not Active</Typography>
134+
<ActiveCellTypesList celltypes={row.celltypes} />
164135
)
165136
}
166137
},
@@ -172,73 +143,17 @@ export const IcresByRegion = (props) => {
172143
<Typography variant="body2">
173144
Active Experiments
174145
</Typography>
175-
<Tooltip title="Activity in individual experiments determined by an ATAC-seq signal z-score of >1.64 (95th percentile)">
146+
<Tooltip arrow title="Activity in individual experiments determined by an ATAC-seq signal z-score of >1.64 (95th percentile)">
176147
<InfoOutlined />
177148
</Tooltip>
178149
</Stack>
179150
)
180151
},
181152
value: (row: ICRE_Row) => row?.activeExps ? Object.values(row.activeExps).flat().length : 0,
182153
FunctionalRender: (row: ICRE_Row) => {
183-
const [open, setOpen] = useState(false)
184-
185-
const handleClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
186-
event.stopPropagation()
187-
setOpen(!open);
188-
};
189-
190-
191-
type GroupListProps = { exps: Experiment_Data[], grouping: string }
192-
193-
const GroupList: React.FC<GroupListProps> = (props: GroupListProps) => {
194-
const [openGroup, setOpenGroup] = useState(false)
195-
196-
const handleClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
197-
event.stopPropagation()
198-
setOpenGroup(!openGroup);
199-
};
200-
201-
return (
202-
<List disablePadding>
203-
<ListItemButton onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => handleClick(event)}>
204-
<ListItemText primary={`${props.grouping} (${props.exps.length})`} />
205-
{openGroup ? <ExpandLess /> : <ExpandMore />}
206-
</ListItemButton>
207-
<Collapse in={openGroup} timeout="auto" unmountOnExit>
208-
<List sx={{ pl: 2 }} component="div" disablePadding>
209-
{
210-
props.exps.sort((a, b) => experimentInfo[a.name].order - experimentInfo[b.name].order).map((exp) =>
211-
<Tooltip key={exp.name} title={exp.description}>
212-
<Stack direction={"row"} alignItems={"center"}>
213-
<ListItemText primary={"\u2022 " + exp.name} />
214-
<InfoOutlined fontSize="small" />
215-
</Stack>
216-
</Tooltip>
217-
)
218-
}
219-
</List>
220-
</Collapse>
221-
</List>
222-
)
223-
}
224-
225154
return (
226155
row?.activeExps ?
227-
<List disablePadding>
228-
<ListItemButton onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => handleClick(event)}>
229-
<ListItemText primary={"Active in " + Object.values(row.activeExps).flat().length + " experiments"} />
230-
{open ? <ExpandLess /> : <ExpandMore />}
231-
</ListItemButton>
232-
<Collapse in={open} timeout="auto" unmountOnExit>
233-
<List sx={{ pl: 2 }} component="div" disablePadding>
234-
{
235-
Object.entries(row.activeExps).map(([grouping, exps]: [string, Experiment_Data[]]) =>
236-
<GroupList key={grouping} exps={exps} grouping={grouping} />
237-
)
238-
}
239-
</List>
240-
</Collapse>
241-
</List>
156+
<ActiveExperimentList activeExps={row.activeExps} />
242157
:
243158
<CircularProgress />
244159
)

immuscreen/src/app/icres/page.tsx

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import { useRouter } from "next/navigation"
44
import { StyledTab } from "../../common/utils"
55
import { client } from "../../common/utils"
66
import SearchIcon from "@mui/icons-material/Search"
7-
import { CircularProgress, Stack, ToggleButtonGroup, Typography } from "@mui/material"
7+
import { Box, CircularProgress, Collapse, List, ListItemButton, ListItemText, Stack, ToggleButtonGroup, Typography } from "@mui/material"
88
import { Tabs } from "@mui/material"
99
import Grid2 from "@mui/material/Unstable_Grid2/Grid2"
1010
import { TextField, IconButton, InputAdornment } from "@mui/material"
1111
import { FormControl, MenuItem } from "@mui/material"
12-
import { useQuery } from "@apollo/client"
12+
import { ApolloError, useQuery } from "@apollo/client"
1313

1414
import Select, { SelectChangeEvent } from "@mui/material/Select";
1515
import { ReadonlyURLSearchParams, useSearchParams} from "next/navigation"
@@ -18,18 +18,21 @@ import { CcreAutoComplete } from "../../common/components/mainsearch/CcreAutocom
1818
import { DataTable } from "@weng-lab/psychscreen-ui-components"
1919

2020
import {IcresByRegion} from "./icresbyregion"
21-
import { ATAC_UMAP_QUERY, EBI_ASSO_QUERY, ICRES_BYCT_ZSCORES_QUERY, ICRES_CT_ZSCORES_QUERY, ICRES_QUERY } from "./queries"
21+
import { ATAC_UMAP_QUERY, EBI_ASSO_QUERY, ICRES_ACTIVE_EXPERIMENTS, ICRES_BYCT_ZSCORES_QUERY, ICRES_CT_ZSCORES_QUERY, ICRES_QUERY } from "./queries"
2222
import InputLabel from "@mui/material/InputLabel";
2323
import { stringToColour } from "../../common/utils";
2424
import { AtacBarPlot } from "./atacbarplot"
2525
import { cellTypeStaticInfo } from "../../common./../common/consts";
2626
import { UmapPlot } from "../../common/components/umapplot";
2727
import CellTypeTree from "../../common/components/cellTypeTree"
28-
import { generateCellLineageTreeState, getCellColor } from "../celllineage/utils"
28+
import { generateCellLineageTreeState, getCellColor, getCellDisplayName } from "../celllineage/utils"
2929

3030

3131
//Need better text styling
3232
import ToggleButton from '@mui/material/ToggleButton';
33+
import { Experiment_Data } from "./types"
34+
import { ExpandLess, ExpandMore } from "@mui/icons-material"
35+
import { ActiveCellTypesList, ActiveExperimentList } from "./utils"
3336

3437

3538
export default function Icres() {
@@ -73,8 +76,7 @@ export default function Icres() {
7376
client,
7477
})
7578

76-
77-
const { loading: aloading, data: adata } = useQuery(ICRES_QUERY, {
79+
const { loading: aloading, data: adata, error: error_adata } = useQuery(ICRES_QUERY, {
7880
variables: {
7981
accession: searchParams.get('accession')
8082
},
@@ -84,6 +86,29 @@ export default function Icres() {
8486
client,
8587
})
8688

89+
const { loading: loading_experiments, data: data_experiments, error: error_experiments }: { loading: boolean, data: { calderoncorcesAtacQuery: Experiment_Data[] }, error?: ApolloError } = useQuery(ICRES_ACTIVE_EXPERIMENTS, {
90+
variables: {
91+
accession: searchParams.get('accession') ? [searchParams.get('accession')] : []
92+
},
93+
skip: !searchParams.get('accession'),
94+
fetchPolicy: "cache-and-network",
95+
nextFetchPolicy: "cache-first",
96+
client,
97+
})
98+
99+
//Parse experiment info
100+
let activeExps: { [key: string]: Experiment_Data[] } = {}
101+
data_experiments?.calderoncorcesAtacQuery.forEach(exp => {
102+
//Cutoff for experiment activity set at 1.64
103+
if (exp.value > 1.64) {
104+
if (activeExps[exp.grouping]) {
105+
activeExps[exp.grouping] = [...activeExps[exp.grouping], exp]
106+
} else {
107+
activeExps[exp.grouping] = [exp]
108+
}
109+
}
110+
});
111+
87112

88113
let barplotdata = icrezscoredata && icrezscoredata.calderoncorcesAtacQuery.map(ic => {
89114
return {
@@ -376,11 +401,19 @@ return !searchParams.get('accession') && !searchParams.get('chromosome') ? (
376401
(aloading ?
377402
<CircularProgress />
378403
:
379-
(adata?.iCREQuery[0].celltypes.length === 0) ?
380-
<Typography>Not identified as active in immune cells</Typography>
381-
:
382404
<Stack rowGap={2}>
383-
<Typography>{searchParams.get('accession')} is determined to be active in the following cells:</Typography>
405+
<Stack direction={"row"}>
406+
{
407+
aloading ? <CircularProgress />
408+
: error_adata ? <Typography>Something went wrong fetching activity in cell types</Typography>
409+
: <Box maxWidth={500}><ActiveCellTypesList celltypes={adata?.iCREQuery[0].celltypes} /></Box>
410+
}
411+
{
412+
loading_experiments ? <CircularProgress />
413+
: error_experiments ? <Typography>Something went wrong fetching activity in individual experiments</Typography>
414+
: <Box maxWidth={500}><ActiveExperimentList activeExps={activeExps} /></Box>
415+
}
416+
</Stack>
384417
<CellTypeTree
385418
width={830}
386419
height={1100}

immuscreen/src/app/icres/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { CellQueryValue } from "../celllineage/types"
2+
3+
4+
export type ICRE_Data = { accession: string, rdhs: string, celltypes: CellQueryValue[], coordinates: { chromosome: string, start: number, end: number, } }
5+
export type Experiment_Data = { grouping: string, description: string, name: string, start: number, value: number }

immuscreen/src/app/icres/utils.tsx

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { useState } from "react";
2+
import { Experiment_Data } from "./types";
3+
import { ExpandLess, ExpandMore, InfoOutlined } from "@mui/icons-material";
4+
import { List, ListItemButton, ListItemText, Collapse, Tooltip, Stack } from "@mui/material";
5+
import { experimentInfo } from "../../common/consts";
6+
import { CellQueryValue } from "../celllineage/types";
7+
import { getCellDisplayName } from "../celllineage/utils";
8+
9+
type GroupListProps = { exps: Experiment_Data[], grouping: string }
10+
11+
const ExperimentGroupList: React.FC<GroupListProps> = (props: GroupListProps) => {
12+
const [openGroup, setOpenGroup] = useState(false)
13+
14+
const handleClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
15+
event.stopPropagation()
16+
setOpenGroup(!openGroup);
17+
};
18+
19+
return (
20+
<List disablePadding>
21+
<ListItemButton onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => handleClick(event)}>
22+
<ListItemText primary={`${props.grouping} (${props.exps.length})`} />
23+
{openGroup ? <ExpandLess /> : <ExpandMore />}
24+
</ListItemButton>
25+
<Collapse in={openGroup} timeout="auto" unmountOnExit>
26+
<List sx={{ pl: 2 }} component="div" disablePadding>
27+
{
28+
props.exps.sort((a, b) => experimentInfo[a.name].order - experimentInfo[b.name].order).map((exp) =>
29+
<Tooltip key={exp.name} title={exp.description}>
30+
<Stack direction={"row"} alignItems={"center"}>
31+
<ListItemText primary={"\u2022 " + exp.name} />
32+
<InfoOutlined fontSize="small" />
33+
</Stack>
34+
</Tooltip>
35+
)
36+
}
37+
</List>
38+
</Collapse>
39+
</List>
40+
)
41+
}
42+
43+
type ActiveExperimentListProps = { activeExps: { [key: string]: Experiment_Data[] } }
44+
45+
export const ActiveExperimentList: React.FC<ActiveExperimentListProps> = (props: ActiveExperimentListProps) => {
46+
const [open, setOpen] = useState(false)
47+
48+
const handleClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
49+
event.stopPropagation()
50+
setOpen(!open);
51+
};
52+
53+
return (
54+
<List disablePadding>
55+
<ListItemButton onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => handleClick(event)}>
56+
<ListItemText primary={"Active in " + Object.values(props.activeExps).flat().length + " experiments"} />
57+
{open ? <ExpandLess /> : <ExpandMore />}
58+
</ListItemButton>
59+
<Collapse in={open} timeout="auto" unmountOnExit>
60+
<List sx={{ pl: 2 }} component="div" disablePadding>
61+
{
62+
Object.entries(props.activeExps).map(([grouping, exps]: [string, Experiment_Data[]]) =>
63+
<ExperimentGroupList key={grouping} exps={exps} grouping={grouping} />
64+
)
65+
}
66+
</List>
67+
</Collapse>
68+
</List>
69+
)
70+
}
71+
72+
type ActiveCellTypesListProps = { celltypes: CellQueryValue[] }
73+
74+
export const ActiveCellTypesList: React.FC<ActiveCellTypesListProps> = (props: ActiveCellTypesListProps) => {
75+
const [open, setOpen] = useState(false)
76+
77+
const celltypes = [... new Set(props.celltypes.map(x => getCellDisplayName(x, true)))].sort()
78+
79+
const handleClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
80+
event.stopPropagation()
81+
setOpen(!open);
82+
};
83+
84+
return (
85+
<List disablePadding>
86+
<ListItemButton onClick={(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => handleClick(event)}>
87+
<ListItemText primary={"Active in " + celltypes.length + " immune cell types"} />
88+
{open ? <ExpandLess /> : <ExpandMore />}
89+
</ListItemButton>
90+
<Collapse in={open} timeout="auto" unmountOnExit>
91+
<List sx={{ pl: 2 }} component="div" disablePadding>
92+
{
93+
celltypes.map((cell: string) =>
94+
<ListItemText key={cell} primary={"\u2022 " + cell} />
95+
)
96+
}
97+
</List>
98+
</Collapse>
99+
</List>
100+
)
101+
}

immuscreen/src/common/components/HomeAppBar.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ThemeProvider } from "@mui/material/styles"
77
import Link from "next/link"
88
import nextConfig from "../../../next.config"
99
import { defaultTheme } from "../lib/themes"
10+
import Image from 'next/image'
1011

1112
const pageLinks = [
1213
{
@@ -82,7 +83,7 @@ const HomeAppBar = () => {
8283
<Container maxWidth={false}>
8384
<Toolbar disableGutters sx={{ justifyContent: "center"}}>
8485

85-
<Typography
86+
{/* <Typography
8687
variant="h5"
8788
noWrap
8889
component="a"
@@ -102,7 +103,13 @@ const HomeAppBar = () => {
102103
}}
103104
>
104105
igSCREEN
105-
</Typography>
106+
</Typography> */}
107+
<Image
108+
src="/igSCREEN.png"
109+
width={116}
110+
height={50}
111+
alt="igSCREEN logo"
112+
/>
106113

107114
<Box sx={{ flexGrow: 0, display: { xs: "inline", md: "none" } }}>
108115
{/* Hamburger Menu, open on click */}

0 commit comments

Comments
 (0)