@jbrowse/plugin-circular-view 2.1.6 → 2.2.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 (25) hide show
  1. package/dist/BaseChordDisplay/models/BaseChordDisplayModel.d.ts +26 -0
  2. package/dist/BaseChordDisplay/models/BaseChordDisplayModel.js +199 -159
  3. package/dist/BaseChordDisplay/models/BaseChordDisplayModel.js.map +1 -1
  4. package/dist/BaseChordDisplay/models/baseChordDisplayConfig.js +13 -1
  5. package/dist/BaseChordDisplay/models/baseChordDisplayConfig.js.map +1 -1
  6. package/dist/CircularView/components/ImportForm.js +1 -1
  7. package/dist/CircularView/components/ImportForm.js.map +1 -1
  8. package/dist/CircularView/models/CircularView.d.ts +149 -8
  9. package/dist/CircularView/models/CircularView.js +176 -10
  10. package/dist/CircularView/models/CircularView.js.map +1 -1
  11. package/esm/BaseChordDisplay/models/BaseChordDisplayModel.d.ts +26 -0
  12. package/esm/BaseChordDisplay/models/BaseChordDisplayModel.js +199 -159
  13. package/esm/BaseChordDisplay/models/BaseChordDisplayModel.js.map +1 -1
  14. package/esm/BaseChordDisplay/models/baseChordDisplayConfig.js +13 -1
  15. package/esm/BaseChordDisplay/models/baseChordDisplayConfig.js.map +1 -1
  16. package/esm/CircularView/components/ImportForm.js +1 -1
  17. package/esm/CircularView/components/ImportForm.js.map +1 -1
  18. package/esm/CircularView/models/CircularView.d.ts +149 -8
  19. package/esm/CircularView/models/CircularView.js +176 -9
  20. package/esm/CircularView/models/CircularView.js.map +1 -1
  21. package/package.json +2 -2
  22. package/src/BaseChordDisplay/models/BaseChordDisplayModel.ts +236 -194
  23. package/src/BaseChordDisplay/models/baseChordDisplayConfig.ts +14 -1
  24. package/src/CircularView/components/ImportForm.tsx +1 -1
  25. package/src/CircularView/models/CircularView.ts +180 -11
@@ -25,7 +25,11 @@ import { calculateStaticSlices, sliceIsVisible } from './slices'
25
25
 
26
26
  import { viewportVisibleSection } from './viewportVisibleRegion'
27
27
 
