@jbrowse/core 1.4.1 → 1.5.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.
- package/BaseFeatureWidget/BaseFeatureDetail.d.ts +4 -4
- package/BaseFeatureWidget/BaseFeatureDetail.js +27 -8
- package/BaseFeatureWidget/SequenceFeatureDetails.js +10 -10
- package/BaseFeatureWidget/index.js +1 -1
- package/BaseFeatureWidget/types.d.ts +1 -1
- package/BaseFeatureWidget/util.js +3 -3
- package/CorePlugin.d.ts +0 -1
- package/CorePlugin.js +13 -1
- package/PluginLoader.d.ts +26 -4
- package/PluginLoader.js +337 -51
- package/PluginManager.d.ts +18 -11
- package/PluginManager.js +53 -31
- package/ReExports/list.js +1 -1
- package/ReExports/material-ui-colors.js +38 -38
- package/ReExports/modules.d.ts +19 -20
- package/ReExports/modules.js +10 -3
- package/TextSearch/BaseResults.d.ts +5 -14
- package/TextSearch/BaseResults.js +16 -58
- package/TextSearch/BaseResults.test.js +1 -11
- package/TextSearch/TextSearchManager.d.ts +3 -3
- package/TextSearch/TextSearchManager.js +1 -1
- package/assemblyManager/assembly.d.ts +21 -8
- package/assemblyManager/assembly.js +163 -120
- package/assemblyManager/assemblyConfigSchema.d.ts +3 -0
- package/assemblyManager/{assemblyConfigSchemas.js → assemblyConfigSchema.js} +35 -27
- package/assemblyManager/assemblyManager.d.ts +169 -60
- package/assemblyManager/index.d.ts +1 -1
- package/assemblyManager/index.js +5 -5
- package/configuration/configurationSchema.d.ts +3 -2
- package/configuration/configurationSchema.js +7 -10
- package/configuration/configurationSchema.test.js +4 -2
- package/configuration/configurationSlot.js +5 -4
- package/configuration/index.js +4 -4
- package/configuration/util.js +5 -5
- package/data_adapters/BaseAdapter.d.ts +5 -3
- package/data_adapters/BaseAdapter.js +7 -4
- package/data_adapters/BaseAdapter.test.js +4 -2
- package/data_adapters/CytobandAdapter.d.ts +8 -0
- package/data_adapters/CytobandAdapter.js +128 -0
- package/data_adapters/dataAdapterCache.js +3 -3
- package/package.json +7 -6
- package/pluggableElementTypes/AdapterType.d.ts +9 -1
- package/pluggableElementTypes/AdapterType.js +20 -0
- package/pluggableElementTypes/InternetAccountType.d.ts +12 -0
- package/pluggableElementTypes/InternetAccountType.js +64 -0
- package/pluggableElementTypes/PluggableElementBase.d.ts +1 -2
- package/pluggableElementTypes/PluggableElementBase.js +2 -3
- package/pluggableElementTypes/RpcMethodType.d.ts +3 -0
- package/pluggableElementTypes/RpcMethodType.js +269 -26
- package/pluggableElementTypes/RpcMethodType.test.d.ts +4 -0
- package/pluggableElementTypes/RpcMethodType.test.js +118 -0
- package/pluggableElementTypes/ViewType.d.ts +1 -1
- package/pluggableElementTypes/WidgetType.d.ts +1 -0
- package/pluggableElementTypes/index.d.ts +7 -3
- package/pluggableElementTypes/index.js +127 -1
- package/pluggableElementTypes/models/BaseDisplayModel.d.ts +6 -6
- package/pluggableElementTypes/models/BaseDisplayModel.js +1 -3
- package/pluggableElementTypes/models/BaseViewModel.js +13 -15
- package/pluggableElementTypes/models/InternetAccountModel.d.ts +24 -0
- package/pluggableElementTypes/models/InternetAccountModel.js +85 -0
- package/pluggableElementTypes/models/baseInternetAccountConfig.d.ts +4 -0
- package/pluggableElementTypes/models/baseInternetAccountConfig.js +25 -0
- package/pluggableElementTypes/models/index.d.ts +3 -0
- package/pluggableElementTypes/models/index.js +24 -8
- package/pluggableElementTypes/renderers/BoxRendererType.js +1 -1
- package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.d.ts +1 -1
- package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.js +15 -6
- package/pluggableElementTypes/renderers/FeatureRendererType.d.ts +3 -3
- package/pluggableElementTypes/renderers/FeatureRendererType.js +17 -8
- package/pluggableElementTypes/renderers/RendererType.d.ts +1 -0
- package/pluggableElementTypes/renderers/RendererType.js +4 -1
- package/pluggableElementTypes/renderers/ServerSideRenderedContent.js +1 -1
- package/pluggableElementTypes/renderers/index.d.ts +9 -0
- package/pluggableElementTypes/renderers/index.js +63 -0
- package/rpc/BaseRpcDriver.js +5 -9
- package/rpc/BaseRpcDriver.test.js +6 -6
- package/rpc/RpcManager.d.ts +1 -1
- package/rpc/RpcManager.js +44 -16
- package/rpc/WebWorkerRpcDriver.js +3 -3
- package/rpc/coreRpcMethods.d.ts +2 -1
- package/rpc/coreRpcMethods.js +109 -75
- package/rpc/remoteAbortSignals.js +2 -2
- package/ui/App.d.ts +17 -4
- package/ui/App.js +55 -41
- package/ui/Drawer.d.ts +6 -14
- package/ui/Drawer.js +11 -12
- package/ui/DrawerWidget.d.ts +5 -3
- package/ui/DrawerWidget.js +100 -61
- package/ui/ErrorMessage.d.ts +5 -0
- package/ui/ErrorMessage.js +54 -0
- package/ui/FileSelector/FileSelector.d.ts +11 -0
- package/ui/FileSelector/FileSelector.js +198 -0
- package/ui/FileSelector/LocalFileChooser.d.ts +7 -0
- package/ui/FileSelector/LocalFileChooser.js +79 -0
- package/ui/FileSelector/UrlChooser.d.ts +9 -0
- package/ui/FileSelector/UrlChooser.js +41 -0
- package/ui/FileSelector/index.d.ts +2 -0
- package/ui/FileSelector/index.js +13 -0
- package/ui/Icons.d.ts +4 -0
- package/ui/Icons.js +34 -0
- package/ui/Logo.js +1 -1
- package/ui/PrerenderedCanvas.d.ts +1 -0
- package/ui/PrerenderedCanvas.js +4 -1
- package/ui/ResizeHandle.d.ts +2 -3
- package/ui/ResizeHandle.js +6 -7
- package/ui/SanitizedHTML.js +1 -1
- package/ui/Snackbar.js +4 -6
- package/ui/SnackbarModel.d.ts +16 -0
- package/ui/SnackbarModel.js +56 -0
- package/ui/Tooltip.d.ts +1 -1
- package/ui/index.js +24 -24
- package/ui/theme.js +5 -5
- package/util/QuickLRU.d.ts +1 -1
- package/util/QuickLRU.js +3 -3
- package/util/aborting.d.ts +1 -1
- package/util/aborting.js +10 -11
- package/util/analytics.d.ts +2 -2
- package/util/analytics.js +20 -7
- package/util/blockTypes.d.ts +11 -6
- package/util/blockTypes.js +7 -1
- package/util/color/cssColorsLevel4.js +1 -1
- package/util/color/index.js +5 -5
- package/util/compositeMap.js +3 -3
- package/util/index.d.ts +6 -16
- package/util/index.js +76 -100
- package/util/io/RemoteFileWithRangeCache.d.ts +17 -0
- package/util/io/RemoteFileWithRangeCache.js +266 -0
- package/util/io/index.d.ts +4 -2
- package/util/io/index.js +134 -25
- package/util/jexl.js +4 -1
- package/util/layouts/BaseLayout.d.ts +3 -0
- package/util/layouts/GranularRectLayout.d.ts +19 -10
- package/util/layouts/GranularRectLayout.js +459 -100
- package/util/layouts/GranularRectLayout.test.js +57 -10
- package/util/layouts/PrecomputedLayout.js +2 -1
- package/util/layouts/index.d.ts +7 -0
- package/util/layouts/index.js +68 -0
- package/util/mst-reflection.js +3 -3
- package/util/offscreenCanvasPonyfill.js +1 -1
- package/util/range.js +1 -1
- package/util/simpleFeature.js +1 -1
- package/util/stats.js +2 -2
- package/util/tracks.d.ts +31 -362
- package/util/tracks.js +74 -190
- package/util/types/index.d.ts +54 -10
- package/util/types/index.js +110 -8
- package/util/types/mst.d.ts +46 -2
- package/util/types/mst.js +56 -8
- package/util/types/util.d.ts +1 -1
- package/util/when.js +1 -1
- package/assemblyManager/assemblyConfigSchemas.d.ts +0 -7
- package/ui/FileSelector.d.ts +0 -9
- package/ui/FileSelector.js +0 -150
- package/util/io/LocalFile.d.ts +0 -18
- package/util/io/LocalFile.js +0 -220
- package/util/io/rangeFetcher.d.ts +0 -3
- package/util/io/rangeFetcher.js +0 -236
- package/value.d.ts +0 -1
- package/value.js +0 -10
|
@@ -7,8 +7,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
});
|
|
8
8
|
exports.default = void 0;
|
|
9
9
|
|
|
10
|
-
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
11
|
-
|
|
12
10
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
13
11
|
|
|
14
12
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
@@ -17,8 +15,6 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
|
|
|
17
15
|
|
|
18
16
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
19
17
|
|
|
20
|
-
var _rbush = _interopRequireDefault(require("rbush"));
|
|
21
|
-
|
|
22
18
|
var _index = require("../index");
|
|
23
19
|
|
|
24
20
|
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
@@ -27,37 +23,315 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
|
|
|
27
23
|
|
|
28
24
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
29
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Rectangle-layout manager that lays out rectangles using bitmaps at
|
|
28
|
+
* resolution that, for efficiency, may be somewhat lower than that of
|
|
29
|
+
* the coordinate system for the rectangles being laid out. `pitchX`
|
|
30
|
+
* and `pitchY` are the ratios of input scale resolution to internal
|
|
31
|
+
* bitmap resolution.
|
|
32
|
+
*/
|
|
33
|
+
// minimum excess size of the array at which we garbage collect
|
|
34
|
+
var minSizeToBotherWith = 10000;
|
|
35
|
+
var maxFeaturePitchWidth = 20000;
|
|
36
|
+
|
|
30
37
|
function segmentsIntersect(x1, x2, y1, y2) {
|
|
31
38
|
return x2 >= y1 && y2 >= x1;
|
|
32
39
|
}
|
|
33
40
|
|
|
41
|
+
// a single row in the layout
|
|
42
|
+
var LayoutRow = /*#__PURE__*/function () {
|
|
43
|
+
function LayoutRow() {
|
|
44
|
+
(0, _classCallCheck2.default)(this, LayoutRow);
|
|
45
|
+
(0, _defineProperty2.default)(this, "padding", void 0);
|
|
46
|
+
(0, _defineProperty2.default)(this, "allFilled", void 0);
|
|
47
|
+
(0, _defineProperty2.default)(this, "widthLimit", void 0);
|
|
48
|
+
(0, _defineProperty2.default)(this, "rowState", void 0);
|
|
49
|
+
this.padding = 1;
|
|
50
|
+
this.widthLimit = 1000000; // this.rowState.offset is the offset of the bits array relative to the genomic coordinates
|
|
51
|
+
// (modified by pitchX, but we don't know that in this class)
|
|
52
|
+
// this.rowState.bits is the array of items in the layout row, indexed by (x - this.offset)
|
|
53
|
+
// this.rowState.min is the leftmost edge of all the rectangles we have in the layout
|
|
54
|
+
// this.rowState.max is the rightmost edge of all the rectangles we have in the layout
|
|
55
|
+
} // log(msg: string): void {
|
|
56
|
+
// // if (this.rowNumber === 0)
|
|
57
|
+
// // eslint-disable-next-line no-console
|
|
58
|
+
// console.log(`r${this.rowNumber}: ${msg}`)
|
|
59
|
+
// }
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
(0, _createClass2.default)(LayoutRow, [{
|
|
63
|
+
key: "setAllFilled",
|
|
64
|
+
value: function setAllFilled(data) {
|
|
65
|
+
this.allFilled = data;
|
|
66
|
+
}
|
|
67
|
+
}, {
|
|
68
|
+
key: "getItemAt",
|
|
69
|
+
value: function getItemAt(x) {
|
|
70
|
+
if (this.allFilled) {
|
|
71
|
+
return this.allFilled;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!this.rowState) {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (this.rowState.min === undefined) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (x < this.rowState.min) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (x >= this.rowState.max) {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
var offset = x - this.rowState.offset; // if (offset < 0)
|
|
91
|
+
// debugger
|
|
92
|
+
// if (offset >= this.rowState.bits.length)
|
|
93
|
+
// debugger
|
|
94
|
+
|
|
95
|
+
return this.rowState.bits[offset];
|
|
96
|
+
}
|
|
97
|
+
}, {
|
|
98
|
+
key: "isRangeClear",
|
|
99
|
+
value: function isRangeClear(left, right) {
|
|
100
|
+
if (this.allFilled) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!this.rowState) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
var _this$rowState = this.rowState,
|
|
109
|
+
min = _this$rowState.min,
|
|
110
|
+
max = _this$rowState.max;
|
|
111
|
+
|
|
112
|
+
if (right <= min || left >= max) {
|
|
113
|
+
return true;
|
|
114
|
+
} // TODO: check right and middle before looping
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
var maxX = Math.min(max, right);
|
|
118
|
+
var x = Math.max(min, left);
|
|
119
|
+
|
|
120
|
+
for (; x < right && x < maxX; x += 1) {
|
|
121
|
+
if (this.getItemAt(x)) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
}, {
|
|
129
|
+
key: "initialize",
|
|
130
|
+
value: function initialize(left, right) {
|
|
131
|
+
// NOTE: this.rowState.min, this.rowState.max, and this.rowState.offset are interbase coordinates
|
|
132
|
+
var rectWidth = right - left;
|
|
133
|
+
return {
|
|
134
|
+
offset: left - rectWidth,
|
|
135
|
+
min: left,
|
|
136
|
+
max: right,
|
|
137
|
+
bits: new Array(3 * rectWidth)
|
|
138
|
+
}; // this.log(`initialize ${this.rowState.min} - ${this.rowState.max} (${this.rowState.bits.length})`)
|
|
139
|
+
}
|
|
140
|
+
}, {
|
|
141
|
+
key: "addRect",
|
|
142
|
+
value: function addRect(rect, data) {
|
|
143
|
+
var left = rect.l;
|
|
144
|
+
var right = rect.r + this.padding; // only padding on the right
|
|
145
|
+
|
|
146
|
+
if (!this.rowState) {
|
|
147
|
+
this.rowState = this.initialize(left, right);
|
|
148
|
+
} // or check if we need to expand to the left and/or to the right
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
var oLeft = left - this.rowState.offset;
|
|
152
|
+
var oRight = right - this.rowState.offset;
|
|
153
|
+
var currLength = this.rowState.bits.length; // console.log(oRight, this.rowState.bits.length)
|
|
154
|
+
// expand rightward if necessary
|
|
155
|
+
|
|
156
|
+
if (oRight >= this.rowState.bits.length) {
|
|
157
|
+
var additionalLength = oRight + 1;
|
|
158
|
+
|
|
159
|
+
if (this.rowState.bits.length + additionalLength > this.widthLimit) {
|
|
160
|
+
console.warn('Layout width limit exceeded, discarding old layout. Please be more careful about discarding unused blocks.');
|
|
161
|
+
this.rowState = this.initialize(left, right);
|
|
162
|
+
} else if (additionalLength > 0) {
|
|
163
|
+
this.rowState.bits = this.rowState.bits.concat(new Array(additionalLength));
|
|
164
|
+
}
|
|
165
|
+
} // expand leftward if necessary
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
if (left < this.rowState.offset) {
|
|
169
|
+
// use math.min to avoid negative lengths
|
|
170
|
+
var _additionalLength = Math.min(currLength - oLeft, this.rowState.offset);
|
|
171
|
+
|
|
172
|
+
if (this.rowState.bits.length + _additionalLength > this.widthLimit) {
|
|
173
|
+
console.warn('Layout width limit exceeded, discarding old layout. Please be more careful about discarding unused blocks.');
|
|
174
|
+
this.rowState = this.initialize(left, right);
|
|
175
|
+
} else {
|
|
176
|
+
this.rowState.bits = new Array(_additionalLength).concat(this.rowState.bits);
|
|
177
|
+
this.rowState.offset -= _additionalLength;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
oRight = right - this.rowState.offset;
|
|
182
|
+
oLeft = left - this.rowState.offset; // set the bits in the bitmask
|
|
183
|
+
// if (oLeft < 0) debugger
|
|
184
|
+
// if (oRight < 0) debugger
|
|
185
|
+
// if (oRight <= oLeft) debugger
|
|
186
|
+
// if (oRight > this.rowState.bits.length) debugger
|
|
187
|
+
|
|
188
|
+
if (oRight - oLeft > maxFeaturePitchWidth) {
|
|
189
|
+
console.warn("Layout X pitch set too low, feature spans ".concat(oRight - oLeft, " bits in a single row."), rect, data);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
for (var x = oLeft; x < oRight; x += 1) {
|
|
193
|
+
// if (this.rowState.bits[x] && this.rowState.bits[x].get('name') !== data.get('name')) debugger
|
|
194
|
+
this.rowState.bits[x] = data;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (left < this.rowState.min) {
|
|
198
|
+
this.rowState.min = left;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (right > this.rowState.max) {
|
|
202
|
+
this.rowState.max = right;
|
|
203
|
+
} // // this.log(`added ${leftX} - ${rightX}`)
|
|
204
|
+
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Given a range of interbase coordinates, deletes all data dealing with that range
|
|
208
|
+
*/
|
|
209
|
+
|
|
210
|
+
}, {
|
|
211
|
+
key: "discardRange",
|
|
212
|
+
value: function discardRange(left, right) {
|
|
213
|
+
if (this.allFilled) {
|
|
214
|
+
return;
|
|
215
|
+
} // allFilled is irrevocable currently
|
|
216
|
+
// if we have no data, do nothing
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
if (!this.rowState) {
|
|
220
|
+
return;
|
|
221
|
+
} // if doesn't overlap at all, do nothing
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
if (right <= this.rowState.min || left >= this.rowState.max) {
|
|
225
|
+
return;
|
|
226
|
+
} // if completely encloses range, discard everything
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
if (left <= this.rowState.min && right >= this.rowState.max) {
|
|
230
|
+
this.rowState = undefined;
|
|
231
|
+
return;
|
|
232
|
+
} // if overlaps left edge, adjust the min
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
if (right > this.rowState.min && left <= this.rowState.min) {
|
|
236
|
+
this.rowState.min = right;
|
|
237
|
+
} // if overlaps right edge, adjust the max
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
if (left < this.rowState.max && right >= this.rowState.max) {
|
|
241
|
+
this.rowState.max = left;
|
|
242
|
+
} // now trim the left, right, or both sides of the array
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
if (this.rowState.offset < this.rowState.min - minSizeToBotherWith && this.rowState.bits.length > this.rowState.max + minSizeToBotherWith - this.rowState.offset) {
|
|
246
|
+
// trim both sides
|
|
247
|
+
var leftTrimAmount = this.rowState.min - this.rowState.offset;
|
|
248
|
+
var rightTrimAmount = this.rowState.bits.length - 1 - (this.rowState.max - this.rowState.offset); // if (rightTrimAmount <= 0) debugger
|
|
249
|
+
// if (leftTrimAmount <= 0) debugger
|
|
250
|
+
// this.log(`trim both sides, ${leftTrimAmount} from left, ${rightTrimAmount} from right`)
|
|
251
|
+
|
|
252
|
+
this.rowState.bits = this.rowState.bits.slice(leftTrimAmount, this.rowState.bits.length - rightTrimAmount);
|
|
253
|
+
this.rowState.offset += leftTrimAmount; // if (this.rowState.offset > this.rowState.min) debugger
|
|
254
|
+
// if (this.rowState.bits.length <= this.rowState.max - this.rowState.offset) debugger
|
|
255
|
+
} else if (this.rowState.offset < this.rowState.min - minSizeToBotherWith) {
|
|
256
|
+
// trim left side
|
|
257
|
+
var desiredOffset = this.rowState.min - Math.floor(minSizeToBotherWith / 2);
|
|
258
|
+
var trimAmount = desiredOffset - this.rowState.offset; // this.log(`trim left side by ${trimAmount}`)
|
|
259
|
+
|
|
260
|
+
this.rowState.bits.splice(0, trimAmount);
|
|
261
|
+
this.rowState.offset += trimAmount; // if (this.rowState.offset > this.rowState.min) debugger
|
|
262
|
+
// if (this.rowState.bits.length <= this.rowState.max - this.rowState.offset) debugger
|
|
263
|
+
} else if (this.rowState.bits.length > this.rowState.max - this.rowState.offset + minSizeToBotherWith) {
|
|
264
|
+
// trim right side
|
|
265
|
+
var desiredLength = this.rowState.max - this.rowState.offset + 1 + Math.floor(minSizeToBotherWith / 2); // this.log(`trim right side by ${this.rowState.bits.length-desiredLength}`)
|
|
266
|
+
// if (desiredLength > this.rowState.bits.length) debugger
|
|
267
|
+
|
|
268
|
+
this.rowState.bits.length = desiredLength; // if (this.rowState.offset > this.rowState.min) debugger
|
|
269
|
+
// if (this.rowState.bits.length <= this.rowState.max - this.rowState.offset) debugger
|
|
270
|
+
} // if (this.rowState.offset > this.rowState.min) debugger
|
|
271
|
+
// if (this.rowState.bits.length <= this.rowState.max - this.rowState.offset) debugger
|
|
272
|
+
// if range now enclosed in the new bounds, loop through and clear the bits
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
var oLeft = Math.max(this.rowState.min, left) - this.rowState.offset; // if (oLeft < 0) debugger
|
|
276
|
+
// if (oLeft >= this.rowState.bits.length) debugger
|
|
277
|
+
// if (oRight < 0) debugger
|
|
278
|
+
// if (oRight >= this.rowState.bits.length) debugger
|
|
279
|
+
|
|
280
|
+
var oRight = Math.min(right, this.rowState.max) - this.rowState.offset;
|
|
281
|
+
|
|
282
|
+
for (var x = oLeft; x >= 0 && x < oRight; x += 1) {
|
|
283
|
+
this.rowState.bits[x] = undefined;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}]);
|
|
287
|
+
return LayoutRow;
|
|
288
|
+
}();
|
|
289
|
+
|
|
34
290
|
var GranularRectLayout = /*#__PURE__*/function () {
|
|
291
|
+
/*
|
|
292
|
+
*
|
|
293
|
+
* pitchX - layout grid pitch in the X direction
|
|
294
|
+
* pitchY - layout grid pitch in the Y direction
|
|
295
|
+
* maxHeight - maximum layout height, default Infinity (no max)
|
|
296
|
+
*/
|
|
35
297
|
function GranularRectLayout() {
|
|
36
298
|
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
|
299
|
+
_ref$pitchX = _ref.pitchX,
|
|
300
|
+
pitchX = _ref$pitchX === void 0 ? 10 : _ref$pitchX,
|
|
301
|
+
_ref$pitchY = _ref.pitchY,
|
|
302
|
+
pitchY = _ref$pitchY === void 0 ? 10 : _ref$pitchY,
|
|
37
303
|
_ref$maxHeight = _ref.maxHeight,
|
|
38
304
|
maxHeight = _ref$maxHeight === void 0 ? 10000 : _ref$maxHeight,
|
|
39
|
-
_ref$
|
|
40
|
-
|
|
41
|
-
_ref$
|
|
42
|
-
|
|
305
|
+
_ref$hardRowLimit = _ref.hardRowLimit,
|
|
306
|
+
hardRowLimit = _ref$hardRowLimit === void 0 ? 10000 : _ref$hardRowLimit,
|
|
307
|
+
_ref$displayMode = _ref.displayMode,
|
|
308
|
+
displayMode = _ref$displayMode === void 0 ? 'normal' : _ref$displayMode;
|
|
43
309
|
|
|
44
310
|
(0, _classCallCheck2.default)(this, GranularRectLayout);
|
|
311
|
+
(0, _defineProperty2.default)(this, "pitchX", void 0);
|
|
312
|
+
(0, _defineProperty2.default)(this, "pitchY", void 0);
|
|
313
|
+
(0, _defineProperty2.default)(this, "hardRowLimit", void 0);
|
|
314
|
+
(0, _defineProperty2.default)(this, "bitmap", void 0);
|
|
45
315
|
(0, _defineProperty2.default)(this, "rectangles", void 0);
|
|
46
316
|
(0, _defineProperty2.default)(this, "maxHeightReached", void 0);
|
|
47
317
|
(0, _defineProperty2.default)(this, "maxHeight", void 0);
|
|
48
|
-
(0, _defineProperty2.default)(this, "
|
|
49
|
-
(0, _defineProperty2.default)(this, "spacing", void 0);
|
|
318
|
+
(0, _defineProperty2.default)(this, "displayMode", void 0);
|
|
50
319
|
(0, _defineProperty2.default)(this, "pTotalHeight", void 0);
|
|
51
|
-
(0, _defineProperty2.default)(this, "pitchX", void 0);
|
|
52
|
-
// we keep holding onto the concept of pitchX so that when we zoom out
|
|
53
|
-
// layout is redone
|
|
54
320
|
this.pitchX = pitchX;
|
|
321
|
+
this.pitchY = pitchY;
|
|
322
|
+
this.hardRowLimit = hardRowLimit;
|
|
55
323
|
this.maxHeightReached = false;
|
|
56
|
-
this.
|
|
57
|
-
|
|
324
|
+
this.displayMode = displayMode; // reduce the pitchY to try and pack the features tighter
|
|
325
|
+
|
|
326
|
+
if (this.displayMode === 'compact') {
|
|
327
|
+
this.pitchY = Math.round(this.pitchY / 4) || 1;
|
|
328
|
+
this.pitchX = Math.round(this.pitchX / 4) || 1;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
this.bitmap = [];
|
|
58
332
|
this.rectangles = new Map();
|
|
59
|
-
this.maxHeight = Math.ceil(maxHeight);
|
|
60
|
-
this.pTotalHeight = 0;
|
|
333
|
+
this.maxHeight = Math.ceil(maxHeight / this.pitchY);
|
|
334
|
+
this.pTotalHeight = 0; // total height, in units of bitmap squares (px/pitchY)
|
|
61
335
|
}
|
|
62
336
|
/**
|
|
63
337
|
* @returns top position for the rect, or Null if laying
|
|
@@ -68,59 +342,117 @@ var GranularRectLayout = /*#__PURE__*/function () {
|
|
|
68
342
|
(0, _createClass2.default)(GranularRectLayout, [{
|
|
69
343
|
key: "addRect",
|
|
70
344
|
value: function addRect(id, left, right, height, data) {
|
|
71
|
-
//
|
|
72
|
-
var
|
|
345
|
+
// if we have already laid it out, return its layout
|
|
346
|
+
var storedRec = this.rectangles.get(id);
|
|
347
|
+
|
|
348
|
+
if (storedRec) {
|
|
349
|
+
if (storedRec.top === null) {
|
|
350
|
+
return null;
|
|
351
|
+
} // add it to the bitmap again, since that bitmap range may have been
|
|
352
|
+
// discarded
|
|
353
|
+
|
|
73
354
|
|
|
74
|
-
|
|
75
|
-
return
|
|
355
|
+
this.addRectToBitmap(storedRec);
|
|
356
|
+
return storedRec.top * this.pitchY;
|
|
76
357
|
}
|
|
77
358
|
|
|
78
|
-
var
|
|
79
|
-
var
|
|
80
|
-
var
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
359
|
+
var pLeft = Math.floor(left / this.pitchX);
|
|
360
|
+
var pRight = Math.floor(right / this.pitchX);
|
|
361
|
+
var pHeight = Math.ceil(height / this.pitchY);
|
|
362
|
+
var rectangle = {
|
|
363
|
+
id: id,
|
|
364
|
+
l: pLeft,
|
|
365
|
+
r: pRight,
|
|
366
|
+
top: null,
|
|
367
|
+
h: pHeight,
|
|
368
|
+
originalHeight: height,
|
|
369
|
+
data: data
|
|
370
|
+
};
|
|
371
|
+
var maxTop = this.maxHeight - pHeight;
|
|
372
|
+
var top = 0;
|
|
373
|
+
|
|
374
|
+
if (this.displayMode !== 'collapse') {
|
|
375
|
+
for (; top <= maxTop; top += 1) {
|
|
376
|
+
if (!this.collides(rectangle, top)) {
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
if (top > maxTop) {
|
|
382
|
+
rectangle.top = null;
|
|
383
|
+
this.rectangles.set(id, rectangle);
|
|
384
|
+
this.maxHeightReached = true;
|
|
385
|
+
return null;
|
|
96
386
|
}
|
|
97
387
|
}
|
|
98
388
|
|
|
99
|
-
|
|
100
|
-
|
|
389
|
+
rectangle.top = top;
|
|
390
|
+
this.addRectToBitmap(rectangle);
|
|
391
|
+
this.rectangles.set(id, rectangle);
|
|
392
|
+
this.pTotalHeight = Math.max(this.pTotalHeight || 0, top + pHeight);
|
|
393
|
+
return top * this.pitchY;
|
|
394
|
+
}
|
|
395
|
+
}, {
|
|
396
|
+
key: "collides",
|
|
397
|
+
value: function collides(rect, top) {
|
|
398
|
+
var bitmap = this.bitmap;
|
|
399
|
+
var maxY = top + rect.h;
|
|
400
|
+
|
|
401
|
+
for (var y = top; y < maxY; y += 1) {
|
|
402
|
+
var row = bitmap[y];
|
|
403
|
+
|
|
404
|
+
if (row && !row.isRangeClear(rect.l, rect.r)) {
|
|
405
|
+
return true;
|
|
406
|
+
}
|
|
101
407
|
}
|
|
102
408
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* make a subarray if it does not exist
|
|
413
|
+
*/
|
|
414
|
+
|
|
415
|
+
}, {
|
|
416
|
+
key: "autovivifyRow",
|
|
417
|
+
value: function autovivifyRow(bitmap, y) {
|
|
418
|
+
var row = bitmap[y];
|
|
419
|
+
|
|
420
|
+
if (!row) {
|
|
421
|
+
if (y > this.hardRowLimit) {
|
|
422
|
+
throw new Error("layout hard limit (".concat(this.hardRowLimit * this.pitchY, "px) exceeded, aborting layout"));
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
row = new LayoutRow();
|
|
426
|
+
bitmap[y] = row;
|
|
115
427
|
}
|
|
116
428
|
|
|
117
|
-
|
|
118
|
-
return maxHeightReached ? null : currHeight;
|
|
429
|
+
return row;
|
|
119
430
|
}
|
|
120
431
|
}, {
|
|
121
|
-
key: "
|
|
122
|
-
value: function
|
|
123
|
-
|
|
432
|
+
key: "addRectToBitmap",
|
|
433
|
+
value: function addRectToBitmap(rect) {
|
|
434
|
+
if (rect.top === null) {
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
var data = rect.data || rect.id;
|
|
439
|
+
var bitmap = this.bitmap;
|
|
440
|
+
var yEnd = rect.top + rect.h;
|
|
441
|
+
|
|
442
|
+
if (rect.r - rect.l > maxFeaturePitchWidth) {
|
|
443
|
+
// the rect is very big in relation to the view size, just pretend, for
|
|
444
|
+
// the purposes of layout, that it extends infinitely. this will cause
|
|
445
|
+
// weird layout if a user scrolls manually for a very, very long time
|
|
446
|
+
// along the genome at the same zoom level. but most users will not do
|
|
447
|
+
// that. hopefully.
|
|
448
|
+
for (var y = rect.top; y < yEnd; y += 1) {
|
|
449
|
+
this.autovivifyRow(bitmap, y).setAllFilled(data);
|
|
450
|
+
}
|
|
451
|
+
} else {
|
|
452
|
+
for (var _y = rect.top; _y < yEnd; _y += 1) {
|
|
453
|
+
this.autovivifyRow(bitmap, _y).addRect(rect, data);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
124
456
|
}
|
|
125
457
|
/**
|
|
126
458
|
* Given a range of X coordinates, deletes all data dealing with
|
|
@@ -129,7 +461,20 @@ var GranularRectLayout = /*#__PURE__*/function () {
|
|
|
129
461
|
|
|
130
462
|
}, {
|
|
131
463
|
key: "discardRange",
|
|
132
|
-
value: function discardRange() {
|
|
464
|
+
value: function discardRange(left, right) {
|
|
465
|
+
// console.log( 'discard', left, right );
|
|
466
|
+
var pLeft = Math.floor(left / this.pitchX);
|
|
467
|
+
var pRight = Math.floor(right / this.pitchX);
|
|
468
|
+
var bitmap = this.bitmap;
|
|
469
|
+
|
|
470
|
+
for (var y = 0; y < bitmap.length; y += 1) {
|
|
471
|
+
var row = bitmap[y];
|
|
472
|
+
|
|
473
|
+
if (row) {
|
|
474
|
+
row.discardRange(pLeft, pRight);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
133
478
|
}, {
|
|
134
479
|
key: "hasSeen",
|
|
135
480
|
value: function hasSeen(id) {
|
|
@@ -138,25 +483,24 @@ var GranularRectLayout = /*#__PURE__*/function () {
|
|
|
138
483
|
}, {
|
|
139
484
|
key: "getByCoord",
|
|
140
485
|
value: function getByCoord(x, y) {
|
|
141
|
-
var
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
|
|
486
|
+
var pY = Math.floor(y / this.pitchY);
|
|
487
|
+
var row = this.bitmap[pY];
|
|
488
|
+
|
|
489
|
+
if (!row) {
|
|
490
|
+
return undefined;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
var pX = Math.floor(x / this.pitchX);
|
|
494
|
+
return row.getItemAt(pX);
|
|
148
495
|
}
|
|
149
496
|
}, {
|
|
150
497
|
key: "getByID",
|
|
151
498
|
value: function getByID(id) {
|
|
152
|
-
var
|
|
499
|
+
var r = this.rectangles.get(id);
|
|
153
500
|
|
|
154
|
-
if (
|
|
155
|
-
var
|
|
156
|
-
|
|
157
|
-
minY = rect.minY,
|
|
158
|
-
maxY = rect.maxY;
|
|
159
|
-
return [minX, minY, maxX, maxY];
|
|
501
|
+
if (r) {
|
|
502
|
+
var t = r.top * this.pitchX;
|
|
503
|
+
return [r.l * this.pitchX, t, r.r * this.pitchX, t + r.originalHeight];
|
|
160
504
|
}
|
|
161
505
|
|
|
162
506
|
return undefined;
|
|
@@ -167,17 +511,37 @@ var GranularRectLayout = /*#__PURE__*/function () {
|
|
|
167
511
|
}, {
|
|
168
512
|
key: "getTotalHeight",
|
|
169
513
|
value: function getTotalHeight() {
|
|
170
|
-
return this.pTotalHeight;
|
|
514
|
+
return this.pTotalHeight * this.pitchY;
|
|
171
515
|
}
|
|
172
516
|
}, {
|
|
173
517
|
key: "totalHeight",
|
|
174
518
|
get: function get() {
|
|
175
519
|
return this.getTotalHeight();
|
|
176
520
|
}
|
|
521
|
+
}, {
|
|
522
|
+
key: "getRectangles",
|
|
523
|
+
value: function getRectangles() {
|
|
524
|
+
var _this = this;
|
|
525
|
+
|
|
526
|
+
return new Map(Array.from(this.rectangles.entries()).map(function (_ref2) {
|
|
527
|
+
var _ref3 = (0, _slicedToArray2.default)(_ref2, 2),
|
|
528
|
+
id = _ref3[0],
|
|
529
|
+
rect = _ref3[1];
|
|
530
|
+
|
|
531
|
+
var l = rect.l,
|
|
532
|
+
r = rect.r,
|
|
533
|
+
originalHeight = rect.originalHeight,
|
|
534
|
+
top = rect.top;
|
|
535
|
+
var t = (top || 0) * _this.pitchY;
|
|
536
|
+
var b = t + originalHeight;
|
|
537
|
+
return [id, [l * _this.pitchX, t, r * _this.pitchX, b]]; // left, top, right, bottom
|
|
538
|
+
}));
|
|
539
|
+
}
|
|
177
540
|
}, {
|
|
178
541
|
key: "serializeRegion",
|
|
179
542
|
value: function serializeRegion(region) {
|
|
180
543
|
var regionRectangles = {};
|
|
544
|
+
var maxHeightReached = false;
|
|
181
545
|
|
|
182
546
|
var _iterator = _createForOfIteratorHelper(this.rectangles.entries()),
|
|
183
547
|
_step;
|
|
@@ -188,15 +552,24 @@ var GranularRectLayout = /*#__PURE__*/function () {
|
|
|
188
552
|
id = _step$value[0],
|
|
189
553
|
rect = _step$value[1];
|
|
190
554
|
|
|
191
|
-
var
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
555
|
+
var l = rect.l,
|
|
556
|
+
r = rect.r,
|
|
557
|
+
originalHeight = rect.originalHeight,
|
|
558
|
+
top = rect.top;
|
|
559
|
+
|
|
560
|
+
if (rect.top === null) {
|
|
561
|
+
maxHeightReached = true;
|
|
562
|
+
} else {
|
|
563
|
+
var t = (top || 0) * this.pitchY;
|
|
564
|
+
var b = t + originalHeight;
|
|
565
|
+
var y1 = l * this.pitchX;
|
|
566
|
+
var y2 = r * this.pitchX;
|
|
567
|
+
var x1 = region.start;
|
|
568
|
+
var x2 = region.end; // add +/- pitchX to avoid resolution causing errors
|
|
569
|
+
|
|
570
|
+
if (segmentsIntersect(x1, x2, y1 - this.pitchX, y2 + this.pitchX)) {
|
|
571
|
+
regionRectangles[id] = [y1, t, y2, b];
|
|
572
|
+
}
|
|
200
573
|
}
|
|
201
574
|
}
|
|
202
575
|
} catch (err) {
|
|
@@ -208,29 +581,15 @@ var GranularRectLayout = /*#__PURE__*/function () {
|
|
|
208
581
|
return {
|
|
209
582
|
rectangles: regionRectangles,
|
|
210
583
|
totalHeight: this.getTotalHeight(),
|
|
211
|
-
maxHeightReached:
|
|
584
|
+
maxHeightReached: maxHeightReached
|
|
212
585
|
};
|
|
213
586
|
}
|
|
214
|
-
}, {
|
|
215
|
-
key: "getRectangles",
|
|
216
|
-
value: function getRectangles() {
|
|
217
|
-
return new Map((0, _toConsumableArray2.default)(this.rectangles.entries()).map(function (_ref2) {
|
|
218
|
-
var _ref3 = (0, _slicedToArray2.default)(_ref2, 2),
|
|
219
|
-
id = _ref3[0],
|
|
220
|
-
_ref3$ = _ref3[1],
|
|
221
|
-
minX = _ref3$.minX,
|
|
222
|
-
minY = _ref3$.minY,
|
|
223
|
-
maxX = _ref3$.maxX,
|
|
224
|
-
maxY = _ref3$.maxY;
|
|
225
|
-
|
|
226
|
-
return [id, [minX, minY, maxX, maxY]];
|
|
227
|
-
}));
|
|
228
|
-
}
|
|
229
587
|
}, {
|
|
230
588
|
key: "toJSON",
|
|
231
589
|
value: function toJSON() {
|
|
590
|
+
var rectangles = (0, _index.objectFromEntries)(this.getRectangles());
|
|
232
591
|
return {
|
|
233
|
-
rectangles:
|
|
592
|
+
rectangles: rectangles,
|
|
234
593
|
totalHeight: this.getTotalHeight(),
|
|
235
594
|
maxHeightReached: this.maxHeightReached
|
|
236
595
|
};
|