@genome-spy/core 0.60.1 → 0.61.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle/index.es.js +5139 -4960
- package/dist/bundle/index.js +110 -110
- package/dist/schema.json +1668 -82
- package/dist/src/data/sources/lazy/gff3Source.d.ts +1 -3
- package/dist/src/data/sources/lazy/gff3Source.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/vcfSource.d.ts.map +1 -1
- package/dist/src/data/transforms/filter.d.ts.map +1 -1
- package/dist/src/data/transforms/filter.js +7 -1
- package/dist/src/encoder/accessor.d.ts.map +1 -1
- package/dist/src/encoder/accessor.js +6 -1
- package/dist/src/encoder/accessor.test.js +2 -1
- package/dist/src/encoder/encoder.d.ts +1 -1
- package/dist/src/encoder/encoder.d.ts.map +1 -1
- package/dist/src/encoder/encoder.js +58 -3
- package/dist/src/encoder/encoder.test.js +2 -1
- package/dist/src/gl/webGLHelper.d.ts +2 -2
- package/dist/src/gl/webGLHelper.d.ts.map +1 -1
- package/dist/src/gl/webGLHelper.js +4 -4
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +8 -20
- package/dist/src/marks/markUtils.d.ts.map +1 -1
- package/dist/src/marks/markUtils.js +26 -16
- package/dist/src/marks/point.d.ts.map +1 -1
- package/dist/src/marks/point.js +6 -0
- package/dist/src/selection/selection.d.ts +4 -10
- package/dist/src/selection/selection.d.ts.map +1 -1
- package/dist/src/selection/selection.js +63 -23
- package/dist/src/spec/transform.d.ts +8 -0
- package/dist/src/tooltip/refseqGeneTooltipHandler.js +60 -21
- package/dist/src/types/encoder.d.ts +4 -0
- package/dist/src/types/selectionTypes.d.ts +6 -2
- package/dist/src/utils/binnedIndex.d.ts.map +1 -1
- package/dist/src/utils/binnedIndex.js +0 -17
- package/dist/src/utils/expression.d.ts.map +1 -1
- package/dist/src/utils/expression.js +3 -2
- package/dist/src/utils/interactionEvent.d.ts +1 -0
- package/dist/src/utils/interactionEvent.d.ts.map +1 -1
- package/dist/src/utils/interactionEvent.js +8 -0
- package/dist/src/utils/mergeObjects.d.ts +0 -2
- package/dist/src/utils/mergeObjects.d.ts.map +1 -1
- package/dist/src/utils/mergeObjects.js +5 -3
- package/dist/src/utils/throttle.d.ts +1 -1
- package/dist/src/utils/throttle.d.ts.map +1 -1
- package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
- package/dist/src/view/gridView/gridChild.js +4 -6
- package/dist/src/view/gridView/scrollbar.d.ts.map +1 -1
- package/dist/src/view/gridView/scrollbar.js +2 -3
- package/dist/src/view/gridView/selectionRect.d.ts +4 -0
- package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
- package/dist/src/view/gridView/selectionRect.js +11 -13
- package/dist/src/view/scaleResolution.d.ts.map +1 -1
- package/dist/src/view/scaleResolution.js +7 -0
- package/dist/src/view/unitView.d.ts.map +1 -1
- package/dist/src/view/unitView.js +31 -10
- package/dist/src/view/view.test.js +6 -4
- package/dist/src/view/viewFactory.test.js +2 -2
- package/dist/src/view/zoom.d.ts.map +1 -1
- package/dist/src/view/zoom.js +2 -5
- package/package.json +7 -7
|
@@ -7,18 +7,31 @@ import { html } from "lit";
|
|
|
7
7
|
* TODO: Implement tool & email parameters: https://www.ncbi.nlm.nih.gov/books/NBK25497/
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
// TODO: Replace with an LRU-cache
|
|
11
10
|
const symbolSummaryCache = new Map();
|
|
12
11
|
|
|
12
|
+
const defaultParams = {
|
|
13
|
+
Organism: "Homo sapiens",
|
|
14
|
+
};
|
|
15
|
+
|
|
13
16
|
/**
|
|
14
17
|
* @type {import("./tooltipHandler.js").TooltipHandler}
|
|
15
18
|
*/
|
|
16
|
-
export default async function refseqGeneTooltipHandler(
|
|
19
|
+
export default async function refseqGeneTooltipHandler(
|
|
20
|
+
datum,
|
|
21
|
+
mark,
|
|
22
|
+
params = {}
|
|
23
|
+
) {
|
|
17
24
|
const symbol = datum.symbol;
|
|
18
25
|
|
|
26
|
+
const term = {
|
|
27
|
+
...defaultParams,
|
|
28
|
+
...params,
|
|
29
|
+
GENE: symbol,
|
|
30
|
+
};
|
|
31
|
+
|
|
19
32
|
let summary =
|
|
20
33
|
symbolSummaryCache.get(symbol) ??
|
|
21
|
-
(await debouncedFetchGeneSummary(
|
|
34
|
+
(await debouncedFetchGeneSummary(term));
|
|
22
35
|
|
|
23
36
|
if (summary) {
|
|
24
37
|
symbolSummaryCache.set(symbol, summary);
|
|
@@ -36,29 +49,43 @@ export default async function refseqGeneTooltipHandler(datum, mark, params) {
|
|
|
36
49
|
}
|
|
37
50
|
|
|
38
51
|
/**
|
|
39
|
-
* @param {string}
|
|
52
|
+
* @param {Record<string, string>} term
|
|
40
53
|
*/
|
|
41
|
-
async function fetchGeneSummary(
|
|
42
|
-
// TODO: Add more search terms to ensure that we really find genes specific to the current genome
|
|
43
|
-
|
|
44
|
-
console.log("Searching: " + symbol);
|
|
45
|
-
|
|
54
|
+
async function fetchGeneSummary(term) {
|
|
46
55
|
/** @type {RequestInit} */
|
|
47
56
|
const opts = { mode: "cors" };
|
|
48
57
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
const url = new URL(
|
|
59
|
+
"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
|
|
60
|
+
);
|
|
61
|
+
url.search = new URLSearchParams({
|
|
62
|
+
db: "gene",
|
|
63
|
+
term: termToQuery(term),
|
|
64
|
+
sort: "relevance",
|
|
65
|
+
retmax: "1",
|
|
66
|
+
retmode: "json",
|
|
67
|
+
}).toString();
|
|
68
|
+
|
|
69
|
+
const searchResult = await fetch(url.toString(), opts).then((res) =>
|
|
70
|
+
res.json()
|
|
71
|
+
);
|
|
53
72
|
|
|
54
73
|
// TODO: Handle failed searchs
|
|
55
74
|
const id = searchResult.esearchresult.idlist[0];
|
|
56
75
|
|
|
57
76
|
if (id) {
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
77
|
+
const summaryUrl = new URL(
|
|
78
|
+
"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi"
|
|
79
|
+
);
|
|
80
|
+
summaryUrl.search = new URLSearchParams({
|
|
81
|
+
db: "gene",
|
|
82
|
+
id: id,
|
|
83
|
+
retmode: "json",
|
|
84
|
+
}).toString();
|
|
85
|
+
|
|
86
|
+
const summaryResult = await fetch(summaryUrl.toString(), opts).then(
|
|
87
|
+
(res) => res.json()
|
|
88
|
+
);
|
|
62
89
|
|
|
63
90
|
const summary = summaryResult.result[id];
|
|
64
91
|
return summary;
|
|
@@ -70,9 +97,21 @@ async function fetchGeneSummary(symbol) {
|
|
|
70
97
|
const debounced = debounce(fetchGeneSummary, 500);
|
|
71
98
|
|
|
72
99
|
/**
|
|
73
|
-
*
|
|
74
|
-
|
|
100
|
+
* @param {Record<string, string>} term
|
|
101
|
+
*/
|
|
102
|
+
function debouncedFetchGeneSummary(term) {
|
|
103
|
+
return debounced(term);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @param {Record<string, string>} term
|
|
75
108
|
*/
|
|
76
|
-
function
|
|
77
|
-
return
|
|
109
|
+
function termToQuery(term) {
|
|
110
|
+
return (
|
|
111
|
+
Object.entries(term)
|
|
112
|
+
.filter(([_, value]) => value && value.length > 0)
|
|
113
|
+
// TODO: Escape
|
|
114
|
+
.map(([key, value]) => `("${value}"[${key}])`)
|
|
115
|
+
.join(" AND ")
|
|
116
|
+
);
|
|
78
117
|
}
|
|
@@ -82,6 +82,10 @@ export interface Predicate extends ExprRefFunction {
|
|
|
82
82
|
* Wraps one or more accessors, uses an optional scale to encode the data.
|
|
83
83
|
*/
|
|
84
84
|
export interface Encoder {
|
|
85
|
+
/**
|
|
86
|
+
* Returns an encoded value for the given datum.
|
|
87
|
+
* If the encoder has a scale, the value is passed through the scale function.
|
|
88
|
+
*/
|
|
85
89
|
(datum: Datum): Scalar;
|
|
86
90
|
|
|
87
91
|
/**
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { Datum } from "../data/flowNode.js";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
ChannelWithScale,
|
|
4
|
+
PositionalChannel,
|
|
5
|
+
Scalar,
|
|
6
|
+
} from "../spec/channel.js";
|
|
3
7
|
|
|
4
8
|
export interface SelectionBase {
|
|
5
9
|
type: string;
|
|
@@ -8,7 +12,7 @@ export interface SelectionBase {
|
|
|
8
12
|
export interface IntervalSelection extends SelectionBase {
|
|
9
13
|
type: "interval";
|
|
10
14
|
|
|
11
|
-
intervals: Partial<Record<
|
|
15
|
+
intervals: Partial<Record<PositionalChannel, number[] | null>>;
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
export interface ProjectedSelection extends SelectionBase {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binnedIndex.d.ts","sourceRoot":"","sources":["../../../src/utils/binnedIndex.js"],"names":[],"mappings":"AAKA;;;;;;GAMG;AAEH;;;;;;;;;;;GAWG;AACH,0CAFa,CAAC,QAJH,MAAM,UACN,CAAC,MAAM,EAAE,MAAM,CAAC,YAChB,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,cACpB,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM;YA0ChB,CAAC,oBACD,MAAM,kBACN,MAAM;
|
|
1
|
+
{"version":3,"file":"binnedIndex.d.ts","sourceRoot":"","sources":["../../../src/utils/binnedIndex.js"],"names":[],"mappings":"AAKA;;;;;;GAMG;AAEH;;;;;;;;;;;GAWG;AACH,0CAFa,CAAC,QAJH,MAAM,UACN,CAAC,MAAM,EAAE,MAAM,CAAC,YAChB,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,cACpB,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM;YA0ChB,CAAC,oBACD,MAAM,kBACN,MAAM;oBAqGJ,MAAM;EA+BtB;6BA/LU,MAAM,OACN,MAAM,QACN,CAAC,MAAM,EAAE,MAAM,CAAC,KACd,CAAC,MAAM,EAAE,MAAM,CAAC"}
|
|
@@ -75,10 +75,6 @@ export function createBinningRangeIndexer(
|
|
|
75
75
|
lastIndex = startVertexIndex;
|
|
76
76
|
} else {
|
|
77
77
|
unordered = true;
|
|
78
|
-
// TODO: Contextual info like view path
|
|
79
|
-
console.debug(
|
|
80
|
-
"Items are not ordered properly. Disabling binned index."
|
|
81
|
-
);
|
|
82
78
|
return;
|
|
83
79
|
}
|
|
84
80
|
|
|
@@ -86,10 +82,6 @@ export function createBinningRangeIndexer(
|
|
|
86
82
|
|
|
87
83
|
if (value < lastStart) {
|
|
88
84
|
unordered = true;
|
|
89
|
-
// TODO: Contextual info like view path
|
|
90
|
-
console.debug(
|
|
91
|
-
"Items are not ordered properly. Disabling binned index."
|
|
92
|
-
);
|
|
93
85
|
return;
|
|
94
86
|
}
|
|
95
87
|
lastStart = value;
|
|
@@ -133,18 +125,9 @@ export function createBinningRangeIndexer(
|
|
|
133
125
|
|
|
134
126
|
if (start < lastStart) {
|
|
135
127
|
unordered = true;
|
|
136
|
-
// TODO: Contextual info like view path
|
|
137
|
-
console.debug(
|
|
138
|
-
"Items are not ordered properly. Disabling binned index."
|
|
139
|
-
);
|
|
140
128
|
return;
|
|
141
129
|
} else if (end < start) {
|
|
142
130
|
unordered = true;
|
|
143
|
-
// TODO: Contextual info like view path
|
|
144
|
-
console.debug(
|
|
145
|
-
"End index is less than start index. Disabling binned index. Datum: ",
|
|
146
|
-
datum
|
|
147
|
-
);
|
|
148
131
|
return;
|
|
149
132
|
}
|
|
150
133
|
lastStart = start;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../../src/utils/expression.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../../src/utils/expression.js"],"names":[],"mappings":"AAuEA;;;;;;;;;;GAUG;AACH,6CAHW,MAAM,sBACJ,kBAAkB,CAgC9B;;YAvCU,MAAM,EAAE;aACR,MAAM,EAAE;UACR,MAAM;;iCAEH,CAAC,CAAC,KAAK,CAAC,EAAE,OAAO,qBAAqB,EAAE,KAAK,KAAK,GAAG,CAAC,GAAG,eAAe"}
|
|
@@ -12,7 +12,6 @@ import { format as d3format } from "d3-format";
|
|
|
12
12
|
import smoothstep from "./smoothstep.js";
|
|
13
13
|
import clamp from "./clamp.js";
|
|
14
14
|
import linearstep from "./linearstep.js";
|
|
15
|
-
import { selectionTest } from "../selection/selection.js";
|
|
16
15
|
|
|
17
16
|
/**
|
|
18
17
|
* Some bits are adapted from https://github.com/vega/vega/blob/main/packages/vega-functions/src/codegen.js
|
|
@@ -22,6 +21,9 @@ const functionContext = {
|
|
|
22
21
|
format(/** @type {number} */ value, /** @type {string} */ format) {
|
|
23
22
|
return d3format(format)(value);
|
|
24
23
|
},
|
|
24
|
+
mapHasKey(/** @type {Map<any, any>} */ map, /** @type {any} */ key) {
|
|
25
|
+
return map.has(key);
|
|
26
|
+
},
|
|
25
27
|
isArray,
|
|
26
28
|
isBoolean,
|
|
27
29
|
isDefined(/** @type {any} */ _) {
|
|
@@ -45,7 +47,6 @@ const functionContext = {
|
|
|
45
47
|
return String(str).replace(pattern, replace);
|
|
46
48
|
},
|
|
47
49
|
smoothstep,
|
|
48
|
-
selectionTest,
|
|
49
50
|
};
|
|
50
51
|
|
|
51
52
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactionEvent.d.ts","sourceRoot":"","sources":["../../../src/utils/interactionEvent.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH;IACI;;;;;OAKG;IACH,mBAJW,OAAO,yBAAyB,EAAE,OAAO,WAEzC,OAAO,EAajB;IAVG,iDAAkB;IAClB,iBAAsB;IACtB,iBAAoB;IAEpB;;;;OAIG;IACH,QAFU,OAAO,iBAAiB,EAAE,OAAO,CAEpB;IAG3B,wBAEC;IAED,mBAEC;CACJ"}
|
|
1
|
+
{"version":3,"file":"interactionEvent.d.ts","sourceRoot":"","sources":["../../../src/utils/interactionEvent.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH;IACI;;;;;OAKG;IACH,mBAJW,OAAO,yBAAyB,EAAE,OAAO,WAEzC,OAAO,EAajB;IAVG,iDAAkB;IAClB,iBAAsB;IACtB,iBAAoB;IAEpB;;;;OAIG;IACH,QAFU,OAAO,iBAAiB,EAAE,OAAO,CAEpB;IAG3B,wBAEC;IAED,mBAEC;IAED,6BAMC;CACJ"}
|
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* A boolean true and an object are compatible. The object survives, the boolean is overwritten.
|
|
5
5
|
*
|
|
6
|
-
* TODO: Support arrays. Should accept identical arrays and complain about others.
|
|
7
|
-
*
|
|
8
6
|
* @param {T[]} objects Objects to merge
|
|
9
7
|
* @param {string} propertyOf What are we merging? Used in warning messages
|
|
10
8
|
* @param {string[]} [skip] Fields to skip. TODO: Support nested fields.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mergeObjects.d.ts","sourceRoot":"","sources":["../../../src/utils/mergeObjects.js"],"names":[],"mappings":"AAGA
|
|
1
|
+
{"version":3,"file":"mergeObjects.d.ts","sourceRoot":"","sources":["../../../src/utils/mergeObjects.js"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,qCAFa,CAAC,WAJF,CAAC,EAAE,cACJ,MAAM,SACN,MAAM,EAAE,GACN,CAAC,CAiFb"}
|
|
@@ -6,8 +6,6 @@ import { isObject } from "vega-util";
|
|
|
6
6
|
*
|
|
7
7
|
* A boolean true and an object are compatible. The object survives, the boolean is overwritten.
|
|
8
8
|
*
|
|
9
|
-
* TODO: Support arrays. Should accept identical arrays and complain about others.
|
|
10
|
-
*
|
|
11
9
|
* @param {T[]} objects Objects to merge
|
|
12
10
|
* @param {string} propertyOf What are we merging? Used in warning messages
|
|
13
11
|
* @param {string[]} [skip] Fields to skip. TODO: Support nested fields.
|
|
@@ -34,7 +32,11 @@ export default function mergeObjects(objects, propertyOf, skip) {
|
|
|
34
32
|
a === b ||
|
|
35
33
|
(isPlainObject(a) && isPlainObject(b)) ||
|
|
36
34
|
(isPlainObject(a) && b === true) ||
|
|
37
|
-
(a === true && isObject(b))
|
|
35
|
+
(a === true && isObject(b)) ||
|
|
36
|
+
(Array.isArray(a) &&
|
|
37
|
+
Array.isArray(b) &&
|
|
38
|
+
a.length === b.length &&
|
|
39
|
+
a.every((v, i) => v === b[i]));
|
|
38
40
|
|
|
39
41
|
/** @param {any} obj */
|
|
40
42
|
const merger = (obj) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../../../src/utils/throttle.js"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wDAFW,MAAM,
|
|
1
|
+
{"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../../../src/utils/throttle.js"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wDAFW,MAAM,cA8BhB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gridChild.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/gridChild.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gridChild.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/gridChild.js"],"names":[],"mappings":"AAkqBA;;;GAGG;AACH,iDAHW,OAAO,oBAAoB,EAAE,cAAc,GACzC,OAAO,oBAAoB,EAAE,QAAQ,CA8BjD;AAED;;;GAGG;AACH,uDAHW,OAAO,oBAAoB,EAAE,cAAc,GACzC,OAAO,oBAAoB,EAAE,QAAQ,CA6CjD;AAhuBD;IACI;;;;OAIG;IACH,kBAJW,OAAO,YAAY,EAAE,OAAO,gBAC5B,OAAO,qBAAqB,EAAE,OAAO,UACrC,MAAM,EAyFhB;IAtFG,oDAAgC;IAChC,mCAAgB;IAChB,eAAoB;IAEpB,uBAAuB;IACvB,YADW,QAAQ,CACQ;IAE3B,uBAAuB;IACvB,kBADW,QAAQ,CACc;IAEjC,sFAAsF;IACtF,MADW,OAAO,CAAC,MAAM,CAAC,OAAO,oBAAoB,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAC/D;IAEd,+FAA+F;IAC/F,WADW,OAAO,CAAC,MAAM,CAAC,OAAO,oBAAoB,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAC9D;IAEnB,mFAAmF;IACnF,YADW,OAAO,CAAC,MAAM,CAAC,OAAO,gBAAgB,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC,CAC3D;IAEpB,4BAA4B;IAC5B,eADW,aAAa,CACM;IAE9B,uBAAuB;IACvB,OADW,QAAQ,CACG;IAEtB,wBAAwB;IACxB,QADW,SAAS,CACQ;IAoZhC,sEAiBC;IAED;;OAEG;IACH,4BAsKC;IAED,uBAqBC;IAED,iCAEC;;CACJ;qBAjpBoB,gBAAgB;qBANK,gBAAgB;yBADjC,oBAAoB;sBAQvB,gBAAgB;0BACZ,oBAAoB;sBAJxB,wBAAwB;oBAF1B,sBAAsB"}
|
|
@@ -257,7 +257,7 @@ export default class GridChild {
|
|
|
257
257
|
};
|
|
258
258
|
|
|
259
259
|
view.addInteractionEventListener("mousedown", (coords, event) => {
|
|
260
|
-
if (
|
|
260
|
+
if (event.mouseEvent.button != 0) {
|
|
261
261
|
return;
|
|
262
262
|
}
|
|
263
263
|
|
|
@@ -283,9 +283,7 @@ export default class GridChild {
|
|
|
283
283
|
preventNextClickPropagation = true;
|
|
284
284
|
}
|
|
285
285
|
|
|
286
|
-
const startSelection =
|
|
287
|
-
event.uiEvent
|
|
288
|
-
).shiftKey;
|
|
286
|
+
const startSelection = event.mouseEvent.shiftKey;
|
|
289
287
|
|
|
290
288
|
if (startSelection) {
|
|
291
289
|
clearSelection();
|
|
@@ -322,7 +320,7 @@ export default class GridChild {
|
|
|
322
320
|
|
|
323
321
|
const start = event.point;
|
|
324
322
|
const viewOffset = Point.fromMouseEvent(
|
|
325
|
-
|
|
323
|
+
event.mouseEvent
|
|
326
324
|
).subtract(start);
|
|
327
325
|
|
|
328
326
|
const mouseMoveListener = (/** @type {MouseEvent} */ event) => {
|
|
@@ -410,7 +408,7 @@ export default class GridChild {
|
|
|
410
408
|
view.addInteractionEventListener(
|
|
411
409
|
"click",
|
|
412
410
|
(coords, event) => {
|
|
413
|
-
if (
|
|
411
|
+
if (event.mouseEvent.button == 0) {
|
|
414
412
|
if (preventNextClickPropagation) {
|
|
415
413
|
event.stopPropagation();
|
|
416
414
|
preventNextClickPropagation = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scrollbar.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/scrollbar.js"],"names":[],"mappings":"AAKA;;GAEG;AACH;IAeI;;;OAGG;IACH,uBAHW,OAAO,gBAAgB,EAAE,OAAO,mBAChC,eAAe,
|
|
1
|
+
{"version":3,"file":"scrollbar.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/scrollbar.js"],"names":[],"mappings":"AAKA;;GAEG;AACH;IAeI;;;OAGG;IACH,uBAHW,OAAO,gBAAgB,EAAE,OAAO,mBAChC,eAAe,EA2FzB;IA/FD,uBAAmB;IAsCf;;;MAAoB;IAIpB;;;;MAQC;IA+CL,2BAKC;IAWD;;;;OAIG;IACH,gCAHW,SAAS,UACT,SAAS,QA8CnB;;CACJ;8BAlLY,YAAY,GAAG,UAAU;qBAHjB,gBAAgB;sBADf,wBAAwB"}
|
|
@@ -83,11 +83,10 @@ export default class Scrollbar extends UnitView {
|
|
|
83
83
|
? mouseEvent.clientY
|
|
84
84
|
: mouseEvent.clientX;
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
mouseEvent.preventDefault();
|
|
86
|
+
event.mouseEvent.preventDefault();
|
|
88
87
|
|
|
89
88
|
const initialScrollOffset = this.scrollOffset;
|
|
90
|
-
const initialOffset = getMouseOffset(mouseEvent);
|
|
89
|
+
const initialOffset = getMouseOffset(event.mouseEvent);
|
|
91
90
|
|
|
92
91
|
const onMousemove = /** @param {MouseEvent} moveEvent */ (
|
|
93
92
|
moveEvent
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export default class SelectionRect extends LayerView {
|
|
2
|
+
/**
|
|
3
|
+
* @typedef {import("../../spec/channel.js").PrimaryPositionalChannel} PrimaryPositionalChannel
|
|
4
|
+
* @typedef {import("../../types/selectionTypes.js").IntervalSelection} IntervalSelection
|
|
5
|
+
*/
|
|
2
6
|
/**
|
|
3
7
|
* @param {import("./gridChild.js").default} gridChild
|
|
4
8
|
* @param {import("../paramMediator.js").ExprRefFunction} selectionExpr
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectionRect.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/selectionRect.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"selectionRect.d.ts","sourceRoot":"","sources":["../../../../src/view/gridView/selectionRect.js"],"names":[],"mappings":"AAGA;IACI;;;OAGG;IAEH;;;;OAIG;IACH,uBAJW,OAAO,gBAAgB,EAAE,OAAO,iBAChC,OAAO,qBAAqB,EAAE,eAAe,gBAC7C,OAAO,yBAAyB,EAAE,WAAW,EA0IvD;CACJ;sBAtJqB,iBAAiB"}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
+
import { primaryPositionalChannels } from "../../encoder/encoder.js";
|
|
1
2
|
import LayerView from "../layerView.js";
|
|
2
3
|
|
|
3
4
|
export default class SelectionRect extends LayerView {
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {import("../../spec/channel.js").PrimaryPositionalChannel} PrimaryPositionalChannel
|
|
7
|
+
* @typedef {import("../../types/selectionTypes.js").IntervalSelection} IntervalSelection
|
|
8
|
+
*/
|
|
9
|
+
|
|
4
10
|
/**
|
|
5
11
|
* @param {import("./gridChild.js").default} gridChild
|
|
6
12
|
* @param {import("../paramMediator.js").ExprRefFunction} selectionExpr
|
|
7
13
|
* @param {import("../../spec/parameter.js").BrushConfig} [brushConfig]
|
|
8
14
|
*/
|
|
9
15
|
constructor(gridChild, selectionExpr, brushConfig = {}) {
|
|
10
|
-
const initialSelection =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
);
|
|
16
|
+
const initialSelection = /** @type {IntervalSelection} */ (
|
|
17
|
+
selectionExpr()
|
|
18
|
+
);
|
|
14
19
|
const channels = Object.keys(initialSelection.intervals);
|
|
15
20
|
|
|
16
|
-
if (
|
|
17
|
-
/** @type {import("../../spec/channel.js").ChannelWithScale[]} */ ([
|
|
18
|
-
"x",
|
|
19
|
-
"y",
|
|
20
|
-
]).every((c) => !channels.includes(c))
|
|
21
|
-
) {
|
|
21
|
+
if (primaryPositionalChannels.every((c) => !channels.includes(c))) {
|
|
22
22
|
throw new Error(
|
|
23
23
|
"SelectionRect requires at least one of the channels 'x' or 'y' to be present in the selection."
|
|
24
24
|
);
|
|
@@ -64,9 +64,7 @@ export default class SelectionRect extends LayerView {
|
|
|
64
64
|
},
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
-
const makeExpr = (
|
|
68
|
-
/** @type {import("../../spec/channel.js").PrimaryPositionalChannel} */ channel
|
|
69
|
-
) => {
|
|
67
|
+
const makeExpr = (/** @type {PrimaryPositionalChannel} */ channel) => {
|
|
70
68
|
const resolution = gridChild.view.getScaleResolution(channel);
|
|
71
69
|
return (
|
|
72
70
|
`format(datum._${channel}2 - datum._${channel}, '.3s')` +
|
|
@@ -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":"AAm/BA;;;;;;;;;;GAUG;AACH,6CAFW,OAAO,WAAW,EAAE,OAAO,GAAG,OAAO,WAAW,EAAE,OAAO,EAAE,QA4BrE;AA3+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;IA8MD;;;;OAIG;IACH,+DAOC;IAED;;OAEG;IACH,oBA6CC;IAED;;OAEG;IACH;eApakC,OAAO,kBAAkB,EAAE,KAAK;MA4cjE;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;kCAr2B+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"}
|
|
@@ -469,6 +469,13 @@ export default class ScaleResolution {
|
|
|
469
469
|
scale.props = props;
|
|
470
470
|
this.#configureRange();
|
|
471
471
|
|
|
472
|
+
if (!this.#initialDomain && isContinuous(scale.type)) {
|
|
473
|
+
const domain = scale.domain();
|
|
474
|
+
if (span(domain) > 0) {
|
|
475
|
+
this.#initialDomain = domain;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
472
479
|
if (!domainWasInitialized) {
|
|
473
480
|
this.#initialDomain = scale.domain();
|
|
474
481
|
this.#notifyListeners("domain");
|
|
@@ -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":"AA4BA;;;;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,EAiCzC;IA5BG,yCAAgB;IAIZ,iDAAiD;IACjD,MADW,OAAO,kBAAkB,EAAE,OAAO,CACnB;IAkHlC,2DAIC;IAgBD;;;;;OAKG;IAEH,iEAsHC;IAED;;;;;OAKG;IACH,4IAEC;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;iBAragB,WAAW"}
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
getPrimaryChannel,
|
|
13
13
|
isChannelWithScale,
|
|
14
14
|
isPrimaryPositionalChannel,
|
|
15
|
+
isValueDefWithCondition,
|
|
15
16
|
} from "../encoder/encoder.js";
|
|
16
17
|
import createDomain from "../utils/domainArray.js";
|
|
17
18
|
import AxisResolution from "./axisResolution.js";
|
|
@@ -125,9 +126,6 @@ export default class UnitView extends View {
|
|
|
125
126
|
/** @type {any} */ _,
|
|
126
127
|
/** @type {import("../utils/interactionEvent.js").default} */ event
|
|
127
128
|
) => {
|
|
128
|
-
const mouseEvent = /** @type {MouseEvent} */ (
|
|
129
|
-
event.uiEvent
|
|
130
|
-
);
|
|
131
129
|
const datum = getHoveredDatum();
|
|
132
130
|
const id = datum ? datum[UNIQUE_ID_KEY] : none;
|
|
133
131
|
|
|
@@ -135,7 +133,7 @@ export default class UnitView extends View {
|
|
|
135
133
|
let selection;
|
|
136
134
|
|
|
137
135
|
if (select.toggle) {
|
|
138
|
-
const toggle = mouseEvent.shiftKey;
|
|
136
|
+
const toggle = event.mouseEvent.shiftKey;
|
|
139
137
|
|
|
140
138
|
if (toggle) {
|
|
141
139
|
if (datum) {
|
|
@@ -223,6 +221,7 @@ export default class UnitView extends View {
|
|
|
223
221
|
if (!type) {
|
|
224
222
|
this.resolve("scale");
|
|
225
223
|
this.resolve("axis");
|
|
224
|
+
return;
|
|
226
225
|
}
|
|
227
226
|
|
|
228
227
|
// TODO: Complain about nonsensical configuration, e.g. shared parent has independent children.
|
|
@@ -230,12 +229,34 @@ export default class UnitView extends View {
|
|
|
230
229
|
const encoding = this.mark.encoding;
|
|
231
230
|
|
|
232
231
|
for (const [channel, channelDef] of Object.entries(encoding)) {
|
|
233
|
-
if (!
|
|
232
|
+
if (!channelDef) {
|
|
234
233
|
continue;
|
|
235
234
|
}
|
|
236
235
|
|
|
236
|
+
/** @type {import("../spec/channel.js").ChannelDefWithScale} */
|
|
237
|
+
let channelDefWithScale;
|
|
238
|
+
|
|
239
|
+
if (isChannelDefWithScale(channelDef)) {
|
|
240
|
+
channelDefWithScale = channelDef;
|
|
241
|
+
} else {
|
|
242
|
+
if (isValueDefWithCondition(channelDef)) {
|
|
243
|
+
const condition = channelDef.condition;
|
|
244
|
+
if (
|
|
245
|
+
!Array.isArray(condition) &&
|
|
246
|
+
isChannelDefWithScale(condition)
|
|
247
|
+
) {
|
|
248
|
+
// There's a single condition (maybe) with a scale
|
|
249
|
+
channelDefWithScale = condition;
|
|
250
|
+
} else {
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
} else {
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
237
258
|
const targetChannel = getPrimaryChannel(
|
|
238
|
-
|
|
259
|
+
channelDefWithScale.resolutionChannel ?? channel
|
|
239
260
|
);
|
|
240
261
|
|
|
241
262
|
if (!isChannelWithScale(targetChannel)) {
|
|
@@ -279,7 +300,7 @@ export default class UnitView extends View {
|
|
|
279
300
|
view.resolutions[type][targetChannel].addMember({
|
|
280
301
|
view: this,
|
|
281
302
|
channel,
|
|
282
|
-
channelDef,
|
|
303
|
+
channelDef: channelDefWithScale,
|
|
283
304
|
});
|
|
284
305
|
} else if (type == "scale" && isChannelWithScale(channel)) {
|
|
285
306
|
if (!view.resolutions[type][targetChannel]) {
|
|
@@ -301,15 +322,15 @@ export default class UnitView extends View {
|
|
|
301
322
|
.some(
|
|
302
323
|
(view) => !view.options.contributesToScaleDomain
|
|
303
324
|
) ||
|
|
304
|
-
(isChannelDefWithScale(
|
|
305
|
-
|
|
325
|
+
(isChannelDefWithScale(channelDefWithScale) &&
|
|
326
|
+
channelDefWithScale.contributesToScaleDomain === false)
|
|
306
327
|
? undefined
|
|
307
328
|
: this.extractDataDomain.bind(this);
|
|
308
329
|
|
|
309
330
|
view.resolutions[type][targetChannel].addMember({
|
|
310
331
|
view: this,
|
|
311
332
|
channel,
|
|
312
|
-
channelDef,
|
|
333
|
+
channelDef: channelDefWithScale,
|
|
313
334
|
dataDomainSource,
|
|
314
335
|
});
|
|
315
336
|
}
|
|
@@ -11,14 +11,16 @@ import LayerView from "./layerView.js";
|
|
|
11
11
|
describe("Trivial creations and initializations", () => {
|
|
12
12
|
test("Fails on empty spec", async () => {
|
|
13
13
|
// @ts-expect-error
|
|
14
|
-
expect(create({}, View)).rejects.toThrow();
|
|
14
|
+
await expect(create({}, View)).rejects.toThrow();
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
test("Parses a trivial spec", () => {
|
|
18
|
-
expect(create({ mark: "point" }, View)).resolves.toBeInstanceOf(
|
|
17
|
+
test("Parses a trivial spec", async () => {
|
|
18
|
+
await expect(create({ mark: "point" }, View)).resolves.toBeInstanceOf(
|
|
19
19
|
UnitView
|
|
20
20
|
);
|
|
21
|
-
expect(create({ layer: [] }, View)).resolves.toBeInstanceOf(
|
|
21
|
+
await expect(create({ layer: [] }, View)).resolves.toBeInstanceOf(
|
|
22
|
+
LayerView
|
|
23
|
+
);
|
|
22
24
|
});
|
|
23
25
|
|
|
24
26
|
test("Parses a more comples spec", async () => {
|
|
@@ -16,10 +16,10 @@ test("isViewSpec", () => {
|
|
|
16
16
|
expect(() => factory.isViewSpec({ mark: "rect", layer: [] })).toThrow();
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
test("Throws if importing is not allowed", () => {
|
|
19
|
+
test("Throws if importing is not allowed", async () => {
|
|
20
20
|
const factory = new ViewFactory({ allowImport: false });
|
|
21
21
|
|
|
22
|
-
expect(() =>
|
|
22
|
+
await expect(() =>
|
|
23
23
|
factory.createOrImportView({ import: { url: "" } }, undefined)
|
|
24
24
|
).rejects.toThrow();
|
|
25
25
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zoom.d.ts","sourceRoot":"","sources":["../../../src/view/zoom.js"],"names":[],"mappings":"AAkBA,0CAGC;AAgBD;;;;;;GAMG;AACH,yCANW,OAAO,8BAA8B,EAAE,OAAO,UAC9C,OAAO,uBAAuB,EAAE,OAAO,cACvC,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,UAC9B,OAAO,yBAAyB,EAAE,KAAK,aACvC,OAAO,sBAAsB,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"zoom.d.ts","sourceRoot":"","sources":["../../../src/view/zoom.js"],"names":[],"mappings":"AAkBA,0CAGC;AAgBD;;;;;;GAMG;AACH,yCANW,OAAO,8BAA8B,EAAE,OAAO,UAC9C,OAAO,uBAAuB,EAAE,OAAO,cACvC,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,UAC9B,OAAO,yBAAyB,EAAE,KAAK,aACvC,OAAO,sBAAsB,EAAE,OAAO,QA+IhD;;OAvLS,MAAM;OACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM"}
|
package/dist/src/view/zoom.js
CHANGED
|
@@ -96,10 +96,7 @@ export function interactionToZoom(event, coords, handleZoom, hover, animator) {
|
|
|
96
96
|
zDelta: 0,
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
|
-
} else if (
|
|
100
|
-
event.type == "mousedown" &&
|
|
101
|
-
/** @type {MouseEvent} */ (event.uiEvent).button === 0
|
|
102
|
-
) {
|
|
99
|
+
} else if (event.type == "mousedown" && event.mouseEvent.button === 0) {
|
|
103
100
|
if (smoother) {
|
|
104
101
|
smoother.stop();
|
|
105
102
|
}
|
|
@@ -107,7 +104,7 @@ export function interactionToZoom(event, coords, handleZoom, hover, animator) {
|
|
|
107
104
|
/** @type {RingBuffer<{point: Point, timestamp: number}>} */
|
|
108
105
|
const eventBuffer = new RingBuffer(30);
|
|
109
106
|
|
|
110
|
-
const mouseEvent =
|
|
107
|
+
const mouseEvent = event.mouseEvent;
|
|
111
108
|
mouseEvent.preventDefault();
|
|
112
109
|
|
|
113
110
|
let prevPoint = Point.fromMouseEvent(mouseEvent);
|