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 authored 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
Loading
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.

Loading

0 comments on commit 932ee42

Please sign in to comment.