@jbrowse/plugin-circular-view 2.17.0 → 2.18.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 (73) hide show
  1. package/dist/BaseChordDisplay/components/BaseChordDisplay.js +5 -4
  2. package/dist/BaseChordDisplay/components/Loading.js +1 -2
  3. package/dist/BaseChordDisplay/{models/configSchema.d.ts → configSchema.d.ts} +0 -3
  4. package/dist/BaseChordDisplay/{models/configSchema.js → configSchema.js} +1 -10
  5. package/dist/BaseChordDisplay/index.d.ts +2 -2
  6. package/dist/BaseChordDisplay/index.js +2 -2
  7. package/{esm/BaseChordDisplay/models → dist/BaseChordDisplay}/model.d.ts +11 -52
  8. package/dist/BaseChordDisplay/{models/model.js → model.js} +29 -89
  9. package/dist/BaseChordDisplay/renderReaction.d.ts +27 -0
  10. package/dist/BaseChordDisplay/{models/renderReaction.js → renderReaction.js} +5 -13
  11. package/dist/CircularView/components/CircularView.d.ts +1 -1
  12. package/dist/CircularView/components/CircularView.js +2 -3
  13. package/dist/CircularView/components/Controls.d.ts +1 -1
  14. package/dist/CircularView/components/Controls.js +11 -12
  15. package/dist/CircularView/components/ExportSvgDialog.d.ts +1 -1
  16. package/dist/CircularView/components/ExportSvgDialog.js +2 -4
  17. package/dist/CircularView/components/ImportForm.d.ts +1 -1
  18. package/dist/CircularView/components/ImportForm.js +3 -3
  19. package/dist/CircularView/components/Ruler.d.ts +2 -2
  20. package/dist/CircularView/components/Ruler.js +1 -7
  21. package/dist/CircularView/index.d.ts +1 -1
  22. package/dist/CircularView/index.js +1 -1
  23. package/dist/CircularView/{models/model.d.ts → model.d.ts} +9 -158
  24. package/dist/CircularView/{models/model.js → model.js} +8 -217
  25. package/dist/CircularView/{models/slices.d.ts → slices.d.ts} +1 -1
  26. package/dist/CircularView/svgcomponents/SVGBackground.js +1 -1
  27. package/dist/CircularView/svgcomponents/SVGCircularView.d.ts +1 -1
  28. package/dist/CircularView/svgcomponents/SVGCircularView.js +4 -9
  29. package/dist/CircularView/{models/viewportVisibleRegion.js → viewportVisibleRegion.js} +0 -70
  30. package/dist/LaunchCircularView/index.d.ts +1 -1
  31. package/dist/LaunchCircularView/index.js +1 -3
  32. package/dist/index.d.ts +3 -3
  33. package/dist/index.js +5 -7
  34. package/esm/BaseChordDisplay/components/BaseChordDisplay.js +5 -4
  35. package/esm/BaseChordDisplay/components/Loading.js +2 -3
  36. package/esm/BaseChordDisplay/{models/configSchema.d.ts → configSchema.d.ts} +0 -3
  37. package/esm/BaseChordDisplay/{models/configSchema.js → configSchema.js} +1 -10
  38. package/esm/BaseChordDisplay/index.d.ts +2 -2
  39. package/esm/BaseChordDisplay/index.js +2 -2
  40. package/{dist/BaseChordDisplay/models → esm/BaseChordDisplay}/model.d.ts +11 -52
  41. package/esm/BaseChordDisplay/{models/model.js → model.js} +30 -90
  42. package/esm/BaseChordDisplay/renderReaction.d.ts +27 -0
  43. package/esm/BaseChordDisplay/{models/renderReaction.js → renderReaction.js} +5 -10
  44. package/esm/CircularView/components/CircularView.d.ts +1 -1
  45. package/esm/CircularView/components/CircularView.js +2 -3
  46. package/esm/CircularView/components/Controls.d.ts +1 -1
  47. package/esm/CircularView/components/Controls.js +11 -12
  48. package/esm/CircularView/components/ExportSvgDialog.d.ts +1 -1
  49. package/esm/CircularView/components/ExportSvgDialog.js +2 -4
  50. package/esm/CircularView/components/ImportForm.d.ts +1 -1
  51. package/esm/CircularView/components/ImportForm.js +3 -3
  52. package/esm/CircularView/components/Ruler.d.ts +2 -2
  53. package/esm/CircularView/components/Ruler.js +2 -8
  54. package/esm/CircularView/index.d.ts +1 -1
  55. package/esm/CircularView/index.js +1 -1
  56. package/esm/CircularView/{models/model.d.ts → model.d.ts} +9 -158
  57. package/esm/CircularView/{models/model.js → model.js} +9 -218
  58. package/esm/CircularView/{models/slices.d.ts → slices.d.ts} +1 -1
  59. package/esm/CircularView/{models/slices.js → slices.js} +1 -1
  60. package/esm/CircularView/svgcomponents/SVGBackground.js +1 -1
  61. package/esm/CircularView/svgcomponents/SVGCircularView.d.ts +1 -1
  62. package/esm/CircularView/svgcomponents/SVGCircularView.js +4 -9
  63. package/esm/CircularView/{models/viewportVisibleRegion.js → viewportVisibleRegion.js} +0 -70
  64. package/esm/LaunchCircularView/index.d.ts +1 -1
  65. package/esm/LaunchCircularView/index.js +1 -3
  66. package/esm/index.d.ts +3 -3
  67. package/esm/index.js +3 -5
  68. package/package.json +2 -3
  69. package/dist/BaseChordDisplay/models/renderReaction.d.ts +0 -45
  70. package/esm/BaseChordDisplay/models/renderReaction.d.ts +0 -45
  71. /package/dist/CircularView/{models/slices.js → slices.js} +0 -0
  72. /package/dist/CircularView/{models/viewportVisibleRegion.d.ts → viewportVisibleRegion.d.ts} +0 -0
  73. /package/esm/CircularView/{models/viewportVisibleRegion.d.ts → viewportVisibleRegion.d.ts} +0 -0
