@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
|
@@ -21,6 +21,7 @@ overflow: hidden;
|
|
|
21
21
|
|
|
22
22
|
canvas {
|
|
23
23
|
display: block;
|
|
24
|
+
touch-action: none;
|
|
24
25
|
transform: scale(1, 1);
|
|
25
26
|
opacity: 1;
|
|
26
27
|
transition:
|
|
@@ -163,6 +164,13 @@ margin-left: 0.4em;
|
|
|
163
164
|
box-shadow: 0px 0px 3px 1px white;
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
.color-legend-unmapped {
|
|
168
|
+
background-color: transparent;
|
|
169
|
+
border: 1px solid black;
|
|
170
|
+
box-sizing: border-box;
|
|
171
|
+
box-shadow: none;
|
|
172
|
+
}
|
|
173
|
+
|
|
166
174
|
.attributes {
|
|
167
175
|
.hovered {
|
|
168
176
|
background-color: #e0e0e0;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { html } from "lit";
|
|
2
|
+
import { splitAccessPath } from "vega-util";
|
|
2
3
|
import formatObject from "../utils/formatObject.js";
|
|
3
4
|
import { flattenDatumRows } from "./flattenDatumRows.js";
|
|
4
5
|
import createTooltipContext from "./tooltipContext.js";
|
|
@@ -7,23 +8,71 @@ import createTooltipContext from "./tooltipContext.js";
|
|
|
7
8
|
* @type {import("./tooltipHandler.js").TooltipHandler}
|
|
8
9
|
*/
|
|
9
10
|
export default async function dataTooltipHandler(datum, mark, params, context) {
|
|
11
|
+
/**
|
|
12
|
+
* @param {string} fieldPath
|
|
13
|
+
* @returns {string}
|
|
14
|
+
*/
|
|
15
|
+
// Tooltip rows are flattened using dot notation. Normalize encoded field
|
|
16
|
+
// access paths (for example bracket syntax) to the same shape.
|
|
17
|
+
const normalizeFieldPath = (fieldPath) =>
|
|
18
|
+
splitAccessPath(fieldPath).join(".");
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {unknown} value
|
|
22
|
+
* @returns {boolean}
|
|
23
|
+
*/
|
|
24
|
+
// Treat NaN like missing in tooltip semantics to avoid showing an
|
|
25
|
+
// "unmapped" marker for invalid numeric values.
|
|
26
|
+
const hasValue = (value) =>
|
|
27
|
+
value !== null &&
|
|
28
|
+
value !== undefined &&
|
|
29
|
+
!(typeof value === "number" && Number.isNaN(value));
|
|
30
|
+
|
|
10
31
|
/**
|
|
11
32
|
* @param {string} key
|
|
33
|
+
* @param {any} value
|
|
12
34
|
* @param {object} datum
|
|
13
35
|
*/
|
|
14
|
-
const legend = (key, datum) => {
|
|
36
|
+
const legend = (key, value, datum) => {
|
|
15
37
|
for (const [channel, encoder] of Object.entries(mark.encoders)) {
|
|
16
|
-
|
|
38
|
+
const fields = encoder?.dataAccessor?.fields;
|
|
39
|
+
if (
|
|
40
|
+
fields &&
|
|
41
|
+
fields.some(
|
|
42
|
+
(fieldPath) =>
|
|
43
|
+
fieldPath === key ||
|
|
44
|
+
normalizeFieldPath(fieldPath) === key
|
|
45
|
+
)
|
|
46
|
+
) {
|
|
17
47
|
switch (channel) {
|
|
18
48
|
case "color":
|
|
19
49
|
case "fill":
|
|
20
|
-
case "stroke":
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
50
|
+
case "stroke": {
|
|
51
|
+
const encodedColor = encoder(datum);
|
|
52
|
+
if (
|
|
53
|
+
encodedColor !== null &&
|
|
54
|
+
encodedColor !== undefined
|
|
55
|
+
) {
|
|
56
|
+
return html`
|
|
57
|
+
<span
|
|
58
|
+
class="color-legend"
|
|
59
|
+
style=${"background-color: " +
|
|
60
|
+
String(encodedColor)}
|
|
61
|
+
></span>
|
|
62
|
+
`;
|
|
63
|
+
} else if (hasValue(value)) {
|
|
64
|
+
// The field has a value but the scale did not map it
|
|
65
|
+
// (typically outside/absent domain): show an empty,
|
|
66
|
+
// black-stroked swatch to signal the mismatch.
|
|
67
|
+
return html`
|
|
68
|
+
<span
|
|
69
|
+
class="color-legend color-legend-unmapped"
|
|
70
|
+
></span>
|
|
71
|
+
`;
|
|
72
|
+
} else {
|
|
73
|
+
return "";
|
|
74
|
+
}
|
|
75
|
+
}
|
|
27
76
|
default:
|
|
28
77
|
}
|
|
29
78
|
}
|
|
@@ -47,7 +96,7 @@ export default async function dataTooltipHandler(datum, mark, params, context) {
|
|
|
47
96
|
|
|
48
97
|
const tableContents = orderedRows.map((row) => {
|
|
49
98
|
const value = formatObject(row.value);
|
|
50
|
-
const valueLegend = legend(row.key, datum);
|
|
99
|
+
const valueLegend = legend(row.key, row.value, datum);
|
|
51
100
|
return html`
|
|
52
101
|
<tr>
|
|
53
102
|
<th>${row.key}</th>
|
|
@@ -75,6 +75,12 @@ export interface EmbedResult {
|
|
|
75
75
|
*/
|
|
76
76
|
getScaleResolutionByName: (name: string) => ScaleResolutionApi;
|
|
77
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Waits until lazy data sources have loaded data for the current visible
|
|
80
|
+
* positional domain.
|
|
81
|
+
*/
|
|
82
|
+
awaitVisibleLazyData: (signal?: AbortSignal) => Promise<void>;
|
|
83
|
+
|
|
78
84
|
/**
|
|
79
85
|
* Updates a named dataset
|
|
80
86
|
*
|
|
@@ -83,6 +89,19 @@ export interface EmbedResult {
|
|
|
83
89
|
*/
|
|
84
90
|
updateNamedData: (name: string, data?: any[]) => void;
|
|
85
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Returns the bounds reached by the last rendered layout in CSS pixels.
|
|
94
|
+
*/
|
|
95
|
+
getRenderedBounds: () => {
|
|
96
|
+
width: number | undefined;
|
|
97
|
+
height: number | undefined;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Returns the current logical canvas size in CSS pixels.
|
|
102
|
+
*/
|
|
103
|
+
getLogicalCanvasSize: () => { width: number; height: number };
|
|
104
|
+
|
|
86
105
|
/**
|
|
87
106
|
* Returns a PNG data URL of the current canvas.
|
|
88
107
|
*
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {string} url
|
|
3
|
+
*/
|
|
4
|
+
export function getCuratedExampleBaseUrl(url: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Infers the effective base URL for a spec loaded from the given URL or path.
|
|
7
|
+
*
|
|
8
|
+
* Curated shared examples resolve against the examples root so they can use
|
|
9
|
+
* tidy `data/...` and `shared/...` paths regardless of their subdirectory.
|
|
10
|
+
*
|
|
11
|
+
* @param {string} url
|
|
12
|
+
*/
|
|
13
|
+
export default function inferSpecBaseUrl(url: string): string;
|
|
14
|
+
//# sourceMappingURL=inferSpecBaseUrl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inferSpecBaseUrl.d.ts","sourceRoot":"","sources":["../../../src/utils/inferSpecBaseUrl.js"],"names":[],"mappings":"AAuBA;;GAEG;AACH,8CAFW,MAAM,UAahB;AAED;;;;;;;GAOG;AACH,8CAFW,MAAM,UAYhB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const CURATED_EXAMPLE_BASES = [
|
|
2
|
+
["/docs/examples/", "/docs/examples/"],
|
|
3
|
+
["/examples/core/", "/examples/"],
|
|
4
|
+
["/examples/docs/", "/examples/"],
|
|
5
|
+
["/examples/app/", "/examples/"],
|
|
6
|
+
];
|
|
7
|
+
|
|
8
|
+
const EXTERNAL_URL_RE = /^(?:[a-z]+:)?\/\//i;
|
|
9
|
+
const DUMMY_ORIGIN = "https://example.invalid";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {string} url
|
|
13
|
+
*/
|
|
14
|
+
function getUrlKind(url) {
|
|
15
|
+
if (EXTERNAL_URL_RE.test(url)) {
|
|
16
|
+
return "external";
|
|
17
|
+
} else if (url.startsWith("/")) {
|
|
18
|
+
return "root";
|
|
19
|
+
} else {
|
|
20
|
+
return "relative";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {string} url
|
|
26
|
+
*/
|
|
27
|
+
export function getCuratedExampleBaseUrl(url) {
|
|
28
|
+
const parsed = new URL(url, DUMMY_ORIGIN);
|
|
29
|
+
const match = CURATED_EXAMPLE_BASES.find(([prefix]) =>
|
|
30
|
+
parsed.pathname.startsWith(prefix)
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
if (!match) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return formatOutputUrl(match[1], parsed, getUrlKind(url));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Infers the effective base URL for a spec loaded from the given URL or path.
|
|
42
|
+
*
|
|
43
|
+
* Curated shared examples resolve against the examples root so they can use
|
|
44
|
+
* tidy `data/...` and `shared/...` paths regardless of their subdirectory.
|
|
45
|
+
*
|
|
46
|
+
* @param {string} url
|
|
47
|
+
*/
|
|
48
|
+
export default function inferSpecBaseUrl(url) {
|
|
49
|
+
const curatedBaseUrl = getCuratedExampleBaseUrl(url);
|
|
50
|
+
if (curatedBaseUrl) {
|
|
51
|
+
return curatedBaseUrl;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const parsed = new URL(url, DUMMY_ORIGIN);
|
|
55
|
+
const directoryUrl = new URL("./", parsed);
|
|
56
|
+
|
|
57
|
+
return formatOutputUrl(directoryUrl.pathname, parsed, getUrlKind(url));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {string} pathname
|
|
62
|
+
* @param {URL} parsed
|
|
63
|
+
* @param {"external" | "root" | "relative"} kind
|
|
64
|
+
*/
|
|
65
|
+
function formatOutputUrl(pathname, parsed, kind) {
|
|
66
|
+
if (kind === "external") {
|
|
67
|
+
return parsed.origin + pathname;
|
|
68
|
+
} else if (kind === "root") {
|
|
69
|
+
return pathname;
|
|
70
|
+
} else {
|
|
71
|
+
return pathname.slice(1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {object} TouchGestureEvent
|
|
3
|
+
* @prop {"touchgesture"} type
|
|
4
|
+
* @prop {"move" | "end"} phase
|
|
5
|
+
* @prop {1 | 2} pointerCount
|
|
6
|
+
* @prop {number} xDelta
|
|
7
|
+
* @prop {number} yDelta
|
|
8
|
+
* @prop {number} zDelta
|
|
9
|
+
* @prop {() => void} [preventDefault]
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Side-effect-free query event for wheel ownership. Handlers should only
|
|
13
|
+
* claim wheel if they would consume native wheel at the current pointer
|
|
14
|
+
* location.
|
|
15
|
+
*
|
|
16
|
+
* @typedef {object} WheelClaimProbeEvent
|
|
17
|
+
* @prop {"wheelclaimprobe"} type
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {UIEvent | TouchGestureEvent | WheelClaimProbeEvent} InteractionUiEvent
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* @param {unknown} eventLike
|
|
24
|
+
* @returns {eventLike is TouchGestureEvent}
|
|
25
|
+
*/
|
|
26
|
+
export function isTouchGestureEvent(eventLike: unknown): eventLike is TouchGestureEvent;
|
|
1
27
|
/**
|
|
2
28
|
* Create a safe proxy for an event-like object that exposes only primitive
|
|
3
29
|
* (string, number, boolean, bigint, symbol, undefined) properties and null.
|
|
@@ -16,12 +42,13 @@ export default class InteractionEvent {
|
|
|
16
42
|
/**
|
|
17
43
|
* @param {import("../view/layout/point.js").default} point Event coordinates
|
|
18
44
|
* inside the visualization canvas.
|
|
19
|
-
* @param {
|
|
45
|
+
* @param {InteractionUiEvent} uiEvent The event to be wrapped
|
|
20
46
|
*/
|
|
21
|
-
constructor(point: import("../view/layout/point.js").default, uiEvent:
|
|
47
|
+
constructor(point: import("../view/layout/point.js").default, uiEvent: InteractionUiEvent);
|
|
22
48
|
point: import("../view/layout/point.js").default;
|
|
23
|
-
uiEvent:
|
|
49
|
+
uiEvent: InteractionUiEvent;
|
|
24
50
|
stopped: boolean;
|
|
51
|
+
wheelClaimed: boolean;
|
|
25
52
|
/**
|
|
26
53
|
* The target is known only in the bubbling phase
|
|
27
54
|
*
|
|
@@ -29,6 +56,11 @@ export default class InteractionEvent {
|
|
|
29
56
|
*/
|
|
30
57
|
target: import("../view/view.js").default;
|
|
31
58
|
stopPropagation(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Marks the event as wheel-owned by the current interaction path.
|
|
61
|
+
* This is used by native wheel probes to decide preventDefault timing.
|
|
62
|
+
*/
|
|
63
|
+
claimWheel(): void;
|
|
32
64
|
/**
|
|
33
65
|
* The event type string of the underlying UI event (e.g. "click", "keydown").
|
|
34
66
|
*
|
|
@@ -41,4 +73,22 @@ export default class InteractionEvent {
|
|
|
41
73
|
get mouseEvent(): MouseEvent;
|
|
42
74
|
#private;
|
|
43
75
|
}
|
|
76
|
+
export type TouchGestureEvent = {
|
|
77
|
+
type: "touchgesture";
|
|
78
|
+
phase: "move" | "end";
|
|
79
|
+
pointerCount: 1 | 2;
|
|
80
|
+
xDelta: number;
|
|
81
|
+
yDelta: number;
|
|
82
|
+
zDelta: number;
|
|
83
|
+
preventDefault?: () => void;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Side-effect-free query event for wheel ownership. Handlers should only
|
|
87
|
+
* claim wheel if they would consume native wheel at the current pointer
|
|
88
|
+
* location.
|
|
89
|
+
*/
|
|
90
|
+
export type WheelClaimProbeEvent = {
|
|
91
|
+
type: "wheelclaimprobe";
|
|
92
|
+
};
|
|
93
|
+
export type InteractionUiEvent = UIEvent | TouchGestureEvent | WheelClaimProbeEvent;
|
|
44
94
|
//# sourceMappingURL=interactionEvent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactionEvent.d.ts","sourceRoot":"","sources":["../../../src/utils/interactionEvent.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"interactionEvent.d.ts","sourceRoot":"","sources":["../../../src/utils/interactionEvent.js"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;GAOG;AAEH;;GAEG;AAEH;;;GAGG;AACH,+CAHW,OAAO,GACL,SAAS,IAAI,iBAAiB,CAoB1C;AA4ED;;;;;;;GAOG;AACH,0CAFa,CAAC,UAFH,CAAC,GACC,CAAC,CA0Eb;AAzJD;;;;GAIG;AACH;IAII;;;;OAIG;IACH,mBAJW,OAAO,yBAAyB,EAAE,OAAO,WAEzC,kBAAkB,EAc5B;IAXG,iDAAkB;IAClB,4BAAsB;IACtB,iBAAoB;IACpB,sBAAyB;IAEzB;;;;OAIG;IACH,QAFU,OAAO,iBAAiB,EAAE,OAAO,CAEpB;IAG3B,wBAEC;IAED;;;OAGG;IACH,mBAMC;IAED;;;;;;OAMG;IACH,YAFa,MAAM,CAIlB;IAED,oCAQC;IAED,6BAMC;;CACJ;;UAtHS,cAAc;WACd,MAAM,GAAG,KAAK;kBACd,CAAC,GAAG,CAAC;YACL,MAAM;YACN,MAAM;YACN,MAAM;qBACN,MAAM,IAAI;;;;;;;;UASV,iBAAiB;;iCAId,OAAO,GAAG,iBAAiB,GAAG,oBAAoB"}
|
|
@@ -1,3 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {object} TouchGestureEvent
|
|
3
|
+
* @prop {"touchgesture"} type
|
|
4
|
+
* @prop {"move" | "end"} phase
|
|
5
|
+
* @prop {1 | 2} pointerCount
|
|
6
|
+
* @prop {number} xDelta
|
|
7
|
+
* @prop {number} yDelta
|
|
8
|
+
* @prop {number} zDelta
|
|
9
|
+
* @prop {() => void} [preventDefault]
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Side-effect-free query event for wheel ownership. Handlers should only
|
|
14
|
+
* claim wheel if they would consume native wheel at the current pointer
|
|
15
|
+
* location.
|
|
16
|
+
*
|
|
17
|
+
* @typedef {object} WheelClaimProbeEvent
|
|
18
|
+
* @prop {"wheelclaimprobe"} type
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {UIEvent | TouchGestureEvent | WheelClaimProbeEvent} InteractionUiEvent
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @param {unknown} eventLike
|
|
27
|
+
* @returns {eventLike is TouchGestureEvent}
|
|
28
|
+
*/
|
|
29
|
+
export function isTouchGestureEvent(eventLike) {
|
|
30
|
+
if (!eventLike || typeof eventLike !== "object") {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const candidate =
|
|
35
|
+
/** @type {{type?: unknown, phase?: unknown, pointerCount?: unknown, xDelta?: unknown, yDelta?: unknown, zDelta?: unknown}} */ (
|
|
36
|
+
eventLike
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
candidate.type === "touchgesture" &&
|
|
41
|
+
(candidate.phase === "move" || candidate.phase === "end") &&
|
|
42
|
+
(candidate.pointerCount === 1 || candidate.pointerCount === 2) &&
|
|
43
|
+
Number.isFinite(candidate.xDelta) &&
|
|
44
|
+
Number.isFinite(candidate.yDelta) &&
|
|
45
|
+
Number.isFinite(candidate.zDelta)
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
1
49
|
/**
|
|
2
50
|
* This class wraps a MouseEvent (or similar) and allows for
|
|
3
51
|
* its propagation through the view hierarchy in a similar manner
|
|
@@ -10,12 +58,13 @@ export default class InteractionEvent {
|
|
|
10
58
|
/**
|
|
11
59
|
* @param {import("../view/layout/point.js").default} point Event coordinates
|
|
12
60
|
* inside the visualization canvas.
|
|
13
|
-
* @param {
|
|
61
|
+
* @param {InteractionUiEvent} uiEvent The event to be wrapped
|
|
14
62
|
*/
|
|
15
63
|
constructor(point, uiEvent) {
|
|
16
64
|
this.point = point;
|
|
17
65
|
this.uiEvent = uiEvent;
|
|
18
66
|
this.stopped = false;
|
|
67
|
+
this.wheelClaimed = false;
|
|
19
68
|
|
|
20
69
|
/**
|
|
21
70
|
* The target is known only in the bubbling phase
|
|
@@ -29,6 +78,18 @@ export default class InteractionEvent {
|
|
|
29
78
|
this.stopped = true;
|
|
30
79
|
}
|
|
31
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Marks the event as wheel-owned by the current interaction path.
|
|
83
|
+
* This is used by native wheel probes to decide preventDefault timing.
|
|
84
|
+
*/
|
|
85
|
+
claimWheel() {
|
|
86
|
+
if (this.type !== "wheel" && this.type !== "wheelclaimprobe") {
|
|
87
|
+
throw new Error("Can claim wheel only for wheel events!");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
this.wheelClaimed = true;
|
|
91
|
+
}
|
|
92
|
+
|
|
32
93
|
/**
|
|
33
94
|
* The event type string of the underlying UI event (e.g. "click", "keydown").
|
|
34
95
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radixSort.d.ts","sourceRoot":"","sources":["../../../src/utils/radixSort.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"radixSort.d.ts","sourceRoot":"","sources":["../../../src/utils/radixSort.js"],"names":[],"mappings":"AAiBA;;GAEG;AACH,uCAFW,MAAM,EAAE,YA8DlB;AAeD;;GAEG;AACH,8CAFW,MAAM,EAAE,YA0DlB"}
|
|
@@ -3,12 +3,29 @@ const MAX_INTEGER_DIGIT = getDigits([MAX_INTEGER]);
|
|
|
3
3
|
|
|
4
4
|
// TODO: Optimize more! Some ideas: https://travisdowns.github.io/blog/2019/05/22/sorting.html
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @param {number[]} arr An array of unsigned integers
|
|
8
|
+
*/
|
|
9
|
+
function checkIfSorted(arr) {
|
|
10
|
+
for (let i = 1; i < arr.length; i++) {
|
|
11
|
+
if (arr[i] < arr[i - 1]) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
|
|
6
18
|
/**
|
|
7
19
|
* @param {number[]} arr An array of unsigned integers
|
|
8
20
|
*/
|
|
9
21
|
export default function radixSort(arr) {
|
|
10
22
|
const maxDigits = getDigits(arr);
|
|
11
23
|
|
|
24
|
+
// Early exit if already sorted
|
|
25
|
+
if (checkIfSorted(arr)) {
|
|
26
|
+
return arr;
|
|
27
|
+
}
|
|
28
|
+
|
|
12
29
|
let buffer = new Array(arr.length);
|
|
13
30
|
let bufferPtr = buffer;
|
|
14
31
|
const counts = new Array(16);
|
|
@@ -69,7 +86,9 @@ export default function radixSort(arr) {
|
|
|
69
86
|
function getDigits(arr) {
|
|
70
87
|
let max = 0;
|
|
71
88
|
for (let i = 0, n = arr.length; i < n; i++) {
|
|
72
|
-
|
|
89
|
+
if (arr[i] > max) {
|
|
90
|
+
max = arr[i];
|
|
91
|
+
}
|
|
73
92
|
}
|
|
74
93
|
return Math.floor(Math.log2(max) / 4) + 1;
|
|
75
94
|
}
|
|
@@ -80,6 +99,12 @@ function getDigits(arr) {
|
|
|
80
99
|
export function radixSortIntoLookupArray(arr) {
|
|
81
100
|
const maxDigits = getDigits(arr);
|
|
82
101
|
let indexes = Array.from({ length: arr.length }, (_, i) => i);
|
|
102
|
+
|
|
103
|
+
// Early exit if already sorted
|
|
104
|
+
if (checkIfSorted(arr)) {
|
|
105
|
+
return indexes;
|
|
106
|
+
}
|
|
107
|
+
|
|
83
108
|
let buffer = new Array(arr.length);
|
|
84
109
|
const counts = new Array(16);
|
|
85
110
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containerMutationHelper.d.ts","sourceRoot":"","sources":["../../../src/view/containerMutationHelper.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"containerMutationHelper.d.ts","sourceRoot":"","sources":["../../../src/view/containerMutationHelper.js"],"names":[],"mappings":"AAQA;;;GAGG;AACH;IACI;;;;;;;;;;OAUG;IAEH;;;;;;;;;;OAUG;IAEH;;;OAGG;IACH,uBAHW,OAAO,oBAAoB,EAAE,OAAO;uBAX3B;mBARR,CAAC,yEAAqB,CAAC,EAAE;sBACtB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,yEAAqB,KAAK,IAAI;sBACpD,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;SAMF;oBACnB,CAAC,IAAI,iEAAM,EAAE,KAAK,EAAE,MAAM,KAAK,GAAG;oBAClC,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;sBACrB,CAAC,IAAI,iEAAM,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC;sBAClE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;sBAChC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,yEAAqB,KAAK,MAAM;wBACpD,OAAO;OAW3B;IAFG,yFAA0B;IAC1B;uBAhBgB;mBARR,CAAC,yEAAqB,CAAC,EAAE;sBACtB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,yEAAqB,KAAK,IAAI;sBACpD,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;SAMF;oBACnB,CAAC,IAAI,iEAAM,EAAE,KAAK,EAAE,MAAM,KAAK,GAAG;oBAClC,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;sBACrB,CAAC,IAAI,iEAAM,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC;sBAClE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;sBAChC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,yEAAqB,KAAK,MAAM;wBACpD,OAAO;MAUF;IAG1B;;;;;;OAMG;IACH,wBAJW,OAAO,iBAAiB,EAAE,QAAQ,GAAG,OAAO,iBAAiB,EAAE,UAAU,UACzE,MAAM,GACJ,OAAO,iEAAM,CAqDzB;IAED;;;;OAIG;IACH,qBAFW,MAAM,iBAehB;CACJ"}
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
loadViewSubtreeData,
|
|
4
4
|
} from "../data/flowInit.js";
|
|
5
5
|
import { configureViewOpacity } from "../genomeSpy/viewHierarchyConfig.js";
|
|
6
|
+
import { ensureAssembliesForView } from "../genome/assemblyPreflight.js";
|
|
6
7
|
import { finalizeSubtreeGraphics } from "./viewUtils.js";
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -64,6 +65,13 @@ export default class ContainerMutationHelper {
|
|
|
64
65
|
name
|
|
65
66
|
);
|
|
66
67
|
|
|
68
|
+
// Reminder: ensure assemblies from the real child hierarchy before any
|
|
69
|
+
// downstream work that may initialize scales (axis prep / encoders).
|
|
70
|
+
await ensureAssembliesForView(
|
|
71
|
+
childView,
|
|
72
|
+
this.container.context.genomeStore
|
|
73
|
+
);
|
|
74
|
+
|
|
67
75
|
insertAt(insertIndex, childSpec);
|
|
68
76
|
const insertionResult = this.options.insertView(childView, insertIndex);
|
|
69
77
|
|
|
@@ -35,12 +35,12 @@ export function isSubtreeLazyReady(subtreeRoot: View, readinessRequest: DataRead
|
|
|
35
35
|
*
|
|
36
36
|
* @param {import("../types/viewContext.js").default} context
|
|
37
37
|
* @param {View} subtreeRoot
|
|
38
|
-
* @param {DataReadinessRequest} readinessRequest
|
|
38
|
+
* @param {DataReadinessRequest | undefined} readinessRequest
|
|
39
39
|
* @param {AbortSignal} [signal]
|
|
40
40
|
* @param {(view: View) => boolean} [viewFilter]
|
|
41
41
|
* @returns {Promise<void>}
|
|
42
42
|
*/
|
|
43
|
-
export function awaitSubtreeLazyReady(context: import("../types/viewContext.js").default, subtreeRoot: View, readinessRequest: DataReadinessRequest, signal?: AbortSignal, viewFilter?: (view: View) => boolean): Promise<void>;
|
|
43
|
+
export function awaitSubtreeLazyReady(context: import("../types/viewContext.js").default, subtreeRoot: View, readinessRequest: DataReadinessRequest | undefined, signal?: AbortSignal, viewFilter?: (view: View) => boolean): Promise<void>;
|
|
44
44
|
export type View = import("../view/view.js").default;
|
|
45
45
|
export type DataReadinessRequest = import("../data/sources/lazy/singleAxisLazySource.js").DataReadinessRequest;
|
|
46
46
|
//# sourceMappingURL=dataReadiness.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataReadiness.d.ts","sourceRoot":"","sources":["../../../src/view/dataReadiness.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dataReadiness.d.ts","sourceRoot":"","sources":["../../../src/view/dataReadiness.js"],"names":[],"mappings":"AAIA;;;GAGG;AAEH;;;;;;GAMG;AACH,4CAJW,IAAI,YACJ,OAAO,oBAAoB,EAAE,wBAAwB,EAAE,GACrD,oBAAoB,GAAG,SAAS,CAe5C;AAED;;;;;;;GAOG;AACH,4CALW,IAAI,oBACJ,oBAAoB,eACpB,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,GACrB,OAAO,CAiDnB;AAED;;;;;;;;GAQG;AACH,gDALW,IAAI,oBACJ,oBAAoB,GAAG,SAAS,eAChC,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,GACrB,OAAO,CAgBnB;AAED;;;;;;;;;;GAUG;AACH,+CAPW,OAAO,yBAAyB,EAAE,OAAO,eACzC,IAAI,oBACJ,oBAAoB,GAAG,SAAS,WAChC,WAAW,eACX,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,GACrB,OAAO,CAAC,IAAI,CAAC,CA0FzB;mBA/MY,OAAO,iBAAiB,EAAE,OAAO;mCACjC,OAAO,8CAA8C,EAAE,oBAAoB"}
|