@jbrowse/plugin-dotplot-view 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/dist/ComparativeRenderer/index.d.ts +27 -0
- package/dist/ComparativeRenderer/index.js +59 -0
- package/dist/ComparativeRenderer/index.js.map +1 -0
- package/dist/DotplotDisplay/components/DotplotDisplay.d.ts +8 -0
- package/dist/DotplotDisplay/components/DotplotDisplay.js +24 -0
- package/dist/DotplotDisplay/components/DotplotDisplay.js.map +1 -0
- package/dist/DotplotDisplay/index.d.ts +12 -0
- package/dist/DotplotDisplay/index.js +48 -0
- package/dist/DotplotDisplay/index.js.map +1 -0
- package/dist/DotplotDisplay/renderDotplotBlock.d.ts +11 -0
- package/dist/DotplotDisplay/renderDotplotBlock.js +57 -0
- package/dist/DotplotDisplay/renderDotplotBlock.js.map +1 -0
- package/dist/DotplotDisplay/stateModelFactory.d.ts +138 -0
- package/dist/DotplotDisplay/stateModelFactory.js +165 -0
- package/dist/DotplotDisplay/stateModelFactory.js.map +1 -0
- package/dist/DotplotReadVsRef/DotplotReadVsRef.d.ts +3 -0
- package/dist/DotplotReadVsRef/DotplotReadVsRef.js +102 -0
- package/dist/DotplotReadVsRef/DotplotReadVsRef.js.map +1 -0
- package/dist/DotplotReadVsRef/index.d.ts +2 -0
- package/dist/DotplotReadVsRef/index.js +42 -0
- package/dist/DotplotReadVsRef/index.js.map +1 -0
- package/dist/DotplotRenderer/ComparativeRenderRpc.d.ts +27 -0
- package/dist/DotplotRenderer/ComparativeRenderRpc.js +59 -0
- package/dist/DotplotRenderer/ComparativeRenderRpc.js.map +1 -0
- package/dist/DotplotRenderer/DotplotRenderer.d.ts +69 -0
- package/dist/DotplotRenderer/DotplotRenderer.js +274 -0
- package/dist/DotplotRenderer/DotplotRenderer.js.map +1 -0
- package/dist/DotplotRenderer/components/DotplotRendering.d.ts +5 -0
- package/dist/DotplotRenderer/components/DotplotRendering.js +13 -0
- package/dist/DotplotRenderer/components/DotplotRendering.js.map +1 -0
- package/dist/DotplotRenderer/configSchema.d.ts +61 -0
- package/dist/DotplotRenderer/configSchema.js +83 -0
- package/dist/DotplotRenderer/configSchema.js.map +1 -0
- package/dist/DotplotRenderer/index.d.ts +3 -0
- package/dist/DotplotRenderer/index.js +17 -0
- package/dist/DotplotRenderer/index.js.map +1 -0
- package/dist/DotplotView/1dview.d.ts +307 -0
- package/dist/DotplotView/1dview.js +95 -0
- package/dist/DotplotView/1dview.js.map +1 -0
- package/dist/DotplotView/blockTypes.d.ts +61 -0
- package/dist/DotplotView/blockTypes.js +117 -0
- package/dist/DotplotView/blockTypes.js.map +1 -0
- package/dist/DotplotView/components/Axes.d.ts +14 -0
- package/dist/DotplotView/components/Axes.js +127 -0
- package/dist/DotplotView/components/Axes.js.map +1 -0
- package/dist/DotplotView/components/CursorIcon.d.ts +4 -0
- package/dist/DotplotView/components/CursorIcon.js +19 -0
- package/dist/DotplotView/components/CursorIcon.js.map +1 -0
- package/dist/DotplotView/components/DotplotTooltip.d.ts +19 -0
- package/dist/DotplotView/components/DotplotTooltip.js +128 -0
- package/dist/DotplotView/components/DotplotTooltip.js.map +1 -0
- package/dist/DotplotView/components/DotplotView.d.ts +6 -0
- package/dist/DotplotView/components/DotplotView.js +272 -0
- package/dist/DotplotView/components/DotplotView.js.map +1 -0
- package/dist/DotplotView/components/DotplotWarnings.d.ts +6 -0
- package/dist/DotplotView/components/DotplotWarnings.js +40 -0
- package/dist/DotplotView/components/DotplotWarnings.js.map +1 -0
- package/dist/DotplotView/components/ExportSvgDialog.d.ts +8 -0
- package/dist/DotplotView/components/ExportSvgDialog.js +76 -0
- package/dist/DotplotView/components/ExportSvgDialog.js.map +1 -0
- package/dist/DotplotView/components/Grid.d.ts +10 -0
- package/dist/DotplotView/components/Grid.js +60 -0
- package/dist/DotplotView/components/Grid.js.map +1 -0
- package/dist/DotplotView/components/Header.d.ts +10 -0
- package/dist/DotplotView/components/Header.js +168 -0
- package/dist/DotplotView/components/Header.js.map +1 -0
- package/dist/DotplotView/components/ImportCustomTrack.d.ts +11 -0
- package/dist/DotplotView/components/ImportCustomTrack.js +180 -0
- package/dist/DotplotView/components/ImportCustomTrack.js.map +1 -0
- package/dist/DotplotView/components/ImportForm.d.ts +6 -0
- package/dist/DotplotView/components/ImportForm.js +121 -0
- package/dist/DotplotView/components/ImportForm.js.map +1 -0
- package/dist/DotplotView/components/ImportSyntenyTrackSelector.d.ts +9 -0
- package/dist/DotplotView/components/ImportSyntenyTrackSelector.js +69 -0
- package/dist/DotplotView/components/ImportSyntenyTrackSelector.js.map +1 -0
- package/dist/DotplotView/components/PanButtons.d.ts +6 -0
- package/dist/DotplotView/components/PanButtons.js +60 -0
- package/dist/DotplotView/components/PanButtons.js.map +1 -0
- package/dist/DotplotView/components/WarningDialog.d.ts +16 -0
- package/dist/DotplotView/components/WarningDialog.js +41 -0
- package/dist/DotplotView/components/WarningDialog.js.map +1 -0
- package/dist/DotplotView/components/util.d.ts +19 -0
- package/dist/DotplotView/components/util.js +90 -0
- package/dist/DotplotView/components/util.js.map +1 -0
- package/dist/DotplotView/index.d.ts +2 -0
- package/dist/DotplotView/index.js +44 -0
- package/dist/DotplotView/index.js.map +1 -0
- package/dist/DotplotView/model.d.ts +616 -0
- package/dist/DotplotView/model.js +647 -0
- package/dist/DotplotView/model.js.map +1 -0
- package/dist/DotplotView/svgcomponents/SVGBackground.d.ts +5 -0
- package/dist/DotplotView/svgcomponents/SVGBackground.js +13 -0
- package/dist/DotplotView/svgcomponents/SVGBackground.js.map +1 -0
- package/dist/DotplotView/svgcomponents/SVGDotplotView.d.ts +2 -0
- package/dist/DotplotView/svgcomponents/SVGDotplotView.js +47 -0
- package/dist/DotplotView/svgcomponents/SVGDotplotView.js.map +1 -0
- package/dist/LaunchDotplotView.d.ts +2 -0
- package/dist/LaunchDotplotView.js +45 -0
- package/dist/LaunchDotplotView.js.map +1 -0
- package/dist/ServerSideRenderedBlockContent.d.ts +12 -0
- package/dist/ServerSideRenderedBlockContent.js +87 -0
- package/dist/ServerSideRenderedBlockContent.js.map +1 -0
- package/dist/ServerSideSyntenyRendering.d.ts +23 -0
- package/dist/ServerSideSyntenyRendering.js +54 -0
- package/dist/ServerSideSyntenyRendering.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/util.d.ts +9 -0
- package/dist/util.js +9 -0
- package/dist/util.js.map +1 -0
- package/esm/ComparativeRenderer/index.d.ts +27 -0
- package/esm/ComparativeRenderer/index.js +53 -0
- package/esm/ComparativeRenderer/index.js.map +1 -0
- package/esm/DotplotDisplay/components/DotplotDisplay.d.ts +8 -0
- package/esm/DotplotDisplay/components/DotplotDisplay.js +19 -0
- package/esm/DotplotDisplay/components/DotplotDisplay.js.map +1 -0
- package/esm/DotplotDisplay/index.d.ts +12 -0
- package/esm/DotplotDisplay/index.js +41 -0
- package/esm/DotplotDisplay/index.js.map +1 -0
- package/esm/DotplotDisplay/renderDotplotBlock.d.ts +11 -0
- package/esm/DotplotDisplay/renderDotplotBlock.js +49 -0
- package/esm/DotplotDisplay/renderDotplotBlock.js.map +1 -0
- package/esm/DotplotDisplay/stateModelFactory.d.ts +138 -0
- package/esm/DotplotDisplay/stateModelFactory.js +158 -0
- package/esm/DotplotDisplay/stateModelFactory.js.map +1 -0
- package/esm/DotplotReadVsRef/DotplotReadVsRef.d.ts +3 -0
- package/esm/DotplotReadVsRef/DotplotReadVsRef.js +98 -0
- package/esm/DotplotReadVsRef/DotplotReadVsRef.js.map +1 -0
- package/esm/DotplotReadVsRef/index.d.ts +2 -0
- package/esm/DotplotReadVsRef/index.js +36 -0
- package/esm/DotplotReadVsRef/index.js.map +1 -0
- package/esm/DotplotRenderer/ComparativeRenderRpc.d.ts +27 -0
- package/esm/DotplotRenderer/ComparativeRenderRpc.js +53 -0
- package/esm/DotplotRenderer/ComparativeRenderRpc.js.map +1 -0
- package/esm/DotplotRenderer/DotplotRenderer.d.ts +69 -0
- package/esm/DotplotRenderer/DotplotRenderer.js +268 -0
- package/esm/DotplotRenderer/DotplotRenderer.js.map +1 -0
- package/esm/DotplotRenderer/components/DotplotRendering.d.ts +5 -0
- package/esm/DotplotRenderer/components/DotplotRendering.js +8 -0
- package/esm/DotplotRenderer/components/DotplotRendering.js.map +1 -0
- package/esm/DotplotRenderer/configSchema.d.ts +61 -0
- package/esm/DotplotRenderer/configSchema.js +81 -0
- package/esm/DotplotRenderer/configSchema.js.map +1 -0
- package/esm/DotplotRenderer/index.d.ts +3 -0
- package/esm/DotplotRenderer/index.js +12 -0
- package/esm/DotplotRenderer/index.js.map +1 -0
- package/esm/DotplotView/1dview.d.ts +307 -0
- package/esm/DotplotView/1dview.js +87 -0
- package/esm/DotplotView/1dview.js.map +1 -0
- package/esm/DotplotView/blockTypes.d.ts +61 -0
- package/esm/DotplotView/blockTypes.js +109 -0
- package/esm/DotplotView/blockTypes.js.map +1 -0
- package/esm/DotplotView/components/Axes.d.ts +14 -0
- package/esm/DotplotView/components/Axes.js +121 -0
- package/esm/DotplotView/components/Axes.js.map +1 -0
- package/esm/DotplotView/components/CursorIcon.d.ts +4 -0
- package/esm/DotplotView/components/CursorIcon.js +11 -0
- package/esm/DotplotView/components/CursorIcon.js.map +1 -0
- package/esm/DotplotView/components/DotplotTooltip.d.ts +19 -0
- package/esm/DotplotView/components/DotplotTooltip.js +101 -0
- package/esm/DotplotView/components/DotplotTooltip.js.map +1 -0
- package/esm/DotplotView/components/DotplotView.d.ts +6 -0
- package/esm/DotplotView/components/DotplotView.js +244 -0
- package/esm/DotplotView/components/DotplotView.js.map +1 -0
- package/esm/DotplotView/components/DotplotWarnings.d.ts +6 -0
- package/esm/DotplotView/components/DotplotWarnings.js +15 -0
- package/esm/DotplotView/components/DotplotWarnings.js.map +1 -0
- package/esm/DotplotView/components/ExportSvgDialog.d.ts +8 -0
- package/esm/DotplotView/components/ExportSvgDialog.js +50 -0
- package/esm/DotplotView/components/ExportSvgDialog.js.map +1 -0
- package/esm/DotplotView/components/Grid.d.ts +10 -0
- package/esm/DotplotView/components/Grid.js +53 -0
- package/esm/DotplotView/components/Grid.js.map +1 -0
- package/esm/DotplotView/components/Header.d.ts +10 -0
- package/esm/DotplotView/components/Header.js +140 -0
- package/esm/DotplotView/components/Header.js.map +1 -0
- package/esm/DotplotView/components/ImportCustomTrack.d.ts +11 -0
- package/esm/DotplotView/components/ImportCustomTrack.js +152 -0
- package/esm/DotplotView/components/ImportCustomTrack.js.map +1 -0
- package/esm/DotplotView/components/ImportForm.d.ts +6 -0
- package/esm/DotplotView/components/ImportForm.js +93 -0
- package/esm/DotplotView/components/ImportForm.js.map +1 -0
- package/esm/DotplotView/components/ImportSyntenyTrackSelector.d.ts +9 -0
- package/esm/DotplotView/components/ImportSyntenyTrackSelector.js +44 -0
- package/esm/DotplotView/components/ImportSyntenyTrackSelector.js.map +1 -0
- package/esm/DotplotView/components/PanButtons.d.ts +6 -0
- package/esm/DotplotView/components/PanButtons.js +55 -0
- package/esm/DotplotView/components/PanButtons.js.map +1 -0
- package/esm/DotplotView/components/WarningDialog.d.ts +16 -0
- package/esm/DotplotView/components/WarningDialog.js +36 -0
- package/esm/DotplotView/components/WarningDialog.js.map +1 -0
- package/esm/DotplotView/components/util.d.ts +19 -0
- package/esm/DotplotView/components/util.js +83 -0
- package/esm/DotplotView/components/util.js.map +1 -0
- package/esm/DotplotView/index.d.ts +2 -0
- package/esm/DotplotView/index.js +15 -0
- package/esm/DotplotView/index.js.map +1 -0
- package/esm/DotplotView/model.d.ts +616 -0
- package/esm/DotplotView/model.js +616 -0
- package/esm/DotplotView/model.js.map +1 -0
- package/esm/DotplotView/svgcomponents/SVGBackground.d.ts +5 -0
- package/esm/DotplotView/svgcomponents/SVGBackground.js +7 -0
- package/esm/DotplotView/svgcomponents/SVGBackground.js.map +1 -0
- package/esm/DotplotView/svgcomponents/SVGDotplotView.d.ts +2 -0
- package/esm/DotplotView/svgcomponents/SVGDotplotView.js +40 -0
- package/esm/DotplotView/svgcomponents/SVGDotplotView.js.map +1 -0
- package/esm/LaunchDotplotView.d.ts +2 -0
- package/esm/LaunchDotplotView.js +42 -0
- package/esm/LaunchDotplotView.js.map +1 -0
- package/esm/ServerSideRenderedBlockContent.d.ts +12 -0
- package/esm/ServerSideRenderedBlockContent.js +62 -0
- package/esm/ServerSideRenderedBlockContent.js.map +1 -0
- package/esm/ServerSideSyntenyRendering.d.ts +23 -0
- package/esm/ServerSideSyntenyRendering.js +29 -0
- package/esm/ServerSideSyntenyRendering.js.map +1 -0
- package/esm/index.d.ts +7 -0
- package/esm/index.js +38 -0
- package/esm/index.js.map +1 -0
- package/esm/util.d.ts +9 -0
- package/esm/util.js +5 -0
- package/esm/util.js.map +1 -0
- package/package.json +69 -0
- package/src/ComparativeRenderer/index.ts +87 -0
- package/src/DotplotDisplay/components/DotplotDisplay.tsx +34 -0
- package/src/DotplotDisplay/index.ts +48 -0
- package/src/DotplotDisplay/renderDotplotBlock.ts +60 -0
- package/src/DotplotDisplay/stateModelFactory.tsx +196 -0
- package/src/DotplotReadVsRef/DotplotReadVsRef.ts +115 -0
- package/src/DotplotReadVsRef/index.ts +50 -0
- package/src/DotplotRenderer/ComparativeRenderRpc.ts +87 -0
- package/src/DotplotRenderer/DotplotRenderer.ts +328 -0
- package/src/DotplotRenderer/__image_snapshots__/linear-synteny-renderer-test-ts-test-rendering-a-simple-synteny-from-fake-data-1-snap.png +0 -0
- package/src/DotplotRenderer/components/DotplotRendering.tsx +12 -0
- package/src/DotplotRenderer/configSchema.ts +92 -0
- package/src/DotplotRenderer/index.ts +16 -0
- package/src/DotplotView/1dview.ts +98 -0
- package/src/DotplotView/blockTypes.ts +140 -0
- package/src/DotplotView/components/Axes.tsx +246 -0
- package/src/DotplotView/components/CursorIcon.tsx +24 -0
- package/src/DotplotView/components/DotplotTooltip.tsx +163 -0
- package/src/DotplotView/components/DotplotView.tsx +348 -0
- package/src/DotplotView/components/DotplotWarnings.tsx +26 -0
- package/src/DotplotView/components/ExportSvgDialog.tsx +129 -0
- package/src/DotplotView/components/Grid.tsx +112 -0
- package/src/DotplotView/components/Header.tsx +182 -0
- package/src/DotplotView/components/ImportCustomTrack.tsx +262 -0
- package/src/DotplotView/components/ImportForm.tsx +209 -0
- package/src/DotplotView/components/ImportSyntenyTrackSelector.tsx +90 -0
- package/src/DotplotView/components/PanButtons.tsx +93 -0
- package/src/DotplotView/components/WarningDialog.tsx +74 -0
- package/src/DotplotView/components/util.ts +118 -0
- package/src/DotplotView/index.ts +16 -0
- package/src/DotplotView/model.test.ts +17 -0
- package/src/DotplotView/model.ts +719 -0
- package/src/DotplotView/svgcomponents/SVGBackground.tsx +21 -0
- package/src/DotplotView/svgcomponents/SVGDotplotView.tsx +68 -0
- package/src/LaunchDotplotView.ts +63 -0
- package/src/ServerSideRenderedBlockContent.tsx +86 -0
- package/src/ServerSideSyntenyRendering.tsx +54 -0
- package/src/index.ts +41 -0
- package/src/util.ts +14 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readConfObject,
|
|
3
|
+
AnyConfigurationModel,
|
|
4
|
+
} from '@jbrowse/core/configuration'
|
|
5
|
+
import {
|
|
6
|
+
renameRegionsIfNeeded,
|
|
7
|
+
renderToAbstractCanvas,
|
|
8
|
+
Region,
|
|
9
|
+
Feature,
|
|
10
|
+
} from '@jbrowse/core/util'
|
|
11
|
+
import { bpToPx } from '@jbrowse/core/util/Base1DUtils'
|
|
12
|
+
import { getSnapshot } from 'mobx-state-tree'
|
|
13
|
+
import ComparativeRenderer, {
|
|
14
|
+
RenderArgsDeserialized,
|
|
15
|
+
RenderArgs,
|
|
16
|
+
} from '@jbrowse/core/pluggableElementTypes/renderers/ComparativeServerSideRendererType'
|
|
17
|
+
import { MismatchParser } from '@jbrowse/plugin-alignments'
|
|
18
|
+
|
|
19
|
+
// locals
|
|
20
|
+
import { Dotplot1DView, Dotplot1DViewModel } from '../DotplotView/model'
|
|
21
|
+
import { createJBrowseTheme } from '@jbrowse/core/ui'
|
|
22
|
+
|
|
23
|
+
const { parseCigar } = MismatchParser
|
|
24
|
+
|
|
25
|
+
export interface DotplotRenderArgsDeserialized extends RenderArgsDeserialized {
|
|
26
|
+
height: number
|
|
27
|
+
width: number
|
|
28
|
+
highResolutionScaling: number
|
|
29
|
+
view: {
|
|
30
|
+
hview: Dotplot1DViewModel
|
|
31
|
+
vview: Dotplot1DViewModel
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface DotplotRenderArgs extends RenderArgs {
|
|
36
|
+
adapterConfig: AnyConfigurationModel
|
|
37
|
+
sessionId: string
|
|
38
|
+
view: {
|
|
39
|
+
hview: { displayedRegions: Region[] }
|
|
40
|
+
vview: { displayedRegions: Region[] }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const r = 'fell outside of range due to CIGAR string'
|
|
45
|
+
const lt = '(less than min coordinate of feature)'
|
|
46
|
+
const gt = '(greater than max coordinate of feature)'
|
|
47
|
+
const fudgeFactor = 1 // allow 1px fuzzyness before warn
|
|
48
|
+
|
|
49
|
+
function drawCir(ctx: CanvasRenderingContext2D, x: number, y: number, r = 1) {
|
|
50
|
+
ctx.beginPath()
|
|
51
|
+
ctx.arc(x, y, r / 2, 0, 2 * Math.PI)
|
|
52
|
+
ctx.fill()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default class DotplotRenderer extends ComparativeRenderer {
|
|
56
|
+
supportsSVG = true
|
|
57
|
+
|
|
58
|
+
async renameRegionsIfNeeded(args: DotplotRenderArgs) {
|
|
59
|
+
const pm = this.pluginManager
|
|
60
|
+
const assemblyManager = pm.rootModel?.session?.assemblyManager
|
|
61
|
+
|
|
62
|
+
const { view, sessionId, adapterConfig } = args
|
|
63
|
+
|
|
64
|
+
async function process(regions?: Region[]) {
|
|
65
|
+
if (!assemblyManager) {
|
|
66
|
+
throw new Error('No assembly manager provided')
|
|
67
|
+
}
|
|
68
|
+
const result = await renameRegionsIfNeeded(assemblyManager, {
|
|
69
|
+
sessionId,
|
|
70
|
+
adapterConfig,
|
|
71
|
+
regions,
|
|
72
|
+
})
|
|
73
|
+
return result.regions
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
view.hview.displayedRegions = await process(view.hview.displayedRegions)
|
|
77
|
+
view.vview.displayedRegions = await process(view.vview.displayedRegions)
|
|
78
|
+
|
|
79
|
+
return args
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async drawDotplot(
|
|
83
|
+
ctx: CanvasRenderingContext2D,
|
|
84
|
+
props: DotplotRenderArgsDeserialized & { views: Dotplot1DViewModel[] },
|
|
85
|
+
) {
|
|
86
|
+
const { config, views, height, drawCigar, theme } = props
|
|
87
|
+
const color = readConfObject(config, 'color')
|
|
88
|
+
const posColor = readConfObject(config, 'posColor')
|
|
89
|
+
const negColor = readConfObject(config, 'negColor')
|
|
90
|
+
const colorBy = readConfObject(config, 'colorBy')
|
|
91
|
+
const lineWidth = readConfObject(config, 'lineWidth')
|
|
92
|
+
const thresholds = readConfObject(config, 'thresholds')
|
|
93
|
+
const palette = readConfObject(config, 'thresholdsPalette')
|
|
94
|
+
const isCallback = config.color.isCallback
|
|
95
|
+
const [hview, vview] = views
|
|
96
|
+
const db1 = hview.dynamicBlocks.contentBlocks[0]?.offsetPx
|
|
97
|
+
const db2 = vview.dynamicBlocks.contentBlocks[0]?.offsetPx
|
|
98
|
+
const warnings = [] as { message: string; effect: string }[]
|
|
99
|
+
ctx.lineWidth = lineWidth
|
|
100
|
+
|
|
101
|
+
// we operate on snapshots of these attributes of the hview/vview because
|
|
102
|
+
// it is significantly faster than accessing the mobx objects
|
|
103
|
+
const { bpPerPx: hBpPerPx } = hview
|
|
104
|
+
const { bpPerPx: vBpPerPx } = vview
|
|
105
|
+
|
|
106
|
+
function clampWithWarnX(
|
|
107
|
+
num: number,
|
|
108
|
+
min: number,
|
|
109
|
+
max: number,
|
|
110
|
+
feature: Feature,
|
|
111
|
+
) {
|
|
112
|
+
const strand = feature.get('strand') || 1
|
|
113
|
+
if (strand === -1) {
|
|
114
|
+
;[max, min] = [min, max]
|
|
115
|
+
}
|
|
116
|
+
if (num < min - fudgeFactor) {
|
|
117
|
+
let start = feature.get('start')
|
|
118
|
+
let end = feature.get('end')
|
|
119
|
+
const refName = feature.get('refName')
|
|
120
|
+
if (strand === -1) {
|
|
121
|
+
;[end, start] = [start, end]
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
warnings.push({
|
|
125
|
+
message: `feature at (X ${refName}:${start}-${end}) ${r} ${lt}`,
|
|
126
|
+
effect: 'clipped the feature',
|
|
127
|
+
})
|
|
128
|
+
return min
|
|
129
|
+
}
|
|
130
|
+
if (num > max + fudgeFactor) {
|
|
131
|
+
const strand = feature.get('strand') || 1
|
|
132
|
+
const start = strand === 1 ? feature.get('start') : feature.get('end')
|
|
133
|
+
const end = strand === 1 ? feature.get('end') : feature.get('start')
|
|
134
|
+
const refName = feature.get('refName')
|
|
135
|
+
|
|
136
|
+
warnings.push({
|
|
137
|
+
message: `feature at (X ${refName}:${start}-${end}) ${r} ${gt}`,
|
|
138
|
+
effect: 'clipped the feature',
|
|
139
|
+
})
|
|
140
|
+
return max
|
|
141
|
+
}
|
|
142
|
+
return num
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function clampWithWarnY(
|
|
146
|
+
num: number,
|
|
147
|
+
min: number,
|
|
148
|
+
max: number,
|
|
149
|
+
feature: Feature,
|
|
150
|
+
) {
|
|
151
|
+
if (num < min - fudgeFactor) {
|
|
152
|
+
const mate = feature.get('mate')
|
|
153
|
+
const { refName, start, end } = mate
|
|
154
|
+
warnings.push({
|
|
155
|
+
message: `feature at (Y ${refName}:${start}-${end}) ${r} ${lt}`,
|
|
156
|
+
effect: 'clipped the feature',
|
|
157
|
+
})
|
|
158
|
+
return min
|
|
159
|
+
}
|
|
160
|
+
if (num > max + fudgeFactor) {
|
|
161
|
+
const mate = feature.get('mate')
|
|
162
|
+
const { refName, start, end } = mate
|
|
163
|
+
|
|
164
|
+
warnings.push({
|
|
165
|
+
message: `feature at (Y ${refName}:${start}-${end}) ${r} ${gt}`,
|
|
166
|
+
effect: 'clipped the feature',
|
|
167
|
+
})
|
|
168
|
+
return max
|
|
169
|
+
}
|
|
170
|
+
return num
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const hsnap = {
|
|
174
|
+
...getSnapshot(hview),
|
|
175
|
+
staticBlocks: hview.staticBlocks,
|
|
176
|
+
width: hview.width,
|
|
177
|
+
}
|
|
178
|
+
const vsnap = {
|
|
179
|
+
...getSnapshot(vview),
|
|
180
|
+
staticBlocks: vview.staticBlocks,
|
|
181
|
+
width: vview.width,
|
|
182
|
+
}
|
|
183
|
+
const t = createJBrowseTheme(theme)
|
|
184
|
+
hview.features?.forEach(feature => {
|
|
185
|
+
const strand = feature.get('strand') || 1
|
|
186
|
+
const start = strand === 1 ? feature.get('start') : feature.get('end')
|
|
187
|
+
const end = strand === 1 ? feature.get('end') : feature.get('start')
|
|
188
|
+
const refName = feature.get('refName')
|
|
189
|
+
const mate = feature.get('mate')
|
|
190
|
+
const mateRef = mate.refName
|
|
191
|
+
|
|
192
|
+
let r
|
|
193
|
+
if (colorBy === 'identity') {
|
|
194
|
+
const identity = feature.get('identity')
|
|
195
|
+
for (let i = 0; i < thresholds.length; i++) {
|
|
196
|
+
if (identity > +thresholds[i]) {
|
|
197
|
+
r = palette[i]
|
|
198
|
+
break
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
} else if (colorBy === 'meanQueryIdentity') {
|
|
202
|
+
r = `hsl(${feature.get('meanScore') * 200},100%,40%)`
|
|
203
|
+
} else if (colorBy === 'mappingQuality') {
|
|
204
|
+
r = `hsl(${feature.get('mappingQual')},100%,40%)`
|
|
205
|
+
} else if (colorBy === 'strand') {
|
|
206
|
+
r = strand === -1 ? negColor : posColor
|
|
207
|
+
} else if (colorBy === 'default') {
|
|
208
|
+
r = isCallback
|
|
209
|
+
? readConfObject(config, 'color', { feature })
|
|
210
|
+
: color === '#f0f'
|
|
211
|
+
? t.palette.text.primary
|
|
212
|
+
: color
|
|
213
|
+
}
|
|
214
|
+
ctx.fillStyle = r
|
|
215
|
+
ctx.strokeStyle = r
|
|
216
|
+
|
|
217
|
+
const b10 = bpToPx({ self: hsnap, refName, coord: start })
|
|
218
|
+
const b20 = bpToPx({ self: hsnap, refName, coord: end })
|
|
219
|
+
const e10 = bpToPx({ self: vsnap, refName: mateRef, coord: mate.start })
|
|
220
|
+
const e20 = bpToPx({ self: vsnap, refName: mateRef, coord: mate.end })
|
|
221
|
+
if (
|
|
222
|
+
b10 !== undefined &&
|
|
223
|
+
b20 !== undefined &&
|
|
224
|
+
e10 !== undefined &&
|
|
225
|
+
e20 !== undefined
|
|
226
|
+
) {
|
|
227
|
+
const b1 = b10.offsetPx - db1
|
|
228
|
+
const b2 = b20.offsetPx - db1
|
|
229
|
+
const e1 = e10.offsetPx - db2
|
|
230
|
+
const e2 = e20.offsetPx - db2
|
|
231
|
+
if (Math.abs(b1 - b2) <= 4 && Math.abs(e1 - e2) <= 4) {
|
|
232
|
+
drawCir(ctx, b1, height - e1, lineWidth)
|
|
233
|
+
} else {
|
|
234
|
+
let currX = b1
|
|
235
|
+
let currY = e1
|
|
236
|
+
const cigar = feature.get('CIGAR')
|
|
237
|
+
if (drawCigar && cigar) {
|
|
238
|
+
const cigarOps = parseCigar(cigar)
|
|
239
|
+
|
|
240
|
+
ctx.beginPath()
|
|
241
|
+
ctx.moveTo(currX, height - currY)
|
|
242
|
+
|
|
243
|
+
for (let i = 0; i < cigarOps.length; i += 2) {
|
|
244
|
+
const val = +cigarOps[i]
|
|
245
|
+
const op = cigarOps[i + 1]
|
|
246
|
+
if (op === 'M' || op === '=' || op === 'X') {
|
|
247
|
+
currX += (val / hBpPerPx) * strand
|
|
248
|
+
currY += val / vBpPerPx
|
|
249
|
+
} else if (op === 'D' || op === 'N') {
|
|
250
|
+
currX += (val / hBpPerPx) * strand
|
|
251
|
+
} else if (op === 'I') {
|
|
252
|
+
currY += val / vBpPerPx
|
|
253
|
+
}
|
|
254
|
+
currX = clampWithWarnX(currX, b1, b2, feature)
|
|
255
|
+
currY = clampWithWarnY(currY, e1, e2, feature)
|
|
256
|
+
ctx.lineTo(currX, height - currY)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
ctx.stroke()
|
|
260
|
+
} else {
|
|
261
|
+
ctx.beginPath()
|
|
262
|
+
ctx.moveTo(b1, height - e1)
|
|
263
|
+
ctx.lineTo(b2, height - e2)
|
|
264
|
+
ctx.stroke()
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
} else {
|
|
268
|
+
if (warnings.length <= 5) {
|
|
269
|
+
if (b10 === undefined || b20 === undefined) {
|
|
270
|
+
warnings.push({
|
|
271
|
+
message: `feature at (X ${refName}:${start}-${end}) not plotted, fell outside of range`,
|
|
272
|
+
effect: 'feature not rendered',
|
|
273
|
+
})
|
|
274
|
+
} else {
|
|
275
|
+
warnings.push({
|
|
276
|
+
message: `feature at (Y ${mateRef}:${mate.start}-${mate.end}) not plotted, fell outside of range`,
|
|
277
|
+
effect: 'feature not rendered',
|
|
278
|
+
})
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
return { warnings }
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
async render(renderProps: DotplotRenderArgsDeserialized) {
|
|
288
|
+
const {
|
|
289
|
+
width,
|
|
290
|
+
height,
|
|
291
|
+
view: { hview, vview },
|
|
292
|
+
} = renderProps
|
|
293
|
+
const dimensions = [width, height]
|
|
294
|
+
const views = [hview, vview].map((snap, idx) => {
|
|
295
|
+
const view = Dotplot1DView.create(snap)
|
|
296
|
+
view.setVolatileWidth(dimensions[idx])
|
|
297
|
+
return view
|
|
298
|
+
})
|
|
299
|
+
const target = views[0]
|
|
300
|
+
const feats = await this.getFeatures({
|
|
301
|
+
...renderProps,
|
|
302
|
+
regions: target.dynamicBlocks.contentBlocks,
|
|
303
|
+
})
|
|
304
|
+
target.setFeatures(feats)
|
|
305
|
+
|
|
306
|
+
const ret = await renderToAbstractCanvas(width, height, renderProps, ctx =>
|
|
307
|
+
this.drawDotplot(ctx, { ...renderProps, views }),
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
const results = await super.render({
|
|
311
|
+
...renderProps,
|
|
312
|
+
...ret,
|
|
313
|
+
height,
|
|
314
|
+
width,
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
return {
|
|
318
|
+
...results,
|
|
319
|
+
...ret,
|
|
320
|
+
height,
|
|
321
|
+
width,
|
|
322
|
+
offsetX: views[0].dynamicBlocks.blocks[0]?.offsetPx || 0,
|
|
323
|
+
offsetY: views[1].dynamicBlocks.blocks[0]?.offsetPx || 0,
|
|
324
|
+
bpPerPxX: views[0].bpPerPx,
|
|
325
|
+
bpPerPxY: views[1].bpPerPx,
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { PrerenderedCanvas } from '@jbrowse/core/ui'
|
|
3
|
+
import { observer } from 'mobx-react'
|
|
4
|
+
|
|
5
|
+
// locals
|
|
6
|
+
import { DotplotRenderArgsDeserialized } from '../DotplotRenderer'
|
|
7
|
+
|
|
8
|
+
function DotplotRendering(props: DotplotRenderArgsDeserialized) {
|
|
9
|
+
return <PrerenderedCanvas {...props} />
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default observer(DotplotRendering)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { ConfigurationSchema } from '@jbrowse/core/configuration'
|
|
2
|
+
import { types } from 'mobx-state-tree'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* #config DotplotRenderer
|
|
6
|
+
* #category renderer
|
|
7
|
+
*/
|
|
8
|
+
function x() {} // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
9
|
+
|
|
10
|
+
export default ConfigurationSchema(
|
|
11
|
+
'DotplotRenderer',
|
|
12
|
+
{
|
|
13
|
+
/**
|
|
14
|
+
* #slot
|
|
15
|
+
*/
|
|
16
|
+
color: {
|
|
17
|
+
type: 'color',
|
|
18
|
+
description:
|
|
19
|
+
'the color of each feature in a synteny, used with colorBy:default',
|
|
20
|
+
defaultValue: '#f0f',
|
|
21
|
+
contextVariable: ['feature'],
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* #slot
|
|
26
|
+
*/
|
|
27
|
+
posColor: {
|
|
28
|
+
type: 'color',
|
|
29
|
+
description: 'the color for forward alignments, used with colorBy:strand',
|
|
30
|
+
defaultValue: 'blue',
|
|
31
|
+
},
|
|
32
|
+
/**
|
|
33
|
+
* #slot
|
|
34
|
+
*/
|
|
35
|
+
negColor: {
|
|
36
|
+
type: 'color',
|
|
37
|
+
description: 'the color for reverse alignments, used with colorBy:strand',
|
|
38
|
+
defaultValue: 'red',
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* #slot
|
|
43
|
+
*/
|
|
44
|
+
lineWidth: {
|
|
45
|
+
type: 'number',
|
|
46
|
+
description: 'width of the lines to be drawn',
|
|
47
|
+
defaultValue: 2.5, // 2.5 is similar to D-GENIES
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* #slot
|
|
52
|
+
*/
|
|
53
|
+
colorBy: {
|
|
54
|
+
type: 'stringEnum',
|
|
55
|
+
model: types.enumeration('colorBy', [
|
|
56
|
+
'identity',
|
|
57
|
+
'meanQueryIdentity',
|
|
58
|
+
'mappingQuality',
|
|
59
|
+
'strand',
|
|
60
|
+
'default',
|
|
61
|
+
]),
|
|
62
|
+
description: `Color by options:<br/>
|
|
63
|
+
<ul>
|
|
64
|
+
<li>"identity" - the identity of the particular hit, similar to D-GENIES, use the other config slots 'thresholds' and 'thresholdsPalette' to define colors for this setting</li>
|
|
65
|
+
<li>"meanQueryIdentity" - calculates the weighted mean identity (weighted by alignment length) of all the hits that the query maps to (e.g. if the query is split aligned to many target, uses their weighted mean. can help show patterns of more related and distant synteny after WGD)</li>
|
|
66
|
+
<li>"mappingQuality" - uses mapping quality from PAF, some adapters don't have this setting</li>
|
|
67
|
+
<li>"strand" - colors negative alignments with negColor and positive alignments with posColor</li>
|
|
68
|
+
<li>"default" - uses the 'color' config slot</li>
|
|
69
|
+
</ul>`,
|
|
70
|
+
defaultValue: 'default',
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* #slot
|
|
75
|
+
*/
|
|
76
|
+
thresholdsPalette: {
|
|
77
|
+
type: 'stringArray',
|
|
78
|
+
defaultValue: ['#094b09', '#2ebd40', '#d5670b', '#ffd84b'],
|
|
79
|
+
description: 'threshold colors, used with colorBy:identity',
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* #slot
|
|
84
|
+
*/
|
|
85
|
+
thresholds: {
|
|
86
|
+
type: 'stringArray',
|
|
87
|
+
defaultValue: ['0.75', '0.5', '0.25', '0'],
|
|
88
|
+
description: 'threshold breakpoints, used with colorBy:identity',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{ explicitlyTyped: true },
|
|
92
|
+
)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import PluginManager from '@jbrowse/core/PluginManager'
|
|
2
|
+
import ReactComponent from './components/DotplotRendering'
|
|
3
|
+
import DotplotRenderer from './DotplotRenderer'
|
|
4
|
+
import configSchema from './configSchema'
|
|
5
|
+
|
|
6
|
+
export default (pluginManager: PluginManager) => {
|
|
7
|
+
pluginManager.addRendererType(
|
|
8
|
+
() =>
|
|
9
|
+
new DotplotRenderer({
|
|
10
|
+
name: 'DotplotRenderer',
|
|
11
|
+
configSchema: configSchema,
|
|
12
|
+
ReactComponent,
|
|
13
|
+
pluginManager,
|
|
14
|
+
}),
|
|
15
|
+
)
|
|
16
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { getParent, Instance } from 'mobx-state-tree'
|
|
2
|
+
import { observable } from 'mobx'
|
|
3
|
+
import Base1DView from '@jbrowse/core/util/Base1DViewModel'
|
|
4
|
+
import calculateDynamicBlocks from '@jbrowse/core/util/calculateDynamicBlocks'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* #stateModel Dotplot1DView
|
|
8
|
+
* ref https://mobx-state-tree.js.org/concepts/volatiles on volatile state used here
|
|
9
|
+
*/
|
|
10
|
+
function x() {} // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
11
|
+
|
|
12
|
+
const Dotplot1DView = Base1DView.extend(self => {
|
|
13
|
+
const scaleFactor = observable.box(1)
|
|
14
|
+
return {
|
|
15
|
+
views: {
|
|
16
|
+
/**
|
|
17
|
+
* #getter
|
|
18
|
+
* this uses padding=false and elision=false
|
|
19
|
+
*/
|
|
20
|
+
get dynamicBlocks() {
|
|
21
|
+
return calculateDynamicBlocks(self, false, false)
|
|
22
|
+
},
|
|
23
|
+
/**
|
|
24
|
+
* #getter
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
get scaleFactor() {
|
|
28
|
+
return scaleFactor.get()
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* #getter
|
|
33
|
+
*/
|
|
34
|
+
get maxBpPerPx() {
|
|
35
|
+
return self.totalBp / (self.width - 50)
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* #getter
|
|
40
|
+
*/
|
|
41
|
+
get minBpPerPx() {
|
|
42
|
+
return 1 / 50
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* #getter
|
|
47
|
+
*/
|
|
48
|
+
get maxOffset() {
|
|
49
|
+
return self.displayedRegionsTotalPx - self.width * 0.2
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* #getter
|
|
54
|
+
*/
|
|
55
|
+
get minOffset() {
|
|
56
|
+
return -self.width * 0.8
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
actions: {
|
|
60
|
+
/**
|
|
61
|
+
* #action
|
|
62
|
+
*/
|
|
63
|
+
setScaleFactor(n: number) {
|
|
64
|
+
scaleFactor.set(n)
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* #action
|
|
69
|
+
*/
|
|
70
|
+
center() {
|
|
71
|
+
const centerBp = self.totalBp / 2
|
|
72
|
+
const centerPx = centerBp / self.bpPerPx
|
|
73
|
+
self.scrollTo(centerPx - self.width / 2)
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const DotplotHView = Dotplot1DView.extend(self => ({
|
|
80
|
+
views: {
|
|
81
|
+
get width() {
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
83
|
+
return getParent<any>(self).viewWidth
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
}))
|
|
87
|
+
|
|
88
|
+
const DotplotVView = Dotplot1DView.extend(self => ({
|
|
89
|
+
views: {
|
|
90
|
+
get width() {
|
|
91
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
92
|
+
return getParent<any>(self).viewHeight
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
}))
|
|
96
|
+
|
|
97
|
+
export { DotplotVView, DotplotHView, Dotplot1DView }
|
|
98
|
+
export type Dotplot1DViewModel = Instance<typeof Dotplot1DView>
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
type Func<T> = (value: BaseBlock, index: number, array: BaseBlock[]) => T
|
|
2
|
+
|
|
3
|
+
export class BlockSet {
|
|
4
|
+
constructor(public blocks: BaseBlock[] = []) {}
|
|
5
|
+
|
|
6
|
+
push(block: BaseBlock) {
|
|
7
|
+
if (block instanceof ElidedBlock && this.blocks.length > 0) {
|
|
8
|
+
const lastBlock = this.blocks.at(-1)
|
|
9
|
+
if (lastBlock instanceof ElidedBlock) {
|
|
10
|
+
lastBlock.push(block)
|
|
11
|
+
return
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
this.blocks.push(block)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getBlocks() {
|
|
19
|
+
return this.blocks
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
map<T, U = this>(func: Func<T>, thisarg?: U) {
|
|
23
|
+
// eslint-disable-next-line unicorn/no-array-method-this-argument
|
|
24
|
+
return this.blocks.map(func, thisarg)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
forEach<T, U = this>(func: Func<T>, thisarg?: U) {
|
|
28
|
+
// eslint-disable-next-line unicorn/no-array-method-this-argument
|
|
29
|
+
return this.blocks.forEach(func, thisarg)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get length() {
|
|
33
|
+
return this.blocks.length
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get totalWidthPx() {
|
|
37
|
+
return this.blocks.length
|
|
38
|
+
? this.blocks.map(blocks => blocks.widthPx).reduce((a, b) => a + b)
|
|
39
|
+
: 0
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
get offsetPx() {
|
|
43
|
+
return this.blocks.length ? this.blocks[0].offsetPx : 0
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get contentBlocks() {
|
|
47
|
+
return this.blocks.filter(block => block instanceof ContentBlock)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export class BaseBlock {
|
|
52
|
+
public reversed?: boolean
|
|
53
|
+
|
|
54
|
+
public refName: string
|
|
55
|
+
|
|
56
|
+
public start: number
|
|
57
|
+
|
|
58
|
+
public end: number
|
|
59
|
+
|
|
60
|
+
public assemblyName: string
|
|
61
|
+
|
|
62
|
+
public key: string
|
|
63
|
+
|
|
64
|
+
public widthPx = 0
|
|
65
|
+
|
|
66
|
+
public offsetPx = 0
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* a block that should be shown as filled with data
|
|
70
|
+
*/
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
72
|
+
constructor(data: any) {
|
|
73
|
+
Object.assign(this, data)
|
|
74
|
+
this.assemblyName = data.assemblyName
|
|
75
|
+
this.refName = data.refName
|
|
76
|
+
this.start = data.start
|
|
77
|
+
this.end = data.end
|
|
78
|
+
this.key = data.key
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* rename the reference sequence of this block and return a new one
|
|
83
|
+
*
|
|
84
|
+
* @param refName -
|
|
85
|
+
* @returns either a new block with a renamed reference sequence,
|
|
86
|
+
* or the same block, if the ref name is not actually different
|
|
87
|
+
*/
|
|
88
|
+
renameReference(refName: string) {
|
|
89
|
+
if (this.refName && refName !== this.refName) {
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
91
|
+
return new (this.constructor as any)({ ...this, refName })
|
|
92
|
+
}
|
|
93
|
+
return this
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
toRegion() {
|
|
97
|
+
return {
|
|
98
|
+
refName: this.refName,
|
|
99
|
+
start: this.start,
|
|
100
|
+
end: this.end,
|
|
101
|
+
assemblyName: this.assemblyName,
|
|
102
|
+
reversed: this.reversed,
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export class ContentBlock extends BaseBlock {}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* marker block representing one or more blocks that are
|
|
111
|
+
* too small to be shown at the current zoom level
|
|
112
|
+
*/
|
|
113
|
+
export class ElidedBlock extends BaseBlock {
|
|
114
|
+
public widthPx: number
|
|
115
|
+
|
|
116
|
+
public elidedBlockCount = 0
|
|
117
|
+
|
|
118
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
119
|
+
constructor(data: Record<string, any>) {
|
|
120
|
+
super(data)
|
|
121
|
+
this.widthPx = data.widthPx
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
push(otherBlock: ElidedBlock) {
|
|
125
|
+
this.elidedBlockCount += 1
|
|
126
|
+
|
|
127
|
+
if (otherBlock) {
|
|
128
|
+
this.refName = ''
|
|
129
|
+
this.start = 0
|
|
130
|
+
this.end = 0
|
|
131
|
+
this.widthPx += otherBlock.widthPx
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* marker block that sits between two different displayed regions
|
|
138
|
+
* and provides a thick border between them
|
|
139
|
+
*/
|
|
140
|
+
export class InterRegionPaddingBlock extends BaseBlock {}
|