@genome-spy/core 0.43.3 → 0.45.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.
Files changed (124) hide show
  1. package/dist/bundle/index.es.js +5231 -4324
  2. package/dist/bundle/index.js +197 -85
  3. package/dist/schema.json +723 -104
  4. package/dist/src/data/collector.d.ts.map +1 -1
  5. package/dist/src/data/collector.js +4 -2
  6. package/dist/src/data/flowOptimizer.test.js +12 -3
  7. package/dist/src/data/sources/dataUtils.d.ts.map +1 -1
  8. package/dist/src/data/sources/dataUtils.js +3 -1
  9. package/dist/src/data/sources/lazy/axisTickSource.d.ts +1 -1
  10. package/dist/src/data/sources/lazy/axisTickSource.d.ts.map +1 -1
  11. package/dist/src/data/sources/lazy/axisTickSource.js +2 -2
  12. package/dist/src/data/sources/lazy/bigBedSource.d.ts +1 -1
  13. package/dist/src/data/sources/lazy/bigBedSource.d.ts.map +1 -1
  14. package/dist/src/data/sources/lazy/bigBedSource.js +52 -20
  15. package/dist/src/data/sources/lazy/bigWigSource.d.ts +6 -1
  16. package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
  17. package/dist/src/data/sources/lazy/bigWigSource.js +33 -9
  18. package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts +1 -1
  19. package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts.map +1 -1
  20. package/dist/src/data/sources/lazy/singleAxisLazySource.js +1 -3
  21. package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts +13 -14
  22. package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts.map +1 -1
  23. package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +70 -48
  24. package/dist/src/data/sources/sequenceSource.d.ts.map +1 -1
  25. package/dist/src/data/sources/sequenceSource.js +14 -5
  26. package/dist/src/data/sources/sequenceSource.test.js +23 -5
  27. package/dist/src/data/sources/urlSource.d.ts.map +1 -1
  28. package/dist/src/data/sources/urlSource.js +15 -2
  29. package/dist/src/data/transforms/aggregate.d.ts.map +1 -1
  30. package/dist/src/data/transforms/aggregate.js +5 -2
  31. package/dist/src/data/transforms/filterScoredLabels.js +1 -1
  32. package/dist/src/encoder/encoder.d.ts +2 -4
  33. package/dist/src/encoder/encoder.d.ts.map +1 -1
  34. package/dist/src/encoder/encoder.js +20 -10
  35. package/dist/src/encoder/encoder.test.js +3 -0
  36. package/dist/src/genomeSpy.d.ts +8 -5
  37. package/dist/src/genomeSpy.d.ts.map +1 -1
  38. package/dist/src/genomeSpy.js +121 -42
  39. package/dist/src/gl/glslScaleGenerator.d.ts +23 -3
  40. package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -1
  41. package/dist/src/gl/glslScaleGenerator.js +137 -42
  42. package/dist/src/gl/webGLHelper.d.ts.map +1 -1
  43. package/dist/src/gl/webGLHelper.js +5 -7
  44. package/dist/src/index.d.ts +1 -1
  45. package/dist/src/index.d.ts.map +1 -1
  46. package/dist/src/index.js +1 -1
  47. package/dist/src/marks/link.common.glsl.js +2 -0
  48. package/dist/src/marks/link.d.ts.map +1 -1
  49. package/dist/src/marks/link.js +19 -9
  50. package/dist/src/marks/link.vertex.glsl.js +1 -1
  51. package/dist/src/marks/mark.d.ts +25 -20
  52. package/dist/src/marks/mark.d.ts.map +1 -1
  53. package/dist/src/marks/mark.js +234 -129
  54. package/dist/src/marks/point.common.glsl.js +1 -1
  55. package/dist/src/marks/point.d.ts +1 -4
  56. package/dist/src/marks/point.d.ts.map +1 -1
  57. package/dist/src/marks/point.js +31 -23
  58. package/dist/src/marks/point.vertex.glsl.js +1 -1
  59. package/dist/src/marks/rect.common.glsl.js +2 -0
  60. package/dist/src/marks/rect.d.ts.map +1 -1
  61. package/dist/src/marks/rect.js +12 -12
  62. package/dist/src/marks/rect.vertex.glsl.js +1 -1
  63. package/dist/src/marks/rule.common.glsl.js +1 -1
  64. package/dist/src/marks/rule.js +2 -2
  65. package/dist/src/marks/text.common.glsl.js +1 -1
  66. package/dist/src/marks/text.d.ts.map +1 -1
  67. package/dist/src/marks/text.js +17 -9
  68. package/dist/src/spec/channel.d.ts +4 -3
  69. package/dist/src/spec/data.d.ts +11 -10
  70. package/dist/src/spec/mark.d.ts +28 -46
  71. package/dist/src/spec/parameter.d.ts +127 -0
  72. package/dist/src/spec/root.d.ts +1 -0
  73. package/dist/src/spec/scale.d.ts +2 -1
  74. package/dist/src/spec/title.d.ts +5 -4
  75. package/dist/src/spec/view.d.ts +20 -5
  76. package/dist/src/styles/genome-spy.css.d.ts +1 -1
  77. package/dist/src/styles/genome-spy.css.d.ts.map +1 -1
  78. package/dist/src/styles/genome-spy.css.js +52 -5
  79. package/dist/src/styles/genome-spy.scss +63 -10
  80. package/dist/src/styles/update.sh +6 -0
  81. package/dist/src/tooltip/dataTooltipHandler.js +1 -1
  82. package/dist/src/tooltip/refseqGeneTooltipHandler.js +1 -1
  83. package/dist/src/tooltip/tooltipHandler.d.ts +1 -1
  84. package/dist/src/tooltip/tooltipHandler.d.ts.map +1 -1
  85. package/dist/src/tooltip/tooltipHandler.ts +1 -1
  86. package/dist/src/types/embedApi.d.ts +6 -0
  87. package/dist/src/types/scaleResolutionApi.d.ts +7 -3
  88. package/dist/src/types/viewContext.d.ts +2 -3
  89. package/dist/src/utils/debounce.d.ts +2 -2
  90. package/dist/src/utils/debounce.d.ts.map +1 -1
  91. package/dist/src/utils/debounce.js +5 -2
  92. package/dist/src/utils/expression.d.ts +2 -2
  93. package/dist/src/utils/expression.d.ts.map +1 -1
  94. package/dist/src/utils/expression.js +3 -3
  95. package/dist/src/utils/formatObject.d.ts +2 -2
  96. package/dist/src/utils/formatObject.d.ts.map +1 -1
  97. package/dist/src/utils/formatObject.js +2 -2
  98. package/dist/src/utils/inputBinding.d.ts +5 -0
  99. package/dist/src/utils/inputBinding.d.ts.map +1 -0
  100. package/dist/src/utils/inputBinding.js +115 -0
  101. package/dist/src/utils/ui/tooltip.js +1 -1
  102. package/dist/src/view/axisView.js +3 -3
  103. package/dist/src/view/paramMediator.d.ts +108 -0
  104. package/dist/src/view/paramMediator.d.ts.map +1 -0
  105. package/dist/src/view/paramMediator.js +337 -0
  106. package/dist/src/view/paramMediator.test.js +211 -0
  107. package/dist/src/view/scaleResolution.d.ts +8 -18
  108. package/dist/src/view/scaleResolution.d.ts.map +1 -1
  109. package/dist/src/view/scaleResolution.js +225 -126
  110. package/dist/src/view/scaleResolution.test.js +7 -7
  111. package/dist/src/view/unitView.d.ts.map +1 -1
  112. package/dist/src/view/unitView.js +10 -3
  113. package/dist/src/view/view.d.ts +4 -1
  114. package/dist/src/view/view.d.ts.map +1 -1
  115. package/dist/src/view/view.js +21 -7
  116. package/dist/src/view/viewFactory.d.ts.map +1 -1
  117. package/dist/src/view/viewFactory.js +45 -0
  118. package/dist/src/view/viewUtils.d.ts +5 -1
  119. package/dist/src/view/viewUtils.d.ts.map +1 -1
  120. package/dist/src/view/viewUtils.js +9 -4
  121. package/package.json +16 -17
  122. package/dist/src/paramBroker.d.ts +0 -30
  123. package/dist/src/paramBroker.d.ts.map +0 -1
  124. package/dist/src/paramBroker.js +0 -102