28
- export default function CircularView(pluginManager: PluginManager) {
28
+ /**
29
+ * #stateModel CircularView
30
+ * extends `BaseViewModel`
31
+ */
32
+ function stateModelFactory(pluginManager: PluginManager) {
29
33
  const minHeight = 40
30
34
  const minWidth = 100
31
35
  const defaultHeight = 400
@@ -33,41 +37,86 @@ export default function CircularView(pluginManager: PluginManager) {
33
37
  BaseViewModel,
34
38
  types
35
39
  .model('CircularView', {
40
+ /**
41
+ * #property
42
+ */
36
43
  type: types.literal('CircularView'),
44
+ /**
45
+ * #property
46
+ * similar to offsetPx in linear genome view
47
+ */
37
48
  offsetRadians: -Math.PI / 2,
49
+ /**
50
+ * #property
51
+ */
38
52
  bpPerPx: 2000000,
53
+ /**
54
+ * #property
55
+ */
39
56
  tracks: types.array(
40
57
  pluginManager.pluggableMstType('track', 'stateModel'),
41
58
  ),
42
59
 
60
+ /**
61
+ * #property
62
+ */
43
63
  hideVerticalResizeHandle: false,
64
+ /**
65
+ * #property
66
+ */
44
67
  hideTrackSelectorButton: false,
68
+ /**
69
+ * #property
70
+ */
45
71
  lockedFitToWindow: true,
72
+ /**
73
+ * #property
74
+ */
46
75
  disableImportForm: false,
47
76
 
77
+ /**
78
+ * #property
79
+ */
48
80
  height: types.optional(
49
81
  types.refinement('trackHeight', types.number, n => n >= minHeight),
50
82
  defaultHeight,
51
83
  ),
84
+ /**
85
+ * #property
86
+ */
87
+ displayedRegions: types.array(Region),
88
+ /**
89
+ * #property
90
+ */
91
+ scrollX: 0,
92
+ /**
93
+ * #property
94
+ */
95
+ scrollY: 0,
96
+
52
97
  minimumRadiusPx: 25,
53
98
  spacingPx: 10,
54
99
  paddingPx: 80,
55
100
  lockedPaddingPx: 100,
56
101
  minVisibleWidth: 6,
57
102
  minimumBlockWidth: 20,
58
- displayedRegions: types.array(Region),
59
- scrollX: 0,
60
- scrollY: 0,
103
+
61
104
  trackSelectorType: 'hierarchical',
62
105
  })
63
106
  .volatile(() => ({
64
107
  width: 0,
65
108
  }))
66
109
  .views(self => ({
110
+ /**
111
+ * #getter
112
+ */
67
113
  get staticSlices() {
68
114
  return calculateStaticSlices(self)
69
115
  },
70
116
 
117
+ /**
118
+ * #getter
119
+ */
71
120
  get visibleSection() {
72
121
  return viewportVisibleSection(
73
122
  [
@@ -80,6 +129,9 @@ export default function CircularView(pluginManager: PluginManager) {
80
129
  this.radiusPx,
81
130
  )
82
131
  },
132
+ /**
133
+ * #getter
134
+ */
83
135
  get circumferencePx() {
84
136
  let elidedBp = 0
85
137
  for (const r of this.elidedRegions) {
@@ -89,21 +141,36 @@ export default function CircularView(pluginManager: PluginManager) {
89
141
  elidedBp / self.bpPerPx + self.spacingPx * this.elidedRegions.length
90
142
  )
91
143
  },
144
+ /**
145
+ * #getter
146
+ */
92
147
  get radiusPx() {
93
148
  return this.circumferencePx / (2 * Math.PI)
94
149
  },
150
+ /**
151
+ * #getter
152
+ */
95
153
  get bpPerRadian() {
96
154
  return self.bpPerPx * this.radiusPx
97
155
  },
156
+ /**
157
+ * #getter
158
+ */
98
159
  get pxPerRadian() {
99
160
  return this.radiusPx
100
161
  },
162
+ /**
163
+ * #getter
164
+ */
101
165
  get centerXY(): [number, number] {
102
166
  return [
103
167
  this.radiusPx + self.paddingPx,
104
168
  this.radiusPx + self.paddingPx,
105
169
  ]
106
170
  },
171
+ /**
172
+ * #getter
173
+ */
107
174
  get totalBp() {
108
175
  let total = 0
109
176
  for (const region of self.displayedRegions) {
@@ -111,15 +178,24 @@ export default function CircularView(pluginManager: PluginManager) {
111
178
  }
112
179
  return total
113
180
  },
181
+ /**
182
+ * #getter
183
+ */
114
184
  get maximumRadiusPx() {
115
185
  return self.lockedFitToWindow
116
186
  ? Math.min(self.width, self.height) / 2 - self.lockedPaddingPx
117
187
  : 1000000
118
188
  },
189
+ /**
190
+ * #getter
191
+ */
119
192
  get maxBpPerPx() {
120
193
  const minCircumferencePx = 2 * Math.PI * self.minimumRadiusPx
121
194
  return this.totalBp / minCircumferencePx
122
195
  },
196
+ /**
197
+ * #getter
198
+ */
123
199
  get minBpPerPx() {
124
200
  // min depends on window dimensions, clamp between old min(0.01) and max
125
201
  const maxCircumferencePx = 2 * Math.PI * this.maximumRadiusPx
@@ -129,29 +205,50 @@ export default function CircularView(pluginManager: PluginManager) {
129
205
  this.maxBpPerPx,
130
206
  )
131
207
  },
208
+ /**
209
+ * #getter
210
+ */
132
211
  get atMaxBpPerPx() {
133
212
  return self.bpPerPx >= this.maxBpPerPx
134
213
  },
214
+ /**
215
+ * #getter
216
+ */
135
217
  get atMinBpPerPx() {
136
218
  return self.bpPerPx <= this.minBpPerPx
137
219
  },
220
+ /**
221
+ * #getter
222
+ */
138
223
  get tooSmallToLock() {
139
224
  return this.minBpPerPx <= 0.0000000001
140
225
  },
226
+ /**
227
+ * #getter
228
+ */
141
229
  get figureDimensions(): [number, number] {
142
230
  return [
143
231
  this.radiusPx * 2 + 2 * self.paddingPx,
144
232
  this.radiusPx * 2 + 2 * self.paddingPx,
145
233
  ]
146
234
  },
235
+ /**
236
+ * #getter
237
+ */
147
238
  get figureWidth() {
148
239
  return this.figureDimensions[0]
149
240
  },
241
+ /**
242
+ * #getter
243
+ */
150
244
  get figureHeight() {
151
245
  return this.figureDimensions[1]
152
246
  },
153
- // this is displayedRegions, post-processed to
154
- // elide regions that are too small to see reasonably
247
+ /**
248
+ * #getter
249
+ * this is displayedRegions, post-processed to
250
+ * elide regions that are too small to see reasonably
251
+ */
155
252
  get elidedRegions() {
156
253
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
157
254
  const visible: any[] = []
@@ -187,7 +284,9 @@ export default function CircularView(pluginManager: PluginManager) {
187
284
  }
188
285
  return visible
189
286
  },
190
-
287
+ /**
288
+ * #getter
289
+ */
191
290
  get assemblyNames() {
192
291
  const assemblyNames: string[] = []
193
292
  self.displayedRegions.forEach(displayedRegion => {
@@ -197,6 +296,9 @@ export default function CircularView(pluginManager: PluginManager) {
197
296
  })
198
297
  return assemblyNames
199
298
  },
299
+ /**
300
+ * #getter
301
+ */
200
302
  get initialized() {
201
303
  const { assemblyManager } = getSession(self)
202
304
  return this.assemblyNames.every(
@@ -205,6 +307,9 @@ export default function CircularView(pluginManager: PluginManager) {
205
307
  },
206
308
  }))
207
309
  .views(self => ({
310
+ /**
311
+ * #getter
312
+ */
208
313
  get visibleStaticSlices() {
209
314
  return self.staticSlices.filter(s => sliceIsVisible(self, s))
210
315
  },
@@ -213,66 +318,107 @@ export default function CircularView(pluginManager: PluginManager) {
213
318
  error: undefined as unknown,
214
319
  }))
215
320
  .actions(self => ({
216
- // toggle action with a flag stating which mode it's in
321
+ /**
322
+ * #action
323
+ */
217
324
  setWidth(newWidth: number) {
218
325
  self.width = Math.max(newWidth, minWidth)
219
326
  return self.width
220
327
  },
328
+ /**
329
+ * #action
330
+ */
221
331
  setHeight(newHeight: number) {
222
332
  self.height = Math.max(newHeight, minHeight)
223
333
  return self.height
224
334
  },
335
+ /**
336
+ * #action
337
+ */
225
338
  resizeHeight(distance: number) {
226
339
  const oldHeight = self.height
227
340
  const newHeight = this.setHeight(self.height + distance)
228
341
  this.setModelViewWhenAdjust(!self.tooSmallToLock)
229
342
  return newHeight - oldHeight
230
343
  },
344
+ /**
345
+ * #action
346
+ */
231
347
  resizeWidth(distance: number) {
232
348
  const oldWidth = self.width
233
349
  const newWidth = this.setWidth(self.width + distance)
234
350
  this.setModelViewWhenAdjust(!self.tooSmallToLock)
235
351
  return newWidth - oldWidth
236
352
  },
353
+ /**
354
+ * #action
355
+ */
237
356
  rotateClockwiseButton() {
238
357
  this.rotateClockwise(Math.PI / 6)
239
358
  },
240
359
 
360
+ /**
361
+ * #action
362
+ */
241
363
  rotateCounterClockwiseButton() {
242
364
  this.rotateCounterClockwise(Math.PI / 6)
243
365
  },
244
366
 
367
+ /**
368
+ * #action
369
+ */
245
370
  rotateClockwise(distance = 0.17) {
246
371
  self.offsetRadians += distance
247
372
  },
248
373
 
374
+ /**
375
+ * #action
376
+ */
249
377
  rotateCounterClockwise(distance = 0.17) {
250
378
  self.offsetRadians -= distance
251
379
  },
252
380
 
381
+ /**
382
+ * #action
383
+ */
253
384
  zoomInButton() {
254
385
  this.setBpPerPx(self.bpPerPx / 1.4)
255
386
  },
256
387
 
388
+ /**
389
+ * #action
390
+ */
257
391
  zoomOutButton() {
258
392
  this.setBpPerPx(self.bpPerPx * 1.4)
259
393
  },
260
394
 
395
+ /**
396
+ * #action
397
+ */
261
398
  setBpPerPx(newVal: number) {
262
399
  self.bpPerPx = clamp(newVal, self.minBpPerPx, self.maxBpPerPx)
263
400
  },
264
401
 
402
+ /**
403
+ * #action
404
+ */
265
405
  setModelViewWhenAdjust(secondCondition: boolean) {
266
406
  if (self.lockedFitToWindow && secondCondition) {
267
407
  this.setBpPerPx(self.minBpPerPx)
268
408
  }
269
409
  },
270
410
 
411
+ /**
412
+ * #action
413
+ */
271
414
  closeView() {
272
415
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
273
416
  getParent<any>(self, 2).removeView(self)
274
417
  },
275
418
 
419
+ /**
420
+ * #action
421
+ */
276
422
  setDisplayedRegions(regions: SnapshotOrInstance<typeof Region>[]) {
277
423
  const previouslyEmpty = self.displayedRegions.length === 0
278
424
  self.displayedRegions = cast(regions)
@@ -284,6 +430,9 @@ export default function CircularView(pluginManager: PluginManager) {
284
430
  }
285
431
  },
286
432
 
433
+ /**
434
+ * #action
435
+ */
287
436
  activateTrackSelector() {
288
437
  if (self.trackSelectorType === 'hierarchical') {
289
438
  const session = getSession(self)
@@ -302,6 +451,9 @@ export default function CircularView(pluginManager: PluginManager) {
302
451
  )
303
452
  },
304
453
 
454
+ /**
455
+ * #action
456
+ */
305
457
  toggleTrack(trackId: string) {
306
458
  // if we have any tracks with that configuration, turn them off
307
459
  const hiddenCount = this.hideTrack(trackId)
@@ -311,11 +463,17 @@ export default function CircularView(pluginManager: PluginManager) {
311
463
  }
312
464
  },
313
465
 
466
+ /**
467
+ * #action
468
+ */
314
469
  setError(error: unknown) {
315
470
  console.error(error)
316
471
  self.error = error
317
472
  },
318
473
 
474
+ /**
475
+ * #action
476
+ */
319
477
  showTrack(trackId: string, initialSnapshot = {}) {
320
478
  const schema = pluginManager.pluggableConfigSchemaType('track')
321
479
  const conf = resolveIdentifier(schema, getRoot(self), trackId)
@@ -337,6 +495,9 @@ export default function CircularView(pluginManager: PluginManager) {
337
495
  self.tracks.push(track)
338
496
  },
339
497
 
498
+ /**
499
+ * #action
500
+ */
340
501
  addTrackConf(
341
502
  configuration: AnyConfigurationModel,
342
503
  initialSnapshot = {},
@@ -362,6 +523,9 @@ export default function CircularView(pluginManager: PluginManager) {
362
523
  self.tracks.push(track)
363
524
  },
364
525
 
526
+ /**
527
+ * #action
528
+ */
365
529
  hideTrack(trackId: string) {
366
530
  const schema = pluginManager.pluggableConfigSchemaType('track')
367
531
  const conf = resolveIdentifier(schema, getRoot(self), trackId)
@@ -370,9 +534,12 @@ export default function CircularView(pluginManager: PluginManager) {
370
534
  return t.length
371
535
  },
372
536
 
537
+ /**
538
+ * #action
539
+ */
373
540
  toggleFitToWindowLock() {
374
- self.lockedFitToWindow = !self.lockedFitToWindow
375
541
  // when going unlocked -> locked and circle is cut off, set to the locked minBpPerPx
542
+ self.lockedFitToWindow = !self.lockedFitToWindow
376
543
  this.setModelViewWhenAdjust(self.atMinBpPerPx)
377
544
  return self.lockedFitToWindow
378
545
  },
@@ -380,10 +547,10 @@ export default function CircularView(pluginManager: PluginManager) {
380
547
  )
381
548
  }
382
549
 
383
- export type CircularViewStateModel = ReturnType<typeof CircularView>
550
+ export type CircularViewStateModel = ReturnType<typeof stateModelFactory>
384
551
  export type CircularViewModel = Instance<CircularViewStateModel>
385
552
 
386
- /*
553
+ /**
387
554
  PLANS
388
555
 
389
556
  - tracks
@@ -391,3 +558,5 @@ PLANS
391
558
  - set viewport scroll from state snapshot
392
559
 
393
560
  */
561
+
562
+ export default stateModelFactory