Skip to content

Commit c5c0321

Browse files
committed
Add genotype mouseover to normal mode
1 parent 085d5d1 commit c5c0321

File tree

5 files changed

+61
-18
lines changed

5 files changed

+61
-18
lines changed

packages/core/ui/BaseTooltip.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
offset,
23
useClientPoint,
34
useFloating,
45
useInteractions,
@@ -43,6 +44,7 @@ export default function BaseTooltip({
4344
const { refs, floatingStyles, context } = useFloating({
4445
placement,
4546
strategy: 'fixed',
47+
middleware: [offset(5)],
4648
})
4749

4850
const clientPoint = useClientPoint(context, clientPointCoords)

plugins/variants/src/MultiLinearVariantRenderer/MultiVariantRenderer.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,11 @@ export default class MultiVariantBaseRenderer extends FeatureRendererType {
1515

1616
const { makeImageData } = await import('./makeImageData')
1717

18-
const rest = await renderToAbstractCanvas(
19-
width,
20-
height,
21-
renderProps,
22-
async ctx => {
23-
await makeImageData(ctx, {
24-
...renderProps,
25-
features,
26-
})
27-
return undefined
28-
},
18+
const rest = await renderToAbstractCanvas(width, height, renderProps, ctx =>
19+
makeImageData(ctx, {
20+
...renderProps,
21+
features,
22+
}),
2923
)
3024

3125
const results = await super.render({

plugins/variants/src/MultiLinearVariantRenderer/MultiVariantRendering.tsx

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
import { useRef } from 'react'
1+
import { useMemo, useRef } from 'react'
22

33
import { PrerenderedCanvas } from '@jbrowse/core/ui'
44
import { observer } from 'mobx-react'
5+
import RBush from 'rbush'
56

67
import type { Source } from '../types'
78
import type { Feature } from '@jbrowse/core/util'
89
import type { Region } from '@jbrowse/core/util/types'
910

10-
// locals
11-
1211
const MultiVariantRendering = observer(function (props: {
1312
regions: Region[]
1413
features: Map<string, Feature>
@@ -18,16 +17,51 @@ const MultiVariantRendering = observer(function (props: {
1817
sources: Source[]
1918
scrollTop: number
2019
totalHeight: number
20+
rbush: RBush<{ genotype: string }>
21+
displayModel: any
2122
onMouseLeave?: (event: React.MouseEvent) => void
2223
onMouseMove?: (event: React.MouseEvent, arg?: Feature) => void
2324
onFeatureClick?: (event: React.MouseEvent, arg?: Feature) => void
2425
}) {
2526
const { totalHeight, scrollTop } = props
27+
const { rbush, displayModel } = props
2628
const ref = useRef<HTMLDivElement>(null)
29+
const rbush2 = useMemo(
30+
() => new RBush<{ genotype: string }>().fromJSON(rbush),
31+
[rbush],
32+
)
33+
34+
function getFeatureUnderMouse(eventClientX: number, eventClientY: number) {
35+
let offsetX = 0
36+
let offsetY = 0
37+
if (ref.current) {
38+
const r = ref.current.getBoundingClientRect()
39+
offsetX = eventClientX - r.left
40+
offsetY = eventClientY - r.top
41+
}
42+
const ret = rbush2.search({
43+
minX: offsetX,
44+
maxX: offsetX + 3,
45+
minY: offsetY,
46+
maxY: offsetY + 3,
47+
})
48+
return ret[0]?.genotype
49+
}
2750

2851
return (
2952
<div
3053
ref={ref}
54+
onMouseMove={e =>
55+
displayModel.setHoveredGenotype?.(
56+
getFeatureUnderMouse(e.clientX, e.clientY),
57+
)
58+
}
59+
onMouseLeave={() => {
60+
displayModel.setHoveredGenotype?.(undefined)
61+
}}
62+
onMouseOut={() => {
63+
displayModel.setHoveredGenotype?.(undefined)
64+
}}
3165
style={{
3266
overflow: 'visible',
3367
position: 'relative',

plugins/variants/src/MultiLinearVariantRenderer/makeImageData.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { featureSpanPx } from '@jbrowse/core/util'
2+
import RBush from 'rbush'
23

34
import {
45
getColorAlleleCount,
@@ -55,20 +56,27 @@ export async function makeImageData(
5556
features.values(),
5657
minorAlleleFrequencyFilter,
5758
)
59+
const rbush = new RBush()
5860
for (const feature of mafs) {
5961
const [leftPx, rightPx] = featureSpanPx(feature, region, bpPerPx)
6062
const w = Math.max(Math.round(rightPx - leftPx), 2)
6163
const samp = feature.get('genotypes') as Record<string, string>
62-
let t = -scrollTop
64+
let y = -scrollTop
6365

6466
const s = sources.length
6567
for (let j = 0; j < s; j++) {
6668
const { name, HP } = sources[j]!
6769
const genotype = samp[name]
6870
const x = Math.floor(leftPx)
69-
const y = t
7071
const h = Math.max(rowHeight, 1)
7172
if (genotype) {
73+
rbush.insert({
74+
minX: x - f2,
75+
maxX: x + w + f2,
76+
minY: y - f2,
77+
maxY: y + h + f2,
78+
genotype,
79+
})
7280
const isPhased = genotype.includes('|')
7381
if (renderingMode === 'phased') {
7482
if (isPhased) {
@@ -83,7 +91,10 @@ export async function makeImageData(
8391
drawColorAlleleCount(alleles, ctx, x, y, w, h)
8492
}
8593
}
86-
t += rowHeight
94+
y += rowHeight
8795
}
8896
}
97+
return {
98+
rbush: rbush.toJSON(),
99+
}
89100
}

plugins/variants/src/shared/SetRowHeightDialog.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ export default function SetRowHeight({
2222
<DialogContent>
2323
<TextField
2424
value={value}
25-
onChange={event => { setValue(event.target.value) }}
25+
onChange={event => {
26+
setValue(event.target.value)
27+
}}
2628
/>
2729
</DialogContent>
2830
<DialogActions>

0 commit comments

Comments
 (0)