@genome-spy/core 0.24.2 → 0.25.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/LICENSE +1 -1
- package/dist/index.js +41 -41
- package/package.json +2 -2
- package/src/data/dataFlow.js +39 -0
- package/src/data/sources/namedSource.js +20 -11
- package/src/embedApi.d.ts +12 -4
- package/src/genomeSpy.js +32 -3
- package/src/gl/includes/picking.fragment.glsl +1 -1
- package/src/gl/includes/picking.vertex.glsl +1 -1
- package/src/gl/point.fragment.glsl +7 -7
- package/src/gl/point.vertex.glsl +7 -7
- package/src/gl/rect.fragment.glsl +5 -5
- package/src/gl/rect.vertex.glsl +5 -5
- package/src/gl/rule.fragment.glsl +2 -2
- package/src/gl/rule.vertex.glsl +2 -2
- package/src/gl/text.fragment.glsl +2 -2
- package/src/gl/text.vertex.glsl +2 -2
- package/src/index.js +3 -0
- package/src/view/flowBuilder.js +5 -1
- package/src/view/viewContext.d.ts +1 -1
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"contributors": [],
|
|
9
9
|
"license": "BSD-2-Clause",
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.25.1",
|
|
11
11
|
"main": "dist/index.js",
|
|
12
12
|
"module": "src/index.js",
|
|
13
13
|
"exports": {
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"vega-scale": "^7.1.1",
|
|
54
54
|
"vega-util": "^1.16.0"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "e9c4acf0c725ce1ef46303a01a05d7ccf6dcc9c3"
|
|
57
57
|
}
|
package/src/data/dataFlow.js
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* @typedef {import("./collector").default} Collector
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import NamedSource from "./sources/namedSource";
|
|
8
|
+
|
|
7
9
|
/**
|
|
8
10
|
* @template H A key (string, object, whatever) that is used to retrieve
|
|
9
11
|
* data sources and collectors.
|
|
@@ -76,6 +78,43 @@ export default class DataFlow {
|
|
|
76
78
|
return this._dataSourcesByHost.get(key);
|
|
77
79
|
}
|
|
78
80
|
|
|
81
|
+
/**
|
|
82
|
+
*
|
|
83
|
+
* @param {string} name
|
|
84
|
+
*/
|
|
85
|
+
findNamedDataSource(name) {
|
|
86
|
+
/** @type {NamedSource} */
|
|
87
|
+
let namedSource;
|
|
88
|
+
/** @type {H[]} */
|
|
89
|
+
let hosts = [];
|
|
90
|
+
|
|
91
|
+
// Note: If a named sources with the same name are present at multiple locations in the
|
|
92
|
+
// view hierarchy, the should actually be exactly the same instance. It's arranged that
|
|
93
|
+
// way in the data flow optimization phase.
|
|
94
|
+
|
|
95
|
+
for (const [host, dataSource] of this._dataSourcesByHost.entries()) {
|
|
96
|
+
if (dataSource instanceof NamedSource) {
|
|
97
|
+
if (name == dataSource.identifier) {
|
|
98
|
+
if (namedSource && namedSource !== dataSource) {
|
|
99
|
+
// TODO: Write a test case for this and remove the runtime check.
|
|
100
|
+
throw new Error(
|
|
101
|
+
`Found multiple instances of named data: ${name}. Data flow optimization is broken (it's a bug).`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
namedSource = dataSource;
|
|
105
|
+
hosts.push(host);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (namedSource) {
|
|
111
|
+
return {
|
|
112
|
+
dataSource: namedSource,
|
|
113
|
+
hosts,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
79
118
|
/**
|
|
80
119
|
*
|
|
81
120
|
* @param {Collector} collector
|
|
@@ -10,14 +10,20 @@ export function isNamedData(data) {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export default class NamedSource extends DataSource {
|
|
13
|
+
/**
|
|
14
|
+
* Data that has been provided explicitly using the updateDynamicData method
|
|
15
|
+
* @type {any[]}
|
|
16
|
+
*/
|
|
17
|
+
#explicitData;
|
|
18
|
+
|
|
13
19
|
/**
|
|
14
20
|
* @param {import("../../spec/data").NamedData} params
|
|
15
|
-
* @param {function(string):any[]}
|
|
21
|
+
* @param {function(string):any[]} provider Function that retrieves a dataset using a name
|
|
16
22
|
*/
|
|
17
|
-
constructor(params,
|
|
23
|
+
constructor(params, provider) {
|
|
18
24
|
super();
|
|
19
25
|
|
|
20
|
-
this.
|
|
26
|
+
this.provider = provider;
|
|
21
27
|
this.params = params;
|
|
22
28
|
}
|
|
23
29
|
|
|
@@ -28,17 +34,20 @@ export default class NamedSource extends DataSource {
|
|
|
28
34
|
return this.params.name;
|
|
29
35
|
}
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Update the named data. If data is omitted, a data provider is used instead.
|
|
39
|
+
*
|
|
40
|
+
* @param {import("../flowNode").Datum[]} [data]
|
|
41
|
+
*/
|
|
42
|
+
updateDynamicData(data) {
|
|
43
|
+
// TODO: Throw is data is undefined and the provider is unable to provide any data
|
|
44
|
+
this.#explicitData = data;
|
|
45
|
+
this.loadSynchronously();
|
|
38
46
|
}
|
|
39
47
|
|
|
40
48
|
loadSynchronously() {
|
|
41
|
-
const data =
|
|
49
|
+
const data =
|
|
50
|
+
this.#explicitData ?? this.provider(this.params.name) ?? [];
|
|
42
51
|
|
|
43
52
|
/** @type {(x: any) => import("../flowNode").Datum} */
|
|
44
53
|
let wrap = (x) => x;
|
package/src/embedApi.d.ts
CHANGED
|
@@ -17,9 +17,9 @@ export type EmbedFunction = (
|
|
|
17
17
|
|
|
18
18
|
export interface EmbedOptions {
|
|
19
19
|
/**
|
|
20
|
-
* A function that allows retrieval of named data
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* A function that allows retrieval of named data. There are two ways to provide named data:
|
|
21
|
+
* 1. A data provider (this)
|
|
22
|
+
* 2. Explicit updates using the `updateNamedData` method (the other).
|
|
23
23
|
*/
|
|
24
24
|
namedDataProvider?: (name: string) => any[];
|
|
25
25
|
|
|
@@ -52,8 +52,16 @@ export interface EmbedResult {
|
|
|
52
52
|
removeEventListener: (type: string, listener: (event: any) => void) => void;
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
|
-
* Returns a named
|
|
55
|
+
* Returns a named `ScaleResolution` object that allows for attaching event
|
|
56
56
|
* listeners and controlling the scale domain.
|
|
57
57
|
*/
|
|
58
58
|
getScaleResolutionByName: (name: string) => ScaleResolutionApi;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Updates a named dataset
|
|
62
|
+
*
|
|
63
|
+
* @param name data source to update
|
|
64
|
+
* @param data new data. If left undefined, the data is retrieved from a provider.
|
|
65
|
+
*/
|
|
66
|
+
updateNamedData: (name: string, data?: any[]) => void;
|
|
59
67
|
}
|
package/src/genomeSpy.js
CHANGED
|
@@ -137,10 +137,9 @@ export default class GenomeSpy {
|
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
/**
|
|
140
|
-
*
|
|
141
140
|
* @param {string} name
|
|
142
141
|
*/
|
|
143
|
-
|
|
142
|
+
getNamedDataFromProvider(name) {
|
|
144
143
|
for (const provider of this.namedDataProviders) {
|
|
145
144
|
const data = provider(name);
|
|
146
145
|
if (data) {
|
|
@@ -149,6 +148,36 @@ export default class GenomeSpy {
|
|
|
149
148
|
}
|
|
150
149
|
}
|
|
151
150
|
|
|
151
|
+
/**
|
|
152
|
+
*
|
|
153
|
+
* @param {string} name
|
|
154
|
+
* @param {any[]} data
|
|
155
|
+
*/
|
|
156
|
+
updateNamedData(name, data) {
|
|
157
|
+
const namedSource =
|
|
158
|
+
this.viewRoot.context.dataFlow.findNamedDataSource(name);
|
|
159
|
+
if (!namedSource) {
|
|
160
|
+
throw new Error("No such named data source: " + name);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
namedSource.dataSource.updateDynamicData(data);
|
|
164
|
+
|
|
165
|
+
// Scale domains may need adjustment.
|
|
166
|
+
// TODO: Refactor so that Collectors handle scale extents etc.
|
|
167
|
+
for (const host of namedSource.hosts) {
|
|
168
|
+
host.visit((view) => {
|
|
169
|
+
for (const resolution of Object.values(
|
|
170
|
+
view.resolutions.scale
|
|
171
|
+
)) {
|
|
172
|
+
// TODO: Only update domain
|
|
173
|
+
resolution.reconfigure();
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
this.animator.requestRender();
|
|
179
|
+
}
|
|
180
|
+
|
|
152
181
|
/**
|
|
153
182
|
* Broadcast a message to all views
|
|
154
183
|
*
|
|
@@ -243,7 +272,7 @@ export default class GenomeSpy {
|
|
|
243
272
|
// placeholder
|
|
244
273
|
},
|
|
245
274
|
updateTooltip: this.updateTooltip.bind(this),
|
|
246
|
-
|
|
275
|
+
getNamedDataFromProvider: this.getNamedDataFromProvider.bind(this),
|
|
247
276
|
getCurrentHover: () => this._currentHover,
|
|
248
277
|
|
|
249
278
|
addKeyboardListener: (type, listener) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
in highp vec4 vPickingColor;
|
|
@@ -4,15 +4,15 @@ const lowp vec4 black = vec4(0.0, 0.0, 0.0, 1.0);
|
|
|
4
4
|
uniform bool uInwardStroke;
|
|
5
5
|
uniform float uGradientStrength;
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
in float vRadius;
|
|
8
|
+
in float vRadiusWithPadding;
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
in lowp vec4 vFillColor;
|
|
11
|
+
in lowp vec4 vStrokeColor;
|
|
12
|
+
in lowp float vShape;
|
|
13
|
+
in lowp float vHalfStrokeWidth;
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
in mat2 vRotationMatrix;
|
|
16
16
|
|
|
17
17
|
out lowp vec4 fragColor;
|
|
18
18
|
|
package/src/gl/point.vertex.glsl
CHANGED
|
@@ -17,13 +17,13 @@ uniform float uMaxPointSize;
|
|
|
17
17
|
uniform float uZoomLevel;
|
|
18
18
|
uniform float uSemanticThreshold;
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
out float vRadius;
|
|
21
|
+
out float vRadiusWithPadding;
|
|
22
|
+
out lowp vec4 vFillColor;
|
|
23
|
+
out lowp vec4 vStrokeColor;
|
|
24
|
+
out lowp float vShape;
|
|
25
|
+
out lowp float vHalfStrokeWidth;
|
|
26
|
+
out mat2 vRotationMatrix;
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
float computeSemanticThresholdFactor() {
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
in vec2 vPosInPixels;
|
|
3
3
|
#endif
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
in vec2 vHalfSizeInPixels;
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
in lowp vec4 vFillColor;
|
|
8
|
+
in lowp vec4 vStrokeColor;
|
|
9
|
+
in float vHalfStrokeWidth;
|
|
10
|
+
in vec4 vCornerRadii;
|
|
11
11
|
|
|
12
12
|
out lowp vec4 fragColor;
|
|
13
13
|
|
package/src/gl/rect.vertex.glsl
CHANGED
|
@@ -15,10 +15,10 @@ uniform float uMinOpacity;
|
|
|
15
15
|
/** top-right, bottom-right, top-left, bottom-left */
|
|
16
16
|
uniform vec4 uCornerRadii;
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
out lowp vec4 vFillColor;
|
|
19
|
+
out lowp vec4 vStrokeColor;
|
|
20
|
+
out float vHalfStrokeWidth;
|
|
21
|
+
out vec4 vCornerRadii;
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
#if defined(ROUNDED_CORNERS) || defined(STROKED)
|
|
@@ -27,7 +27,7 @@ out vec2 vPosInPixels;
|
|
|
27
27
|
#endif
|
|
28
28
|
|
|
29
29
|
/** Size of the rect in pixels */
|
|
30
|
-
|
|
30
|
+
out vec2 vHalfSizeInPixels;
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Clamps the minimumSize and returns an opacity that reflects the amount of clamping.
|
|
@@ -8,8 +8,8 @@ uniform float uDashTextureSize;
|
|
|
8
8
|
uniform float uStrokeDashOffset;
|
|
9
9
|
uniform lowp int uStrokeCap;
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
in vec4 vColor;
|
|
12
|
+
in float vSize;
|
|
13
13
|
|
|
14
14
|
/** Position on the rule along its length in pixels */
|
|
15
15
|
in vec2 vPosInPixels;
|
package/src/gl/rule.vertex.glsl
CHANGED
|
@@ -15,10 +15,10 @@ uniform float uMinLength;
|
|
|
15
15
|
uniform mediump float uDashTextureSize;
|
|
16
16
|
uniform lowp int uStrokeCap;
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
out vec4 vColor;
|
|
19
19
|
|
|
20
20
|
/** Stroke width */
|
|
21
|
-
|
|
21
|
+
out float vSize;
|
|
22
22
|
|
|
23
23
|
/** The distance from the line center to the direction of normal in pixels */
|
|
24
24
|
out float vNormalLengthInPixels;
|
package/src/gl/text.vertex.glsl
CHANGED
package/src/index.js
CHANGED
|
@@ -11,6 +11,7 @@ export { GenomeSpy, html, icon };
|
|
|
11
11
|
* Embeds GenomeSpy into the DOM
|
|
12
12
|
*
|
|
13
13
|
* @type {import("./embedApi.js").EmbedFunction}
|
|
14
|
+
* @returns {Promise<import("./embedApi").EmbedResult>}
|
|
14
15
|
*/
|
|
15
16
|
export async function embed(el, spec, options = {}) {
|
|
16
17
|
/** @type {HTMLElement} */
|
|
@@ -85,6 +86,8 @@ export async function embed(el, spec, options = {}) {
|
|
|
85
86
|
getScaleResolutionByName(name) {
|
|
86
87
|
return genomeSpy.getNamedScaleResolutions().get(name);
|
|
87
88
|
},
|
|
89
|
+
|
|
90
|
+
updateNamedData: genomeSpy.updateNamedData.bind(genomeSpy),
|
|
88
91
|
};
|
|
89
92
|
}
|
|
90
93
|
|
package/src/view/flowBuilder.js
CHANGED
|
@@ -116,7 +116,11 @@ export function buildDataFlow(root, existingFlow) {
|
|
|
116
116
|
const dataSource = isDynamicCallbackData(view.spec.data)
|
|
117
117
|
? view.getDynamicDataSource()
|
|
118
118
|
: isNamedData(view.spec.data)
|
|
119
|
-
?
|
|
119
|
+
? // TODO: Only one NamedSource instance per unique name should exists
|
|
120
|
+
new NamedSource(
|
|
121
|
+
view.spec.data,
|
|
122
|
+
view.context.getNamedDataFromProvider
|
|
123
|
+
)
|
|
120
124
|
: createDataSource(view.spec.data, view.getBaseUrl());
|
|
121
125
|
|
|
122
126
|
currentNode = dataSource;
|