Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bookmark highlight to overview scale bar #4266

Merged
merged 2 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/core/ui/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ declare module '@mui/material/styles/createPalette' {
interface Palette {
tertiary: Palette['primary']
quaternary: Palette['primary']
highlight: Palette['primary']
stopCodon?: string
startCodon?: string
bases: {
Expand All @@ -19,6 +20,7 @@ declare module '@mui/material/styles/createPalette' {
interface PaletteOptions {
tertiary?: PaletteOptions['primary']
quaternary?: PaletteOptions['primary']
highlight?: PaletteOptions['primary']
stopCodon?: string
startCodon?: string
bases?: {
Expand All @@ -45,6 +47,7 @@ function stockTheme() {
secondary: { main: grape },
tertiary: refTheme.palette.augmentColor({ color: { main: forest } }),
quaternary: refTheme.palette.augmentColor({ color: { main: mandarin } }),
highlight: refTheme.palette.augmentColor({ color: { main: mandarin } }),
stopCodon: '#e22',
startCodon: '#3e3',
bases: {
Expand Down Expand Up @@ -93,6 +96,7 @@ function getDarkStockTheme() {
secondary: { main: grape },
tertiary: refTheme.palette.augmentColor({ color: { main: forest } }),
quaternary: refTheme.palette.augmentColor({ color: { main: mandarin } }),
highlight: refTheme.palette.augmentColor({ color: { main: mandarin } }),
stopCodon: '#e22',
startCodon: '#3e3',
bases: {
Expand Down Expand Up @@ -127,6 +131,7 @@ function getDarkMinimalTheme() {
secondary: { main: grey[800] },
tertiary: refTheme.palette.augmentColor({ color: { main: grey[900] } }),
quaternary: refTheme.palette.augmentColor({ color: { main: mandarin } }),
highlight: refTheme.palette.augmentColor({ color: { main: mandarin } }),
stopCodon: '#e22',
startCodon: '#3e3',
bases: {
Expand All @@ -147,6 +152,7 @@ function getMinimalTheme() {
secondary: { main: grey[800] },
tertiary: refTheme.palette.augmentColor({ color: { main: grey[900] } }),
quaternary: refTheme.palette.augmentColor({ color: { main: mandarin } }),
highlight: refTheme.palette.augmentColor({ color: { main: mandarin } }),
stopCodon: '#e22',
startCodon: '#3e3',
bases: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ const useStyles = makeStyles()({
highlight: {
height: '100%',
position: 'absolute',
textAlign: 'center',
overflow: 'hidden',
display: 'flex',
alignItems: 'start',
},
})

Expand Down Expand Up @@ -76,7 +73,11 @@ const Highlight = observer(function Highlight({ model }: { model: LGV }) {
<div
key={`${left}_${width}_${idx}`}
className={classes.highlight}
style={{ left, width, background: highlight }}
style={{
left,
width,
background: highlight,
}}
>
{showBookmarkLabels ? (
<Tooltip title={label} arrow>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React, { useEffect, useRef } from 'react'
import { observer } from 'mobx-react'
import { makeStyles } from 'tss-react/mui'
import { SessionWithWidgets, getSession, notEmpty } from '@jbrowse/core/util'
import { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel'
import { Tooltip } from '@mui/material'

// locals
import { GridBookmarkModel } from '../../model'
import { IExtendedLGV } from '../../model'

type LGV = IExtendedLGV

const useStyles = makeStyles()({
highlight: {
height: '100%',
position: 'absolute',
},
})

const OverviewHighlight = observer(function OverviewHighlight({
model,
overview,
}: {
model: LGV
overview: Base1DViewModel
}) {
const { classes } = useStyles()
const { cytobandOffset } = model
const session = getSession(model) as SessionWithWidgets

const { showBookmarkHighlights, showBookmarkLabels } = model
const assemblyNames = new Set(session.assemblyNames)

const bookmarkWidget = session.widgets.get(
'GridBookmark',
) as GridBookmarkModel

const bookmarks = useRef(bookmarkWidget?.bookmarks ?? [])

useEffect(() => {
if (!bookmarkWidget) {
const newBookmarkWidget = session.addWidget(
'GridBookmarkWidget',
'GridBookmark',
) as GridBookmarkModel
bookmarks.current = newBookmarkWidget.bookmarks
}
}, [session, bookmarkWidget])

return (
<>
{showBookmarkHighlights && bookmarks.current
? bookmarks.current
.filter(value => assemblyNames.has(value.assemblyName))
.map(r => {
const s = overview.bpToPx({
...r,
coord: r.reversed ? r.end : r.start,
})
const e = overview.bpToPx({
...r,
coord: r.reversed ? r.start : r.end,
})
return s !== undefined && e !== undefined
? {
width: Math.abs(e - s),
left: s + cytobandOffset,
highlight: r.highlight,
label: r.label,
}
: undefined
})
.filter(notEmpty)
.map(({ left, width, highlight, label }, idx) => (
<>
{showBookmarkLabels ? (
<Tooltip title={label} arrow>
<div
key={`${left}_${width}_${idx}`}
className={classes.highlight}
style={{
left,
width,
background: highlight,
borderLeft: `1px solid ${highlight}`,
borderRight: `1px solid ${highlight}`,
}}
/>
</Tooltip>
) : (
<div
key={`${left}_${width}_${idx}`}
className={classes.highlight}
style={{
left,
width,
background: highlight,
borderLeft: `1px solid ${highlight}`,
borderRight: `1px solid ${highlight}`,
}}
/>
)}
</>
))
: null}
</>
)
})

export default OverviewHighlight
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react'
import PluginManager from '@jbrowse/core/PluginManager'
import { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel'

// locals
import Highlight from './Highlight'
import OverviewHighlight from './OverviewHighlight'
import { IExtendedLGV } from '../../model'

export default function AddHighlightModelF(pluginManager: PluginManager) {
Expand All @@ -16,4 +18,21 @@ export default function AddHighlightModelF(pluginManager: PluginManager) {
]
},
)
pluginManager.addToExtensionPoint(
'LinearGenomeView-OverviewScalebarComponent',
// @ts-expect-error
(
rest: React.ReactNode[] = [],
{ model, overview }: { model: IExtendedLGV; overview: Base1DViewModel },
) => {
return [
...rest,
<OverviewHighlight
key={`overview_highlight_grid_bookmark`}
model={model}
overview={overview}
/>,
]
},
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,18 @@ const useStyles = makeStyles()(theme => ({
highlight: {
height: '100%',
position: 'absolute',
background: `${colord(theme.palette.quaternary?.main ?? 'goldenrod')
overflow: 'hidden',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason for overflow: hidden being added here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

without it, the icon on the highlight always shows (so if you're zoomed out and the highlight is a sliver you see it)

realistically, anything you're highlighting and looking at, you'd be a close enough zoom level to make use of the icon options, i think

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good. i had this idea that possibly the link icon could even be hidden if the user is not hovering over, as the user might like it hidden for e.g. screenshot. just an idea though

background: `${colord(theme.palette.highlight?.main ?? 'goldenrod')
.alpha(0.35)
.toRgbString()}`,
borderLeft: `1px solid ${theme.palette.quaternary?.main ?? 'goldenrod'}`,
borderRight: `1px solid ${theme.palette.quaternary?.main ?? 'goldenrod'}`,
},
}))

const Highlight = observer(function Highlight({ model }: { model: LGV }) {
const { classes } = useStyles()
const [open, setOpen] = useState(false)
const anchorEl = useRef(null)
const color = useTheme().palette.quaternary?.main ?? 'goldenrod'
const color = useTheme().palette.highlight?.main ?? 'goldenrod'

const session = getSession(model) as SessionWithWidgets

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ const useStyles = makeStyles()(theme => ({
highlight: {
height: '100%',
position: 'absolute',
background: `${colord(theme.palette.quaternary?.main ?? 'goldenrod')
background: `${colord(theme.palette.highlight?.main ?? 'goldenrod')
.alpha(0.35)
.toRgbString()}`,
borderLeft: `1px solid ${theme.palette.quaternary?.main ?? 'goldenrod'}`,
borderRight: `1px solid ${theme.palette.quaternary?.main ?? 'goldenrod'}`,
borderLeft: `1px solid ${theme.palette.highlight?.main ?? 'goldenrod'}`,
borderRight: `1px solid ${theme.palette.highlight?.main ?? 'goldenrod'}`,
},
}))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { observer } from 'mobx-react'

// core
import Base1DView, { Base1DViewModel } from '@jbrowse/core/util/Base1DViewModel'
import { getSession, getTickDisplayStr } from '@jbrowse/core/util'
import { getEnv, getSession, getTickDisplayStr } from '@jbrowse/core/util'
import { ContentBlock } from '@jbrowse/core/util/blockTypes'

// locals
Expand Down Expand Up @@ -201,6 +201,7 @@ const Scalebar = observer(function ({
const { classes } = useStyles()
const theme = useTheme()
const { dynamicBlocks, showCytobands, cytobandOffset } = model
const { pluginManager } = getEnv(model)
const visibleRegions = dynamicBlocks.contentBlocks
const overviewVisibleRegions = overview.dynamicBlocks

Expand Down Expand Up @@ -229,6 +230,12 @@ const Scalebar = observer(function ({
const color = showCytobands ? '#f00' : scalebarColor
const transparency = showCytobands ? 0.1 : 0.3

const additional = pluginManager.evaluateExtensionPoint(
'LinearGenomeView-OverviewScalebarComponent',
undefined,
{ model, overview },
) as React.ReactNode

return (
<div className={classes.scalebar}>
<div
Expand Down Expand Up @@ -265,6 +272,7 @@ const Scalebar = observer(function ({
)
})}
<OverviewHighlight model={model} overview={overview} />
{additional}
</div>
)
})
Expand Down
Loading