@genome-spy/core 0.45.0 → 0.46.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-lmJu1tfP.js → index-BtRKzKhM.js} +6 -6
- package/dist/bundle/{index--cKb-dKG.js → index-BwFvhduA.js} +5 -5
- package/dist/bundle/{index-1QVesMzU.js → index-C8lYPtq_.js} +1 -1
- package/dist/bundle/{index-Pv3tKJ1W.js → index-CkI3Kd2P.js} +3 -3
- package/dist/bundle/{index-Y-LdHNIz.js → index-CmBp-spD.js} +1 -1
- package/dist/bundle/{index-z4Cs62EO.js → index-Dixm7K89.js} +4 -4
- package/dist/bundle/{index-noY1e-G6.js → index-Sk-Wtwdn.js} +5 -5
- package/dist/bundle/{index-UyrC0vvF.js → index-Z7JiNsFI.js} +4 -4
- package/dist/bundle/{index-LD6yPc3X.js → index-mihmTLo-.js} +1 -1
- package/dist/bundle/index.es.js +2698 -2615
- package/dist/bundle/index.js +93 -84
- package/dist/bundle/{long-Veu0zKh9.js → long-CYrAUkxh.js} +2 -2
- package/dist/bundle/{remoteFile-Ur-gRKsH.js → remoteFile-1_eCK3VV.js} +1 -1
- package/dist/schema.json +156 -15
- package/dist/src/data/collector.d.ts +1 -0
- package/dist/src/data/collector.d.ts.map +1 -1
- package/dist/src/data/collector.js +19 -3
- package/dist/src/data/flow.test.js +4 -0
- package/dist/src/data/flowNode.d.ts +10 -8
- package/dist/src/data/flowNode.d.ts.map +1 -1
- package/dist/src/data/flowNode.js +25 -15
- package/dist/src/data/sources/dataSource.d.ts +17 -0
- package/dist/src/data/sources/dataSource.d.ts.map +1 -1
- package/dist/src/data/sources/dataSource.js +34 -0
- package/dist/src/data/sources/inlineSource.js +1 -1
- package/dist/src/data/sources/lazy/bigBedSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigBedSource.js +6 -0
- package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigWigSource.js +28 -15
- package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts +0 -8
- package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/singleAxisLazySource.js +1 -13
- package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +3 -3
- package/dist/src/data/sources/namedSource.js +1 -1
- package/dist/src/data/sources/sequenceSource.d.ts.map +1 -1
- package/dist/src/data/sources/sequenceSource.js +2 -1
- package/dist/src/data/sources/urlSource.d.ts.map +1 -1
- package/dist/src/data/sources/urlSource.js +9 -5
- package/dist/src/data/transforms/filter.d.ts +2 -2
- package/dist/src/data/transforms/filter.d.ts.map +1 -1
- package/dist/src/data/transforms/filter.js +3 -6
- package/dist/src/data/transforms/filter.test.js +6 -0
- package/dist/src/data/transforms/formula.d.ts +2 -2
- package/dist/src/data/transforms/formula.d.ts.map +1 -1
- package/dist/src/data/transforms/formula.js +3 -3
- package/dist/src/data/transforms/formula.test.js +7 -1
- package/dist/src/genomeSpy.d.ts +5 -2
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/genomeSpy.js +24 -8
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +11 -0
- package/dist/src/spec/view.d.ts +52 -9
- 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 +4 -0
- package/dist/src/styles/genome-spy.scss +5 -0
- package/dist/src/types/viewContext.d.ts +9 -2
- package/dist/src/utils/expression.js +1 -1
- 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 +3 -2
- package/dist/src/view/paramMediator.test.js +13 -0
- package/dist/src/view/viewFactory.d.ts +4 -1
- package/dist/src/view/viewFactory.d.ts.map +1 -1
- package/dist/src/view/viewFactory.js +52 -24
- package/dist/src/view/viewUtils.d.ts +2 -7
- package/dist/src/view/viewUtils.d.ts.map +1 -1
- package/dist/src/view/viewUtils.js +21 -30
- package/package.json +2 -2
- /package/dist/bundle/{__vite-browser-external-ENoMJThg.js → __vite-browser-external-C--ziKoh.js} +0 -0
- /package/dist/bundle/{_commonjsHelpers-QtkX90xp.js → _commonjsHelpers-BIiJCwQW.js} +0 -0
package/dist/src/spec/view.d.ts
CHANGED
|
@@ -124,6 +124,11 @@ export interface ViewSpecBase extends ResolveSpec {
|
|
|
124
124
|
*/
|
|
125
125
|
description?: string | string[];
|
|
126
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Optional base URL for constructing request URLs. When set, all views
|
|
129
|
+
* deeper in the hierarchy inherit this base URL, using it for importing
|
|
130
|
+
* loading data and importing specifications.
|
|
131
|
+
*/
|
|
127
132
|
baseUrl?: string;
|
|
128
133
|
|
|
129
134
|
/**
|
|
@@ -151,6 +156,12 @@ export interface ViewSpecBase extends ResolveSpec {
|
|
|
151
156
|
* **Default:** `false` for children of `layer`, `true` for others.
|
|
152
157
|
*/
|
|
153
158
|
configurableVisibility?: boolean;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Templates that can be reused within the view specification by importing
|
|
162
|
+
* them with the template key.
|
|
163
|
+
*/
|
|
164
|
+
templates?: Record<string, ViewSpec>;
|
|
154
165
|
}
|
|
155
166
|
|
|
156
167
|
export interface UnitSpec extends ViewSpecBase, AggregateSamplesSpec {
|
|
@@ -165,7 +176,7 @@ export interface AggregateSamplesSpec {
|
|
|
165
176
|
|
|
166
177
|
export interface LayerSpec extends ViewSpecBase, AggregateSamplesSpec {
|
|
167
178
|
view?: ViewBackground;
|
|
168
|
-
layer: (LayerSpec | UnitSpec)[];
|
|
179
|
+
layer: (LayerSpec | UnitSpec | ImportSpec)[];
|
|
169
180
|
}
|
|
170
181
|
|
|
171
182
|
export interface FacetSpec extends ViewSpecBase {
|
|
@@ -218,39 +229,71 @@ export type ViewSpec =
|
|
|
218
229
|
| ConcatSpec
|
|
219
230
|
| SampleSpec;
|
|
220
231
|
|
|
221
|
-
export interface
|
|
222
|
-
|
|
232
|
+
export interface UrlImport {
|
|
233
|
+
/**
|
|
234
|
+
* Imports a specification from the specified URL.
|
|
235
|
+
*/
|
|
236
|
+
url: string;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export interface TemplateImport {
|
|
240
|
+
/**
|
|
241
|
+
* Imports a specification from the current view hierarchy, searching
|
|
242
|
+
* first in the current view, then ascending through ancestors.
|
|
243
|
+
*/
|
|
244
|
+
template: string;
|
|
245
|
+
}
|
|
223
246
|
|
|
247
|
+
export interface ImportSpec {
|
|
224
248
|
/**
|
|
225
|
-
*
|
|
249
|
+
* The name given to the imported view. This property overrides the name
|
|
250
|
+
* specified in the imported specification.
|
|
226
251
|
*/
|
|
227
252
|
name?: string;
|
|
228
253
|
|
|
229
254
|
/**
|
|
230
|
-
* Dynamic variables that parameterize a visualization. Parameters defined
|
|
231
|
-
* override the parameters defined in the imported
|
|
255
|
+
* Dynamic variables that parameterize a visualization. Parameters defined
|
|
256
|
+
* here override the parameters defined in the imported specification.
|
|
232
257
|
*/
|
|
233
258
|
params?: VariableParameter[] | Record<string, any>;
|
|
234
|
-
}
|
|
235
259
|
|
|
236
|
-
|
|
237
|
-
|
|
260
|
+
/**
|
|
261
|
+
* The method to import a specification.
|
|
262
|
+
*/
|
|
263
|
+
import: UrlImport | TemplateImport;
|
|
238
264
|
}
|
|
239
265
|
|
|
240
266
|
export interface ConcatBase extends ViewSpecBase {
|
|
267
|
+
/**
|
|
268
|
+
* The gap between the views, in pixels.
|
|
269
|
+
*/
|
|
241
270
|
spacing?: number;
|
|
242
271
|
}
|
|
243
272
|
|
|
244
273
|
export interface VConcatSpec extends ConcatBase {
|
|
274
|
+
/**
|
|
275
|
+
* Specifies views that will be concatenated vertically.
|
|
276
|
+
*/
|
|
245
277
|
vconcat: (ViewSpec | ImportSpec)[];
|
|
246
278
|
}
|
|
247
279
|
|
|
248
280
|
export interface HConcatSpec extends ConcatBase {
|
|
281
|
+
/**
|
|
282
|
+
* Specifies views that will be concatenated horizontally.
|
|
283
|
+
*/
|
|
249
284
|
hconcat: (ViewSpec | ImportSpec)[];
|
|
250
285
|
}
|
|
251
286
|
|
|
252
287
|
export interface ConcatSpec extends ConcatBase {
|
|
288
|
+
/**
|
|
289
|
+
* Specifies views that will be concatenated into a grid that wraps when
|
|
290
|
+
* the specified number of columns are used.
|
|
291
|
+
*/
|
|
253
292
|
concat: (ViewSpec | ImportSpec)[];
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* The number of columns in the grid.
|
|
296
|
+
*/
|
|
254
297
|
columns: number;
|
|
255
298
|
}
|
|
256
299
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export default css;
|
|
2
|
-
declare const css: "\n.genome-spy {\n font-family: system-ui, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n position: relative;\n display: flex;\n flex-direction: column;\n}\n.genome-spy .canvas-wrapper {\n position: relative;\n flex-grow: 1;\n overflow: hidden;\n}\n.genome-spy canvas {\n transform: scale(1, 1);\n opacity: 1;\n transition: transform 0.6s, opacity 0.6s;\n}\n.genome-spy .loading-message {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.genome-spy .loading-message .message {\n color: #666;\n opacity: 0;\n transition: opacity 0.7s;\n}\n.genome-spy .loading > canvas {\n transform: scale(0.95, 0.95);\n opacity: 0;\n}\n.genome-spy .loading > .loading-message .message {\n opacity: 1;\n}\n.genome-spy .loading > .loading-message .message .ellipsis {\n animation: blinker 1s linear infinite;\n}\n@keyframes blinker {\n 50% {\n opacity: 0;\n }\n}\n.genome-spy .loading-indicators {\n position: absolute;\n inset: 0;\n user-select: none;\n pointer-events: none;\n}\n.genome-spy .loading-indicators div {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.genome-spy .loading-indicators div > div {\n font-size: 11px;\n transition: opacity 0.2s;\n background: white;\n padding: 2px 5px;\n display: flex;\n border-radius: 3px;\n gap: 0.5em;\n opacity: 0;\n}\n.genome-spy .loading-indicators div > div.loading {\n opacity: 0.5;\n}\n.genome-spy .loading-indicators div > div > * {\n display: block;\n}\n.genome-spy .loading-indicators div > div img {\n width: 1.5em;\n height: 1.5em;\n}\n.genome-spy .tooltip {\n position: absolute;\n max-width: 450px;\n overflow: hidden;\n background: #f6f6f6;\n padding: 10px;\n font-size: 13px;\n box-shadow: 0px 3px 15px 0px rgba(0, 0, 0, 0.21);\n pointer-events: none;\n z-index: 100;\n}\n.genome-spy .tooltip > :last-child {\n margin-bottom: 0;\n}\n.genome-spy .tooltip > .title {\n padding-bottom: 5px;\n margin-bottom: 5px;\n border-bottom: 1px dashed #b6b6b6;\n}\n.genome-spy .tooltip .summary {\n font-size: 12px;\n}\n.genome-spy .tooltip table {\n border-collapse: collapse;\n}\n.genome-spy .tooltip table:first-child {\n margin-top: 0;\n}\n.genome-spy .tooltip table th,\n.genome-spy .tooltip table td {\n padding: 2px 0.4em;\n vertical-align: top;\n}\n.genome-spy .tooltip table th:first-child,\n.genome-spy .tooltip table td:first-child {\n padding-left: 0;\n}\n.genome-spy .tooltip table th {\n text-align: left;\n font-weight: bold;\n}\n.genome-spy .tooltip .color-legend {\n display: inline-block;\n width: 0.8em;\n height: 0.8em;\n margin-left: 0.4em;\n box-shadow: 0px 0px 3px 1px white;\n}\n.genome-spy .tooltip .attributes .hovered {\n background-color: #e0e0e0;\n}\n.genome-spy .tooltip .na {\n color: #aaa;\n font-style: italic;\n font-size: 80%;\n}\n.genome-spy .gene-track-tooltip .summary {\n font-size: 90%;\n}\n.genome-spy .message-box {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n top: 0;\n height: 100%;\n width: 100%;\n}\n.genome-spy .message-box > div {\n border: 1px solid red;\n padding: 10px;\n background: #fff0f0;\n}\n\n.gs-input-binding {\n display: grid;\n grid-template-columns: max-content max-content;\n column-gap: 1em;\n row-gap: 0.3em;\n justify-items: start;\n}\n.gs-input-binding > select,\n.gs-input-binding > input:not([type=checkbox]) {\n width: 100%;\n}\n.gs-input-binding input[type=range] + span {\n display: inline-block;\n margin-left: 0.3em;\n min-width: 2.2em;\n font-variant-numeric: tabular-nums;\n}\n.gs-input-binding input[type=range],\n.gs-input-binding input[type=radio] {\n vertical-align: text-bottom;\n}\n.gs-input-binding .radio-group {\n display: flex;\n align-items: center;\n}\n.gs-input-binding .description {\n max-width: 26em;\n grid-column: 1/-1;\n color: #777;\n font-size: 90%;\n margin-top: -0.5em;\n}\n\n.gs-input-bindings {\n flex-basis: content;\n font-size: 14px;\n padding: 10px;\n}\n";
|
|
2
|
+
declare const css: "\n.genome-spy {\n font-family: system-ui, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n position: relative;\n display: flex;\n flex-direction: column;\n}\n.genome-spy .canvas-wrapper {\n position: relative;\n flex-grow: 1;\n overflow: hidden;\n}\n.genome-spy canvas {\n transform: scale(1, 1);\n opacity: 1;\n transition: transform 0.6s, opacity 0.6s;\n}\n.genome-spy .loading-message {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.genome-spy .loading-message .message {\n color: #666;\n opacity: 0;\n transition: opacity 0.7s;\n}\n.genome-spy .loading > canvas {\n transform: scale(0.95, 0.95);\n opacity: 0;\n}\n.genome-spy .loading > .loading-message .message {\n opacity: 1;\n}\n.genome-spy .loading > .loading-message .message .ellipsis {\n animation: blinker 1s linear infinite;\n}\n@keyframes blinker {\n 50% {\n opacity: 0;\n }\n}\n.genome-spy .loading-indicators {\n position: absolute;\n inset: 0;\n user-select: none;\n pointer-events: none;\n}\n.genome-spy .loading-indicators div {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.genome-spy .loading-indicators div > div {\n font-size: 11px;\n transition: opacity 0.2s;\n background: white;\n padding: 2px 5px;\n display: flex;\n border-radius: 3px;\n gap: 0.5em;\n opacity: 0;\n}\n.genome-spy .loading-indicators div > div.loading {\n opacity: 0.5;\n}\n.genome-spy .loading-indicators div > div.error {\n opacity: 0.8;\n color: firebrick;\n}\n.genome-spy .loading-indicators div > div > * {\n display: block;\n}\n.genome-spy .loading-indicators div > div img {\n width: 1.5em;\n height: 1.5em;\n}\n.genome-spy .tooltip {\n position: absolute;\n max-width: 450px;\n overflow: hidden;\n background: #f6f6f6;\n padding: 10px;\n font-size: 13px;\n box-shadow: 0px 3px 15px 0px rgba(0, 0, 0, 0.21);\n pointer-events: none;\n z-index: 100;\n}\n.genome-spy .tooltip > :last-child {\n margin-bottom: 0;\n}\n.genome-spy .tooltip > .title {\n padding-bottom: 5px;\n margin-bottom: 5px;\n border-bottom: 1px dashed #b6b6b6;\n}\n.genome-spy .tooltip .summary {\n font-size: 12px;\n}\n.genome-spy .tooltip table {\n border-collapse: collapse;\n}\n.genome-spy .tooltip table:first-child {\n margin-top: 0;\n}\n.genome-spy .tooltip table th,\n.genome-spy .tooltip table td {\n padding: 2px 0.4em;\n vertical-align: top;\n}\n.genome-spy .tooltip table th:first-child,\n.genome-spy .tooltip table td:first-child {\n padding-left: 0;\n}\n.genome-spy .tooltip table th {\n text-align: left;\n font-weight: bold;\n}\n.genome-spy .tooltip .color-legend {\n display: inline-block;\n width: 0.8em;\n height: 0.8em;\n margin-left: 0.4em;\n box-shadow: 0px 0px 3px 1px white;\n}\n.genome-spy .tooltip .attributes .hovered {\n background-color: #e0e0e0;\n}\n.genome-spy .tooltip .na {\n color: #aaa;\n font-style: italic;\n font-size: 80%;\n}\n.genome-spy .gene-track-tooltip .summary {\n font-size: 90%;\n}\n.genome-spy .message-box {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n top: 0;\n height: 100%;\n width: 100%;\n}\n.genome-spy .message-box > div {\n border: 1px solid red;\n padding: 10px;\n background: #fff0f0;\n}\n\n.gs-input-binding {\n display: grid;\n grid-template-columns: max-content max-content;\n column-gap: 1em;\n row-gap: 0.3em;\n justify-items: start;\n}\n.gs-input-binding > select,\n.gs-input-binding > input:not([type=checkbox]) {\n width: 100%;\n}\n.gs-input-binding input[type=range] + span {\n display: inline-block;\n margin-left: 0.3em;\n min-width: 2.2em;\n font-variant-numeric: tabular-nums;\n}\n.gs-input-binding input[type=range],\n.gs-input-binding input[type=radio] {\n vertical-align: text-bottom;\n}\n.gs-input-binding .radio-group {\n display: flex;\n align-items: center;\n}\n.gs-input-binding .description {\n max-width: 26em;\n grid-column: 1/-1;\n color: #777;\n font-size: 90%;\n margin-top: -0.5em;\n}\n\n.gs-input-bindings {\n flex-basis: content;\n font-size: 14px;\n padding: 10px;\n}\n";
|
|
3
3
|
//# sourceMappingURL=genome-spy.css.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genome-spy.css.d.ts","sourceRoot":"","sources":["../../../src/styles/genome-spy.css.js"],"names":[],"mappings":";AAAA,
|
|
1
|
+
{"version":3,"file":"genome-spy.css.d.ts","sourceRoot":"","sources":["../../../src/styles/genome-spy.css.js"],"names":[],"mappings":";AAAA,yoIAgME"}
|
|
@@ -67,6 +67,10 @@ const css = `
|
|
|
67
67
|
.genome-spy .loading-indicators div > div.loading {
|
|
68
68
|
opacity: 0.5;
|
|
69
69
|
}
|
|
70
|
+
.genome-spy .loading-indicators div > div.error {
|
|
71
|
+
opacity: 0.8;
|
|
72
|
+
color: firebrick;
|
|
73
|
+
}
|
|
70
74
|
.genome-spy .loading-indicators div > div > * {
|
|
71
75
|
display: block;
|
|
72
76
|
}
|
|
@@ -18,6 +18,8 @@ export interface Hover {
|
|
|
18
18
|
datum: Datum;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
export type DataLoadingStatus = "loading" | "complete" | "error";
|
|
22
|
+
|
|
21
23
|
/**
|
|
22
24
|
* ViewContext provides essential data and interfaces to View classes.
|
|
23
25
|
*/
|
|
@@ -74,9 +76,14 @@ export default interface ViewContext {
|
|
|
74
76
|
* The status is shown in the UI somewhere within or near the view.
|
|
75
77
|
*
|
|
76
78
|
* @param view The view where the data source is located.
|
|
77
|
-
* @param status
|
|
79
|
+
* @param status
|
|
80
|
+
* @param detail Details about the error, if any.
|
|
78
81
|
*/
|
|
79
|
-
setDataLoadingStatus: (
|
|
82
|
+
setDataLoadingStatus: (
|
|
83
|
+
view: View,
|
|
84
|
+
status: DataLoadingStatus,
|
|
85
|
+
detail?: string
|
|
86
|
+
) => void;
|
|
80
87
|
|
|
81
88
|
/**
|
|
82
89
|
* Returns true if the view is configured to be visible.
|
|
@@ -52,10 +52,11 @@ export default class ParamMediator {
|
|
|
52
52
|
*
|
|
53
53
|
* @param {string} paramName
|
|
54
54
|
* @param {T} initialValue
|
|
55
|
+
* @param {boolean} [passive] If true, the setter will not notify listeners when the value changes.
|
|
55
56
|
* @returns {(value: T) => void}
|
|
56
57
|
* @template T
|
|
57
58
|
*/
|
|
58
|
-
allocateSetter<T>(paramName: string, initialValue: T): (value: T) => void;
|
|
59
|
+
allocateSetter<T>(paramName: string, initialValue: T, passive?: boolean): (value: T) => void;
|
|
59
60
|
/**
|
|
60
61
|
* Gets an existing setter for a parameter. Throws if the setter is not found.
|
|
61
62
|
* @param {string} paramName
|
|
@@ -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":"AAuQA;;;GAGG;AACH,6BAHW,GAAG,+CAKb;AAED;;;;;;;GAOG;AACH,oFASC;AAED;;;;;;;;;;GAUG;AACH,mFANW,aAAa,+CAEW,IAAI,KAwCtC;AA9UD;;;;;GAKG;AACH;IA2BI;;;;;OAKG;IACH,2BALW,MAAM,aAAa,EAU7B;IA7BD;;;OAGG;IACH,0BAHU,IAAI,MAAM,EAAE,IAAI,MAAM,IAAI,CAAC,CAAC,CAGvB;IA2Bf;;;OAGG;IACH,gFAzCqB,GAAG,KAAK,IAAI,CAkEhC;IAED;;;;;;;OAOG;IACH,6BANW,MAAM,6BAEN,OAAO,iBACS,IAAI,CA8B9B;IAED;;;OAGG;IACH,qBAFW,MAAM,WA/Fc,GAAG,KAAK,IAAI,CAuG1C;IAED;;;OAGG;IACH,oBAFW,MAAM,OAIhB;IAED;;;OAGG;IACH,qBAFW,MAAM,OAKhB;IAED;;OAEG;IACH,0FAIC;IAED;;;;;OAKG;IACH,0CAJW,MAAM,GACJ,aAAa,CASzB;IAID;;;;OAIG;IACH,uBAFW,MAAM,mBA4EhB;IAED;;;;OAIG;IACH,qBAFW,MAAM,OAKhB;;CACJ;;;;;;4BA9P4F,MAAM,IAAI,KAAK,IAAI;gBAAc,MAAM,IAAI;gBAAc,MAAM,MAAM"}
|
|
@@ -82,10 +82,11 @@ export default class ParamMediator {
|
|
|
82
82
|
*
|
|
83
83
|
* @param {string} paramName
|
|
84
84
|
* @param {T} initialValue
|
|
85
|
+
* @param {boolean} [passive] If true, the setter will not notify listeners when the value changes.
|
|
85
86
|
* @returns {(value: T) => void}
|
|
86
87
|
* @template T
|
|
87
88
|
*/
|
|
88
|
-
allocateSetter(paramName, initialValue) {
|
|
89
|
+
allocateSetter(paramName, initialValue, passive = false) {
|
|
89
90
|
if (this.#allocatedSetters.has(paramName)) {
|
|
90
91
|
throw new Error(
|
|
91
92
|
"Setter already allocated for parameter: " + paramName
|
|
@@ -99,7 +100,7 @@ export default class ParamMediator {
|
|
|
99
100
|
this.#paramValues.set(paramName, value);
|
|
100
101
|
|
|
101
102
|
const listeners = this.paramListeners.get(paramName);
|
|
102
|
-
if (listeners) {
|
|
103
|
+
if (listeners && !passive) {
|
|
103
104
|
for (const listener of listeners) {
|
|
104
105
|
listener();
|
|
105
106
|
}
|
|
@@ -55,6 +55,19 @@ describe("Single-level ParamMediator", () => {
|
|
|
55
55
|
expect(calls).toBe(2);
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
+
test("Passive parameter does not trigger listeners", () => {
|
|
59
|
+
const pm = new ParamMediator();
|
|
60
|
+
const setter = pm.allocateSetter("foo", 42, true);
|
|
61
|
+
const expr = pm.createExpression("foo");
|
|
62
|
+
|
|
63
|
+
let result = expr();
|
|
64
|
+
|
|
65
|
+
expr.addListener(() => (result = expr()));
|
|
66
|
+
|
|
67
|
+
setter(50);
|
|
68
|
+
expect(result).toBe(42);
|
|
69
|
+
});
|
|
70
|
+
|
|
58
71
|
test("Expression invalidation", () => {
|
|
59
72
|
const pm = new ParamMediator();
|
|
60
73
|
const setter = pm.allocateSetter("foo", 42);
|
|
@@ -55,7 +55,7 @@ export function isSampleSpec(spec: import("../spec/view.js").ViewSpec): spec is
|
|
|
55
55
|
export const VIEW_ROOT_NAME: "viewRoot";
|
|
56
56
|
/**
|
|
57
57
|
* @typedef {object} ViewFactoryOptions
|
|
58
|
-
* @property {boolean} [allowImport]
|
|
58
|
+
* @property {boolean} [allowImport] allows imports from urls
|
|
59
59
|
* @property {boolean} [wrapRoot]
|
|
60
60
|
*/
|
|
61
61
|
/**
|
|
@@ -102,6 +102,9 @@ export class ViewFactory {
|
|
|
102
102
|
#private;
|
|
103
103
|
}
|
|
104
104
|
export type ViewFactoryOptions = {
|
|
105
|
+
/**
|
|
106
|
+
* allows imports from urls
|
|
107
|
+
*/
|
|
105
108
|
allowImport?: boolean;
|
|
106
109
|
wrapRoot?: boolean;
|
|
107
110
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewFactory.d.ts","sourceRoot":"","sources":["../../../src/view/viewFactory.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"viewFactory.d.ts","sourceRoot":"","sources":["../../../src/view/viewFactory.js"],"names":[],"mappings":"AAgRA;;;;GAIG;AACH,iHAEC;AAED;;;;GAIG;AACH,mHAEC;AAED;;;;GAIG;AACH,mHAOC;AAED;;;;GAIG;AACH,yIAMC;AAED;;;;GAIG;AACH,mCAHW,MAAM,gDAKhB;AAED;;;;GAIG;AACH,uHAEC;AAED;;;;GAIG;AACH,6FAEC;AAED;;;;GAIG;AACH,qHAEC;AAED;;;;GAIG;AACH,2HAOC;AAlWD,wCAAyC;AAEzC;;;;GAIG;AAEH;;GAEG;AACH;IAiBI;;OAEG;IACH,sBAFW,kBAAkB,EAoC5B;IAjCG,2CAA2C;IAC3C,SADW,SAAS,kBAAkB,CAAC,CAKtC;IA8BL;;;OAGG;IACH,qEAlDiC,OAAO,yHAC2B,OAAO,oBAAoB,EAAE,OAAO,eAAe,OAAO,WAAW,EAAE,OAAO,gBAAgB,MAAM,KAAK,IAAI,QAmD/K;IAED;;;;;;OAMG;IACH,wHAJW,OAAO,oBAAoB,EAAE,OAAO,eACpC,OAAO,WAAW,EAAE,OAAO,gBAC3B,MAAM,QAmBhB;IAED;;;;OAIG;IACH,iGAQC;IAED;;;;;;;;;;OAUG;IACH,uKALW,OAAO,oBAAoB,EAAE,OAAO,eACpC,OAAO,WAAW,EAAE,OAAO,gBAC3B,MAAM,4DACc,IAAI,iBAuElC;;CACJ;;;;;kBAjMa,OAAO;eACP,OAAO;;iBAfJ,WAAW"}
|
|
@@ -13,7 +13,7 @@ export const VIEW_ROOT_NAME = "viewRoot";
|
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* @typedef {object} ViewFactoryOptions
|
|
16
|
-
* @property {boolean} [allowImport]
|
|
16
|
+
* @property {boolean} [allowImport] allows imports from urls
|
|
17
17
|
* @property {boolean} [wrapRoot]
|
|
18
18
|
*/
|
|
19
19
|
|
|
@@ -148,24 +148,33 @@ export class ViewFactory {
|
|
|
148
148
|
let viewSpec;
|
|
149
149
|
|
|
150
150
|
if (isImportSpec(spec)) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
spec,
|
|
154
|
-
dataParent.getBaseUrl(),
|
|
155
|
-
context
|
|
156
|
-
);
|
|
151
|
+
/** @type {ViewSpec} */
|
|
152
|
+
let importedSpec;
|
|
157
153
|
|
|
158
|
-
|
|
159
|
-
|
|
154
|
+
if ("url" in spec.import) {
|
|
155
|
+
if (this.options.allowImport) {
|
|
156
|
+
importedSpec = await loadExternalViewSpec(
|
|
157
|
+
spec,
|
|
158
|
+
dataParent.getBaseUrl(),
|
|
159
|
+
context
|
|
160
|
+
);
|
|
161
|
+
} else {
|
|
162
|
+
throw new ViewError(
|
|
163
|
+
"Importing views is not allowed!",
|
|
164
|
+
layoutParent
|
|
165
|
+
);
|
|
160
166
|
}
|
|
161
|
-
|
|
162
|
-
|
|
167
|
+
} else if ("template" in spec.import) {
|
|
168
|
+
importedSpec = findTemplate(spec.import.template, dataParent);
|
|
163
169
|
} else {
|
|
164
|
-
throw new
|
|
165
|
-
"Importing views is not allowed!",
|
|
166
|
-
layoutParent
|
|
167
|
-
);
|
|
170
|
+
throw new Error("Invalid import: " + JSON.stringify(spec));
|
|
168
171
|
}
|
|
172
|
+
|
|
173
|
+
validator?.(importedSpec);
|
|
174
|
+
|
|
175
|
+
applyParamsToImportedSpec(importedSpec, spec);
|
|
176
|
+
|
|
177
|
+
viewSpec = importedSpec;
|
|
169
178
|
} else {
|
|
170
179
|
viewSpec = spec;
|
|
171
180
|
}
|
|
@@ -200,19 +209,38 @@ export class ViewFactory {
|
|
|
200
209
|
}
|
|
201
210
|
|
|
202
211
|
/**
|
|
203
|
-
*
|
|
212
|
+
* @param {string} name
|
|
213
|
+
* @param {View} view Start searching from this view, then search within its parent, etc.
|
|
214
|
+
*/
|
|
215
|
+
function findTemplate(name, view) {
|
|
216
|
+
const template = view.spec?.templates?.[name];
|
|
217
|
+
if (template) {
|
|
218
|
+
// Ensure that the template is not altered
|
|
219
|
+
return structuredClone(template);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (view.dataParent) {
|
|
223
|
+
return findTemplate(name, view.dataParent);
|
|
224
|
+
} else {
|
|
225
|
+
throw new Error(
|
|
226
|
+
`Cannot find template "${name}" in current view or its ancestors!`
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
204
232
|
* @param {ViewSpec} importedSpec
|
|
205
|
-
* @param {import("../spec/view.js").
|
|
233
|
+
* @param {import("../spec/view.js").ImportSpec} importSpec
|
|
206
234
|
*/
|
|
207
|
-
function applyParamsToImportedSpec(importedSpec,
|
|
208
|
-
if (
|
|
209
|
-
importedSpec.name =
|
|
235
|
+
function applyParamsToImportedSpec(importedSpec, importSpec) {
|
|
236
|
+
if (importSpec.name != null) {
|
|
237
|
+
importedSpec.name = importSpec.name;
|
|
210
238
|
}
|
|
211
239
|
|
|
212
|
-
const params = isArray(
|
|
213
|
-
?
|
|
214
|
-
: isObject(
|
|
215
|
-
? Object.entries(
|
|
240
|
+
const params = isArray(importSpec.params)
|
|
241
|
+
? importSpec.params
|
|
242
|
+
: isObject(importSpec.params)
|
|
243
|
+
? Object.entries(importSpec.params).map(([name, value]) => ({
|
|
216
244
|
name,
|
|
217
245
|
value,
|
|
218
246
|
}))
|
|
@@ -10,12 +10,6 @@ export function isFacetFieldDef(def: import("../spec/channel.js").ChannelDef | i
|
|
|
10
10
|
* @returns {spec is FacetMapping}
|
|
11
11
|
*/
|
|
12
12
|
export function isFacetMapping(def: import("../spec/channel.js").FacetFieldDef | import("../spec/view.js").FacetMapping): spec is FacetMapping;
|
|
13
|
-
/**
|
|
14
|
-
*
|
|
15
|
-
* @param {object} config
|
|
16
|
-
* @returns {config is ImportConfig}
|
|
17
|
-
*/
|
|
18
|
-
export function isImportConfig(config: object): config is ImportConfig;
|
|
19
13
|
/**
|
|
20
14
|
* Returns all marks in the order (DFS) they are rendered
|
|
21
15
|
* @param {View} root
|
|
@@ -60,8 +54,9 @@ export function findEncodedFields(view: View): {
|
|
|
60
54
|
* @param {import("../spec/view.js").ImportSpec} spec
|
|
61
55
|
* @param {string} baseUrl
|
|
62
56
|
* @param {import("../types/viewContext.js").default} viewContext
|
|
57
|
+
* @returns {Promise<import("../spec/view.js").ViewSpec>}
|
|
63
58
|
*/
|
|
64
|
-
export function loadExternalViewSpec(spec: import("../spec/view.js").ImportSpec, baseUrl: string, viewContext: import("../types/viewContext.js").default): Promise<
|
|
59
|
+
export function loadExternalViewSpec(spec: import("../spec/view.js").ImportSpec, baseUrl: string, viewContext: import("../types/viewContext.js").default): Promise<import("../spec/view.js").ViewSpec>;
|
|
65
60
|
/**
|
|
66
61
|
* @param {function(View, View[]):void} visitor
|
|
67
62
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewUtils.d.ts","sourceRoot":"","sources":["../../../src/view/viewUtils.js"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,qCAHW,OAAO,oBAAoB,EAAE,UAAU,GAAG,OAAO,iBAAiB,EAAE,YAAY,yBAK1F;AAED;;;;GAIG;AACH,oCAHW,OAAO,oBAAoB,EAAE,aAAa,GAAG,OAAO,iBAAiB,EAAE,YAAY,wBAQ7F;AAED
|
|
1
|
+
{"version":3,"file":"viewUtils.d.ts","sourceRoot":"","sources":["../../../src/view/viewUtils.js"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,qCAHW,OAAO,oBAAoB,EAAE,UAAU,GAAG,OAAO,iBAAiB,EAAE,YAAY,yBAK1F;AAED;;;;GAIG;AACH,oCAHW,OAAO,oBAAoB,EAAE,aAAa,GAAG,OAAO,iBAAiB,EAAE,YAAY,wBAQ7F;AAED;;;GAGG;AACH,+BAFW,IAAI,wCAMd;AAED;;;;GAIG;AACH,wCAFW,IAAI,UASd;AAED;;GAEG;AACH,kDAFW,IAAI,QAiBd;AAED;;;;;;;GAOG;AACH,4CAFW,IAAI,QAUd;AAED;;;;GAIG;AACH,qCAJW,IAAI,iBACJ,OAAO,qBAAqB,EAAE,OAAO,CAAC,IAAI,CAAC,wDAcrD;AAED;;;GAGG;AACH,wCAFW,IAAI;UAGO,QAAQ;aAAW,OAAO,oBAAoB,EAAE,OAAO;WAAS,OAAO,oBAAoB,EAAE,KAAK;UAAQ,OAAO,oBAAoB,EAAE,IAAI;IAqBhK;AAED;;;;;GAKG;AACH,2CALW,OAAO,iBAAiB,EAAE,UAAU,WACpC,MAAM,eACN,OAAO,yBAAyB,EAAE,OAAO,GACvC,QAAQ,OAAO,iBAAiB,EAAE,QAAQ,CAAC,CA6BvD;AAED;;GAEG;AACH,gDAFoB,IAAI,QAAE,IAAI,EAAE,KAAE,IAAI,+BAkBrC;AAED;;;;;;GAMG;AACH,4CAJW,IAAI,QACJ,MAAM,GACJ,IAAI,EAAE,CAalB;AAED;;;GAGG;AACH,0CAFW,IAAI,eAqBd;AAOD;;GAEG;AACH,gDAFW,IAAI,mDAId;AAED;;GAEG;AACH,kDAFW,OAAO,wBAAwB,EAAE,cAAc;;;EAczD;AAxBM,uCAFI,MAAM,WAE0D;iBA/O9B,WAAW;qBAFnC,eAAe"}
|
|
@@ -30,15 +30,6 @@ export function isFacetMapping(def) {
|
|
|
30
30
|
);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
/**
|
|
34
|
-
*
|
|
35
|
-
* @param {object} config
|
|
36
|
-
* @returns {config is ImportConfig}
|
|
37
|
-
*/
|
|
38
|
-
export function isImportConfig(config) {
|
|
39
|
-
return "name" in config || "url" in config;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
33
|
/**
|
|
43
34
|
* Returns all marks in the order (DFS) they are rendered
|
|
44
35
|
* @param {View} root
|
|
@@ -151,34 +142,34 @@ export function findEncodedFields(view) {
|
|
|
151
142
|
* @param {import("../spec/view.js").ImportSpec} spec
|
|
152
143
|
* @param {string} baseUrl
|
|
153
144
|
* @param {import("../types/viewContext.js").default} viewContext
|
|
145
|
+
* @returns {Promise<import("../spec/view.js").ViewSpec>}
|
|
154
146
|
*/
|
|
155
147
|
export async function loadExternalViewSpec(spec, baseUrl, viewContext) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
148
|
+
const importParam = spec.import;
|
|
149
|
+
if ("url" in importParam) {
|
|
150
|
+
const loader = vegaLoader({ baseURL: baseUrl });
|
|
151
|
+
const url = importParam.url;
|
|
161
152
|
|
|
162
|
-
|
|
163
|
-
|
|
153
|
+
const importedSpec = JSON.parse(
|
|
154
|
+
await loader.load(url).catch((/** @type {Error} */ e) => {
|
|
155
|
+
throw new Error(
|
|
156
|
+
`Could not load imported view spec: ${url} \nReason: ${e.message}`
|
|
157
|
+
);
|
|
158
|
+
})
|
|
159
|
+
);
|
|
164
160
|
|
|
165
|
-
|
|
166
|
-
|
|
161
|
+
if (viewContext.isViewSpec(importedSpec)) {
|
|
162
|
+
importedSpec.baseUrl = url.match(/^[^?#]*\//)?.[0];
|
|
163
|
+
return importedSpec;
|
|
164
|
+
} else {
|
|
167
165
|
throw new Error(
|
|
168
|
-
`
|
|
166
|
+
`The imported spec "${url}" is not a view spec: ${JSON.stringify(
|
|
167
|
+
spec
|
|
168
|
+
)}`
|
|
169
169
|
);
|
|
170
|
-
}
|
|
171
|
-
);
|
|
172
|
-
|
|
173
|
-
if (viewContext.isViewSpec(importedSpec)) {
|
|
174
|
-
importedSpec.baseUrl = url.match(/^[^?#]*\//)?.[0];
|
|
175
|
-
return importedSpec;
|
|
170
|
+
}
|
|
176
171
|
} else {
|
|
177
|
-
throw new Error(
|
|
178
|
-
`The imported spec "${url}" is not a view spec: ${JSON.stringify(
|
|
179
|
-
spec
|
|
180
|
-
)}`
|
|
181
|
-
);
|
|
172
|
+
throw new Error("Not an url import: " + JSON.stringify(importParam));
|
|
182
173
|
}
|
|
183
174
|
}
|
|
184
175
|
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"contributors": [],
|
|
9
9
|
"license": "MIT",
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.46.0",
|
|
11
11
|
"jsdelivr": "dist/bundle/index.js",
|
|
12
12
|
"unpkg": "dist/bundle/index.js",
|
|
13
13
|
"browser": "dist/bundle/index.js",
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"vega-scale": "^7.3.1",
|
|
65
65
|
"vega-util": "^1.17.2"
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "cb5df0a9b0ea35b7325e148d34d0184a6384da85"
|
|
68
68
|
}
|
/package/dist/bundle/{__vite-browser-external-ENoMJThg.js → __vite-browser-external-C--ziKoh.js}
RENAMED
|
File without changes
|
|
File without changes
|