Skip to content

Commit

Permalink
cellefp, publications, chromosome views
Browse files Browse the repository at this point in the history
  • Loading branch information
Yukthiw committed Oct 13, 2024
1 parent adac7f1 commit f7b7ead
Show file tree
Hide file tree
Showing 14 changed files with 2,712 additions and 1,182 deletions.
41 changes: 22 additions & 19 deletions Eplant/Eplant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@
import { useEffect, useState } from 'react'
import { Outlet, useLocation, useNavigate, useParams } from 'react-router-dom'

import {
Box,
CircularProgress,
CssBaseline,
ThemeProvider,
useTheme,
} from '@mui/material'
import { Box, CircularProgress, CssBaseline, useTheme } from '@mui/material'
import { ThemeProvider } from '@mui/material/styles'

import { dark, light } from './css/theme'
import { ViewContainer } from './UI/Layout/ViewContainer'
Expand Down Expand Up @@ -71,26 +66,34 @@ const Eplant = () => {
setActiveGeneId(params.geneid)
}
} else {
setActiveGeneId('')
// Set active gene to first available if one is already loaded
if (genes.length > 0) {
setActiveGeneId(genes[0].id)
} else {
setActiveGeneId('')
}
}
setActiveViewId(location.pathname.split('/')[1])
}, [location.pathname])

// On active gene change update the gene path segment
useEffect(() => {
const pathSegments = location.pathname.split('/')
const geneid = activeGeneId ? activeGeneId : ''
if (pathSegments.length == 3) {
pathSegments[pathSegments.length - 1] = geneid
} else if (pathSegments.length == 2) {
pathSegments.push(geneid)
}
if (location.pathname !== import.meta.env.BASE_URL) {
// Only run this after initial redirect
const pathSegments = location.pathname.split('/')
const geneid = activeGeneId ? activeGeneId : ''
if (pathSegments.length == 3) {
pathSegments[pathSegments.length - 1] = geneid
} else if (pathSegments.length == 2) {
pathSegments.push(geneid)
}

const newPath = pathSegments.join('/') + location.search
if (newPath !== location.pathname + location.search) {
navigate(newPath)
const newPath = pathSegments.join('/') + location.search
if (newPath !== location.pathname + location.search) {
navigate(newPath)
}
}
}, [activeGeneId])
}, [activeGeneId, location.pathname])

