@jbrowse/plugin-linear-genome-view 1.6.9 → 1.7.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.
Files changed (62) hide show
  1. package/dist/BaseLinearDisplay/components/BaseLinearDisplay.js +232 -0
  2. package/dist/BaseLinearDisplay/components/Block.js +86 -0
  3. package/dist/BaseLinearDisplay/components/LinearBlocks.js +110 -0
  4. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +192 -0
  5. package/dist/BaseLinearDisplay/index.js +41 -0
  6. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +763 -0
  7. package/dist/BaseLinearDisplay/models/baseLinearDisplayConfigSchema.js +24 -0
  8. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js +328 -0
  9. package/dist/LinearBareDisplay/configSchema.js +19 -0
  10. package/dist/LinearBareDisplay/index.js +21 -0
  11. package/dist/LinearBareDisplay/index.test.js +33 -0
  12. package/dist/LinearBareDisplay/model.js +44 -0
  13. package/dist/LinearBasicDisplay/components/SetMaxHeight.js +94 -0
  14. package/dist/LinearBasicDisplay/configSchema.js +25 -0
  15. package/dist/LinearBasicDisplay/index.js +23 -0
  16. package/dist/LinearBasicDisplay/model.js +162 -0
  17. package/dist/LinearGenomeView/components/CenterLine.js +80 -0
  18. package/dist/LinearGenomeView/components/ExportSvgDialog.js +137 -0
  19. package/dist/LinearGenomeView/components/Header.js +144 -0
  20. package/dist/LinearGenomeView/components/HelpDialog.js +48 -0
  21. package/dist/LinearGenomeView/components/ImportForm.js +330 -0
  22. package/dist/LinearGenomeView/components/LinearGenomeView.js +129 -0
  23. package/dist/LinearGenomeView/components/LinearGenomeView.test.js +234 -0
  24. package/dist/LinearGenomeView/components/LinearGenomeViewSvg.js +349 -0
  25. package/dist/LinearGenomeView/components/MiniControls.js +83 -0
  26. package/dist/LinearGenomeView/components/OverviewRubberBand.js +310 -0
  27. package/dist/LinearGenomeView/components/OverviewScaleBar.js +403 -0
  28. package/dist/LinearGenomeView/components/RefNameAutocomplete.js +331 -0
  29. package/dist/LinearGenomeView/components/RubberBand.js +309 -0
  30. package/dist/LinearGenomeView/components/Ruler.js +101 -0
  31. package/dist/LinearGenomeView/components/ScaleBar.js +184 -0
  32. package/dist/LinearGenomeView/components/ScaleBar.test.js +180 -0
  33. package/dist/LinearGenomeView/components/SearchBox.js +201 -0
  34. package/dist/LinearGenomeView/components/SearchResultsDialog.js +159 -0
  35. package/dist/LinearGenomeView/components/SequenceDialog.js +304 -0
  36. package/dist/LinearGenomeView/components/TrackContainer.js +179 -0
  37. package/dist/LinearGenomeView/components/TrackLabel.js +165 -0
  38. package/dist/LinearGenomeView/components/TracksContainer.js +214 -0
  39. package/dist/LinearGenomeView/components/VerticalGuides.js +116 -0
  40. package/dist/LinearGenomeView/components/ZoomControls.js +92 -0
  41. package/dist/LinearGenomeView/components/util.js +16 -0
  42. package/dist/LinearGenomeView/index.js +1418 -0
  43. package/dist/LinearGenomeView/index.test.js +1170 -0
  44. package/dist/LinearGenomeView/util.js +93 -0
  45. package/dist/LinearGenomeView/util.test.js +78 -0
  46. package/dist/index.js +293 -6
  47. package/package.json +4 -8
  48. package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +2 -0
  49. package/src/BaseLinearDisplay/models/serverSideRenderedBlock.ts +10 -8
  50. package/src/LinearBasicDisplay/components/SetMaxHeight.tsx +1 -1
  51. package/src/LinearBasicDisplay/model.ts +17 -18
  52. package/src/LinearGenomeView/components/Header.tsx +1 -1
  53. package/src/LinearGenomeView/components/ImportForm.tsx +10 -4
  54. package/src/LinearGenomeView/components/LinearGenomeView.test.js +1 -0
  55. package/src/LinearGenomeView/components/OverviewScaleBar.tsx +2 -2
  56. package/src/LinearGenomeView/components/RubberBand.tsx +14 -24
  57. package/src/LinearGenomeView/components/ScaleBar.test.tsx +1 -0
  58. package/src/LinearGenomeView/components/ScaleBar.tsx +3 -6
  59. package/src/LinearGenomeView/components/SequenceDialog.tsx +1 -1
  60. package/src/LinearGenomeView/components/TrackLabel.tsx +1 -1
  61. package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.js.snap +0 -4
  62. package/src/LinearGenomeView/index.tsx +2 -3