@@ -27,109 +27,42 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const react_1 = require("react");
30
- const mobx_state_tree_1 = require("mobx-state-tree");
31
- const mst_1 = require("@jbrowse/core/util/types/mst");
32
- const mobx_1 = require("mobx");
33
- const file_saver_1 = require("file-saver");
34
30
  const configuration_1 = require("@jbrowse/core/configuration");
35
- const util_1 = require("@jbrowse/core/util");
36
31
  const models_1 = require("@jbrowse/core/pluggableElementTypes/models");
37
- // icons
38
32
  const Icons_1 = require("@jbrowse/core/ui/Icons");
33
+ const util_1 = require("@jbrowse/core/util");
39
34
  const FolderOpen_1 = __importDefault(require("@mui/icons-material/FolderOpen"));
40
35
  const PhotoCamera_1 = __importDefault(require("@mui/icons-material/PhotoCamera"));
41
- // locals
36
+ const file_saver_1 = require("file-saver");
37
+ const mobx_1 = require("mobx");
38
+ const mobx_state_tree_1 = require("mobx-state-tree");
42
39
  const slices_1 = require("./slices");
43
40
  const viewportVisibleRegion_1 = require("./viewportVisibleRegion");
44
- // lazies
45
- const ExportSvgDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('../components/ExportSvgDialog'))));
46
- /**
47
- * #stateModel CircularView
48
- * extends
49
- * - [BaseViewModel](../baseviewmodel)
50
- */
41
+ const ExportSvgDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./components/ExportSvgDialog'))));
51
42
  function stateModelFactory(pluginManager) {
52
43
  const minHeight = 40;
53
44
  const minWidth = 100;
54
45
  const defaultHeight = 400;
55
46
  return mobx_state_tree_1.types
56
47
  .compose('CircularView', models_1.BaseViewModel, mobx_state_tree_1.types.model({
57
- /**
58
- * #property
59
- */
60
48
  type: mobx_state_tree_1.types.literal('CircularView'),
61
- /**
62
- * #property
63
- * similar to offsetPx in linear genome view
64
- */
65
49
  offsetRadians: -Math.PI / 2,
66
- /**
67
- * #property
68
- */
69
50
  bpPerPx: 200,
70
- /**
71
- * #property
72
- */
73
51
  tracks: mobx_state_tree_1.types.array(pluginManager.pluggableMstType('track', 'stateModel')),
74
- /**
75
- * #property
76
- */
77
52
  hideVerticalResizeHandle: false,
78
- /**
79
- * #property
80
- */
81
53
  hideTrackSelectorButton: false,
82
- /**
83
- * #property
84
- */
85
54
  lockedFitToWindow: true,
86
- /**
87
- * #property
88
- */
89
55
  disableImportForm: false,
90
- /**
91
- * #property
92
- */
93
- height: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.refinement('trackHeight', mobx_state_tree_1.types.number, n => n >= minHeight), defaultHeight),
94
- /**
95
- * #property
96
- */
97
- displayedRegions: mobx_state_tree_1.types.array(mst_1.Region),
98
- /**
99
- * #property
100
- */
56
+ height: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.number, defaultHeight),
57
+ displayedRegions: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.frozen(), []),
101
58
  scrollX: 0,
102
- /**
103
- * #property
104
- */
105
59
  scrollY: 0,
106
- /**
107
- * #property
108
- */
109
60
  minimumRadiusPx: 25,
110
- /**
111
- * #property
112
- */
113
61
  spacingPx: 10,
114
- /**
115
- * #property
116
- */
117
62
  paddingPx: 80,
118
- /**
119
- * #property
120
- */
121
63
  lockedPaddingPx: 100,
122
- /**
123
- * #property
124
- */
125
64
  minVisibleWidth: 6,
126
- /**
127
- * #property
128
- */
129
65
  minimumBlockWidth: 20,
130
- /**
131
- * #property
132
- */
133
66
  trackSelectorType: 'hierarchical',
134
67
  }))
