@vitessce/config 3.3.2 → 3.3.4

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.
@@ -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 {boolean} meta Should meta-coordination be used? Optional. By default, true.
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, meta?: boolean): VitessceConfig;
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":"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"}
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 = null;
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 {boolean} meta Should meta-coordination be used? Optional. By default, true.
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, meta = true) {
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',
@@ -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.2",
3
+ "version": "3.3.4",
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.2",
20
- "@vitessce/utils": "3.3.2"
19
+ "@vitessce/constants-internal": "3.3.4",
20
+ "@vitessce/utils": "3.3.4"
21
21
  },
22
22
  "scripts": {
23
23
  "bundle": "pnpm exec vite build -c ../../scripts/vite.config.js",
@@ -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 = null;
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 {boolean} meta Should meta-coordination be used? Optional. By default, true.
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, meta = true) {
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';