@jbrowse/plugin-linear-genome-view 1.7.8 → 1.7.11

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 (53) hide show
  1. package/dist/BaseLinearDisplay/components/BaseLinearDisplay.d.ts +1 -5
  2. package/dist/BaseLinearDisplay/components/BaseLinearDisplay.js +32 -120
  3. package/dist/BaseLinearDisplay/components/Tooltip.d.ts +8 -0
  4. package/dist/BaseLinearDisplay/components/Tooltip.js +125 -0
  5. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +4 -4
  6. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +3 -2
  7. package/dist/LinearBareDisplay/model.d.ts +1 -1
  8. package/dist/LinearBasicDisplay/model.d.ts +1 -2
  9. package/dist/LinearBasicDisplay/model.js +2 -2
  10. package/dist/LinearGenomeView/components/ExportSvgDialog.js +35 -25
  11. package/dist/LinearGenomeView/components/Header.d.ts +0 -1
  12. package/dist/LinearGenomeView/components/Header.js +3 -1
  13. package/dist/LinearGenomeView/components/HelpDialog.js +2 -3
  14. package/dist/LinearGenomeView/components/ImportForm.d.ts +0 -1
  15. package/dist/LinearGenomeView/components/ImportForm.js +40 -70
  16. package/dist/LinearGenomeView/components/LinearGenomeView.js +6 -2
  17. package/dist/LinearGenomeView/components/LinearGenomeView.test.js +2 -2
  18. package/dist/LinearGenomeView/components/OverviewScaleBar.d.ts +21 -5
  19. package/dist/LinearGenomeView/components/OverviewScaleBar.js +25 -18
  20. package/dist/LinearGenomeView/components/ScaleBar.d.ts +6 -2
  21. package/dist/LinearGenomeView/components/ScaleBar.js +8 -3
  22. package/dist/LinearGenomeView/components/SearchBox.js +36 -72
  23. package/dist/LinearGenomeView/components/SearchResultsDialog.d.ts +1 -1
  24. package/dist/LinearGenomeView/components/SearchResultsDialog.js +0 -1
  25. package/dist/LinearGenomeView/components/TrackLabel.js +25 -41
  26. package/dist/LinearGenomeView/components/util.d.ts +12 -0
  27. package/dist/LinearGenomeView/components/util.js +59 -0
  28. package/dist/LinearGenomeView/index.d.ts +7 -11
  29. package/dist/LinearGenomeView/index.js +60 -33
  30. package/dist/LinearGenomeView/index.test.js +22 -5
  31. package/dist/index.d.ts +3 -3
  32. package/dist/index.js +22 -11
  33. package/package.json +3 -2
  34. package/src/BaseLinearDisplay/components/BaseLinearDisplay.tsx +4 -89
  35. package/src/BaseLinearDisplay/components/Tooltip.tsx +97 -0
  36. package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +11 -4
  37. package/src/LinearBasicDisplay/model.ts +2 -4
  38. package/src/LinearGenomeView/components/ExportSvgDialog.tsx +24 -11
  39. package/src/LinearGenomeView/components/Header.tsx +2 -1
  40. package/src/LinearGenomeView/components/HelpDialog.tsx +5 -4
  41. package/src/LinearGenomeView/components/ImportForm.tsx +18 -25
  42. package/src/LinearGenomeView/components/LinearGenomeView.test.js +2 -2
  43. package/src/LinearGenomeView/components/LinearGenomeView.tsx +16 -10
  44. package/src/LinearGenomeView/components/OverviewScaleBar.tsx +42 -34
  45. package/src/LinearGenomeView/components/ScaleBar.tsx +6 -9
  46. package/src/LinearGenomeView/components/SearchBox.tsx +18 -29
  47. package/src/LinearGenomeView/components/SearchResultsDialog.tsx +0 -1
  48. package/src/LinearGenomeView/components/TrackLabel.tsx +25 -28
  49. package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.js.snap +4 -21
  50. package/src/LinearGenomeView/components/util.ts +43 -0
  51. package/src/LinearGenomeView/index.test.ts +20 -5
  52. package/src/LinearGenomeView/index.tsx +56 -27
  53. package/src/index.ts +35 -30
