Skip to content

Commit

Permalink
Manually set row height on matrix
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Jan 28, 2025
1 parent 26d2e10 commit e6c5eb4
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const Crosshair = observer(function ({
const { hoveredGenotype, height, scrollTop, rowHeight, sources } = model
const { width } = getContainingView(model) as LinearGenomeViewModel
const source = sources?.[Math.floor(mouseY / rowHeight)]
const y = mouseY - scrollTop
const y = mouseY - lineZoneHeight - scrollTop
return source ? (
<div className={classes.rel}>
<svg
Expand Down
82 changes: 1 addition & 81 deletions plugins/variants/src/MultiLinearVariantDisplay/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,105 +22,25 @@ export function stateModelFactory(configSchema: AnyConfigurationSchemaType) {
* #property
*/
type: types.literal('MultiLinearVariantDisplay'),

/**
* #property
* used only if autoHeight is false
*/
rowHeightSetting: types.optional(types.number, 11),

/**
* #property
* adjust to height of track/display
*/
autoHeight: false,
/**
* #property
*/
minorAlleleFrequencyFilter: types.optional(types.number, 0),
}),
)
.actions(self => ({
/**
* #action
*/
setRowHeight(arg: number) {
self.rowHeightSetting = arg
},
/**
* #action
*/
setAutoHeight(arg: boolean) {
self.autoHeight = arg
},
}))

.views(self => ({
.views(() => ({
/**
* #getter
*/
get rendererTypeName() {
return 'MultiVariantRenderer'
},
/**
* #getter
*/
get rowHeight() {
const { autoHeight, sources, rowHeightSetting, height } = self
return autoHeight ? height / (sources?.length || 1) : rowHeightSetting
},
}))
.views(self => {
return {
get canDisplayLabels() {
return self.rowHeight > 8 && self.showSidebarLabelsSetting
},
/**
* #getter
*/
get totalHeight() {
return self.rowHeight * (self.sources?.length || 1)
},
}
})

.views(self => {
const { trackMenuItems: superTrackMenuItems } = self
return {
/**
* #method
*/
trackMenuItems() {
return [
...superTrackMenuItems(),
{
label: 'Adjust to height of display?',
type: 'checkbox',
checked: self.autoHeight,
onClick: () => {
self.setAutoHeight(!self.autoHeight)
},
},
]
},

renderProps() {
const superProps = self.adapterProps()
return {
...superProps,
notReady:
superProps.notReady || !self.sources || !self.featuresVolatile,
height: self.height,
totalHeight: self.totalHeight,
renderingMode: self.renderingMode,
minorAlleleFrequencyFilter: self.minorAlleleFrequencyFilter,
rowHeight: self.rowHeight,
sources: self.sources,
scrollTop: self.scrollTop,
}
},
}
})
.actions(self => {
const { renderSvg: superRenderSvg } = self
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,23 @@ const Crosshair = observer(function ({
model: MultiLinearVariantMatrixDisplayModel
}) {
const { classes } = useStyles()
const { hoveredGenotype, lineZoneHeight, height, rowHeight, sources } = model
const { hoveredGenotype, lineZoneHeight, totalHeight, rowHeight, sources } =
model
const { width } = getContainingView(model) as LinearGenomeViewModel
const source = sources?.[Math.floor((mouseY - lineZoneHeight) / rowHeight)]
const yoff = mouseY - lineZoneHeight
return source ? (
<>
<svg className={classes.cursor} width={width} height={height}>
<line x1={0} x2={width} y1={mouseY} y2={mouseY} stroke="black" />
<line x1={mouseX} x2={mouseX} y1={0} y2={height} stroke="black" />
<svg
className={classes.cursor}
width={width}
height={totalHeight}
style={{
top: lineZoneHeight,
}}
>
<line x1={0} x2={width} y1={yoff} y2={yoff} stroke="black" />
<line x1={mouseX} x2={mouseX} y1={0} y2={totalHeight} stroke="black" />
</svg>
<MultiVariantTooltip source={{ ...source, hoveredGenotype }} />
</>
Expand Down
14 changes: 12 additions & 2 deletions plugins/variants/src/MultiLinearVariantMatrixDisplay/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ export default function stateModelFactory(
* #property
*/
type: types.literal('LinearVariantMatrixDisplay'),

/**
* #property
*/
rowHeightSetting: types.optional(types.number, 1),
}),
)

Expand All @@ -38,16 +43,21 @@ export default function stateModelFactory(
* #getter
*/
get totalHeight() {
return self.height - self.lineZoneHeight
return self.autoHeight
? self.height - self.lineZoneHeight
: (self.sources?.length || 1) * self.rowHeightSetting
},

/**
* #getter
*/
get rowHeight() {
return this.totalHeight / (self.sources?.length || 1)
return self.autoHeight
? self.height / (self.sources?.length || 1)
: self.rowHeightSetting
},
}))

.views(self => ({
/**
* #method
Expand Down
88 changes: 88 additions & 0 deletions plugins/variants/src/shared/MultiVariantBaseModel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getSession } from '@jbrowse/core/util'
import { stopStopToken } from '@jbrowse/core/util/stopToken'
import { linearBareDisplayStateModelFactory } from '@jbrowse/plugin-linear-genome-view'
import FilterListIcon from '@mui/icons-material/FilterList'
import HeightIcon from '@mui/icons-material/Height'
import PaletteIcon from '@mui/icons-material/Palette'
import VisibilityIcon from '@mui/icons-material/Visibility'
import deepEqual from 'fast-deep-equal'
Expand All @@ -19,6 +20,7 @@ import type { Instance } from 'mobx-state-tree'
const SetColorDialog = lazy(() => import('../shared/SetColorDialog'))
const MAFFilterDialog = lazy(() => import('../shared/MAFFilterDialog'))
const ClusterDialog = lazy(() => import('../shared/ClusterDialog'))
const SetRowHeightDialog = lazy(() => import('../shared/SetRowHeightDialog'))

/**
* #stateModel MultiVariantBaseModel
Expand Down Expand Up @@ -61,6 +63,18 @@ export default function MultiVariantBaseModelF(
* #property
*/
renderingMode: types.optional(types.string, 'alleleCount'),

/**
* #property
* used only if autoHeight is false
*/
rowHeightSetting: types.optional(types.number, 1),

/**
* #property
* used only if autoHeight is false
*/
autoHeight: true,
}),
)
.volatile(() => ({
Expand Down Expand Up @@ -98,6 +112,12 @@ export default function MultiVariantBaseModelF(
hoveredGenotype: undefined as string | undefined,
}))
.actions(self => ({
/**
* #action
*/
setRowHeight(arg: number) {
self.rowHeightSetting = arg
},
/**
* #action
*/
Expand Down Expand Up @@ -158,6 +178,12 @@ export default function MultiVariantBaseModelF(
setPhasedMode(arg: string) {
self.renderingMode = arg
},
/**
* #action
*/
setAutoHeight(arg: boolean) {
self.autoHeight = arg
},
/**
* #action
*/
Expand Down Expand Up @@ -229,6 +255,13 @@ export default function MultiVariantBaseModelF(
} = self

return {
/**
* #getter
*/
get rowHeight() {
const { sources, autoHeight, rowHeightSetting, height } = self
return autoHeight ? height / (sources?.length || 1) : rowHeightSetting
},
/**
* #method
*/
Expand Down Expand Up @@ -257,6 +290,33 @@ export default function MultiVariantBaseModelF(
},
},

{
label: 'Row height',
icon: HeightIcon,
subMenu: [
{
label: 'Manually set row height',
disabled: self.autoHeight,
onClick: () => {
getSession(self).queueDialog(handleClose => [
SetRowHeightDialog,
{
model: self,
handleClose,
},
])
},
},
{
label: 'Auto-adjust to display height',
type: 'checkbox',
checked: self.autoHeight,
onClick: () => {
self.setAutoHeight(!self.autoHeight)
},
},
],
},
{
label: 'Color by',
icon: PaletteIcon,
Expand Down Expand Up @@ -329,6 +389,34 @@ export default function MultiVariantBaseModelF(
},
}
})
.views(self => ({
get canDisplayLabels() {
return self.rowHeight > 8 && self.showSidebarLabelsSetting
},
/**
* #getter
*/
get totalHeight() {
return self.rowHeight * (self.sources?.length || 1)
},
}))
.views(self => ({
renderProps() {
const superProps = self.adapterProps()
return {
...superProps,
notReady:
superProps.notReady || !self.sources || !self.featuresVolatile,
height: self.height,
totalHeight: self.totalHeight,
renderingMode: self.renderingMode,
minorAlleleFrequencyFilter: self.minorAlleleFrequencyFilter,
rowHeight: self.rowHeight,
sources: self.sources,
scrollTop: self.scrollTop,
}
},
}))
}

export type MultiVariantBaseStateModel = ReturnType<
Expand Down
51 changes: 51 additions & 0 deletions plugins/variants/src/shared/SetRowHeightDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { useState } from 'react'

import { Dialog } from '@jbrowse/core/ui'
import { Button, DialogActions, DialogContent, TextField } from '@mui/material'

import type { Source } from '../types'

export default function SetRowHeight({
model,
handleClose,
}: {
model: {
rowHeight?: Source[]
setRowHeight: (arg: number) => void
}
handleClose: () => void
}) {
const [value, setValue] = useState<string>(`${model.rowHeight}`)

return (
<Dialog open title="Set row height" onClose={handleClose}>
<DialogContent>
<TextField
value={value}
onChange={event => { setValue(event.target.value) }}
/>
</DialogContent>
<DialogActions>
<Button
disabled={Number.isNaN(+value)}
variant="contained"
onClick={() => {
model.setRowHeight(+value)
handleClose()
}}
>
Submit
</Button>
<Button
variant="contained"
color="secondary"
onClick={() => {
handleClose()
}}
>
Cancel
</Button>
</DialogActions>
</Dialog>
)
}

0 comments on commit e6c5eb4

Please sign in to comment.