@jbrowse/plugin-linear-genome-view 2.2.0 → 2.2.2

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 (225) hide show
  1. package/dist/BaseLinearDisplay/components/Tooltip.d.ts +1 -1
  2. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +3 -3
  3. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.d.ts +2 -2
  4. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js +1 -1
  5. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
  6. package/dist/BasicTrack/index.d.ts +1 -1
  7. package/dist/BasicTrack/index.js +4 -4
  8. package/dist/BasicTrack/index.js.map +1 -1
  9. package/dist/LaunchLinearGenomeView/index.d.ts +3 -0
  10. package/dist/LaunchLinearGenomeView/index.js +44 -0
  11. package/dist/LaunchLinearGenomeView/index.js.map +1 -0
  12. package/dist/LinearBareDisplay/index.d.ts +6 -2
  13. package/dist/LinearBareDisplay/index.js +17 -2
  14. package/dist/LinearBareDisplay/index.js.map +1 -1
  15. package/dist/LinearBasicDisplay/components/SetMaxHeight.js +2 -15
  16. package/dist/LinearBasicDisplay/components/SetMaxHeight.js.map +1 -1
  17. package/dist/LinearBasicDisplay/index.d.ts +6 -2
  18. package/dist/LinearBasicDisplay/index.js +20 -4
  19. package/dist/LinearBasicDisplay/index.js.map +1 -1
  20. package/dist/LinearBasicDisplay/model.d.ts +21 -14
  21. package/dist/LinearBasicDisplay/model.js +2 -1
  22. package/dist/LinearBasicDisplay/model.js.map +1 -1
  23. package/dist/LinearGenomeView/components/CenterLine.d.ts +1 -1
  24. package/dist/LinearGenomeView/components/ExportSvgDialog.js +1 -19
  25. package/dist/LinearGenomeView/components/ExportSvgDialog.js.map +1 -1
  26. package/dist/LinearGenomeView/components/GetSequenceDialog.d.ts +1 -1
  27. package/dist/LinearGenomeView/components/GetSequenceDialog.js +7 -18
  28. package/dist/LinearGenomeView/components/GetSequenceDialog.js.map +1 -1
  29. package/dist/LinearGenomeView/components/Gridlines.d.ts +1 -1
  30. package/dist/LinearGenomeView/components/Header.d.ts +1 -1
  31. package/dist/LinearGenomeView/components/Header.js +2 -2
  32. package/dist/LinearGenomeView/components/HelpDialog.js +2 -17
  33. package/dist/LinearGenomeView/components/HelpDialog.js.map +1 -1
  34. package/dist/LinearGenomeView/components/ImportForm.d.ts +1 -1
  35. package/dist/LinearGenomeView/components/ImportForm.js +18 -16
  36. package/dist/LinearGenomeView/components/ImportForm.js.map +1 -1
  37. package/dist/LinearGenomeView/components/LinearGenomeView.d.ts +1 -1
  38. package/dist/LinearGenomeView/components/LinearGenomeView.js +1 -3
  39. package/dist/LinearGenomeView/components/LinearGenomeView.js.map +1 -1
  40. package/dist/LinearGenomeView/components/LinearGenomeViewSvg.d.ts +1 -1
  41. package/dist/LinearGenomeView/components/LinearGenomeViewSvg.js +5 -5
  42. package/dist/LinearGenomeView/components/{OverviewRubberBand.d.ts → OverviewRubberband.d.ts} +3 -3
  43. package/dist/LinearGenomeView/components/{OverviewRubberBand.js → OverviewRubberband.js} +27 -79
  44. package/dist/LinearGenomeView/components/OverviewRubberband.js.map +1 -0
  45. package/{esm/LinearGenomeView/components/OverviewScaleBar.d.ts → dist/LinearGenomeView/components/OverviewScalebar.d.ts} +3 -3
  46. package/dist/LinearGenomeView/components/{OverviewScaleBar.js → OverviewScalebar.js} +25 -24
  47. package/dist/LinearGenomeView/components/OverviewScalebar.js.map +1 -0
  48. package/dist/LinearGenomeView/components/RefNameAutocomplete.js +1 -1
  49. package/dist/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
  50. package/dist/LinearGenomeView/components/{RubberBand.d.ts → Rubberband.d.ts} +3 -3
  51. package/dist/LinearGenomeView/components/Rubberband.js +57 -0
  52. package/dist/LinearGenomeView/components/Rubberband.js.map +1 -0
  53. package/dist/LinearGenomeView/components/RubberbandSpan.d.ts +14 -0
  54. package/dist/LinearGenomeView/components/RubberbandSpan.js +90 -0
  55. package/dist/LinearGenomeView/components/RubberbandSpan.js.map +1 -0
  56. package/dist/LinearGenomeView/components/{ScaleBar.d.ts → Scalebar.d.ts} +3 -3
  57. package/dist/LinearGenomeView/components/{ScaleBar.js → Scalebar.js} +11 -11
  58. package/dist/LinearGenomeView/components/{ScaleBar.js.map → Scalebar.js.map} +1 -1
  59. package/dist/LinearGenomeView/components/SearchBox.js +6 -6
  60. package/dist/LinearGenomeView/components/SearchBox.js.map +1 -1
  61. package/dist/LinearGenomeView/components/SearchResultsDialog.js +17 -31
  62. package/dist/LinearGenomeView/components/SearchResultsDialog.js.map +1 -1
  63. package/dist/LinearGenomeView/components/SequenceSearchDialog.js +4 -19
  64. package/dist/LinearGenomeView/components/SequenceSearchDialog.js.map +1 -1
  65. package/dist/LinearGenomeView/components/TrackContainer.d.ts +1 -1
  66. package/dist/LinearGenomeView/components/TrackContainer.js +13 -10
  67. package/dist/LinearGenomeView/components/TrackContainer.js.map +1 -1
  68. package/dist/LinearGenomeView/components/TrackLabel.js +9 -1
  69. package/dist/LinearGenomeView/components/TrackLabel.js.map +1 -1
  70. package/dist/LinearGenomeView/components/TracksContainer.d.ts +1 -1
  71. package/dist/LinearGenomeView/components/TracksContainer.js +21 -118
  72. package/dist/LinearGenomeView/components/TracksContainer.js.map +1 -1
  73. package/dist/LinearGenomeView/components/VerticalGuide.d.ts +9 -0
  74. package/dist/LinearGenomeView/components/VerticalGuide.js +29 -0
  75. package/dist/LinearGenomeView/components/VerticalGuide.js.map +1 -0
  76. package/dist/LinearGenomeView/components/hooks.d.ts +65 -0
  77. package/dist/LinearGenomeView/components/hooks.js +264 -0
  78. package/dist/LinearGenomeView/components/hooks.js.map +1 -0
  79. package/dist/LinearGenomeView/components/util.d.ts +5 -2
  80. package/dist/LinearGenomeView/components/util.js +7 -6
  81. package/dist/LinearGenomeView/components/util.js.map +1 -1
  82. package/dist/LinearGenomeView/index.d.ts +3 -453
  83. package/dist/LinearGenomeView/index.js +11 -1247
  84. package/dist/LinearGenomeView/index.js.map +1 -1
  85. package/dist/LinearGenomeView/model.d.ts +535 -0
  86. package/dist/LinearGenomeView/model.js +1357 -0
  87. package/dist/LinearGenomeView/model.js.map +1 -0
  88. package/dist/index.d.ts +20 -8
  89. package/dist/index.js +9 -72
  90. package/dist/index.js.map +1 -1
  91. package/esm/BaseLinearDisplay/components/Tooltip.d.ts +1 -1
  92. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +3 -3
  93. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.d.ts +2 -2
  94. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +1 -1
  95. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
  96. package/esm/BasicTrack/index.d.ts +1 -1
  97. package/esm/BasicTrack/index.js +4 -4
  98. package/esm/BasicTrack/index.js.map +1 -1
  99. package/esm/LaunchLinearGenomeView/index.d.ts +3 -0
  100. package/esm/LaunchLinearGenomeView/index.js +42 -0
  101. package/esm/LaunchLinearGenomeView/index.js.map +1 -0
  102. package/esm/LinearBareDisplay/index.d.ts +6 -2
  103. package/esm/LinearBareDisplay/index.js +18 -2
  104. package/esm/LinearBareDisplay/index.js.map +1 -1
  105. package/esm/LinearBasicDisplay/components/SetMaxHeight.js +3 -13
  106. package/esm/LinearBasicDisplay/components/SetMaxHeight.js.map +1 -1
  107. package/esm/LinearBasicDisplay/index.d.ts +6 -2
  108. package/esm/LinearBasicDisplay/index.js +19 -2
  109. package/esm/LinearBasicDisplay/index.js.map +1 -1
  110. package/esm/LinearBasicDisplay/model.d.ts +21 -14
  111. package/esm/LinearBasicDisplay/model.js +2 -1
  112. package/esm/LinearBasicDisplay/model.js.map +1 -1
  113. package/esm/LinearGenomeView/components/CenterLine.d.ts +1 -1
  114. package/esm/LinearGenomeView/components/ExportSvgDialog.js +3 -18
  115. package/esm/LinearGenomeView/components/ExportSvgDialog.js.map +1 -1
  116. package/esm/LinearGenomeView/components/GetSequenceDialog.d.ts +1 -1
  117. package/esm/LinearGenomeView/components/GetSequenceDialog.js +8 -19
  118. package/esm/LinearGenomeView/components/GetSequenceDialog.js.map +1 -1
  119. package/esm/LinearGenomeView/components/Gridlines.d.ts +1 -1
  120. package/esm/LinearGenomeView/components/Header.d.ts +1 -1
  121. package/esm/LinearGenomeView/components/Header.js +2 -2
  122. package/esm/LinearGenomeView/components/HelpDialog.js +3 -18
  123. package/esm/LinearGenomeView/components/HelpDialog.js.map +1 -1
  124. package/esm/LinearGenomeView/components/ImportForm.d.ts +1 -1
  125. package/esm/LinearGenomeView/components/ImportForm.js +18 -16
  126. package/esm/LinearGenomeView/components/ImportForm.js.map +1 -1
  127. package/esm/LinearGenomeView/components/LinearGenomeView.d.ts +1 -1
  128. package/esm/LinearGenomeView/components/LinearGenomeView.js +2 -4
  129. package/esm/LinearGenomeView/components/LinearGenomeView.js.map +1 -1
  130. package/esm/LinearGenomeView/components/LinearGenomeViewSvg.d.ts +1 -1
  131. package/esm/LinearGenomeView/components/LinearGenomeViewSvg.js +3 -3
  132. package/esm/LinearGenomeView/components/{OverviewRubberBand.d.ts → OverviewRubberband.d.ts} +3 -3
  133. package/esm/LinearGenomeView/components/{OverviewRubberBand.js → OverviewRubberband.js} +25 -80
  134. package/esm/LinearGenomeView/components/OverviewRubberband.js.map +1 -0
  135. package/{dist/LinearGenomeView/components/OverviewScaleBar.d.ts → esm/LinearGenomeView/components/OverviewScalebar.d.ts} +3 -3
  136. package/esm/LinearGenomeView/components/{OverviewScaleBar.js → OverviewScalebar.js} +25 -24
  137. package/esm/LinearGenomeView/components/OverviewScalebar.js.map +1 -0
  138. package/esm/LinearGenomeView/components/RefNameAutocomplete.js +1 -1
  139. package/esm/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
  140. package/esm/LinearGenomeView/components/{RubberBand.d.ts → Rubberband.d.ts} +3 -3
  141. package/esm/LinearGenomeView/components/Rubberband.js +29 -0
  142. package/esm/LinearGenomeView/components/Rubberband.js.map +1 -0
  143. package/esm/LinearGenomeView/components/RubberbandSpan.d.ts +14 -0
  144. package/esm/LinearGenomeView/components/RubberbandSpan.js +65 -0
  145. package/esm/LinearGenomeView/components/RubberbandSpan.js.map +1 -0
  146. package/esm/LinearGenomeView/components/{ScaleBar.d.ts → Scalebar.d.ts} +3 -3
  147. package/esm/LinearGenomeView/components/{ScaleBar.js → Scalebar.js} +11 -11
  148. package/esm/LinearGenomeView/components/{ScaleBar.js.map → Scalebar.js.map} +1 -1
  149. package/esm/LinearGenomeView/components/SearchBox.js +6 -6
  150. package/esm/LinearGenomeView/components/SearchBox.js.map +1 -1
  151. package/esm/LinearGenomeView/components/SearchResultsDialog.js +18 -32
  152. package/esm/LinearGenomeView/components/SearchResultsDialog.js.map +1 -1
  153. package/esm/LinearGenomeView/components/SequenceSearchDialog.js +5 -17
  154. package/esm/LinearGenomeView/components/SequenceSearchDialog.js.map +1 -1
  155. package/esm/LinearGenomeView/components/TrackContainer.d.ts +1 -1
  156. package/esm/LinearGenomeView/components/TrackContainer.js +14 -11
  157. package/esm/LinearGenomeView/components/TrackContainer.js.map +1 -1
  158. package/esm/LinearGenomeView/components/TrackLabel.js +9 -1
  159. package/esm/LinearGenomeView/components/TrackLabel.js.map +1 -1
  160. package/esm/LinearGenomeView/components/TracksContainer.d.ts +1 -1
  161. package/esm/LinearGenomeView/components/TracksContainer.js +22 -119
  162. package/esm/LinearGenomeView/components/TracksContainer.js.map +1 -1
  163. package/esm/LinearGenomeView/components/VerticalGuide.d.ts +9 -0
  164. package/esm/LinearGenomeView/components/VerticalGuide.js +24 -0
  165. package/esm/LinearGenomeView/components/VerticalGuide.js.map +1 -0
  166. package/esm/LinearGenomeView/components/hooks.d.ts +65 -0
  167. package/esm/LinearGenomeView/components/hooks.js +255 -0
  168. package/esm/LinearGenomeView/components/hooks.js.map +1 -0
  169. package/esm/LinearGenomeView/components/util.d.ts +5 -2
  170. package/esm/LinearGenomeView/components/util.js +4 -3
  171. package/esm/LinearGenomeView/components/util.js.map +1 -1
  172. package/esm/LinearGenomeView/index.d.ts +3 -453
  173. package/esm/LinearGenomeView/index.js +9 -1238
  174. package/esm/LinearGenomeView/index.js.map +1 -1
  175. package/esm/LinearGenomeView/model.d.ts +535 -0
  176. package/esm/LinearGenomeView/model.js +1322 -0
  177. package/esm/LinearGenomeView/model.js.map +1 -0
  178. package/esm/index.d.ts +20 -8
  179. package/esm/index.js +9 -72
  180. package/esm/index.js.map +1 -1
  181. package/package.json +3 -3
  182. package/src/BaseLinearDisplay/models/serverSideRenderedBlock.ts +1 -1
  183. package/src/BasicTrack/index.ts +4 -8
  184. package/src/LaunchLinearGenomeView/index.ts +66 -0
  185. package/src/LinearBareDisplay/index.ts +21 -2
  186. package/src/LinearBasicDisplay/components/SetMaxHeight.tsx +3 -28
  187. package/src/LinearBasicDisplay/index.ts +23 -2
  188. package/src/LinearBasicDisplay/model.ts +2 -1
  189. package/src/LinearGenomeView/components/ExportSvgDialog.tsx +2 -23
  190. package/src/LinearGenomeView/components/GetSequenceDialog.tsx +13 -31
  191. package/src/LinearGenomeView/components/Header.tsx +3 -3
  192. package/src/LinearGenomeView/components/HelpDialog.tsx +8 -34
  193. package/src/LinearGenomeView/components/ImportForm.tsx +19 -16
  194. package/src/LinearGenomeView/components/LinearGenomeView.tsx +2 -8
  195. package/src/LinearGenomeView/components/LinearGenomeViewSvg.tsx +3 -3
  196. package/src/LinearGenomeView/components/{OverviewRubberBand.tsx → OverviewRubberband.tsx} +32 -114
  197. package/src/LinearGenomeView/components/{OverviewScaleBar.tsx → OverviewScalebar.tsx} +26 -25
  198. package/src/LinearGenomeView/components/RefNameAutocomplete.tsx +2 -1
  199. package/src/LinearGenomeView/components/Rubberband.tsx +89 -0
  200. package/src/LinearGenomeView/components/RubberbandSpan.tsx +116 -0
  201. package/src/LinearGenomeView/components/{ScaleBar.test.tsx → Scalebar.test.tsx} +5 -5
  202. package/src/LinearGenomeView/components/{ScaleBar.tsx → Scalebar.tsx} +11 -11
  203. package/src/LinearGenomeView/components/SearchBox.tsx +6 -6
  204. package/src/LinearGenomeView/components/SearchResultsDialog.tsx +17 -44
  205. package/src/LinearGenomeView/components/SequenceSearchDialog.tsx +4 -30
  206. package/src/LinearGenomeView/components/TrackContainer.tsx +41 -28
  207. package/src/LinearGenomeView/components/TrackLabel.tsx +10 -1
  208. package/src/LinearGenomeView/components/TracksContainer.tsx +59 -136
  209. package/src/LinearGenomeView/components/VerticalGuide.tsx +37 -0
  210. package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.tsx.snap +37 -39
  211. package/src/LinearGenomeView/components/hooks.ts +300 -0
  212. package/src/LinearGenomeView/components/util.ts +8 -11
  213. package/src/LinearGenomeView/index.test.ts +6 -7
  214. package/src/LinearGenomeView/index.ts +17 -0
  215. package/src/LinearGenomeView/{index.tsx → model.ts} +159 -75
  216. package/src/index.ts +13 -108
  217. package/dist/LinearGenomeView/components/OverviewRubberBand.js.map +0 -1
  218. package/dist/LinearGenomeView/components/OverviewScaleBar.js.map +0 -1
  219. package/dist/LinearGenomeView/components/RubberBand.js +0 -221
  220. package/dist/LinearGenomeView/components/RubberBand.js.map +0 -1
  221. package/esm/LinearGenomeView/components/OverviewRubberBand.js.map +0 -1
  222. package/esm/LinearGenomeView/components/OverviewScaleBar.js.map +0 -1
  223. package/esm/LinearGenomeView/components/RubberBand.js +0 -196
  224. package/esm/LinearGenomeView/components/RubberBand.js.map +0 -1
  225. package/src/LinearGenomeView/components/RubberBand.tsx +0 -308
