@genome-spy/core 0.63.0 → 0.65.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/dist/bundle/{index-CCJIjehY.js → AbortablePromiseCache-CcuMrnn7.js} +22 -91
- package/dist/bundle/browser-txUcLy2H.js +123 -0
- package/dist/bundle/index-BQpbYrv4.js +1712 -0
- package/dist/bundle/index-BhtHKLUo.js +73 -0
- package/dist/bundle/index-C0llXMqm.js +280 -0
- package/dist/bundle/index-CCe8rnZz.js +716 -0
- package/dist/bundle/index-CD7FLu9x.js +269 -0
- package/dist/bundle/{index-C08YCM2T.js → index-D-w7Mmt9.js} +246 -126
- package/dist/bundle/index-D74H8TTz.js +508 -0
- package/dist/bundle/index-DhcU-Gk-.js +1487 -0
- package/dist/bundle/index.es.js +5394 -4989
- package/dist/bundle/index.js +420 -362
- package/dist/bundle/inflate-DRgHi_KK.js +1050 -0
- package/dist/schema.json +93 -13
- package/dist/src/data/collector.d.ts +7 -2
- package/dist/src/data/collector.d.ts.map +1 -1
- package/dist/src/data/collector.js +13 -2
- package/dist/src/data/dataFlow.d.ts +20 -42
- package/dist/src/data/dataFlow.d.ts.map +1 -1
- package/dist/src/data/dataFlow.js +57 -80
- package/dist/src/data/dataFlow.test.js +35 -2
- package/dist/src/data/flowHandle.d.ts +15 -0
- package/dist/src/data/flowHandle.d.ts.map +1 -0
- package/dist/src/data/flowHandle.js +13 -0
- package/dist/src/data/flowInit.d.ts +85 -0
- package/dist/src/data/flowInit.d.ts.map +1 -0
- package/dist/src/data/flowInit.js +238 -0
- package/dist/src/data/flowInit.test.d.ts +2 -0
- package/dist/src/data/flowInit.test.d.ts.map +1 -0
- package/dist/src/data/flowInit.test.js +413 -0
- package/dist/src/data/flowOptimizer.d.ts +6 -4
- package/dist/src/data/flowOptimizer.d.ts.map +1 -1
- package/dist/src/data/flowOptimizer.js +29 -14
- package/dist/src/data/flowOptimizer.test.js +20 -15
- package/dist/src/data/sources/lazy/bamSource.js +1 -1
- package/dist/src/data/sources/lazy/bigBedSource.js +1 -1
- package/dist/src/data/sources/lazy/bigWigSource.js +1 -1
- package/dist/src/data/sources/lazy/gff3Source.d.ts +2 -6
- package/dist/src/data/sources/lazy/gff3Source.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/gff3Source.js +4 -8
- package/dist/src/data/sources/lazy/indexedFastaSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/indexedFastaSource.js +17 -17
- package/dist/src/data/sources/lazy/tabixSource.js +1 -1
- package/dist/src/genomeSpy.d.ts +1 -1
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/genomeSpy.js +18 -61
- package/dist/src/gl/webGLHelper.d.ts.map +1 -1
- package/dist/src/gl/webGLHelper.js +8 -0
- package/dist/src/marks/link.fragment.glsl.js +1 -1
- package/dist/src/marks/link.vertex.glsl.js +1 -1
- package/dist/src/marks/mark.d.ts +1 -0
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +22 -1
- package/dist/src/marks/point.fragment.glsl.js +1 -1
- package/dist/src/marks/point.vertex.glsl.js +1 -1
- package/dist/src/marks/rect.fragment.glsl.js +1 -1
- package/dist/src/marks/rect.vertex.glsl.js +1 -1
- package/dist/src/marks/rule.fragment.glsl.js +1 -1
- package/dist/src/marks/rule.vertex.glsl.js +1 -1
- package/dist/src/marks/text.fragment.glsl.js +1 -1
- package/dist/src/marks/text.vertex.glsl.js +1 -1
- package/dist/src/selection/selection.d.ts +5 -0
- package/dist/src/selection/selection.d.ts.map +1 -1
- package/dist/src/selection/selection.js +43 -6
- package/dist/src/selection/selection.test.d.ts +2 -0
- package/dist/src/selection/selection.test.d.ts.map +1 -0
- package/dist/src/selection/selection.test.js +14 -0
- package/dist/src/spec/parameter.d.ts +28 -2
- package/dist/src/spec/sampleView.d.ts +3 -2
- package/dist/src/styles/{genome-spy.scss → genome-spy.css} +25 -21
- 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 +264 -195
- package/dist/src/styles/update.sh +14 -4
- package/dist/src/types/viewContext.d.ts +1 -1
- package/dist/src/utils/expression.d.ts +5 -0
- package/dist/src/utils/expression.d.ts.map +1 -1
- package/dist/src/utils/expression.js +37 -0
- package/dist/src/utils/interactionEvent.d.ts +18 -1
- package/dist/src/utils/interactionEvent.d.ts.map +1 -1
- package/dist/src/utils/interactionEvent.js +101 -1
- package/dist/src/utils/interactionEvent.test.d.ts +2 -0
- package/dist/src/utils/interactionEvent.test.d.ts.map +1 -0
- package/dist/src/utils/interactionEvent.test.js +35 -0
- package/dist/src/view/axisResolution.d.ts +5 -0
- package/dist/src/view/axisResolution.d.ts.map +1 -1
- package/dist/src/view/axisResolution.js +16 -1
- package/dist/src/view/facetView.d.ts +1 -1
- package/dist/src/view/facetView.d.ts.map +1 -1
- package/dist/src/view/facetView.js +1 -0
- package/dist/src/view/flowBuilder.d.ts +2 -2
- package/dist/src/view/flowBuilder.d.ts.map +1 -1
- package/dist/src/view/flowBuilder.js +21 -4
- package/dist/src/view/gridView/gridView.d.ts.map +1 -1
- package/dist/src/view/gridView/gridView.js +13 -0
- package/dist/src/view/gridView/selectionRect.d.ts +8 -4
- package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
- package/dist/src/view/gridView/selectionRect.js +28 -3
- package/dist/src/view/gridView/selectionRect.test.d.ts +2 -0
- package/dist/src/view/gridView/selectionRect.test.d.ts.map +1 -0
- package/dist/src/view/gridView/selectionRect.test.js +87 -0
- package/dist/src/view/paramMediator.d.ts +2 -1
- package/dist/src/view/paramMediator.d.ts.map +1 -1
- package/dist/src/view/paramMediator.js +13 -1
- package/dist/src/view/paramMediator.test.js +22 -0
- package/dist/src/view/scaleResolution.d.ts +5 -0
- package/dist/src/view/scaleResolution.d.ts.map +1 -1
- package/dist/src/view/scaleResolution.js +10 -0
- package/dist/src/view/testUtils.d.ts.map +1 -1
- package/dist/src/view/testUtils.js +16 -4
- package/dist/src/view/unitView.d.ts.map +1 -1
- package/dist/src/view/unitView.js +103 -10
- package/dist/src/view/view.d.ts +17 -1
- package/dist/src/view/view.d.ts.map +1 -1
- package/dist/src/view/view.js +57 -1
- package/dist/src/view/viewDispose.test.d.ts +2 -0
- package/dist/src/view/viewDispose.test.d.ts.map +1 -0
- package/dist/src/view/viewDispose.test.js +110 -0
- package/dist/src/view/viewUtils.d.ts +4 -4
- package/dist/src/view/viewUtils.d.ts.map +1 -1
- package/dist/src/view/viewUtils.js +19 -15
- package/dist/src/view/viewUtils.test.d.ts +2 -0
- package/dist/src/view/viewUtils.test.d.ts.map +1 -0
- package/dist/src/view/viewUtils.test.js +87 -0
- package/package.json +16 -16
- package/dist/bundle/__vite-browser-external-C--ziKoh.js +0 -8
- package/dist/bundle/_commonjsHelpers-DjF3Plf2.js +0 -26
- package/dist/bundle/index-5ajWdKly.js +0 -1319
- package/dist/bundle/index-B03-Om4z.js +0 -274
- package/dist/bundle/index-BftNdA0O.js +0 -27
- package/dist/bundle/index-Bg7C4Xat.js +0 -2750
- package/dist/bundle/index-C3QR8Lv6.js +0 -2131
- package/dist/bundle/index-DTcHjAHp.js +0 -505
- package/dist/bundle/index-DnIkxb0L.js +0 -1025
- package/dist/bundle/index-Ww3TAo6_.js +0 -71
- package/dist/bundle/index-g8iXgW0W.js +0 -651
- package/dist/bundle/long-B-FASCSo.js +0 -2387
- package/dist/bundle/remoteFile-BuaqFGWk.js +0 -94
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
import ConcatView from "../concatView.js";
|
|
4
|
+
import UnitView from "../unitView.js";
|
|
5
|
+
import SelectionRect from "./selectionRect.js";
|
|
6
|
+
import { createTestViewContext } from "../testUtils.js";
|
|
7
|
+
import { buildDataFlow } from "../flowBuilder.js";
|
|
8
|
+
import { optimizeDataFlow } from "../../data/flowOptimizer.js";
|
|
9
|
+
import { syncFlowHandles } from "../../data/flowInit.js";
|
|
10
|
+
|
|
11
|
+
describe("SelectionRect", () => {
|
|
12
|
+
it("uses flow handles for dynamic data updates", () => {
|
|
13
|
+
const context = createTestViewContext();
|
|
14
|
+
const parent = new ConcatView(
|
|
15
|
+
{ hconcat: [] },
|
|
16
|
+
context,
|
|
17
|
+
null,
|
|
18
|
+
null,
|
|
19
|
+
"p"
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
/** @type {import("../../spec/view.js").UnitSpec} */
|
|
23
|
+
const unitSpec = {
|
|
24
|
+
data: { values: [{ x: 0, y: 0 }] },
|
|
25
|
+
mark: "point",
|
|
26
|
+
encoding: {
|
|
27
|
+
x: { field: "x", type: "quantitative" },
|
|
28
|
+
y: { field: "y", type: "quantitative" },
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const unitView = new UnitView(unitSpec, context, parent, parent, "u");
|
|
33
|
+
|
|
34
|
+
let selection = {
|
|
35
|
+
intervals: { x: [0, 1], y: [2, 3] },
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** @type {(listener: () => void) => void} */
|
|
39
|
+
const addListener = () => undefined;
|
|
40
|
+
/** @type {(listener: () => void) => void} */
|
|
41
|
+
const removeListener = () => undefined;
|
|
42
|
+
/** @type {() => void} */
|
|
43
|
+
const invalidate = () => undefined;
|
|
44
|
+
|
|
45
|
+
/** @type {import("../paramMediator.js").ExprRefFunction} */
|
|
46
|
+
const selectionExpr = Object.assign(() => selection, {
|
|
47
|
+
addListener,
|
|
48
|
+
removeListener,
|
|
49
|
+
invalidate,
|
|
50
|
+
identifier: () => "selection",
|
|
51
|
+
fields: [],
|
|
52
|
+
globals: [],
|
|
53
|
+
code: "selection",
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const gridChild = /** @type {import("./gridChild.js").default} */ (
|
|
57
|
+
/** @type {unknown} */ ({
|
|
58
|
+
layoutParent: parent,
|
|
59
|
+
view: unitView,
|
|
60
|
+
})
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const selectionRect = new SelectionRect(gridChild, selectionExpr);
|
|
64
|
+
|
|
65
|
+
const flow = buildDataFlow(selectionRect, context.dataFlow);
|
|
66
|
+
syncFlowHandles(selectionRect, optimizeDataFlow(flow));
|
|
67
|
+
|
|
68
|
+
const dataSource =
|
|
69
|
+
/** @type {import("../../data/sources/inlineSource.js").default} */ (
|
|
70
|
+
selectionRect.flowHandle?.dataSource
|
|
71
|
+
);
|
|
72
|
+
expect(dataSource).toBeDefined();
|
|
73
|
+
|
|
74
|
+
// Selection updates should push new interval data to the inline source.
|
|
75
|
+
const updateSpy = vi.spyOn(dataSource, "updateDynamicData");
|
|
76
|
+
selection = {
|
|
77
|
+
intervals: { x: [5, 6], y: [7, 8] },
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
selectionRect._selectionListener();
|
|
81
|
+
|
|
82
|
+
expect(updateSpy).toHaveBeenCalledTimes(1);
|
|
83
|
+
expect(updateSpy).toHaveBeenCalledWith([
|
|
84
|
+
{ _x: 5, _x2: 6, _y: 7, _y2: 8 },
|
|
85
|
+
]);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
@@ -58,7 +58,7 @@ export function makeConstantExprRef(value: any): ExprRefFunction;
|
|
|
58
58
|
* TODO: The proposed JavaScript signals may provide a better way to implement this.
|
|
59
59
|
* https://github.com/proposal-signals/proposal-signals
|
|
60
60
|
*
|
|
61
|
-
* @typedef {import("../utils/expression.js").ExpressionFunction & { addListener: (listener: () => void) => void, invalidate: () => void, identifier: () => string}} ExprRefFunction
|
|
61
|
+
* @typedef {import("../utils/expression.js").ExpressionFunction & { addListener: (listener: () => void) => void, removeListener: (listener: () => void) => void, invalidate: () => void, identifier: () => string}} ExprRefFunction
|
|
62
62
|
*/
|
|
63
63
|
export default class ParamMediator {
|
|
64
64
|
/**
|
|
@@ -142,6 +142,7 @@ export default class ParamMediator {
|
|
|
142
142
|
*/
|
|
143
143
|
export type ExprRefFunction = import("../utils/expression.js").ExpressionFunction & {
|
|
144
144
|
addListener: (listener: () => void) => void;
|
|
145
|
+
removeListener: (listener: () => void) => void;
|
|
145
146
|
invalidate: () => void;
|
|
146
147
|
identifier: () => string;
|
|
147
148
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paramMediator.d.ts","sourceRoot":"","sources":["../../../src/view/paramMediator.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"paramMediator.d.ts","sourceRoot":"","sources":["../../../src/view/paramMediator.js"],"names":[],"mappings":"AA8VA;;;GAGG;AACH,6BAHW,GAAG,GACD,CAAC,IAAI,OAAO,sBAAsB,EAAE,OAAO,CAIvD;AAED;;;;;;;GAOG;AACH,+BAHa,CAAC,KADH,CAAC,GAAG,OAAO,sBAAsB,EAAE,OAAO,GAExC,CAAC,CAWb;AAED;;;GAGG;AACH,sFAFa,KAAK,IAAI,OAAO,sBAAsB,EAAE,iBAAiB,CAIrE;AAED;;;GAGG;AACH,uFAFa,KAAK,IAAI,OAAO,sBAAsB,EAAE,kBAAkB,CAItE;AAED;;;;;;;;;;GAUG;AACH,qCAF4E,CAAC,SAA/D,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,sBAAsB,EAAE,OAAO,CAAE,iBAJhE,aAAa,SACb,CAAC,aACD,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,IAAI,GAuCjB,CAAC,CACtB;AAED;;;;;;GAMG;AACH,4CAHW,MAAM,GACJ,MAAM,CAUlB;AAED;;;;;;;GAOG;AACH,2CAHW,GAAG,GACD,eAAe,CAY3B;AAldD;;;;;;;;GAQG;AACH;IA2BI;;;;;OAKG;IACH,2BALW,MAAM,aAAa,EAU7B;IA7BD;;;OAGG;IACH,0BAHU,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,CAGvB;IA2Bf;;;OAGG;IACH,wEAzCqB,GAAG,KAAK,IAAI,CA2GhC;IAED;;;;;;;OAOG;IACH,eAFa,CAAC,aAJH,MAAM,gBACN,CAAC,YACD,OAAO,GACL,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAgC9B;IAED;;;OAGG;IACH,qBAFW,MAAM,WA1Ic,GAAG,KAAK,IAAI,CAkJ1C;IAED;;;OAGG;IACH,oBAFW,MAAM,OAIhB;IAED;;;OAGG;IACH,qBAFW,MAAM,OAKhB;IAED;;OAEG;IACH,oBACsB,WAAW,CAAC,MAAM,2CAAY,CAGnD;IAED;;;;OAIG;IACH,gCAHW,MAAM,GACJ,aAAa,CAQzB;IAID;;;;OAIG;IACH,uBAFW,MAAM,mBAuFhB;IAED;;;;OAIG;IACH,qBAFW,MAAM,OAKhB;IAED;;;;;OAKG;IACH,sBAFa,OAAO,CAiBnB;;CACJ;;;;;;;;8BA1UY,OAAO,wBAAwB,EAAE,kBAAkB,GAAG;IAAE,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,MAAM,CAAA;CAAC"}
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
* TODO: The proposed JavaScript signals may provide a better way to implement this.
|
|
17
17
|
* https://github.com/proposal-signals/proposal-signals
|
|
18
18
|
*
|
|
19
|
-
* @typedef {import("../utils/expression.js").ExpressionFunction & { addListener: (listener: () => void) => void, invalidate: () => void, identifier: () => string}} ExprRefFunction
|
|
19
|
+
* @typedef {import("../utils/expression.js").ExpressionFunction & { addListener: (listener: () => void) => void, removeListener: (listener: () => void) => void, invalidate: () => void, identifier: () => string}} ExprRefFunction
|
|
20
20
|
*/
|
|
21
21
|
export default class ParamMediator {
|
|
22
22
|
/**
|
|
@@ -280,6 +280,16 @@ export default class ParamMediator {
|
|
|
280
280
|
}
|
|
281
281
|
};
|
|
282
282
|
|
|
283
|
+
/**
|
|
284
|
+
* @param {() => void} listener
|
|
285
|
+
*/
|
|
286
|
+
fn.removeListener = (listener) => {
|
|
287
|
+
for (const [param, mediator] of mediatorsForParams) {
|
|
288
|
+
mediator.paramListeners.get(param)?.delete(listener);
|
|
289
|
+
}
|
|
290
|
+
myListeners.delete(listener);
|
|
291
|
+
};
|
|
292
|
+
|
|
283
293
|
/**
|
|
284
294
|
* Detach listeners. This must be called if the expression is no longer used.
|
|
285
295
|
* TODO: What if the expression is used in multiple places?
|
|
@@ -290,6 +300,7 @@ export default class ParamMediator {
|
|
|
290
300
|
mediator.paramListeners.get(param)?.delete(listener);
|
|
291
301
|
}
|
|
292
302
|
}
|
|
303
|
+
myListeners.clear();
|
|
293
304
|
};
|
|
294
305
|
|
|
295
306
|
// TODO: This should contain unique identifier for each parameter.
|
|
@@ -457,6 +468,7 @@ export function validateParameterName(name) {
|
|
|
457
468
|
export function makeConstantExprRef(value) {
|
|
458
469
|
return Object.assign(() => value, {
|
|
459
470
|
addListener: () => /** @type {void} */ (undefined),
|
|
471
|
+
removeListener: () => /** @type {void} */ (undefined),
|
|
460
472
|
invalidate: () => /** @type {void} */ (undefined),
|
|
461
473
|
identifier: () => "constant",
|
|
462
474
|
fields: [],
|
|
@@ -87,6 +87,28 @@ describe("Single-level ParamMediator", () => {
|
|
|
87
87
|
expect(result).toBe(51);
|
|
88
88
|
});
|
|
89
89
|
|
|
90
|
+
test("Expression removeListener detaches a listener", () => {
|
|
91
|
+
const pm = new ParamMediator();
|
|
92
|
+
const setter = pm.allocateSetter("foo", 42);
|
|
93
|
+
const expr = pm.createExpression("foo + 1");
|
|
94
|
+
|
|
95
|
+
let calls = 0;
|
|
96
|
+
|
|
97
|
+
const listener = () => {
|
|
98
|
+
calls++;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
expr.addListener(listener);
|
|
102
|
+
|
|
103
|
+
setter(50);
|
|
104
|
+
expect(calls).toBe(1);
|
|
105
|
+
|
|
106
|
+
expr.removeListener(listener);
|
|
107
|
+
|
|
108
|
+
setter(60);
|
|
109
|
+
expect(calls).toBe(1);
|
|
110
|
+
});
|
|
111
|
+
|
|
90
112
|
test("Expression parameter handles dependencies", () => {
|
|
91
113
|
const pm = new ParamMediator();
|
|
92
114
|
const setter = pm.registerParam({ name: "foo", value: 42 });
|
|
@@ -66,6 +66,11 @@ export default class ScaleResolution implements ScaleResolutionApi {
|
|
|
66
66
|
* @param {ScaleResolutionMember} newMember
|
|
67
67
|
*/
|
|
68
68
|
addMember(newMember: ScaleResolutionMember): void;
|
|
69
|
+
/**
|
|
70
|
+
* @param {UnitView} view
|
|
71
|
+
* @returns {boolean}
|
|
72
|
+
*/
|
|
73
|
+
removeMembersByView(view: import("./unitView.js").default): boolean;
|
|
69
74
|
/**
|
|
70
75
|
* Extracts and unions the data domains of all participating views.
|
|
71
76
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaleResolution.d.ts","sourceRoot":"","sources":["../../../src/view/scaleResolution.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scaleResolution.d.ts","sourceRoot":"","sources":["../../../src/view/scaleResolution.js"],"names":[],"mappings":"AA6/BA;;;;;;;;;;GAUG;AACH,6CAFW,OAAO,WAAW,EAAE,OAAO,GAAG,OAAO,WAAW,EAAE,OAAO,EAAE,QA4BrE;AAr/BD,2BAA4B,cAAc,CAAC;AAC3C,sBAAuB,SAAS,CAAC;AACjC,sBAAuB,SAAS,CAAC;AACjC,oBAAqB,OAAO,CAAC;AAC7B,oBAAqB,OAAO,CAAC;AAE7B;;;;;;;;GAQG;AACH;;;;;;;GAOG;AACH;IA4CI;;OAEG;IACH,2DASC;IARG,8CAAsB;IACtB,yDAAyD;IACzD,SADW,qBAAqB,EAAE,CACjB;IACjB,0FAA0F;IAC1F,MADW,OAAO,oBAAoB,EAAE,IAAI,CAC5B;IAEhB,iEAAiE;IACjE,MADW,MAAM,CACI;IAWzB,2BAMC;IAED;;;;;;;OAOG;IACH,4KAEC;IAED;;;OAGG;IACH,+KAEC;IAcD;;;;;OAKG;IACH,qBAFW,qBAAqB,QAqD/B;IAED;;;OAGG;IACH,4DAFa,OAAO,CAMnB;IA8MD;;;;OAIG;IACH,+DAOC;IAED;;OAEG;IACH,oBA6CC;IAED;;OAEG;IACH;eA9akC,OAAO,kBAAkB,EAAE,KAAK;MAsdjE;IAED,mBAEC;IAED;;OAEG;IACH,oBAFa,mFAA6B,CAOzC;IAED;;;;OAIG;IACH,oBAKC;IAED;;OAEG;IACH,sBAGC;IAUD;;;;;;;OAOG;IACH,kBALW,MAAM,eACN,MAAM,OACN,MAAM,GACJ,OAAO,CAmEnB;IAED;;;;;;OAMG;IACH,eAJW,mFAA6B,aAC7B,OAAO,GAAG,MAAM,iBA0D1B;IAED;;;;OAIG;IACH,qBAcC;IAED;;;;;OAKG;IACH,uBAOC;IAED;;;;;;;OAOG;IACH,wBAoBC;IAiED;;;OAGG;IACH,aAFa,OAAO,qBAAqB,EAAE,OAAO,CAajD;IAID;;;;;OAKG;IACH,uBAFW,MAAM,yDAUhB;IAED;;OAEG;IACH,iBAFW,MAAM,yDAKhB;IAED;;;OAGG;IACH,qBAHW,MAAM,+CAAmB,GACvB,MAAM,CAQlB;IAED;;;OAGG;IACH,8BAHW,kFAA4B,GAC1B,MAAM,EAAE,CAOpB;;CACJ;kCA/2B+B,CAAC,SAApB,6CAAkB;;;;UAGrB,OAAO,eAAe,EAAE,OAAO;aAC/B,CAAC;gBACD,OAAO,oBAAoB,EAAE,mBAAmB;sBAChD,CAAC,OAAO,+CAAkB,EAAE,IAAI,EAAE,OAAO,oBAAoB,EAAE,IAAI,kDAAgB"}
|
|
@@ -231,6 +231,16 @@ export default class ScaleResolution {
|
|
|
231
231
|
this.members.push(newMember);
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
+
/**
|
|
235
|
+
* @param {UnitView} view
|
|
236
|
+
* @returns {boolean}
|
|
237
|
+
*/
|
|
238
|
+
removeMembersByView(view) {
|
|
239
|
+
const before = this.members.length;
|
|
240
|
+
this.members = this.members.filter((member) => member.view !== view);
|
|
241
|
+
return this.members.length !== before;
|
|
242
|
+
}
|
|
243
|
+
|
|
234
244
|
/**
|
|
235
245
|
* Returns true if the domain has been defined explicitly, i.e. not extracted from the data.
|
|
236
246
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../../../src/view/testUtils.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../../../src/view/testUtils.js"],"names":[],"mappings":"AAoBA;;;GAGG;AACH,2DAHW,OAAO,kBAAkB,EAAE,kBAAkB,6CAwDvD;AAGS,uBAAC,CAAC,SAAS,OAAO,WAAW,EAAE,OAAO,QAAQ,QAAQ,aAAa;IAAE,KAAI,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;CAAE,uBAAuB,OAAO,kBAAkB,EAAE,kBAAkB,GAAK,OAAO,CAAC,CAAC,CAAC,CAAA;AAgBhL,oCAAC,CAAC,SAAS,OAAO,WAAW,EAAE,OAAO,QAAQ,QAAQ,aAAa;IAAE,KAAI,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;CAAE,YAAY,WAAW,YAAY;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAC,GAAK,OAAO,CAAC,CAAC,CAAC,CAAA;;;;;uBA5FpL,OAAO,iBAAiB,EAAE,QAAQ;;;;;0BAClC,OAAO,yBAAyB,EAAE,OAAO"}
|
|
@@ -6,12 +6,15 @@
|
|
|
6
6
|
* @typedef {import("../types/viewContext.js").default} ViewContext
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { checkForDuplicateScaleNames
|
|
9
|
+
import { checkForDuplicateScaleNames } from "./viewUtils.js";
|
|
10
|
+
import {
|
|
11
|
+
initializeViewSubtree,
|
|
12
|
+
loadViewSubtreeData,
|
|
13
|
+
} from "../data/flowInit.js";
|
|
10
14
|
import DataFlow from "../data/dataFlow.js";
|
|
11
15
|
import { VIEW_ROOT_NAME, ViewFactory } from "./viewFactory.js";
|
|
12
16
|
import GenomeStore from "../genome/genomeStore.js";
|
|
13
17
|
import BmFontManager from "../fonts/bmFontManager.js";
|
|
14
|
-
import { reconfigureScales } from "./scaleResolution.js";
|
|
15
18
|
import UnitView from "./unitView.js";
|
|
16
19
|
import ContainerView from "./containerView.js";
|
|
17
20
|
|
|
@@ -56,6 +59,15 @@ export function createTestViewContext(viewFactoryOptions = {}) {
|
|
|
56
59
|
genomeStore,
|
|
57
60
|
|
|
58
61
|
fontManager: new BmFontManager(),
|
|
62
|
+
animator: /** @type {import("../utils/animator.js").default} */ (
|
|
63
|
+
/** @type {any} */ ({
|
|
64
|
+
requestRender: /** @type {() => void} */ (() => undefined),
|
|
65
|
+
requestTransition:
|
|
66
|
+
/** @type {(callback: () => void) => void} */ (
|
|
67
|
+
(callback) => callback()
|
|
68
|
+
),
|
|
69
|
+
})
|
|
70
|
+
),
|
|
59
71
|
|
|
60
72
|
isViewConfiguredVisible: () => true,
|
|
61
73
|
|
|
@@ -99,7 +111,7 @@ export async function createAndInitialize(spec, viewClass) {
|
|
|
99
111
|
});
|
|
100
112
|
}
|
|
101
113
|
|
|
102
|
-
|
|
103
|
-
|
|
114
|
+
const { dataSources } = initializeViewSubtree(view, view.context.dataFlow);
|
|
115
|
+
await loadViewSubtreeData(view, dataSources);
|
|
104
116
|
return view;
|
|
105
117
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unitView.d.ts","sourceRoot":"","sources":["../../../src/view/unitView.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"unitView.d.ts","sourceRoot":"","sources":["../../../src/view/unitView.js"],"names":[],"mappings":"AA6BA;;;;GAIG;AACH,wBAHU,MAAM,CAAC,OAAO,iBAAiB,EAAE,QAAQ,EAAE,cAAc,kBAAkB,EAAE,OAAO,CAAC,CAc7F;AAEF;IAeI;;;;;;;;OAQG;IACH,kBAPW,OAAO,iBAAiB,EAAE,QAAQ,WAClC,OAAO,yBAAyB,EAAE,OAAO,gBACzC,OAAO,oBAAoB,EAAE,OAAO,cACpC,OAAO,WAAW,EAAE,OAAO,QAC3B,MAAM,YACN,OAAO,WAAW,EAAE,WAAW,EAyCzC;IApCG,yCAAgB;IAIZ,iDAAiD;IACjD,MADW,OAAO,kBAAkB,EAAE,OAAO,CACnB;IAoKlC,2DAIC;IAgBD;;;;;OAKG;IAEH,iEAsHC;IAwCD;;;;;OAKG;IACH,4IAMC;IAkBD;;OAEG;IACH,uDAEC;IAED;;;;;;;;;;;;;OAaG;IACH,uEAHW,OAAO,oBAAoB,EAAE,IAAI,iDAqB3C;IAED,uBAQC;IAgBD;;;;OAIG;IACH,8BAJW,MAAM,+DAEJ,OAAO,iBAAiB,EAAE,kBAAkB,CAKxD;;CACJ;iBAlgBgB,WAAW"}
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
updateMultiPointSelection,
|
|
26
26
|
} from "../selection/selection.js";
|
|
27
27
|
import { UNIQUE_ID_KEY } from "../data/transforms/identifier.js";
|
|
28
|
+
import { createEventFilterFunction } from "../utils/expression.js";
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
31
|
*
|
|
@@ -87,14 +88,22 @@ export default class UnitView extends View {
|
|
|
87
88
|
"zoomLevel",
|
|
88
89
|
1.0
|
|
89
90
|
);
|
|
90
|
-
|
|
91
|
+
|
|
92
|
+
for (const channel of /** @type {import("../spec/channel.js").ChannelWithScale[]} */ ([
|
|
91
93
|
"x",
|
|
92
94
|
"y",
|
|
93
|
-
])
|
|
94
|
-
this.getScaleResolution(channel)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
])) {
|
|
96
|
+
const resolution = this.getScaleResolution(channel);
|
|
97
|
+
if (resolution) {
|
|
98
|
+
const listener = () => {
|
|
99
|
+
this.#zoomLevelSetter(Math.sqrt(this.getZoomLevel()));
|
|
100
|
+
};
|
|
101
|
+
resolution.addEventListener("domain", listener);
|
|
102
|
+
this.registerDisposer(() =>
|
|
103
|
+
resolution.removeEventListener("domain", listener)
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
98
107
|
|
|
99
108
|
this.needsAxes = { x: true, y: true };
|
|
100
109
|
|
|
@@ -108,6 +117,16 @@ export default class UnitView extends View {
|
|
|
108
117
|
}
|
|
109
118
|
|
|
110
119
|
const select = asSelectionConfig(param.select);
|
|
120
|
+
// Normalized config has eventConfig in "on"
|
|
121
|
+
const eventConfig =
|
|
122
|
+
/** @type {import("../spec/parameter.js").EventConfig} */ (
|
|
123
|
+
select.on
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
const clearEventConfig =
|
|
127
|
+
/** @type {import("../spec/parameter.js").EventConfig} */ (
|
|
128
|
+
select.clear
|
|
129
|
+
);
|
|
111
130
|
|
|
112
131
|
if (isPointSelectionConfig(select)) {
|
|
113
132
|
// Handle projection-free point selections
|
|
@@ -122,10 +141,17 @@ export default class UnitView extends View {
|
|
|
122
141
|
return h?.mark?.unitView === this ? h.datum : null;
|
|
123
142
|
};
|
|
124
143
|
|
|
144
|
+
const eventPredicate = eventConfig.filter
|
|
145
|
+
? createEventFilterFunction(eventConfig.filter)
|
|
146
|
+
: () => true;
|
|
147
|
+
|
|
125
148
|
const listener = (
|
|
126
149
|
/** @type {any} */ _,
|
|
127
150
|
/** @type {import("../utils/interactionEvent.js").default} */ event
|
|
128
151
|
) => {
|
|
152
|
+
if (!eventPredicate(event.proxiedMouseEvent)) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
129
155
|
const datum = getHoveredDatum();
|
|
130
156
|
const id = datum ? datum[UNIQUE_ID_KEY] : none;
|
|
131
157
|
|
|
@@ -164,11 +190,36 @@ export default class UnitView extends View {
|
|
|
164
190
|
};
|
|
165
191
|
|
|
166
192
|
this.addInteractionEventListener(
|
|
167
|
-
["mouseover", "pointerover"].includes(
|
|
193
|
+
["mouseover", "pointerover"].includes(eventConfig.type)
|
|
168
194
|
? "mousemove"
|
|
169
|
-
:
|
|
195
|
+
: eventConfig.type,
|
|
170
196
|
listener
|
|
171
197
|
);
|
|
198
|
+
|
|
199
|
+
if (clearEventConfig) {
|
|
200
|
+
const clearPredicate = clearEventConfig.filter
|
|
201
|
+
? createEventFilterFunction(clearEventConfig.filter)
|
|
202
|
+
: () => true;
|
|
203
|
+
|
|
204
|
+
const clearListener = (
|
|
205
|
+
/** @type {any} */ _,
|
|
206
|
+
/** @type {import("../utils/interactionEvent.js").default} */ event
|
|
207
|
+
) => {
|
|
208
|
+
if (!clearPredicate(event.proxiedMouseEvent)) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
lastId = none;
|
|
212
|
+
const selection = select.toggle
|
|
213
|
+
? createMultiPointSelection()
|
|
214
|
+
: createSinglePointSelection(null);
|
|
215
|
+
setter(selection);
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
this.addInteractionEventListener(
|
|
219
|
+
clearEventConfig.type,
|
|
220
|
+
clearListener
|
|
221
|
+
);
|
|
222
|
+
}
|
|
172
223
|
}
|
|
173
224
|
}
|
|
174
225
|
}
|
|
@@ -337,6 +388,44 @@ export default class UnitView extends View {
|
|
|
337
388
|
}
|
|
338
389
|
}
|
|
339
390
|
|
|
391
|
+
/**
|
|
392
|
+
* @override
|
|
393
|
+
*/
|
|
394
|
+
dispose() {
|
|
395
|
+
super.dispose();
|
|
396
|
+
|
|
397
|
+
this.#unresolve();
|
|
398
|
+
this.mark.dispose();
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
#unresolve() {
|
|
402
|
+
for (const view of this.getDataAncestors()) {
|
|
403
|
+
for (const [channel, resolution] of Object.entries(
|
|
404
|
+
view.resolutions.scale
|
|
405
|
+
)) {
|
|
406
|
+
if (
|
|
407
|
+
resolution &&
|
|
408
|
+
resolution.removeMembersByView(this) &&
|
|
409
|
+
resolution.members.length === 0
|
|
410
|
+
) {
|
|
411
|
+
delete view.resolutions.scale[channel];
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
for (const [channel, resolution] of Object.entries(
|
|
416
|
+
view.resolutions.axis
|
|
417
|
+
)) {
|
|
418
|
+
if (
|
|
419
|
+
resolution &&
|
|
420
|
+
resolution.removeMembersByView(this) &&
|
|
421
|
+
resolution.members.length === 0
|
|
422
|
+
) {
|
|
423
|
+
delete view.resolutions.axis[channel];
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
340
429
|
/**
|
|
341
430
|
* Returns an accessor that accesses a field or an evaluated expression,
|
|
342
431
|
* if there is one.
|
|
@@ -344,7 +433,11 @@ export default class UnitView extends View {
|
|
|
344
433
|
* @param {Channel} channel
|
|
345
434
|
*/
|
|
346
435
|
getDataAccessor(channel) {
|
|
347
|
-
|
|
436
|
+
const encoders = this.mark.encoders;
|
|
437
|
+
if (!encoders) {
|
|
438
|
+
return undefined;
|
|
439
|
+
}
|
|
440
|
+
return encoders[channel]?.dataAccessor;
|
|
348
441
|
}
|
|
349
442
|
|
|
350
443
|
/**
|
|
@@ -367,7 +460,7 @@ export default class UnitView extends View {
|
|
|
367
460
|
* Returns a collector that is associated with this view.
|
|
368
461
|
*/
|
|
369
462
|
getCollector() {
|
|
370
|
-
return this.
|
|
463
|
+
return this.flowHandle?.collector;
|
|
371
464
|
}
|
|
372
465
|
|
|
373
466
|
/**
|
package/dist/src/view/view.d.ts
CHANGED
|
@@ -90,6 +90,10 @@ export default class View {
|
|
|
90
90
|
*/
|
|
91
91
|
layersChildren?: boolean;
|
|
92
92
|
};
|
|
93
|
+
/**
|
|
94
|
+
* @type {import("../data/flowHandle.js").FlowHandle | undefined}
|
|
95
|
+
*/
|
|
96
|
+
flowHandle: import("../data/flowHandle.js").FlowHandle | undefined;
|
|
93
97
|
/**
|
|
94
98
|
* Whether GridView or equivalent should draw axis and grid lines for this view.
|
|
95
99
|
* TODO: Use view options for this.
|
|
@@ -210,9 +214,21 @@ export default class View {
|
|
|
210
214
|
*/
|
|
211
215
|
visit(visitor: Visitor): VisitResult;
|
|
212
216
|
/**
|
|
213
|
-
* Get
|
|
217
|
+
* Get this view and all descendants in depth-first order.
|
|
214
218
|
*/
|
|
215
219
|
getDescendants(): View[];
|
|
220
|
+
/**
|
|
221
|
+
* Release resources owned by this view.
|
|
222
|
+
*/
|
|
223
|
+
dispose(): void;
|
|
224
|
+
/**
|
|
225
|
+
* @param {() => void} disposer
|
|
226
|
+
*/
|
|
227
|
+
registerDisposer(disposer: () => void): void;
|
|
228
|
+
/**
|
|
229
|
+
* Dispose this view and all descendants in post-order.
|
|
230
|
+
*/
|
|
231
|
+
disposeSubtree(): void;
|
|
216
232
|
/**
|
|
217
233
|
* Called after all scales in the view hierarchy have been resolved.
|
|
218
234
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/view/view.js"],"names":[],"mappings":"AA2BA,oBAAoB;AACpB,yBAA0B,YAAY,CAAC;AACvC,0BAA0B;AAC1B,yBAA0B,YAAY,CAAC;AAKvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH;
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/view/view.js"],"names":[],"mappings":"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"}
|
package/dist/src/view/view.js
CHANGED
|
@@ -86,6 +86,11 @@ export default class View {
|
|
|
86
86
|
*/
|
|
87
87
|
opacityFunction = defaultOpacityFunction;
|
|
88
88
|
|
|
89
|
+
/**
|
|
90
|
+
* @type {(() => void)[]}
|
|
91
|
+
*/
|
|
92
|
+
#disposers = [];
|
|
93
|
+
|
|
89
94
|
/**
|
|
90
95
|
* Coords of the view for each facet, recorded during the last layout rendering pass.
|
|
91
96
|
* Most views have only one facet, so the map is usually of size 1.
|
|
@@ -136,6 +141,11 @@ export default class View {
|
|
|
136
141
|
...options,
|
|
137
142
|
};
|
|
138
143
|
|
|
144
|
+
/**
|
|
145
|
+
* @type {import("../data/flowHandle.js").FlowHandle | undefined}
|
|
146
|
+
*/
|
|
147
|
+
this.flowHandle = undefined;
|
|
148
|
+
|
|
139
149
|
/**
|
|
140
150
|
* Whether GridView or equivalent should draw axis and grid lines for this view.
|
|
141
151
|
* TODO: Use view options for this.
|
|
@@ -497,7 +507,7 @@ export default class View {
|
|
|
497
507
|
}
|
|
498
508
|
|
|
499
509
|
/**
|
|
500
|
-
* Get
|
|
510
|
+
* Get this view and all descendants in depth-first order.
|
|
501
511
|
*/
|
|
502
512
|
getDescendants() {
|
|
503
513
|
/** @type {View[]} */
|
|
@@ -508,6 +518,52 @@ export default class View {
|
|
|
508
518
|
return descendants;
|
|
509
519
|
}
|
|
510
520
|
|
|
521
|
+
/**
|
|
522
|
+
* Release resources owned by this view.
|
|
523
|
+
*/
|
|
524
|
+
dispose() {
|
|
525
|
+
for (const disposer of this.#disposers) {
|
|
526
|
+
disposer();
|
|
527
|
+
}
|
|
528
|
+
this.#disposers.length = 0;
|
|
529
|
+
|
|
530
|
+
const handle = this.flowHandle;
|
|
531
|
+
|
|
532
|
+
if (handle?.collector) {
|
|
533
|
+
this.context.dataFlow.pruneCollectorBranch(handle.collector);
|
|
534
|
+
this.context.dataFlow.removeCollector(handle.collector);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
if (
|
|
538
|
+
handle?.dataSource &&
|
|
539
|
+
handle.dataSource.view === this &&
|
|
540
|
+
!handle.dataSource.identifier
|
|
541
|
+
) {
|
|
542
|
+
this.context.dataFlow.removeDataSource(handle.dataSource);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
this.flowHandle = undefined;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* @param {() => void} disposer
|
|
550
|
+
*/
|
|
551
|
+
registerDisposer(disposer) {
|
|
552
|
+
this.#disposers.push(disposer);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Dispose this view and all descendants in post-order.
|
|
557
|
+
*/
|
|
558
|
+
disposeSubtree() {
|
|
559
|
+
/** @type {Visitor} */
|
|
560
|
+
const visitor = () => undefined;
|
|
561
|
+
visitor.postOrder = (view) => {
|
|
562
|
+
view.dispose();
|
|
563
|
+
};
|
|
564
|
+
this.visit(visitor);
|
|
565
|
+
}
|
|
566
|
+
|
|
511
567
|
/**
|
|
512
568
|
* Called after all scales in the view hierarchy have been resolved.
|
|
513
569
|
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewDispose.test.d.ts","sourceRoot":"","sources":["../../../src/view/viewDispose.test.js"],"names":[],"mappings":""}
|