135
68
  .volatile(() => ({
@@ -137,25 +70,16 @@ function stateModelFactory(pluginManager) {
137
70
  error: undefined,
138
71
  }))
139
72
  .views(self => ({
140
- /**
141
- * #getter
142
- */
143
73
  get width() {
144
74
  if (self.volatileWidth === undefined) {
145
75
  throw new Error('wait for view to be initialized first before accessing width');
146
76
  }
147
77
  return self.volatileWidth;
148
78
  },
149
- /**
150
- * #getter
151
- */
152
79
  get visibleSection() {
153
80
  const { scrollX, scrollY, width, height } = self;
154
81
  return (0, viewportVisibleRegion_1.viewportVisibleSection)([scrollX, scrollX + width, scrollY, scrollY + height], this.centerXY, this.radiusPx);
155
82
  },
156
- /**
157
- * #getter
158
- */
159
83
  get circumferencePx() {
160
84
  let elidedBp = 0;
161
85
  for (const r of this.elidedRegions) {
@@ -163,33 +87,18 @@ function stateModelFactory(pluginManager) {
163
87
  }
164
88
  return (elidedBp / self.bpPerPx + self.spacingPx * this.elidedRegions.length);
165
89
  },
166
- /**
167
- * #getter
168
- */
169
90
  get radiusPx() {
170
91
  return this.circumferencePx / (2 * Math.PI);
171
92
  },
172
- /**
173
- * #getter
174
- */
175
93
  get bpPerRadian() {
176
94
  return self.bpPerPx * this.radiusPx;
177
95
  },
178
- /**
179
- * #getter
180
- */
181
96
  get pxPerRadian() {
182
97
  return this.radiusPx;
183
98
  },
184
- /**
185
- * #getter
186
- */
187
99
  get centerXY() {
188
100
  return [this.radiusPx + self.paddingPx, this.radiusPx + self.paddingPx];
189
101
  },
190
- /**
191
- * #getter
192
- */
193
102
  get totalBp() {
194
103
  let total = 0;
195
104
  for (const region of self.displayedRegions) {
@@ -197,80 +106,46 @@ function stateModelFactory(pluginManager) {
197
106
  }
198
107
  return total;
199
108
  },
200
- /**
201
- * #getter
202
- */
203
109
  get maximumRadiusPx() {
204
110
  return self.lockedFitToWindow
205
111
  ? Math.min(self.width, self.height) / 2 - self.lockedPaddingPx
206
112
  : 1000000;
207
113
  },
208
- /**
209
- * #getter
210
- */
211
114
  get maxBpPerPx() {
212
115
  const minCircumferencePx = 2 * Math.PI * self.minimumRadiusPx;
213
116
  return this.totalBp / minCircumferencePx;
214
117
  },
215
- /**
216
- * #getter
217
- */
218
118
  get minBpPerPx() {
219
- // min depends on window dimensions, clamp between old min(0.01) and max
220
119
  const maxCircumferencePx = 2 * Math.PI * this.maximumRadiusPx;
221
120
  return (0, util_1.clamp)(this.totalBp / maxCircumferencePx, 0.0000000001, this.maxBpPerPx);
222
121
  },
223
- /**
224
- * #getter
225
- */
226
122
  get atMaxBpPerPx() {
227
123
  return self.bpPerPx >= this.maxBpPerPx;
228
124
  },
229
- /**
230
- * #getter
231
- */
232
125
  get atMinBpPerPx() {
233
126
  return self.bpPerPx <= this.minBpPerPx;
234
127
  },
235
- /**
236
- * #getter
237
- */
238
128
  get tooSmallToLock() {
239
129
  return this.minBpPerPx <= 0.0000000001;
240
130
  },
241
- /**
242
- * #getter
243
- */
244
131
  get figureDimensions() {
245
132
  return [
246
133
  this.radiusPx * 2 + 2 * self.paddingPx,
247
134
  this.radiusPx * 2 + 2 * self.paddingPx,
248
135
  ];
249
136
  },
250
- /**
251
- * #getter
252
- */
253
137
  get figureWidth() {
254
138
  return this.figureDimensions[0];
255
139
  },
256
- /**
257
- * #getter
258
- */
259
140
  get figureHeight() {
260
141
  return this.figureDimensions[1];
261
142
  },
262
- /**
263
- * #getter
264
- * this is displayedRegions, post-processed to elide regions that are too
265
- * small to see reasonably
266
- */
267
143
  get elidedRegions() {
268
144
  const visible = [];
269
145
  self.displayedRegions.forEach(region => {
270
146
  const widthBp = region.end - region.start;
271
147
  const widthPx = widthBp / self.bpPerPx;
272
148
  if (widthPx < self.minVisibleWidth) {
273
- // too small to see, collapse into a single elision region
274
149
  const lastVisible = visible.at(-1);
275
150
  if (lastVisible === null || lastVisible === void 0 ? void 0 : lastVisible.elided) {
276
151
  lastVisible.regions.push({ ...region });
@@ -285,11 +160,9 @@ function stateModelFactory(pluginManager) {
285
160
  }
286
161
  }
287
162
  else {
288
- // big enough to see, display it
289
163
  visible.push({ ...region, widthBp, elided: false });
290
164
  }
291
165
  });
292
- // remove any single-region elisions
293
166
  for (let i = 0; i < visible.length; i += 1) {
294
167
  const v = visible[i];
295
168
  if (v.elided && v.regions.length === 1) {
@@ -298,9 +171,6 @@ function stateModelFactory(pluginManager) {
298
171
  }
299
172
  return visible;
300
173
  },
301
- /**
302
- * #getter
303
- */
304
174
  get assemblyNames() {
305
175
  const assemblyNames = [];
306
176
  self.displayedRegions.forEach(displayedRegion => {
@@ -310,9 +180,6 @@ function stateModelFactory(pluginManager) {
310
180
  });
311
181
  return assemblyNames;
312
182
  },
313
- /**
314
- * #getter
315
- */
316
183
  get initialized() {
317
184
  const { assemblyManager } = (0, util_1.getSession)(self);
318
185
  return (self.volatileWidth !== undefined &&
@@ -320,107 +187,62 @@ function stateModelFactory(pluginManager) {
320
187
  },
321
188
  }))
322
189
  .views(self => ({
323
- /**
324
- * #getter
325
- */
326
190
  get staticSlices() {
327
191
  return (0, slices_1.calculateStaticSlices)(self);
328
192
  },
329
193
  }))
330
194
  .views(self => ({
331
- /**
332
- * #getter
333
- */
334
195
  get visibleStaticSlices() {
335
196
  return self.staticSlices.filter(s => (0, slices_1.sliceIsVisible)(self, s));
336
197
  },
337
198
  }))
338
199
  .actions(self => ({
339
- /**
340
- * #action
341
- */
342
200
  setWidth(newWidth) {
343
201
  self.volatileWidth = Math.max(newWidth, minWidth);
344
202
  return self.volatileWidth;
345
203
  },
346
- /**
347
- * #action
348
- */
349
204
  setHeight(newHeight) {
350
205
  self.height = Math.max(newHeight, minHeight);
351
206
  return self.height;
352
207
  },
353
- /**
354
- * #action
355
- */
356
208
  resizeHeight(distance) {
357
209
  const oldHeight = self.height;
358
210
  const newHeight = this.setHeight(self.height + distance);
359
211
  this.setModelViewWhenAdjust(!self.tooSmallToLock);
360
212
  return newHeight - oldHeight;
361
213
  },
362
- /**
363
- * #action
364
- */
365
214
  resizeWidth(distance) {
366
215
  const oldWidth = self.width;
367
216
  const newWidth = this.setWidth(self.width + distance);
368
217
  this.setModelViewWhenAdjust(!self.tooSmallToLock);
369
218
  return newWidth - oldWidth;
370
219
  },
371
- /**
372
- * #action
373
- */
374
220
  rotateClockwiseButton() {
375
221
  this.rotateClockwise(Math.PI / 6);
376
222
  },
377
- /**
378
- * #action
379
- */
380
223
  rotateCounterClockwiseButton() {
381
224
  this.rotateCounterClockwise(Math.PI / 6);
382
225
  },
383
- /**
384
- * #action
385
- */
386
226
  rotateClockwise(distance = 0.17) {
387
227
  self.offsetRadians += distance;
388
228
  },
389
- /**
390
- * #action
391
- */
392
229
  rotateCounterClockwise(distance = 0.17) {
393
230
  self.offsetRadians -= distance;
394
231
  },
395
- /**
396
- * #action
397
- */
398
232
  zoomInButton() {
399
233
  this.setBpPerPx(self.bpPerPx / 1.4);
400
234
  },
401
- /**
402
- * #action
403
- */
404
235
  zoomOutButton() {
405
236
  this.setBpPerPx(self.bpPerPx * 1.4);
406
237
  },
407
- /**
408
- * #action
409
- */
410
238
  setBpPerPx(newVal) {
411
239
  self.bpPerPx = (0, util_1.clamp)(newVal, self.minBpPerPx, self.maxBpPerPx);
412
240
  },
413
- /**
414
- * #action
415
- */
416
241
  setModelViewWhenAdjust(secondCondition) {
417
242
  if (self.lockedFitToWindow && secondCondition) {
418
243
  this.setBpPerPx(self.minBpPerPx);
419
244
  }
420
245
  },
421
- /**
422
- * #action
423
- */
424
246
  setDisplayedRegions(regions) {
425
247
  const previouslyEmpty = self.displayedRegions.length === 0;
426
248
  self.displayedRegions = (0, mobx_state_tree_1.cast)(regions);
@@ -431,9 +253,6 @@ function stateModelFactory(pluginManager) {
431
253
  this.setBpPerPx(self.bpPerPx);
432
254
  }
433
255
  },
434
- /**
435
- * #action
436
- */
437
256
  activateTrackSelector() {
438
257
  if (self.trackSelectorType === 'hierarchical') {
439
258
  const session = (0, util_1.getSession)(self);
@@ -445,9 +264,6 @@ function stateModelFactory(pluginManager) {
445
264
  }
446
265
  throw new Error(`invalid track selector type ${self.trackSelectorType}`);
447
266
  },
448
- /**
449
- * #action
450
- */
451
267
  toggleTrack(trackId) {
452
268
  const hiddenCount = this.hideTrack(trackId);
453
269
  if (!hiddenCount) {
@@ -456,15 +272,9 @@ function stateModelFactory(pluginManager) {
456
272
  }
457
273
  return false;
458
274
  },
459
- /**
460
- * #action
461
- */
462
275
  setError(error) {
463
276
  self.error = error;
464
277
  },
465
- /**
466
- * #action
467
- */
468
278
  showTrack(trackId, initialSnapshot = {}) {
469
279
  const schema = pluginManager.pluggableConfigSchemaType('track');
470
280
  const conf = (0, mobx_state_tree_1.resolveIdentifier)(schema, (0, mobx_state_tree_1.getRoot)(self), trackId);
@@ -483,9 +293,6 @@ function stateModelFactory(pluginManager) {
483
293
  });
484
294
  self.tracks.push(track);
485
295
  },
486
- /**
487
- * #action
488
- */
489
296
  addTrackConf(configuration, initialSnapshot = {}) {
490
297
  const { type } = configuration;
491
298
  const name = (0, configuration_1.readConfObject)(configuration, 'name');
@@ -504,9 +311,6 @@ function stateModelFactory(pluginManager) {
504
311
  displays: [{ type: displayConf.type, configuration: displayConf }],
505
312
  }));
506
313
  },
507
- /**
508
- * #action
509
- */
510
314
  hideTrack(trackId) {
511
315
  const schema = pluginManager.pluggableConfigSchemaType('track');
512
316
  const conf = (0, mobx_state_tree_1.resolveIdentifier)(schema, (0, mobx_state_tree_1.getRoot)(self), trackId);
@@ -516,32 +320,19 @@ function stateModelFactory(pluginManager) {
516
320
  });
517
321
  return t.length;
518
322
  },
519
- /**
520
- * #action
521
- */
522
323
  toggleFitToWindowLock() {
523
- // when going unlocked -> locked and circle is cut off, set to the
524
- // locked minBpPerPx
525
324
  self.lockedFitToWindow = !self.lockedFitToWindow;
526
325
  this.setModelViewWhenAdjust(self.atMinBpPerPx);
527
326
  return self.lockedFitToWindow;
528
327
  },
529
- /**
530
- * #action
531
- * creates an svg export and save using FileSaver
532
- */
533
328
  async exportSvg(opts = {}) {
534
- const { renderToSvg } = await Promise.resolve().then(() => __importStar(require('../svgcomponents/SVGCircularView')));
329
+ const { renderToSvg } = await Promise.resolve().then(() => __importStar(require('./svgcomponents/SVGCircularView')));
535
330
  const html = await renderToSvg(self, opts);
536
331
  const blob = new Blob([html], { type: 'image/svg+xml' });
537
332
  (0, file_saver_1.saveAs)(blob, opts.filename || 'image.svg');
538
333
  },
539
334
  }))
540
335
  .views(self => ({
541
- /**
542
- * #method
543
- * return the view menu items
544
- */
545
336
  menuItems() {
546
337
  return [
547
338
  {
@@ -1,4 +1,4 @@
1
- import { Region } from '@jbrowse/core/util';
1
+ import type { Region } from '@jbrowse/core/util';
2
2
  export interface SliceElidedRegion {
3
3
  elided: true;
4
4
  widthBp: number;
@@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = SVGBackground;
7
7
  const react_1 = __importDefault(require("react"));
8
- const material_1 = require("@mui/material");
9
8
  const util_1 = require("@jbrowse/core/util");
9
+ const material_1 = require("@mui/material");
10
10
  function SVGBackground({ width, height, shift, }) {
11
11
  const theme = (0, material_1.useTheme)();
12
12
  return (react_1.default.createElement("rect", { width: width + shift * 2, height: height, fill: (0, util_1.stripAlpha)(theme.palette.background.default) }));
@@ -1,4 +1,4 @@
1
- import { ExportSvgOptions, CircularViewModel } from '../models/model';
1
+ import type { CircularViewModel, ExportSvgOptions } from '../model';
2
2
  type CGV = CircularViewModel;
3
3
  export declare function renderToSvg(model: CGV, opts: ExportSvgOptions): Promise<string>;
4
4
  export {};
@@ -5,10 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.renderToSvg = renderToSvg;
7
7
  const react_1 = __importDefault(require("react"));
8
+ const ui_1 = require("@jbrowse/core/ui");
9
+ const util_1 = require("@jbrowse/core/util");
8
10
  const material_1 = require("@mui/material");
9
11
  const mobx_1 = require("mobx");
10
- const util_1 = require("@jbrowse/core/util");
11
- const ui_1 = require("@jbrowse/core/ui");
12
12
  const mobx_state_tree_1 = require("mobx-state-tree");
13
13
  const SVGBackground_1 = __importDefault(require("./SVGBackground"));
14
14
  const Ruler_1 = __importDefault(require("../components/Ruler"));
@@ -28,16 +28,11 @@ async function renderToSvg(model, opts) {
28
28
  }));
29
29
  const { staticSlices, offsetRadians, centerXY } = model;
30
30
  const deg = (0, util_1.radToDeg)(offsetRadians);
31
- // the xlink namespace is used for rendering <image> tag
32
31
  return (0, util_1.renderToStaticMarkup)(react_1.default.createElement(material_1.ThemeProvider, { theme: (0, ui_1.createJBrowseTheme)(theme) },
33
32
  react_1.default.createElement(Wrapper, null,
34
33
  react_1.default.createElement("svg", { width: width, height: height, xmlns: "http://www.w3.org/2000/svg", xmlnsXlink: "http://www.w3.org/1999/xlink", viewBox: [0, 0, width + shift * 2, height].toString() },
35
34
  react_1.default.createElement(SVGBackground_1.default, { width: width, height: height, shift: shift }),
36
35
  react_1.default.createElement("g", { transform: `translate(${centerXY}) rotate(${deg})` },
37
- staticSlices.map((slice, i) => (
38
- /* biome-ignore lint/suspicious/noArrayIndexKey: */
39
- react_1.default.createElement(Ruler_1.default, { key: i, model: model, slice: slice }))),
40
- displayResults.map(({ result }, i) => (
41
- /* biome-ignore lint/suspicious/noArrayIndexKey: */
42
- react_1.default.createElement(react_1.default.Fragment, { key: i }, result))))))), createRootFn);
36
+ staticSlices.map((slice, i) => (react_1.default.createElement(Ruler_1.default, { key: i, model: model, slice: slice }))),
37
+ displayResults.map(({ result }, i) => (react_1.default.createElement(react_1.default.Fragment, { key: i }, result))))))), createRootFn);
43
38
  }
@@ -53,26 +53,21 @@ function thetaRangesOverlap(r1start, r1length, r2start, r2length) {
53
53
  if (r1length + 0.0001 >= twoPi || r2length + 0.0001 >= twoPi) {
54
54
  return true;
55
55
  }
56
- // put both range starts between 2π and 4π
57
56
  r1start = (((r1start % twoPi) + twoPi) % twoPi) + twoPi;
58
57
  r2start = (((r2start % twoPi) + twoPi) % twoPi) + twoPi;
59
58
  if (r1start < r2start + r2length && r1start + r1length > r2start) {
60
59
  return true;
61
60
  }
62
- // move r2 2π to the left and check
63
61
  r2start -= twoPi;
64
62
  if (r1start < r2start + r2length && r1start + r1length > r2start) {
65
63
  return true;
66
64
  }
67
- // move it 2π to the right and check
68
65
  r2start += twoPi + twoPi;
69
66
  return r1start < r2start + r2length && r1start + r1length > r2start;
70
67
  }
71
- // return which arc range has any part of the circle visible in the viewport
72
68
  function viewportVisibleSection(viewSides, circleCenter, circleRadius) {
73
69
  let [viewL, viewR, viewT, viewB] = viewSides;
74
70
  const [cx, cy] = circleCenter;
75
- // transform coordinate system to center of circle
76
71
  viewL -= cx;
77
72
  viewR -= cx;
78
73
  viewT -= cy;
@@ -97,61 +92,6 @@ function viewportVisibleSection(viewSides, circleCenter, circleRadius) {
97
92
  theta: [0, 2 * Math.PI],
98
93
  };
99
94
  }
100
- // const viewportCompletelyContainsCircle =
101
- // circleCenter[0] - viewL >= circleRadius &&
102
- // viewR - circleCenter[0] >= circleRadius &&
103
- // circleCenter[1] - viewT >= circleRadius &&
104
- // viewB - circleCenter[1] >= circleRadius
105
- // if (viewportCompletelyContainsCircle) {
106
- // return [0, 2 * Math.PI]
107
- // }
108
- // const distToCenterSquared = ([x, y]) => {
109
- // const [cx, cy] = circleCenter
110
- // const sq = n => n * n
111
- // return sq(x - cx) + sq(y - cy)
112
- // }
113
- // const circleRadiusSquared = circleRadius * circleRadius
114
- // const tlInside = distToCenterSquared([viewL, viewT]) <= circleRadiusSquared
115
- // const trInside = distToCenterSquared([viewR, viewT]) <= circleRadiusSquared
116
- // const blInside = distToCenterSquared([viewL, viewB]) <= circleRadiusSquared
117
- // const brInside = distToCenterSquared([viewR, viewB]) <= circleRadiusSquared
118
- // const noIntersection = !tlInside && !trInside && !blInside && !brInside
119
- // if (noIntersection) return undefined
120
- // const circleCompletelyContainsViewport =
121
- // tlInside && trInside && blInside && brInside
122
- // if (circleCompletelyContainsViewport) {
123
- // // viewport is in the circle, but the center is not in it, so take max
124
- // // and min of thetas to the center
125
- // const thetas = [
126
- // Math.atan(viewT / viewL),
127
- // Math.atan(viewT / viewR),
128
- // Math.atan(viewB / viewL),
129
- // Math.atan(viewB / viewR),
130
- // ]
131
- // return [Math.min(...thetas), Math.max(...thetas)]
132
- // }
133
- // if we get here, the viewport is partly in, partly out of the circle
134
- // const viewLIntersects = Math.abs(viewL - circleCenter[0]) <= circleRadius
135
- // const viewRIntersects = Math.abs(viewR - circleCenter[0]) <= circleRadius
136
- // const viewTIntersects = Math.abs(viewT - circleCenter[1]) <= circleRadius
137
- // const viewBIntersects = Math.abs(viewB - circleCenter[1]) <= circleRadius
138
- // const numIntersectingSides =
139
- // Number(viewLIntersects) +
140
- // Number(viewRIntersects) +
141
- // Number(viewTIntersects) +
142
- // Number(viewBIntersects)
143
- // if (numIntersectingSides === 4) return [0, 2 * Math.PI]
144
- // if (numIntersectingSides === 3) {
145
- // // TODO calculate the thetas of the
146
- // } else if (numIntersectingSides === 2) {
147
- // // TODO calculate the thetas of the 2 intersection points
148
- // } else if (numIntersectingSides === 1) {
149
- // // TODO calculate the thetas of the 1-2 intersection points of the line, and the angle between
150
- // }
151
- // make a list of vertices-of-interest that lie inside both shapes to examine
152
- // to determine the range covered by their intersection
153
- // transform coordinates to have the circle as the origin and find the intersections
154
- // of the circle and the view rectangle
155
95
  const vertices = [
156
96
  [viewL, viewT],
157
97
  [viewR, viewT],
@@ -162,7 +102,6 @@ function viewportVisibleSection(viewSides, circleCenter, circleRadius) {
162
102
  findCircleIntersectionY(viewR, 0, 0, circleRadius, vertices);
163
103
  findCircleIntersectionX(viewT, 0, 0, circleRadius, vertices);
164
104
  findCircleIntersectionX(viewB, 0, 0, circleRadius, vertices);
165
- // for each edge, also look at the closest point to center if it is inside the circle
166
105
  if (-viewL < circleRadius) {
167
106
  vertices.push([viewL, 0]);
168
107
  }
@@ -175,24 +114,15 @@ function viewportVisibleSection(viewSides, circleCenter, circleRadius) {
175
114
  if (viewB < circleRadius) {
176
115
  vertices.push([0, viewB]);
177
116
  }
178
- // const verticesOriginal = vertices.map(([x, y]) => [x + cx, y + cy])
179
- // now convert them all to polar and take the max and min of rho and theta
180
- // const viewportCenterTheta = cartesianToTheta(viewR + viewL, viewT + viewB)
181
117
  const reflect = viewL >= 0 ? -1 : 1;
182
- // viewportCenterTheta < Math.PI / 2 || viewportCenterTheta > 1.5 * Math.PI
183
- // ? -1
184
- // : 1
185
118
  let rhoMin = Number.POSITIVE_INFINITY;
186
119
  let rhoMax = Number.NEGATIVE_INFINITY;
187
120
  let thetaMin = Number.POSITIVE_INFINITY;
188
121
  let thetaMax = Number.NEGATIVE_INFINITY;
189
122
  for (const [vx, vy] of vertices) {
190
- // ignore vertex if outside the viewport
191
123
  if (vx >= viewL && vx <= viewR && vy >= viewT && vy <= viewB) {
192
124
  const [rho, theta] = cartesianToPolar(vx * reflect, vy * reflect);
193
- // ignore vertex if outside the circle
194
125
  if (rho <= circleRadius + 0.001) {
195
- // ignore theta if rho is 0
196
126
  if (theta < thetaMin && rho > 0.0001) {
197
127
  thetaMin = theta;
198
128
  }
@@ -1,2 +1,2 @@
1
- import PluginManager from '@jbrowse/core/PluginManager';
1
+ import type PluginManager from '@jbrowse/core/PluginManager';
2
2
  export default function LaunchCircularViewF(pluginManager: PluginManager): void;
@@ -3,9 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = LaunchCircularViewF;
4
4
  const mobx_1 = require("mobx");
5
5
  function LaunchCircularViewF(pluginManager) {
6
- pluginManager.addToExtensionPoint('LaunchView-CircularView',
7
- // @ts-expect-error
8
- async ({ session, assembly, tracks = [], }) => {
6
+ pluginManager.addToExtensionPoint('LaunchView-CircularView', async ({ session, assembly, tracks = [], }) => {
9
7
  const { assemblyManager } = session;
10
8
  const view = session.addView('CircularView', {});
11
9
  await (0, mobx_1.when)(() => view.initialized);