Skip to content

Commit

Permalink
wip(browser): update frontend types
Browse files Browse the repository at this point in the history
  • Loading branch information
rileyhgrant committed Oct 21, 2024
1 parent 1eee02f commit 7c33629
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 194 deletions.
7 changes: 1 addition & 6 deletions browser/src/GenePage/GenePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
isExac,
hasCopyNumberVariants,
isV2,
getTopLevelDataset,
} from '@gnomad/dataset-metadata/metadata'
import ConstraintTable from '../ConstraintTable/ConstraintTable'
import VariantCooccurrenceCountsTable, {
Expand Down Expand Up @@ -73,7 +72,6 @@ import {
} from '../ChartStyles'
import { logButtonClick } from '../analytics'
import { GtexTissueExpression } from './TranscriptsTissueExpression'
import { GTEX_TISSUES } from '../gtex'

export type Strand = '+' | '-'

Expand Down Expand Up @@ -527,7 +525,6 @@ const GenePage = ({ datasetId, gene, geneId }: Props) => {
<GeneTranscriptsTrack
datasetId={datasetId}
isTissueExpressionAvailable={!!gene.pext}
gtexTissues={GTEX_TISSUES[getTopLevelDataset(datasetId)]}
gene={gene}
includeNonCodingTranscripts={includeNonCodingTranscripts}
includeUTRs={includeUTRs}
Expand All @@ -539,12 +536,10 @@ const GenePage = ({ datasetId, gene, geneId }: Props) => {

{hasCodingExons && gene.chrom !== 'M' && gene.pext && (
<TissueExpressionTrack
gtexTissues={GTEX_TISSUES[getTopLevelDataset(datasetId)]}
exons={cdsCompositeExons}
expressionRegions={gene.pext.regions}
flags={gene.pext.flags}
// if a gene has pext, it also has GTEx
transcripts={gene.transcripts as TranscriptWithTissueExpression[]} // if a gene has pext,
transcripts={gene.transcripts as TranscriptWithTissueExpression[]} // if a gene has pext, it has gtex
preferredTranscriptId={preferredTranscriptId}
preferredTranscriptDescription={preferredTranscriptDescription}
/>
Expand Down
22 changes: 17 additions & 5 deletions browser/src/GenePage/GeneTranscriptsTrack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import { Track } from '@gnomad/region-viewer'
import TranscriptsTrack from '@gnomad/track-transcripts'
import { Button, Modal, TooltipAnchor } from '@gnomad/ui'

import { AllGtexTissues, TissueDetail } from '../gtex'
import { ALL_GTEX_TISSUES, GtexTissueName } from '../gtex'
import InfoButton from '../help/InfoButton'
import Link from '../Link'
import sortedTranscripts from './sortedTranscripts'
import TranscriptsTissueExpression from './TranscriptsTissueExpression'
import { Gene } from './GenePage'
import { DatasetId, hasStructuralVariants } from '../../../dataset-metadata/metadata'
import { TranscriptWithTissueExpression } from './TissueExpressionTrack'
import { GtexTissueDetail, TranscriptWithTissueExpression } from './TissueExpressionTrack'

const TranscriptsInfoWrapper = styled.div`
display: flex;
Expand All @@ -38,7 +38,6 @@ const RightPanel = styled.div`
type GeneTranscriptsTrack = {
datasetId: DatasetId
isTissueExpressionAvailable: boolean
gtexTissues: Partial<AllGtexTissues> & { [key: string]: TissueDetail | undefined }
gene: Gene
includeNonCodingTranscripts: boolean
includeUTRs: boolean
Expand All @@ -49,7 +48,6 @@ type GeneTranscriptsTrack = {
const GeneTranscriptsTrack = ({
datasetId,
isTissueExpressionAvailable,
gtexTissues,
gene,
includeNonCodingTranscripts,
includeUTRs,
Expand All @@ -59,6 +57,20 @@ const GeneTranscriptsTrack = ({
const transcriptsTrack = useRef(null)
const [showTissueExpressionModal, setShowTissueExpressionModal] = useState(false)

const gtexTissues: Partial<Record<GtexTissueName, GtexTissueDetail>> = {}
if (isTissueExpressionAvailable) {
const preferredTranscript = (gene.transcripts as TranscriptWithTissueExpression[]).find(
(transcript) => transcript.transcript_id === preferredTranscriptId
)
preferredTranscript!.gtex_tissue_expression.forEach((tissue) => {
gtexTissues[tissue.tissue as GtexTissueName] = {
fullName: ALL_GTEX_TISSUES[tissue.tissue as GtexTissueName].fullName || tissue.tissue,
color: ALL_GTEX_TISSUES[tissue.tissue as GtexTissueName].color || '#888888',
value: tissue.value,
}
})
}

const maxMeanExpression = isTissueExpressionAvailable
? max(
(gene.transcripts as TranscriptWithTissueExpression[]).map(
Expand Down Expand Up @@ -167,7 +179,7 @@ const GeneTranscriptsTrack = ({
tooltip={`Mean expression across all tissues = ${meanExpression.toFixed(
2
)} TPM\nMost expressed in ${
gtexTissues[tissueMostExpressedIn]!.fullName
gtexTissues[tissueMostExpressedIn as GtexTissueName]!.fullName
} (${maxExpression.toFixed(2)} TPM)`}
>
<rect
Expand Down
135 changes: 77 additions & 58 deletions browser/src/GenePage/TissueExpressionTrack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Track } from '@gnomad/region-viewer'
import { RegionsPlot } from '@gnomad/track-regions'
import { Badge, Button, Modal, SearchInput, Select, TooltipAnchor } from '@gnomad/ui'

import { AllGtexTissues } from '../gtex'
import { ALL_GTEX_TISSUES, GtexTissueName, GtexTissues } from '../gtex'
import InfoButton from '../help/InfoButton'

import { logButtonClick } from '../analytics'
Expand Down Expand Up @@ -68,8 +68,7 @@ const TRACK_HEIGHT = 20
const heightScale = scaleLinear().domain([0, 1]).range([0, TRACK_HEIGHT]).clamp(true)

type PextRegionsPlotProps = {
// datasetId: DatasetId
gtexTissues: Partial<AllGtexTissues>
gtexTissues: Partial<GtexTissues>
color: string
regions: {
start: number
Expand Down Expand Up @@ -154,8 +153,7 @@ type ExpressedTissue = {
}

type IndividualTissueTrackProps = {
// datasetId: DatasetId
gtexTissues: Partial<AllGtexTissues>
gtexTissues: Partial<GtexTissues>
exons: {
start: number
stop: number
Expand All @@ -169,7 +167,7 @@ type IndividualTissueTrackProps = {
maxTranscriptExpressionInTissue: number
maxMeanTranscriptExpressionInAnyTissue: number
meanTranscriptExpressionInTissue: number
tissue: string
tissue: GtexTissueName
transcriptWithMaxExpressionInTissue: {
transcript_id: string
transcript_version: string
Expand All @@ -189,13 +187,13 @@ const IndividualTissueTrack = ({
const isExpressed = expressionRegions.some(
(region: any) =>
region.tissues.find((tissueObject: ExpressedTissue) => tissueObject.tissue === tissue)
.value !== 0
?.value !== 0
)

return (
<Track
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
renderLeftPanel={() => <TissueName>{gtexTissuesForDataset[tissue].fullName}</TissueName>}
renderLeftPanel={() => <TissueName>{gtexTissues[tissue].fullName}</TissueName>}
renderRightPanel={({ width }: any) =>
width > 36 && (
<svg width={width} height={31}>
Expand Down Expand Up @@ -223,8 +221,7 @@ const IndividualTissueTrack = ({
)} (${transcriptWithMaxExpressionInTissue!.transcript_id}.${
transcriptWithMaxExpressionInTissue!.transcript_version
})`
: // @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
`Gene is not expressed in ${gtexTissuesForDataset[tissue].fullName}`
: `Gene is not expressed in ${gtexTissues[tissue]!.fullName}`
}
>
<rect x={12} y={2} width={25} height={27} fill="none" pointerEvents="visible" />
Expand Down Expand Up @@ -258,13 +255,12 @@ const IndividualTissueTrack = ({
<PlotWrapper key={tissue}>
<PextRegionsPlot
gtexTissues={gtexTissues}
// @ts-expect-error TS(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
color={gtexTissues[tissue].color}
color={gtexTissues[tissue]!.color}
regions={getPlotRegions(
expressionRegions,
(r: any) =>
r.tissues.find((tissueObject: ExpressedTissue) => tissueObject.tissue === tissue)
.value
?.value || 0
)}
scalePosition={scalePosition}
width={width}
Expand Down Expand Up @@ -330,7 +326,6 @@ export type TranscriptWithTissueExpression = Omit<GeneTranscript, 'gtex_tissue_e
}

type TissueExpressionTrackProps = {
gtexTissues: Partial<AllGtexTissues>
exons: {
start: number
stop: number
Expand All @@ -350,8 +345,13 @@ type TissueExpressionTrackProps = {
preferredTranscriptDescription?: string | React.ReactNode
}

export type GtexTissueDetail = {
fullName: string
color: string
value: number
}

const TissueExpressionTrack = ({
gtexTissues,
exons,
expressionRegions,
flags,
Expand All @@ -368,6 +368,17 @@ const TissueExpressionTrack = ({
'alphabetical'
)

const gtexTissues: Partial<Record<GtexTissueName, GtexTissueDetail>> = {}
transcripts
.find((transcript) => transcript.transcript_id === preferredTranscriptId)
?.gtex_tissue_expression.forEach((tissue) => {
gtexTissues[tissue.tissue as GtexTissueName] = {
fullName: ALL_GTEX_TISSUES[tissue.tissue as GtexTissueName].fullName || tissue.tissue,
color: ALL_GTEX_TISSUES[tissue.tissue as GtexTissueName].color || '#888888',
value: tissue.value,
}
})

type ExpressionByTissueDetails = {
maxTranscriptExpressionInTissue: number
meanTranscriptExpressionInTissue: number
Expand All @@ -386,10 +397,10 @@ const TissueExpressionTrack = ({
transcripts.forEach((transcript) => {
const expressionInTissue = transcript.gtex_tissue_expression.find(
(tissue) => tissue.tissue === tissueId
)!.value
)

if (expressionInTissue > maxTranscriptExpressionInTissue) {
maxTranscriptExpressionInTissue = expressionInTissue!
if (expressionInTissue && expressionInTissue.value > maxTranscriptExpressionInTissue) {
maxTranscriptExpressionInTissue = expressionInTissue.value
transcriptWithMaxExpressionInTissue = {
transcript_id: transcript.transcript_id,
transcript_version: transcript.transcript_version,
Expand All @@ -398,10 +409,12 @@ const TissueExpressionTrack = ({
})

const meanTranscriptExpressionInTissue = mean(
transcripts.map(
(transcript) =>
transcript.gtex_tissue_expression.find((tissue) => tissue.tissue === tissueId)!.value
)
transcripts
.map(
(transcript) =>
transcript.gtex_tissue_expression.find((tissue) => tissue.tissue === tissueId)?.value
)
.filter((value): value is number => value !== undefined)
)

return {
Expand All @@ -420,23 +433,27 @@ const TissueExpressionTrack = ({
Object.values(expressionByTissue).map((v) => v.meanTranscriptExpressionInTissue)
)!

let tissues
if (sortTissuesBy === 'mean-expression') {
tissues = Object.entries(gtexTissues)
.sort((t1, t2) => {
const t1Expression = expressionByTissue[t1[0]].meanTranscriptExpressionInTissue
const t2Expression = expressionByTissue[t2[0]].meanTranscriptExpressionInTissue
if (t1Expression === t2Expression) {
return t1[1].fullName.localeCompare(t2[1].fullName)
}
return t2Expression - t1Expression
})
.map((t: any) => t[0])
} else {
tissues = Object.entries(gtexTissues)
.sort((t1, t2) => t1[1].fullName.localeCompare(t2[1].fullName))
.map((t) => t[0])
}
const tissues =
sortTissuesBy === 'mean-expression'
? Object.entries(gtexTissues)
.sort((t1, t2) => {
const t1Expression = expressionByTissue[t1[0]].meanTranscriptExpressionInTissue
const t2Expression = expressionByTissue[t2[0]].meanTranscriptExpressionInTissue
if (t1Expression === t2Expression) {
return ALL_GTEX_TISSUES[t1[0] as GtexTissueName].fullName.localeCompare(
ALL_GTEX_TISSUES[t2[0] as GtexTissueName].fullName
)
}
return t2Expression - t1Expression
})
.map((t: any) => t[0])
: Object.entries(gtexTissues)
.sort((t1, t2) =>
ALL_GTEX_TISSUES[t1[0] as GtexTissueName].fullName.localeCompare(
ALL_GTEX_TISSUES[t2[0] as GtexTissueName].fullName
)
)
.map((t) => t[0])

const isExpressed = expressionRegions.some((region: any) => region.mean !== 0)

Expand Down Expand Up @@ -579,25 +596,27 @@ const TissueExpressionTrack = ({
}}
</Track>
{(tissueFilterText ? tissues.filter(tissuePredicate(tissueFilterText)) : tissues).map(
(tissue: any) => (
<IndividualTissueTrack
gtexTissues={gtexTissues}
key={tissue}
exons={exons}
expressionRegions={expressionRegions}
maxTranscriptExpressionInTissue={
expressionByTissue[tissue].maxTranscriptExpressionInTissue
}
maxMeanTranscriptExpressionInAnyTissue={maxMeanTranscriptExpressionInAnyTissue}
meanTranscriptExpressionInTissue={
expressionByTissue[tissue].meanTranscriptExpressionInTissue
}
transcriptWithMaxExpressionInTissue={
expressionByTissue[tissue].transcriptWithMaxExpressionInTissue
}
tissue={tissue}
/>
)
(tissue: any) => {
return (
<IndividualTissueTrack
gtexTissues={gtexTissues}
key={`${tissue}`}
exons={exons}
expressionRegions={expressionRegions}
maxTranscriptExpressionInTissue={
expressionByTissue[tissue].maxTranscriptExpressionInTissue
}
maxMeanTranscriptExpressionInAnyTissue={maxMeanTranscriptExpressionInAnyTissue}
meanTranscriptExpressionInTissue={
expressionByTissue[tissue].meanTranscriptExpressionInTissue
}
transcriptWithMaxExpressionInTissue={
expressionByTissue[tissue].transcriptWithMaxExpressionInTissue
}
tissue={tissue}
/>
)
}
)}
<span>
<Button
Expand Down
4 changes: 2 additions & 2 deletions browser/src/GenePage/TranscriptsTissueExpression.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import styled from 'styled-components'

import { Select } from '@gnomad/ui'

import { AllGtexTissues } from '../gtex'
import { GtexTissues } from '../gtex'

import sortedTranscripts from './sortedTranscripts'
import TranscriptsTissueExpressionPlot from './TranscriptsTissueExpressionPlot'
Expand All @@ -21,7 +21,7 @@ const isTranscriptCoding = (transcript: any) =>
transcript.exons.some((exon: any) => exon.feature_type === 'CDS')

type TranscriptsTissueExpressionProps = {
gtexTissues: Partial<AllGtexTissues>
gtexTissues: Partial<GtexTissues>
transcripts: TranscriptWithTissueExpression[]
includeNonCodingTranscripts: boolean
preferredTranscriptId?: string
Expand Down
Loading

0 comments on commit 7c33629

Please sign in to comment.