@vitessce/config 3.3.1 → 3.3.3
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/index.js +107 -13
- package/dist-tsc/VitessceConfig.d.ts +25 -4
- package/dist-tsc/VitessceConfig.d.ts.map +1 -1
- package/dist-tsc/VitessceConfig.js +59 -8
- package/dist-tsc/VitessceConfig.test.js +105 -0
- package/dist-tsc/index.d.ts +1 -1
- package/dist-tsc/index.js +2 -1
- package/package.json +3 -3
- package/src/VitessceConfig.js +64 -9
- package/src/VitessceConfig.test.js +110 -0
- package/src/index.js +5 -1
package/dist/index.js
CHANGED
|
@@ -44,7 +44,9 @@ const FileType$1 = {
|
|
|
44
44
|
OBS_SEGMENTATIONS_JSON: "obsSegmentations.json",
|
|
45
45
|
OBS_SETS_CSV: "obsSets.csv",
|
|
46
46
|
OBS_SETS_JSON: "obsSets.json",
|
|
47
|
+
// OME-Zarr
|
|
47
48
|
IMAGE_OME_ZARR: "image.ome-zarr",
|
|
49
|
+
OBS_SEGMENTATIONS_OME_ZARR: "obsSegmentations.ome-zarr",
|
|
48
50
|
// AnnData
|
|
49
51
|
OBS_FEATURE_MATRIX_ANNDATA_ZARR: "obsFeatureMatrix.anndata.zarr",
|
|
50
52
|
OBS_SETS_ANNDATA_ZARR: "obsSets.anndata.zarr",
|
|
@@ -645,6 +647,24 @@ function getNextScope(prevScopes) {
|
|
|
645
647
|
} while (prevScopes.includes(nextScope));
|
|
646
648
|
return nextScope;
|
|
647
649
|
}
|
|
650
|
+
function createPrefixedGetNextScopeNumeric(prefix) {
|
|
651
|
+
return (prevScopes) => {
|
|
652
|
+
let nextScopeInt = 0;
|
|
653
|
+
let nextScopeStr;
|
|
654
|
+
do {
|
|
655
|
+
nextScopeStr = `${prefix}${nextScopeInt}`;
|
|
656
|
+
nextScopeInt += 1;
|
|
657
|
+
} while (prevScopes.includes(nextScopeStr));
|
|
658
|
+
return nextScopeStr;
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
function getInitialCoordinationScopePrefix(datasetUid, dataType) {
|
|
662
|
+
return `init_${datasetUid}_${dataType}_`;
|
|
663
|
+
}
|
|
664
|
+
function getInitialCoordinationScopeName(datasetUid, dataType, i = null) {
|
|
665
|
+
const prefix = getInitialCoordinationScopePrefix(datasetUid, dataType);
|
|
666
|
+
return `${prefix}${i === null ? 0 : i}`;
|
|
667
|
+
}
|
|
648
668
|
let getRandomValues;
|
|
649
669
|
const rnds8 = new Uint8Array(16);
|
|
650
670
|
function rng() {
|
|
@@ -8990,30 +9010,39 @@ const omeCoordinateTransformations = z.array(z.union([
|
|
|
8990
9010
|
scale: z.array(z.number())
|
|
8991
9011
|
})
|
|
8992
9012
|
]));
|
|
8993
|
-
z.object({
|
|
9013
|
+
const imageOmeTiffSchema = z.object({
|
|
8994
9014
|
offsetsUrl: z.string().optional(),
|
|
8995
9015
|
coordinateTransformations: omeCoordinateTransformations.optional()
|
|
8996
9016
|
});
|
|
9017
|
+
imageOmeTiffSchema.extend({
|
|
9018
|
+
obsTypesFromChannelNames: z.boolean().optional()
|
|
9019
|
+
});
|
|
8997
9020
|
const imageOmeZarrSchema = z.object({
|
|
8998
9021
|
coordinateTransformations: omeCoordinateTransformations.optional()
|
|
8999
9022
|
});
|
|
9000
9023
|
imageOmeZarrSchema.extend({
|
|
9024
|
+
obsTypesFromChannelNames: z.boolean().optional()
|
|
9025
|
+
});
|
|
9026
|
+
const imageSpatialdataSchema = imageOmeZarrSchema.extend({
|
|
9001
9027
|
path: z.string()
|
|
9002
9028
|
});
|
|
9003
|
-
z.object({
|
|
9029
|
+
const obsSegmentationsSpatialdataSchema = z.object({
|
|
9030
|
+
// TODO: should this also extend the imageOmeZarrSchema?
|
|
9031
|
+
// TODO: should this be renamed labelsSpatialdataSchema?
|
|
9032
|
+
// TODO: support obsTypesFromChannelNames?
|
|
9004
9033
|
path: z.string()
|
|
9005
9034
|
});
|
|
9006
9035
|
z.object({
|
|
9007
9036
|
path: z.string()
|
|
9008
9037
|
});
|
|
9009
|
-
z.object({
|
|
9038
|
+
const obsSpotsSpatialdataSchema = z.object({
|
|
9010
9039
|
path: z.string(),
|
|
9011
9040
|
tablePath: z.string().optional().describe("The path to a table which annotates the spots. If available but not specified, the spot identifiers may not be aligned with associated tabular data as expected.")
|
|
9012
9041
|
});
|
|
9013
|
-
annDataObsFeatureMatrix.extend({
|
|
9042
|
+
const obsFeatureMatrixSpatialdataSchema = annDataObsFeatureMatrix.extend({
|
|
9014
9043
|
region: z.string().describe("The name of a region to use to filter instances (i.e., rows) in the table").optional()
|
|
9015
9044
|
});
|
|
9016
|
-
z.object({
|
|
9045
|
+
const obsSetsSpatialdataSchema = z.object({
|
|
9017
9046
|
region: z.string().describe("The name of a region to use to filter instances (i.e., rows) in the table").optional(),
|
|
9018
9047
|
tablePath: z.string().optional().describe("The path to a table which contains the index for the set values."),
|
|
9019
9048
|
obsSets: annDataObsSets
|
|
@@ -9076,6 +9105,19 @@ z.object({
|
|
|
9076
9105
|
z.array(annDataConvenienceObsEmbeddingItem)
|
|
9077
9106
|
])
|
|
9078
9107
|
}).partial();
|
|
9108
|
+
z.object({
|
|
9109
|
+
// TODO: should `image` be a special schema
|
|
9110
|
+
// to allow specifying fileUid (like for embeddingType)?
|
|
9111
|
+
image: imageSpatialdataSchema,
|
|
9112
|
+
// TODO: should this be a special schema
|
|
9113
|
+
// to allow specifying fileUid (like for embeddingType)?
|
|
9114
|
+
labels: obsSegmentationsSpatialdataSchema,
|
|
9115
|
+
obsFeatureMatrix: obsFeatureMatrixSpatialdataSchema,
|
|
9116
|
+
obsSpots: obsSpotsSpatialdataSchema,
|
|
9117
|
+
// TODO: obsPoints
|
|
9118
|
+
// TODO: obsLocations
|
|
9119
|
+
obsSets: obsSetsSpatialdataSchema
|
|
9120
|
+
}).partial();
|
|
9079
9121
|
z.object({
|
|
9080
9122
|
obsLabelsTypes: z.array(z.string()).optional(),
|
|
9081
9123
|
embeddingTypes: z.array(z.string()).optional()
|
|
@@ -15921,11 +15963,12 @@ class VitessceConfigCoordinationScope {
|
|
|
15921
15963
|
* Construct a new coordination scope instance.
|
|
15922
15964
|
* @param {string} cType The coordination type for this coordination scope.
|
|
15923
15965
|
* @param {string} cScope The name of the coordination scope.
|
|
15966
|
+
* @param {[any]} cValue Optional. The coordination value of the coordination scope.
|
|
15924
15967
|
*/
|
|
15925
|
-
constructor(cType, cScope) {
|
|
15968
|
+
constructor(cType, cScope, cValue = null) {
|
|
15926
15969
|
this.cType = cType;
|
|
15927
15970
|
this.cScope = cScope;
|
|
15928
|
-
this.cValue =
|
|
15971
|
+
this.cValue = cValue;
|
|
15929
15972
|
}
|
|
15930
15973
|
/**
|
|
15931
15974
|
* Set the coordination value of the coordination scope.
|
|
@@ -16032,6 +16075,7 @@ class VitessceConfig {
|
|
|
16032
16075
|
layout: [],
|
|
16033
16076
|
initStrategy: "auto"
|
|
16034
16077
|
};
|
|
16078
|
+
this.getNextScope = getNextScope;
|
|
16035
16079
|
}
|
|
16036
16080
|
/**
|
|
16037
16081
|
* Add a new dataset to the config.
|
|
@@ -16045,7 +16089,7 @@ class VitessceConfig {
|
|
|
16045
16089
|
addDataset(name = void 0, description = void 0, options = void 0) {
|
|
16046
16090
|
const { uid } = options || {};
|
|
16047
16091
|
const prevDatasetUids = this.config.datasets.map((d) => d.dataset.uid);
|
|
16048
|
-
const nextUid = uid || getNextScope(prevDatasetUids);
|
|
16092
|
+
const nextUid = uid || this.getNextScope(prevDatasetUids);
|
|
16049
16093
|
const newDataset = new VitessceConfigDataset(nextUid, name, description);
|
|
16050
16094
|
this.config.datasets.push(newDataset);
|
|
16051
16095
|
const [newScope] = this.addCoordination(CoordinationType$1.DATASET);
|
|
@@ -16104,7 +16148,7 @@ class VitessceConfig {
|
|
|
16104
16148
|
const result = [];
|
|
16105
16149
|
cTypes.forEach((cType) => {
|
|
16106
16150
|
const prevScopes = this.config.coordinationSpace[cType] ? Object.keys(this.config.coordinationSpace[cType]) : [];
|
|
16107
|
-
const scope = new VitessceConfigCoordinationScope(cType, getNextScope(prevScopes));
|
|
16151
|
+
const scope = new VitessceConfigCoordinationScope(cType, this.getNextScope(prevScopes));
|
|
16108
16152
|
if (!this.config.coordinationSpace[scope.cType]) {
|
|
16109
16153
|
this.config.coordinationSpace[scope.cType] = {};
|
|
16110
16154
|
}
|
|
@@ -16122,8 +16166,8 @@ class VitessceConfig {
|
|
|
16122
16166
|
const prevMetaScopes = this.config.coordinationSpace[CoordinationType$1.META_COORDINATION_SCOPES] ? Object.keys(this.config.coordinationSpace[CoordinationType$1.META_COORDINATION_SCOPES]) : [];
|
|
16123
16167
|
const prevMetaByScopes = this.config.coordinationSpace[CoordinationType$1.META_COORDINATION_SCOPES_BY] ? Object.keys(this.config.coordinationSpace[CoordinationType$1.META_COORDINATION_SCOPES_BY]) : [];
|
|
16124
16168
|
const metaContainer = new VitessceConfigMetaCoordinationScope(
|
|
16125
|
-
getNextScope(prevMetaScopes),
|
|
16126
|
-
getNextScope(prevMetaByScopes)
|
|
16169
|
+
this.getNextScope(prevMetaScopes),
|
|
16170
|
+
this.getNextScope(prevMetaByScopes)
|
|
16127
16171
|
);
|
|
16128
16172
|
if (!this.config.coordinationSpace[CoordinationType$1.META_COORDINATION_SCOPES]) {
|
|
16129
16173
|
this.config.coordinationSpace[CoordinationType$1.META_COORDINATION_SCOPES] = {};
|
|
@@ -16151,6 +16195,9 @@ class VitessceConfig {
|
|
|
16151
16195
|
addCoordinationByObject(input) {
|
|
16152
16196
|
const processLevel = (level) => {
|
|
16153
16197
|
const result = {};
|
|
16198
|
+
if (level === null) {
|
|
16199
|
+
return result;
|
|
16200
|
+
}
|
|
16154
16201
|
Object.entries(level).forEach(([cType, nextLevelOrInitialValue]) => {
|
|
16155
16202
|
if (nextLevelOrInitialValue instanceof CoordinationLevel) {
|
|
16156
16203
|
const nextLevel = nextLevelOrInitialValue.value;
|
|
@@ -16225,10 +16272,18 @@ class VitessceConfig {
|
|
|
16225
16272
|
* instance, or a `CoordinationLevel` instance.
|
|
16226
16273
|
* The CL function takes an array of objects as its argument, and returns a CoordinationLevel
|
|
16227
16274
|
* instance, to support nesting.
|
|
16228
|
-
* @param {
|
|
16275
|
+
* @param {object|null} options
|
|
16276
|
+
* @param {bool} options.meta Should meta-coordination be used? Optional.
|
|
16277
|
+
* By default, true.
|
|
16278
|
+
* @param {string|null} options.scopePrefix A prefix to add to all
|
|
16279
|
+
* coordination scope names. Optional.
|
|
16229
16280
|
* @returns {VitessceConfig} This, to allow chaining.
|
|
16230
16281
|
*/
|
|
16231
|
-
linkViewsByObject(views, input,
|
|
16282
|
+
linkViewsByObject(views, input, options = null) {
|
|
16283
|
+
const { meta = true, scopePrefix = null } = options || {};
|
|
16284
|
+
if (scopePrefix) {
|
|
16285
|
+
this.getNextScope = createPrefixedGetNextScopeNumeric(scopePrefix);
|
|
16286
|
+
}
|
|
16232
16287
|
const scopes = this.addCoordinationByObject(input);
|
|
16233
16288
|
if (meta) {
|
|
16234
16289
|
const metaScope = this.addMetaCoordination();
|
|
@@ -16241,8 +16296,28 @@ class VitessceConfig {
|
|
|
16241
16296
|
view.useCoordinationByObject(scopes);
|
|
16242
16297
|
});
|
|
16243
16298
|
}
|
|
16299
|
+
if (scopePrefix) {
|
|
16300
|
+
this.getNextScope = getNextScope;
|
|
16301
|
+
}
|
|
16244
16302
|
return this;
|
|
16245
16303
|
}
|
|
16304
|
+
/**
|
|
16305
|
+
* Set the value for a coordination scope.
|
|
16306
|
+
* If a coordination object for the coordination type does not yet exist
|
|
16307
|
+
* in the coordination space, it will be created.
|
|
16308
|
+
* @param {string} cType The coordination type.
|
|
16309
|
+
* @param {string} cScope The coordination scope.
|
|
16310
|
+
* @param {any} cValue The initial value for the coordination scope.
|
|
16311
|
+
* @returns {VitessceConfigCoordinationScope} A coordination scope instance.
|
|
16312
|
+
*/
|
|
16313
|
+
setCoordinationValue(cType, cScope, cValue) {
|
|
16314
|
+
const scope = new VitessceConfigCoordinationScope(cType, cScope, cValue);
|
|
16315
|
+
if (!this.config.coordinationSpace[scope.cType]) {
|
|
16316
|
+
this.config.coordinationSpace[scope.cType] = {};
|
|
16317
|
+
}
|
|
16318
|
+
this.config.coordinationSpace[scope.cType][scope.cScope] = scope;
|
|
16319
|
+
return scope;
|
|
16320
|
+
}
|
|
16246
16321
|
/**
|
|
16247
16322
|
* Set the layout of views.
|
|
16248
16323
|
* @param {VitessceConfigView|VitessceConfigViewHConcat|VitessceConfigViewVConcat} viewConcat A
|
|
@@ -16333,6 +16408,22 @@ class VitessceConfig {
|
|
|
16333
16408
|
return vc;
|
|
16334
16409
|
}
|
|
16335
16410
|
}
|
|
16411
|
+
function getCoordinationSpaceAndScopes(partialCoordinationValues, scopePrefix) {
|
|
16412
|
+
const vc = new VitessceConfig({ schemaVersion: "1.0.16", name: "__dummy__" });
|
|
16413
|
+
vc.getNextScope = createPrefixedGetNextScopeNumeric(scopePrefix);
|
|
16414
|
+
const dataset = vc.addDataset("__dummy__");
|
|
16415
|
+
const v1 = vc.addView(dataset, "__dummy__");
|
|
16416
|
+
vc.linkViewsByObject([v1], partialCoordinationValues, { meta: true });
|
|
16417
|
+
const vcJson = vc.toJSON();
|
|
16418
|
+
const { coordinationSpace } = vcJson;
|
|
16419
|
+
const { coordinationScopes } = vcJson.layout[0];
|
|
16420
|
+
const { coordinationScopesBy } = vcJson.layout[0];
|
|
16421
|
+
return {
|
|
16422
|
+
coordinationSpace,
|
|
16423
|
+
coordinationScopes,
|
|
16424
|
+
coordinationScopesBy
|
|
16425
|
+
};
|
|
16426
|
+
}
|
|
16336
16427
|
const SINGLE_CELL_WITH_HEATMAP_VIEWS = {
|
|
16337
16428
|
obsSets: { x: 4, y: 0, w: 4, h: 4 },
|
|
16338
16429
|
obsSetSizes: { x: 8, y: 0, w: 4, h: 4 },
|
|
@@ -16948,7 +17039,10 @@ export {
|
|
|
16948
17039
|
HINT_TYPE_TO_FILE_TYPE_MAP,
|
|
16949
17040
|
VitessceConfig,
|
|
16950
17041
|
generateConfig,
|
|
17042
|
+
getCoordinationSpaceAndScopes,
|
|
16951
17043
|
getHintOptions,
|
|
17044
|
+
getInitialCoordinationScopeName,
|
|
17045
|
+
getInitialCoordinationScopePrefix,
|
|
16952
17046
|
hconcat,
|
|
16953
17047
|
vconcat
|
|
16954
17048
|
};
|
|
@@ -13,6 +13,11 @@ export function hconcat(...views: (VitessceConfigView | VitessceConfigViewHConca
|
|
|
13
13
|
*/
|
|
14
14
|
export function vconcat(...views: (VitessceConfigView | VitessceConfigViewHConcat | VitessceConfigViewVConcat)[]): VitessceConfigViewVConcat;
|
|
15
15
|
export function CL(value: any): CoordinationLevel;
|
|
16
|
+
export function getCoordinationSpaceAndScopes(partialCoordinationValues: any, scopePrefix: any): {
|
|
17
|
+
coordinationSpace: any;
|
|
18
|
+
coordinationScopes: any;
|
|
19
|
+
coordinationScopesBy: any;
|
|
20
|
+
};
|
|
16
21
|
/**
|
|
17
22
|
* Class representing a file within a Vitessce config dataset.
|
|
18
23
|
*/
|
|
@@ -162,11 +167,12 @@ export class VitessceConfigCoordinationScope {
|
|
|
162
167
|
* Construct a new coordination scope instance.
|
|
163
168
|
* @param {string} cType The coordination type for this coordination scope.
|
|
164
169
|
* @param {string} cScope The name of the coordination scope.
|
|
170
|
+
* @param {[any]} cValue Optional. The coordination value of the coordination scope.
|
|
165
171
|
*/
|
|
166
|
-
constructor(cType: string, cScope: string);
|
|
172
|
+
constructor(cType: string, cScope: string, cValue?: [any]);
|
|
167
173
|
cType: string;
|
|
168
174
|
cScope: string;
|
|
169
|
-
cValue: any;
|
|
175
|
+
cValue: [any];
|
|
170
176
|
/**
|
|
171
177
|
* Set the coordination value of the coordination scope.
|
|
172
178
|
* @param {any} cValue The value to set.
|
|
@@ -237,6 +243,7 @@ export class VitessceConfig {
|
|
|
237
243
|
layout: never[];
|
|
238
244
|
initStrategy: string;
|
|
239
245
|
};
|
|
246
|
+
getNextScope: any;
|
|
240
247
|
/**
|
|
241
248
|
* Add a new dataset to the config.
|
|
242
249
|
* @param {string} name A name for the dataset. Optional.
|
|
@@ -315,10 +322,24 @@ export class VitessceConfig {
|
|
|
315
322
|
* instance, or a `CoordinationLevel` instance.
|
|
316
323
|
* The CL function takes an array of objects as its argument, and returns a CoordinationLevel
|
|
317
324
|
* instance, to support nesting.
|
|
318
|
-
* @param {
|
|
325
|
+
* @param {object|null} options
|
|
326
|
+
* @param {bool} options.meta Should meta-coordination be used? Optional.
|
|
327
|
+
* By default, true.
|
|
328
|
+
* @param {string|null} options.scopePrefix A prefix to add to all
|
|
329
|
+
* coordination scope names. Optional.
|
|
319
330
|
* @returns {VitessceConfig} This, to allow chaining.
|
|
320
331
|
*/
|
|
321
|
-
linkViewsByObject(views: VitessceConfigView[], input: object,
|
|
332
|
+
linkViewsByObject(views: VitessceConfigView[], input: object, options?: object | null): VitessceConfig;
|
|
333
|
+
/**
|
|
334
|
+
* Set the value for a coordination scope.
|
|
335
|
+
* If a coordination object for the coordination type does not yet exist
|
|
336
|
+
* in the coordination space, it will be created.
|
|
337
|
+
* @param {string} cType The coordination type.
|
|
338
|
+
* @param {string} cScope The coordination scope.
|
|
339
|
+
* @param {any} cValue The initial value for the coordination scope.
|
|
340
|
+
* @returns {VitessceConfigCoordinationScope} A coordination scope instance.
|
|
341
|
+
*/
|
|
342
|
+
setCoordinationValue(cType: string, cScope: string, cValue: any): VitessceConfigCoordinationScope;
|
|
322
343
|
/**
|
|
323
344
|
* Set the layout of views.
|
|
324
345
|
* @param {VitessceConfigView|VitessceConfigViewHConcat|VitessceConfigViewVConcat} viewConcat A
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VitessceConfig.d.ts","sourceRoot":"","sources":["../src/VitessceConfig.js"],"names":[],"mappings":"AA0XA;;;;;GAKG;AACH,kCAJe,CAAC,kBAAkB,GAAC,yBAAyB,GAAC,yBAAyB,CAAC,KAE1E,yBAAyB,CAKrC;AAED;;;;;GAKG;AACH,kCAJe,CAAC,kBAAkB,GAAC,yBAAyB,GAAC,yBAAyB,CAAC,KAE1E,yBAAyB,CAKrC;AAsBD,kDAEC;
|
|
1
|
+
{"version":3,"file":"VitessceConfig.d.ts","sourceRoot":"","sources":["../src/VitessceConfig.js"],"names":[],"mappings":"AA0XA;;;;;GAKG;AACH,kCAJe,CAAC,kBAAkB,GAAC,yBAAyB,GAAC,yBAAyB,CAAC,KAE1E,yBAAyB,CAKrC;AAED;;;;;GAKG;AACH,kCAJe,CAAC,kBAAkB,GAAC,yBAAyB,GAAC,yBAAyB,CAAC,KAE1E,yBAAyB,CAKrC;AAsBD,kDAEC;AA8kBD;;;;EAiBC;AAjgCD;;GAEG;AACH;IACE;;;;;;;;OAQG;IACH,iBAPW,MAAM,YAEN,MAAM,oCACN,MAAM,WAAO,IAAI,EAW3B;IANC;;;;;MAKC;IAGH;;OAEG;IACH,UAFa,MAAM,CAIlB;CACF;AAED;;GAEG;AACH;IACE;;;;;OAKG;IACH,iBAJW,MAAM,QACN,MAAM,eACN,MAAM,EAShB;IANC;;;;;MAKC;IAGH;;;;;;;;;;OAUG;IACH;QARoC,GAAG,EAA5B,MAAM,GAAC,SAAS;QACD,QAAQ,EAAvB,MAAM;QACmB,kBAAkB,EAA3C,MAAM,GAAC,SAAS;QACe,OAAO,EAAtC,MAAM,WAAO,SAAS;wBAGpB,qBAAqB,CA6BjC;IAED;;OAEG;IACH,UAFa,MAAM,CAOlB;CACF;AA0ID;;GAEG;AACH;IACE;;;;;;;;;OASG;IACH,uBARW,MAAM,sBACN,MAAM,KAEN,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,EAYhB;IATC;;;;;;;;MAQC;IAGH;;;;;OAKG;IACH,yBAJe,+BAA+B,KAEjC,kBAAkB,CAQ9B;IAED;;;;;OAKG;IACH,gCAJW,MAAM,GAEJ,kBAAkB,CAiB9B;IAED;;;;OAIG;IACH,+BAHW,mCAAmC,GACjC,kBAAkB,CAe9B;IAED;;;;;;;QAOI;IACJ,WANY,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,GACJ,kBAAkB,CAS/B;IAED;;;OAGG;IACH,sBAFa,kBAAkB,CAQ9B;IAED;;OAEG;IACH,UAFa,MAAM,CAIlB;CACF;AAED;;GAEG;AACH;IACE,wBAEC;IADC,WAAkB;CAErB;AAED;;GAEG;AACH;IACE,wBAEC;IADC,WAAkB;CAErB;AAgDD;;GAEG;AACH;IACE;;;;;OAKG;IACH,mBAJW,MAAM,UACN,MAAM,WACN,CAAC,GAAG,CAAC,EAMf;IAHC,cAAkB;IAClB,eAAoB;IACpB,cAAoB;IAGtB;;;;OAIG;IACH,iBAHW,GAAG,GACD,+BAA+B,CAK3C;CACF;AAED;;;;GAIG;AACH;IACE;;;;OAIG;IACH,uBAHW,MAAM,eACN,MAAM,EAWhB;IARC,2CAGC;IACD,6CAGC;IAGH;;;;;OAKG;IACH,yBAJe,+BAA+B,KAEjC,mCAAmC,CAU/C;IAED;;;;;;OAMG;IACH,gCAJW,MAAM,GAEJ,kBAAkB,CAiB9B;CACF;AAED;;GAEG;AACH;IAscE;;;;;;OAMG;IACH,wBAJW,MAAM,GACJ,cAAc,CAiC1B;IA1eD;;;;;;OAMG;IACH;QAJ0B,aAAa,EAA5B,MAAM;QACS,IAAI,EAAnB,MAAM;QACmB,WAAW,EAApC,MAAM,GAAC,SAAS;uBAoC1B;IAVC;;;;;;;;MAQC;IACD,kBAAgC;IAGlC;;;;;;;;OAQG;IACH,kBAPW,MAAM,gBACN,MAAM;QAEU,GAAG,EAAnB,MAAM;QAEJ,qBAAqB,CAWjC;IAED;;;;;;;;;;;;;OAaG;IACH,iBAZW,qBAAqB,aAErB,MAAM;QAEU,CAAC,EAAjB,MAAM;QACU,CAAC,EAAjB,MAAM;QACU,CAAC,EAAjB,MAAM;QACU,CAAC,EAAjB,MAAM;QACU,OAAO,EAAvB,MAAM;QAEJ,kBAAkB,CAmC9B;IAED;;;;;OAKG;IACH,yBAHc,MAAM,KACP,+BAA+B,EAAE,CAmB7C;IAED;;;;OAIG;IACH,uBAFa,mCAAmC,CA4B/C;IAED;;;;;;;;;;;;OAYG;IACH,+BATW,MAAM,GAKJ,MAAM,CAuIlB;IAED;;;;;;;OAOG;IACH,iBANW,kBAAkB,EAAE,UACpB,MAAM,EAAE,YACR,GAAG,EAAE,GAEH,cAAc,CAe1B;IAED;;;;;;;;;;;;;;;OAeG;IACH,yBAbW,kBAAkB,EAAE,SACpB,MAAM,YAKN,MAAM,GAAC,IAAI,GAKT,cAAc,CAyB1B;IAED;;;;;;;;OAQG;IACH,4BALW,MAAM,UACN,MAAM,UACN,GAAG,GACD,+BAA+B,CAS3C;IAED;;;;;OAKG;IACH,mBAJW,kBAAkB,GAAC,yBAAyB,GAAC,yBAAyB,GAEpE,cAAc,CA0B1B;IAED;;;OAGG;IACH,UAFa,MAAM,CAmBlB;CAwCF;AAhmBD;IACE,wBAGC;IAFC,WAAkB;IAClB,iBAAuB;IAGzB,qCAEC;IAED,iBAEC;IAED,oBAEC;CACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable react-hooks/rules-of-hooks */
|
|
2
2
|
import { CoordinationType } from '@vitessce/constants-internal';
|
|
3
|
-
import { fromEntries, getNextScope } from '@vitessce/utils';
|
|
3
|
+
import { fromEntries, getNextScope, createPrefixedGetNextScopeNumeric } from '@vitessce/utils';
|
|
4
4
|
/**
|
|
5
5
|
* Class representing a file within a Vitessce config dataset.
|
|
6
6
|
*/
|
|
@@ -393,11 +393,12 @@ export class VitessceConfigCoordinationScope {
|
|
|
393
393
|
* Construct a new coordination scope instance.
|
|
394
394
|
* @param {string} cType The coordination type for this coordination scope.
|
|
395
395
|
* @param {string} cScope The name of the coordination scope.
|
|
396
|
+
* @param {[any]} cValue Optional. The coordination value of the coordination scope.
|
|
396
397
|
*/
|
|
397
|
-
constructor(cType, cScope) {
|
|
398
|
+
constructor(cType, cScope, cValue = null) {
|
|
398
399
|
this.cType = cType;
|
|
399
400
|
this.cScope = cScope;
|
|
400
|
-
this.cValue =
|
|
401
|
+
this.cValue = cValue;
|
|
401
402
|
}
|
|
402
403
|
/**
|
|
403
404
|
* Set the coordination value of the coordination scope.
|
|
@@ -506,6 +507,7 @@ export class VitessceConfig {
|
|
|
506
507
|
layout: [],
|
|
507
508
|
initStrategy: 'auto',
|
|
508
509
|
};
|
|
510
|
+
this.getNextScope = getNextScope;
|
|
509
511
|
}
|
|
510
512
|
/**
|
|
511
513
|
* Add a new dataset to the config.
|
|
@@ -519,7 +521,7 @@ export class VitessceConfig {
|
|
|
519
521
|
addDataset(name = undefined, description = undefined, options = undefined) {
|
|
520
522
|
const { uid } = options || {};
|
|
521
523
|
const prevDatasetUids = this.config.datasets.map(d => d.dataset.uid);
|
|
522
|
-
const nextUid = (uid || getNextScope(prevDatasetUids));
|
|
524
|
+
const nextUid = (uid || this.getNextScope(prevDatasetUids));
|
|
523
525
|
const newDataset = new VitessceConfigDataset(nextUid, name, description);
|
|
524
526
|
this.config.datasets.push(newDataset);
|
|
525
527
|
const [newScope] = this.addCoordination(CoordinationType.DATASET);
|
|
@@ -580,7 +582,7 @@ export class VitessceConfig {
|
|
|
580
582
|
const prevScopes = (this.config.coordinationSpace[cType]
|
|
581
583
|
? Object.keys(this.config.coordinationSpace[cType])
|
|
582
584
|
: []);
|
|
583
|
-
const scope = new VitessceConfigCoordinationScope(cType, getNextScope(prevScopes));
|
|
585
|
+
const scope = new VitessceConfigCoordinationScope(cType, this.getNextScope(prevScopes));
|
|
584
586
|
if (!this.config.coordinationSpace[scope.cType]) {
|
|
585
587
|
this.config.coordinationSpace[scope.cType] = {};
|
|
586
588
|
}
|
|
@@ -601,7 +603,7 @@ export class VitessceConfig {
|
|
|
601
603
|
const prevMetaByScopes = (this.config.coordinationSpace[CoordinationType.META_COORDINATION_SCOPES_BY]
|
|
602
604
|
? Object.keys(this.config.coordinationSpace[CoordinationType.META_COORDINATION_SCOPES_BY])
|
|
603
605
|
: []);
|
|
604
|
-
const metaContainer = new VitessceConfigMetaCoordinationScope(getNextScope(prevMetaScopes), getNextScope(prevMetaByScopes));
|
|
606
|
+
const metaContainer = new VitessceConfigMetaCoordinationScope(this.getNextScope(prevMetaScopes), this.getNextScope(prevMetaByScopes));
|
|
605
607
|
if (!this.config.coordinationSpace[CoordinationType.META_COORDINATION_SCOPES]) {
|
|
606
608
|
this.config.coordinationSpace[CoordinationType.META_COORDINATION_SCOPES] = {};
|
|
607
609
|
}
|
|
@@ -707,6 +709,9 @@ export class VitessceConfig {
|
|
|
707
709
|
*/
|
|
708
710
|
const processLevel = (level) => {
|
|
709
711
|
const result = {};
|
|
712
|
+
if (level === null) {
|
|
713
|
+
return result;
|
|
714
|
+
}
|
|
710
715
|
Object.entries(level).forEach(([cType, nextLevelOrInitialValue]) => {
|
|
711
716
|
// Check if value of object is instanceof CoordinationLevel
|
|
712
717
|
// (otherwise assume it is the coordination value).
|
|
@@ -791,10 +796,18 @@ export class VitessceConfig {
|
|
|
791
796
|
* instance, or a `CoordinationLevel` instance.
|
|
792
797
|
* The CL function takes an array of objects as its argument, and returns a CoordinationLevel
|
|
793
798
|
* instance, to support nesting.
|
|
794
|
-
* @param {
|
|
799
|
+
* @param {object|null} options
|
|
800
|
+
* @param {bool} options.meta Should meta-coordination be used? Optional.
|
|
801
|
+
* By default, true.
|
|
802
|
+
* @param {string|null} options.scopePrefix A prefix to add to all
|
|
803
|
+
* coordination scope names. Optional.
|
|
795
804
|
* @returns {VitessceConfig} This, to allow chaining.
|
|
796
805
|
*/
|
|
797
|
-
linkViewsByObject(views, input,
|
|
806
|
+
linkViewsByObject(views, input, options = null) {
|
|
807
|
+
const { meta = true, scopePrefix = null } = options || {};
|
|
808
|
+
if (scopePrefix) {
|
|
809
|
+
this.getNextScope = createPrefixedGetNextScopeNumeric(scopePrefix);
|
|
810
|
+
}
|
|
798
811
|
const scopes = this.addCoordinationByObject(input);
|
|
799
812
|
if (meta) {
|
|
800
813
|
const metaScope = this.addMetaCoordination();
|
|
@@ -808,8 +821,28 @@ export class VitessceConfig {
|
|
|
808
821
|
view.useCoordinationByObject(scopes);
|
|
809
822
|
});
|
|
810
823
|
}
|
|
824
|
+
if (scopePrefix) {
|
|
825
|
+
this.getNextScope = getNextScope;
|
|
826
|
+
}
|
|
811
827
|
return this;
|
|
812
828
|
}
|
|
829
|
+
/**
|
|
830
|
+
* Set the value for a coordination scope.
|
|
831
|
+
* If a coordination object for the coordination type does not yet exist
|
|
832
|
+
* in the coordination space, it will be created.
|
|
833
|
+
* @param {string} cType The coordination type.
|
|
834
|
+
* @param {string} cScope The coordination scope.
|
|
835
|
+
* @param {any} cValue The initial value for the coordination scope.
|
|
836
|
+
* @returns {VitessceConfigCoordinationScope} A coordination scope instance.
|
|
837
|
+
*/
|
|
838
|
+
setCoordinationValue(cType, cScope, cValue) {
|
|
839
|
+
const scope = new VitessceConfigCoordinationScope(cType, cScope, cValue);
|
|
840
|
+
if (!this.config.coordinationSpace[scope.cType]) {
|
|
841
|
+
this.config.coordinationSpace[scope.cType] = {};
|
|
842
|
+
}
|
|
843
|
+
this.config.coordinationSpace[scope.cType][scope.cScope] = scope;
|
|
844
|
+
return scope;
|
|
845
|
+
}
|
|
813
846
|
/**
|
|
814
847
|
* Set the layout of views.
|
|
815
848
|
* @param {VitessceConfigView|VitessceConfigViewHConcat|VitessceConfigViewVConcat} viewConcat A
|
|
@@ -898,3 +931,21 @@ export class VitessceConfig {
|
|
|
898
931
|
return vc;
|
|
899
932
|
}
|
|
900
933
|
}
|
|
934
|
+
// For usage during auto-initialization.
|
|
935
|
+
export function getCoordinationSpaceAndScopes(partialCoordinationValues, scopePrefix) {
|
|
936
|
+
const vc = new VitessceConfig({ schemaVersion: '1.0.16', name: '__dummy__' });
|
|
937
|
+
vc.getNextScope = createPrefixedGetNextScopeNumeric(scopePrefix);
|
|
938
|
+
const dataset = vc.addDataset('__dummy__');
|
|
939
|
+
const v1 = vc.addView(dataset, '__dummy__');
|
|
940
|
+
vc.linkViewsByObject([v1], partialCoordinationValues, { meta: true });
|
|
941
|
+
const vcJson = vc.toJSON();
|
|
942
|
+
// TODO: remove the "dataset" coordination type from these objects.
|
|
943
|
+
const { coordinationSpace } = vcJson;
|
|
944
|
+
const { coordinationScopes } = vcJson.layout[0];
|
|
945
|
+
const { coordinationScopesBy } = vcJson.layout[0];
|
|
946
|
+
return {
|
|
947
|
+
coordinationSpace,
|
|
948
|
+
coordinationScopes,
|
|
949
|
+
coordinationScopesBy,
|
|
950
|
+
};
|
|
951
|
+
}
|
|
@@ -701,6 +701,111 @@ describe('src/api/VitessceConfig.js', () => {
|
|
|
701
701
|
initStrategy: 'auto',
|
|
702
702
|
});
|
|
703
703
|
});
|
|
704
|
+
it('can use _meta_ complex coordination with a scope prefix via the linkViewsByObject convenience function', () => {
|
|
705
|
+
const config = new VitessceConfig({
|
|
706
|
+
schemaVersion: '1.0.16',
|
|
707
|
+
name: 'My config',
|
|
708
|
+
});
|
|
709
|
+
const dataset = config.addDataset('My dataset');
|
|
710
|
+
const spatialView = config.addView(dataset, 'spatial');
|
|
711
|
+
const lcView = config.addView(dataset, 'layerController');
|
|
712
|
+
config.linkViewsByObject([spatialView, lcView], {
|
|
713
|
+
spatialImageLayer: CL([
|
|
714
|
+
{
|
|
715
|
+
spatialLayerOpacity: 1,
|
|
716
|
+
spatialImageChannel: CL([
|
|
717
|
+
{
|
|
718
|
+
spatialTargetC: 0,
|
|
719
|
+
spatialChannelColor: [255, 0, 0],
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
spatialTargetC: 1,
|
|
723
|
+
spatialChannelColor: [0, 255, 0],
|
|
724
|
+
},
|
|
725
|
+
]),
|
|
726
|
+
},
|
|
727
|
+
]),
|
|
728
|
+
}, { scopePrefix: 'SOME_PREFIX_' });
|
|
729
|
+
const configJSON = config.toJSON();
|
|
730
|
+
expect(configJSON).toEqual({
|
|
731
|
+
version: '1.0.16',
|
|
732
|
+
name: 'My config',
|
|
733
|
+
datasets: [
|
|
734
|
+
{ uid: 'A', name: 'My dataset', files: [] },
|
|
735
|
+
],
|
|
736
|
+
coordinationSpace: {
|
|
737
|
+
dataset: { A: 'A' },
|
|
738
|
+
spatialImageLayer: { SOME_PREFIX_0: '__dummy__' },
|
|
739
|
+
spatialLayerOpacity: { SOME_PREFIX_0: 1 },
|
|
740
|
+
spatialImageChannel: {
|
|
741
|
+
SOME_PREFIX_0: '__dummy__',
|
|
742
|
+
SOME_PREFIX_1: '__dummy__',
|
|
743
|
+
},
|
|
744
|
+
spatialTargetC: {
|
|
745
|
+
SOME_PREFIX_0: 0,
|
|
746
|
+
SOME_PREFIX_1: 1,
|
|
747
|
+
},
|
|
748
|
+
spatialChannelColor: {
|
|
749
|
+
SOME_PREFIX_0: [255, 0, 0],
|
|
750
|
+
SOME_PREFIX_1: [0, 255, 0],
|
|
751
|
+
},
|
|
752
|
+
metaCoordinationScopes: {
|
|
753
|
+
SOME_PREFIX_0: {
|
|
754
|
+
spatialImageLayer: ['SOME_PREFIX_0'],
|
|
755
|
+
},
|
|
756
|
+
},
|
|
757
|
+
metaCoordinationScopesBy: {
|
|
758
|
+
SOME_PREFIX_0: {
|
|
759
|
+
spatialImageLayer: {
|
|
760
|
+
spatialLayerOpacity: {
|
|
761
|
+
SOME_PREFIX_0: 'SOME_PREFIX_0',
|
|
762
|
+
},
|
|
763
|
+
spatialImageChannel: {
|
|
764
|
+
SOME_PREFIX_0: ['SOME_PREFIX_0', 'SOME_PREFIX_1'],
|
|
765
|
+
},
|
|
766
|
+
},
|
|
767
|
+
spatialImageChannel: {
|
|
768
|
+
spatialTargetC: {
|
|
769
|
+
SOME_PREFIX_0: 'SOME_PREFIX_0',
|
|
770
|
+
SOME_PREFIX_1: 'SOME_PREFIX_1',
|
|
771
|
+
},
|
|
772
|
+
spatialChannelColor: {
|
|
773
|
+
SOME_PREFIX_0: 'SOME_PREFIX_0',
|
|
774
|
+
SOME_PREFIX_1: 'SOME_PREFIX_1',
|
|
775
|
+
},
|
|
776
|
+
},
|
|
777
|
+
},
|
|
778
|
+
},
|
|
779
|
+
},
|
|
780
|
+
layout: [
|
|
781
|
+
{
|
|
782
|
+
component: 'spatial',
|
|
783
|
+
coordinationScopes: {
|
|
784
|
+
dataset: 'A',
|
|
785
|
+
metaCoordinationScopes: ['SOME_PREFIX_0'],
|
|
786
|
+
metaCoordinationScopesBy: ['SOME_PREFIX_0'],
|
|
787
|
+
},
|
|
788
|
+
x: 0,
|
|
789
|
+
y: 0,
|
|
790
|
+
w: 1,
|
|
791
|
+
h: 1,
|
|
792
|
+
},
|
|
793
|
+
{
|
|
794
|
+
component: 'layerController',
|
|
795
|
+
coordinationScopes: {
|
|
796
|
+
dataset: 'A',
|
|
797
|
+
metaCoordinationScopes: ['SOME_PREFIX_0'],
|
|
798
|
+
metaCoordinationScopesBy: ['SOME_PREFIX_0'],
|
|
799
|
+
},
|
|
800
|
+
x: 0,
|
|
801
|
+
y: 0,
|
|
802
|
+
w: 1,
|
|
803
|
+
h: 1,
|
|
804
|
+
},
|
|
805
|
+
],
|
|
806
|
+
initStrategy: 'auto',
|
|
807
|
+
});
|
|
808
|
+
});
|
|
704
809
|
it('can add a coordination scope using the link views convenience function', () => {
|
|
705
810
|
const config = new VitessceConfig({
|
|
706
811
|
schemaVersion: '1.0.4',
|
package/dist-tsc/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { VitessceConfig, vconcat, hconcat, CL as CoordinationLevel } from "./VitessceConfig.js";
|
|
1
|
+
export { VitessceConfig, vconcat, hconcat, CL as CoordinationLevel, getCoordinationSpaceAndScopes } from "./VitessceConfig.js";
|
|
2
2
|
export { generateConfig, getHintOptions } from "./VitessceAutoConfig.js";
|
|
3
3
|
export { HINTS_CONFIG, HINT_TYPE_TO_FILE_TYPE_MAP } from "./constants.js";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist-tsc/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { VitessceConfig, vconcat, hconcat, CL as CoordinationLevel } from './VitessceConfig.js';
|
|
1
|
+
export { VitessceConfig, vconcat, hconcat, CL as CoordinationLevel, getCoordinationSpaceAndScopes } from './VitessceConfig.js';
|
|
2
2
|
export { generateConfig, getHintOptions } from './VitessceAutoConfig.js';
|
|
3
3
|
export { HINTS_CONFIG, HINT_TYPE_TO_FILE_TYPE_MAP } from './constants.js';
|
|
4
|
+
export { getInitialCoordinationScopePrefix, getInitialCoordinationScopeName, } from '@vitessce/utils';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitessce/config",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.3",
|
|
4
4
|
"author": "Gehlenborg Lab",
|
|
5
5
|
"homepage": "http://vitessce.io",
|
|
6
6
|
"repository": {
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"dist-tsc"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@vitessce/constants-internal": "3.3.
|
|
20
|
-
"@vitessce/utils": "3.3.
|
|
19
|
+
"@vitessce/constants-internal": "3.3.3",
|
|
20
|
+
"@vitessce/utils": "3.3.3"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
23
|
"bundle": "pnpm exec vite build -c ../../scripts/vite.config.js",
|
package/src/VitessceConfig.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable react-hooks/rules-of-hooks */
|
|
2
2
|
import { CoordinationType } from '@vitessce/constants-internal';
|
|
3
|
-
import { fromEntries, getNextScope } from '@vitessce/utils';
|
|
3
|
+
import { fromEntries, getNextScope, createPrefixedGetNextScopeNumeric } from '@vitessce/utils';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Class representing a file within a Vitessce config dataset.
|
|
@@ -430,11 +430,12 @@ export class VitessceConfigCoordinationScope {
|
|
|
430
430
|
* Construct a new coordination scope instance.
|
|
431
431
|
* @param {string} cType The coordination type for this coordination scope.
|
|
432
432
|
* @param {string} cScope The name of the coordination scope.
|
|
433
|
+
* @param {[any]} cValue Optional. The coordination value of the coordination scope.
|
|
433
434
|
*/
|
|
434
|
-
constructor(cType, cScope) {
|
|
435
|
+
constructor(cType, cScope, cValue = null) {
|
|
435
436
|
this.cType = cType;
|
|
436
437
|
this.cScope = cScope;
|
|
437
|
-
this.cValue =
|
|
438
|
+
this.cValue = cValue;
|
|
438
439
|
}
|
|
439
440
|
|
|
440
441
|
/**
|
|
@@ -555,6 +556,7 @@ export class VitessceConfig {
|
|
|
555
556
|
layout: [],
|
|
556
557
|
initStrategy: 'auto',
|
|
557
558
|
};
|
|
559
|
+
this.getNextScope = getNextScope;
|
|
558
560
|
}
|
|
559
561
|
|
|
560
562
|
/**
|
|
@@ -569,7 +571,7 @@ export class VitessceConfig {
|
|
|
569
571
|
addDataset(name = undefined, description = undefined, options = undefined) {
|
|
570
572
|
const { uid } = options || {};
|
|
571
573
|
const prevDatasetUids = this.config.datasets.map(d => d.dataset.uid);
|
|
572
|
-
const nextUid = (uid || getNextScope(prevDatasetUids));
|
|
574
|
+
const nextUid = (uid || this.getNextScope(prevDatasetUids));
|
|
573
575
|
const newDataset = new VitessceConfigDataset(nextUid, name, description);
|
|
574
576
|
this.config.datasets.push(newDataset);
|
|
575
577
|
const [newScope] = this.addCoordination(CoordinationType.DATASET);
|
|
@@ -641,7 +643,7 @@ export class VitessceConfig {
|
|
|
641
643
|
? Object.keys(this.config.coordinationSpace[cType])
|
|
642
644
|
: []
|
|
643
645
|
);
|
|
644
|
-
const scope = new VitessceConfigCoordinationScope(cType, getNextScope(prevScopes));
|
|
646
|
+
const scope = new VitessceConfigCoordinationScope(cType, this.getNextScope(prevScopes));
|
|
645
647
|
if (!this.config.coordinationSpace[scope.cType]) {
|
|
646
648
|
this.config.coordinationSpace[scope.cType] = {};
|
|
647
649
|
}
|
|
@@ -668,8 +670,8 @@ export class VitessceConfig {
|
|
|
668
670
|
: []
|
|
669
671
|
);
|
|
670
672
|
const metaContainer = new VitessceConfigMetaCoordinationScope(
|
|
671
|
-
getNextScope(prevMetaScopes),
|
|
672
|
-
getNextScope(prevMetaByScopes),
|
|
673
|
+
this.getNextScope(prevMetaScopes),
|
|
674
|
+
this.getNextScope(prevMetaByScopes),
|
|
673
675
|
);
|
|
674
676
|
if (!this.config.coordinationSpace[CoordinationType.META_COORDINATION_SCOPES]) {
|
|
675
677
|
this.config.coordinationSpace[CoordinationType.META_COORDINATION_SCOPES] = {};
|
|
@@ -777,6 +779,9 @@ export class VitessceConfig {
|
|
|
777
779
|
*/
|
|
778
780
|
const processLevel = (level) => {
|
|
779
781
|
const result = {};
|
|
782
|
+
if (level === null) {
|
|
783
|
+
return result;
|
|
784
|
+
}
|
|
780
785
|
Object.entries(level).forEach(([cType, nextLevelOrInitialValue]) => {
|
|
781
786
|
// Check if value of object is instanceof CoordinationLevel
|
|
782
787
|
// (otherwise assume it is the coordination value).
|
|
@@ -859,10 +864,19 @@ export class VitessceConfig {
|
|
|
859
864
|
* instance, or a `CoordinationLevel` instance.
|
|
860
865
|
* The CL function takes an array of objects as its argument, and returns a CoordinationLevel
|
|
861
866
|
* instance, to support nesting.
|
|
862
|
-
* @param {
|
|
867
|
+
* @param {object|null} options
|
|
868
|
+
* @param {bool} options.meta Should meta-coordination be used? Optional.
|
|
869
|
+
* By default, true.
|
|
870
|
+
* @param {string|null} options.scopePrefix A prefix to add to all
|
|
871
|
+
* coordination scope names. Optional.
|
|
863
872
|
* @returns {VitessceConfig} This, to allow chaining.
|
|
864
873
|
*/
|
|
865
|
-
linkViewsByObject(views, input,
|
|
874
|
+
linkViewsByObject(views, input, options = null) {
|
|
875
|
+
const { meta = true, scopePrefix = null } = options || {};
|
|
876
|
+
|
|
877
|
+
if (scopePrefix) {
|
|
878
|
+
this.getNextScope = createPrefixedGetNextScopeNumeric(scopePrefix);
|
|
879
|
+
}
|
|
866
880
|
const scopes = this.addCoordinationByObject(input);
|
|
867
881
|
if (meta) {
|
|
868
882
|
const metaScope = this.addMetaCoordination();
|
|
@@ -876,9 +890,30 @@ export class VitessceConfig {
|
|
|
876
890
|
view.useCoordinationByObject(scopes);
|
|
877
891
|
});
|
|
878
892
|
}
|
|
893
|
+
if (scopePrefix) {
|
|
894
|
+
this.getNextScope = getNextScope;
|
|
895
|
+
}
|
|
879
896
|
return this;
|
|
880
897
|
}
|
|
881
898
|
|
|
899
|
+
/**
|
|
900
|
+
* Set the value for a coordination scope.
|
|
901
|
+
* If a coordination object for the coordination type does not yet exist
|
|
902
|
+
* in the coordination space, it will be created.
|
|
903
|
+
* @param {string} cType The coordination type.
|
|
904
|
+
* @param {string} cScope The coordination scope.
|
|
905
|
+
* @param {any} cValue The initial value for the coordination scope.
|
|
906
|
+
* @returns {VitessceConfigCoordinationScope} A coordination scope instance.
|
|
907
|
+
*/
|
|
908
|
+
setCoordinationValue(cType, cScope, cValue) {
|
|
909
|
+
const scope = new VitessceConfigCoordinationScope(cType, cScope, cValue);
|
|
910
|
+
if (!this.config.coordinationSpace[scope.cType]) {
|
|
911
|
+
this.config.coordinationSpace[scope.cType] = {};
|
|
912
|
+
}
|
|
913
|
+
this.config.coordinationSpace[scope.cType][scope.cScope] = scope;
|
|
914
|
+
return scope;
|
|
915
|
+
}
|
|
916
|
+
|
|
882
917
|
/**
|
|
883
918
|
* Set the layout of views.
|
|
884
919
|
* @param {VitessceConfigView|VitessceConfigViewHConcat|VitessceConfigViewVConcat} viewConcat A
|
|
@@ -973,3 +1008,23 @@ export class VitessceConfig {
|
|
|
973
1008
|
return vc;
|
|
974
1009
|
}
|
|
975
1010
|
}
|
|
1011
|
+
|
|
1012
|
+
// For usage during auto-initialization.
|
|
1013
|
+
export function getCoordinationSpaceAndScopes(partialCoordinationValues, scopePrefix) {
|
|
1014
|
+
const vc = new VitessceConfig({ schemaVersion: '1.0.16', name: '__dummy__' });
|
|
1015
|
+
vc.getNextScope = createPrefixedGetNextScopeNumeric(scopePrefix);
|
|
1016
|
+
const dataset = vc.addDataset('__dummy__');
|
|
1017
|
+
const v1 = vc.addView(dataset, '__dummy__');
|
|
1018
|
+
vc.linkViewsByObject([v1], partialCoordinationValues, { meta: true });
|
|
1019
|
+
const vcJson = vc.toJSON();
|
|
1020
|
+
// TODO: remove the "dataset" coordination type from these objects.
|
|
1021
|
+
const { coordinationSpace } = vcJson;
|
|
1022
|
+
const { coordinationScopes } = vcJson.layout[0];
|
|
1023
|
+
const { coordinationScopesBy } = vcJson.layout[0];
|
|
1024
|
+
|
|
1025
|
+
return {
|
|
1026
|
+
coordinationSpace,
|
|
1027
|
+
coordinationScopes,
|
|
1028
|
+
coordinationScopesBy,
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
@@ -744,6 +744,116 @@ describe('src/api/VitessceConfig.js', () => {
|
|
|
744
744
|
});
|
|
745
745
|
});
|
|
746
746
|
|
|
747
|
+
it('can use _meta_ complex coordination with a scope prefix via the linkViewsByObject convenience function', () => {
|
|
748
|
+
const config = new VitessceConfig({
|
|
749
|
+
schemaVersion: '1.0.16',
|
|
750
|
+
name: 'My config',
|
|
751
|
+
});
|
|
752
|
+
const dataset = config.addDataset('My dataset');
|
|
753
|
+
|
|
754
|
+
const spatialView = config.addView(dataset, 'spatial');
|
|
755
|
+
const lcView = config.addView(dataset, 'layerController');
|
|
756
|
+
|
|
757
|
+
config.linkViewsByObject([spatialView, lcView], {
|
|
758
|
+
spatialImageLayer: CL([
|
|
759
|
+
{
|
|
760
|
+
spatialLayerOpacity: 1,
|
|
761
|
+
spatialImageChannel: CL([
|
|
762
|
+
{
|
|
763
|
+
spatialTargetC: 0,
|
|
764
|
+
spatialChannelColor: [255, 0, 0],
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
spatialTargetC: 1,
|
|
768
|
+
spatialChannelColor: [0, 255, 0],
|
|
769
|
+
},
|
|
770
|
+
]),
|
|
771
|
+
},
|
|
772
|
+
]),
|
|
773
|
+
}, { scopePrefix: 'SOME_PREFIX_' });
|
|
774
|
+
|
|
775
|
+
const configJSON = config.toJSON();
|
|
776
|
+
|
|
777
|
+
expect(configJSON).toEqual({
|
|
778
|
+
version: '1.0.16',
|
|
779
|
+
name: 'My config',
|
|
780
|
+
datasets: [
|
|
781
|
+
{ uid: 'A', name: 'My dataset', files: [] },
|
|
782
|
+
],
|
|
783
|
+
coordinationSpace: {
|
|
784
|
+
dataset: { A: 'A' },
|
|
785
|
+
spatialImageLayer: { SOME_PREFIX_0: '__dummy__' },
|
|
786
|
+
spatialLayerOpacity: { SOME_PREFIX_0: 1 },
|
|
787
|
+
spatialImageChannel: {
|
|
788
|
+
SOME_PREFIX_0: '__dummy__',
|
|
789
|
+
SOME_PREFIX_1: '__dummy__',
|
|
790
|
+
},
|
|
791
|
+
spatialTargetC: {
|
|
792
|
+
SOME_PREFIX_0: 0,
|
|
793
|
+
SOME_PREFIX_1: 1,
|
|
794
|
+
},
|
|
795
|
+
spatialChannelColor: {
|
|
796
|
+
SOME_PREFIX_0: [255, 0, 0],
|
|
797
|
+
SOME_PREFIX_1: [0, 255, 0],
|
|
798
|
+
},
|
|
799
|
+
metaCoordinationScopes: {
|
|
800
|
+
SOME_PREFIX_0: {
|
|
801
|
+
spatialImageLayer: ['SOME_PREFIX_0'],
|
|
802
|
+
},
|
|
803
|
+
},
|
|
804
|
+
metaCoordinationScopesBy: {
|
|
805
|
+
SOME_PREFIX_0: {
|
|
806
|
+
spatialImageLayer: {
|
|
807
|
+
spatialLayerOpacity: {
|
|
808
|
+
SOME_PREFIX_0: 'SOME_PREFIX_0',
|
|
809
|
+
},
|
|
810
|
+
spatialImageChannel: {
|
|
811
|
+
SOME_PREFIX_0: ['SOME_PREFIX_0', 'SOME_PREFIX_1'],
|
|
812
|
+
},
|
|
813
|
+
},
|
|
814
|
+
spatialImageChannel: {
|
|
815
|
+
spatialTargetC: {
|
|
816
|
+
SOME_PREFIX_0: 'SOME_PREFIX_0',
|
|
817
|
+
SOME_PREFIX_1: 'SOME_PREFIX_1',
|
|
818
|
+
},
|
|
819
|
+
spatialChannelColor: {
|
|
820
|
+
SOME_PREFIX_0: 'SOME_PREFIX_0',
|
|
821
|
+
SOME_PREFIX_1: 'SOME_PREFIX_1',
|
|
822
|
+
},
|
|
823
|
+
},
|
|
824
|
+
},
|
|
825
|
+
},
|
|
826
|
+
},
|
|
827
|
+
layout: [
|
|
828
|
+
{
|
|
829
|
+
component: 'spatial',
|
|
830
|
+
coordinationScopes: {
|
|
831
|
+
dataset: 'A',
|
|
832
|
+
metaCoordinationScopes: ['SOME_PREFIX_0'],
|
|
833
|
+
metaCoordinationScopesBy: ['SOME_PREFIX_0'],
|
|
834
|
+
},
|
|
835
|
+
x: 0,
|
|
836
|
+
y: 0,
|
|
837
|
+
w: 1,
|
|
838
|
+
h: 1,
|
|
839
|
+
},
|
|
840
|
+
{
|
|
841
|
+
component: 'layerController',
|
|
842
|
+
coordinationScopes: {
|
|
843
|
+
dataset: 'A',
|
|
844
|
+
metaCoordinationScopes: ['SOME_PREFIX_0'],
|
|
845
|
+
metaCoordinationScopesBy: ['SOME_PREFIX_0'],
|
|
846
|
+
},
|
|
847
|
+
x: 0,
|
|
848
|
+
y: 0,
|
|
849
|
+
w: 1,
|
|
850
|
+
h: 1,
|
|
851
|
+
},
|
|
852
|
+
],
|
|
853
|
+
initStrategy: 'auto',
|
|
854
|
+
});
|
|
855
|
+
});
|
|
856
|
+
|
|
747
857
|
it('can add a coordination scope using the link views convenience function', () => {
|
|
748
858
|
const config = new VitessceConfig({
|
|
749
859
|
schemaVersion: '1.0.4',
|
package/src/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
export { VitessceConfig, vconcat, hconcat, CL as CoordinationLevel } from './VitessceConfig.js';
|
|
1
|
+
export { VitessceConfig, vconcat, hconcat, CL as CoordinationLevel, getCoordinationSpaceAndScopes } from './VitessceConfig.js';
|
|
2
2
|
export { generateConfig, getHintOptions } from './VitessceAutoConfig.js';
|
|
3
3
|
export { HINTS_CONFIG, HINT_TYPE_TO_FILE_TYPE_MAP } from './constants.js';
|
|
4
|
+
export {
|
|
5
|
+
getInitialCoordinationScopePrefix,
|
|
6
|
+
getInitialCoordinationScopeName,
|
|
7
|
+
} from '@vitessce/utils';
|