return (
<ThemeProvider theme={darkMode ? dark : light}>
Expand Down
5 changes: 3 additions & 2 deletions Eplant/UI/Layout/ViewContainer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import ErrorBoundary from '@eplant/util/ErrorBoundary'
import { useViewData } from '@eplant/View/viewData'
import {
AppBar,
Box,
BoxProps,
Button,
DialogActions,
DialogContent,
Expand All @@ -22,7 +24,6 @@ import {
Toolbar,
Typography,
} from '@mui/material'
import Box, { BoxProps } from '@mui/material/Box'

import { View } from '../../../View'

Expand Down Expand Up @@ -296,7 +297,7 @@ export function ViewContainer<T, S, A>({
>
<ErrorBoundary>
{/* Only show the gene header if a gene is selected and this view belongs to the gene */}
{loading ? (
{loading && loadAmount < 100 ? (
<LoadingPage
loadingAmount={loadAmount}
gene={gene}
Expand Down
6 changes: 3 additions & 3 deletions Eplant/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createContext, useContext } from 'react'

import CellEFP from './views/CellEFP'
import { CellEFPView } from './views/CellEFP/CellEFP'
import ChromosomeViewer from './views/ChromosomeViewer'
import { ChromosomeViewerObject } from './views/ChromosomeViewer'
import DebugView from './views/DebugView'
import ExperimentEFP from './views/ExperimentEFP'
import FallbackView from './views/FallbackView'
Expand All @@ -29,12 +29,12 @@ const genericViews = [GetStartedView, FallbackView]
// Can contain views from the genericViews list too
const userViews = [
// GeneInfoView,
// PublicationViewer,
PublicationViewer,
// DebugView,
// PlantEFP,
CellEFP,
// ExperimentEFP,
// ChromosomeViewer,
ChromosomeViewerObject,
]

// List of views that are used to lookup a view by id
Expand Down
17 changes: 14 additions & 3 deletions Eplant/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,38 @@ import * as ReactDOM from 'react-dom/client'
import { createBrowserRouter, Navigate, RouterProvider } from 'react-router-dom'

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'

import ErrorBoundary from './util/ErrorBoundary'
import { CellEFPView } from './views/CellEFP/CellEFP'
import { ChromosomeView } from './views/ChromosomeViewer/ChromosomeView'
import { PublicationsView } from './views/PublicationViewer/PublicationsView'
import { Config, defaultConfig } from './config'
import Eplant from './Eplant'

import './css/index.css'

const router = createBrowserRouter([
{
path: import.meta.env.BASE_URL,
path: '/',
element: <Eplant />,
children: [
{
path: '/:geneid?',
element: <Navigate to={'/cell-efp/'} replace={true}></Navigate>,
element: <Navigate to={'/cell-efp'} replace={true}></Navigate>,
index: true,
},
{
path: '/cell-efp/:geneid?',
element: <CellEFPView></CellEFPView>,
},
{
path: '/publications/:geneid?',
element: <PublicationsView></PublicationsView>,
},
{
path: '/chromosome/:geneid?',
element: <ChromosomeView></ChromosomeView>,
},
],
errorElement: <ErrorBoundary></ErrorBoundary>,
},
Expand All @@ -40,6 +50,7 @@ function RootApp() {
<Config.Provider value={defaultConfig}>
<QueryClientProvider client={queryClient}>
<RouterProvider router={router} />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</Config.Provider>
</Provider>
Expand Down
7 changes: 7 additions & 0 deletions Eplant/util/stateUtils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { SvgIconProps } from '@mui/material'

export type StateAction<T> = {
icon: React.ReactElement<SvgIconProps>
mutation: (prevState: T) => T
description: string
}
65 changes: 44 additions & 21 deletions Eplant/views/CellEFP/CellEFP.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,45 @@
import { useEffect, useMemo, useState } from 'react'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { debounce } from 'lodash'
import { useOutletContext, useSearchParams } from 'react-router-dom'

import GeneticElement from '@eplant/GeneticElement'
import { ViewContext } from '@eplant/UI/Layout/ViewContainer/types'
import NotSupported from '@eplant/UI/Layout/ViewNotSupported'
import PanZoom from '@eplant/util/PanZoom'
import { flattenState } from '@eplant/util/router'
import { ViewDataError } from '@eplant/View/viewData'
import { Box, Typography } from '@mui/material'
import { Box, Button, Tooltip, Typography } from '@mui/material'
import { useQuery } from '@tanstack/react-query'

import Legend from '../eFP/Viewer/legend'

import { CellEFPStateActions } from './actions'
import { CellEFPDataObject } from './CellEFPDataObject'
import { CellEFPViewerData, CellEFPViewerState } from './types'

export const CellEFPView = () => {
const { geneticElement, setIsLoading, setLoadAmount } =
useOutletContext<ViewContext>()

const [searchParams, setSearchParams] = useSearchParams()
const [viewState, setViewState] = useState<CellEFPViewerState>({
transform: {
offset: {
x: parseInt(searchParams.get('x') || '0') || 0,
y: parseInt(searchParams.get('y') || '0') || 0,
},
zoom: parseInt(searchParams.get('zoom') || '0') || 0,
zoom: parseInt(searchParams.get('zoom') || '1') || 1,
},
})
const { data, isLoading, isError, error } = useQuery<CellEFPViewerData>({
queryKey: [`cellEFP-${geneticElement}`],
queryKey: [`cellEFP-${geneticElement?.id}`],
queryFn: async () => {
if (!geneticElement) {
console.log('throwing error')
throw Error('No gene')
}
const data = await cellEFPLoader(geneticElement, setLoadAmount)
console.log(data) // This shows that the data HAS been fetched
const data = cellEFPLoader(geneticElement, setLoadAmount)
return data
},
enabled: !!geneticElement,
})
console.log('data', data)
console.log('isloading', isLoading)

useEffect(() => {
const validateParams = () => {
Expand All @@ -60,20 +56,30 @@ export const CellEFPView = () => {

useEffect(() => {
setIsLoading(isLoading)
}, [isLoading])
}, [isLoading, setIsLoading])

const debouncedUpdateSearchParams = useCallback(
debounce((updatedState) => {
setSearchParams(new URLSearchParams(flattenState(updatedState)))
}, 200), // 200ms delay before updating the URL
[setSearchParams]
)

useEffect(() => {
setSearchParams(new URLSearchParams(flattenState(viewState)))
}, [viewState])
debouncedUpdateSearchParams(viewState)
return () => {
debouncedUpdateSearchParams.cancel()
}
}, [viewState, debouncedUpdateSearchParams])

const efp = useMemo(() => {
const Component = CellEFPDataObject.component
if (data) {
return <Component data={data} geneticElement={geneticElement} />
} else {
return <div></div>
return <div>Yo</div>
}
}, [geneticElement?.id])
}, [geneticElement?.id, data])

if (isLoading || isError || !data) return <></>
return (
Expand All @@ -84,11 +90,28 @@ export const CellEFPView = () => {
position: 'relative',
}}
>
<Typography variant='h6'>
{'Cell EFP'}
{': '}
{geneticElement?.id}
</Typography>
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
width: '100%',
}}
>
<Typography variant='h6'>
{'Cell EFP'}
{': '}
{geneticElement?.id}
</Typography>
{CellEFPStateActions.map((action, index) => (
<Button
key={index}
onClick={() => setViewState(action.mutation(viewState))}
>
<Tooltip title={action.description}>{action.icon}</Tooltip>
</Button>
))}
</Box>
<Box
sx={{
width: '100%',
Expand Down
21 changes: 21 additions & 0 deletions Eplant/views/CellEFP/actions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { StateAction } from '@eplant/util/stateUtils'
import YoutubeSearchedForRoundedIcon from '@mui/icons-material/YoutubeSearchedForRounded'

import { CellEFPViewerState } from './types'

export const CellEFPStateActions: StateAction<CellEFPViewerState>[] = [
{
icon: <YoutubeSearchedForRoundedIcon />,
mutation: (prevState) => ({
...prevState,
transform: {
offset: {
x: 0,
y: 0,
},
zoom: 1,
},
}),
description: 'Reset Pan/Zoom',
},
]
Loading

0 comments on commit f7b7ead

Please sign in to comment.