higlass 1.12.4 → 1.13.1
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/README.md +3 -3
- package/app/globals.d.ts +11 -0
- package/app/missing-types.d.ts +21 -0
- package/app/scripts/CenterTrack.jsx +0 -1
- package/app/scripts/DraggableDiv.jsx +0 -1
- package/app/scripts/GenomePositionSearchBox.jsx +0 -1
- package/app/scripts/PixiTrack.js +106 -42
- package/app/scripts/Track.js +153 -45
- package/app/scripts/TrackRenderer.jsx +452 -135
- package/app/scripts/VerticalTiledPlot.jsx +0 -1
- package/app/scripts/configs/default-tracks-for-datatype.js +3 -2
- package/app/scripts/configs/primitives.js +3 -2
- package/app/scripts/configs/tracks-info-by-type.js +4 -1
- package/app/scripts/configs/tracks-info.js +25 -1
- package/app/scripts/hocs/with-pub-sub.jsx +3 -1
- package/app/scripts/types.ts +105 -0
- package/app/scripts/utils/abs-to-chr.js +16 -1
- package/app/scripts/utils/accessor-transposition.js +5 -4
- package/app/scripts/utils/add-arrays.js +9 -7
- package/app/scripts/utils/add-class.js +4 -2
- package/app/scripts/utils/add-event-listener-once.js +9 -3
- package/app/scripts/utils/background-task-scheduler.js +58 -2
- package/app/scripts/utils/base64-to-canvas.js +12 -5
- package/app/scripts/utils/chr-to-abs.js +10 -0
- package/app/scripts/utils/chrom-info-bisector.js +4 -1
- package/app/scripts/utils/clone-event.js +11 -4
- package/app/scripts/utils/color-to-hex.js +8 -0
- package/app/scripts/utils/color-to-rgba.js +8 -0
- package/app/scripts/utils/data-to-genomic-loci.js +13 -1
- package/app/scripts/utils/debounce.js +16 -11
- package/app/scripts/utils/dec-to-hex-str.js +7 -0
- package/app/scripts/utils/dict-from-tuples.js +11 -3
- package/app/scripts/utils/dict-items.js +15 -0
- package/app/scripts/utils/dict-keys.js +11 -1
- package/app/scripts/utils/dict-values.js +7 -0
- package/app/scripts/utils/download.js +14 -11
- package/app/scripts/utils/flatten.js +5 -2
- package/app/scripts/utils/for-each.js +7 -5
- package/app/scripts/utils/forward-event.js +3 -2
- package/app/scripts/utils/genome-loci-to-pixels.js +8 -0
- package/app/scripts/utils/genomic-range-to-chromosome-chunks.js +13 -6
- package/app/scripts/utils/get-aggregation-function.js +10 -2
- package/app/scripts/utils/get-element-dim.js +6 -0
- package/app/scripts/utils/gradient.js +14 -0
- package/app/scripts/utils/has-class.js +6 -4
- package/app/scripts/utils/hex-string-to-int.js +11 -4
- package/app/scripts/utils/index.js +1 -0
- package/app/scripts/utils/into-the-void.js +2 -1
- package/app/scripts/utils/is-track-or-child-track.js +6 -0
- package/app/scripts/utils/is-track-range-selectable.js +10 -1
- package/app/scripts/utils/is-within.js +9 -7
- package/app/scripts/utils/lat-to-y.js +6 -3
- package/app/scripts/utils/lng-to-x.js +4 -3
- package/app/scripts/utils/map.js +5 -2
- package/app/scripts/utils/max-non-zero.js +6 -0
- package/app/scripts/utils/max.js +4 -3
- package/app/scripts/utils/min-non-zero.js +6 -0
- package/app/scripts/utils/min.js +4 -3
- package/app/scripts/utils/mod.js +4 -3
- package/app/scripts/utils/numericify-version.js +5 -0
- package/app/scripts/utils/obj-vals.js +3 -2
- package/app/scripts/utils/or.js +4 -3
- package/app/scripts/utils/parse-chromsizes-rows.js +26 -5
- package/app/scripts/utils/q.js +3 -2
- package/app/scripts/utils/rad-to-deg.js +3 -2
- package/app/scripts/utils/reduce.js +2 -2
- package/app/scripts/utils/rel-to-abs-chrom-pos.js +10 -0
- package/app/scripts/utils/remove-class.js +3 -2
- package/app/scripts/utils/reset-d3-brush-style.js +7 -2
- package/app/scripts/utils/rgb-to-hex.js +9 -0
- package/app/scripts/utils/scales-center-and-k.js +5 -3
- package/app/scripts/utils/scales-to-genome-loci.js +10 -0
- package/app/scripts/utils/selected-items-to-cum-weights.js +12 -4
- package/app/scripts/utils/selected-items-to-size.js +5 -2
- package/app/scripts/utils/show-mouse-position.js +62 -19
- package/app/scripts/utils/some.js +6 -4
- package/app/scripts/utils/sum.js +4 -3
- package/app/scripts/utils/throttle-and-debounce.js +15 -6
- package/app/scripts/utils/tile-to-canvas.js +8 -4
- package/app/scripts/utils/timeout.js +2 -0
- package/app/scripts/utils/to-void.js +2 -0
- package/app/scripts/utils/total-track-pixel-height.js +11 -12
- package/app/scripts/utils/trim-trailing-slash.js +3 -2
- package/app/scripts/utils/type-guards.js +41 -0
- package/app/scripts/utils/value-to-color.js +7 -6
- package/app/scripts/utils/visit-positioned-tracks.js +16 -11
- package/app/scripts/utils/visit-tracks.js +12 -13
- package/dist/esm.html +283 -0
- package/dist/hglib.js +42 -82804
- package/dist/hglib.min.js +86 -105
- package/dist/higlass.mjs +207 -0
- package/dist/index.html +6 -6
- package/package.json +23 -5
package/app/scripts/Track.js
CHANGED
|
@@ -1,41 +1,62 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import { scaleLinear } from 'd3-scale';
|
|
2
3
|
import { fake as fakePubSub } from './hocs/with-pub-sub';
|
|
3
4
|
|
|
4
5
|
// Services
|
|
5
6
|
import { isWithin } from './utils';
|
|
6
7
|
|
|
8
|
+
/**
|
|
9
|
+
* @typedef TrackContext
|
|
10
|
+
* @property {string} id - The track ID.
|
|
11
|
+
* @property {import('pub-sub-es').PubSub & { __fake__?: boolean }} [pubSub] - The pub-sub channel.
|
|
12
|
+
* @property {() => import('./types').Theme} [getTheme] - A function that returns the current theme.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @template T
|
|
17
|
+
* @typedef {T & TrackContext} ExtendedTrackContext
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** @template Options */
|
|
7
21
|
class Track {
|
|
8
|
-
|
|
22
|
+
/**
|
|
23
|
+
* @param {TrackContext} context
|
|
24
|
+
* @param {Options} options
|
|
25
|
+
*/
|
|
26
|
+
constructor(context, options) {
|
|
9
27
|
this.context = context;
|
|
10
28
|
|
|
11
29
|
const { id, pubSub, getTheme } = context;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} else {
|
|
15
|
-
this.pubSub = fakePubSub;
|
|
16
|
-
}
|
|
30
|
+
/** @type {import('pub-sub-es').PubSub} */
|
|
31
|
+
this.pubSub = pubSub ?? fakePubSub;
|
|
17
32
|
|
|
33
|
+
/** @type {string} */
|
|
18
34
|
this.id = id;
|
|
35
|
+
/** @type {import('./types').Scale} */
|
|
19
36
|
this._xScale = scaleLinear();
|
|
37
|
+
/** @type {import('./types').Scale} */
|
|
20
38
|
this._yScale = scaleLinear();
|
|
21
39
|
|
|
22
40
|
// reference scales used for tracks that can translate and scale
|
|
23
41
|
// their graphics
|
|
24
42
|
// They will draw their graphics on the reference scales and then translate
|
|
25
43
|
// and pan them as needed
|
|
44
|
+
/** @type {import('./types').Scale} */
|
|
26
45
|
this._refXScale = scaleLinear();
|
|
46
|
+
/** @type {import('./types').Scale} */
|
|
27
47
|
this._refYScale = scaleLinear();
|
|
28
48
|
|
|
49
|
+
/** @type {[number, number]} */
|
|
29
50
|
this.position = [0, 0];
|
|
51
|
+
/** @type {[number, number]} */
|
|
30
52
|
this.dimensions = [1, 1];
|
|
31
|
-
|
|
53
|
+
/** @type {Options} */
|
|
54
|
+
this.options = options;
|
|
55
|
+
/** @type {Array<import('pub-sub-es').Subscription>} */
|
|
32
56
|
this.pubSubs = [];
|
|
33
57
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
} else {
|
|
37
|
-
this.getTheme = () => {};
|
|
38
|
-
}
|
|
58
|
+
/** @type {() => (import('./types').Theme | undefined)} */
|
|
59
|
+
this.getTheme = getTheme ?? (() => undefined);
|
|
39
60
|
|
|
40
61
|
this.pubSubs.push(
|
|
41
62
|
this.pubSub.subscribe(
|
|
@@ -43,14 +64,16 @@ class Track {
|
|
|
43
64
|
this.defaultMouseMoveHandler.bind(this),
|
|
44
65
|
),
|
|
45
66
|
);
|
|
67
|
+
|
|
68
|
+
this.isLeftModified = false;
|
|
46
69
|
}
|
|
47
70
|
|
|
48
71
|
/**
|
|
49
72
|
* Check if a 2d location (x, y) is within the bounds of this track.
|
|
50
73
|
*
|
|
51
|
-
* @param {
|
|
52
|
-
* @param {
|
|
53
|
-
* @return {
|
|
74
|
+
* @param {number} x - X position to be tested.
|
|
75
|
+
* @param {number} y - Y position to be tested.
|
|
76
|
+
* @return {boolean} If `true` location is within the track.
|
|
54
77
|
*/
|
|
55
78
|
isWithin(x, y) {
|
|
56
79
|
let xx = x;
|
|
@@ -75,14 +98,26 @@ class Track {
|
|
|
75
98
|
);
|
|
76
99
|
}
|
|
77
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Get a property from the track.
|
|
103
|
+
* @template {keyof this} T
|
|
104
|
+
* @param {T} prop - The property to get.
|
|
105
|
+
* @return {() => this[T]}
|
|
106
|
+
*/
|
|
78
107
|
getProp(prop) {
|
|
79
108
|
return () => this[prop];
|
|
80
109
|
}
|
|
81
110
|
|
|
82
111
|
getData() {}
|
|
83
112
|
|
|
84
|
-
/**
|
|
85
|
-
* position
|
|
113
|
+
/**
|
|
114
|
+
* Capture click events. x and y are relative to the track position
|
|
115
|
+
* @template T
|
|
116
|
+
* @param {number} x - X position of the click event.
|
|
117
|
+
* @param {number} y - Y position of the click event.
|
|
118
|
+
* @param {T} evt - The event.
|
|
119
|
+
* @return {{ type: 'generic', event: T, payload: null }}
|
|
120
|
+
*/
|
|
86
121
|
click(x, y, evt) {
|
|
87
122
|
return {
|
|
88
123
|
type: 'generic',
|
|
@@ -94,10 +129,12 @@ class Track {
|
|
|
94
129
|
/** There was a click event outside the track * */
|
|
95
130
|
clickOutside() {}
|
|
96
131
|
|
|
132
|
+
/** @returns {[number, number]} */
|
|
97
133
|
getDimensions() {
|
|
98
134
|
return this.dimensions;
|
|
99
135
|
}
|
|
100
136
|
|
|
137
|
+
/** @param {[number, number]} newDimensions */
|
|
101
138
|
setDimensions(newDimensions) {
|
|
102
139
|
this.dimensions = newDimensions;
|
|
103
140
|
|
|
@@ -105,82 +142,136 @@ class Track {
|
|
|
105
142
|
this._yScale.range([0, this.dimensions[1]]);
|
|
106
143
|
}
|
|
107
144
|
|
|
145
|
+
/**
|
|
146
|
+
* @overload
|
|
147
|
+
* @return {import('./types').Scale}
|
|
148
|
+
*/
|
|
149
|
+
/**
|
|
150
|
+
* @overload
|
|
151
|
+
* @param {import('./types').Scale} scale
|
|
152
|
+
* @return {this}
|
|
153
|
+
*/
|
|
108
154
|
/**
|
|
109
155
|
* Either get or set the reference xScale
|
|
156
|
+
*
|
|
157
|
+
* @param {import('./types').Scale=} scale
|
|
158
|
+
* @return {import('./types').Scale | this}
|
|
110
159
|
*/
|
|
111
|
-
refXScale(
|
|
112
|
-
if (!
|
|
113
|
-
|
|
114
|
-
this._refXScale = _;
|
|
115
|
-
|
|
160
|
+
refXScale(scale) {
|
|
161
|
+
if (!scale) return this._refXScale;
|
|
162
|
+
this._refXScale = scale;
|
|
116
163
|
return this;
|
|
117
164
|
}
|
|
118
165
|
|
|
166
|
+
/**
|
|
167
|
+
* @overload
|
|
168
|
+
* @return {import('./types').Scale}
|
|
169
|
+
*/
|
|
170
|
+
/**
|
|
171
|
+
* @overload
|
|
172
|
+
* @param {import('./types').Scale} scale
|
|
173
|
+
* @return {this}
|
|
174
|
+
*/
|
|
119
175
|
/**
|
|
120
176
|
* Either get or set the reference yScale
|
|
177
|
+
*
|
|
178
|
+
* @param {import('./types').Scale=} scale
|
|
179
|
+
* @return {import('./types').Scale | this}
|
|
121
180
|
*/
|
|
122
|
-
refYScale(
|
|
123
|
-
if (!
|
|
124
|
-
|
|
125
|
-
this._refYScale = _;
|
|
126
|
-
|
|
181
|
+
refYScale(scale) {
|
|
182
|
+
if (!scale) return this._refYScale;
|
|
183
|
+
this._refYScale = scale;
|
|
127
184
|
return this;
|
|
128
185
|
}
|
|
129
186
|
|
|
187
|
+
/**
|
|
188
|
+
* @overload
|
|
189
|
+
* @return {import('./types').Scale}
|
|
190
|
+
*/
|
|
191
|
+
/**
|
|
192
|
+
* @overload
|
|
193
|
+
* @param {import('./types').Scale} scale
|
|
194
|
+
* @return {this}
|
|
195
|
+
*/
|
|
130
196
|
/**
|
|
131
197
|
* Either get or set the xScale
|
|
198
|
+
*
|
|
199
|
+
* @param {import('./types').Scale=} scale
|
|
200
|
+
* @return {import('./types').Scale | this}
|
|
132
201
|
*/
|
|
133
|
-
xScale(
|
|
134
|
-
if (!
|
|
135
|
-
|
|
136
|
-
this._xScale = _;
|
|
137
|
-
|
|
202
|
+
xScale(scale) {
|
|
203
|
+
if (!scale) return this._xScale;
|
|
204
|
+
this._xScale = scale;
|
|
138
205
|
return this;
|
|
139
206
|
}
|
|
140
207
|
|
|
208
|
+
/**
|
|
209
|
+
* @overload
|
|
210
|
+
* @return {import('./types').Scale}
|
|
211
|
+
*/
|
|
212
|
+
/**
|
|
213
|
+
* @overload
|
|
214
|
+
* @param {import('./types').Scale} scale
|
|
215
|
+
* @return {this}
|
|
216
|
+
*/
|
|
141
217
|
/**
|
|
142
218
|
* Either get or set the yScale
|
|
219
|
+
*
|
|
220
|
+
* @param {import('./types').Scale=} scale
|
|
221
|
+
* @return {import('./types').Scale | this}
|
|
143
222
|
*/
|
|
144
|
-
yScale(
|
|
145
|
-
if (!
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
this._yScale = _;
|
|
150
|
-
|
|
223
|
+
yScale(scale) {
|
|
224
|
+
if (!scale) return this._yScale;
|
|
225
|
+
this._yScale = scale;
|
|
151
226
|
return this;
|
|
152
227
|
}
|
|
153
228
|
|
|
229
|
+
/**
|
|
230
|
+
* @param {import('./types').Scale} newXScale
|
|
231
|
+
* @param {import('./types').Scale} newYScale
|
|
232
|
+
* @returns {void}
|
|
233
|
+
*/
|
|
154
234
|
zoomed(newXScale, newYScale) {
|
|
155
235
|
this.xScale(newXScale);
|
|
156
236
|
this.yScale(newYScale);
|
|
157
237
|
}
|
|
158
238
|
|
|
239
|
+
/**
|
|
240
|
+
* @param {import('./types').Scale} refXScale
|
|
241
|
+
* @param {import('./types').Scale} refYScale
|
|
242
|
+
* @returns {void}
|
|
243
|
+
*/
|
|
159
244
|
refScalesChanged(refXScale, refYScale) {
|
|
160
245
|
this._refXScale = refXScale;
|
|
161
246
|
this._refYScale = refYScale;
|
|
162
247
|
}
|
|
163
248
|
|
|
249
|
+
/** @returns {void} */
|
|
164
250
|
draw() {}
|
|
165
251
|
|
|
252
|
+
/** @returns {[number, number]} */
|
|
166
253
|
getPosition() {
|
|
167
254
|
return this.position;
|
|
168
255
|
}
|
|
169
256
|
|
|
257
|
+
/**
|
|
258
|
+
* @param {[number, number]} newPosition
|
|
259
|
+
* @returns {void}
|
|
260
|
+
*/
|
|
170
261
|
setPosition(newPosition) {
|
|
171
262
|
this.position = newPosition;
|
|
172
263
|
}
|
|
173
264
|
|
|
174
|
-
|
|
265
|
+
/**
|
|
175
266
|
* A blank handler for MouseMove / Zoom events. Should be overriden
|
|
176
267
|
* by individual tracks to provide
|
|
177
268
|
*
|
|
178
|
-
* @param {
|
|
179
|
-
*
|
|
180
|
-
* @returns nothing
|
|
269
|
+
* @param {{}} evt
|
|
270
|
+
* @returns {void}
|
|
181
271
|
*/
|
|
182
272
|
defaultMouseMoveHandler(evt) {}
|
|
183
273
|
|
|
274
|
+
/** @returns {void} */
|
|
184
275
|
remove() {
|
|
185
276
|
// Clear all pubSub subscriptions
|
|
186
277
|
this.pubSubs.forEach((subscription) =>
|
|
@@ -189,19 +280,36 @@ class Track {
|
|
|
189
280
|
this.pubSubs = [];
|
|
190
281
|
}
|
|
191
282
|
|
|
192
|
-
|
|
283
|
+
/**
|
|
284
|
+
* @param {Options} options
|
|
285
|
+
* @returns {void}
|
|
286
|
+
*/
|
|
287
|
+
rerender(options) {}
|
|
193
288
|
|
|
194
|
-
|
|
289
|
+
/**
|
|
195
290
|
* This function is for seeing whether this track should respond
|
|
196
291
|
* to events at this mouse position. The difference to `isWithin()` is that it
|
|
197
292
|
* can be overwritten if a track is inactive for example.
|
|
293
|
+
*
|
|
294
|
+
* @param {number} x - X position to be tested.
|
|
295
|
+
* @param {number} y - Y position to be tested.
|
|
296
|
+
* @returns {boolean}
|
|
198
297
|
*/
|
|
199
298
|
respondsToPosition(x, y) {
|
|
200
299
|
return this.isWithin(x, y);
|
|
201
300
|
}
|
|
202
301
|
|
|
302
|
+
/**
|
|
303
|
+
* @param {number} trackY
|
|
304
|
+
* @param {number} kMultiplier
|
|
305
|
+
* @returns {void}
|
|
306
|
+
*/
|
|
203
307
|
zoomedY(trackY, kMultiplier) {}
|
|
204
308
|
|
|
309
|
+
/**
|
|
310
|
+
* @param {number} dY
|
|
311
|
+
* @returns {void}
|
|
312
|
+
*/
|
|
205
313
|
movedY(dY) {}
|
|
206
314
|
}
|
|
207
315
|
|