@@ -22,1255 +22,19 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
25
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
26
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.ReactComponent = exports.LinearGenomeView = exports.ZoomControls = exports.SearchBox = exports.RefNameAutocomplete = exports.renderToSvg = exports.stateModelFactory = exports.WIDGET_HEIGHT = exports.SPACING = exports.INTER_REGION_PADDING_WIDTH = exports.RESIZE_HANDLE_HEIGHT = exports.SCALE_BAR_HEIGHT = exports.HEADER_OVERVIEW_HEIGHT = exports.HEADER_BAR_HEIGHT = void 0;
30
29
  const react_1 = require("react");
31
- const configuration_1 = require("@jbrowse/core/configuration");
32
- const models_1 = require("@jbrowse/core/pluggableElementTypes/models");
33
- const mst_1 = require("@jbrowse/core/util/types/mst");
34
- const ui_1 = require("@jbrowse/core/ui");
35
- const util_1 = require("@jbrowse/core/util");
36
- const calculateDynamicBlocks_1 = __importDefault(require("@jbrowse/core/util/calculateDynamicBlocks"));
37
- const calculateStaticBlocks_1 = __importDefault(require("@jbrowse/core/util/calculateStaticBlocks"));
38
- const tracks_1 = require("@jbrowse/core/util/tracks");
39
- const mobx_1 = require("mobx");
40
- const mobx_state_tree_1 = require("mobx-state-tree");
41
- const Base1DViewModel_1 = __importDefault(require("@jbrowse/core/util/Base1DViewModel"));
42
- const Base1DUtils_1 = require("@jbrowse/core/util/Base1DUtils");
43
- const file_saver_1 = require("file-saver");
44
- const clone_1 = __importDefault(require("clone"));
45
- // icons
46
- const Icons_1 = require("@jbrowse/core/ui/Icons");
47
- const SyncAlt_1 = __importDefault(require("@mui/icons-material/SyncAlt"));
48
- const Visibility_1 = __importDefault(require("@mui/icons-material/Visibility"));
49
- const Label_1 = __importDefault(require("@mui/icons-material/Label"));
50
- const FolderOpen_1 = __importDefault(require("@mui/icons-material/FolderOpen"));
51
- const PhotoCamera_1 = __importDefault(require("@mui/icons-material/PhotoCamera"));
52
- const ZoomIn_1 = __importDefault(require("@mui/icons-material/ZoomIn"));
53
- const MenuOpen_1 = __importDefault(require("@mui/icons-material/MenuOpen"));
54
- // locals
55
- const LinearGenomeViewSvg_1 = require("./components/LinearGenomeViewSvg");
56
- Object.defineProperty(exports, "renderToSvg", { enumerable: true, get: function () { return LinearGenomeViewSvg_1.renderToSvg; } });
57
- const RefNameAutocomplete_1 = __importDefault(require("./components/RefNameAutocomplete"));
58
- exports.RefNameAutocomplete = RefNameAutocomplete_1.default;
59
- const SearchBox_1 = __importDefault(require("./components/SearchBox"));
60
- exports.SearchBox = SearchBox_1.default;
61
- const ExportSvgDialog_1 = __importDefault(require("./components/ExportSvgDialog"));
62
- const MiniControls_1 = __importDefault(require("./components/MiniControls"));
63
- const Header_1 = __importDefault(require("./components/Header"));
64
- const ZoomControls_1 = __importDefault(require("./components/ZoomControls"));
65
- exports.ZoomControls = ZoomControls_1.default;
66
- const LinearGenomeView_1 = __importDefault(require("./components/LinearGenomeView"));
67
- exports.LinearGenomeView = LinearGenomeView_1.default;
68
- const SequenceSearchDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./components/SequenceSearchDialog'))));
69
- function calculateVisibleLocStrings(contentBlocks) {
70
- if (!contentBlocks.length) {
71
- return '';
72
- }
73
- const isSingleAssemblyName = contentBlocks.every(b => b.assemblyName === contentBlocks[0].assemblyName);
74
- const locs = contentBlocks.map(block => (0, util_1.assembleLocString)({
75
- ...block,
76
- start: Math.round(block.start),
77
- end: Math.round(block.end),
78
- assemblyName: isSingleAssemblyName ? undefined : block.assemblyName,
79
- }));
80
- return locs.join(' ');
81
- }
82
- exports.HEADER_BAR_HEIGHT = 48;
83
- exports.HEADER_OVERVIEW_HEIGHT = 20;
84
- exports.SCALE_BAR_HEIGHT = 17;
85
- exports.RESIZE_HANDLE_HEIGHT = 3;
86
- exports.INTER_REGION_PADDING_WIDTH = 2;
87
- exports.SPACING = 7;
88
- exports.WIDGET_HEIGHT = 32;
89
- function localStorageGetItem(item) {
90
- return typeof localStorage !== 'undefined'
91
- ? localStorage.getItem(item)
92
- : undefined;
93
- }
94
- /**
95
- * #stateModel LinearGenomeView
96
- */
97
- function stateModelFactory(pluginManager) {
98
- return mobx_state_tree_1.types
99
- .compose(models_1.BaseViewModel, mobx_state_tree_1.types.model('LinearGenomeView', {
100
- /**
101
- * #property
102
- */
103
- id: mst_1.ElementId,
104
- /**
105
- * #property
106
- */
107
- type: mobx_state_tree_1.types.literal('LinearGenomeView'),
108
- /**
109
- * #property
110
- * corresponds roughly to the horizontal scroll of the LGV
111
- */
112
- offsetPx: 0,
113
- /**
114
- * #property
115
- * corresponds roughly to the zoom level, base-pairs per pixel
116
- */
117
- bpPerPx: 1,
118
- /**
119
- * #property
120
- * currently displayed regions, can be a single chromosome, arbitrary subsections,
121
- * or the entire set of chromosomes in the genome, but it not advised to use the
122
- * entire set of chromosomes if your assembly is very fragmented
123
- */
124
- displayedRegions: mobx_state_tree_1.types.array(mst_1.Region),
125
- /**
126
- * #property
127
- * array of currently displayed tracks state models instances
128
- */
129
- tracks: mobx_state_tree_1.types.array(pluginManager.pluggableMstType('track', 'stateModel')),
130
- /**
131
- * #property
132
- * array of currently displayed tracks state model's
133
- */
134
- hideHeader: false,
135
- /**
136
- * #property
137
- */
138
- hideHeaderOverview: false,
139
- /**
140
- * #property
141
- */
142
- hideNoTracksActive: false,
143
- /**
144
- * #property
145
- */
146
- trackSelectorType: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.enumeration(['hierarchical']), 'hierarchical'),
147
- /**
148
- * #property
149
- * how to display the track labels, can be "overlapping", "offset", or "hidden"
150
- */
151
- trackLabels: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.string, () => localStorageGetItem('lgv-trackLabels') || 'overlapping'),
152
- /**
153
- * #property
154
- * show the "center line"
155
- */
156
- showCenterLine: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, () => {
157
- const setting = localStorageGetItem('lgv-showCenterLine');
158
- return setting !== undefined && setting !== null ? !!+setting : false;
159
- }),
160
- /**
161
- * #property
162
- * show the "cytobands" in the overview scale bar
163
- */
164
- showCytobandsSetting: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, () => {
165
- const setting = localStorageGetItem('lgv-showCytobands');
166
- return setting !== undefined && setting !== null ? !!+setting : true;
167
- }),
168
- /**
169
- * #property
170
- * show the "gridlines" in the track area
171
- */
172
- showGridlines: true,
173
- }))
174
- .volatile(() => ({
175
- volatileWidth: undefined,
176
- minimumBlockWidth: 3,
177
- draggingTrackId: undefined,
178
- volatileError: undefined,
179
- // array of callbacks to run after the next set of the displayedRegions,
180
- // which is basically like an onLoad
181
- afterDisplayedRegionsSetCallbacks: [],
182
- scaleFactor: 1,
183
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
184
- trackRefs: {},
185
- coarseDynamicBlocks: [],
186
- coarseTotalBp: 0,
187
- leftOffset: undefined,
188
- rightOffset: undefined,
189
- searchResults: undefined,
190
- searchQuery: undefined,
191
- seqDialogDisplayed: false,
192
- }))
193
- .views(self => ({
194
- /**
195
- * #getter
196
- */
197
- get width() {
198
- if (self.volatileWidth === undefined) {
199
- throw new Error('width undefined, make sure to check for model.initialized');
200
- }
201
- return self.volatileWidth;
202
- },
203
- /**
204
- * #getter
205
- */
206
- get interRegionPaddingWidth() {
207
- return exports.INTER_REGION_PADDING_WIDTH;
208
- },
209
- /**
210
- * #getter
211
- */
212
- get assemblyNames() {
213
- return [
214
- ...new Set(self.displayedRegions.map(region => region.assemblyName)),
215
- ];
216
- },
217
- }))
218
- .views(self => ({
219
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
220
- MiniControlsComponent() {
221
- return MiniControls_1.default;
222
- },
223
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
224
- HeaderComponent() {
225
- return Header_1.default;
226
- },
227
- get assemblyErrors() {
228
- const { assemblyManager } = (0, util_1.getSession)(self);
229
- const { assemblyNames } = self;
230
- return assemblyNames
231
- .map(a => { var _a; return (_a = assemblyManager.get(a)) === null || _a === void 0 ? void 0 : _a.error; })
232
- .filter(f => !!f)
233
- .join(', ');
234
- },
235
- get assembliesInitialized() {
236
- const { assemblyManager } = (0, util_1.getSession)(self);
237
- const { assemblyNames } = self;
238
- return assemblyNames.every(a => { var _a; return (_a = assemblyManager.get(a)) === null || _a === void 0 ? void 0 : _a.initialized; });
239
- },
240
- get initialized() {
241
- return self.volatileWidth !== undefined && this.assembliesInitialized;
242
- },
243
- get hasDisplayedRegions() {
244
- return self.displayedRegions.length > 0;
245
- },
246
- get isSearchDialogDisplayed() {
247
- return self.searchResults !== undefined;
248
- },
249
- get scaleBarHeight() {
250
- return exports.SCALE_BAR_HEIGHT + exports.RESIZE_HANDLE_HEIGHT;
251
- },
252
- get headerHeight() {
253
- if (self.hideHeader) {
254
- return 0;
255
- }
256
- if (self.hideHeaderOverview) {
257
- return exports.HEADER_BAR_HEIGHT;
258
- }
259
- return exports.HEADER_BAR_HEIGHT + exports.HEADER_OVERVIEW_HEIGHT;
260
- },
261
- get trackHeights() {
262
- return self.tracks
263
- .map(t => t.displays[0].height)
264
- .reduce((a, b) => a + b, 0);
265
- },
266
- get trackHeightsWithResizeHandles() {
267
- return this.trackHeights + self.tracks.length * exports.RESIZE_HANDLE_HEIGHT;
268
- },
269
- get height() {
270
- return (this.trackHeightsWithResizeHandles +
271
- this.headerHeight +
272
- this.scaleBarHeight);
273
- },
274
- get totalBp() {
275
- return self.displayedRegions.reduce((a, b) => a + b.end - b.start, 0);
276
- },
277
- get maxBpPerPx() {
278
- return this.totalBp / (self.width * 0.9);
279
- },
280
- get minBpPerPx() {
281
- return 1 / 50;
282
- },
283
- get error() {
284
- return self.volatileError || this.assemblyErrors;
285
- },
286
- get maxOffset() {
287
- // objectively determined to keep the linear genome on the main screen
288
- const leftPadding = 10;
289
- return this.displayedRegionsTotalPx - leftPadding;
290
- },
291
- get minOffset() {
292
- // objectively determined to keep the linear genome on the main screen
293
- const rightPadding = 30;
294
- return -self.width + rightPadding;
295
- },
296
- get displayedRegionsTotalPx() {
297
- return this.totalBp / self.bpPerPx;
298
- },
299
- renderProps() {
300
- return {
301
- ...(0, tracks_1.getParentRenderProps)(self),
302
- bpPerPx: self.bpPerPx,
303
- highResolutionScaling: (0, configuration_1.getConf)((0, util_1.getSession)(self), 'highResolutionScaling'),
304
- };
305
- },
306
- searchScope(assemblyName) {
307
- return {
308
- assemblyName,
309
- includeAggregateIndexes: true,
310
- tracks: self.tracks,
311
- };
312
- },
313
- getTrack(id) {
314
- return self.tracks.find(t => t.configuration.trackId === id);
315
- },
316
- rankSearchResults(results) {
317
- // order of rank
318
- const openTrackIds = self.tracks.map(track => track.configuration.trackId);
319
- results.forEach(result => {
320
- if (openTrackIds.includes(result.trackId)) {
321
- result.updateScore(result.getScore() + 1);
322
- }
323
- });
324
- return results;
325
- },
326
- // modifies view menu action onClick to apply to all tracks of same type
327
- rewriteOnClicks(trackType, viewMenuActions) {
328
- viewMenuActions.forEach(action => {
329
- // go to lowest level menu
330
- if ('subMenu' in action) {
331
- this.rewriteOnClicks(trackType, action.subMenu);
332
- }
333
- if ('onClick' in action) {
334
- const holdOnClick = action.onClick;
335
- action.onClick = (...args) => {
336
- self.tracks.forEach(track => {
337
- if (track.type === trackType) {
338
- holdOnClick.apply(track, [track, ...args]);
339
- }
340
- });
341
- };
342
- }
343
- });
344
- },
345
- get trackTypeActions() {
346
- const allActions = new Map();
347
- self.tracks.forEach(track => {
348
- const trackInMap = allActions.get(track.type);
349
- if (!trackInMap) {
350
- const viewMenuActions = (0, clone_1.default)(track.viewMenuActions);
351
- this.rewriteOnClicks(track.type, viewMenuActions);
352
- allActions.set(track.type, viewMenuActions);
353
- }
354
- });
355
- return allActions;
356
- },
357
- }))
358
- .actions(self => ({
359
- /**
360
- * #action
361
- */
362
- setShowCytobands(flag) {
363
- self.showCytobandsSetting = flag;
364
- localStorage.setItem('lgv-showCytobands', `${+flag}`);
365
- },
366
- /**
367
- * #action
368
- */
369
- setWidth(newWidth) {
370
- self.volatileWidth = newWidth;
371
- },
372
- /**
373
- * #action
374
- */
375
- setError(error) {
376
- self.volatileError = error;
377
- },
378
- /**
379
- * #action
380
- */
381
- toggleHeader() {
382
- self.hideHeader = !self.hideHeader;
383
- },
384
- /**
385
- * #action
386
- */
387
- toggleHeaderOverview() {
388
- self.hideHeaderOverview = !self.hideHeaderOverview;
389
- },
390
- /**
391
- * #action
392
- */
393
- toggleNoTracksActive() {
394
- self.hideNoTracksActive = !self.hideNoTracksActive;
395
- },
396
- /**
397
- * #action
398
- */
399
- toggleShowGridlines() {
400
- self.showGridlines = !self.showGridlines;
401
- },
402
- /**
403
- * #action
404
- */
405
- scrollTo(offsetPx) {
406
- const newOffsetPx = (0, util_1.clamp)(offsetPx, self.minOffset, self.maxOffset);
407
- self.offsetPx = newOffsetPx;
408
- return newOffsetPx;
409
- },
410
- /**
411
- * #action
412
- */
413
- zoomTo(bpPerPx) {
414
- const newBpPerPx = (0, util_1.clamp)(bpPerPx, self.minBpPerPx, self.maxBpPerPx);
415
- if (newBpPerPx === self.bpPerPx) {
416
- return newBpPerPx;
417
- }
418
- const oldBpPerPx = self.bpPerPx;
419
- self.bpPerPx = newBpPerPx;
420
- if (Math.abs(oldBpPerPx - newBpPerPx) < 0.000001) {
421
- console.warn('zoomTo bpPerPx rounding error');
422
- return oldBpPerPx;
423
- }
424
- // tweak the offset so that the center of the view remains at the same coordinate
425
- const viewWidth = self.width;
426
- this.scrollTo(Math.round(((self.offsetPx + viewWidth / 2) * oldBpPerPx) / newBpPerPx -
427
- viewWidth / 2));
428
- return newBpPerPx;
429
- },
430
- /**
431
- * #action
432
- * sets offsets used in the get sequence dialog
433
- */
434
- setOffsets(left, right) {
435
- self.leftOffset = left;
436
- self.rightOffset = right;
437
- },
438
- /**
439
- * #action
440
- */
441
- setSearchResults(results, query) {
442
- self.searchResults = results;
443
- self.searchQuery = query;
444
- },
445
- /**
446
- * #action
447
- */
448
- setGetSequenceDialogOpen(open) {
449
- self.seqDialogDisplayed = open;
450
- },
451
- /**
452
- * #action
453
- */
454
- setNewView(bpPerPx, offsetPx) {
455
- this.zoomTo(bpPerPx);
456
- this.scrollTo(offsetPx);
457
- },
458
- /**
459
- * #action
460
- */
461
- horizontallyFlip() {
462
- self.displayedRegions = (0, mobx_state_tree_1.cast)(self.displayedRegions
463
- .slice()
464
- .reverse()
465
- .map(region => ({ ...region, reversed: !region.reversed })));
466
- this.scrollTo(self.totalBp / self.bpPerPx - self.offsetPx - self.width);
467
- },
468
- /**
469
- * #action
470
- */
471
- showTrack(trackId, initialSnapshot = {}, displayInitialSnapshot = {}) {
472
- const schema = pluginManager.pluggableConfigSchemaType('track');
473
- const conf = (0, mobx_state_tree_1.resolveIdentifier)(schema, (0, mobx_state_tree_1.getRoot)(self), trackId);
474
- if (!conf) {
475
- throw new Error(`Could not resolve identifier "${trackId}"`);
476
- }
477
- const trackType = pluginManager.getTrackType(conf === null || conf === void 0 ? void 0 : conf.type);
478
- if (!trackType) {
479
- throw new Error(`Unknown track type ${conf.type}`);
480
- }
481
- const viewType = pluginManager.getViewType(self.type);
482
- const supportedDisplays = viewType.displayTypes.map(d => d.name);
483
- const displayConf = conf.displays.find((d) => supportedDisplays.includes(d.type));
484
- if (!displayConf) {
485
- throw new Error(`Could not find a compatible display for view type ${self.type}`);
486
- }
487
- const t = self.tracks.filter(t => t.configuration === conf);
488
- if (t.length === 0) {
489
- const track = trackType.stateModel.create({
490
- ...initialSnapshot,
491
- type: conf.type,
492
- configuration: conf,
493
- displays: [
494
- {
495
- type: displayConf.type,
496
- configuration: displayConf,
497
- ...displayInitialSnapshot,
498
- },
499
- ],
500
- });
501
- self.tracks.push(track);
502
- return track;
503
- }
504
- return t[0];
505
- },
506
- hideTrack(trackId) {
507
- const schema = pluginManager.pluggableConfigSchemaType('track');
508
- const conf = (0, mobx_state_tree_1.resolveIdentifier)(schema, (0, mobx_state_tree_1.getRoot)(self), trackId);
509
- const t = self.tracks.filter(t => t.configuration === conf);
510
- (0, mobx_1.transaction)(() => t.forEach(t => self.tracks.remove(t)));
511
- return t.length;
512
- },
513
- }))
514
- .actions(self => ({
515
- /**
516
- * #action
517
- */
518
- moveTrack(movingId, targetId) {
519
- const oldIndex = self.tracks.findIndex(track => track.id === movingId);
520
- if (oldIndex === -1) {
521
- throw new Error(`Track ID ${movingId} not found`);
522
- }
523
- const newIndex = self.tracks.findIndex(track => track.id === targetId);
524
- if (newIndex === -1) {
525
- throw new Error(`Track ID ${targetId} not found`);
526
- }
527
- const track = (0, mobx_state_tree_1.getSnapshot)(self.tracks[oldIndex]);
528
- self.tracks.splice(oldIndex, 1);
529
- self.tracks.splice(newIndex, 0, track);
530
- },
531
- /**
532
- * #action
533
- */
534
- closeView() {
535
- const parent = (0, util_1.getContainingView)(self);
536
- if (parent) {
537
- // I am embedded in a some other view
538
- if ((0, util_1.isViewContainer)(parent)) {
539
- parent.removeView(self);
540
- }
541
- }
542
- else {
543
- // I am part of a session
544
- (0, util_1.getSession)(self).removeView(self);
545
- }
546
- },
547
- /**
548
- * #action
549
- */
550
- toggleTrack(trackId) {
551
- // if we have any tracks with that configuration, turn them off
552
- const hiddenCount = self.hideTrack(trackId);
553
- // if none had that configuration, turn one on
554
- if (!hiddenCount) {
555
- self.showTrack(trackId);
556
- }
557
- },
558
- /**
559
- * #action
560
- */
561
- setTrackLabels(setting) {
562
- self.trackLabels = setting;
563
- localStorage.setItem('lgv-trackLabels', setting);
564
- },
565
- /**
566
- * #action
567
- */
568
- toggleCenterLine() {
569
- self.showCenterLine = !self.showCenterLine;
570
- localStorage.setItem('lgv-showCenterLine', `${+self.showCenterLine}`);
571
- },
572
- /**
573
- * #action
574
- */
575
- setDisplayedRegions(regions) {
576
- self.displayedRegions = (0, mobx_state_tree_1.cast)(regions);
577
- self.zoomTo(self.bpPerPx);
578
- },
579
- /**
580
- * #action
581
- */
582
- activateTrackSelector() {
583
- if (self.trackSelectorType === 'hierarchical') {
584
- const session = (0, util_1.getSession)(self);
585
- if ((0, util_1.isSessionModelWithWidgets)(session)) {
586
- const selector = session.addWidget('HierarchicalTrackSelectorWidget', 'hierarchicalTrackSelector', { view: self });
587
- session.showWidget(selector);
588
- return selector;
589
- }
590
- }
591
- throw new Error(`invalid track selector type ${self.trackSelectorType}`);
592
- },
593
- /**
594
- * #method
595
- * Helper method for the fetchSequence.
596
- * Retrieves the corresponding regions that were selected by the rubberband
597
- *
598
- * @param leftOffset - `object as {start, end, index, offset}`, offset = start of user drag
599
- * @param rightOffset - `object as {start, end, index, offset}`, offset = end of user drag
600
- * @returns array of Region[]
601
- */
602
- getSelectedRegions(leftOffset, rightOffset) {
603
- const snap = (0, mobx_state_tree_1.getSnapshot)(self);
604
- const simView = Base1DViewModel_1.default.create({
605
- ...snap,
606
- interRegionPaddingWidth: self.interRegionPaddingWidth,
607
- });
608
- simView.setVolatileWidth(self.width);
609
- simView.moveTo(leftOffset, rightOffset);
610
- return simView.dynamicBlocks.contentBlocks.map(region => ({
611
- ...region,
612
- start: Math.floor(region.start),
613
- end: Math.ceil(region.end),
614
- }));
615
- },
616
- /**
617
- * #action
618
- * schedule something to be run after the next time displayedRegions is set
619
- */
620
- afterDisplayedRegionsSet(cb) {
621
- self.afterDisplayedRegionsSetCallbacks.push(cb);
622
- },
623
- /**
624
- * #action
625
- */
626
- horizontalScroll(distance) {
627
- const oldOffsetPx = self.offsetPx;
628
- // newOffsetPx is the actual offset after the scroll is clamped
629
- const newOffsetPx = self.scrollTo(self.offsetPx + distance);
630
- return newOffsetPx - oldOffsetPx;
631
- },
632
- /**
633
- * #action
634
- */
635
- center() {
636
- const centerBp = self.totalBp / 2;
637
- const centerPx = centerBp / self.bpPerPx;
638
- self.scrollTo(Math.round(centerPx - self.width / 2));
639
- },
640
- /**
641
- * #action
642
- */
643
- showAllRegions() {
644
- self.zoomTo(self.maxBpPerPx);
645
- this.center();
646
- },
647
- /**
648
- * #action
649
- */
650
- showAllRegionsInAssembly(assemblyName) {
651
- const session = (0, util_1.getSession)(self);
652
- const { assemblyManager } = session;
653
- if (!assemblyName) {
654
- const names = new Set(self.displayedRegions.map(r => r.assemblyName));
655
- if (names.size > 1) {
656
- session.notify(`Can't perform operation with multiple assemblies currently`);
657
- return;
658
- }
659
- ;
660
- [assemblyName] = [...names];
661
- }
662
- const assembly = assemblyManager.get(assemblyName);
663
- if (assembly) {
664
- const { regions } = assembly;
665
- if (regions) {
666
- this.setDisplayedRegions(regions);
667
- self.zoomTo(self.maxBpPerPx);
668
- this.center();
669
- }
670
- }
671
- },
672
- /**
673
- * #action
674
- */
675
- setDraggingTrackId(idx) {
676
- self.draggingTrackId = idx;
677
- },
678
- /**
679
- * #action
680
- */
681
- setScaleFactor(factor) {
682
- self.scaleFactor = factor;
683
- },
684
- /**
685
- * #action
686
- * this "clears the view" and makes the view return to the import form
687
- */
688
- clearView() {
689
- this.setDisplayedRegions([]);
690
- self.tracks.clear();
691
- // it is necessary to run these after setting displayed regions empty
692
- // or else model.offsetPx gets set to Infinity and breaks
693
- // mobx-state-tree snapshot
694
- self.scrollTo(0);
695
- self.zoomTo(10);
696
- },
697
- /**
698
- * #action
699
- * creates an svg export and save using FileSaver
700
- */
701
- async exportSvg(opts = {}) {
702
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
703
- const html = await (0, LinearGenomeViewSvg_1.renderToSvg)(self, opts);
704
- const blob = new Blob([html], { type: 'image/svg+xml' });
705
- (0, file_saver_1.saveAs)(blob, opts.filename || 'image.svg');
706
- },
707
- }))
708
- .actions(self => {
709
- let cancelLastAnimation = () => { };
710
- /**
711
- * #action
712
- * perform animated slide
713
- */
714
- function slide(viewWidths) {
715
- const [animate, cancelAnimation] = (0, util_1.springAnimate)(self.offsetPx, self.offsetPx + self.width * viewWidths, self.scrollTo);
716
- cancelLastAnimation();
717
- cancelLastAnimation = cancelAnimation;
718
- animate();
719
- }
720
- return { slide };
721
- })
722
- .actions(self => {
723
- let cancelLastAnimation = () => { };
724
- /**
725
- * #action
726
- * perform animated zoom
727
- */
728
- function zoom(targetBpPerPx) {
729
- self.zoomTo(self.bpPerPx);
730
- if (
731
- // already zoomed all the way in
732
- (targetBpPerPx < self.bpPerPx && self.bpPerPx === self.minBpPerPx) ||
733
- // already zoomed all the way out
734
- (targetBpPerPx > self.bpPerPx && self.bpPerPx === self.maxBpPerPx)) {
735
- return;
736
- }
737
- const factor = self.bpPerPx / targetBpPerPx;
738
- const [animate, cancelAnimation] = (0, util_1.springAnimate)(1, factor, self.setScaleFactor, () => {
739
- self.zoomTo(targetBpPerPx);
740
- self.setScaleFactor(1);
741
- });
742
- cancelLastAnimation();
743
- cancelLastAnimation = cancelAnimation;
744
- animate();
745
- }
746
- return { zoom };
747
- })
748
- .views(self => ({
749
- /**
750
- * #getter
751
- */
752
- get canShowCytobands() {
753
- return self.displayedRegions.length === 1 && this.anyCytobandsExist;
754
- },
755
- /**
756
- * #getter
757
- */
758
- get showCytobands() {
759
- return this.canShowCytobands && self.showCytobandsSetting;
760
- },
761
- /**
762
- * #getter
763
- */
764
- get anyCytobandsExist() {
765
- const { assemblyManager } = (0, util_1.getSession)(self);
766
- return self.assemblyNames.some(a => { var _a, _b; return (_b = (_a = assemblyManager.get(a)) === null || _a === void 0 ? void 0 : _a.cytobands) === null || _b === void 0 ? void 0 : _b.length; });
767
- },
768
- /**
769
- * #getter
770
- * the cytoband is displayed to the right of the chromosome name,
771
- * and that offset is calculated manually with this method
772
- */
773
- get cytobandOffset() {
774
- return this.showCytobands
775
- ? (0, util_1.measureText)(self.displayedRegions[0].refName, 12) + 15
776
- : 0;
777
- },
778
- }))
779
- .views(self => ({
780
- /**
781
- * #method
782
- * return the view menu items
783
- */
784
- menuItems() {
785
- const { canShowCytobands, showCytobands } = self;
786
- const session = (0, util_1.getSession)(self);
787
- const menuItems = [
788
- {
789
- label: 'Return to import form',
790
- onClick: () => {
791
- (0, util_1.getSession)(self).queueDialog(handleClose => [
792
- ui_1.ReturnToImportFormDialog,
793
- { model: self, handleClose },
794
- ]);
795
- },
796
- icon: FolderOpen_1.default,
797
- },
798
- ...((0, util_1.isSessionWithAddTracks)(session)
799
- ? [
800
- {
801
- label: 'Sequence search',
802
- onClick: () => {
803
- (0, util_1.getSession)(self).queueDialog(handleClose => [
804
- SequenceSearchDialog,
805
- { model: self, handleClose },
806
- ]);
807
- },
808
- },
809
- ]
810
- : []),
811
- {
812
- label: 'Export SVG',
813
- icon: PhotoCamera_1.default,
814
- onClick: () => {
815
- (0, util_1.getSession)(self).queueDialog(handleClose => [
816
- ExportSvgDialog_1.default,
817
- { model: self, handleClose },
818
- ]);
819
- },
820
- },
821
- {
822
- label: 'Open track selector',
823
- onClick: self.activateTrackSelector,
824
- icon: Icons_1.TrackSelector,
825
- },
826
- {
827
- label: 'Horizontally flip',
828
- icon: SyncAlt_1.default,
829
- onClick: self.horizontallyFlip,
830
- },
831
- { type: 'divider' },
832
- {
833
- label: 'Show all regions in assembly',
834
- icon: Visibility_1.default,
835
- onClick: self.showAllRegionsInAssembly,
836
- },
837
- {
838
- label: 'Show center line',
839
- icon: Visibility_1.default,
840
- type: 'checkbox',
841
- checked: self.showCenterLine,
842
- onClick: self.toggleCenterLine,
843
- },
844
- {
845
- label: 'Show header',
846
- icon: Visibility_1.default,
847
- type: 'checkbox',
848
- checked: !self.hideHeader,
849
- onClick: self.toggleHeader,
850
- },
851
- {
852
- label: 'Show header overview',
853
- icon: Visibility_1.default,
854
- type: 'checkbox',
855
- checked: !self.hideHeaderOverview,
856
- onClick: self.toggleHeaderOverview,
857
- disabled: self.hideHeader,
858
- },
859
- {
860
- label: 'Show no tracks active button',
861
- icon: Visibility_1.default,
862
- type: 'checkbox',
863
- checked: !self.hideNoTracksActive,
864
- onClick: self.toggleNoTracksActive,
865
- },
866
- {
867
- label: 'Show guidelines',
868
- icon: Visibility_1.default,
869
- type: 'checkbox',
870
- checked: self.showGridlines,
871
- onClick: self.toggleShowGridlines,
872
- },
873
- ...(canShowCytobands
874
- ? [
875
- {
876
- label: 'Show ideogram',
877
- icon: Visibility_1.default,
878
- type: 'checkbox',
879
- checked: self.showCytobands,
880
- onClick: () => self.setShowCytobands(!showCytobands),
881
- },
882
- ]
883
- : []),
884
- {
885
- label: 'Track labels',
886
- icon: Label_1.default,
887
- subMenu: [
888
- {
889
- label: 'Overlapping',
890
- icon: Visibility_1.default,
891
- type: 'radio',
892
- checked: self.trackLabels === 'overlapping',
893
- onClick: () => self.setTrackLabels('overlapping'),
894
- },
895
- {
896
- label: 'Offset',
897
- icon: Visibility_1.default,
898
- type: 'radio',
899
- checked: self.trackLabels === 'offset',
900
- onClick: () => self.setTrackLabels('offset'),
901
- },
902
- {
903
- label: 'Hidden',
904
- icon: Visibility_1.default,
905
- type: 'radio',
906
- checked: self.trackLabels === 'hidden',
907
- onClick: () => self.setTrackLabels('hidden'),
908
- },
909
- ],
910
- },
911
- ];
912
- // add track's view level menu options
913
- for (const [key, value] of self.trackTypeActions.entries()) {
914
- if (value.length) {
915
- menuItems.push({ type: 'divider' }, { type: 'subHeader', label: key });
916
- value.forEach(action => menuItems.push(action));
917
- }
918
- }
919
- return menuItems;
920
- },
921
- }))
922
- .views(self => {
923
- let currentlyCalculatedStaticBlocks;
924
- let stringifiedCurrentlyCalculatedStaticBlocks = '';
925
- return {
926
- /**
927
- * #getter
928
- * static blocks are an important concept jbrowse uses to avoid
929
- * re-rendering when you scroll to the side. when you horizontally
930
- * scroll to the right, old blocks to the left may be removed, and
931
- * new blocks may be instantiated on the right. tracks may use the
932
- * static blocks to render their data for the region represented by
933
- * the block
934
- */
935
- get staticBlocks() {
936
- const ret = (0, calculateStaticBlocks_1.default)(self);
937
- const sret = JSON.stringify(ret);
938
- if (stringifiedCurrentlyCalculatedStaticBlocks !== sret) {
939
- currentlyCalculatedStaticBlocks = ret;
940
- stringifiedCurrentlyCalculatedStaticBlocks = sret;
941
- }
942
- return currentlyCalculatedStaticBlocks;
943
- },
944
- /**
945
- * #getter
946
- * dynamic blocks represent the exact coordinates of the currently
947
- * visible genome regions on the screen. they are similar to static
948
- * blocks, but statcic blocks can go offscreen while dynamic blocks
949
- * represent exactly what is on screen
950
- */
951
- get dynamicBlocks() {
952
- return (0, calculateDynamicBlocks_1.default)(self);
953
- },
954
- /**
955
- * #getter
956
- * rounded dynamic blocks are dynamic blocks without fractions of bp
957
- */
958
- get roundedDynamicBlocks() {
959
- return this.dynamicBlocks.contentBlocks.map(block => ({
960
- ...block,
961
- start: Math.floor(block.start),
962
- end: Math.ceil(block.end),
963
- }));
964
- },
965
- /**
966
- * #getter
967
- * a single "combo-locstring" representing all the regions visible
968
- * on the screen
969
- */
970
- get visibleLocStrings() {
971
- return calculateVisibleLocStrings(this.dynamicBlocks.contentBlocks);
972
- },
973
- /**
974
- * #getter
975
- * same as visibleLocStrings, but only updated every 300ms
976
- */
977
- get coarseVisibleLocStrings() {
978
- return calculateVisibleLocStrings(self.coarseDynamicBlocks);
979
- },
980
- };
981
- })
982
- .actions(self => ({
983
- /**
984
- * #action
985
- */
986
- setCoarseDynamicBlocks(blocks) {
987
- self.coarseDynamicBlocks = blocks.contentBlocks;
988
- self.coarseTotalBp = blocks.totalBp;
989
- },
990
- afterAttach() {
991
- (0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
992
- if (self.initialized) {
993
- this.setCoarseDynamicBlocks(self.dynamicBlocks);
994
- }
995
- }, { delay: 150 }));
996
- },
997
- }))
998
- .actions(self => ({
999
- /**
1000
- * #action
1001
- * offset is the base-pair-offset in the displayed region, index is the index of the
1002
- * displayed region in the linear genome view
1003
- *
1004
- * @param start - object as `{start, end, offset, index}`
1005
- * @param end - object as `{start, end, offset, index}`
1006
- */
1007
- moveTo(start, end) {
1008
- (0, Base1DUtils_1.moveTo)(self, start, end);
1009
- },
1010
- /**
1011
- * #action
1012
- * navigate to the given locstring
1013
- *
1014
- * @param locString - e.g. "chr1:1-100"
1015
- * @param optAssemblyName - (optional) the assembly name to use when navigating to the locstring
1016
- */
1017
- async navToLocString(locString, optAssemblyName) {
1018
- const { assemblyNames } = self;
1019
- const { assemblyManager } = (0, util_1.getSession)(self);
1020
- const { isValidRefName } = assemblyManager;
1021
- const assemblyName = optAssemblyName || assemblyNames[0];
1022
- let parsedLocStrings;
1023
- const inputs = locString
1024
- .split(/(\s+)/)
1025
- .map(f => f.trim())
1026
- .filter(f => !!f);
1027
- if (assemblyName) {
1028
- await assemblyManager.waitForAssembly(assemblyName);
1029
- }
1030
- // first try interpreting as a whitespace-separated sequence of
1031
- // multiple locstrings
1032
- try {
1033
- parsedLocStrings = inputs.map(l => (0, util_1.parseLocString)(l, ref => isValidRefName(ref, assemblyName)));
1034
- }
1035
- catch (e) {
1036
- // if this fails, try interpreting as a whitespace-separated refname,
1037
- // start, end if start and end are integer inputs
1038
- const [refName, start, end] = inputs;
1039
- if (`${e}`.match(/Unknown reference sequence/) &&
1040
- Number.isInteger(+start) &&
1041
- Number.isInteger(+end)) {
1042
- parsedLocStrings = [
1043
- (0, util_1.parseLocString)(refName + ':' + start + '..' + end, ref => isValidRefName(ref, assemblyName)),
1044
- ];
1045
- }
1046
- else {
1047
- throw e;
1048
- }
1049
- }
1050
- const locations = await Promise.all(parsedLocStrings === null || parsedLocStrings === void 0 ? void 0 : parsedLocStrings.map(async (region) => {
1051
- const asmName = region.assemblyName || assemblyName;
1052
- const asm = await assemblyManager.waitForAssembly(asmName);
1053
- const { refName } = region;
1054
- if (!asm) {
1055
- throw new Error(`assembly ${asmName} not found`);
1056
- }
1057
- const { regions } = asm;
1058
- if (!regions) {
1059
- throw new Error(`regions not loaded yet for ${asmName}`);
1060
- }
1061
- const canonicalRefName = asm.getCanonicalRefName(region.refName);
1062
- if (!canonicalRefName) {
1063
- throw new Error(`Could not find refName ${refName} in ${asm.name}`);
1064
- }
1065
- const parentRegion = regions.find(r => r.refName === canonicalRefName);
1066
- if (!parentRegion) {
1067
- throw new Error(`Could not find refName ${refName} in ${asmName}`);
1068
- }
1069
- return {
1070
- ...region,
1071
- assemblyName: asmName,
1072
- parentRegion,
1073
- };
1074
- }));
1075
- if (locations.length === 1) {
1076
- const loc = locations[0];
1077
- self.setDisplayedRegions([
1078
- { reversed: loc.reversed, ...loc.parentRegion },
1079
- ]);
1080
- const { start, end, parentRegion } = loc;
1081
- this.navTo({
1082
- ...loc,
1083
- start: (0, util_1.clamp)(start !== null && start !== void 0 ? start : 0, 0, parentRegion.end),
1084
- end: (0, util_1.clamp)(end !== null && end !== void 0 ? end : parentRegion.end, 0, parentRegion.end),
1085
- });
1086
- }
1087
- else {
1088
- self.setDisplayedRegions(
1089
- // @ts-ignore
1090
- locations.map(r => (r.start === undefined ? r.parentRegion : r)));
1091
- self.showAllRegions();
1092
- }
1093
- },
1094
- /**
1095
- * #action
1096
- * Navigate to a location based on its refName and optionally start, end,
1097
- * and assemblyName. Can handle if there are multiple displayedRegions
1098
- * from same refName. Only navigates to a location if it is entirely
1099
- * within a displayedRegion. Navigates to the first matching location
1100
- * encountered.
1101
- *
1102
- * Throws an error if navigation was unsuccessful
1103
- *
1104
- * @param query - a proposed location to navigate to
1105
- */
1106
- navTo(query) {
1107
- this.navToMultiple([query]);
1108
- },
1109
- /**
1110
- * #action
1111
- */
1112
- navToMultiple(locations) {
1113
- const firstLocation = locations[0];
1114
- let { refName } = firstLocation;
1115
- const { start, end, assemblyName = self.assemblyNames[0], } = firstLocation;
1116
- if (start !== undefined && end !== undefined && start > end) {
1117
- throw new Error(`start "${start + 1}" is greater than end "${end}"`);
1118
- }
1119
- const session = (0, util_1.getSession)(self);
1120
- const { assemblyManager } = session;
1121
- const assembly = assemblyManager.get(assemblyName);
1122
- if (assembly) {
1123
- const canonicalRefName = assembly.getCanonicalRefName(refName);
1124
- if (canonicalRefName) {
1125
- refName = canonicalRefName;
1126
- }
1127
- }
1128
- let s = start;
1129
- let e = end;
1130
- let refNameMatched = false;
1131
- const predicate = (r) => {
1132
- if (refName === r.refName) {
1133
- refNameMatched = true;
1134
- if (s === undefined) {
1135
- s = r.start;
1136
- }
1137
- if (e === undefined) {
1138
- e = r.end;
1139
- }
1140
- if (s >= r.start && s <= r.end && e <= r.end && e >= r.start) {
1141
- return true;
1142
- }
1143
- s = start;
1144
- e = end;
1145
- }
1146
- return false;
1147
- };
1148
- const lastIndex = (0, util_1.findLastIndex)(self.displayedRegions, predicate);
1149
- let index;
1150
- while (index !== lastIndex) {
1151
- try {
1152
- const previousIndex = index;
1153
- index = self.displayedRegions
1154
- .slice(previousIndex === undefined ? 0 : previousIndex + 1)
1155
- .findIndex(predicate);
1156
- if (previousIndex !== undefined) {
1157
- index += previousIndex + 1;
1158
- }
1159
- if (!refNameMatched) {
1160
- throw new Error(`could not find a region with refName "${refName}"`);
1161
- }
1162
- if (s === undefined) {
1163
- throw new Error(`could not find a region with refName "${refName}" that contained an end position ${e}`);
1164
- }
1165
- if (e === undefined) {
1166
- throw new Error(`could not find a region with refName "${refName}" that contained a start position ${s + 1}`);
1167
- }
1168
- if (index === -1) {
1169
- throw new Error(`could not find a region that completely contained "${(0, util_1.assembleLocString)(firstLocation)}"`);
1170
- }
1171
- if (locations.length === 1) {
1172
- const f = self.displayedRegions[index];
1173
- this.moveTo({ index, offset: f.reversed ? f.end - e : s - f.start }, { index, offset: f.reversed ? f.end - s : e - f.start });
1174
- return;
1175
- }
1176
- let locationIndex = 0;
1177
- let locationStart = 0;
1178
- let locationEnd = 0;
1179
- for (locationIndex; locationIndex < locations.length; locationIndex++) {
1180
- const location = locations[locationIndex];
1181
- const region = self.displayedRegions[index + locationIndex];
1182
- locationStart = location.start || region.start;
1183
- locationEnd = location.end || region.end;
1184
- if (location.refName !== region.refName) {
1185
- throw new Error(`Entered location ${(0, util_1.assembleLocString)(location)} does not match with displayed regions`);
1186
- }
1187
- }
1188
- locationIndex -= 1;
1189
- const startDisplayedRegion = self.displayedRegions[index];
1190
- const endDisplayedRegion = self.displayedRegions[index + locationIndex];
1191
- this.moveTo({
1192
- index,
1193
- offset: startDisplayedRegion.reversed
1194
- ? startDisplayedRegion.end - e
1195
- : s - startDisplayedRegion.start,
1196
- }, {
1197
- index: index + locationIndex,
1198
- offset: endDisplayedRegion.reversed
1199
- ? endDisplayedRegion.end - locationStart
1200
- : locationEnd - endDisplayedRegion.start,
1201
- });
1202
- return;
1203
- }
1204
- catch (error) {
1205
- if (index === lastIndex) {
1206
- throw error;
1207
- }
1208
- }
1209
- }
1210
- },
1211
- }))
1212
- .views(self => ({
1213
- /**
1214
- * #method
1215
- */
1216
- rubberBandMenuItems() {
1217
- return [
1218
- {
1219
- label: 'Zoom to region',
1220
- icon: ZoomIn_1.default,
1221
- onClick: () => {
1222
- const { leftOffset, rightOffset } = self;
1223
- self.moveTo(leftOffset, rightOffset);
1224
- },
1225
- },
1226
- {
1227
- label: 'Get sequence',
1228
- icon: MenuOpen_1.default,
1229
- onClick: () => self.setGetSequenceDialogOpen(true),
1230
- },
1231
- ];
1232
- },
1233
- /**
1234
- * #method
1235
- */
1236
- bpToPx({ refName, coord, regionNumber, }) {
1237
- return (0, Base1DUtils_1.bpToPx)({ refName, coord, regionNumber, self });
1238
- },
1239
- /**
1240
- * #method
1241
- * scrolls the view to center on the given bp. if that is not in any
1242
- * of the displayed regions, does nothing
1243
- * @param coord - basepair at which you want to center the view
1244
- * @param refName - refName of the displayedRegion you are centering at
1245
- * @param regionNumber - index of the displayedRegion
1246
- */
1247
- centerAt(coord, refName, regionNumber) {
1248
- const centerPx = this.bpToPx({
1249
- refName,
1250
- coord,
1251
- regionNumber,
1252
- });
1253
- if (centerPx) {
1254
- self.scrollTo(Math.round(centerPx.offsetPx - self.width / 2));
1255
- }
1256
- },
1257
- /**
1258
- * #method
1259
- */
1260
- pxToBp(px) {
1261
- return (0, Base1DUtils_1.pxToBp)(self, px);
1262
- },
1263
- /**
1264
- * #getter
1265
- */
1266
- get centerLineInfo() {
1267
- return self.displayedRegions.length
1268
- ? this.pxToBp(self.width / 2)
1269
- : undefined;
1270
- },
30
+ const pluggableElementTypes_1 = require("@jbrowse/core/pluggableElementTypes");
31
+ const model_1 = require("./model");
32
+ exports.default = (pluginManager) => {
33
+ pluginManager.addViewType(() => new pluggableElementTypes_1.ViewType({
34
+ name: 'LinearGenomeView',
35
+ stateModel: (0, model_1.stateModelFactory)(pluginManager),
36
+ ReactComponent: (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./components/LinearGenomeView')))),
1271
37
  }));
1272
- }
1273
- exports.stateModelFactory = stateModelFactory;
1274
- var LinearGenomeView_2 = require("./components/LinearGenomeView");
1275
- Object.defineProperty(exports, "ReactComponent", { enumerable: true, get: function () { return __importDefault(LinearGenomeView_2).default; } });
38
+ };
39
+ __exportStar(require("./model"), exports);
1276
40
  //# sourceMappingURL=index.js.map