From c7dc049141a1e673ede571a3e8bcf7b2467b2d44 Mon Sep 17 00:00:00 2001 From: Caroline Bridge <83305007+carolinebridge-oicr@users.noreply.github.com> Date: Fri, 8 Mar 2024 11:47:41 -0500 Subject: [PATCH] Add bookmark highlight to overview scale bar (#4266) --- packages/core/ui/theme.ts | 6 + .../components/Highlight/Highlight.tsx | 9 +- .../Highlight/OverviewHighlight.tsx | 111 ++++++++++++++++++ .../components/Highlight/index.tsx | 19 +++ .../LinearGenomeView/components/Highlight.tsx | 7 +- .../components/OverviewHighlight.tsx | 6 +- .../components/OverviewScalebar.tsx | 10 +- 7 files changed, 156 insertions(+), 12 deletions(-) create mode 100644 plugins/grid-bookmark/src/GridBookmarkWidget/components/Highlight/OverviewHighlight.tsx diff --git a/packages/core/ui/theme.ts b/packages/core/ui/theme.ts index c6c40878b1..34b8ca9553 100644 --- a/packages/core/ui/theme.ts +++ b/packages/core/ui/theme.ts @@ -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: { @@ -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?: { @@ -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: { @@ -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: { @@ -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: { @@ -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: { diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/components/Highlight/Highlight.tsx b/plugins/grid-bookmark/src/GridBookmarkWidget/components/Highlight/Highlight.tsx index b4a8635be8..f329864351 100644 --- a/plugins/grid-bookmark/src/GridBookmarkWidget/components/Highlight/Highlight.tsx +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/components/Highlight/Highlight.tsx @@ -18,10 +18,7 @@ const useStyles = makeStyles()({ highlight: { height: '100%', position: 'absolute', - textAlign: 'center', overflow: 'hidden', - display: 'flex', - alignItems: 'start', }, }) @@ -76,7 +73,11 @@ const Highlight = observer(function Highlight({ model }: { model: LGV }) {
{showBookmarkLabels ? ( diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/components/Highlight/OverviewHighlight.tsx b/plugins/grid-bookmark/src/GridBookmarkWidget/components/Highlight/OverviewHighlight.tsx new file mode 100644 index 0000000000..d651920a56 --- /dev/null +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/components/Highlight/OverviewHighlight.tsx @@ -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 ? ( + +
+ + ) : ( +
+ )} + + )) + : null} + + ) +}) + +export default OverviewHighlight diff --git a/plugins/grid-bookmark/src/GridBookmarkWidget/components/Highlight/index.tsx b/plugins/grid-bookmark/src/GridBookmarkWidget/components/Highlight/index.tsx index c837c1859c..22b9818992 100644 --- a/plugins/grid-bookmark/src/GridBookmarkWidget/components/Highlight/index.tsx +++ b/plugins/grid-bookmark/src/GridBookmarkWidget/components/Highlight/index.tsx @@ -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) { @@ -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, + , + ] + }, + ) } diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/Highlight.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/Highlight.tsx index 7b5b8bb85e..6b861051d9 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/Highlight.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/Highlight.tsx @@ -25,11 +25,10 @@ const useStyles = makeStyles()(theme => ({ highlight: { height: '100%', position: 'absolute', - background: `${colord(theme.palette.quaternary?.main ?? 'goldenrod') + overflow: 'hidden', + 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'}`, }, })) @@ -37,7 +36,7 @@ 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 const { assemblyManager } = session diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewHighlight.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewHighlight.tsx index 0aac2efedc..7da0a4f695 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewHighlight.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewHighlight.tsx @@ -18,11 +18,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'}`, }, })) diff --git a/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebar.tsx b/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebar.tsx index d092af9712..3f57c79e70 100644 --- a/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebar.tsx +++ b/plugins/linear-genome-view/src/LinearGenomeView/components/OverviewScalebar.tsx @@ -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 @@ -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 @@ -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 (
+ {additional}
) })