Skip to content

Commit

Permalink
Fix incorrect tick mark label on dotplot axes in some cases (#3924)
Browse files Browse the repository at this point in the history
  • Loading branch information
cmdcolin committed Sep 12, 2023
1 parent daf93bb commit 932ee42
Show file tree
Hide file tree
Showing 6 changed files with 935 additions and 917 deletions.
96 changes: 49 additions & 47 deletions plugins/dotplot-view/src/DotplotView/components/Axes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ const useStyles = makeStyles()(() => ({
userSelect: 'none',
},
}))

export const HorizontalAxis = observer(function ({
model,
}: {
Expand Down Expand Up @@ -55,6 +54,21 @@ export const HorizontalAxisRaw = observer(function ({
staticBlocks: hview.staticBlocks,
}

const ticks = hticks
.map(
tick =>
[
tick,
bpToPx({
refName: tick.refName,
coord: tick.base,
self: hviewSnap,
})?.offsetPx,
] as const,
)
.filter(f => f[1] !== undefined)
.map(f => [f[0], f[1]! - offsetPx] as const)

return (
<>
{dblocks
Expand All @@ -79,13 +93,7 @@ export const HorizontalAxisRaw = observer(function ({
</text>
)
})}
{hticks.map(tick => {
const x =
(bpToPx({
refName: tick.refName,
coord: tick.base,
self: hviewSnap,
})?.offsetPx || 0) - offsetPx
{ticks.map(([tick, x]) => {
return (
<line
key={`line-${JSON.stringify(tick)}`}
Expand All @@ -94,19 +102,13 @@ export const HorizontalAxisRaw = observer(function ({
y1={0}
y2={tick.type === 'major' ? 6 : 4}
strokeWidth={1}
stroke={theme.palette.divider}
stroke={theme.palette.grey[400]}
/>
)
})}
{hticks
.filter(tick => tick.type === 'major')
.map(tick => {
const x =
(bpToPx({
refName: tick.refName,
coord: tick.base,
self: hviewSnap,
})?.offsetPx || 0) - offsetPx
{ticks
.filter(t => t[0].type === 'major')
.map(([tick, x]) => {
const y = 0
return x > 10 ? (
<text
Expand Down Expand Up @@ -136,7 +138,6 @@ export const HorizontalAxisRaw = observer(function ({
</>
)
})

export const VerticalAxis = observer(function ({
model,
}: {
Expand Down Expand Up @@ -166,6 +167,21 @@ export const VerticalAxisRaw = observer(function ({
width,
staticBlocks: vview.staticBlocks,
}
const ticks = vticks
.map(
tick =>
[
tick,
bpToPx({
refName: tick.refName,
coord: tick.base,
self: vviewSnap,
})?.offsetPx,
] as const,
)
.filter(f => f[1] !== undefined)
.map(f => [f[0], f[1]! - offsetPx] as const)

return (
<>
{dblocks
Expand All @@ -189,34 +205,20 @@ export const VerticalAxisRaw = observer(function ({
</text>
)
})}
{vticks.map(tick => {
const y =
(bpToPx({
refName: tick.refName,
coord: tick.base,
self: vviewSnap,
})?.offsetPx || 0) - offsetPx
return (
<line
key={`line-${JSON.stringify(tick)}`}
y1={viewHeight - y}
y2={viewHeight - y}
x1={borderX}
x2={borderX - (tick.type === 'major' ? 6 : 4)}
strokeWidth={1}
stroke={theme.palette.divider}
/>
)
})}
{vticks
.filter(tick => tick.type === 'major')
.map(tick => {
const y =
(bpToPx({
refName: tick.refName,
coord: tick.base,
self: vviewSnap,
})?.offsetPx || 0) - offsetPx
{ticks.map(([tick, y]) => (
<line
key={`line-${JSON.stringify(tick)}`}
y1={viewHeight - y}
y2={viewHeight - y}
x1={borderX}
x2={borderX - (tick.type === 'major' ? 6 : 4)}
strokeWidth={1}
stroke={theme.palette.grey[400]}
/>
))}
{ticks
.filter(t => t[0].type === 'major')
.map(([tick, y]) => {
return y > 10 ? (
<text
y={viewHeight - y - 3}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { DotplotViewModel } from '../model'
import ImportForm from './ImportForm'
import Header from './Header'
import Grid from './Grid'
import { HorizontalAxis, VerticalAxis } from './Axes'
import { VerticalAxis, HorizontalAxis } from './Axes'
import { TooltipWhereClicked, TooltipWhereMouseovered } from './DotplotTooltip'

const blank = { left: 0, top: 0, width: 0, height: 0 }
Expand Down
169 changes: 74 additions & 95 deletions plugins/dotplot-view/src/DotplotView/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { useState } from 'react'
import React from 'react'
import { IconButton, Typography } from '@mui/material'
import { observer } from 'mobx-react'
import { makeStyles } from 'tss-react/mui'
import { getBpDisplayStr } from '@jbrowse/core/util'
import { Menu } from '@jbrowse/core/ui'
import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'

// icons
import ZoomOut from '@mui/icons-material/ZoomOut'
Expand All @@ -18,9 +18,6 @@ import DotplotWarnings from './DotplotWarnings'
import PanButtons from './PanButtons'

const useStyles = makeStyles()({
iconButton: {
margin: 5,
},
bp: {
display: 'flex',
alignItems: 'center',
Expand All @@ -36,113 +33,95 @@ const useStyles = makeStyles()({
})

const DotplotControls = observer(({ model }: { model: DotplotViewModel }) => {
const { classes } = useStyles()
const [menuAnchorEl, setMenuAnchorEl] = useState<HTMLElement>()
return (
<div>
<IconButton onClick={model.zoomOutButton} className={classes.iconButton}>
<IconButton onClick={model.zoomOutButton}>
<ZoomOut />
</IconButton>

<IconButton onClick={model.zoomInButton} className={classes.iconButton}>
<IconButton onClick={model.zoomInButton}>
<ZoomIn />
</IconButton>

<IconButton
onClick={() => model.activateTrackSelector()}
className={classes.iconButton}
title="Open track selector"
data-testid="circular_track_select"
>
<TrackSelectorIcon />
</IconButton>

<IconButton
onClick={event => setMenuAnchorEl(event.currentTarget)}
className={classes.iconButton}
<CascadingMenuButton
menuItems={[
{
onClick: () => model.squareView(),
label: 'Square view - same base pairs per pixel',
},
{
onClick: () => model.squareViewProportional(),
label: 'Rectanglularize view - same total bp',
},
{
onClick: () => model.showAllRegions(),
label: 'Show all regions',
},
{
onClick: () => model.setDrawCigar(!model.drawCigar),
type: 'checkbox',
label: 'Draw CIGAR',
checked: model.drawCigar,
},
{
onClick: () => model.setShowPanButtons(!model.showPanButtons),
label: 'Show pan buttons',
type: 'checkbox',
checked: model.showPanButtons,
},
{
label: 'Click and drag mode',
subMenu: [
{
onClick: () => model.setCursorMode('move'),
label: 'Pan by default, select region when ctrl key is held',
icon: CursorMove,
type: 'radio',
checked: model.cursorMode === 'move',
},
{
onClick: () => model.setCursorMode('crosshair'),
label: 'Select region by default, pan when ctrl key is held',
icon: CursorMouse,
type: 'radio',
checked: model.cursorMode === 'crosshair',
},
],
},
{
label: 'Wheel scroll mode',
subMenu: [
{
onClick: () => model.setWheelMode('pan'),
label: 'Pans view',
type: 'radio',
checked: model.wheelMode === 'pan',
},
{
onClick: () => model.setWheelMode('zoom'),
label: 'Zooms view',
type: 'radio',
checked: model.wheelMode === 'zoom',
},
{
onClick: () => model.setWheelMode('none'),
label: 'Disable',
type: 'radio',
checked: model.wheelMode === 'none',
},
],
},
]}
>
<MoreVert />
</IconButton>

{menuAnchorEl ? (
<Menu
anchorEl={menuAnchorEl}
open
onMenuItemClick={(_event, callback) => {
callback()
setMenuAnchorEl(undefined)
}}
menuItems={[
{
onClick: () => model.squareView(),
label: 'Square view - same base pairs per pixel',
},
{
onClick: () => model.squareViewProportional(),
label: 'Rectanglularize view - same total bp',
},
{
onClick: () => model.showAllRegions(),
label: 'Show all regions',
},
{
onClick: () => model.setDrawCigar(!model.drawCigar),
type: 'checkbox',
label: 'Draw CIGAR',
checked: model.drawCigar,
},
{
onClick: () => model.setShowPanButtons(!model.showPanButtons),
label: 'Show pan buttons',
type: 'checkbox',
checked: model.showPanButtons,
},
{
label: 'Click and drag mode',
subMenu: [
{
onClick: () => model.setCursorMode('move'),
label: 'Pan by default, select region when ctrl key is held',
icon: CursorMove,
type: 'radio',
checked: model.cursorMode === 'move',
},
{
onClick: () => model.setCursorMode('crosshair'),
label: 'Select region by default, pan when ctrl key is held',
icon: CursorMouse,
type: 'radio',
checked: model.cursorMode === 'crosshair',
},
],
},
{
label: 'Wheel scroll mode',
subMenu: [
{
onClick: () => model.setWheelMode('pan'),
label: 'Pans view',
type: 'radio',
checked: model.wheelMode === 'pan',
},
{
onClick: () => model.setWheelMode('zoom'),
label: 'Zooms view',
type: 'radio',
checked: model.wheelMode === 'zoom',
},
{
onClick: () => model.setWheelMode('none'),
label: 'Disable',
type: 'radio',
checked: model.wheelMode === 'none',
},
],
},
]}
onClose={() => setMenuAnchorEl(undefined)}
/>
) : null}
</CascadingMenuButton>
</div>
)
})
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

Large diffs are not rendered by default.

0 comments on commit 932ee42

Please sign in to comment.