@genome-spy/core 0.71.0 → 0.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/dist/bundle/index.es.js +6842 -5365
- package/dist/bundle/index.js +159 -140
- package/dist/bundle/parquetRead-BnAGCa4_.js +1663 -0
- package/dist/schema.json +281 -17
- package/dist/src/data/formats/bed.d.ts +8 -0
- package/dist/src/data/formats/bed.d.ts.map +1 -0
- package/dist/src/data/formats/bed.js +53 -0
- package/dist/src/data/formats/bedpe.d.ts +8 -0
- package/dist/src/data/formats/bedpe.d.ts.map +1 -0
- package/dist/src/data/formats/bedpe.js +160 -0
- package/dist/src/data/formats/parquet.d.ts +12 -0
- package/dist/src/data/formats/parquet.d.ts.map +1 -0
- package/dist/src/data/formats/parquet.js +29 -0
- package/dist/src/data/formats/parquetRead.d.ts +18 -0
- package/dist/src/data/formats/parquetRead.d.ts.map +1 -0
- package/dist/src/data/formats/parquetRead.js +326 -0
- package/dist/src/data/sources/dataUtils.d.ts +16 -0
- package/dist/src/data/sources/dataUtils.d.ts.map +1 -1
- package/dist/src/data/sources/dataUtils.js +53 -3
- package/dist/src/data/sources/urlSource.d.ts +4 -0
- package/dist/src/data/sources/urlSource.d.ts.map +1 -1
- package/dist/src/data/sources/urlSource.js +141 -17
- package/dist/src/encoder/encoder.d.ts +2 -2
- package/dist/src/fonts/bmFontManager.d.ts +1 -1
- package/dist/src/genome/assemblyPreflight.d.ts +31 -0
- package/dist/src/genome/assemblyPreflight.d.ts.map +1 -0
- package/dist/src/genome/assemblyPreflight.js +99 -0
- package/dist/src/genome/genome.d.ts +2 -2
- package/dist/src/genome/genome.d.ts.map +1 -1
- package/dist/src/genome/genome.js +4 -0
- package/dist/src/genome/genomeStore.d.ts +34 -3
- package/dist/src/genome/genomeStore.d.ts.map +1 -1
- package/dist/src/genome/genomeStore.js +409 -18
- package/dist/src/genome/rootGenomeConfig.d.ts +26 -0
- package/dist/src/genome/rootGenomeConfig.d.ts.map +1 -0
- package/dist/src/genome/rootGenomeConfig.js +94 -0
- package/dist/src/genomeSpy/interactionController.d.ts +5 -1
- package/dist/src/genomeSpy/interactionController.d.ts.map +1 -1
- package/dist/src/genomeSpy/interactionController.js +244 -29
- package/dist/src/genomeSpy/renderCoordinator.js +1 -1
- package/dist/src/genomeSpy.d.ts +13 -3
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/genomeSpy.js +83 -7
- package/dist/src/gl/canvasSizeHelper.d.ts +74 -0
- package/dist/src/gl/canvasSizeHelper.d.ts.map +1 -0
- package/dist/src/gl/canvasSizeHelper.js +203 -0
- package/dist/src/gl/hashTable.d.ts +78 -0
- package/dist/src/gl/hashTable.d.ts.map +1 -0
- package/dist/src/gl/hashTable.js +164 -0
- package/dist/src/gl/includes/common.glsl.js +1 -1
- package/dist/src/gl/webGLHelper.d.ts +25 -11
- package/dist/src/gl/webGLHelper.d.ts.map +1 -1
- package/dist/src/gl/webGLHelper.js +71 -39
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -2
- package/dist/src/marks/link.d.ts.map +1 -1
- package/dist/src/marks/link.js +5 -3
- package/dist/src/marks/mark.d.ts +1 -1
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +8 -4
- package/dist/src/scales/domainPlanner.d.ts +34 -3
- package/dist/src/scales/domainPlanner.d.ts.map +1 -1
- package/dist/src/scales/domainPlanner.js +247 -26
- package/dist/src/scales/scaleInstanceManager.d.ts +2 -1
- package/dist/src/scales/scaleInstanceManager.d.ts.map +1 -1
- package/dist/src/scales/scaleInstanceManager.js +10 -11
- package/dist/src/scales/scaleInteractionController.d.ts.map +1 -1
- package/dist/src/scales/scaleInteractionController.js +16 -14
- package/dist/src/scales/scaleResolution.d.ts +16 -0
- package/dist/src/scales/scaleResolution.d.ts.map +1 -1
- package/dist/src/scales/scaleResolution.js +314 -54
- package/dist/src/scales/scaleResolutionTestUtils.d.ts +21 -0
- package/dist/src/scales/scaleResolutionTestUtils.d.ts.map +1 -0
- package/dist/src/scales/scaleResolutionTestUtils.js +33 -0
- package/dist/src/scales/selectionDomainUtils.d.ts +22 -0
- package/dist/src/scales/selectionDomainUtils.d.ts.map +1 -0
- package/dist/src/scales/selectionDomainUtils.js +79 -0
- package/dist/src/scales/zoomDomainUtils.d.ts +18 -0
- package/dist/src/scales/zoomDomainUtils.d.ts.map +1 -0
- package/dist/src/scales/zoomDomainUtils.js +69 -0
- package/dist/src/screenshotHarness.d.ts +16 -0
- package/dist/src/screenshotHarness.d.ts.map +1 -0
- package/dist/src/screenshotHarness.js +242 -0
- package/dist/src/singlePageApp.js +1 -1
- package/dist/src/spec/data.d.ts +23 -3
- package/dist/src/spec/genome.d.ts +22 -2
- package/dist/src/spec/parameter.d.ts +39 -2
- package/dist/src/spec/root.d.ts +20 -1
- package/dist/src/spec/scale.d.ts +41 -5
- package/dist/src/styles/genome-spy.css +8 -0
- package/dist/src/styles/genome-spy.css.d.ts +1 -1
- package/dist/src/styles/genome-spy.css.d.ts.map +1 -1
- package/dist/src/styles/genome-spy.css.js +8 -0
- package/dist/src/tooltip/dataTooltipHandler.js +59 -10
- package/dist/src/types/embedApi.d.ts +19 -0
- package/dist/src/utils/inferSpecBaseUrl.d.ts +14 -0
- package/dist/src/utils/inferSpecBaseUrl.d.ts.map +1 -0
- package/dist/src/utils/inferSpecBaseUrl.js +73 -0
- package/dist/src/utils/interactionEvent.d.ts +53 -3
- package/dist/src/utils/interactionEvent.d.ts.map +1 -1
- package/dist/src/utils/interactionEvent.js +62 -1
- package/dist/src/utils/radixSort.d.ts.map +1 -1
- package/dist/src/utils/radixSort.js +26 -1
- package/dist/src/view/containerMutationHelper.d.ts.map +1 -1
- package/dist/src/view/containerMutationHelper.js +8 -0
- package/dist/src/view/dataReadiness.d.ts +2 -2
- package/dist/src/view/dataReadiness.d.ts.map +1 -1
- package/dist/src/view/dataReadiness.js +63 -58
- package/dist/src/view/facetView.d.ts +1 -1
- package/dist/src/view/facetView.js +1 -1
- package/dist/src/view/gridView/gridChild.d.ts +7 -0
- package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
- package/dist/src/view/gridView/gridChild.js +180 -11
- package/dist/src/view/gridView/gridView.d.ts.map +1 -1
- package/dist/src/view/gridView/gridView.js +60 -17
- package/dist/src/view/unitView.d.ts +1 -1
- package/dist/src/view/zoom.d.ts +14 -2
- package/dist/src/view/zoom.d.ts.map +1 -1
- package/dist/src/view/zoom.js +373 -76
- package/package.json +5 -2
|
@@ -2,14 +2,22 @@ import { span } from "vega-util";
|
|
|
2
2
|
import { isContinuous } from "vega-scale";
|
|
3
3
|
|
|
4
4
|
import { LOCUS } from "./scaleResolutionConstants.js";
|
|
5
|
+
import { requireIntervalSelection } from "./selectionDomainUtils.js";
|
|
5
6
|
import createDomain from "../utils/domainArray.js";
|
|
6
7
|
import { getAccessorDomainKey, isScaleAccessor } from "../encoder/accessor.js";
|
|
8
|
+
import { getPrimaryChannel } from "../encoder/encoder.js";
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* @typedef {import("../utils/domainArray.js").DomainArray} DomainArray
|
|
10
12
|
* @typedef {import("../spec/scale.js").ComplexDomain} ComplexDomain
|
|
11
13
|
* @typedef {import("../spec/scale.js").ScalarDomain} ScalarDomain
|
|
14
|
+
* @typedef {import("../spec/scale.js").SelectionDomainRef} SelectionDomainRef
|
|
12
15
|
* @typedef {import("./scaleResolution.js").ScaleResolutionMember} ScaleResolutionMember
|
|
16
|
+
* @typedef {{
|
|
17
|
+
* param: string,
|
|
18
|
+
* encoding: "x" | "y",
|
|
19
|
+
* sync: "auto" | "oneWay" | "twoWay",
|
|
20
|
+
* }} SelectionDomainLinkInfo
|
|
13
21
|
*/
|
|
14
22
|
|
|
15
23
|
export default class DomainPlanner {
|
|
@@ -22,7 +30,7 @@ export default class DomainPlanner {
|
|
|
22
30
|
/** @type {() => import("../spec/channel.js").Type} */
|
|
23
31
|
#getType;
|
|
24
32
|
|
|
25
|
-
/** @type {() => number[]} */
|
|
33
|
+
/** @type {(assembly: import("../spec/scale.js").Scale["assembly"] | undefined) => number[]} */
|
|
26
34
|
#getLocusExtent;
|
|
27
35
|
|
|
28
36
|
/** @type {(interval: ScalarDomain | ComplexDomain) => number[]} */
|
|
@@ -34,6 +42,9 @@ export default class DomainPlanner {
|
|
|
34
42
|
/** @type {DomainArray | undefined} */
|
|
35
43
|
#configuredDomain;
|
|
36
44
|
|
|
45
|
+
/** @type {SelectionDomainLinkInfo | undefined} */
|
|
46
|
+
#selectionDomainLinkInfo = undefined;
|
|
47
|
+
|
|
37
48
|
#configuredDomainDirty = true;
|
|
38
49
|
|
|
39
50
|
/** @type {WeakMap<ScaleResolutionMember, import("../types/encoder.js").ScaleAccessor[]>} */
|
|
@@ -44,7 +55,7 @@ export default class DomainPlanner {
|
|
|
44
55
|
* @param {() => Set<ScaleResolutionMember>} options.getMembers
|
|
45
56
|
* @param {() => Set<ScaleResolutionMember>} [options.getDataMembers]
|
|
46
57
|
* @param {() => import("../spec/channel.js").Type} options.getType
|
|
47
|
-
* @param {() => number[]} options.getLocusExtent
|
|
58
|
+
* @param {(assembly: import("../spec/scale.js").Scale["assembly"] | undefined) => number[]} options.getLocusExtent
|
|
48
59
|
* @param {(interval: ScalarDomain | ComplexDomain) => number[]} options.fromComplexInterval
|
|
49
60
|
*/
|
|
50
61
|
constructor({
|
|
@@ -72,25 +83,51 @@ export default class DomainPlanner {
|
|
|
72
83
|
return !!this.getConfiguredDomain();
|
|
73
84
|
}
|
|
74
85
|
|
|
86
|
+
hasSelectionConfiguredDomain() {
|
|
87
|
+
this.getConfiguredDomain();
|
|
88
|
+
return !!this.#selectionDomainLinkInfo;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @returns {SelectionDomainLinkInfo | undefined}
|
|
93
|
+
*/
|
|
94
|
+
getSelectionConfiguredDomainInfo() {
|
|
95
|
+
this.getConfiguredDomain();
|
|
96
|
+
return this.#selectionDomainLinkInfo;
|
|
97
|
+
}
|
|
98
|
+
|
|
75
99
|
invalidateConfiguredDomain() {
|
|
76
100
|
this.#configuredDomainDirty = true;
|
|
77
101
|
}
|
|
78
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Returns the default domain without considering configured domains.
|
|
105
|
+
*
|
|
106
|
+
* @param {boolean} [extractDataDomain]
|
|
107
|
+
* @param {import("../spec/scale.js").Scale["assembly"]} [locusAssembly]
|
|
108
|
+
* @returns {any[]}
|
|
109
|
+
*/
|
|
110
|
+
getDefaultDomain(extractDataDomain = false, locusAssembly) {
|
|
111
|
+
return resolveDefaultDomain(
|
|
112
|
+
this.#getType(),
|
|
113
|
+
this.#getLocusExtent,
|
|
114
|
+
extractDataDomain ? this.getDataDomain() : undefined,
|
|
115
|
+
locusAssembly
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
79
119
|
/**
|
|
80
120
|
* Returns the configured domain or a data-derived/default domain.
|
|
81
121
|
*
|
|
82
122
|
* @param {boolean} [extractDataDomain]
|
|
123
|
+
* @param {import("../spec/scale.js").Scale["assembly"]} [locusAssembly]
|
|
83
124
|
* @returns {any[]}
|
|
84
125
|
*/
|
|
85
|
-
getConfiguredOrDefaultDomain(extractDataDomain = false) {
|
|
126
|
+
getConfiguredOrDefaultDomain(extractDataDomain = false, locusAssembly) {
|
|
86
127
|
// TODO: intersect the domain with zoom extent (if it's defined)
|
|
87
128
|
return (
|
|
88
129
|
this.getConfiguredDomain() ??
|
|
89
|
-
|
|
90
|
-
this.#getType(),
|
|
91
|
-
this.#getLocusExtent,
|
|
92
|
-
extractDataDomain ? this.getDataDomain() : undefined
|
|
93
|
-
)
|
|
130
|
+
this.getDefaultDomain(extractDataDomain, locusAssembly)
|
|
94
131
|
);
|
|
95
132
|
}
|
|
96
133
|
|
|
@@ -104,13 +141,14 @@ export default class DomainPlanner {
|
|
|
104
141
|
return this.#configuredDomain;
|
|
105
142
|
}
|
|
106
143
|
|
|
107
|
-
const
|
|
144
|
+
const configuredDomain = resolveConfiguredDomain(
|
|
108
145
|
this.#getMembers(),
|
|
109
146
|
this.#fromComplexInterval
|
|
110
147
|
);
|
|
111
|
-
this.#configuredDomain = domain;
|
|
148
|
+
this.#configuredDomain = configuredDomain.domain;
|
|
149
|
+
this.#selectionDomainLinkInfo = configuredDomain.selectionRef;
|
|
112
150
|
this.#configuredDomainDirty = false;
|
|
113
|
-
return domain;
|
|
151
|
+
return configuredDomain.domain;
|
|
114
152
|
}
|
|
115
153
|
|
|
116
154
|
/**
|
|
@@ -184,25 +222,207 @@ export default class DomainPlanner {
|
|
|
184
222
|
/**
|
|
185
223
|
* @param {Set<ScaleResolutionMember>} members
|
|
186
224
|
* @param {(interval: ScalarDomain | ComplexDomain) => number[]} fromComplexInterval
|
|
187
|
-
* @returns {
|
|
225
|
+
* @returns {{
|
|
226
|
+
* domain: DomainArray | undefined,
|
|
227
|
+
* selectionRef: SelectionDomainLinkInfo | undefined,
|
|
228
|
+
* }}
|
|
188
229
|
*/
|
|
189
230
|
function resolveConfiguredDomain(members, fromComplexInterval) {
|
|
190
|
-
const
|
|
231
|
+
const domainMembers = Array.from(members)
|
|
191
232
|
.filter((member) => member.contributesToDomain)
|
|
192
|
-
.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
233
|
+
.filter((member) => member.channelDef.scale?.domain);
|
|
234
|
+
|
|
235
|
+
/** @type {DomainArray[]} */
|
|
236
|
+
const domains = [];
|
|
237
|
+
|
|
238
|
+
/** @type {string | undefined} */
|
|
239
|
+
let selectionRefKey = undefined;
|
|
240
|
+
/** @type {string | undefined} */
|
|
241
|
+
let selectionRefDescription = undefined;
|
|
242
|
+
/** @type {"auto" | "oneWay" | "twoWay" | undefined} */
|
|
243
|
+
let selectionRefSync = undefined;
|
|
244
|
+
/** @type {SelectionDomainLinkInfo | undefined} */
|
|
245
|
+
let selectionRef = undefined;
|
|
246
|
+
let hasLiteralDomain = false;
|
|
247
|
+
|
|
248
|
+
for (const member of domainMembers) {
|
|
249
|
+
const domainDef = member.channelDef.scale.domain;
|
|
250
|
+
if (isSelectionDomainRef(domainDef)) {
|
|
251
|
+
if (hasLiteralDomain) {
|
|
252
|
+
throw new Error(
|
|
253
|
+
"Cannot mix selection-driven and literal configured domains on a shared scale."
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const resolved = resolveSelectionDomain(
|
|
258
|
+
member,
|
|
259
|
+
domainDef,
|
|
260
|
+
fromComplexInterval
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
if (selectionRefKey && selectionRefKey !== resolved.key) {
|
|
264
|
+
throw new Error(
|
|
265
|
+
"Conflicting selection domain references on a shared scale: " +
|
|
266
|
+
selectionRefDescription +
|
|
267
|
+
" vs " +
|
|
268
|
+
resolved.description +
|
|
269
|
+
"."
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (!selectionRefSync) {
|
|
274
|
+
selectionRefSync = resolved.sync;
|
|
275
|
+
} else if (selectionRefSync === "auto") {
|
|
276
|
+
selectionRefSync = resolved.sync;
|
|
277
|
+
} else if (resolved.sync !== "auto") {
|
|
278
|
+
if (selectionRefSync !== resolved.sync) {
|
|
279
|
+
throw new Error(
|
|
280
|
+
"Conflicting selection domain sync modes on a shared scale: " +
|
|
281
|
+
selectionRefSync +
|
|
282
|
+
" vs " +
|
|
283
|
+
resolved.sync +
|
|
284
|
+
"."
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
selectionRefKey = resolved.key;
|
|
290
|
+
selectionRefDescription = resolved.description;
|
|
291
|
+
selectionRef = {
|
|
292
|
+
param: resolved.param,
|
|
293
|
+
encoding: resolved.encoding,
|
|
294
|
+
sync: selectionRefSync,
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
if (resolved.domain) {
|
|
298
|
+
domains.push(resolved.domain);
|
|
299
|
+
}
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (selectionRefKey) {
|
|
304
|
+
throw new Error(
|
|
305
|
+
"Cannot mix literal configured domains with selection-driven domains on a shared scale."
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
hasLiteralDomain = true;
|
|
310
|
+
domains.push(
|
|
311
|
+
createDomain(member.channelDef.type, fromComplexInterval(domainDef))
|
|
201
312
|
);
|
|
313
|
+
}
|
|
202
314
|
|
|
203
315
|
if (domains.length > 0) {
|
|
204
|
-
return
|
|
316
|
+
return {
|
|
317
|
+
domain: domains.reduce((acc, curr) => acc.extendAll(curr)),
|
|
318
|
+
selectionRef,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (selectionRefKey) {
|
|
323
|
+
// Selection refs are still the source of truth even when the
|
|
324
|
+
// selection interval currently resolves to no domain.
|
|
325
|
+
return { domain: undefined, selectionRef };
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return { domain: undefined, selectionRef: undefined };
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* @param {ScaleResolutionMember} member
|
|
333
|
+
* @param {SelectionDomainRef} domainRef
|
|
334
|
+
* @param {(interval: ScalarDomain | ComplexDomain) => number[]} fromComplexInterval
|
|
335
|
+
* @returns {{
|
|
336
|
+
* domain: DomainArray | undefined,
|
|
337
|
+
* key: string,
|
|
338
|
+
* description: string,
|
|
339
|
+
* param: string,
|
|
340
|
+
* encoding: "x" | "y",
|
|
341
|
+
* sync: "auto" | "oneWay" | "twoWay",
|
|
342
|
+
* }}
|
|
343
|
+
*/
|
|
344
|
+
function resolveSelectionDomain(member, domainRef, fromComplexInterval) {
|
|
345
|
+
const paramName = domainRef.param;
|
|
346
|
+
const syncMode = domainRef.sync ?? "auto";
|
|
347
|
+
|
|
348
|
+
if (syncMode !== "auto" && syncMode !== "oneWay" && syncMode !== "twoWay") {
|
|
349
|
+
throw new Error(
|
|
350
|
+
`Invalid selection domain sync mode "${syncMode}" for parameter "${paramName}".`
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const resolvedChannel = resolveSelectionDomainChannel(
|
|
355
|
+
member.channel,
|
|
356
|
+
domainRef,
|
|
357
|
+
paramName
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
const paramRuntime = member.view.paramRuntime;
|
|
361
|
+
const selection = requireIntervalSelection(
|
|
362
|
+
paramRuntime?.findValue(paramName),
|
|
363
|
+
paramName
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
const interval = selection.intervals[resolvedChannel];
|
|
367
|
+
const key = [paramName, resolvedChannel].join("|");
|
|
368
|
+
const description = paramName + "." + resolvedChannel;
|
|
369
|
+
|
|
370
|
+
if (!interval || interval.length !== 2) {
|
|
371
|
+
return {
|
|
372
|
+
domain: undefined,
|
|
373
|
+
key,
|
|
374
|
+
description,
|
|
375
|
+
param: paramName,
|
|
376
|
+
encoding: resolvedChannel,
|
|
377
|
+
sync: syncMode,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return {
|
|
382
|
+
domain: createDomain(
|
|
383
|
+
member.channelDef.type,
|
|
384
|
+
fromComplexInterval(interval)
|
|
385
|
+
),
|
|
386
|
+
key,
|
|
387
|
+
description,
|
|
388
|
+
param: paramName,
|
|
389
|
+
encoding: resolvedChannel,
|
|
390
|
+
sync: syncMode,
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* @param {import("../spec/channel.js").ChannelWithScale} channel
|
|
396
|
+
* @param {SelectionDomainRef} domainRef
|
|
397
|
+
* @param {string} paramName
|
|
398
|
+
* @returns {"x" | "y"}
|
|
399
|
+
*/
|
|
400
|
+
function resolveSelectionDomainChannel(channel, domainRef, paramName) {
|
|
401
|
+
if (domainRef.encoding) {
|
|
402
|
+
return domainRef.encoding;
|
|
205
403
|
}
|
|
404
|
+
|
|
405
|
+
const primaryChannel = getPrimaryChannel(channel);
|
|
406
|
+
if (primaryChannel === "x" || primaryChannel === "y") {
|
|
407
|
+
return primaryChannel;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
throw new Error(
|
|
411
|
+
`Selection domain reference "${paramName}" on channel "${channel}" requires an explicit "encoding" ("x" or "y").`
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* @param {any} domain
|
|
417
|
+
* @returns {domain is SelectionDomainRef}
|
|
418
|
+
*/
|
|
419
|
+
export function isSelectionDomainRef(domain) {
|
|
420
|
+
return (
|
|
421
|
+
typeof domain === "object" &&
|
|
422
|
+
domain !== null &&
|
|
423
|
+
!Array.isArray(domain) &&
|
|
424
|
+
typeof domain.param === "string"
|
|
425
|
+
);
|
|
206
426
|
}
|
|
207
427
|
|
|
208
428
|
/**
|
|
@@ -273,13 +493,14 @@ function resolveDataDomain(members, getType, getAccessorsForMember) {
|
|
|
273
493
|
|
|
274
494
|
/**
|
|
275
495
|
* @param {import("../spec/channel.js").Type} type
|
|
276
|
-
* @param {() => number[]} getLocusExtent
|
|
496
|
+
* @param {(assembly: import("../spec/scale.js").Scale["assembly"] | undefined) => number[]} getLocusExtent
|
|
277
497
|
* @param {DomainArray | undefined} dataDomain
|
|
498
|
+
* @param {import("../spec/scale.js").Scale["assembly"] | undefined} locusAssembly
|
|
278
499
|
* @returns {any[]}
|
|
279
500
|
*/
|
|
280
|
-
function resolveDefaultDomain(type, getLocusExtent, dataDomain) {
|
|
501
|
+
function resolveDefaultDomain(type, getLocusExtent, dataDomain, locusAssembly) {
|
|
281
502
|
if (type == LOCUS) {
|
|
282
|
-
return getLocusExtent();
|
|
503
|
+
return getLocusExtent(locusAssembly);
|
|
283
504
|
}
|
|
284
505
|
return dataDomain ?? [];
|
|
285
506
|
}
|
|
@@ -18,9 +18,10 @@ export default class ScaleInstanceManager {
|
|
|
18
18
|
props: import("../spec/scale.js").Scale;
|
|
19
19
|
};
|
|
20
20
|
/**
|
|
21
|
+
* @param {import("../spec/scale.js").Scale["assembly"]} [assembly]
|
|
21
22
|
* @returns {import("../genome/genome.js").default}
|
|
22
23
|
*/
|
|
23
|
-
getLocusGenome(): import("../genome/genome.js").default;
|
|
24
|
+
getLocusGenome(assembly?: import("../spec/scale.js").Scale["assembly"]): import("../genome/genome.js").default;
|
|
24
25
|
/**
|
|
25
26
|
* @param {import("../spec/scale.js").Scale} props
|
|
26
27
|
* @returns {ScaleWithProps}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaleInstanceManager.d.ts","sourceRoot":"","sources":["../../../src/scales/scaleInstanceManager.js"],"names":[],"mappings":"AAMA;IA0BI;;;;;;OAMG;IACH,iFALG;QAAkH,eAAe,EAAzH,MAAM;YAAE,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,0BAA0B,EAAE,eAAe,CAAA;SAAE;QAC5E,aAAa,EAAjC,MAAM,IAAI;QACW,cAAc,GAAnC,MAAM,IAAI;QAC6D,cAAc,GAArF,MAAM,OAAO,0BAA0B,EAAE,OAAO,GAAG,SAAS;KAA0B,EAYhG;IAED;eA1CkC,OAAO,kBAAkB,EAAE,KAAK;MA4CjE;IAED
|
|
1
|
+
{"version":3,"file":"scaleInstanceManager.d.ts","sourceRoot":"","sources":["../../../src/scales/scaleInstanceManager.js"],"names":[],"mappings":"AAMA;IA0BI;;;;;;OAMG;IACH,iFALG;QAAkH,eAAe,EAAzH,MAAM;YAAE,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,0BAA0B,EAAE,eAAe,CAAA;SAAE;QAC5E,aAAa,EAAjC,MAAM,IAAI;QACW,cAAc,GAAnC,MAAM,IAAI;QAC6D,cAAc,GAArF,MAAM,OAAO,0BAA0B,EAAE,OAAO,GAAG,SAAS;KAA0B,EAYhG;IAED;eA1CkC,OAAO,kBAAkB,EAAE,KAAK;MA4CjE;IAED;;;OAGG;IACH,0BAHW,OAAO,kBAAkB,EAAE,KAAK,CAAC,UAAU,CAAC,GAC1C,OAAO,qBAAqB,EAAE,OAAO,CAajD;IAED;;;OAGG;IACH,mBAHW,OAAO,kBAAkB,EAAE,KAAK;eAhET,OAAO,kBAAkB,EAAE,KAAK;MAqFjE;IAcD;;OAEG;IACH,wBAFW,OAAO,kBAAkB,EAAE,KAAK,QAc1C;IAED;;;OAGG;IACH,4CAHW,MAAM,IAAI,GACR,IAAI,CAShB;IAmFD,gBAGC;;CACJ"}
|
|
@@ -54,15 +54,20 @@ export default class ScaleInstanceManager {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
|
+
* @param {import("../spec/scale.js").Scale["assembly"]} [assembly]
|
|
57
58
|
* @returns {import("../genome/genome.js").default}
|
|
58
59
|
*/
|
|
59
|
-
getLocusGenome() {
|
|
60
|
+
getLocusGenome(assembly) {
|
|
60
61
|
const genomeStore = this.#getGenomeStore?.();
|
|
61
|
-
|
|
62
|
-
if (!genome) {
|
|
62
|
+
if (!genomeStore) {
|
|
63
63
|
throw new Error("No genome has been defined!");
|
|
64
64
|
}
|
|
65
|
-
|
|
65
|
+
|
|
66
|
+
if (assembly) {
|
|
67
|
+
return genomeStore.getGenome(assembly);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return genomeStore.getGenome();
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
/**
|
|
@@ -98,13 +103,7 @@ export default class ScaleInstanceManager {
|
|
|
98
103
|
return;
|
|
99
104
|
}
|
|
100
105
|
|
|
101
|
-
|
|
102
|
-
const genome = genomeStore?.getGenome(props.assembly);
|
|
103
|
-
if (!genome) {
|
|
104
|
-
throw new Error("No genome has been defined!");
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
scale.genome(genome);
|
|
106
|
+
scale.genome(this.getLocusGenome(props.assembly));
|
|
108
107
|
}
|
|
109
108
|
|
|
110
109
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaleInteractionController.d.ts","sourceRoot":"","sources":["../../../src/scales/scaleInteractionController.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scaleInteractionController.d.ts","sourceRoot":"","sources":["../../../src/scales/scaleInteractionController.js"],"names":[],"mappings":"AAkBA;;;;;;;GAOG;AAEH;IAsBI;;;;;;;;OAQG;IACH,wHAPG;QAAsC,QAAQ,EAAtC,MAAM,cAAc;QACkC,WAAW,EAAjE,MAAM,OAAO,sBAAsB,EAAE,OAAO;QACpB,wBAAwB,EAAhD,MAAM,MAAM,EAAE;QACU,cAAc,EAAtC,MAAM,MAAM,EAAE;QAC8C,mBAAmB,EAA/E,CAAC,MAAM,EAAE,YAAY,GAAG,aAAa,KAAK,MAAM,EAAE;QAC1B,eAAe,EAAvC,MAAM,MAAM,EAAE;KACxB,EAeA;IAED,0BAUC;IAED,sBAEC;IAED,8BAGC;IAED;;;;OAIG;IACH,sCAJW,MAAM,EAAE,aACR,MAAM,EAAE,GACN,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAarD;IAED;;;;OAIG;IACH,oBAQC;IAED;;;;;;;OAOG;IACH,kBALW,MAAM,eACN,MAAM,OACN,MAAM,GACJ,OAAO,CA2BnB;IAED;;;;;;OAMG;IACH,eAJW,aAAa,GAAG,aAAa,aAC7B,OAAO,GAAG,MAAM,iBA+D1B;IASD;;;;OAIG;IACH,qBAcC;IAED;;OAEG;IACH,uBAOC;;CACJ;4BA5PY,OAAO,kBAAkB,EAAE,aAAa;2BACxC,OAAO,kBAAkB,EAAE,YAAY;4BACvC,OAAO,kBAAkB,EAAE,aAAa;yBACxC,OAAO,kBAAkB,EAAE,UAAU;wBACrC,OAAO,qBAAqB,EAAE,SAAS;6BACvC,SAAS,GAAG;IAAE,KAAK,EAAE,OAAO,kBAAkB,EAAE,KAAK,CAAA;CAAE"}
|
|
@@ -7,9 +7,6 @@ import {
|
|
|
7
7
|
panLog,
|
|
8
8
|
panPow,
|
|
9
9
|
span,
|
|
10
|
-
zoomLinear,
|
|
11
|
-
zoomLog,
|
|
12
|
-
zoomPow,
|
|
13
10
|
} from "vega-util";
|
|
14
11
|
import { isContinuous, isDiscrete } from "vega-scale";
|
|
15
12
|
import { easeCubicInOut } from "d3-ease";
|
|
@@ -17,6 +14,7 @@ import { easeCubicInOut } from "d3-ease";
|
|
|
17
14
|
import eerp from "../utils/eerp.js";
|
|
18
15
|
import { shallowArrayEquals } from "../utils/arrayUtils.js";
|
|
19
16
|
import { createCancelToken } from "../utils/transition.js";
|
|
17
|
+
import { zoomDomainByScaleType } from "./zoomDomainUtils.js";
|
|
20
18
|
|
|
21
19
|
/**
|
|
22
20
|
* @typedef {import("../spec/scale.js").NumericDomain} NumericDomain
|
|
@@ -121,7 +119,7 @@ export default class ScaleInteractionController {
|
|
|
121
119
|
isZoomed() {
|
|
122
120
|
return (
|
|
123
121
|
this.isZoomingSupported() &&
|
|
124
|
-
shallowArrayEquals(
|
|
122
|
+
!shallowArrayEquals(
|
|
125
123
|
this.#getResetDomain(),
|
|
126
124
|
this.#getScale().domain()
|
|
127
125
|
)
|
|
@@ -326,17 +324,14 @@ function applyZoomTransform(scale, domain, scaleFactor, scaleAnchor, pan) {
|
|
|
326
324
|
anchor += scale.align();
|
|
327
325
|
}
|
|
328
326
|
|
|
329
|
-
// TODO: symlog
|
|
330
327
|
switch (scale.type) {
|
|
331
328
|
case "linear":
|
|
332
329
|
case "index":
|
|
333
330
|
case "locus":
|
|
334
331
|
newDomain = panLinear(newDomain, pan || 0);
|
|
335
|
-
newDomain = zoomLinear(newDomain, anchor, scaleFactor);
|
|
336
332
|
break;
|
|
337
333
|
case "log":
|
|
338
334
|
newDomain = panLog(newDomain, pan || 0);
|
|
339
|
-
newDomain = zoomLog(newDomain, anchor, scaleFactor);
|
|
340
335
|
break;
|
|
341
336
|
case "pow":
|
|
342
337
|
case "sqrt": {
|
|
@@ -345,19 +340,26 @@ function applyZoomTransform(scale, domain, scaleFactor, scaleAnchor, pan) {
|
|
|
345
340
|
scale
|
|
346
341
|
);
|
|
347
342
|
newDomain = panPow(newDomain, pan || 0, powScale.exponent());
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
case "symlog": {
|
|
346
|
+
if (pan !== 0) {
|
|
347
|
+
throw new Error(
|
|
348
|
+
"Panning is not implemented for: " + scale.type
|
|
349
|
+
);
|
|
350
|
+
}
|
|
354
351
|
break;
|
|
355
352
|
}
|
|
356
353
|
default:
|
|
357
354
|
throw new Error("Zooming is not implemented for: " + scale.type);
|
|
358
355
|
}
|
|
359
356
|
|
|
360
|
-
return
|
|
357
|
+
return zoomDomainByScaleType(
|
|
358
|
+
scale,
|
|
359
|
+
/** @type {[number, number]} */ (newDomain),
|
|
360
|
+
anchor,
|
|
361
|
+
scaleFactor
|
|
362
|
+
);
|
|
361
363
|
}
|
|
362
364
|
|
|
363
365
|
/**
|
|
@@ -63,6 +63,22 @@ export default class ScaleResolution implements ScaleResolutionApi {
|
|
|
63
63
|
* @returns {() => void}
|
|
64
64
|
*/
|
|
65
65
|
registerCollectorSubscriptions(collector: import("../data/collector.js").default, accessors: Iterable<import("../types/encoder.js").ScaleAccessor>): () => void;
|
|
66
|
+
/**
|
|
67
|
+
* Returns locus assembly requirements without initializing the scale.
|
|
68
|
+
*
|
|
69
|
+
* This is intentionally side-effect free: it only inspects merged scale
|
|
70
|
+
* properties from registered members and does not touch default domains or
|
|
71
|
+
* instantiate scale instances.
|
|
72
|
+
*
|
|
73
|
+
* @returns {{
|
|
74
|
+
* assembly: import("../spec/scale.js").Scale["assembly"] | undefined,
|
|
75
|
+
* needsDefaultAssembly: boolean
|
|
76
|
+
* }}
|
|
77
|
+
*/
|
|
78
|
+
getAssemblyRequirement(): {
|
|
79
|
+
assembly: import("../spec/scale.js").Scale["assembly"] | undefined;
|
|
80
|
+
needsDefaultAssembly: boolean;
|
|
81
|
+
};
|
|
66
82
|
/**
|
|
67
83
|
* Reconfigures the scale: updates domain and other settings.
|
|
68
84
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaleResolution.d.ts","sourceRoot":"","sources":["../../../src/scales/scaleResolution.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scaleResolution.d.ts","sourceRoot":"","sources":["../../../src/scales/scaleResolution.js"],"names":[],"mappings":"AAgDA;;;;;;;;GAQG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH;IAmDI;;OAEG;IACH,2DAkCC;IAjCG,8CAAsB;IACtB,0FAA0F;IAC1F,MADW,OAAO,oBAAoB,EAAE,IAAI,CAC5B;IAEhB,iEAAiE;IACjE,MADW,MAAM,CACI;IAoEzB,2BASC;IAwBD;;;;;;;OAOG;IACH,4KAEC;IAED;;;OAGG;IACH,+KAEC;IAkLD;;;OAGG;IACH,uBAHW,qBAAqB,GACnB,MAAM,OAAO,CAazB;IAED,gBAKC;IA4CD;;;;OAIG;IACH,0CAJW,OAAO,sBAAsB,EAAE,OAAO,aACtC,QAAQ,CAAC,OAAO,qBAAqB,EAAE,aAAa,CAAC,GACnD,MAAM,IAAI,CAkCtB;IA2CD;;;;;;;;;;;OAWG;IACH,0BALa;QACR,QAAQ,EAAE,OAAO,kBAAkB,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;QACnE,oBAAoB,EAAE,OAAO,CAAA;KAC9B,CAeH;IAmFD;;;;;OAKG;IACH,oBAYC;IAED;;;;;OAKG;IACH,0BAyBC;IA0HD;;OAEG;IACH;eApwBkC,OAAO,kBAAkB,EAAE,KAAK;MA2wBjE;IAED;;;;;;OAMG;IACH;eApxBkC,OAAO,kBAAkB,EAAE,KAAK;MAsxBjE;IAED;;;;OAIG;IACH;eA7xBkC,OAAO,kBAAkB,EAAE,KAAK;MAsyBjE;IAED,mBAEC;IAED;;;;OAIG;IACH,+DAEC;IAED;;OAEG;IACH,oBAFa,mFAA6B,CAMzC;IAED;;;;OAIG;IACH,oBAEC;IAED;;OAEG;IACH,sBAGC;IAED;;;;;;;OAOG;IACH,kBALW,MAAM,eACN,MAAM,OACN,MAAM,GACJ,OAAO,CAInB;IAED;;;;;;OAMG;IACH,eAJW,mFAA6B,aAC7B,OAAO,GAAG,MAAM,iBAK1B;IAED;;;;OAIG;IACH,qBAEC;IAED;;;;;OAKG;IACH,uBAEC;IAED;;;;;;;OAOG;IACH,wBAoBC;IAED;;;;;OAKG;IACH,uBAFW,MAAM,yDAUhB;IAED;;OAEG;IACH,iBAFW,MAAM,yDAIhB;IAED;;;OAGG;IACH,qBAHW,MAAM,+CAAmB,GACvB,MAAM,CAIlB;IAED;;;OAGG;IACH,8BAHW,kFAA4B,GAC1B,MAAM,EAAE,CAOpB;;CACJ;kCA1+B+B,CAAC,SAApB,6CAAkB;;;;UAGrB,OAAO,qBAAqB,EAAE,OAAO;aACrC,CAAC;gBACD,OAAO,oBAAoB,EAAE,mBAAmB;yBAChD,OAAO;;sBAhCV,+BAA+B;sBAA/B,+BAA+B;wBAA/B,+BAA+B;wBAA/B,+BAA+B;6BAA/B,+BAA+B"}
|