@apollo-annotation/jbrowse-plugin-apollo 0.3.12 → 1.0.0
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/dist/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.d.ts +1 -1
- package/dist/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.d.ts.map +1 -1
- package/dist/BackendDrivers/BackendDriver.d.ts +29 -4
- package/dist/BackendDrivers/BackendDriver.d.ts.map +1 -1
- package/dist/BackendDrivers/CollaborationServerDriver.d.ts +3 -1
- package/dist/BackendDrivers/CollaborationServerDriver.d.ts.map +1 -1
- package/dist/BackendDrivers/LocalDriver/LocalDriver.d.ts +22 -0
- package/dist/BackendDrivers/LocalDriver/LocalDriver.d.ts.map +1 -0
- package/dist/BackendDrivers/LocalDriver/db.d.ts +4 -0
- package/dist/BackendDrivers/LocalDriver/db.d.ts.map +1 -0
- package/dist/BackendDrivers/index.d.ts +1 -2
- package/dist/BackendDrivers/index.d.ts.map +1 -1
- package/dist/ChangeManager.d.ts +3 -3
- package/dist/ChangeManager.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.d.ts +0 -6
- package/dist/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/TranscriptWidgetEditLocation.d.ts.map +1 -1
- package/dist/FeatureDetailsWidget/model.d.ts +0 -2
- package/dist/FeatureDetailsWidget/model.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/components/CheckResultWarnings.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/components/LinearApolloDisplay.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/components/OverlayCanvas.d.ts +7 -0
- package/dist/LinearApolloDisplay/components/OverlayCanvas.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/components/Tooltip.d.ts +10 -0
- package/dist/LinearApolloDisplay/components/Tooltip.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/BoxGlyph.d.ts +0 -1
- package/dist/LinearApolloDisplay/glyphs/BoxGlyph.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/glyphs/CDSGlyph.d.ts +3 -0
- package/dist/LinearApolloDisplay/glyphs/CDSGlyph.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/ExonGlyph.d.ts +3 -0
- package/dist/LinearApolloDisplay/glyphs/ExonGlyph.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/GeneGlyph.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/glyphs/GenericChildGlyph.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/glyphs/Glyph.d.ts +26 -20
- package/dist/LinearApolloDisplay/glyphs/Glyph.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/glyphs/TranscriptGlyph.d.ts +3 -0
- package/dist/LinearApolloDisplay/glyphs/TranscriptGlyph.d.ts.map +1 -0
- package/dist/LinearApolloDisplay/glyphs/util.d.ts +13 -0
- package/dist/LinearApolloDisplay/glyphs/util.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/base.d.ts +17 -0
- package/dist/LinearApolloDisplay/stateModel/base.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/index.d.ts +35 -17
- package/dist/LinearApolloDisplay/stateModel/index.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/layouts.d.ts +29 -7
- package/dist/LinearApolloDisplay/stateModel/layouts.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/mouseEvents.d.ts +69 -23
- package/dist/LinearApolloDisplay/stateModel/mouseEvents.d.ts.map +1 -1
- package/dist/LinearApolloDisplay/stateModel/rendering.d.ts +26 -9
- package/dist/LinearApolloDisplay/stateModel/rendering.d.ts.map +1 -1
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/base.d.ts +6 -0
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/base.d.ts.map +1 -1
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/index.d.ts +6 -0
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/index.d.ts.map +1 -1
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/rendering.d.ts +6 -0
- package/dist/LinearApolloReferenceSequenceDisplay/stateModel/rendering.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/glyphs/Glyph.d.ts +1 -1
- package/dist/LinearApolloSixFrameDisplay/glyphs/Glyph.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/stateModel/layouts.d.ts.map +1 -1
- package/dist/LinearApolloSixFrameDisplay/stateModel/rendering.d.ts.map +1 -1
- package/dist/OntologyManager/OntologyStore/fulltext.d.ts +1 -1
- package/dist/OntologyManager/OntologyStore/fulltext.d.ts.map +1 -1
- package/dist/OntologyManager/OntologyStore/index.d.ts +2 -2
- package/dist/OntologyManager/OntologyStore/index.d.ts.map +1 -1
- package/dist/OntologyManager/OntologyStore/indexeddb-storage.d.ts +1 -1
- package/dist/OntologyManager/OntologyStore/indexeddb-storage.d.ts.map +1 -1
- package/dist/OntologyManager/OntologyStore/types.d.ts +18 -0
- package/dist/OntologyManager/OntologyStore/types.d.ts.map +1 -0
- package/dist/TabularEditor/HybridGrid/featureContextMenuItems.d.ts.map +1 -1
- package/dist/components/AddChildFeature.d.ts.map +1 -1
- package/dist/components/ColorFeature.d.ts +13 -0
- package/dist/components/ColorFeature.d.ts.map +1 -0
- package/dist/components/CreateApolloAnnotation.d.ts.map +1 -1
- package/dist/components/DownloadGFF3.d.ts +4 -1
- package/dist/components/DownloadGFF3.d.ts.map +1 -1
- package/dist/components/DuplicateTranscript.d.ts.map +1 -1
- package/dist/components/ViewChangeLog.d.ts +2 -1
- package/dist/components/ViewChangeLog.d.ts.map +1 -1
- package/dist/components/ViewCheckResults.d.ts +2 -1
- package/dist/components/ViewCheckResults.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/extensions/annotationFromJBrowseFeature.d.ts.map +1 -1
- package/dist/extensions/annotationFromPileup.d.ts.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.js +6325 -5997
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +5869 -5541
- package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.development.js +16782 -25897
- package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -1
- package/dist/makeDisplayComponent.d.ts.map +1 -1
- package/dist/menus/Icons.d.ts +3 -0
- package/dist/menus/Icons.d.ts.map +1 -0
- package/dist/menus/topLevelMenu.d.ts.map +1 -1
- package/dist/session/changeHandlers.d.ts +9 -0
- package/dist/session/changeHandlers.d.ts.map +1 -0
- package/dist/util/annotationFeatureUtils.d.ts +2 -1
- package/dist/util/annotationFeatureUtils.d.ts.map +1 -1
- package/dist/util/glyphUtils.d.ts +3 -3
- package/dist/util/glyphUtils.d.ts.map +1 -1
- package/dist/util/index.d.ts +0 -1
- package/dist/util/index.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/ApolloInternetAccount/model.ts +68 -4
- package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +6 -3
- package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +1 -1
- package/src/BackendDrivers/BackendDriver.ts +36 -3
- package/src/BackendDrivers/CollaborationServerDriver.ts +78 -23
- package/src/BackendDrivers/LocalDriver/LocalDriver.ts +367 -0
- package/src/BackendDrivers/LocalDriver/db.ts +37 -0
- package/src/BackendDrivers/index.ts +1 -2
- package/src/ChangeManager.ts +27 -25
- package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +1 -1
- package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +69 -53
- package/src/LinearApolloDisplay/components/CheckResultWarnings.tsx +1 -5
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +95 -115
- package/src/LinearApolloDisplay/components/OverlayCanvas.tsx +76 -0
- package/src/LinearApolloDisplay/components/Tooltip.tsx +42 -0
- package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +60 -302
- package/src/LinearApolloDisplay/glyphs/CDSGlyph.ts +145 -0
- package/src/LinearApolloDisplay/glyphs/ExonGlyph.ts +212 -0
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +65 -999
- package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +71 -181
- package/src/LinearApolloDisplay/glyphs/Glyph.ts +42 -66
- package/src/LinearApolloDisplay/glyphs/TranscriptGlyph.ts +291 -0
- package/src/LinearApolloDisplay/glyphs/util.ts +87 -0
- package/src/LinearApolloDisplay/stateModel/base.ts +83 -0
- package/src/LinearApolloDisplay/stateModel/layouts.ts +198 -138
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +252 -158
- package/src/LinearApolloDisplay/stateModel/rendering.ts +103 -21
- package/src/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.ts +3 -3
- package/src/LinearApolloReferenceSequenceDisplay/stateModel/base.ts +20 -2
- package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +7 -2
- package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +8 -13
- package/src/LinearApolloSixFrameDisplay/glyphs/Glyph.ts +1 -1
- package/src/LinearApolloSixFrameDisplay/stateModel/layouts.ts +4 -3
- package/src/LinearApolloSixFrameDisplay/stateModel/mouseEvents.ts +1 -1
- package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +2 -1
- package/src/OntologyManager/OntologyStore/__snapshots__/index.test.ts.snap +18262 -8519
- package/src/OntologyManager/OntologyStore/fulltext.ts +1 -2
- package/src/OntologyManager/OntologyStore/index.test.ts +5 -2
- package/src/OntologyManager/OntologyStore/index.ts +7 -8
- package/src/OntologyManager/OntologyStore/indexeddb-storage.ts +2 -2
- package/src/OntologyManager/OntologyStore/types.ts +27 -0
- package/src/OntologyManager/index.ts +15 -26
- package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +4 -5
- package/src/components/AddChildFeature.tsx +15 -8
- package/src/components/ColorFeature.tsx +167 -0
- package/src/components/CreateApolloAnnotation.tsx +35 -9
- package/src/components/DownloadGFF3.tsx +92 -121
- package/src/components/DuplicateTranscript.tsx +10 -0
- package/src/components/ViewChangeLog.tsx +123 -83
- package/src/components/ViewCheckResults.tsx +15 -73
- package/src/components/index.ts +1 -1
- package/src/config.ts +37 -19
- package/src/extensions/annotationFromJBrowseFeature.test.ts +1 -1
- package/src/extensions/annotationFromJBrowseFeature.ts +91 -63
- package/src/extensions/annotationFromPileup.ts +40 -40
- package/src/index.ts +45 -1
- package/src/makeDisplayComponent.tsx +10 -3
- package/src/menus/Icons.tsx +49 -0
- package/src/menus/topLevelMenu.ts +24 -96
- package/src/session/ClientDataStore.ts +16 -17
- package/src/session/changeHandlers.ts +261 -0
- package/src/session/session.ts +77 -46
- package/src/util/annotationFeatureUtils.ts +29 -1
- package/src/util/glyphUtils.ts +74 -31
- package/src/util/index.ts +0 -1
- package/dist/BackendDrivers/DesktopFileDriver.d.ts +0 -160
- package/dist/BackendDrivers/DesktopFileDriver.d.ts.map +0 -1
- package/dist/BackendDrivers/InMemoryFileDriver.d.ts +0 -162
- package/dist/BackendDrivers/InMemoryFileDriver.d.ts.map +0 -1
- package/dist/LinearApolloDisplay/glyphs/index.d.ts +0 -4
- package/dist/LinearApolloDisplay/glyphs/index.d.ts.map +0 -1
- package/dist/components/OpenLocalFile.d.ts +0 -15
- package/dist/components/OpenLocalFile.d.ts.map +0 -1
- package/dist/util/loadAssemblyIntoClient.d.ts +0 -5
- package/dist/util/loadAssemblyIntoClient.d.ts.map +0 -1
- package/src/BackendDrivers/DesktopFileDriver.ts +0 -184
- package/src/BackendDrivers/InMemoryFileDriver.ts +0 -107
- package/src/LinearApolloDisplay/glyphs/index.ts +0 -3
- package/src/components/OpenLocalFile.tsx +0 -189
- package/src/util/loadAssemblyIntoClient.ts +0 -94
|
@@ -8,43 +8,22 @@ import { addDisposer, isAlive } from '@jbrowse/mobx-state-tree'
|
|
|
8
8
|
import { autorun, observable } from 'mobx'
|
|
9
9
|
|
|
10
10
|
import type { ApolloSessionModel } from '../../session'
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
isCDSFeature,
|
|
13
|
+
isExonFeature,
|
|
14
|
+
isGeneFeature,
|
|
15
|
+
isTranscriptFeature,
|
|
16
|
+
} from '../../util/glyphUtils'
|
|
17
|
+
import { boxGlyph } from '../glyphs/BoxGlyph'
|
|
18
|
+
import { cdsGlyph } from '../glyphs/CDSGlyph'
|
|
19
|
+
import { exonGlyph } from '../glyphs/ExonGlyph'
|
|
20
|
+
import { geneGlyph } from '../glyphs/GeneGlyph'
|
|
21
|
+
import { genericChildGlyph } from '../glyphs/GenericChildGlyph'
|
|
22
|
+
import type { Layout } from '../glyphs/Glyph'
|
|
23
|
+
import { transcriptGlyph } from '../glyphs/TranscriptGlyph'
|
|
12
24
|
|
|
13
25
|
import { baseModelFactory } from './base'
|
|
14
26
|
|
|
15
|
-
function getRowsForFeature(
|
|
16
|
-
startingRow: number,
|
|
17
|
-
rowCount: number,
|
|
18
|
-
filledRowLocations: Map<number, [number, number][]>,
|
|
19
|
-
) {
|
|
20
|
-
const rowsForFeature = []
|
|
21
|
-
for (let i = startingRow; i < startingRow + rowCount; i++) {
|
|
22
|
-
const row = filledRowLocations.get(i)
|
|
23
|
-
if (row) {
|
|
24
|
-
rowsForFeature.push(row)
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
return rowsForFeature
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function canPlaceFeatureInRows(
|
|
31
|
-
rowsForFeature: [number, number][][],
|
|
32
|
-
feature: AnnotationFeature,
|
|
33
|
-
) {
|
|
34
|
-
for (const rowForFeature of rowsForFeature) {
|
|
35
|
-
for (const [rowStart, rowEnd] of rowForFeature) {
|
|
36
|
-
if (
|
|
37
|
-
doesIntersect2(feature.min, feature.max, rowStart, rowEnd) ||
|
|
38
|
-
doesIntersect2(rowStart, rowEnd, feature.min, feature.max)
|
|
39
|
-
) {
|
|
40
|
-
return false
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return true
|
|
46
|
-
}
|
|
47
|
-
|
|
48
27
|
export function layoutsModelFactory(
|
|
49
28
|
pluginManager: PluginManager,
|
|
50
29
|
configSchema: AnyConfigurationSchemaType,
|
|
@@ -63,11 +42,19 @@ export function layoutsModelFactory(
|
|
|
63
42
|
return self.seenFeatures.get(id)
|
|
64
43
|
},
|
|
65
44
|
getGlyph(feature: AnnotationFeature) {
|
|
66
|
-
|
|
67
|
-
if (topLevelFeature.looksLikeGene) {
|
|
45
|
+
if (isGeneFeature(feature, self.session)) {
|
|
68
46
|
return geneGlyph
|
|
69
47
|
}
|
|
70
|
-
if (
|
|
48
|
+
if (isTranscriptFeature(feature, self.session)) {
|
|
49
|
+
return transcriptGlyph
|
|
50
|
+
}
|
|
51
|
+
if (isExonFeature(feature, self.session)) {
|
|
52
|
+
return exonGlyph
|
|
53
|
+
}
|
|
54
|
+
if (isCDSFeature(feature, self.session)) {
|
|
55
|
+
return cdsGlyph
|
|
56
|
+
}
|
|
57
|
+
if (feature.children?.size) {
|
|
71
58
|
return genericChildGlyph
|
|
72
59
|
}
|
|
73
60
|
return boxGlyph
|
|
@@ -82,125 +69,198 @@ export function layoutsModelFactory(
|
|
|
82
69
|
},
|
|
83
70
|
}))
|
|
84
71
|
.views((self) => ({
|
|
85
|
-
|
|
72
|
+
getCanonicalRefName(assemblyName: string, refSeq: string) {
|
|
86
73
|
const { assemblyManager } =
|
|
87
74
|
self.session as unknown as AbstractSessionModel
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
75
|
+
const assembly = assemblyManager.get(assemblyName)
|
|
76
|
+
if (!assembly) {
|
|
77
|
+
throw new Error('no assembly in layout')
|
|
78
|
+
}
|
|
79
|
+
const canonicalRefName = assembly.getCanonicalRefName(refSeq)
|
|
80
|
+
if (!canonicalRefName) {
|
|
81
|
+
throw new Error('no canonical refName in layout')
|
|
82
|
+
}
|
|
83
|
+
return canonicalRefName
|
|
84
|
+
},
|
|
85
|
+
}))
|
|
86
|
+
.views((self) => ({
|
|
87
|
+
/**
|
|
88
|
+
* Is a feature in one of the currently displayed regions and also is not
|
|
89
|
+
* currently filtered out by the display.
|
|
90
|
+
*/
|
|
91
|
+
isFeatureDisplayed(feature: AnnotationFeature) {
|
|
92
|
+
const canonicalRefName = self.getCanonicalRefName(
|
|
93
|
+
feature.assemblyId,
|
|
94
|
+
feature.refSeq,
|
|
95
|
+
)
|
|
96
|
+
return self.lgv.displayedRegions.some((region) => {
|
|
93
97
|
const { end, refName, start } = region
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
(self.filteredFeatureTypes.length > 0 &&
|
|
103
|
-
!self.filteredFeatureTypes.includes(feature.type))
|
|
104
|
-
) {
|
|
105
|
-
continue
|
|
106
|
-
}
|
|
107
|
-
const { featureTypeOntology } =
|
|
108
|
-
self.session.apolloDataStore.ontologyManager
|
|
109
|
-
if (!featureTypeOntology) {
|
|
110
|
-
throw new Error('featureTypeOntology is undefined')
|
|
111
|
-
}
|
|
112
|
-
const rowCount = self
|
|
113
|
-
.getGlyph(feature)
|
|
114
|
-
.getRowCount(feature, featureTypeOntology, self.lgv.bpPerPx)
|
|
115
|
-
let startingRow = 0
|
|
116
|
-
let placed = false
|
|
117
|
-
while (!placed) {
|
|
118
|
-
let rowsForFeature = getRowsForFeature(
|
|
119
|
-
startingRow,
|
|
120
|
-
rowCount,
|
|
121
|
-
filledRowLocations,
|
|
122
|
-
)
|
|
123
|
-
if (rowsForFeature.length < rowCount) {
|
|
124
|
-
for (let i = 0; i < rowCount - rowsForFeature.length; i++) {
|
|
125
|
-
const newRowNumber = filledRowLocations.size
|
|
126
|
-
filledRowLocations.set(newRowNumber, [])
|
|
127
|
-
featureLayout.set(newRowNumber, [])
|
|
128
|
-
}
|
|
129
|
-
rowsForFeature = getRowsForFeature(
|
|
130
|
-
startingRow,
|
|
131
|
-
rowCount,
|
|
132
|
-
filledRowLocations,
|
|
133
|
-
)
|
|
134
|
-
}
|
|
135
|
-
if (!canPlaceFeatureInRows(rowsForFeature, feature)) {
|
|
136
|
-
startingRow += 1
|
|
137
|
-
continue
|
|
138
|
-
}
|
|
139
|
-
for (
|
|
140
|
-
let rowNum = startingRow;
|
|
141
|
-
rowNum < startingRow + rowCount;
|
|
142
|
-
rowNum++
|
|
143
|
-
) {
|
|
144
|
-
filledRowLocations.get(rowNum)?.push([feature.min, feature.max])
|
|
145
|
-
const layoutRow = featureLayout.get(rowNum)
|
|
146
|
-
layoutRow?.push([rowNum - startingRow, feature._id])
|
|
147
|
-
}
|
|
148
|
-
placed = true
|
|
149
|
-
}
|
|
98
|
+
const hasDisplayedFeatureTypes = self.filteredFeatureTypes.length > 0
|
|
99
|
+
if (
|
|
100
|
+
(!hasDisplayedFeatureTypes ||
|
|
101
|
+
self.filteredFeatureTypes.includes(feature.type)) &&
|
|
102
|
+
canonicalRefName === refName &&
|
|
103
|
+
doesIntersect2(start, end, feature.min, feature.max)
|
|
104
|
+
) {
|
|
105
|
+
return true
|
|
150
106
|
}
|
|
151
|
-
return
|
|
107
|
+
return false
|
|
152
108
|
})
|
|
153
109
|
},
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
110
|
+
}))
|
|
111
|
+
.views((self) => ({
|
|
112
|
+
get layouts(): Map<string, Map<string, Layout>> {
|
|
113
|
+
// Each refName in an assembly gets its own layout so that if a feature
|
|
114
|
+
// is drawn in multiple displayed regions, it has the same layout for
|
|
115
|
+
// each of them
|
|
116
|
+
const layoutByAssemblyAndRefName = new Map<
|
|
117
|
+
string,
|
|
118
|
+
Map<string, Layout>
|
|
119
|
+
>()
|
|
120
|
+
// Go through all the features we know about and add them to th
|
|
121
|
+
for (const [id, feature] of self.seenFeatures.entries()) {
|
|
122
|
+
if (!isAlive(feature)) {
|
|
123
|
+
self.deleteSeenFeature(id)
|
|
124
|
+
continue
|
|
125
|
+
}
|
|
126
|
+
const isDisplayed = self.isFeatureDisplayed(feature)
|
|
127
|
+
if (!isDisplayed) {
|
|
128
|
+
continue
|
|
129
|
+
}
|
|
130
|
+
// This contains layout information for all the feature's sub-features
|
|
131
|
+
// as well
|
|
132
|
+
const featureLayout = self
|
|
133
|
+
.getGlyph(feature)
|
|
134
|
+
// @ts-expect-error ts doesn't understand mst extension
|
|
135
|
+
.getLayout(self, feature)
|
|
136
|
+
const canonicalRefName = self.getCanonicalRefName(
|
|
137
|
+
feature.assemblyId,
|
|
138
|
+
feature.refSeq,
|
|
139
|
+
)
|
|
140
|
+
let layoutForAssembly = layoutByAssemblyAndRefName.get(
|
|
141
|
+
feature.assemblyId,
|
|
142
|
+
)
|
|
143
|
+
if (!layoutForAssembly) {
|
|
144
|
+
layoutForAssembly = new Map<string, Layout>()
|
|
145
|
+
layoutByAssemblyAndRefName.set(
|
|
146
|
+
feature.assemblyId,
|
|
147
|
+
layoutForAssembly,
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
const layout = layoutForAssembly.get(canonicalRefName)
|
|
151
|
+
if (!layout) {
|
|
152
|
+
// If this refSeq doesn't have a layout yet, use this feature's
|
|
153
|
+
// layout as a starting layout and move on to the next feature
|
|
154
|
+
layoutForAssembly.set(canonicalRefName, featureLayout)
|
|
155
|
+
continue
|
|
156
|
+
}
|
|
157
|
+
// Check this feature for collisions in the layout, and increase the
|
|
158
|
+
// starting row if needed until there are no collisions. Then place
|
|
159
|
+
// the feature in the layout.
|
|
160
|
+
let startingRowIndex = 0
|
|
161
|
+
placeFeature: while (true) {
|
|
162
|
+
let layoutRow = layout.byRow.at(startingRowIndex)
|
|
163
|
+
if (!layoutRow) {
|
|
164
|
+
// We've increased startingRowIndex to a row that doesn't exist in
|
|
165
|
+
// layout yet. Create new row(s), place the feature in them, and
|
|
166
|
+
// move on to the next feature
|
|
167
|
+
layout.byRow.push(...featureLayout.byRow)
|
|
168
|
+
for (const entry of featureLayout.byFeature.entries()) {
|
|
169
|
+
const [featureId, rowNumber] = entry
|
|
170
|
+
layout.byFeature.set(featureId, rowNumber + startingRowIndex)
|
|
170
171
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
172
|
+
layout.min = Math.min(layout.min, featureLayout.min)
|
|
173
|
+
layout.max = Math.max(layout.max, featureLayout.max)
|
|
174
|
+
break placeFeature
|
|
175
|
+
}
|
|
176
|
+
// Check this row for collisions. Also check higher rows for
|
|
177
|
+
// collisions if the feature layout takes up more than one row.
|
|
178
|
+
// If there is a collision, set the startingRowIndex to the next
|
|
179
|
+
// row.
|
|
180
|
+
const highestRow = startingRowIndex + featureLayout.byRow.length - 1
|
|
181
|
+
let currentRow = startingRowIndex
|
|
182
|
+
while (layoutRow && startingRowIndex <= highestRow) {
|
|
183
|
+
for (const layoutFeature of layoutRow.values()) {
|
|
184
|
+
if (
|
|
185
|
+
doesIntersect2(
|
|
186
|
+
featureLayout.min,
|
|
187
|
+
featureLayout.max,
|
|
188
|
+
layoutFeature.feature.min,
|
|
189
|
+
layoutFeature.feature.max,
|
|
190
|
+
)
|
|
191
|
+
) {
|
|
192
|
+
startingRowIndex += 1
|
|
193
|
+
continue placeFeature
|
|
176
194
|
}
|
|
177
195
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
featureRow: row,
|
|
190
|
-
}
|
|
191
|
-
}
|
|
196
|
+
currentRow += 1
|
|
197
|
+
layoutRow = layout.byRow.at(currentRow)
|
|
198
|
+
}
|
|
199
|
+
// Now we have our startingRowIndex. Place feature in the layout,
|
|
200
|
+
// adding new rows if necessary.
|
|
201
|
+
for (let i = 0; i < featureLayout.byRow.length; i++) {
|
|
202
|
+
const layoutRow = layout.byRow.at(startingRowIndex + i)
|
|
203
|
+
if (layoutRow) {
|
|
204
|
+
layoutRow.push(...featureLayout.byRow[i])
|
|
205
|
+
} else {
|
|
206
|
+
layout.byRow.push(featureLayout.byRow[i])
|
|
192
207
|
}
|
|
193
208
|
}
|
|
209
|
+
for (const entry of featureLayout.byFeature.entries()) {
|
|
210
|
+
const [featureId, rowNumber] = entry
|
|
211
|
+
layout.byFeature.set(featureId, rowNumber + startingRowIndex)
|
|
212
|
+
}
|
|
213
|
+
layout.min = Math.min(layout.min, featureLayout.min)
|
|
214
|
+
layout.max = Math.max(layout.max, featureLayout.max)
|
|
215
|
+
break placeFeature
|
|
194
216
|
}
|
|
195
217
|
}
|
|
196
|
-
return
|
|
218
|
+
return layoutByAssemblyAndRefName
|
|
219
|
+
},
|
|
220
|
+
getRowForFeature(feature: AnnotationFeature) {
|
|
221
|
+
const canonicalRefName = self.getCanonicalRefName(
|
|
222
|
+
feature.assemblyId,
|
|
223
|
+
feature.refSeq,
|
|
224
|
+
)
|
|
225
|
+
return this.layouts
|
|
226
|
+
.get(feature.assemblyId)
|
|
227
|
+
?.get(canonicalRefName)
|
|
228
|
+
?.byFeature.get(feature._id)
|
|
229
|
+
},
|
|
230
|
+
getFeaturesAtPosition(
|
|
231
|
+
assemblyName: string,
|
|
232
|
+
refName: string,
|
|
233
|
+
row: number,
|
|
234
|
+
bp: number,
|
|
235
|
+
): AnnotationFeature[] {
|
|
236
|
+
const assemblyLayouts = this.layouts.get(assemblyName)
|
|
237
|
+
if (!assemblyLayouts) {
|
|
238
|
+
return []
|
|
239
|
+
}
|
|
240
|
+
const layout = assemblyLayouts.get(refName)
|
|
241
|
+
if (!layout) {
|
|
242
|
+
return []
|
|
243
|
+
}
|
|
244
|
+
const layoutRow = layout.byRow.at(row)
|
|
245
|
+
if (!layoutRow) {
|
|
246
|
+
return []
|
|
247
|
+
}
|
|
248
|
+
return layoutRow
|
|
249
|
+
.filter(({ feature }) => {
|
|
250
|
+
return bp >= feature.min && bp <= feature.max
|
|
251
|
+
})
|
|
252
|
+
.map((row) => row.feature)
|
|
197
253
|
},
|
|
198
254
|
}))
|
|
199
255
|
.views((self) => ({
|
|
200
|
-
|
|
256
|
+
highestRow(assemblyName: string) {
|
|
257
|
+
const assemblyLayouts = self.layouts.get(assemblyName)
|
|
258
|
+
if (!assemblyLayouts) {
|
|
259
|
+
return 0
|
|
260
|
+
}
|
|
201
261
|
return Math.max(
|
|
202
262
|
0,
|
|
203
|
-
...
|
|
263
|
+
...[...assemblyLayouts.values()].map((layout) => layout.byRow.length),
|
|
204
264
|
)
|
|
205
265
|
},
|
|
206
266
|
}))
|