@@ -0,0 +1,763 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ var _typeof = require("@babel/runtime/helpers/typeof");
6
+
7
+ Object.defineProperty(exports, "__esModule", {
8
+ value: true
9
+ });
10
+ exports.BaseLinearDisplay = void 0;
11
+
12
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
13
+
14
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
15
+
16
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
17
+
18
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
19
+
20
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
21
+
22
+ var _react = _interopRequireDefault(require("react"));
23
+
24
+ var _core = require("@material-ui/core");
25
+
26
+ var _models = require("@jbrowse/core/pluggableElementTypes/models");
27
+
28
+ var _configuration = require("@jbrowse/core/configuration");
29
+
30
+ var _util = require("@jbrowse/core/util");
31
+
32
+ var _compositeMap = _interopRequireDefault(require("@jbrowse/core/util/compositeMap"));
33
+
34
+ var _simpleFeature = require("@jbrowse/core/util/simpleFeature");
35
+
36
+ var _tracks = require("@jbrowse/core/util/tracks");
37
+
38
+ var _mobx = require("mobx");
39
+
40
+ var _mobxStateTree = require("mobx-state-tree");
41
+
42
+ var _MenuOpen = _interopRequireDefault(require("@material-ui/icons/MenuOpen"));
43
+
44
+ var _BaseLinearDisplay = require("../components/BaseLinearDisplay");
45
+
46
+ var _serverSideRenderedBlock = _interopRequireWildcard(require("./serverSideRenderedBlock"));
47
+
48
+ var _excluded = ["blockState"];
49
+
50
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
51
+
52
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
53
+
54
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
55
+
56
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
57
+
58
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
59
+
60
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
61
+
62
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
63
+
64
+ // stabilize clipid under test for snapshot
65
+ function getId(id, index) {
66
+ var isJest = typeof jest === 'undefined';
67
+ return "clip-".concat(isJest ? id : 'jest', "-").concat(index);
68
+ }
69
+
70
+ function getDisplayStr(totalBytes) {
71
+ var displayBp;
72
+
73
+ if (Math.floor(totalBytes / 1000000) > 0) {
74
+ displayBp = "".concat(parseFloat((totalBytes / 1000000).toPrecision(3)), " Mb");
75
+ } else if (Math.floor(totalBytes / 1000) > 0) {
76
+ displayBp = "".concat(parseFloat((totalBytes / 1000).toPrecision(3)), " Kb");
77
+ } else {
78
+ displayBp = "".concat(Math.floor(totalBytes), " bytes");
79
+ }
80
+
81
+ return displayBp;
82
+ }
83
+
84
+ var minDisplayHeight = 20;
85
+ var defaultDisplayHeight = 100;
86
+
87
+ var BaseLinearDisplay = _mobxStateTree.types.compose('BaseLinearDisplay', _models.BaseDisplay, _mobxStateTree.types.model({
88
+ height: _mobxStateTree.types.optional(_mobxStateTree.types.refinement('displayHeight', _mobxStateTree.types.number, function (n) {
89
+ return n >= minDisplayHeight;
90
+ }), defaultDisplayHeight),
91
+ blockState: _mobxStateTree.types.map(_serverSideRenderedBlock["default"]),
92
+ userBpPerPxLimit: _mobxStateTree.types.maybe(_mobxStateTree.types.number),
93
+ userByteSizeLimit: _mobxStateTree.types.maybe(_mobxStateTree.types.number)
94
+ }))["volatile"](function () {
95
+ return {
96
+ currBpPerPx: 0,
97
+ message: '',
98
+ featureIdUnderMouse: undefined,
99
+ contextMenuFeature: undefined,
100
+ scrollTop: 0,
101
+ estimatedRegionStatsP: undefined,
102
+ estimatedRegionStats: undefined
103
+ };
104
+ }).views(function (self) {
105
+ return {
106
+ get blockType() {
107
+ return 'staticBlocks';
108
+ },
109
+
110
+ get blockDefinitions() {
111
+ var blockType = this.blockType;
112
+ var view = (0, _util.getContainingView)(self);
113
+
114
+ if (!view.initialized) {
115
+ throw new Error('view not initialized yet');
116
+ }
117
+
118
+ return view[blockType];
119
+ }
120
+
121
+ };
122
+ }).views(function (self) {
123
+ return {
124
+ /**
125
+ * how many milliseconds to wait for the display to
126
+ * "settle" before re-rendering a block
127
+ */
128
+ get renderDelay() {
129
+ return 50;
130
+ },
131
+
132
+ get TooltipComponent() {
133
+ return _BaseLinearDisplay.Tooltip;
134
+ },
135
+
136
+ /**
137
+ * returns a string feature ID if the globally-selected object
138
+ * is probably a feature
139
+ */
140
+ get selectedFeatureId() {
141
+ if ((0, _mobxStateTree.isAlive)(self)) {
142
+ var _getSession = (0, _util.getSession)(self),
143
+ selection = _getSession.selection; // does it quack like a feature?
144
+
145
+
146
+ if ((0, _simpleFeature.isFeature)(selection)) {
147
+ return selection.id();
148
+ }
149
+ }
150
+
151
+ return undefined;
152
+ },
153
+
154
+ /**
155
+ * if a display-level message should be displayed instead of the blocks,
156
+ * make this return a react component
157
+ */
158
+ get DisplayMessageComponent() {
159
+ return undefined;
160
+ }
161
+
162
+ };
163
+ }).views(function (self) {
164
+ return {
165
+ /**
166
+ * a CompositeMap of `featureId -> feature obj` that
167
+ * just looks in all the block data for that feature
168
+ */
169
+ get features() {
170
+ var featureMaps = [];
171
+
172
+ var _iterator = _createForOfIteratorHelper(self.blockState.values()),
173
+ _step;
174
+
175
+ try {
176
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
177
+ var block = _step.value;
178
+
179
+ if (block && block.features) {
180
+ featureMaps.push(block.features);
181
+ }
182
+ }
183
+ } catch (err) {
184
+ _iterator.e(err);
185
+ } finally {
186
+ _iterator.f();
187
+ }
188
+
189
+ return new _compositeMap["default"](featureMaps);
190
+ },
191
+
192
+ get featureUnderMouse() {
193
+ var feat = self.featureIdUnderMouse;
194
+ return feat ? this.features.get(feat) : undefined;
195
+ },
196
+
197
+ getFeatureOverlapping: function getFeatureOverlapping(blockKey, x, y) {
198
+ var _self$blockState$get, _self$blockState$get$;
199
+
200
+ return (_self$blockState$get = self.blockState.get(blockKey)) === null || _self$blockState$get === void 0 ? void 0 : (_self$blockState$get$ = _self$blockState$get.layout) === null || _self$blockState$get$ === void 0 ? void 0 : _self$blockState$get$.getByCoord(x, y);
201
+ },
202
+ getFeatureByID: function getFeatureByID(blockKey, id) {
203
+ var _self$blockState$get2, _self$blockState$get3;
204
+
205
+ return (_self$blockState$get2 = self.blockState.get(blockKey)) === null || _self$blockState$get2 === void 0 ? void 0 : (_self$blockState$get3 = _self$blockState$get2.layout) === null || _self$blockState$get3 === void 0 ? void 0 : _self$blockState$get3.getByID(id);
206
+ },
207
+ // if block key is not supplied, can look at all blocks
208
+ searchFeatureByID: function searchFeatureByID(id) {
209
+ var ret;
210
+ self.blockState.forEach(function (block) {
211
+ var _block$layout;
212
+
213
+ var val = block === null || block === void 0 ? void 0 : (_block$layout = block.layout) === null || _block$layout === void 0 ? void 0 : _block$layout.getByID(id);
214
+
215
+ if (val) {
216
+ ret = val;
217
+ }
218
+ });
219
+ return ret;
220
+ },
221
+
222
+ get currentBytesRequested() {
223
+ var _self$estimatedRegion;
224
+
225
+ return ((_self$estimatedRegion = self.estimatedRegionStats) === null || _self$estimatedRegion === void 0 ? void 0 : _self$estimatedRegion.bytes) || 0;
226
+ },
227
+
228
+ get currentFeatureScreenDensity() {
229
+ var _self$estimatedRegion2;
230
+
231
+ var view = (0, _util.getContainingView)(self);
232
+ return (((_self$estimatedRegion2 = self.estimatedRegionStats) === null || _self$estimatedRegion2 === void 0 ? void 0 : _self$estimatedRegion2.featureDensity) || 0) * view.bpPerPx;
233
+ },
234
+
235
+ get maxFeatureScreenDensity() {
236
+ return (0, _configuration.getConf)(self, 'maxFeatureScreenDensity');
237
+ },
238
+
239
+ get estimatedStatsReady() {
240
+ return !!self.estimatedRegionStats;
241
+ },
242
+
243
+ get maxAllowableBytes() {
244
+ var _self$estimatedRegion3;
245
+
246
+ return self.userByteSizeLimit || ((_self$estimatedRegion3 = self.estimatedRegionStats) === null || _self$estimatedRegion3 === void 0 ? void 0 : _self$estimatedRegion3.fetchSizeLimit) || (0, _configuration.getConf)(self, 'fetchSizeLimit');
247
+ }
248
+
249
+ };
250
+ }).actions(function (self) {
251
+ return {
252
+ // base display reload does nothing, see specialized displays for details
253
+ setMessage: function setMessage(message) {
254
+ self.message = message;
255
+ },
256
+ afterAttach: function afterAttach() {
257
+ var _this = this;
258
+
259
+ // watch the parent's blocks to update our block state when they change,
260
+ // then we recreate the blocks on our own model (creating and deleting to
261
+ // match the parent blocks)
262
+ var blockWatchDisposer = (0, _mobx.autorun)(function () {
263
+ var blocksPresent = {};
264
+ var view = (0, _util.getContainingView)(self);
265
+
266
+ if (view.initialized) {
267
+ self.blockDefinitions.contentBlocks.forEach(function (block) {
268
+ blocksPresent[block.key] = true;
269
+
270
+ if (!self.blockState.has(block.key)) {
271
+ _this.addBlock(block.key, block);
272
+ }
273
+ });
274
+ self.blockState.forEach(function (_, key) {
275
+ if (!blocksPresent[key]) {
276
+ _this.deleteBlock(key);
277
+ }
278
+ });
279
+ }
280
+ });
281
+ (0, _mobxStateTree.addDisposer)(self, blockWatchDisposer);
282
+ },
283
+ estimateRegionsStats: function estimateRegionsStats(regions, opts) {
284
+ var _this2 = this;
285
+
286
+ if (self.estimatedRegionStatsP) {
287
+ return self.estimatedRegionStatsP;
288
+ }
289
+
290
+ var _getSession2 = (0, _util.getSession)(self),
291
+ rpcManager = _getSession2.rpcManager;
292
+
293
+ var adapterConfig = self.adapterConfig;
294
+ var sessionId = (0, _tracks.getRpcSessionId)(self);
295
+
296
+ var params = _objectSpread({
297
+ sessionId: sessionId,
298
+ regions: regions,
299
+ adapterConfig: adapterConfig,
300
+ statusCallback: function statusCallback(message) {
301
+ if ((0, _mobxStateTree.isAlive)(self)) {
302
+ _this2.setMessage(message);
303
+ }
304
+ }
305
+ }, opts);
306
+
307
+ self.estimatedRegionStatsP = rpcManager.call(sessionId, 'CoreEstimateRegionStats', params)["catch"](function (e) {
308
+ _this2.setRegionStatsP(undefined);
309
+
310
+ throw e;
311
+ });
312
+ return self.estimatedRegionStatsP;
313
+ },
314
+ setRegionStatsP: function setRegionStatsP(p) {
315
+ self.estimatedRegionStatsP = p;
316
+ },
317
+ setRegionStats: function setRegionStats(estimatedRegionStats) {
318
+ self.estimatedRegionStats = estimatedRegionStats;
319
+ },
320
+ clearRegionStats: function clearRegionStats() {
321
+ self.estimatedRegionStatsP = undefined;
322
+ self.estimatedRegionStats = undefined;
323
+ },
324
+ setHeight: function setHeight(displayHeight) {
325
+ if (displayHeight > minDisplayHeight) {
326
+ self.height = displayHeight;
327
+ } else {
328
+ self.height = minDisplayHeight;
329
+ }
330
+
331
+ return self.height;
332
+ },
333
+ resizeHeight: function resizeHeight(distance) {
334
+ var oldHeight = self.height;
335
+ var newHeight = this.setHeight(self.height + distance);
336
+ return newHeight - oldHeight;
337
+ },
338
+ setScrollTop: function setScrollTop(scrollTop) {
339
+ self.scrollTop = scrollTop;
340
+ },
341
+ updateStatsLimit: function updateStatsLimit(stats) {
342
+ var view = (0, _util.getContainingView)(self);
343
+
344
+ if (stats.bytes) {
345
+ self.userByteSizeLimit = stats.bytes;
346
+ } else {
347
+ self.userBpPerPxLimit = view.bpPerPx;
348
+ }
349
+ },
350
+ addBlock: function addBlock(key, block) {
351
+ self.blockState.set(key, _serverSideRenderedBlock["default"].create({
352
+ key: key,
353
+ region: block.toRegion()
354
+ }));
355
+ },
356
+ setCurrBpPerPx: function setCurrBpPerPx(n) {
357
+ self.currBpPerPx = n;
358
+ },
359
+ deleteBlock: function deleteBlock(key) {
360
+ self.blockState["delete"](key);
361
+ },
362
+ selectFeature: function selectFeature(feature) {
363
+ var session = (0, _util.getSession)(self);
364
+
365
+ if ((0, _util.isSessionModelWithWidgets)(session)) {
366
+ var featureWidget = session.addWidget('BaseFeatureWidget', 'baseFeature', {
367
+ featureData: feature.toJSON(),
368
+ view: (0, _util.getContainingView)(self)
369
+ });
370
+ session.showWidget(featureWidget);
371
+ }
372
+
373
+ if ((0, _util.isSelectionContainer)(session)) {
374
+ session.setSelection(feature);
375
+ }
376
+ },
377
+ clearFeatureSelection: function clearFeatureSelection() {
378
+ var session = (0, _util.getSession)(self);
379
+ session.clearSelection();
380
+ },
381
+ setFeatureIdUnderMouse: function setFeatureIdUnderMouse(feature) {
382
+ self.featureIdUnderMouse = feature;
383
+ },
384
+ reload: function reload() {
385
+ ;
386
+ (0, _toConsumableArray2["default"])(self.blockState.values()).map(function (val) {
387
+ return val.doReload();
388
+ });
389
+ },
390
+ setContextMenuFeature: function setContextMenuFeature(feature) {
391
+ self.contextMenuFeature = feature;
392
+ }
393
+ };
394
+ }).views(function (self) {
395
+ return {
396
+ // region is too large if:
397
+ // - stats are ready
398
+ // - region is greater than 20kb (don't warn when zoomed in less than that)
399
+ // - and bytes > max allowed bytes || curr density>max density
400
+ get regionTooLarge() {
401
+ var view = (0, _util.getContainingView)(self);
402
+
403
+ if (!self.estimatedStatsReady || view.dynamicBlocks.totalBp < 20000) {
404
+ return false;
405
+ }
406
+
407
+ var bpLimitOrDensity = self.userBpPerPxLimit ? view.bpPerPx > self.userBpPerPxLimit : self.currentFeatureScreenDensity > self.maxFeatureScreenDensity;
408
+ return self.currentBytesRequested > self.maxAllowableBytes || bpLimitOrDensity;
409
+ },
410
+
411
+ // only shows a message of bytes requested is defined, the feature density
412
+ // based stats don't produce any helpful message besides to zoom in
413
+ get regionTooLargeReason() {
414
+ var req = self.currentBytesRequested;
415
+ var max = self.maxAllowableBytes;
416
+ return req && req > max ? "Requested too much data (".concat(getDisplayStr(req), ")") : '';
417
+ }
418
+
419
+ };
420
+ }).actions(function (self) {
421
+ var superReload = self.reload;
422
+ return {
423
+ reload: function reload() {
424
+ return (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee() {
425
+ var aborter, view, estimatedRegionStats;
426
+ return _regenerator["default"].wrap(function _callee$(_context) {
427
+ while (1) {
428
+ switch (_context.prev = _context.next) {
429
+ case 0:
430
+ self.setError();
431
+ aborter = new AbortController();
432
+ view = (0, _util.getContainingView)(self); // extra check for contentBlocks.length
433
+ // https://github.com/GMOD/jbrowse-components/issues/2694
434
+
435
+ if (!(!view.initialized || !view.staticBlocks.contentBlocks.length)) {
436
+ _context.next = 5;
437
+ break;
438
+ }
439
+
440
+ return _context.abrupt("return");
441
+
442
+ case 5:
443
+ _context.prev = 5;
444
+ self.estimatedRegionStatsP = self.estimateRegionsStats(view.staticBlocks.contentBlocks, {
445
+ signal: aborter.signal
446
+ });
447
+ _context.next = 9;
448
+ return self.estimatedRegionStatsP;
449
+
450
+ case 9:
451
+ estimatedRegionStats = _context.sent;
452
+
453
+ if (!(0, _mobxStateTree.isAlive)(self)) {
454
+ _context.next = 15;
455
+ break;
456
+ }
457
+
458
+ self.setRegionStats(estimatedRegionStats);
459
+ superReload();
460
+ _context.next = 16;
461
+ break;
462
+
463
+ case 15:
464
+ return _context.abrupt("return");
465
+
466
+ case 16:
467
+ _context.next = 21;
468
+ break;
469
+
470
+ case 18:
471
+ _context.prev = 18;
472
+ _context.t0 = _context["catch"](5);
473
+ self.setError(_context.t0);
474
+
475
+ case 21:
476
+ case "end":
477
+ return _context.stop();
478
+ }
479
+ }
480
+ }, _callee, null, [[5, 18]]);
481
+ }))();
482
+ },
483
+ afterAttach: function afterAttach() {
484
+ // this autorun performs stats estimation
485
+ //
486
+ // the chain of events calls estimateRegionsStats against the data
487
+ // adapter which by default uses featureDensity, but can also respond
488
+ // with a byte size estimate and fetch size limit (data adapter can
489
+ // define what is too much data)
490
+ (0, _mobxStateTree.addDisposer)(self, (0, _mobx.autorun)( /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() {
491
+ var _self$estimatedRegion4, aborter, view, statsP, estimatedRegionStats;
492
+
493
+ return _regenerator["default"].wrap(function _callee2$(_context2) {
494
+ while (1) {
495
+ switch (_context2.prev = _context2.next) {
496
+ case 0:
497
+ _context2.prev = 0;
498
+ aborter = new AbortController();
499
+ view = (0, _util.getContainingView)(self); // extra check for contentBlocks.length
500
+ // https://github.com/GMOD/jbrowse-components/issues/2694
501
+
502
+ if (!(!view.initialized || !view.staticBlocks.contentBlocks.length)) {
503
+ _context2.next = 5;
504
+ break;
505
+ }
506
+
507
+ return _context2.abrupt("return");
508
+
509
+ case 5:
510
+ if (!(((_self$estimatedRegion4 = self.estimatedRegionStats) === null || _self$estimatedRegion4 === void 0 ? void 0 : _self$estimatedRegion4.featureDensity) !== undefined)) {
511
+ _context2.next = 8;
512
+ break;
513
+ }
514
+
515
+ self.setCurrBpPerPx(view.bpPerPx);
516
+ return _context2.abrupt("return");
517
+
518
+ case 8:
519
+ if (!(view.bpPerPx === self.currBpPerPx)) {
520
+ _context2.next = 10;
521
+ break;
522
+ }
523
+
524
+ return _context2.abrupt("return");
525
+
526
+ case 10:
527
+ self.clearRegionStats();
528
+ self.setCurrBpPerPx(view.bpPerPx);
529
+ statsP = self.estimateRegionsStats(view.staticBlocks.contentBlocks, {
530
+ signal: aborter.signal
531
+ });
532
+ self.setRegionStatsP(statsP);
533
+ _context2.next = 16;
534
+ return statsP;
535
+
536
+ case 16:
537
+ estimatedRegionStats = _context2.sent;
538
+
539
+ if ((0, _mobxStateTree.isAlive)(self)) {
540
+ self.setRegionStats(estimatedRegionStats);
541
+ }
542
+
543
+ _context2.next = 23;
544
+ break;
545
+
546
+ case 20:
547
+ _context2.prev = 20;
548
+ _context2.t0 = _context2["catch"](0);
549
+
550
+ if (!(0, _util.isAbortException)(_context2.t0) && (0, _mobxStateTree.isAlive)(self)) {
551
+ console.error(_context2.t0);
552
+ self.setError(_context2.t0);
553
+ }
554
+
555
+ case 23:
556
+ case "end":
557
+ return _context2.stop();
558
+ }
559
+ }
560
+ }, _callee2, null, [[0, 20]]);
561
+ })), {
562
+ delay: 500
563
+ }));
564
+ }
565
+ };
566
+ }).views(function (self) {
567
+ return {
568
+ regionCannotBeRenderedText: function regionCannotBeRenderedText(_region) {
569
+ return self.regionTooLarge ? 'Force load to see features' : '';
570
+ },
571
+
572
+ /**
573
+ * @param region -
574
+ * @returns falsy if the region is fine to try rendering. Otherwise,
575
+ * return a react node + string of text.
576
+ * string of text describes why it cannot be rendered
577
+ * react node allows user to force load at current setting
578
+ */
579
+ regionCannotBeRendered: function regionCannotBeRendered(_region) {
580
+ var regionTooLarge = self.regionTooLarge,
581
+ regionTooLargeReason = self.regionTooLargeReason;
582
+
583
+ if (regionTooLarge) {
584
+ return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(_core.Typography, {
585
+ component: "span",
586
+ variant: "body2"
587
+ }, regionTooLargeReason ? regionTooLargeReason + '. ' : '', "Zoom in to see features or", ' '), /*#__PURE__*/_react["default"].createElement(_core.Button, {
588
+ "data-testid": "force_reload_button",
589
+ onClick: function onClick() {
590
+ if (!self.estimatedRegionStats) {
591
+ console.error('No global stats?');
592
+ } else {
593
+ self.updateStatsLimit(self.estimatedRegionStats);
594
+ self.reload();
595
+ }
596
+ },
597
+ variant: "outlined"
598
+ }, "Force Load"), /*#__PURE__*/_react["default"].createElement(_core.Typography, {
599
+ component: "span",
600
+ variant: "body2"
601
+ }, "(force load may be slow)"));
602
+ }
603
+
604
+ return undefined;
605
+ },
606
+ trackMenuItems: function trackMenuItems() {
607
+ return [];
608
+ },
609
+ contextMenuItems: function contextMenuItems() {
610
+ return self.contextMenuFeature ? [{
611
+ label: 'Open feature details',
612
+ icon: _MenuOpen["default"],
613
+ onClick: function onClick() {
614
+ if (self.contextMenuFeature) {
615
+ self.selectFeature(self.contextMenuFeature);
616
+ }
617
+ }
618
+ }] : [];
619
+ },
620
+ renderProps: function renderProps() {
621
+ var view = (0, _util.getContainingView)(self);
622
+ return _objectSpread(_objectSpread({}, (0, _tracks.getParentRenderProps)(self)), {}, {
623
+ notReady: self.currBpPerPx !== view.bpPerPx || !self.estimatedRegionStats,
624
+ rpcDriverName: self.rpcDriverName,
625
+ displayModel: self,
626
+ onFeatureClick: function onFeatureClick(_, featureId) {
627
+ var f = featureId || self.featureIdUnderMouse;
628
+
629
+ if (!f) {
630
+ self.clearFeatureSelection();
631
+ } else {
632
+ var feature = self.features.get(f);
633
+
634
+ if (feature) {
635
+ self.selectFeature(feature);
636
+ }
637
+ }
638
+ },
639
+ onClick: function onClick() {
640
+ self.clearFeatureSelection();
641
+ },
642
+ // similar to click but opens a menu with further options
643
+ onFeatureContextMenu: function onFeatureContextMenu(_, featureId) {
644
+ var f = featureId || self.featureIdUnderMouse;
645
+
646
+ if (!f) {
647
+ self.clearFeatureSelection();
648
+ } else {
649
+ // feature id under mouse passed to context menu
650
+ self.setContextMenuFeature(self.features.get(f));
651
+ }
652
+ },
653
+ onMouseMove: function onMouseMove(_, featureId) {
654
+ self.setFeatureIdUnderMouse(featureId);
655
+ },
656
+ onMouseLeave: function onMouseLeave(_) {
657
+ self.setFeatureIdUnderMouse(undefined);
658
+ },
659
+ onContextMenu: function onContextMenu() {
660
+ self.setContextMenuFeature(undefined);
661
+ self.clearFeatureSelection();
662
+ }
663
+ });
664
+ }
665
+ };
666
+ }).actions(function (self) {
667
+ return {
668
+ renderSvg: function renderSvg(opts) {
669
+ return (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3() {
670
+ var height, id, overrideHeight, view, viewOffsetPx, roundedDynamicBlocks, width, renderings;
671
+ return _regenerator["default"].wrap(function _callee3$(_context3) {
672
+ while (1) {
673
+ switch (_context3.prev = _context3.next) {
674
+ case 0:
675
+ height = self.height, id = self.id;
676
+ overrideHeight = opts.overrideHeight;
677
+ view = (0, _util.getContainingView)(self);
678
+ viewOffsetPx = view.offsetPx, roundedDynamicBlocks = view.roundedDynamicBlocks, width = view.width;
679
+ _context3.next = 6;
680
+ return Promise.all(roundedDynamicBlocks.map(function (block) {
681
+ var blockState = _serverSideRenderedBlock["default"].create({
682
+ key: block.key,
683
+ region: block
684
+ }); // regionCannotBeRendered can return jsx so look for plaintext
685
+ // version, or just get the default if none available
686
+
687
+
688
+ // regionCannotBeRendered can return jsx so look for plaintext
689
+ // version, or just get the default if none available
690
+ var cannotBeRenderedReason = self.regionCannotBeRenderedText(block) || self.regionCannotBeRendered(block);
691
+
692
+ if (cannotBeRenderedReason) {
693
+ return {
694
+ reactElement: /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("rect", {
695
+ x: 0,
696
+ y: 0,
697
+ width: width,
698
+ height: 20,
699
+ fill: "#aaa"
700
+ }), /*#__PURE__*/_react["default"].createElement("text", {
701
+ x: 0,
702
+ y: 15
703
+ }, cannotBeRenderedReason))
704
+ };
705
+ }
706
+
707
+ var _renderBlockData = (0, _serverSideRenderedBlock.renderBlockData)(blockState, self),
708
+ rpcManager = _renderBlockData.rpcManager,
709
+ renderArgs = _renderBlockData.renderArgs,
710
+ renderProps = _renderBlockData.renderProps,
711
+ rendererType = _renderBlockData.rendererType;
712
+
713
+ return rendererType.renderInClient(rpcManager, _objectSpread(_objectSpread(_objectSpread({}, renderArgs), renderProps), {}, {
714
+ viewParams: (0, _util.getViewParams)(self, true),
715
+ exportSVG: opts
716
+ }));
717
+ }));
718
+
719
+ case 6:
720
+ renderings = _context3.sent;
721
+ return _context3.abrupt("return", /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, renderings.map(function (rendering, index) {
722
+ var offsetPx = roundedDynamicBlocks[index].offsetPx;
723
+ var offset = offsetPx - viewOffsetPx;
724
+ var clipid = getId(id, index);
725
+ return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, {
726
+ key: "frag-".concat(index)
727
+ }, /*#__PURE__*/_react["default"].createElement("defs", null, /*#__PURE__*/_react["default"].createElement("clipPath", {
728
+ id: clipid
729
+ }, /*#__PURE__*/_react["default"].createElement("rect", {
730
+ x: 0,
731
+ y: 0,
732
+ width: width,
733
+ height: overrideHeight || height
734
+ }))), /*#__PURE__*/_react["default"].createElement("g", {
735
+ transform: "translate(".concat(offset, " 0)")
736
+ }, /*#__PURE__*/_react["default"].createElement("g", {
737
+ clipPath: "url(#".concat(clipid, ")")
738
+ }, /*#__PURE__*/_react["default"].isValidElement(rendering.reactElement) ? rendering.reactElement :
739
+ /*#__PURE__*/
740
+ // eslint-disable-next-line react/no-danger
741
+ _react["default"].createElement("g", {
742
+ dangerouslySetInnerHTML: {
743
+ __html: rendering.html
744
+ }
745
+ }))));
746
+ })));
747
+
748
+ case 8:
749
+ case "end":
750
+ return _context3.stop();
751
+ }
752
+ }
753
+ }, _callee3);
754
+ }))();
755
+ }
756
+ };
757
+ }).postProcessSnapshot(function (self) {
758
+ var blockState = self.blockState,
759
+ rest = (0, _objectWithoutProperties2["default"])(self, _excluded);
760
+ return rest;
761
+ });
762
+
763
+ exports.BaseLinearDisplay = BaseLinearDisplay;