UNPKG

@jbrowse/plugin-wiggle

Version:

JBrowse 2 wiggle adapters, tracks, etc.

225 lines (224 loc) 8.63 kB
import { lazy } from 'react'; import { getConf } from '@jbrowse/core/configuration'; import { getContainingView, getSession } from '@jbrowse/core/util'; import EqualizerIcon from '@mui/icons-material/Equalizer'; import PaletteIcon from '@mui/icons-material/Palette'; import VisibilityIcon from '@mui/icons-material/Visibility'; import { types } from 'mobx-state-tree'; import { axisPropsFromTickScale } from 'react-d3-axis-mod'; import SharedWiggleMixin from '../shared/SharedWiggleMixin'; import { YSCALEBAR_LABEL_OFFSET, getScale } from '../util'; const Tooltip = lazy(() => import('./components/Tooltip')); const SetColorDialog = lazy(() => import('./components/SetColorDialog')); const rendererTypes = new Map([ ['xyplot', 'XYPlotRenderer'], ['density', 'DensityRenderer'], ['line', 'LinePlotRenderer'], ]); function stateModelFactory(pluginManager, configSchema) { return types .compose('LinearWiggleDisplay', SharedWiggleMixin(configSchema), types.model({ type: types.literal('LinearWiggleDisplay'), invertedSetting: types.maybe(types.boolean), })) .actions(self => ({ setInverted(arg) { self.invertedSetting = arg; }, })) .views(self => ({ get TooltipComponent() { return Tooltip; }, get rendererTypeName() { const name = self.rendererTypeNameSimple; const rendererType = rendererTypes.get(name); if (!rendererType) { throw new Error(`unknown renderer ${name}`); } return rendererType; }, get quantitativeStatsRelevantToCurrentZoom() { var _a; const view = getContainingView(self); return ((_a = self.stats) === null || _a === void 0 ? void 0 : _a.currStatsBpPerPx) === view.bpPerPx; }, get graphType() { return (self.rendererTypeName === 'XYPlotRenderer' || self.rendererTypeName === 'LinePlotRenderer'); }, get inverted() { var _a; return (_a = self.invertedSetting) !== null && _a !== void 0 ? _a : getConf(self, 'inverted'); }, })) .views(self => { const { renderProps: superRenderProps } = self; return { adapterProps() { const superProps = superRenderProps(); const { filters, resolution, scaleOpts } = self; return { ...superProps, rpcDriverName: self.rpcDriverName, displayModel: self, config: self.rendererConfig, displayCrossHatches: self.displayCrossHatchesSetting, scaleOpts, resolution, filters, }; }, get ticks() { const { inverted, scaleType, domain, height } = self; const minimalTicks = getConf(self, 'minimalTicks'); if (domain) { const ticks = axisPropsFromTickScale(getScale({ scaleType, domain, range: [ height - YSCALEBAR_LABEL_OFFSET, YSCALEBAR_LABEL_OFFSET, ], inverted, }), 4); return height < 100 || minimalTicks ? { ...ticks, values: domain } : ticks; } else { return undefined; } }, }; }) .views(self => ({ renderProps() { const { inverted, ticks, height } = self; const superProps = self.adapterProps(); return { ...self.adapterProps(), notReady: superProps.notReady || !self.stats, height, ticks, inverted, }; }, get fillSetting() { if (self.filled) { return 0; } else if (self.minSize === 1) { return 1; } else { return 2; } }, get quantitativeStatsReady() { const view = getContainingView(self); return (view.initialized && self.statsReadyAndRegionNotTooLarge && !self.error); }, })) .views(self => { const { trackMenuItems: superTrackMenuItems } = self; const hasRenderings = getConf(self, 'defaultRendering'); return { trackMenuItems() { return [ ...superTrackMenuItems(), { label: 'Score', icon: EqualizerIcon, subMenu: self.scoreTrackMenuItems(), }, ...(self.graphType ? [ { label: 'Inverted', type: 'checkbox', checked: self.inverted, onClick: () => { self.setInverted(!self.inverted); }, }, ] : []), ...(self.canHaveFill ? [ { label: 'Fill mode', subMenu: ['filled', 'no fill', 'no fill w/ emphasis'].map((elt, idx) => ({ label: elt, type: 'radio', checked: self.fillSetting === idx, onClick: () => { self.setFill(idx); }, })), }, ] : []), ...(hasRenderings ? [ { label: 'Renderer type', subMenu: ['xyplot', 'density', 'line'].map(key => ({ label: key, type: 'radio', checked: self.rendererTypeNameSimple === key, onClick: () => { self.setRendererType(key); }, })), }, ] : []), { label: 'Color', icon: PaletteIcon, onClick: () => { getSession(self).queueDialog(handleClose => [ SetColorDialog, { model: self, handleClose, }, ]); }, }, ...(self.graphType ? [ { type: 'checkbox', icon: VisibilityIcon, label: 'Show cross hatches', checked: self.displayCrossHatchesSetting, onClick: () => { self.toggleCrossHatches(); }, }, ] : []), ]; }, }; }) .actions(self => { const { renderSvg: superRenderSvg } = self; return { afterAttach() { ; (async () => { const { getQuantitativeStatsAutorun } = await import('../getQuantitativeStatsAutorun'); getQuantitativeStatsAutorun(self); })(); }, async renderSvg(opts) { const { renderSvg } = await import('./renderSvg'); return renderSvg(self, opts, superRenderSvg); }, }; }); } export default stateModelFactory;