Skip to content

Commit 1df6ead

Browse files
Add legend to allele size plot
1 parent 2ecd966 commit 1df6ead

File tree

4 files changed

+77
-5
lines changed

4 files changed

+77
-5
lines changed

browser/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"@gnomad/ui": "2.0.0",
2424
"@hot-loader/react-dom": "^17.0.0",
2525
"@visx/axis": "^3.0.0",
26+
"@visx/legend": "^3.12.0",
2627
"@visx/scale": "^3.12.0",
2728
"@visx/shape": "^3.12.0",
2829
"core-js": "3.5.0",

browser/src/ShortTandemRepeatPage/ShortTandemRepeatAlleleSizeDistributionPlot.tsx

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { max } from 'd3-array'
2-
import { scaleBand, scaleLinear, scaleLog } from 'd3-scale'
2+
import { scaleBand, scaleLinear, scaleLog, scaleOrdinal, scaleThreshold } from 'd3-scale'
33
import React, { useMemo } from 'react'
44
import { withSize } from 'react-sizeme'
55
import styled from 'styled-components'
66
import { AxisBottom, AxisLeft } from '@visx/axis'
77
import { BarStack } from '@visx/shape'
88
import { AnyD3Scale } from '@visx/scale'
9+
import { LegendOrdinal, LegendThreshold } from '@visx/legend'
910

1011
import { TooltipAnchor } from '@gnomad/ui'
1112
import {
@@ -17,7 +18,7 @@ import {
1718
ScaleType,
1819
Sex,
1920
} from './ShortTandemRepeatPage'
20-
import { PopulationId } from '@gnomad/dataset-metadata/gnomadPopulations'
21+
import { GNOMAD_POPULATION_NAMES, PopulationId } from '@gnomad/dataset-metadata/gnomadPopulations'
2122

2223
// The 100% width/height container is necessary the component
2324
// to size to fit its container vs staying at its initial size.
@@ -36,13 +37,13 @@ const TooltipTrigger = styled.rect`
3637
`
3738

3839
const defaultColor = '#73ab3d'
39-
const colorMap: Record<string, Record<string, string>> = {
40+
const colorMap: Record<ColorBy | '', Record<string, string>> = {
4041
'': {
4142
'': defaultColor,
4243
},
4344
quality_description: {
4445
low: '#d73027',
45-
'low-medium': '#fc8d59',
46+
'medium-low': '#fc8d59',
4647
medium: '#fee08b',
4748
'medium-high': '#d9ef8b',
4849
high: '#1a9850',
@@ -60,6 +61,7 @@ const colorMap: Record<string, Record<string, string>> = {
6061
'0.8': '#66ff99',
6162
'0.9': '#33ffcc',
6263
'1.0': '#00ff00',
64+
'': defaultColor,
6365
},
6466
sex: {
6567
XX: '#F7C3CC',
@@ -77,8 +79,41 @@ const colorMap: Record<string, Record<string, string>> = {
7779
oth: '#ABB8B9',
7880
sas: '#FE9A10',
7981
},
82+
} as const
83+
84+
const qualityDescriptionLabels: Record<GenotypeQuality, string> = {
85+
low: 'Low',
86+
'medium-low': 'Medium-low',
87+
medium: 'Medium',
88+
'medium-high': 'Medium-high',
89+
high: 'High',
90+
'not-reviewed': 'Not reviewed',
91+
}
92+
93+
const qScoreLabels: Record<QScoreBin, string> = {
94+
'0.0': '0',
95+
'0.1': '0 < q ≤ 0.1',
96+
'0.2': '0.1 < q ≤ 0.2',
97+
'0.3': '0.2 < q ≤ 0.3',
98+
'0.4': '0.3 < q ≤ 0.4',
99+
'0.5': '0.4 < q ≤ 0.5',
100+
'0.6': '0.5 < q ≤ 0.6',
101+
'0.7': '0.6 < q ≤ 0.7',
102+
'0.8': '0.7 < q ≤ 0.8',
103+
'0.9': '0.8 < q ≤ 0.9',
104+
'1.0': '0.9 < q ≤ 1.0',
105+
'': 'Not reviewed',
106+
}
107+
108+
const fixedLegendLabels: Partial<Record<ColorBy, Record<string, string>>> = {
109+
quality_description: qualityDescriptionLabels,
110+
q_score: qScoreLabels,
111+
population: GNOMAD_POPULATION_NAMES,
80112
}
81113

114+
const legendLabels = (colorBy: ColorBy, keys: string[]) =>
115+
keys.map((key) => fixedLegendLabels[colorBy]?.[key] || key)
116+
82117
const colorForValue = (colorBy: ColorBy | '', value: string) =>
83118
colorMap[colorBy]?.[value] || defaultColor
84119

@@ -118,6 +153,18 @@ type Bin = Partial<Record<ColorByValue, number>> & {
118153
fullFrequency: number
119154
}
120155

156+
const LegendFromColorBy = ({ colorBy }: { colorBy: ColorBy | '' }) => {
157+
if (colorBy === '') {
158+
return null
159+
}
160+
161+
const keys = Object.keys(colorMap[colorBy])
162+
const labels = legendLabels(colorBy, keys)
163+
const colors = keys.map((key) => colorMap[colorBy][key])
164+
const scale = scaleOrdinal().domain(labels).range(colors)
165+
return <LegendOrdinal scale={scale} direction="row" />
166+
}
167+
121168
const ShortTandemRepeatAlleleSizeDistributionPlot = withSize()(
122169
({
123170
maxRepeats,
@@ -219,6 +266,7 @@ const ShortTandemRepeatAlleleSizeDistributionPlot = withSize()(
219266

220267
return (
221268
<GraphWrapper>
269+
<LegendFromColorBy colorBy={colorBy} />
222270
<svg height={binSize === 1 ? height - 20 : height} width={width}>
223271
<AxisBottom
224272
label="Repeats"

browser/src/ShortTandemRepeatPage/ShortTandemRepeatPage.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,13 @@ type ShortTandemRepeatReferenceRegion = {
3838
stop: number
3939
}
4040

41-
export type GenotypeQuality = 'low' | 'medium-low' | 'medium' | 'medium-high' | 'high'
41+
export type GenotypeQuality =
42+
| 'low'
43+
| 'medium-low'
44+
| 'medium'
45+
| 'medium-high'
46+
| 'high'
47+
| 'not-reviewed'
4248
export type QScoreBin =
4349
| '0.0'
4450
| '0.1'
@@ -51,6 +57,7 @@ export type QScoreBin =
5157
| '0.8'
5258
| '0.9'
5359
| '1.0'
60+
| ''
5461
export type ColorByValue = GenotypeQuality | QScoreBin | Sex | PopulationId | ''
5562

5663
export type AlleleSizeDistributionItem = {

pnpm-lock.yaml

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)