@@ -335,7 +335,7 @@ describe("Domain handling", () => {
335
335
  );
336
336
 
337
337
  /** @param {import("./view.js").default} view */
338
- const d = (view) => view.getScaleResolution("y").getScale().domain();
338
+ const d = (view) => view.getScaleResolution("y").scale.domain();
339
339
 
340
340
  expect(r(d(view))).toEqual([1, 5]);
341
341
  expect(r(d(view.children[0]))).toEqual([1, 5]);
@@ -371,7 +371,7 @@ describe("Domain handling", () => {
371
371
  );
372
372
 
373
373
  /** @param {import("./view.js").default} view */
374
- const d = (view) => view.getScaleResolution("y").getScale().domain();
374
+ const d = (view) => view.getScaleResolution("y").scale.domain();
375
375
 
376
376
  expect(r(d(view))).toEqual([1, 5]);
377
377
  expect(r(d(view.children[0]))).toEqual([1, 5]);
@@ -403,7 +403,7 @@ describe("Domain handling", () => {
403
403
  );
404
404
 
405
405
  /** @param {import("./view.js").default} view */
406
- const d = (view) => view.getScaleResolution("y").getScale().domain();
406
+ const d = (view) => view.getScaleResolution("y").scale.domain();
407
407
 
408
408
  // FAILS!!!!!!! TODO: FIX!!
409
409
  // expect(r(d(view))).toEqual([1, 5]);
@@ -442,7 +442,7 @@ describe("Domain handling", () => {
442
442
  );
443
443
 
444
444
  /** @param {import("./view.js").default} view */
445
- const d = (view) => view.getScaleResolution("y").getScale().domain();
445
+ const d = (view) => view.getScaleResolution("y").scale.domain();
446
446
 
447
447
  expect(r(d(view))).toEqual([1, 5]);
448
448
  expect(r(d(view.children[0]))).toEqual([1, 5]);
@@ -469,7 +469,7 @@ describe("Domain handling", () => {
469
469
 
470
470
  const d = /** @param {import("../spec/channel.js").Channel} channel*/ (
471
471
  channel
472
- ) => view.getScaleResolution(channel).getScale().domain();
472
+ ) => view.getScaleResolution(channel).scale.domain();
473
473
 
474
474
  expect(d("x")).toEqual([0, 3]);
475
475
  expect(d("y")).toEqual([0, 3]);
@@ -497,7 +497,7 @@ describe("Domain handling", () => {
497
497
  );
498
498
 
499
499
  const d = /** @param {Channel} channel*/ (channel) =>
500
- view.getScaleResolution(channel).getScale().domain();
500
+ view.getScaleResolution(channel).scale.domain();
501
501
 
502
502
  expect(d("x")).toEqual([1, 4]);
503
503
  expect(d("x")).toEqual([1, 4]);
@@ -530,7 +530,7 @@ describe("Domain handling", () => {
530
530
  }
531
531
 
532
532
  const d = /** @param {Channel} channel*/ (channel) =>
533
- view.getScaleResolution(channel).getScale().domain();
533
+ view.getScaleResolution(channel).scale.domain();
534
534
 
535
535
  expect(d("x")).toEqual([2, 3]);
536
536
  expect(d("y")).toEqual([2, 3]);
@@ -1 +1 @@
1
- {"version":3,"file":"unitView.d.ts","sourceRoot":"","sources":["../../../src/view/unitView.js"],"names":[],"mappings":"AAqBA;;;;GAIG;AACH;QAHkB,MAAM,GAAE,cAAc,kBAAkB,EAAE,OAAO;EASjE;AAEF;IACI;;;;;;;OAOG;IACH;;;;;;;;OAQG;IACH,kBAPW,OAAO,iBAAiB,EAAE,QAAQ,WAClC,OAAO,yBAAyB,EAAE,OAAO,gBACzC,OAAO,oBAAoB,EAAE,OAAO,cACpC,OAAO,WAAW,EAAE,OAAO,QAC3B,MAAM,YACN,OAAO,WAAW,EAAE,WAAW,EAkBzC;IAbG,yCAAgB;IAIZ,iDAAiD;IACjD,MADW,OAAO,kBAAkB,EAAE,OAAO,CACnB;IAUlC;;;;OAIG;IACH,gBAJW,OAAO,4CAA4C,EAAE,OAAO,UAC5D,OAAO,uBAAuB,EAAE,OAAO,YACvC,OAAO,uBAAuB,EAAE,gBAAgB,QAY1D;IAED,kDAIC;IAED;;;;;OAKG;IACH,iEAyEC;IAED;;;OAGG;IACH,mGASC;IAkBD;;OAEG;IACH,uDAEC;IAED;;OAEG;IACH,6/CAcC;IAED;;;;;OAKG;IACH,6BAHW,OAAO,oBAAoB,EAAE,gBAAgB,iDAkBvD;IAED;;;;;;;;;;;;OAYG;IACH,gHA2CC;IAED,uBAQC;IAgBD;;;;OAIG;IACH,8BAJW,MAAM,+DAEJ,OAAO,iBAAiB,EAAE,kBAAkB,CAKxD;CACJ;0BAnVyB,oBAAoB"}
1
+ {"version":3,"file":"unitView.d.ts","sourceRoot":"","sources":["../../../src/view/unitView.js"],"names":[],"mappings":"AAqBA;;;;GAIG;AACH;QAHkB,MAAM,GAAE,cAAc,kBAAkB,EAAE,OAAO;EASjE;AAEF;IACI;;;;;;;OAOG;IACH;;;;;;;;OAQG;IACH,kBAPW,OAAO,iBAAiB,EAAE,QAAQ,WAClC,OAAO,yBAAyB,EAAE,OAAO,gBACzC,OAAO,oBAAoB,EAAE,OAAO,cACpC,OAAO,WAAW,EAAE,OAAO,QAC3B,MAAM,YACN,OAAO,WAAW,EAAE,WAAW,EAkBzC;IAbG,yCAAgB;IAIZ,iDAAiD;IACjD,MADW,OAAO,kBAAkB,EAAE,OAAO,CACnB;IAUlC;;;;OAIG;IACH,gBAJW,OAAO,4CAA4C,EAAE,OAAO,UAC5D,OAAO,uBAAuB,EAAE,OAAO,YACvC,OAAO,uBAAuB,EAAE,gBAAgB,QAY1D;IAED,kDAIC;IAED;;;;;OAKG;IACH,iEAgFC;IAED;;;OAGG;IACH,mGASC;IAkBD;;OAEG;IACH,uDAEC;IAED;;OAEG;IACH,6/CAcC;IAED;;;;;OAKG;IACH,6BAHW,OAAO,oBAAoB,EAAE,gBAAgB,iDAkBvD;IAED;;;;;;;;;;;;OAYG;IACH,gHA2CC;IAED,uBAQC;IAgBD;;;;OAIG;IACH,8BAJW,MAAM,+DAEJ,OAAO,iBAAiB,EAAE,kBAAkB,CAKxD;CACJ;0BA1VyB,oBAAoB"}
@@ -160,9 +160,16 @@ export default class UnitView extends ContainerView {
160
160
  );
161
161
  } else if (type == "scale" && isChannelWithScale(channel)) {
162
162
  if (!view.resolutions[type][targetChannel]) {
163
- view.resolutions[type][targetChannel] = new ScaleResolution(
164
- targetChannel
165
- );
163
+ const resolution = new ScaleResolution(targetChannel);
164
+ view.resolutions[type][targetChannel] = resolution;
165
+
166
+ resolution.addEventListener("range", (event) => {
167
+ // Create if WebGLHelper is available, i.e., if not running in headless mode
168
+ this.context.glHelper?.createRangeTexture(
169
+ event.scaleResolution,
170
+ true
171
+ );
172
+ });
166
173
  }
167
174
  view.resolutions[type][targetChannel].pushUnitView(
168
175
  this,
@@ -84,6 +84,8 @@ export default class View {
84
84
  * @type {Record<import("../spec/channel.js").PrimaryPositionalChannel, boolean>}
85
85
  */
86
86
  needsAxes: Record<import("../spec/channel.js").PrimaryPositionalChannel, boolean>;
87
+ /** @type {ParamMediator} */
88
+ paramMediator: ParamMediator;
87
89
  getPadding(): Padding;
88
90
  /**
89
91
  * Returns a padding that indicates how much axes and titles extend over the plot area.
@@ -267,7 +269,7 @@ export default class View {
267
269
  * Returns `true` if this view and its children supports picking.
268
270
  */
269
271
  isPickingSupported(): boolean;
270
- getTitleText(): string;
272
+ getTitleText(): any;
271
273
  /**
272
274
  * @param {any} key string
273
275
  * @param {function(key?):T} callable A function that produces a value to be cached
@@ -321,6 +323,7 @@ export type ViewOptions = {
321
323
  */
322
324
  contributesToScaleDomain?: boolean;
323
325
  };
326
+ import ParamMediator from "./paramMediator.js";
324
327
  import Padding from "./layout/padding.js";
325
328
  import { FlexDimensions } from "./layout/flexLayout.js";
326
329
  //# sourceMappingURL=view.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/view/view.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/view/view.js"],"names":[],"mappings":"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"}
@@ -16,7 +16,7 @@ import { appendToBaseUrl } from "../utils/url.js";
16
16
  import { isDiscrete, bandSpace } from "vega-scale";
17
17
  import { peek } from "../utils/arrayUtils.js";
18
18
  import ViewError from "./viewError.js";
19
- import { isExprRef } from "../marks/mark.js";
19
+ import ParamMediator, { isExprRef } from "./paramMediator.js";
20
20
 
21
21
  // TODO: View classes have too many responsibilities. Come up with a way
22
22
  // to separate the concerns. However, most concerns are tightly tied to
@@ -128,6 +128,17 @@ export default class View {
128
128
  * @type {Record<import("../spec/channel.js").PrimaryPositionalChannel, boolean>}
129
129
  */
130
130
  this.needsAxes = { x: false, y: false };
131
+
132
+ /** @type {ParamMediator} */
133
+ this.paramMediator = new ParamMediator(
134
+ () => this.dataParent?.paramMediator
135
+ );
136
+
137
+ if (spec.params) {
138
+ for (const param of spec.params) {
139
+ this.paramMediator.registerParam(param);
140
+ }
141
+ }
131
142
  }
132
143
 
133
144
  getPadding() {
@@ -217,7 +228,7 @@ export default class View {
217
228
 
218
229
  const scale = this.getScaleResolution(
219
230
  dimension == "width" ? "x" : "y"
220
- )?.getScale();
231
+ )?.scale;
221
232
 
222
233
  if (scale) {
223
234
  // Note: this and all ancestral views need to be refreshed when the domain is changed.
@@ -631,7 +642,11 @@ export default class View {
631
642
  getTitleText() {
632
643
  const title = this.spec.title;
633
644
  if (title) {
634
- return isString(title) ? title : title.text;
645
+ return isString(title)
646
+ ? title
647
+ : isExprRef(title.text)
648
+ ? this.paramMediator.evaluateAndGet(title.text.expr)
649
+ : title.text;
635
650
  }
636
651
  }
637
652
 
@@ -706,7 +721,7 @@ function createViewOpacityFunction(view) {
706
721
  } else if (isDynamicOpacity(opacityDef)) {
707
722
  /** @type {(channel: import("../spec/channel.js").ChannelWithScale) => any} */
708
723
  const getScale = (channel) => {
709
- const scale = view.getScaleResolution(channel)?.getScale();
724
+ const scale = view.getScaleResolution(channel)?.scale;
710
725
  // Only works on linear scales
711
726
  if (["linear", "index", "locus"].includes(scale?.type)) {
712
727
  return scale;
@@ -736,9 +751,8 @@ function createViewOpacityFunction(view) {
736
751
  return interpolate(unitsPerPixel) * parentOpacity;
737
752
  };
738
753
  } else if (isExprRef(opacityDef)) {
739
- const fn = view.context.paramBroker.createExpression(
740
- opacityDef.expr
741
- );
754
+ const fn = view.paramMediator.createExpression(opacityDef.expr);
755
+ fn.addListener(() => view.context.animator.requestRender());
742
756
  return (parentOpacity) => fn(null) * parentOpacity;
743
757
  }
744
758
  }
@@ -1 +1 @@
1
- {"version":3,"file":"viewFactory.d.ts","sourceRoot":"","sources":["../../../src/view/viewFactory.js"],"names":[],"mappings":"AAuMA;;;;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;AAzRD,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,iBA4DlC;;CACJ;;kBAtLa,OAAO;eACP,OAAO;;iBAfJ,WAAW"}
1
+ {"version":3,"file":"viewFactory.d.ts","sourceRoot":"","sources":["../../../src/view/viewFactory.js"],"names":[],"mappings":"AAoPA;;;;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;AAtUD,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,iBA8DlC;;CACJ;;kBAxLa,OAAO;eACP,OAAO;;iBAfJ,WAAW"}
@@ -158,6 +158,8 @@ export class ViewFactory {
158
158
  if (validator) {
159
159
  validator(viewSpec);
160
160
  }
161
+
162
+ applyParamsToImportedSpec(viewSpec, spec.import);
161
163
  } else {
162
164
  throw new ViewError(
163
165
  "Importing views is not allowed!",
@@ -197,6 +199,49 @@ export class ViewFactory {
197
199
  }
198
200
  }
199
201
 
202
+ /**
203
+ *
204
+ * @param {ViewSpec} importedSpec
205
+ * @param {import("../spec/view.js").ImportParams} importParams
206
+ */
207
+ function applyParamsToImportedSpec(importedSpec, importParams) {
208
+ if (importParams.name != null) {
209
+ importedSpec.name = importParams.name;
210
+ }
211
+
212
+ const params = isArray(importParams.params)
213
+ ? importParams.params
214
+ : isObject(importParams.params)
215
+ ? Object.entries(importParams.params).map(([name, value]) => ({
216
+ name,
217
+ value,
218
+ }))
219
+ : [];
220
+
221
+ if (!params.length) {
222
+ return;
223
+ }
224
+
225
+ importedSpec.params ??= [];
226
+
227
+ // Replace overridden parameters
228
+ for (const param of params) {
229
+ const index = importedSpec.params.findIndex(
230
+ (p) => p.name == param.name
231
+ );
232
+ if (index >= 0) {
233
+ importedSpec.params[index] = param;
234
+ }
235
+ }
236
+
237
+ // Add missing parameters
238
+ for (const param of params) {
239
+ if (!importedSpec.params.some((p) => p.name == param.name)) {
240
+ importedSpec.params.push(param);
241
+ }
242
+ }
243
+ }
244
+
200
245
  /**
201
246
  *
202
247
  * @param {ViewSpec} spec
@@ -82,7 +82,11 @@ export function findUniqueViewNames(root: View): Set<string>;
82
82
  /**
83
83
  * @param {View} viewRoot
84
84
  */
85
- export function calculateCanvasSize(viewRoot: View): {
85
+ export function calculateViewRootSize(viewRoot: View): import("./layout/flexLayout.js").FlexDimensions;
86
+ /**
87
+ * @param {import("./layout/flexLayout.js").FlexDimensions} viewRootSize
88
+ */
89
+ export function calculateCanvasSize(viewRootSize: import("./layout/flexLayout.js").FlexDimensions): {
86
90
  width: number;
87
91
  height: number;
88
92
  };
@@ -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;;;;GAIG;AACH,uCAHW,MAAM,0BAKhB;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;;;;GAIG;AACH,2CAJW,OAAO,iBAAiB,EAAE,UAAU,WACpC,MAAM,eACN,OAAO,yBAAyB,EAAE,OAAO,gBA8BnD;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,8CAFW,IAAI;;;EAgBd;AAnBM,uCAFI,MAAM,WAE0D;iBAxP9B,WAAW;qBAFnC,eAAe"}
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;;;;GAIG;AACH,uCAHW,MAAM,0BAKhB;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;;;;GAIG;AACH,2CAJW,OAAO,iBAAiB,EAAE,UAAU,WACpC,MAAM,eACN,OAAO,yBAAyB,EAAE,OAAO,gBA8BnD;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;iBAxP9B,WAAW;qBAFnC,eAAe"}
@@ -256,9 +256,14 @@ export const isCustomViewName = (name) => !/^(layer|concat)\d+$/.test(name);
256
256
  /**
257
257
  * @param {View} viewRoot
258
258
  */
259
- export function calculateCanvasSize(viewRoot) {
260
- const size = viewRoot.getSize().addPadding(viewRoot.getOverhang());
259
+ export function calculateViewRootSize(viewRoot) {
260
+ return viewRoot.getSize().addPadding(viewRoot.getOverhang());
261
+ }
261
262
 
263
+ /**
264
+ * @param {import("./layout/flexLayout.js").FlexDimensions} viewRootSize
265
+ */
266
+ export function calculateCanvasSize(viewRootSize) {
262
267
  // If a dimension has an absolutely specified size (in pixels), use it for the canvas size.
263
268
  // However, if the dimension has a growing component, the canvas should be fit to the
264
269
  // container.
@@ -267,7 +272,7 @@ export function calculateCanvasSize(viewRoot) {
267
272
  /** @param {import("./layout/flexLayout.js").SizeDef} dim */
268
273
  const f = (dim) => (dim.grow > 0 ? undefined : dim.px);
269
274
  return {
270
- width: f(size.width),
271
- height: f(size.height),
275
+ width: f(viewRootSize.width),
276
+ height: f(viewRootSize.height),
272
277
  };
273
278
  }
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "contributors": [],
9
9
  "license": "MIT",
10
- "version": "0.43.3",
10
+ "version": "0.45.0",
11
11
  "jsdelivr": "dist/bundle/index.js",
12
12
  "unpkg": "dist/bundle/index.js",
13
13
  "browser": "dist/bundle/index.js",
@@ -43,27 +43,26 @@
43
43
  "@gmod/gff": "^1.3.0",
44
44
  "@gmod/indexedfasta": "^2.0.4",
45
45
  "@gmod/tabix": "^1.5.13",
46
- "@types/d3-array": "^3.0.2",
47
- "@types/d3-dsv": "^3.0.0",
48
- "@types/d3-ease": "^3.0.0",
49
- "@types/d3-format": "^3.0.1",
50
- "@types/d3-interpolate": "^3.0.1",
51
- "@types/d3-scale": "^4.0.2",
46
+ "@types/d3-array": "^3.2.1",
47
+ "@types/d3-dsv": "^3.0.7",
48
+ "@types/d3-ease": "^3.0.2",
49
+ "@types/d3-format": "^3.0.4",
50
+ "@types/d3-interpolate": "^3.0.4",
51
+ "@types/d3-scale": "^4.0.8",
52
52
  "buffer": "^6.0.3",
53
- "d3-array": "^3.1.1",
54
- "d3-color": "^3.0.1",
53
+ "d3-array": "^3.2.4",
54
+ "d3-color": "^3.1.0",
55
55
  "d3-ease": "^3.0.1",
56
- "d3-format": "^3.0.1",
56
+ "d3-format": "^3.1.0",
57
57
  "events": "^3.3.0",
58
58
  "flatqueue": "^2.0.3",
59
59
  "internmap": "^2.0.3",
60
- "lit": "^3.1.0",
61
- "lit-html": "^3.0.2",
60
+ "lit": "^3.1.2",
62
61
  "twgl.js": "^4.19.1",
63
- "vega-expression": "^5.0.0",
64
- "vega-loader": "^4.4.0",
65
- "vega-scale": "^7.1.1",
66
- "vega-util": "^1.16.0"
62
+ "vega-expression": "^5.1.0",
63
+ "vega-loader": "^4.5.1",
64
+ "vega-scale": "^7.3.1",
65
+ "vega-util": "^1.17.2"
67
66
  },
68
- "gitHead": "0c6e0418a7461b40da98896bfaf5e05732384e85"
67
+ "gitHead": "7b6de39e856c85c755b2134bf451780c8b7922bb"
69
68
  }
@@ -1,30 +0,0 @@
1
- /**
2
- * A class that manages parameters and expressions. Still a work in progress.
3
- *
4
- * TODO: Write tests for this class.
5
- *
6
- * This should eventually handle the following:
7
- * - Parameter registration
8
- * - Dependency tracking
9
- * - Calling observers when a parameter changes
10
- * - Somehow saving parameter "state" (in bookmarks)
11
- * - Maybe something else
12
- */
13
- export default class ParamBroker {
14
- /**
15
- *
16
- * @param {string} paramName
17
- * @returns {(value: any) => void}
18
- */
19
- allocateSetter(paramName: string): (value: any) => void;
20
- /**
21
- * Parse expr and return a function that returns the value of the parameter.
22
- *
23
- * @param {string} expr
24
- */
25
- createExpression(expr: string): ((x: object) => any) & import("./utils/expression.js").ExpressionProps & {
26
- addListener: (listener: () => void) => void;
27
- };
28
- #private;
29
- }
30
- //# sourceMappingURL=paramBroker.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"paramBroker.d.ts","sourceRoot":"","sources":["../../src/paramBroker.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH;IAyBI;;;;OAIG;IACH,0BAHW,MAAM,WACI,GAAG,KAAK,IAAI,CAqBhC;IAID;;;;OAIG;IACH,uBAFW,MAAM;gCAG6E,MAAM,IAAI,KAAK,IAAI;MA0BhH;;CACJ"}
@@ -1,102 +0,0 @@
1
- import { isString } from "vega-util";
2
- import createFunction from "./utils/expression.js";
3
-
4
- /**
5
- * A class that manages parameters and expressions. Still a work in progress.
6
- *
7
- * TODO: Write tests for this class.
8
- *
9
- * This should eventually handle the following:
10
- * - Parameter registration
11
- * - Dependency tracking
12
- * - Calling observers when a parameter changes
13
- * - Somehow saving parameter "state" (in bookmarks)
14
- * - Maybe something else
15
- */
16
- export default class ParamBroker {
17
- /** @type {Map<string, any>} */
18
- #params;
19
-
20
- /** @type {Set<string>} */
21
- #allocatedSetters;
22
-
23
- /** @type {Record<string, any>} */
24
- #proxy;
25
-
26
- /** @type {Map<string, Set<() => void>>} */
27
- #paramListeners;
28
-
29
- constructor() {
30
- this.#params = new Map();
31
- this.#allocatedSetters = new Set();
32
- this.#paramListeners = new Map();
33
-
34
- this.#proxy = new Proxy(this.#params, {
35
- get(target, prop) {
36
- return isString(prop) ? target.get(prop) : undefined;
37
- },
38
- });
39
- }
40
-
41
- /**
42
- *
43
- * @param {string} paramName
44
- * @returns {(value: any) => void}
45
- */
46
- allocateSetter(paramName) {
47
- if (this.#allocatedSetters.has(paramName)) {
48
- throw new Error(
49
- "Setter already allocated for parameter: " + paramName
50
- );
51
- }
52
-
53
- this.#allocatedSetters.add(paramName);
54
-
55
- return (value) => {
56
- this.#params.set(paramName, value);
57
-
58
- const listeners = this.#paramListeners.get(paramName);
59
- if (listeners) {
60
- for (const listener of listeners) {
61
- listener();
62
- }
63
- }
64
- };
65
- }
66
-
67
- // TODO: deallocateSetter
68
-
69
- /**
70
- * Parse expr and return a function that returns the value of the parameter.
71
- *
72
- * @param {string} expr
73
- */
74
- createExpression(expr) {
75
- /** @type {import("./utils/expression.js").ExpressionFunction & { addListener: (listener: () => void) => void}} */
76
- const fn = /** @type {any} */ (createFunction(expr, this.#proxy));
77
-
78
- for (const g of fn.globals) {
79
- if (!this.#allocatedSetters.has(g)) {
80
- throw new Error(
81
- `Unknown variable "${g}" in expression: ${expr}`
82
- );
83
- }
84
- }
85
-
86
- /**
87
- *
88
- * @param {() => void} listener
89
- */
90
- fn.addListener = (listener) => {
91
- for (const g of fn.globals) {
92
- const listeners = this.#paramListeners.get(g) ?? new Set();
93
- this.#paramListeners.set(g, listeners);
94
- listeners.add(listener);
95
- }
96
- };
97
-
98
- // TODO: remove listener
99
-
100
- return fn;
101
- }
102
- }