@jbrowse/plugin-circular-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.
@@ -0,0 +1,422 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports["default"] = CircularView;
9
+
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
+
12
+ var _mobxStateTree = require("mobx-state-tree");
13
+
14
+ var _mst = require("@jbrowse/core/util/types/mst");
15
+
16
+ var _mobx = require("mobx");
17
+
18
+ var _configuration = require("@jbrowse/core/configuration");
19
+
20
+ var _util = require("@jbrowse/core/util");
21
+
22
+ var _models = require("@jbrowse/core/pluggableElementTypes/models");
23
+
24
+ var _slices = require("./slices");
25
+
26
+ var _viewportVisibleRegion = require("./viewportVisibleRegion");
27
+
28
+ 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; }
29
+
30
+ 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; }
31
+
32
+ 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; } } }; }
33
+
34
+ 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); }
35
+
36
+ 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; }
37
+
38
+ function CircularView(pluginManager) {
39
+ var minHeight = 40;
40
+ var minWidth = 100;
41
+ var defaultHeight = 400;
42
+ return _mobxStateTree.types.compose(_models.BaseViewModel, _mobxStateTree.types.model('CircularView', {
43
+ type: _mobxStateTree.types.literal('CircularView'),
44
+ offsetRadians: -Math.PI / 2,
45
+ bpPerPx: 2000000,
46
+ tracks: _mobxStateTree.types.array(pluginManager.pluggableMstType('track', 'stateModel')),
47
+ hideVerticalResizeHandle: false,
48
+ hideTrackSelectorButton: false,
49
+ lockedFitToWindow: true,
50
+ disableImportForm: false,
51
+ height: _mobxStateTree.types.optional(_mobxStateTree.types.refinement('trackHeight', _mobxStateTree.types.number, function (n) {
52
+ return n >= minHeight;
53
+ }), defaultHeight),
54
+ minimumRadiusPx: 25,
55
+ spacingPx: 10,
56
+ paddingPx: 80,
57
+ lockedPaddingPx: 100,
58
+ minVisibleWidth: 6,
59
+ minimumBlockWidth: 20,
60
+ displayedRegions: _mobxStateTree.types.array(_mst.Region),
61
+ scrollX: 0,
62
+ scrollY: 0,
63
+ trackSelectorType: 'hierarchical'
64
+ })["volatile"](function () {
65
+ return {
66
+ width: 0
67
+ };
68
+ }).views(function (self) {
69
+ return {
70
+ get staticSlices() {
71
+ return (0, _slices.calculateStaticSlices)(self);
72
+ },
73
+
74
+ get visibleStaticSlices() {
75
+ return this.staticSlices.filter(_slices.sliceIsVisible.bind(this, self));
76
+ },
77
+
78
+ get visibleSection() {
79
+ return (0, _viewportVisibleRegion.viewportVisibleSection)([self.scrollX, self.scrollX + self.width, self.scrollY, self.scrollY + self.height], this.centerXY, this.radiusPx);
80
+ },
81
+
82
+ get circumferencePx() {
83
+ var elidedBp = 0;
84
+
85
+ var _iterator = _createForOfIteratorHelper(this.elidedRegions),
86
+ _step;
87
+
88
+ try {
89
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
90
+ var r = _step.value;
91
+ elidedBp += r.widthBp;
92
+ }
93
+ } catch (err) {
94
+ _iterator.e(err);
95
+ } finally {
96
+ _iterator.f();
97
+ }
98
+
99
+ return elidedBp / self.bpPerPx + self.spacingPx * this.elidedRegions.length;
100
+ },
101
+
102
+ get radiusPx() {
103
+ return this.circumferencePx / (2 * Math.PI);
104
+ },
105
+
106
+ get bpPerRadian() {
107
+ return self.bpPerPx * this.radiusPx;
108
+ },
109
+
110
+ get pxPerRadian() {
111
+ return this.radiusPx;
112
+ },
113
+
114
+ get centerXY() {
115
+ return [this.radiusPx + self.paddingPx, this.radiusPx + self.paddingPx];
116
+ },
117
+
118
+ get totalBp() {
119
+ var total = 0;
120
+
121
+ var _iterator2 = _createForOfIteratorHelper(self.displayedRegions),
122
+ _step2;
123
+
124
+ try {
125
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
126
+ var region = _step2.value;
127
+ total += region.end - region.start;
128
+ }
129
+ } catch (err) {
130
+ _iterator2.e(err);
131
+ } finally {
132
+ _iterator2.f();
133
+ }
134
+
135
+ return total;
136
+ },
137
+
138
+ get maximumRadiusPx() {
139
+ return self.lockedFitToWindow ? Math.min(self.width, self.height) / 2 - self.lockedPaddingPx : 1000000;
140
+ },
141
+
142
+ get maxBpPerPx() {
143
+ var minCircumferencePx = 2 * Math.PI * self.minimumRadiusPx;
144
+ return this.totalBp / minCircumferencePx;
145
+ },
146
+
147
+ get minBpPerPx() {
148
+ // min depends on window dimensions, clamp between old min(0.01) and max
149
+ var maxCircumferencePx = 2 * Math.PI * this.maximumRadiusPx;
150
+ return (0, _util.clamp)(this.totalBp / maxCircumferencePx, 0.0000000001, this.maxBpPerPx);
151
+ },
152
+
153
+ get atMaxBpPerPx() {
154
+ return self.bpPerPx >= this.maxBpPerPx;
155
+ },
156
+
157
+ get atMinBpPerPx() {
158
+ return self.bpPerPx <= this.minBpPerPx;
159
+ },
160
+
161
+ get tooSmallToLock() {
162
+ return this.minBpPerPx <= 0.0000000001;
163
+ },
164
+
165
+ get figureDimensions() {
166
+ return [this.radiusPx * 2 + 2 * self.paddingPx, this.radiusPx * 2 + 2 * self.paddingPx];
167
+ },
168
+
169
+ get figureWidth() {
170
+ return this.figureDimensions[0];
171
+ },
172
+
173
+ get figureHeight() {
174
+ return this.figureDimensions[1];
175
+ },
176
+
177
+ // this is displayedRegions, post-processed to
178
+ // elide regions that are too small to see reasonably
179
+ get elidedRegions() {
180
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
181
+ var visible = [];
182
+ self.displayedRegions.forEach(function (region) {
183
+ var widthBp = region.end - region.start;
184
+ var widthPx = widthBp / self.bpPerPx;
185
+
186
+ if (widthPx < self.minVisibleWidth) {
187
+ // too small to see, collapse into a single elision region
188
+ var lastVisible = visible[visible.length - 1];
189
+
190
+ if (lastVisible && lastVisible.elided) {
191
+ lastVisible.regions.push(_objectSpread({}, region));
192
+ lastVisible.widthBp += widthBp;
193
+ } else {
194
+ visible.push({
195
+ elided: true,
196
+ widthBp: widthBp,
197
+ regions: [_objectSpread({}, region)]
198
+ });
199
+ }
200
+ } else {
201
+ // big enough to see, display it
202
+ visible.push(_objectSpread(_objectSpread({}, region), {}, {
203
+ widthBp: widthBp
204
+ }));
205
+ }
206
+ }); // remove any single-region elisions
207
+
208
+ for (var i = 0; i < visible.length; i += 1) {
209
+ var v = visible[i];
210
+
211
+ if (v.elided && v.regions.length === 1) {
212
+ delete v.elided;
213
+ visible[i] = _objectSpread(_objectSpread({}, v), v.regions[0]);
214
+ }
215
+ }
216
+
217
+ return visible;
218
+ },
219
+
220
+ get assemblyNames() {
221
+ var assemblyNames = [];
222
+ self.displayedRegions.forEach(function (displayedRegion) {
223
+ if (!assemblyNames.includes(displayedRegion.assemblyName)) {
224
+ assemblyNames.push(displayedRegion.assemblyName);
225
+ }
226
+ });
227
+ return assemblyNames;
228
+ },
229
+
230
+ get initialized() {
231
+ var _getSession = (0, _util.getSession)(self),
232
+ assemblyManager = _getSession.assemblyManager;
233
+
234
+ return this.assemblyNames.every(function (a) {
235
+ var _assemblyManager$get;
236
+
237
+ return (_assemblyManager$get = assemblyManager.get(a)) === null || _assemblyManager$get === void 0 ? void 0 : _assemblyManager$get.initialized;
238
+ });
239
+ }
240
+
241
+ };
242
+ })["volatile"](function () {
243
+ return {
244
+ error: undefined
245
+ };
246
+ }).actions(function (self) {
247
+ return {
248
+ // toggle action with a flag stating which mode it's in
249
+ setWidth: function setWidth(newWidth) {
250
+ self.width = Math.max(newWidth, minWidth);
251
+ return self.width;
252
+ },
253
+ setHeight: function setHeight(newHeight) {
254
+ self.height = Math.max(newHeight, minHeight);
255
+ return self.height;
256
+ },
257
+ resizeHeight: function resizeHeight(distance) {
258
+ var oldHeight = self.height;
259
+ var newHeight = this.setHeight(self.height + distance);
260
+ this.setModelViewWhenAdjust(!self.tooSmallToLock);
261
+ return newHeight - oldHeight;
262
+ },
263
+ resizeWidth: function resizeWidth(distance) {
264
+ var oldWidth = self.width;
265
+ var newWidth = this.setWidth(self.width + distance);
266
+ this.setModelViewWhenAdjust(!self.tooSmallToLock);
267
+ return newWidth - oldWidth;
268
+ },
269
+ rotateClockwiseButton: function rotateClockwiseButton() {
270
+ this.rotateClockwise(Math.PI / 6);
271
+ },
272
+ rotateCounterClockwiseButton: function rotateCounterClockwiseButton() {
273
+ this.rotateCounterClockwise(Math.PI / 6);
274
+ },
275
+ rotateClockwise: function rotateClockwise() {
276
+ var distance = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0.17;
277
+ self.offsetRadians += distance;
278
+ },
279
+ rotateCounterClockwise: function rotateCounterClockwise() {
280
+ var distance = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0.17;
281
+ self.offsetRadians -= distance;
282
+ },
283
+ zoomInButton: function zoomInButton() {
284
+ this.setBpPerPx(self.bpPerPx / 1.4);
285
+ },
286
+ zoomOutButton: function zoomOutButton() {
287
+ this.setBpPerPx(self.bpPerPx * 1.4);
288
+ },
289
+ setBpPerPx: function setBpPerPx(newVal) {
290
+ self.bpPerPx = (0, _util.clamp)(newVal, self.minBpPerPx, self.maxBpPerPx);
291
+ },
292
+ setModelViewWhenAdjust: function setModelViewWhenAdjust(secondCondition) {
293
+ if (self.lockedFitToWindow && secondCondition) {
294
+ this.setBpPerPx(self.minBpPerPx);
295
+ }
296
+ },
297
+ closeView: function closeView() {
298
+ (0, _mobxStateTree.getParent)(self, 2).removeView(self);
299
+ },
300
+ setDisplayedRegions: function setDisplayedRegions(regions) {
301
+ var previouslyEmpty = self.displayedRegions.length === 0;
302
+ self.displayedRegions = (0, _mobxStateTree.cast)(regions);
303
+
304
+ if (previouslyEmpty) {
305
+ this.setBpPerPx(self.minBpPerPx);
306
+ } else {
307
+ this.setBpPerPx(self.bpPerPx);
308
+ }
309
+ },
310
+ activateTrackSelector: function activateTrackSelector() {
311
+ if (self.trackSelectorType === 'hierarchical') {
312
+ var session = (0, _util.getSession)(self);
313
+
314
+ if ((0, _util.isSessionModelWithWidgets)(session)) {
315
+ var selector = session.addWidget('HierarchicalTrackSelectorWidget', 'hierarchicalTrackSelector', {
316
+ view: self
317
+ });
318
+ session.showWidget(selector);
319
+ return selector;
320
+ }
321
+ }
322
+
323
+ throw new Error("invalid track selector type ".concat(self.trackSelectorType));
324
+ },
325
+ toggleTrack: function toggleTrack(trackId) {
326
+ // if we have any tracks with that configuration, turn them off
327
+ var hiddenCount = this.hideTrack(trackId); // if none had that configuration, turn one on
328
+
329
+ if (!hiddenCount) {
330
+ this.showTrack(trackId);
331
+ }
332
+ },
333
+ setError: function setError(error) {
334
+ console.error(error);
335
+ self.error = error;
336
+ },
337
+ showTrack: function showTrack(trackId) {
338
+ var initialSnapshot = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
339
+ var trackConfigSchema = pluginManager.pluggableConfigSchemaType('track');
340
+ var configuration = (0, _mobxStateTree.resolveIdentifier)(trackConfigSchema, (0, _mobxStateTree.getRoot)(self), trackId);
341
+ var trackType = pluginManager.getTrackType(configuration.type);
342
+
343
+ if (!trackType) {
344
+ throw new Error("unknown track type ".concat(configuration.type));
345
+ }
346
+
347
+ var viewType = pluginManager.getViewType(self.type);
348
+ var supportedDisplays = viewType.displayTypes.map(function (displayType) {
349
+ return displayType.name;
350
+ });
351
+ var displayConf = configuration.displays.find(function (d) {
352
+ return supportedDisplays.includes(d.type);
353
+ });
354
+ var track = trackType.stateModel.create(_objectSpread(_objectSpread({}, initialSnapshot), {}, {
355
+ type: configuration.type,
356
+ configuration: configuration,
357
+ displays: [{
358
+ type: displayConf.type,
359
+ configuration: displayConf
360
+ }]
361
+ }));
362
+ self.tracks.push(track);
363
+ },
364
+ addTrackConf: function addTrackConf(configuration) {
365
+ var initialSnapshot = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
366
+ var type = configuration.type;
367
+ var name = (0, _configuration.readConfObject)(configuration, 'name');
368
+ var trackType = pluginManager.getTrackType(type);
369
+
370
+ if (!trackType) {
371
+ throw new Error("unknown track type ".concat(configuration.type));
372
+ }
373
+
374
+ var viewType = pluginManager.getViewType(self.type);
375
+ var supportedDisplays = viewType.displayTypes.map(function (displayType) {
376
+ return displayType.name;
377
+ });
378
+ var displayConf = configuration.displays.find(function (d) {
379
+ return supportedDisplays.includes(d.type);
380
+ });
381
+ var track = trackType.stateModel.create(_objectSpread(_objectSpread({}, initialSnapshot), {}, {
382
+ name: name,
383
+ type: type,
384
+ configuration: configuration,
385
+ displays: [{
386
+ type: displayConf.type,
387
+ configuration: displayConf
388
+ }]
389
+ }));
390
+ self.tracks.push(track);
391
+ },
392
+ hideTrack: function hideTrack(trackId) {
393
+ var trackConfigSchema = pluginManager.pluggableConfigSchemaType('track');
394
+ var configuration = (0, _mobxStateTree.resolveIdentifier)(trackConfigSchema, (0, _mobxStateTree.getRoot)(self), trackId); // if we have any tracks with that configuration, turn them off
395
+
396
+ var shownTracks = self.tracks.filter(function (t) {
397
+ return t.configuration === configuration;
398
+ });
399
+ (0, _mobx.transaction)(function () {
400
+ return shownTracks.forEach(function (t) {
401
+ return self.tracks.remove(t);
402
+ });
403
+ });
404
+ return shownTracks.length;
405
+ },
406
+ toggleFitToWindowLock: function toggleFitToWindowLock() {
407
+ self.lockedFitToWindow = !self.lockedFitToWindow; // when going unlocked -> locked and circle is cut off, set to the locked minBpPerPx
408
+
409
+ this.setModelViewWhenAdjust(self.atMinBpPerPx);
410
+ return self.lockedFitToWindow;
411
+ }
412
+ };
413
+ }));
414
+ }
415
+ /*
416
+ PLANS
417
+
418
+ - tracks
419
+ - ruler tick marks
420
+ - set viewport scroll from state snapshot
421
+
422
+ */
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.Slice = void 0;
9
+ exports.calculateStaticSlices = calculateStaticSlices;
10
+ exports.sliceIsVisible = sliceIsVisible;
11
+
12
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
13
+
14
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
15
+
16
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
17
+
18
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
19
+
20
+ var _util = require("@jbrowse/core/util");
21
+
22
+ var _viewportVisibleRegion = require("./viewportVisibleRegion");
23
+
24
+ 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; } } }; }
25
+
26
+ 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); }
27
+
28
+ 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; }
29
+
30
+ var Slice = /*#__PURE__*/function () {
31
+ function Slice(view, region, currentRadianOffset, radianWidth) {
32
+ (0, _classCallCheck2["default"])(this, Slice);
33
+ this.region = region;
34
+ this.radianWidth = radianWidth;
35
+ (0, _defineProperty2["default"])(this, "key", void 0);
36
+ (0, _defineProperty2["default"])(this, "offsetRadians", void 0);
37
+ (0, _defineProperty2["default"])(this, "startRadians", void 0);
38
+ (0, _defineProperty2["default"])(this, "endRadians", void 0);
39
+ (0, _defineProperty2["default"])(this, "bpPerRadian", void 0);
40
+ (0, _defineProperty2["default"])(this, "flipped", void 0);
41
+ var bpPerRadian = view.bpPerRadian;
42
+ this.key = (0, _util.assembleLocString)(region);
43
+ this.offsetRadians = currentRadianOffset;
44
+ this.bpPerRadian = bpPerRadian;
45
+ this.flipped = false;
46
+ this.startRadians = this.offsetRadians;
47
+ this.endRadians = region.widthBp / this.bpPerRadian + this.offsetRadians;
48
+ Object.freeze(this);
49
+ }
50
+
51
+ (0, _createClass2["default"])(Slice, [{
52
+ key: "bpToXY",
53
+ value: function bpToXY(bp, radiusPx) {
54
+ var offsetBp;
55
+
56
+ if (this.region.elided) {
57
+ offsetBp = this.region.widthBp / 2;
58
+ } else if (this.flipped) {
59
+ offsetBp = this.region.end - bp;
60
+ } else {
61
+ offsetBp = bp - this.region.start;
62
+ }
63
+
64
+ var totalRadians = offsetBp / this.bpPerRadian + this.offsetRadians;
65
+ return (0, _util.polarToCartesian)(radiusPx, totalRadians);
66
+ }
67
+ }, {
68
+ key: "toJSON",
69
+ value: function toJSON() {
70
+ return (0, _util.objectFromEntries)(Object.entries(this));
71
+ }
72
+ }]);
73
+ return Slice;
74
+ }(); // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
+
76
+
77
+ exports.Slice = Slice;
78
+
79
+ function calculateStaticSlices(self) {
80
+ var slices = [];
81
+ var currentRadianOffset = 0;
82
+
83
+ var _iterator = _createForOfIteratorHelper(self.elidedRegions),
84
+ _step;
85
+
86
+ try {
87
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
88
+ var _region = _step.value;
89
+
90
+ var _radianWidth = _region.widthBp / self.bpPerRadian + self.spacingPx / self.pxPerRadian;
91
+
92
+ slices.push(new Slice(self, _region, currentRadianOffset, _radianWidth));
93
+ currentRadianOffset += _radianWidth;
94
+ }
95
+ } catch (err) {
96
+ _iterator.e(err);
97
+ } finally {
98
+ _iterator.f();
99
+ }
100
+
101
+ return slices;
102
+ } // eslint-disable-next-line @typescript-eslint/no-explicit-any
103
+
104
+
105
+ function sliceIsVisible(self, slice) {
106
+ var _self$visibleSection$ = (0, _slicedToArray2["default"])(self.visibleSection.theta, 2),
107
+ visibleThetaMin = _self$visibleSection$[0],
108
+ visibleThetaMax = _self$visibleSection$[1];
109
+
110
+ return (0, _viewportVisibleRegion.thetaRangesOverlap)(slice.offsetRadians + self.offsetRadians, slice.radianWidth, visibleThetaMin, visibleThetaMax - visibleThetaMin);
111
+ }
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
6
+
7
+ var _slices2 = require("./slices");
8
+
9
+ test('one slice', function () {
10
+ var view = {
11
+ elidedRegions: [{
12
+ refName: 'toast',
13
+ start: 0,
14
+ end: 10000,
15
+ widthBp: 10000
16
+ }],
17
+ spacingPx: 5,
18
+ radiusPx: 1000,
19
+ totalBp: 10000,
20
+ bpPerRadian: 10000 / (2 * Math.PI),
21
+ pxPerRadian: 1000
22
+ };
23
+ var slices = (0, _slices2.calculateStaticSlices)(view); // console.log(slices)
24
+
25
+ expect(slices.length).toBe(1);
26
+
27
+ var _slices = (0, _slicedToArray2["default"])(slices, 1),
28
+ slice = _slices[0]; // expect(slices).toMatchSnapshot()
29
+
30
+
31
+ expect(slice).toMatchSnapshot();
32
+ });
33
+ test('two slices', function () {
34
+ var view = {
35
+ elidedRegions: [{
36
+ refName: 'toast',
37
+ start: 0,
38
+ end: 10000,
39
+ widthBp: 10000
40
+ }, {
41
+ refName: 'teest',
42
+ start: 0,
43
+ end: 10000,
44
+ widthBp: 10000
45
+ }],
46
+ spacingPx: 5,
47
+ radiusPx: 1000,
48
+ pxPerRadian: 1000,
49
+ totalBp: 20000,
50
+ bpPerRadian: 20000 / (2 * Math.PI)
51
+ };
52
+ var slices = (0, _slices2.calculateStaticSlices)(view); // console.log(slices)
53
+
54
+ expect(slices.length).toBe(2);
55
+ expect(slices).toMatchSnapshot();
56
+ });
57
+ test('volvox', function () {
58
+ var totalBp = 50001 + 6079;
59
+ var view = {
60
+ elidedRegions: [{
61
+ refName: 'ctgA',
62
+ start: 0,
63
+ end: 50001,
64
+ assemblyName: 'volvox',
65
+ widthBp: 50001
66
+ }, {
67
+ refName: 'ctgB',
68
+ start: 0,
69
+ end: 6079,
70
+ assemblyName: 'volvox',
71
+ widthBp: 6079
72
+ }],
73
+ spacingPx: 5,
74
+ radiusPx: 1000,
75
+ pxPerRadian: 1000,
76
+ totalBp: totalBp,
77
+ bpPerRadian: totalBp / (2 * Math.PI)
78
+ };
79
+ var slices = (0, _slices2.calculateStaticSlices)(view); // console.log(slices)
80
+
81
+ expect(slices.length).toBe(2);
82
+ expect(slices).toMatchSnapshot();
83
+ });