@jbrowse/plugin-linear-genome-view 5.0.0-beta.15 → 5.0.0-beta.17
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/esm/LinearGenomeView/axisConfigSchema.d.ts +18 -0
- package/esm/LinearGenomeView/axisConfigSchema.js +22 -0
- package/esm/LinearGenomeView/components/Highlight.js +21 -5
- package/esm/LinearGenomeView/components/HighlightBand.js +18 -13
- package/esm/LinearGenomeView/components/HighlightChip.js +9 -4
- package/esm/LinearGenomeView/components/HighlightLabelDialog.d.ts +6 -0
- package/esm/LinearGenomeView/components/HighlightLabelDialog.js +18 -0
- package/esm/LinearGenomeView/components/SVGHighlightBand.js +3 -3
- package/esm/LinearGenomeView/components/TracksContainer.js +2 -2
- package/esm/LinearGenomeView/components/useSideScroll.d.ts +3 -2
- package/esm/LinearGenomeView/components/useSideScroll.js +13 -8
- package/esm/LinearGenomeView/launchKeys.d.ts +1 -1
- package/esm/LinearGenomeView/launchKeys.js +6 -5
- package/esm/LinearGenomeView/menuItems.js +4 -4
- package/esm/LinearGenomeView/model.d.ts +113 -101
- package/esm/LinearGenomeView/model.js +88 -83
- package/esm/LinearGenomeView/rExport/rScript.js +1 -0
- package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.js +2 -2
- package/esm/index.js +1 -1
- package/package.json +6 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { canonicalLocString } from '@jbrowse/core/TextSearch/places';
|
|
2
|
-
import { getConf } from '@jbrowse/core/configuration';
|
|
2
|
+
import { getConf, readConfObject } from '@jbrowse/core/configuration';
|
|
3
3
|
import { BaseViewModel } from '@jbrowse/core/pluggableElementTypes/models';
|
|
4
4
|
import { exportViewSvg } from '@jbrowse/core/svg/exportViewSvg';
|
|
5
5
|
import { assembleLocString, clamp, getBpDisplayStr, getNotificationSink, getSession, isSessionModelWithWidgets, localStorageGetBoolean, localStorageGetItem, localStorageSetBoolean, localStorageSetItem, springAnimate, sum, } from '@jbrowse/core/util';
|
|
@@ -15,10 +15,11 @@ import { assemblyErrorMessage, computeViewStatus, viewLoading, } from '@jbrowse/
|
|
|
15
15
|
import { pendingLaunch, withLaunchInput, } from '@jbrowse/core/util/withLaunchInput';
|
|
16
16
|
import { MIN_DISPLAY_HEIGHT } from '@jbrowse/display-kit/const';
|
|
17
17
|
import { contentRightEdgePx } from '@jbrowse/display-kit/regionHost';
|
|
18
|
-
import { cast, getParent, hasParent, isAlive, types, } from '@jbrowse/mobx-state-tree';
|
|
18
|
+
import { cast, getParent, getSnapshot, hasParent, isAlive, types, } from '@jbrowse/mobx-state-tree';
|
|
19
19
|
import { observable, when } from 'mobx';
|
|
20
20
|
import { handleSelectedRegion, isOpenInView, navToOption, } from '../searchUtils.js';
|
|
21
21
|
import { doAfterAttach } from './afterAttach.js';
|
|
22
|
+
import { linearGenomeViewAxisConfigSchema } from './axisConfigSchema.js';
|
|
22
23
|
import { getCytobands, shouldSwapTracks } from './components/util.js';
|
|
23
24
|
import { HEADER_BAR_HEIGHT, HEADER_OVERVIEW_HEIGHT, MIN_BP_PER_PX, MINIMIZED_TRACK_HEIGHT, MINIMUM_BLOCK_WIDTH, RESIZE_ALL_HANDLE_HEIGHT, RESIZE_HANDLE_HEIGHT, SCALE_BAR_HEIGHT, SHOW_ALL_REGIONS_FILL, TRACK_OUTLINE_BORDER, TRACK_TOP_GAP, } from './consts.js';
|
|
24
25
|
import { planFlight } from './flyTo.js';
|
|
@@ -154,7 +155,7 @@ function isTrackSelectorVisible(self) {
|
|
|
154
155
|
* views: [
|
|
155
156
|
* {
|
|
156
157
|
* type: 'LinearGenomeView',
|
|
157
|
-
*
|
|
158
|
+
* colorByFrame: true,
|
|
158
159
|
* assembly: 'hg38',
|
|
159
160
|
* loc: 'chr1:1,000,000-1,100,000',
|
|
160
161
|
* tracks: ['genes', 'alignments'],
|
|
@@ -164,7 +165,7 @@ function isTrackSelectorVisible(self) {
|
|
|
164
165
|
* ```
|
|
165
166
|
* `assembly`, `loc`, `tracks`, `tracklist`, `nav` and `highlight` need
|
|
166
167
|
* on-attach resolution and are captured into the `launch` property below;
|
|
167
|
-
* `
|
|
168
|
+
* `colorByFrame`, `showAminoAcids`, `showCenterLine` and `trackLabels` are plain
|
|
168
169
|
* view props MST restores natively. Both are written the same way.
|
|
169
170
|
* At runtime the same model is driven imperatively — every property and action
|
|
170
171
|
* below is reachable on `viewState.session.views[0]`:
|
|
@@ -192,17 +193,16 @@ export function stateModelFactory(pluginManager) {
|
|
|
192
193
|
/**
|
|
193
194
|
* #property
|
|
194
195
|
* Left edge of the viewport, in linearized bp — the concatenated
|
|
195
|
-
* `displayedRegions` space that `offsetPx` indexes, which
|
|
196
|
+
* `displayedRegions` space that `offsetPx` indexes, which has no
|
|
196
197
|
* inter-region padding, so the two differ only by `bpPerPx`. May be
|
|
197
|
-
* negative
|
|
198
|
+
* negative when the view is scrolled past the left end.
|
|
198
199
|
*
|
|
199
|
-
* The
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
* at 500px
|
|
204
|
-
*
|
|
205
|
-
* view disagreed, and only the one that stores intent was right.
|
|
200
|
+
* The view stores the genomic window it frames rather than the pixels
|
|
201
|
+
* that framed it, because pixels mean nothing without the width they
|
|
202
|
+
* were measured at and a snapshot does not include one. A session
|
|
203
|
+
* authored in a 1000px window therefore shows the same region when
|
|
204
|
+
* opened at 500px, as the same location given as a `&loc=` does: both
|
|
205
|
+
* ways to share a view store intent.
|
|
206
206
|
*/
|
|
207
207
|
windowStartBp: types.stripDefault(types.number, 0),
|
|
208
208
|
/**
|
|
@@ -215,14 +215,15 @@ export function stateModelFactory(pluginManager) {
|
|
|
215
215
|
windowWidthBp: types.stripDefault(types.number, 0),
|
|
216
216
|
/**
|
|
217
217
|
* #property
|
|
218
|
-
*
|
|
219
|
-
* was stored
|
|
218
|
+
* Used for migration only, and permanent: share links written before the
|
|
219
|
+
* window was stored contain `bpPerPx`/`offsetPx`, and there are many of
|
|
220
|
+
* them.
|
|
220
221
|
*
|
|
221
|
-
* A snapshot written before the window was stored
|
|
222
|
+
* A snapshot written before the window was stored has `offsetPx` and
|
|
222
223
|
* `bpPerPx` but not the width they were measured at, so the window they
|
|
223
224
|
* framed cannot be recovered. `windowStartBp` can (it is
|
|
224
225
|
* `offsetPx * bpPerPx`, no width needed); the width in bp cannot. This
|
|
225
|
-
*
|
|
226
|
+
* property holds the old `bpPerPx` until the first measure, which adopts it at
|
|
226
227
|
* whatever width arrives — exactly what the old code did — and clears
|
|
227
228
|
* this. So an old link keeps its old behavior rather than being
|
|
228
229
|
* reinterpreted, and everything authored since restores its window.
|
|
@@ -231,9 +232,8 @@ export function stateModelFactory(pluginManager) {
|
|
|
231
232
|
/**
|
|
232
233
|
* #property
|
|
233
234
|
* currently displayed regions, can be a single chromosome, arbitrary
|
|
234
|
-
* subsections, or the entire
|
|
235
|
-
*
|
|
236
|
-
* fragmented
|
|
235
|
+
* subsections, or the entire set of chromosomes in the genome. The entire
|
|
236
|
+
* set is not advised if your assembly is very fragmented
|
|
237
237
|
*/
|
|
238
238
|
displayedRegions: types.stripDefault(types.frozen(), []),
|
|
239
239
|
/**
|
|
@@ -268,7 +268,7 @@ export function stateModelFactory(pluginManager) {
|
|
|
268
268
|
/**
|
|
269
269
|
* #property
|
|
270
270
|
* show the "center line". A personal preference: never in a session
|
|
271
|
-
* snapshot. It, showCytobands, trackLabels,
|
|
271
|
+
* snapshot. It, showCytobands, trackLabels, colorByFrame, showAminoAcids
|
|
272
272
|
* and showTrackOutlines start from this browser's last choice, which
|
|
273
273
|
* their setters record.
|
|
274
274
|
*/
|
|
@@ -283,29 +283,30 @@ export function stateModelFactory(pluginManager) {
|
|
|
283
283
|
/**
|
|
284
284
|
* #property
|
|
285
285
|
* how to display the track labels, can be "overlapping", "offset", or
|
|
286
|
-
* "hidden", or empty string "" (which
|
|
287
|
-
*
|
|
288
|
-
*
|
|
289
|
-
* https://jbrowse.org/jb2/docs/config/lineargenomeviewconfigschema/
|
|
290
|
-
* how
|
|
286
|
+
* "hidden", or empty string "" (which uses the LinearGenomeViewPlugin
|
|
287
|
+
* config default). The resolved value is the `effectiveTrackLabels`
|
|
288
|
+
* getter. See the LinearGenomeViewPlugin docs at
|
|
289
|
+
* https://jbrowse.org/jb2/docs/config/lineargenomeviewconfigschema/ for
|
|
290
|
+
* how the config is used
|
|
291
291
|
*/
|
|
292
292
|
trackLabels: types.optional(types.string, () => localStorageGetItem('lgv-trackLabels') ?? ''),
|
|
293
293
|
/**
|
|
294
294
|
* #property
|
|
295
|
-
*
|
|
295
|
+
* The ruler's guide, a [](/docs/config/lineargenomeviewaxis) object:
|
|
296
|
+
* `{ grid: false }` stops its ticks running down through the tracks.
|
|
296
297
|
*/
|
|
297
|
-
|
|
298
|
+
axis: types.stripDefault(linearGenomeViewAxisConfigSchema, {}),
|
|
298
299
|
/**
|
|
299
300
|
* #property
|
|
300
301
|
* color CDS segments by reading frame
|
|
301
302
|
*/
|
|
302
|
-
|
|
303
|
+
colorByFrame: types.optional(types.boolean, () => localStorageGetBoolean('lgv-colorByFrame', false)),
|
|
303
304
|
/**
|
|
304
305
|
* #property
|
|
305
306
|
* draw translated codons on coding features once zoomed in far enough:
|
|
306
307
|
* an alternating per-codon shading, and the amino acid letters on top of
|
|
307
|
-
* it at base-level zoom. Independent of `
|
|
308
|
-
* the segments by frame.
|
|
308
|
+
* it at base-level zoom. Independent of `colorByFrame`, which only
|
|
309
|
+
* recolors the segments by frame.
|
|
309
310
|
*/
|
|
310
311
|
showAminoAcids: types.optional(types.boolean, () => localStorageGetBoolean('lgv-showAminoAcids', true)),
|
|
311
312
|
/**
|
|
@@ -407,6 +408,13 @@ export function stateModelFactory(pluginManager) {
|
|
|
407
408
|
};
|
|
408
409
|
})
|
|
409
410
|
.views(self => ({
|
|
411
|
+
/**
|
|
412
|
+
* #getter
|
|
413
|
+
* `axis.grid`: whether the ruler's ticks run down through the tracks.
|
|
414
|
+
*/
|
|
415
|
+
get axisGrid() {
|
|
416
|
+
return readConfObject(self.axis, 'grid');
|
|
417
|
+
},
|
|
410
418
|
// The viewport in pixels, derived from the window it frames — declared
|
|
411
419
|
// ahead of every other getter so that the ~300 reads of `self.bpPerPx` /
|
|
412
420
|
// `self.offsetPx` across the codebase go on resolving by name. Only the
|
|
@@ -659,8 +667,8 @@ export function stateModelFactory(pluginManager) {
|
|
|
659
667
|
},
|
|
660
668
|
/**
|
|
661
669
|
* #getter
|
|
662
|
-
*
|
|
663
|
-
* assembly
|
|
670
|
+
* The loading screen's text while `showLoading`, taken from the
|
|
671
|
+
* assembly being waited on; undefined otherwise.
|
|
664
672
|
*/
|
|
665
673
|
get loading() {
|
|
666
674
|
return viewLoading(this.showLoading, () => this.loadingAssembly);
|
|
@@ -714,12 +722,12 @@ export function stateModelFactory(pluginManager) {
|
|
|
714
722
|
* `width`/`staticBlocks` throw by design before the view has been
|
|
715
723
|
* measured and navigated.
|
|
716
724
|
*
|
|
717
|
-
*
|
|
725
|
+
* Use this getter rather than `initialized`.
|
|
718
726
|
* That one answers "have the assembly's regions loaded", which is only
|
|
719
727
|
* the first of two async steps: navigating then populates
|
|
720
728
|
* `displayedRegions`, and in the window between the two `initialized` is
|
|
721
729
|
* already true while there is still nothing on screen. `showLoading`
|
|
722
|
-
* folds in `awaitingInitNavigation`, the getter
|
|
730
|
+
* folds in `awaitingInitNavigation`, the getter for exactly
|
|
723
731
|
* that gap.
|
|
724
732
|
*
|
|
725
733
|
* `error` is the third outcome and is why this is not a bare
|
|
@@ -796,7 +804,7 @@ export function stateModelFactory(pluginManager) {
|
|
|
796
804
|
},
|
|
797
805
|
/**
|
|
798
806
|
* #method
|
|
799
|
-
* rendered height of a single track,
|
|
807
|
+
* rendered height of a single track, using a fixed height when
|
|
800
808
|
* minimized. Shared by trackHeights and getTrackYOffset so the two can't
|
|
801
809
|
* disagree. Reads `activeDisplay` — the display TrackContainer actually
|
|
802
810
|
* mounts — rather than re-picking `displays[0]`, so the view's height math
|
|
@@ -926,8 +934,8 @@ export function stateModelFactory(pluginManager) {
|
|
|
926
934
|
* or 0 for a standalone view, a mode that is off, and a stack that cannot
|
|
927
935
|
* answer yet.
|
|
928
936
|
*
|
|
929
|
-
*
|
|
930
|
-
* function of every row's fit, all of which
|
|
937
|
+
* A getter rather than a volatile the container writes: the number is a
|
|
938
|
+
* function of every row's fit, all of which change on a resize, and a
|
|
931
939
|
* stored copy would be stale by the next layout.
|
|
932
940
|
*/
|
|
933
941
|
get sharedFitBpPerPx() {
|
|
@@ -1054,9 +1062,9 @@ export function stateModelFactory(pluginManager) {
|
|
|
1054
1062
|
/**
|
|
1055
1063
|
* #action
|
|
1056
1064
|
*/
|
|
1057
|
-
|
|
1058
|
-
self.
|
|
1059
|
-
localStorageSetBoolean('lgv-
|
|
1065
|
+
setColorByFrame(flag) {
|
|
1066
|
+
self.colorByFrame = flag;
|
|
1067
|
+
localStorageSetBoolean('lgv-colorByFrame', flag);
|
|
1060
1068
|
},
|
|
1061
1069
|
/**
|
|
1062
1070
|
* #action
|
|
@@ -1172,8 +1180,8 @@ export function stateModelFactory(pluginManager) {
|
|
|
1172
1180
|
/**
|
|
1173
1181
|
* #action
|
|
1174
1182
|
*/
|
|
1175
|
-
|
|
1176
|
-
self.
|
|
1183
|
+
setAxisGrid(grid) {
|
|
1184
|
+
self.axis = cast({ ...getSnapshot(self.axis), grid });
|
|
1177
1185
|
},
|
|
1178
1186
|
/**
|
|
1179
1187
|
* #action
|
|
@@ -1454,7 +1462,7 @@ export function stateModelFactory(pluginManager) {
|
|
|
1454
1462
|
/**
|
|
1455
1463
|
* #method
|
|
1456
1464
|
* Helper method for the fetchSequence.
|
|
1457
|
-
*
|
|
1465
|
+
* Returns the regions the user selected with the
|
|
1458
1466
|
* rubberband
|
|
1459
1467
|
*
|
|
1460
1468
|
* @param leftOffset - `object as {start, end, index, offset}`, offset = start
|
|
@@ -1584,8 +1592,8 @@ export function stateModelFactory(pluginManager) {
|
|
|
1584
1592
|
}
|
|
1585
1593
|
/**
|
|
1586
1594
|
* #action
|
|
1587
|
-
* cancel an in-flight animated zoom.
|
|
1588
|
-
*
|
|
1595
|
+
* cancel an in-flight animated zoom. Any other zoom already stops the
|
|
1596
|
+
* animation, so this is for stopping it *without* changing the
|
|
1589
1597
|
* zoom — the slider grabbing the thumb, before it has a value to commit.
|
|
1590
1598
|
*/
|
|
1591
1599
|
function cancelZoomAnimation() {
|
|
@@ -1613,8 +1621,8 @@ export function stateModelFactory(pluginManager) {
|
|
|
1613
1621
|
* #getter
|
|
1614
1622
|
* an ideogram only reads correctly against an entire chromosome: on a
|
|
1615
1623
|
* sub-region it is a meaningless slice of bands, and the centromere shows
|
|
1616
|
-
* up as a lone half-triangle. The chromosome needs bands
|
|
1617
|
-
*
|
|
1624
|
+
* up as a lone half-triangle. The chromosome also needs bands: a cytoband
|
|
1625
|
+
* file often lists only the main chromosomes, not chrM or the
|
|
1618
1626
|
* unplaced scaffolds
|
|
1619
1627
|
*/
|
|
1620
1628
|
get canShowCytobands() {
|
|
@@ -1626,7 +1634,7 @@ export function stateModelFactory(pluginManager) {
|
|
|
1626
1634
|
/**
|
|
1627
1635
|
* #getter
|
|
1628
1636
|
* the `showCytobands` setting gated by whether cytobands can be shown at
|
|
1629
|
-
* all (whole chromosome with bands
|
|
1637
|
+
* all (whole chromosome with bands in the cytoband file) and by the header
|
|
1630
1638
|
* overview they draw in being on, which the SVG export follows too
|
|
1631
1639
|
*/
|
|
1632
1640
|
get effectiveShowCytobands() {
|
|
@@ -1750,9 +1758,8 @@ export function stateModelFactory(pluginManager) {
|
|
|
1750
1758
|
/**
|
|
1751
1759
|
* #getter
|
|
1752
1760
|
* dynamic blocks represent the exact coordinates of the currently
|
|
1753
|
-
* visible genome regions on the screen.
|
|
1754
|
-
*
|
|
1755
|
-
* represent exactly what is on screen
|
|
1761
|
+
* visible genome regions on the screen. Static blocks can go
|
|
1762
|
+
* offscreen, while dynamic blocks represent exactly what is on screen
|
|
1756
1763
|
*/
|
|
1757
1764
|
get dynamicBlocks() {
|
|
1758
1765
|
return calculateDynamicBlocks(self);
|
|
@@ -1794,12 +1801,10 @@ export function stateModelFactory(pluginManager) {
|
|
|
1794
1801
|
* The frame exists because those three are laid out across every
|
|
1795
1802
|
* displayed region rather than across the viewport — it overhangs on
|
|
1796
1803
|
* both sides — so their `x` values are stable under a scroll and only
|
|
1797
|
-
* this number moves. `scalebarRefNameLabels` is the exception
|
|
1798
|
-
* so: its `transform` is already a screen x, because a sticky label's
|
|
1804
|
+
* this number moves. `scalebarRefNameLabels` is the exception: its `transform` is already a screen x, because a sticky label's
|
|
1799
1805
|
* position is a function of the scroll rather than of block geometry.
|
|
1800
1806
|
*
|
|
1801
|
-
* **The subtraction must happen here, in float64
|
|
1802
|
-
* load-bearing part.** `offsetPx` is a whole-genome pixel coordinate —
|
|
1807
|
+
* **The subtraction must happen here, in float64.** `offsetPx` is a whole-genome pixel coordinate —
|
|
1803
1808
|
* hg38 chr1 at base resolution is already past 1e10 — and a length that
|
|
1804
1809
|
* size does not survive the trip through CSS: the transform matrix is
|
|
1805
1810
|
* float32 by the time it reaches the compositor, where consecutive
|
|
@@ -1811,13 +1816,12 @@ export function stateModelFactory(pluginManager) {
|
|
|
1811
1816
|
* assemblies at high zoom, which is not where anyone tests. Both
|
|
1812
1817
|
* operands here are large and their difference is bounded by the
|
|
1813
1818
|
* overhang (a block or two), so what reaches CSS is small and exact.
|
|
1814
|
-
*
|
|
1819
|
+
* This applies the GPU side's rule one layer up; see
|
|
1815
1820
|
* `agent-docs/reference/BP_PRECISION.md`.
|
|
1816
1821
|
*
|
|
1817
1822
|
* Published because it is the one piece of coordinate arithmetic a host
|
|
1818
1823
|
* drawing its own chrome would otherwise have to know, and because
|
|
1819
|
-
*
|
|
1820
|
-
* came to disagree about rounding. Round it where the content is text
|
|
1824
|
+
* copies written out at each call site disagree about rounding. Round it where the content is text
|
|
1821
1825
|
* (a fractional offset blurs a label); leave it alone for paths and
|
|
1822
1826
|
* boxes.
|
|
1823
1827
|
*/
|
|
@@ -1870,11 +1874,11 @@ export function stateModelFactory(pluginManager) {
|
|
|
1870
1874
|
* sticky, transform, maxWidth, paddingLeft, text}` each. One per run of
|
|
1871
1875
|
* same-refName regions, plus a "sticky" one pinned to the viewport's
|
|
1872
1876
|
* left edge naming the refName under it, so panning into a chromosome
|
|
1873
|
-
* does not scroll
|
|
1877
|
+
* does not scroll the chromosome's name off the screen.
|
|
1874
1878
|
*
|
|
1875
|
-
*
|
|
1876
|
-
* otherwise
|
|
1877
|
-
*
|
|
1879
|
+
* This getter applies three rules that a host drawing region names would
|
|
1880
|
+
* otherwise have to rediscover, and two of them are invisible until the
|
|
1881
|
+
* data is awkward:
|
|
1878
1882
|
*
|
|
1879
1883
|
* - the sticky label rides the rightmost run that has scrolled off the
|
|
1880
1884
|
* left, not the region's first block — that one is gone from
|
|
@@ -1886,7 +1890,7 @@ export function stateModelFactory(pluginManager) {
|
|
|
1886
1890
|
* is fitted to the whole run, and `displayedRegionIndex` /
|
|
1887
1891
|
* `lastDisplayedRegionIndex` bracket what it stands for.
|
|
1888
1892
|
* - a name is drawn whole or not at all, measured against the space its
|
|
1889
|
-
* run leaves. Clipped to
|
|
1893
|
+
* run leaves. Clipped to that space, `chr16` reads as `chr1` —
|
|
1890
1894
|
* a different chromosome rather than a shortened name, which is why
|
|
1891
1895
|
* this is a fit test rather than an ellipsis.
|
|
1892
1896
|
*
|
|
@@ -1906,7 +1910,7 @@ export function stateModelFactory(pluginManager) {
|
|
|
1906
1910
|
* pins to its right edge rather than the viewport's, and the coordinate
|
|
1907
1911
|
* numbers stay out from under it. The SVG export deliberately
|
|
1908
1912
|
* calls `getScalebarRefNameLabels` itself with no prefix rather than
|
|
1909
|
-
* reading this, since it draws
|
|
1913
|
+
* reading this, since it draws the assembly name itself above the ruler.
|
|
1910
1914
|
*/
|
|
1911
1915
|
get scalebarRefNameLabels() {
|
|
1912
1916
|
return getScalebarRefNameLabels({
|
|
@@ -1921,7 +1925,7 @@ export function stateModelFactory(pluginManager) {
|
|
|
1921
1925
|
* Every span along the row that is not track data, as plain geometry in
|
|
1922
1926
|
* the staticBlocks frame — the same frame as gridlineTicks and
|
|
1923
1927
|
* scalebarLabels, so one `translateX(staticBlocksTranslateX)` places all
|
|
1924
|
-
* three. A host
|
|
1928
|
+
* three. A host that draws the row's chrome itself needs all three kinds:
|
|
1925
1929
|
*
|
|
1926
1930
|
* - `seam`: the 3px bar at a region's right edge. Displayed regions are
|
|
1927
1931
|
* laid out **contiguously** (calculateStaticBlocks emits boundary
|
|
@@ -1936,11 +1940,11 @@ export function stateModelFactory(pluginManager) {
|
|
|
1936
1940
|
* but the 24 chromosomes are under a pixel wide), so a host that
|
|
1937
1941
|
* skips them leaves that part of the row empty.
|
|
1938
1942
|
* - `boundary`: past the start of the first region or the end of the
|
|
1939
|
-
* last. Greying it
|
|
1943
|
+
* last. Greying it makes the last region's seam read as the edge of a
|
|
1940
1944
|
* filled area, where it would otherwise look like a line in the
|
|
1941
1945
|
* middle of the track.
|
|
1942
1946
|
*
|
|
1943
|
-
* Elided blocks get no seam even though they
|
|
1947
|
+
* Elided blocks get no seam even though they have the flag: at the
|
|
1944
1948
|
* zoom where regions elide, one bar per region would fill the row solid
|
|
1945
1949
|
* grey.
|
|
1946
1950
|
*
|
|
@@ -2042,7 +2046,7 @@ export function stateModelFactory(pluginManager) {
|
|
|
2042
2046
|
* array of fresh objects on every pan and zoom frame, so a component
|
|
2043
2047
|
* that derived this number itself re-rendered on every frame of every
|
|
2044
2048
|
* gesture — to produce, whenever content fills the track, the unchanged
|
|
2045
|
-
* `trackWidthPx`.
|
|
2049
|
+
* `trackWidthPx`. A component that reads the scalar lets MobX's `===` stop the chain at
|
|
2046
2050
|
* this computed instead. Measured over 20 zoom frames: the wiggle
|
|
2047
2051
|
* family's three body instances fell from 66 renders to 7.
|
|
2048
2052
|
*/
|
|
@@ -2181,17 +2185,16 @@ export function stateModelFactory(pluginManager) {
|
|
|
2181
2185
|
* as a navigation that didn't happen, and wiggle's autoscale domain is
|
|
2182
2186
|
* computed over the window the user just left — measured at `[0,200]`
|
|
2183
2187
|
* against a correct `[0,300]` when a 40bp coarse window survived a jump to
|
|
2184
|
-
* 4040bp on screen.
|
|
2185
|
-
* made that reachable: at 600ms the data never landed inside the hole.
|
|
2188
|
+
* 4040bp on screen.
|
|
2186
2189
|
*
|
|
2187
|
-
* **The continuous paths
|
|
2190
|
+
* **The continuous paths do not call this.** The
|
|
2188
2191
|
* spring zoom writes through `zoomTo` per frame and a drag through
|
|
2189
2192
|
* `scrollTo`, so this adds no per-frame work; the settle is idempotent
|
|
2190
2193
|
* (`setCoarseDynamicBlocks` compares block keys), so the debounced
|
|
2191
|
-
* autorun's
|
|
2194
|
+
* autorun's follow-up run costs nothing.
|
|
2192
2195
|
*
|
|
2193
|
-
* Every placer calls it, and `placersSettleCoarseBlocks.test.ts`
|
|
2194
|
-
*
|
|
2196
|
+
* Every placer calls it, and `placersSettleCoarseBlocks.test.ts` enforces
|
|
2197
|
+
* that for the next one: it scans this file for the writes and
|
|
2195
2198
|
* fails on a placer that reaches neither the settle nor its named list of
|
|
2196
2199
|
* continuous paths. Two passes by hand missed four.
|
|
2197
2200
|
*/
|
|
@@ -2252,8 +2255,8 @@ export function stateModelFactory(pluginManager) {
|
|
|
2252
2255
|
},
|
|
2253
2256
|
/**
|
|
2254
2257
|
* #action
|
|
2255
|
-
* Place the viewport by
|
|
2256
|
-
*
|
|
2258
|
+
* Place the viewport by `bpPerPx` and `offsetPx`, the pixel pair the view
|
|
2259
|
+
* stored before it stored the window. Prefer `setWindow`: pixels mean nothing without the width they were
|
|
2257
2260
|
* measured at, so a round trip through here is only exact while the width
|
|
2258
2261
|
* holds still. Kept for callers that genuinely have pixels — a wheel
|
|
2259
2262
|
* gesture, a rubberband.
|
|
@@ -2266,7 +2269,7 @@ export function stateModelFactory(pluginManager) {
|
|
|
2266
2269
|
/**
|
|
2267
2270
|
* #action
|
|
2268
2271
|
* Place the viewport by the pair it is actually STORED as: the window's
|
|
2269
|
-
* width and left edge, both in bp.
|
|
2272
|
+
* width and left edge, both in bp. The bp-space counterpart of `setNewView`, and the
|
|
2270
2273
|
* right one for anything that captures a viewport and puts it back later
|
|
2271
2274
|
* (an Undo, a saved location) — those two moments can be a window resize
|
|
2272
2275
|
* apart, and this pair survives one where a pixel pair does not.
|
|
@@ -2296,8 +2299,8 @@ export function stateModelFactory(pluginManager) {
|
|
|
2296
2299
|
},
|
|
2297
2300
|
/**
|
|
2298
2301
|
* #action
|
|
2299
|
-
*
|
|
2300
|
-
* by `displayedRegionIndex`, so a set that outlives the region list has a
|
|
2302
|
+
* Settles the coarse blocks, since this is the worst jump to leave
|
|
2303
|
+
* unsettled: they are keyed by `displayedRegionIndex`, so a set that outlives the region list has a
|
|
2301
2304
|
* consumer reading one contig's data against another's blocks.
|
|
2302
2305
|
*/
|
|
2303
2306
|
setDisplayedRegions(regions) {
|
|
@@ -2756,7 +2759,7 @@ export function stateModelFactory(pluginManager) {
|
|
|
2756
2759
|
/**
|
|
2757
2760
|
* #method
|
|
2758
2761
|
* returns menu items for a highlight context menu. plugins can extend
|
|
2759
|
-
* this via Core-extendPluggableElement to add
|
|
2762
|
+
* this via Core-extendPluggableElement to add items
|
|
2760
2763
|
*/
|
|
2761
2764
|
highlightMenuItems(_highlight) {
|
|
2762
2765
|
return [];
|
|
@@ -2897,12 +2900,14 @@ export function stateModelFactory(pluginManager) {
|
|
|
2897
2900
|
return snap;
|
|
2898
2901
|
}
|
|
2899
2902
|
// v4's `showCytobandsSetting` persists as the bare `showCytobands` prop
|
|
2900
|
-
// (the capability-gated getter is `effectiveShowCytobands`)
|
|
2901
|
-
|
|
2903
|
+
// (the capability-gated getter is `effectiveShowCytobands`), and v4's
|
|
2904
|
+
// `colorByCDS` as `colorByFrame`.
|
|
2905
|
+
const { showCytobandsSetting, colorByCDS, offsetPx, bpPerPx, ...rest } = snap;
|
|
2902
2906
|
return {
|
|
2903
2907
|
...(showCytobandsSetting !== undefined
|
|
2904
2908
|
? { showCytobands: showCytobandsSetting }
|
|
2905
2909
|
: {}),
|
|
2910
|
+
...(colorByCDS !== undefined ? { colorByFrame: colorByCDS } : {}),
|
|
2906
2911
|
// The viewport used to persist as pixels. Half of that converts
|
|
2907
2912
|
// exactly and needs no width — the left edge in bp is offsetPx *
|
|
2908
2913
|
// bpPerPx — and half of it cannot convert at all, because the width
|
|
@@ -11,6 +11,7 @@ const READERS = {
|
|
|
11
11
|
adapters: {
|
|
12
12
|
Gff3TabixAdapter: { slot: 'gffGzLocation', ext: /\.gff3?\.gz$/ },
|
|
13
13
|
Gff3Adapter: { slot: 'gffLocation', ext: /\.gff3?$/ },
|
|
14
|
+
GtfTabixAdapter: { slot: 'gtfGzLocation', ext: /\.gtf\.gz$/ },
|
|
14
15
|
GtfAdapter: { slot: 'gtfLocation', ext: /\.gtf$/ },
|
|
15
16
|
BedTabixAdapter: { slot: 'bedGzLocation', ext: /\.bed\.gz$/ },
|
|
16
17
|
BedAdapter: { slot: 'bedLocation', ext: /\.bed$/ },
|
|
@@ -126,7 +126,7 @@ const FrozenSvgFigure = memo(function FrozenSvgFigure({ view, snapshot, }) {
|
|
|
126
126
|
* (hidden sections, collapses, height overrides: `groupStateKey`), which are
|
|
127
127
|
* volatile and in no snapshot; **the reload counter**, since a Retry or a Force
|
|
128
128
|
* load leaves every snapshot as it was while the figure has an error or a
|
|
129
|
-
* too-large note to replace; **the view's coloring toggles** (`
|
|
129
|
+
* too-large note to replace; **the view's coloring toggles** (`colorByFrame`,
|
|
130
130
|
* `showAminoAcids`), named one by one because the view's own snapshot moves
|
|
131
131
|
* every pan frame; **the width**, since a resize can widen the canvas without
|
|
132
132
|
* moving the locus; **the theme**, since each display bakes colors into its own
|
|
@@ -172,7 +172,7 @@ function figureKey(view, themeName) {
|
|
|
172
172
|
display?.reloadCounter,
|
|
173
173
|
];
|
|
174
174
|
}),
|
|
175
|
-
view.
|
|
175
|
+
view.colorByFrame,
|
|
176
176
|
view.showAminoAcids,
|
|
177
177
|
session.getActiveThemeOptions?.(themeName),
|
|
178
178
|
session.highlightsVisible ? view.highlights : false,
|
package/esm/index.js
CHANGED
|
@@ -19,7 +19,7 @@ export default class LinearGenomeViewPlugin extends Plugin {
|
|
|
19
19
|
configurationSchema = ConfigurationSchema('LinearGenomeViewConfigSchema', {
|
|
20
20
|
/**
|
|
21
21
|
* #slot configuration.LinearGenomeViewPlugin.trackLabels
|
|
22
|
-
* The placement of a track's name: `offset`
|
|
22
|
+
* The placement of a track's name: `offset` puts it on a line above the
|
|
23
23
|
* data, `overlapping` floats it over the top of the data to save vertical
|
|
24
24
|
* space, `hidden` omits it. The view menu's "Track labels" submenu sets the
|
|
25
25
|
* same thing per session
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/plugin-linear-genome-view",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.17",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "JBrowse 2 linear genome view",
|
|
6
6
|
"keywords": [
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
"@mui/material": "^9.5.0",
|
|
27
27
|
"mobx": "^7.0.6",
|
|
28
28
|
"mobx-react": "^10.0.2",
|
|
29
|
-
"@jbrowse/
|
|
30
|
-
"@jbrowse/display-ui": "^5.0.0-beta.
|
|
31
|
-
"@jbrowse/core": "^5.0.0-beta.
|
|
32
|
-
"@jbrowse/
|
|
29
|
+
"@jbrowse/core": "^5.0.0-beta.17",
|
|
30
|
+
"@jbrowse/display-ui": "^5.0.0-beta.17",
|
|
31
|
+
"@jbrowse/render-core": "^5.0.0-beta.17",
|
|
32
|
+
"@jbrowse/display-kit": "^5.0.0-beta.17"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"react": ">=19.0.0",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"sideEffects": false,
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@jbrowse/display-test-utils": "^5.0.0-beta.
|
|
43
|
+
"@jbrowse/display-test-utils": "^5.0.0-beta.17"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"prebuild": "pnpm clean",
|