@@ -67,6 +67,7 @@ export interface BpOffset {
67
67
 
68
68
  export interface ExportSvgOptions {
69
69
  rasterizeLayers?: boolean
70
+ filename?: string
70
71
  }
71
72
 
72
73
  function calculateVisibleLocStrings(contentBlocks: BaseBlock[]) {
@@ -126,6 +127,7 @@ export function stateModelFactory(pluginManager: PluginManager) {
126
127
  ),
127
128
  hideHeader: false,
128
129
  hideHeaderOverview: false,
130
+ hideNoTracksActive: false,
129
131
  trackSelectorType: types.optional(
130
132
  types.enumeration(['hierarchical']),
131
133
  'hierarchical',
@@ -176,11 +178,18 @@ export function stateModelFactory(pluginManager: PluginManager) {
176
178
  get interRegionPaddingWidth() {
177
179
  return INTER_REGION_PADDING_WIDTH
178
180
  },
181
+
182
+ get assemblyNames() {
183
+ return [
184
+ ...new Set(self.displayedRegions.map(region => region.assemblyName)),
185
+ ]
186
+ },
179
187
  }))
180
188
  .views(self => ({
181
189
  get assemblyErrors() {
182
190
  const { assemblyManager } = getSession(self)
183
- return this.assemblyNames
191
+ const { assemblyNames } = self
192
+ return assemblyNames
184
193
  .map(a => assemblyManager.get(a)?.error)
185
194
  .filter(f => !!f)
186
195
  .join(', ')
@@ -188,9 +197,8 @@ export function stateModelFactory(pluginManager: PluginManager) {
188
197
 
189
198
  get assembliesInitialized() {
190
199
  const { assemblyManager } = getSession(self)
191
- return this.assemblyNames.every(
192
- a => assemblyManager.get(a)?.initialized,
193
- )
200
+ const { assemblyNames } = self
201
+ return assemblyNames.every(a => assemblyManager.get(a)?.initialized)
194
202
  },
195
203
  get initialized() {
196
204
  return self.volatileWidth !== undefined && this.assembliesInitialized
@@ -272,11 +280,6 @@ export function stateModelFactory(pluginManager: PluginManager) {
272
280
  }
273
281
  },
274
282
 
275
- get assemblyNames() {
276
- return [
277
- ...new Set(self.displayedRegions.map(region => region.assemblyName)),
278
- ]
279
- },
280
283
  searchScope(assemblyName: string) {
281
284
  return {
282
285
  assemblyName,
@@ -285,13 +288,6 @@ export function stateModelFactory(pluginManager: PluginManager) {
285
288
  }
286
289
  },
287
290
 
288
- /**
289
- * @param refName - refName of the displayedRegion
290
- * @param coord - coordinate at the displayed Region
291
- * @param regionNumber - optional param used as identifier when
292
- * there are multiple displayedRegions with the same refName
293
- * @returns offsetPx of the displayed region that it lands in
294
- */
295
291
  bpToPx({
296
292
  refName,
297
293
  coord,
@@ -395,10 +391,8 @@ export function stateModelFactory(pluginManager: PluginManager) {
395
391
  track => track.configuration.trackId,
396
392
  )
397
393
  results.forEach(result => {
398
- if (openTrackIds !== []) {
399
- if (openTrackIds.includes(result.trackId)) {
400
- result.updateScore(result.getScore() + 1)
401
- }
394
+ if (openTrackIds.includes(result.trackId)) {
395
+ result.updateScore(result.getScore() + 1)
402
396
  }
403
397
  })
404
398
  return results
@@ -406,7 +400,7 @@ export function stateModelFactory(pluginManager: PluginManager) {
406
400
 
407
401
  // modifies view menu action onClick to apply to all tracks of same type
408
402
  rewriteOnClicks(trackType: string, viewMenuActions: MenuItem[]) {
409
- viewMenuActions.forEach((action: MenuItem) => {
403
+ viewMenuActions.forEach(action => {
410
404
  // go to lowest level menu
411
405
  if ('subMenu' in action) {
412
406
  this.rewriteOnClicks(trackType, action.subMenu)
@@ -463,6 +457,9 @@ export function stateModelFactory(pluginManager: PluginManager) {
463
457
  toggleHeaderOverview() {
464
458
  self.hideHeaderOverview = !self.hideHeaderOverview
465
459
  },
460
+ toggleNoTracksActive() {
461
+ self.hideNoTracksActive = !self.hideNoTracksActive
462
+ },
466
463
 
467
464
  scrollTo(offsetPx: number) {
468
465
  const newOffsetPx = clamp(offsetPx, self.minOffset, self.maxOffset)
@@ -674,13 +671,38 @@ export function stateModelFactory(pluginManager: PluginManager) {
674
671
  const { assemblyManager } = getSession(self)
675
672
  const { isValidRefName } = assemblyManager
676
673
  const assemblyName = optAssemblyName || assemblyNames[0]
674
+ let parsedLocStrings
675
+ const inputs = locString
676
+ .split(/(\s+)/)
677
+ .map(f => f.trim())
678
+ .filter(f => !!f)
677
679
 
678
- const parsedLocStrings = locString
679
- .split(' ')
680
- .filter(f => !!f.trim())
681
- .map(l => parseLocString(l, ref => isValidRefName(ref, assemblyName)))
680
+ // first try interpreting as a whitespace-separated sequence of
681
+ // multiple locstrings
682
+ try {
683
+ parsedLocStrings = inputs.map(l =>
684
+ parseLocString(l, ref => isValidRefName(ref, assemblyName)),
685
+ )
686
+ } catch (e) {
687
+ // if this fails, try interpreting as a whitespace-separated refname,
688
+ // start, end if start and end are integer inputs
689
+ const [refName, start, end] = inputs
690
+ if (
691
+ `${e}`.match(/Unknown reference sequence/) &&
692
+ Number.isInteger(+start) &&
693
+ Number.isInteger(+end)
694
+ ) {
695
+ parsedLocStrings = [
696
+ parseLocString(refName + ':' + start + '..' + end, ref =>
697
+ isValidRefName(ref, assemblyName),
698
+ ),
699
+ ]
700
+ } else {
701
+ throw e
702
+ }
703
+ }
682
704
 
683
- const locations = parsedLocStrings.map(region => {
705
+ const locations = parsedLocStrings?.map(region => {
684
706
  const asmName = region.assemblyName || assemblyName
685
707
  const asm = assemblyManager.get(asmName)
686
708
  const { refName } = region
@@ -1206,6 +1228,13 @@ export function stateModelFactory(pluginManager: PluginManager) {
1206
1228
  onClick: self.toggleHeaderOverview,
1207
1229
  disabled: self.hideHeader,
1208
1230
  },
1231
+ {
1232
+ label: 'Show no tracks active button',
1233
+ icon: VisibilityIcon,
1234
+ type: 'checkbox',
1235
+ checked: !self.hideNoTracksActive,
1236
+ onClick: self.toggleNoTracksActive,
1237
+ },
1209
1238
  {
1210
1239
  label: 'Track labels',
1211
1240
  icon: LabelIcon,
@@ -1330,7 +1359,7 @@ export function stateModelFactory(pluginManager: PluginManager) {
1330
1359
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1331
1360
  const html = await renderToSvg(self as any, opts)
1332
1361
  const blob = new Blob([html], { type: 'image/svg+xml' })
1333
- saveAs(blob, 'image.svg')
1362
+ saveAs(blob, opts.filename || 'image.svg')
1334
1363
  },
1335
1364
  }))
1336
1365
  .views(self => ({
package/src/index.ts CHANGED
@@ -137,42 +137,47 @@ export default class LinearGenomeViewPlugin extends Plugin {
137
137
  loc: string
138
138
  tracks?: string[]
139
139
  }) => {
140
- const { assemblyManager } = session
141
- const view = session.addView('LinearGenomeView', {}) as LGV
140
+ try {
141
+ const { assemblyManager } = session
142
+ const view = session.addView('LinearGenomeView', {}) as LGV
142
143
 
143
- await when(() => !!view.volatileWidth)
144
+ await when(() => !!view.volatileWidth)
144
145
 
145
- if (!assembly) {
146
- throw new Error(
147
- 'No assembly provided when launching linear genome view',
148
- )
149
- }
146
+ if (!assembly) {
147
+ throw new Error(
148
+ 'No assembly provided when launching linear genome view',
149
+ )
150
+ }
150
151
 
151
- const asm = await assemblyManager.waitForAssembly(assembly)
152
- if (!asm) {
153
- throw new Error(
154
- `Assembly "${assembly}" not found when launching linear genome view`,
155
- )
156
- }
152
+ const asm = await assemblyManager.waitForAssembly(assembly)
153
+ if (!asm) {
154
+ throw new Error(
155
+ `Assembly "${assembly}" not found when launching linear genome view`,
156
+ )
157
+ }
157
158
 
158
- view.navToLocString(loc, assembly)
159
-
160
- const idsNotFound = [] as string[]
161
- tracks.forEach(track => {
162
- try {
163
- view.showTrack(track)
164
- } catch (e) {
165
- if (`${e}`.match('Could not resolve identifier')) {
166
- idsNotFound.push(track)
167
- } else {
168
- throw e
159
+ view.navToLocString(loc, assembly)
160
+
161
+ const idsNotFound = [] as string[]
162
+ tracks.forEach(track => {
163
+ try {
164
+ view.showTrack(track)
165
+ } catch (e) {
166
+ if (`${e}`.match('Could not resolve identifier')) {
167
+ idsNotFound.push(track)
168
+ } else {
169
+ throw e
170
+ }
169
171
  }
172
+ })
173
+ if (idsNotFound.length) {
174
+ throw new Error(
175
+ `Could not resolve identifiers: ${idsNotFound.join(',')}`,
176
+ )
170
177
  }
171
- })
172
- if (idsNotFound.length) {
173
- throw new Error(
174
- `Could not resolve identifiers: ${idsNotFound.join(',')}`,
175
- )
178
+ } catch (e) {
179
+ session.notify(`${e}`, 'error')
180
+ throw e
176
181
  }
177
182
  },
178
183
  )