@genome-spy/core 0.46.1 → 0.47.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 (44) hide show
  1. package/dist/bundle/index.es.js +5184 -5086
  2. package/dist/bundle/index.js +104 -93
  3. package/dist/schema.json +38 -0
  4. package/dist/src/genomeSpy.d.ts.map +1 -1
  5. package/dist/src/genomeSpy.js +23 -15
  6. package/dist/src/gl/webGLHelper.d.ts +2 -1
  7. package/dist/src/gl/webGLHelper.d.ts.map +1 -1
  8. package/dist/src/gl/webGLHelper.js +8 -1
  9. package/dist/src/marks/mark.d.ts +24 -12
  10. package/dist/src/marks/mark.d.ts.map +1 -1
  11. package/dist/src/marks/mark.js +27 -13
  12. package/dist/src/marks/point.d.ts +0 -1
  13. package/dist/src/marks/point.d.ts.map +1 -1
  14. package/dist/src/marks/point.js +6 -2
  15. package/dist/src/marks/text.d.ts.map +1 -1
  16. package/dist/src/marks/text.js +4 -1
  17. package/dist/src/scale/scale.js +2 -0
  18. package/dist/src/spec/parameter.d.ts +20 -1
  19. package/dist/src/types/embedApi.d.ts +7 -0
  20. package/dist/src/types/rendering.d.ts +6 -0
  21. package/dist/src/utils/animator.d.ts +15 -0
  22. package/dist/src/utils/animator.d.ts.map +1 -1
  23. package/dist/src/utils/animator.js +66 -0
  24. package/dist/src/utils/inertia.d.ts +4 -15
  25. package/dist/src/utils/inertia.d.ts.map +1 -1
  26. package/dist/src/utils/inertia.js +28 -63
  27. package/dist/src/utils/inputBinding.d.ts.map +1 -1
  28. package/dist/src/utils/inputBinding.js +26 -2
  29. package/dist/src/view/gridView.d.ts +4 -6
  30. package/dist/src/view/gridView.d.ts.map +1 -1
  31. package/dist/src/view/gridView.js +45 -27
  32. package/dist/src/view/unitView.d.ts +3 -14
  33. package/dist/src/view/unitView.d.ts.map +1 -1
  34. package/dist/src/view/unitView.js +26 -8
  35. package/dist/src/view/view.d.ts +14 -5
  36. package/dist/src/view/view.d.ts.map +1 -1
  37. package/dist/src/view/view.js +26 -7
  38. package/dist/src/view/zoom.d.ts +2 -2
  39. package/dist/src/view/zoom.d.ts.map +1 -1
  40. package/dist/src/view/zoom.js +1 -1
  41. package/package.json +2 -2
  42. package/dist/src/view/renderingContext/layoutRecorderViewRenderingContext.d.ts +0 -60
  43. package/dist/src/view/renderingContext/layoutRecorderViewRenderingContext.d.ts.map +0 -1
  44. package/dist/src/view/renderingContext/layoutRecorderViewRenderingContext.js +0 -128
@@ -1,4 +1,6 @@
1
1
  import { lerp } from "vega-util";
2
+ import { makeLerpSmoother } from "./animator.js";
3
+ import clamp from "./clamp.js";
2
4
 
3
5
  /**
4
6
  * Creates some inertia, mainly for zooming with a mechanical mouse wheel
@@ -11,35 +13,32 @@ export default class Inertia {
11
13
  constructor(animator, disabled) {
12
14
  this.animator = animator;
13
15
  this.disabled = !!disabled;
14
- this.damping = 0.015;
15
- this.acceleration = 0.3; // per event
16
- /** Use acceleration if the momentum step is greater than X */
17
- this.accelerationThreshold = 100;
18
- this.lowerLimit = 0.5; // When to stop updating
19
- this.loop = false;
20
16
 
21
- this.momentum = 0;
22
- this.timestamp = 0;
17
+ // Limit the velocity by setting the maximum distance the value can travel
18
+ this.maxDistance = 500;
19
+
23
20
  /** @type {function(number):void} */
24
21
  this.callback = null;
25
22
 
26
- this._transitionCallback = this.animate.bind(this);
27
- this.clear();
28
- }
29
-
30
- clear() {
31
- /** @type {number} */
32
- this.momentum = 0;
33
- this.timestamp = null;
34
- this.loop = null;
35
- this.callback = null;
23
+ this.targetValue = 0;
24
+ this.lastValue = 0;
25
+
26
+ this.smoother = makeLerpSmoother(
27
+ animator,
28
+ (value) => {
29
+ const delta = value - this.lastValue;
30
+ this.lastValue = value;
31
+ this.callback?.(delta);
32
+ },
33
+ 40,
34
+ 0.1
35
+ );
36
36
  }
37
37
 
38
38
  cancel() {
39
- if (this.loop) {
40
- this.animator.cancelTransition(this._transitionCallback);
41
- this.clear();
42
- }
39
+ // decelelerate rapidly
40
+ this.targetValue = lerp([this.lastValue, this.targetValue], 0.3);
41
+ this.smoother(this.targetValue);
43
42
  }
44
43
 
45
44
  /**
@@ -53,50 +52,16 @@ export default class Inertia {
53
52
  return;
54
53
  }
55
54
 
56
- // This may have some use in the future to improve the behavior of
57
- // a mechanical mouse wheel:
58
- // https://github.com/w3c/uievents/issues/181
59
-
60
- if (value * this.momentum < 0) {
61
- this.momentum = 0; // Stop if the direction changes
62
- } else if (Math.abs(value) > this.accelerationThreshold) {
63
- this.momentum = lerp([this.momentum, value], this.acceleration);
64
- } else {
65
- this.momentum = value;
66
- }
67
-
68
55
  this.callback = callback;
69
56
 
70
- if (!this.loop) {
71
- this.animate();
72
- }
73
- }
74
-
75
- /**
76
- *
77
- * @param {number} [timestamp]
78
- */
79
- animate(timestamp) {
80
- this.callback(this.momentum); // TODO: This is actually a delta, should take the elapsed time into account
57
+ const delta = clamp(
58
+ this.targetValue + value - this.lastValue,
59
+ -this.maxDistance,
60
+ this.maxDistance
61
+ );
62
+ this.targetValue = this.lastValue + delta;
81
63
 
82
- const timeDelta = timestamp - this.timestamp || 0;
83
- this.timestamp = timestamp;
84
-
85
- const velocity = Math.abs(this.momentum);
86
-
87
- this.momentum =
88
- Math.sign(this.momentum) *
89
- Math.max(
90
- 0,
91
- velocity - ((velocity * this.damping) ** 1.5 + 0.04) * timeDelta
92
- );
93
-
94
- if (Math.abs(this.momentum) > this.lowerLimit) {
95
- this.loop = true;
96
- this.animator.requestTransition(this._transitionCallback);
97
- } else {
98
- this.clear();
99
- }
64
+ this.smoother(this.targetValue);
100
65
  }
101
66
  }
102
67
 
@@ -1 +1 @@
1
- {"version":3,"file":"inputBinding.d.ts","sourceRoot":"","sources":["../../../src/utils/inputBinding.js"],"names":[],"mappings":"AAIA;;GAEG;AACH,sDAFW,OAAO,0BAA0B,EAAE,OAAO,8CA6GpD"}
1
+ {"version":3,"file":"inputBinding.d.ts","sourceRoot":"","sources":["../../../src/utils/inputBinding.js"],"names":[],"mappings":"AAIA;;GAEG;AACH,sDAFW,OAAO,0BAA0B,EAAE,OAAO,8CAqIpD"}
@@ -32,7 +32,6 @@ export default function createBindingInputs(mediator) {
32
32
  const id = `${random}-param-${name}`;
33
33
 
34
34
  if (bind.input == "range") {
35
- // TODO: Show the value next to the slider
36
35
  inputs.push(
37
36
  html`<label for=${id}>${label}</label>
38
37
  <div>
@@ -99,8 +98,33 @@ export default function createBindingInputs(mediator) {
99
98
  )}
100
99
  </select> `
101
100
  );
101
+ } else if (
102
+ bind.input == "text" ||
103
+ bind.input == "number" ||
104
+ bind.input == "color"
105
+ ) {
106
+ inputs.push(
107
+ html`<label for=${id}>${label}</label>
108
+ <div>
109
+ <input
110
+ id=${id}
111
+ type=${bind.input}
112
+ placeholder=${bind.placeholder ?? ""}
113
+ autocomplete=${bind.autocomplete ?? "off"}
114
+ .value=${value}
115
+ @focus=${(/** @type {any} */ e) =>
116
+ e.target.select()}
117
+ @input=${(/** @type {any} */ e) => {
118
+ debouncedSetter(
119
+ bind.input == "number"
120
+ ? e.target.valueAsNumber
121
+ : e.target.value
122
+ );
123
+ }}
124
+ />
125
+ </div>`
126
+ );
102
127
  } else {
103
- // TODO: Support other types: "text", "number", "color".
104
128
  throw new Error("Unsupported input type: " + bind.input);
105
129
  }
106
130
 
@@ -117,22 +117,20 @@ declare class Scrollbar extends UnitView {
117
117
  * @param {ScrollDirection} scrollDirection
118
118
  */
119
119
  constructor(gridChild: GridChild, scrollDirection: "vertical" | "horizontal");
120
+ viewportOffset: number;
120
121
  config: {
121
122
  scrollbarSize: number;
122
123
  scrollbarPadding: number;
123
124
  };
124
- scrollDirection: "vertical" | "horizontal";
125
- viewportOffset: number;
126
- maxScrollOffset: number;
127
- scrollbarCoords: Rectangle;
128
- getScrollOffset(): number;
125
+ interpolateViewportOffset: (target: number) => void;
126
+ get scrollOffset(): number;
129
127
  /**
130
128
  *
131
129
  * @param {Rectangle} viewportCoords
132
130
  * @param {Rectangle} coords
133
131
  */
134
132
  updateScrollbar(viewportCoords: Rectangle, coords: Rectangle): void;
135
- maxViewportOffset: number;
133
+ #private;
136
134
  }
137
135
  import Padding from "./layout/padding.js";
138
136
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"gridView.d.ts","sourceRoot":"","sources":["../../../src/view/gridView.js"],"names":[],"mappings":"AAowBA;;;GAGG;AACH,iDAHW,OAAO,iBAAiB,EAAE,cAAc,GACtC,OAAO,iBAAiB,EAAE,QAAQ,CAwB9C;AAED;;;GAGG;AACH,uDAHW,OAAO,iBAAiB,EAAE,cAAc,GACtC,OAAO,iBAAiB,EAAE,QAAQ,CA6C9C;AA2BD;;GAEG;AACH,8EAUC;AAED;;;;;GAKG;AACH,4CAJW,OAAO,uBAAuB,EAAE,OAAO,UACvC,OAAO,iBAAiB,EAAE,UAAU,YACpC,QAAQ,aAmBlB;AA33BD;;;;;;;;;;;;;;;GAeG;AACH;IA6BI;;;;;;;;;OASG;IACH,kBARW,OAAO,iBAAiB,EAAE,aAAa,WACvC,OAAO,yBAAyB,EAAE,OAAO,gBACzC,aAAa,iDAEb,MAAM,WACN,MAAM,YACN,OAAO,WAAW,EAAE,WAAW,EAoBzC;IARG,8CAAgB;IAOhB,uBAA0B;IAG9B;;OAEG;IACH,qDAIC;IAeD;;OAEG;IACH,wDAKC;IAqBD;;OAEG;IACH,8CAEC;IAED,yBAEC;IAED;;OAEG;IACH,wCAmCC;IA2OD;;;;OAIG;IAEH,gBALW,OAAO,4CAA4C,EAAE,OAAO,UAC5D,OAAO,uBAAuB,EAAE,OAAO,YACvC,OAAO,uBAAuB,EAAE,gBAAgB,QA6O1D;;CAmGJ;AAgJD;IACI;;;;OAIG;IACH,6DAHW,aAAa,UACb,MAAM,EAoFhB;IAjFG,4BAAgC;IAChC,kCAAgB;IAChB,eAAoB;IAEpB,uBAAuB;IACvB,YADW,QAAQ,CACQ;IAE3B,uBAAuB;IACvB,kBADW,QAAQ,CACc;IAEjC,mFAAmF;IACnF,MADW,QAAQ,OAAO,OAAO,iBAAiB,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAC5D;IAEd,4FAA4F;IAC5F,WADW,QAAQ,OAAO,OAAO,iBAAiB,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAC3D;IAEnB,0DAA0D;IAC1D,kEAAoB;IAEpB,uBAAuB;IACvB,OADW,QAAQ,CACG;IAEtB,wBAAwB;IACxB,QADW,SAAS,CACQ;IA4DhC,uEAcC;IAED;;OAEG;IACH,4BAkKC;IAED,uBAqBC;IAED,iCAEC;CACJ;qBAhrC0D,eAAe;sBAFpD,uBAAuB;0BAGnB,oBAAoB;qBAGzB,eAAe;yBALX,mBAAmB;AAmrC5C;IACI;;;OAGG;IACH,uBAHW,SAAS,8CAyFnB;IAtDG;;;MAAoB;IACpB,2CAAsC;IAKtC,uBAAuB;IAEvB,wBAAwB;IACxB,2BAAqC;IA+CzC,0BAKC;IAWD;;;;OAIG;IACH,gCAHW,SAAS,UACT,SAAS,QA8CnB;IA7BG,0BAAsE;CA8B7E;oBAp1CmB,qBAAqB"}
1
+ {"version":3,"file":"gridView.d.ts","sourceRoot":"","sources":["../../../src/view/gridView.js"],"names":[],"mappings":"AAqwBA;;;GAGG;AACH,iDAHW,OAAO,iBAAiB,EAAE,cAAc,GACtC,OAAO,iBAAiB,EAAE,QAAQ,CAwB9C;AAED;;;GAGG;AACH,uDAHW,OAAO,iBAAiB,EAAE,cAAc,GACtC,OAAO,iBAAiB,EAAE,QAAQ,CA6C9C;AA2BD;;GAEG;AACH,8EAUC;AAED;;;;;GAKG;AACH,4CAJW,OAAO,uBAAuB,EAAE,OAAO,UACvC,OAAO,iBAAiB,EAAE,UAAU,YACpC,QAAQ,aAmBlB;AA33BD;;;;;;;;;;;;;;;GAeG;AACH;IA6BI;;;;;;;;;OASG;IACH,kBARW,OAAO,iBAAiB,EAAE,aAAa,WACvC,OAAO,yBAAyB,EAAE,OAAO,gBACzC,aAAa,iDAEb,MAAM,WACN,MAAM,YACN,OAAO,WAAW,EAAE,WAAW,EAoBzC;IARG,8CAAgB;IAOhB,uBAA0B;IAG9B;;OAEG;IACH,qDAIC;IAeD;;OAEG;IACH,wDAKC;IAqBD;;OAEG;IACH,8CAEC;IAED,yBAEC;IAED;;OAEG;IACH,wCAmCC;IA2OD;;;;OAIG;IAEH,gBALW,OAAO,4CAA4C,EAAE,OAAO,UAC5D,OAAO,uBAAuB,EAAE,OAAO,YACvC,OAAO,uBAAuB,EAAE,gBAAgB,QA6O1D;;CAmGJ;AAgJD;IACI;;;;OAIG;IACH,6DAHW,aAAa,UACb,MAAM,EAoFhB;IAjFG,4BAAgC;IAChC,kCAAgB;IAChB,eAAoB;IAEpB,uBAAuB;IACvB,YADW,QAAQ,CACQ;IAE3B,uBAAuB;IACvB,kBADW,QAAQ,CACc;IAEjC,mFAAmF;IACnF,MADW,QAAQ,OAAO,OAAO,iBAAiB,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAC5D;IAEd,4FAA4F;IAC5F,WADW,QAAQ,OAAO,OAAO,iBAAiB,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAC3D;IAEnB,0DAA0D;IAC1D,kEAAoB;IAEpB,uBAAuB;IACvB,OADW,QAAQ,CACG;IAEtB,wBAAwB;IACxB,QADW,SAAS,CACQ;IA4DhC,uEAcC;IAED;;OAEG;IACH,4BAkKC;IAED,uBAqBC;IAED,iCAEC;CACJ;qBAjrC0D,eAAe;sBAFpD,uBAAuB;0BAGnB,oBAAoB;qBAGzB,eAAe;yBALX,mBAAmB;AAorC5C;IAeI;;;OAGG;IACH,uBAHW,SAAS,8CA4FnB;IA/FD,uBAAmB;IAsCf;;;MAAoB;IAIpB,oDAQC;IA+CL,2BAKC;IAWD;;;;OAIG;IACH,gCAHW,SAAS,UACT,SAAS,QA8CnB;;CACJ;oBAt2CmB,qBAAqB"}
@@ -18,6 +18,7 @@ import createTitle from "./title.js";
18
18
  import UnitView from "./unitView.js";
19
19
  import interactionToZoom from "./zoom.js";
20
20
  import clamp from "../utils/clamp.js";
21
+ import { makeLerpSmoother } from "../utils/animator.js";
21
22
 
22
23
  /**
23
24
  * Modeled after: https://vega.github.io/vega/docs/layout/
@@ -1214,6 +1215,20 @@ export class GridChild {
1214
1215
  }
1215
1216
 
1216
1217
  class Scrollbar extends UnitView {
1218
+ /** @type {ScrollDirection} */
1219
+ #scrollDirection;
1220
+
1221
+ #scrollbarCoords = Rectangle.ZERO;
1222
+
1223
+ #maxScrollOffset = 0;
1224
+
1225
+ #maxViewportOffset = 0;
1226
+
1227
+ // This is the actual state of the scrollbar. It's better to keep track of
1228
+ // the viewport offset rather than the scrollbar offset because the former
1229
+ // is more stable when the viewport size changes.
1230
+ viewportOffset = 0;
1231
+
1217
1232
  /**
1218
1233
  * @param {GridChild} gridChild
1219
1234
  * @param {ScrollDirection} scrollDirection
@@ -1251,20 +1266,23 @@ class Scrollbar extends UnitView {
1251
1266
  );
1252
1267
 
1253
1268
  this.config = config;
1254
- this.scrollDirection = scrollDirection;
1269
+ this.#scrollDirection = scrollDirection;
1255
1270
 
1256
- // This is the actual state of the scrollbar. It's better to keep track of
1257
- // the viewport offset rather than the scrollbar offset because the former
1258
- // is more stable when the viewport size changes.
1259
- this.viewportOffset = 0;
1260
-
1261
- this.maxScrollOffset = 0;
1262
- this.scrollbarCoords = Rectangle.ZERO;
1271
+ // Make it smooth!
1272
+ this.interpolateViewportOffset = makeLerpSmoother(
1273
+ this.context.animator,
1274
+ (value) => {
1275
+ this.viewportOffset = value;
1276
+ },
1277
+ 50,
1278
+ 0.4,
1279
+ this.viewportOffset
1280
+ );
1263
1281
 
1264
1282
  this.addInteractionEventListener("mousedown", (coords, event) => {
1265
1283
  event.stopPropagation();
1266
1284
 
1267
- if (this.maxScrollOffset <= 0) {
1285
+ if (this.#maxScrollOffset <= 0) {
1268
1286
  return;
1269
1287
  }
1270
1288
 
@@ -1276,7 +1294,7 @@ class Scrollbar extends UnitView {
1276
1294
  const mouseEvent = /** @type {MouseEvent} */ (event.uiEvent);
1277
1295
  mouseEvent.preventDefault();
1278
1296
 
1279
- const initialScrollOffset = this.getScrollOffset();
1297
+ const initialScrollOffset = this.scrollOffset;
1280
1298
  const initialOffset = getMouseOffset(mouseEvent);
1281
1299
 
1282
1300
  const onMousemove = /** @param {MouseEvent} moveEvent */ (
@@ -1287,13 +1305,13 @@ class Scrollbar extends UnitView {
1287
1305
  initialOffset +
1288
1306
  initialScrollOffset,
1289
1307
  0,
1290
- this.maxScrollOffset
1308
+ this.#maxScrollOffset
1291
1309
  );
1292
1310
 
1293
- this.viewportOffset =
1294
- (scrollOffset / this.maxScrollOffset) *
1295
- this.maxViewportOffset;
1296
- this.context.animator.requestRender();
1311
+ this.interpolateViewportOffset(
1312
+ (scrollOffset / this.#maxScrollOffset) *
1313
+ this.#maxViewportOffset
1314
+ );
1297
1315
  };
1298
1316
 
1299
1317
  const onMouseup = () => {
@@ -1306,10 +1324,10 @@ class Scrollbar extends UnitView {
1306
1324
  });
1307
1325
  }
1308
1326
 
1309
- getScrollOffset() {
1327
+ get scrollOffset() {
1310
1328
  return (
1311
- (this.viewportOffset / this.maxViewportOffset) *
1312
- this.maxScrollOffset
1329
+ (this.viewportOffset / this.#maxViewportOffset) *
1330
+ this.#maxScrollOffset
1313
1331
  );
1314
1332
  }
1315
1333
 
@@ -1319,7 +1337,7 @@ class Scrollbar extends UnitView {
1319
1337
  * @param {import("../types/rendering.js").RenderingOptions} [options]
1320
1338
  */
1321
1339
  render(context, coords, options) {
1322
- super.render(context, this.scrollbarCoords, options);
1340
+ super.render(context, this.#scrollbarCoords, options);
1323
1341
  }
1324
1342
 
1325
1343
  /**
@@ -1332,7 +1350,7 @@ class Scrollbar extends UnitView {
1332
1350
  const sSize = this.config.scrollbarSize;
1333
1351
 
1334
1352
  const dimension =
1335
- this.scrollDirection == "horizontal" ? "width" : "height";
1353
+ this.#scrollDirection == "horizontal" ? "width" : "height";
1336
1354
 
1337
1355
  const visibleFraction = Math.min(
1338
1356
  1,
@@ -1341,28 +1359,28 @@ class Scrollbar extends UnitView {
1341
1359
  const maxScrollLength = viewportCoords[dimension] - 2 * sPad;
1342
1360
  const scrollLength = visibleFraction * maxScrollLength;
1343
1361
 
1344
- this.maxScrollOffset = maxScrollLength - scrollLength;
1345
- this.maxViewportOffset = coords[dimension] - viewportCoords[dimension];
1362
+ this.#maxScrollOffset = maxScrollLength - scrollLength;
1363
+ this.#maxViewportOffset = coords[dimension] - viewportCoords[dimension];
1346
1364
  this.viewportOffset = clamp(
1347
1365
  this.viewportOffset,
1348
1366
  0,
1349
- this.maxViewportOffset
1367
+ this.#maxViewportOffset
1350
1368
  );
1351
1369
 
1352
- this.scrollbarCoords =
1353
- this.scrollDirection == "vertical"
1370
+ this.#scrollbarCoords =
1371
+ this.#scrollDirection == "vertical"
1354
1372
  ? new Rectangle(
1355
1373
  () =>
1356
1374
  viewportCoords.x +
1357
1375
  viewportCoords.width -
1358
1376
  sSize -
1359
1377
  sPad,
1360
- () => viewportCoords.y + sPad + this.getScrollOffset(),
1378
+ () => viewportCoords.y + sPad + this.scrollOffset,
1361
1379
  () => sSize,
1362
1380
  () => scrollLength
1363
1381
  )
1364
1382
  : new Rectangle(
1365
- () => viewportCoords.x + sPad + this.getScrollOffset(),
1383
+ () => viewportCoords.x + sPad + this.scrollOffset,
1366
1384
  () =>
1367
1385
  viewportCoords.y +
1368
1386
  viewportCoords.height -
@@ -6,15 +6,7 @@
6
6
  export const markTypes: {
7
7
  [x: string]: typeof import("../marks/mark.js").default;
8
8
  };
9
- export default class UnitView extends ContainerView {
10
- /**
11
- * @typedef {import("../spec/channel.js").Channel} Channel
12
- * @typedef {import("./view.js").default} View
13
- * @typedef {import("./layerView.js").default} LayerView
14
- * @typedef {import("../utils/domainArray.js").DomainArray} DomainArray
15
- * @typedef {import("../spec/view.js").ResolutionTarget} ResolutionTarget
16
- *
17
- */
9
+ export default class UnitView extends View {
18
10
  /**
19
11
  *
20
12
  * @param {import("../spec/view.js").UnitSpec} spec
@@ -51,10 +43,6 @@ export default class UnitView extends ContainerView {
51
43
  * Returns a collector that is associated with this view.
52
44
  */
53
45
  getCollector(): import("../data/collector.js").default;
54
- /**
55
- * @param {Channel} channel A primary channel
56
- */
57
- _validateDomainQuery(channel: import("../spec/channel.js").Channel): import("../spec/channel.js").MarkPropExprDef<import("../spec/channel.js").Type> | import("../spec/channel.js").MarkPropDatumDef<import("../spec/channel.js").Type> | import("../spec/channel.js").ChromPosDef | import("../spec/channel.js").PositionDatumDef | (import("../spec/channel.js").ChromPosDefBase & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").TypeMixins<"locus"> & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").XIndexDef) | (import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").DatumDefBase & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").XIndexDef) | import("../spec/channel.js").MarkPropDatumDef<import("../spec/channel.js").TypeForShape> | import("../spec/channel.js").MarkPropFieldDef<string, import("../spec/channel.js").Type> | import("../spec/channel.js").PositionFieldDef<string> | (import("../spec/channel.js").FieldDefBase<string> & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").XIndexDef) | import("../spec/channel.js").MarkPropFieldDef<string, import("../spec/channel.js").TypeForShape>;
58
46
  /**
59
47
  * Returns the domain of the specified channel of this domain/mark.
60
48
  *
@@ -83,6 +71,7 @@ export default class UnitView extends ContainerView {
83
71
  * @returns {import("../spec/view.js").ResolutionBehavior}
84
72
  */
85
73
  getDefaultResolution(channel: string, resolutionType: import("../spec/view.js").ResolutionTarget): import("../spec/view.js").ResolutionBehavior;
74
+ #private;
86
75
  }
87
- import ContainerView from "./containerView.js";
76
+ import View from "./view.js";
88
77
  //# sourceMappingURL=unitView.d.ts.map
@@ -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,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"}
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;;;;;;;;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,EA+BzC;IA1BG,yCAAgB;IAIZ,iDAAiD;IACjD,MADW,OAAO,kBAAkB,EAAE,OAAO,CACnB;IAuBlC;;;;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;IAqBD;;;;;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;iBA/VgB,WAAW"}
@@ -4,7 +4,6 @@ import RuleMark from "../marks/rule.js";
4
4
  import LinkMark from "../marks/link.js";
5
5
  import TextMark from "../marks/text.js";
6
6
 
7
- import ContainerView from "./containerView.js";
8
7
  import ScaleResolution from "./scaleResolution.js";
9
8
  import {
10
9
  isSecondaryChannel,
@@ -18,6 +17,7 @@ import {
18
17
  } from "../encoder/encoder.js";
19
18
  import createDomain from "../utils/domainArray.js";
20
19
  import AxisResolution from "./axisResolution.js";
20
+ import View from "./view.js";
21
21
 
22
22
  /**
23
23
  *
@@ -32,15 +32,20 @@ export const markTypes = {
32
32
  text: TextMark,
33
33
  };
34
34
 
35
- export default class UnitView extends ContainerView {
35
+ export default class UnitView extends View {
36
36
  /**
37
37
  * @typedef {import("../spec/channel.js").Channel} Channel
38
- * @typedef {import("./view.js").default} View
39
- * @typedef {import("./layerView.js").default} LayerView
40
38
  * @typedef {import("../utils/domainArray.js").DomainArray} DomainArray
41
39
  * @typedef {import("../spec/view.js").ResolutionTarget} ResolutionTarget
42
40
  *
43
41
  */
42
+
43
+ /**
44
+ * Sets the zoom level parameter.
45
+ * @type {(zoomLevel: number) => void}
46
+ */
47
+ #zoomLevelSetter;
48
+
44
49
  /**
45
50
  *
46
51
  * @param {import("../spec/view.js").UnitSpec} spec
@@ -65,6 +70,19 @@ export default class UnitView extends ContainerView {
65
70
 
66
71
  this.resolve();
67
72
 
73
+ this.#zoomLevelSetter = this.paramMediator.allocateSetter(
74
+ "zoomLevel",
75
+ 1.0
76
+ );
77
+ /** @type {import("../spec/channel.js").ChannelWithScale[]} */ ([
78
+ "x",
79
+ "y",
80
+ ]).forEach((channel) =>
81
+ this.getScaleResolution(channel)?.addEventListener("domain", () =>
82
+ this.#zoomLevelSetter(Math.sqrt(this.getZoomLevel()))
83
+ )
84
+ );
85
+
68
86
  this.needsAxes = { x: true, y: true };
69
87
  }
70
88
 
@@ -129,7 +147,7 @@ export default class UnitView extends ContainerView {
129
147
  while (
130
148
  (view.getConfiguredOrDefaultResolution(targetChannel, type) ==
131
149
  "forced" ||
132
- (view.dataParent instanceof ContainerView &&
150
+ (view.dataParent &&
133
151
  ["shared", "excluded", "forced"].includes(
134
152
  view.dataParent.getConfiguredOrDefaultResolution(
135
153
  targetChannel,
@@ -220,7 +238,7 @@ export default class UnitView extends ContainerView {
220
238
  /**
221
239
  * @param {Channel} channel A primary channel
222
240
  */
223
- _validateDomainQuery(channel) {
241
+ #validateDomainQuery(channel) {
224
242
  if (isSecondaryChannel(channel)) {
225
243
  throw new Error(
226
244
  `getDomain(${channel}), must only be called for primary channels!`
@@ -243,7 +261,7 @@ export default class UnitView extends ContainerView {
243
261
  * @returns {DomainArray}
244
262
  */
245
263
  getConfiguredDomain(channel) {
246
- const channelDef = this._validateDomainQuery(channel);
264
+ const channelDef = this.#validateDomainQuery(channel);
247
265
 
248
266
  const specDomain =
249
267
  channelDef && channelDef.scale && channelDef.scale.domain;
@@ -273,7 +291,7 @@ export default class UnitView extends ContainerView {
273
291
  * @returns {DomainArray}
274
292
  */
275
293
  extractDataDomain(channel) {
276
- const channelDef = this._validateDomainQuery(channel);
294
+ const channelDef = this.#validateDomainQuery(channel);
277
295
  const type = channelDef.type ?? "nominal"; // TODO: Should check that this is a channel without scale
278
296
 
279
297
  /** @param {Channel} channel */
@@ -47,11 +47,12 @@ export default class View {
47
47
  */
48
48
  opacityFunction: (arg0: number) => number;
49
49
  /**
50
- * Not nice! Inconsistent when faceting!
51
- * TODO: Something. Maybe store only width/height
52
- * @type {import("./layout/rectangle.js").default}
50
+ * Coords of the view for each facet, recorded during the last layout rendering pass.
51
+ * Most views have only one facet, so the map is usually of size 1.
52
+ *
53
+ * @type {Map<any, import("./layout/rectangle.js").default>}
53
54
  */
54
- coords: import("./layout/rectangle.js").default;
55
+ facetCoords: Map<any, import("./layout/rectangle.js").default>;
55
56
  context: import("../types/viewContext.js").default;
56
57
  layoutParent: import("./containerView.js").default;
57
58
  dataParent: View;
@@ -86,6 +87,13 @@ export default class View {
86
87
  needsAxes: Record<import("../spec/channel.js").PrimaryPositionalChannel, boolean>;
87
88
  /** @type {ParamMediator} */
88
89
  paramMediator: ParamMediator;
90
+ /**
91
+ * Returns the coords of the view. If view has been faceted, returns the coords
92
+ * of an arbitrary facet. If all or specific facet coords are needed, use `facetCoords`.
93
+ *
94
+ * @returns {import("./layout/rectangle.js").default}
95
+ */
96
+ get coords(): import("./layout/rectangle.js").default;
89
97
  getPadding(): Padding;
90
98
  /**
91
99
  * Returns a padding that indicates how much axes and titles extend over the plot area.
@@ -160,8 +168,9 @@ export default class View {
160
168
  * Coordinates of the view
161
169
  * @param {import("../utils/interactionEvent.js").default} event
162
170
  * @param {boolean} capturing
171
+ * @protected
163
172
  */
164
- handleInteractionEvent(coords: import("./layout/rectangle.js").default, event: import("../utils/interactionEvent.js").default, capturing: boolean): void;
173
+ protected handleInteractionEvent(coords: import("./layout/rectangle.js").default, event: import("../utils/interactionEvent.js").default, capturing: boolean): void;
165
174
  /**
166
175
  * Add an "interaction" event listener that mimics DOM's event model inside
167
176
  * the view hierarchy.
@@ -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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"}
@@ -17,6 +17,7 @@ import { isDiscrete, bandSpace } from "vega-scale";
17
17
  import { peek } from "../utils/arrayUtils.js";
18
18
  import ViewError from "./viewError.js";
19
19
  import ParamMediator, { isExprRef } from "./paramMediator.js";
20
+ import { InternMap } from "internmap";
20
21
 
21
22
  // TODO: View classes have too many responsibilities. Come up with a way
22
23
  // to separate the concerns. However, most concerns are tightly tied to
@@ -75,11 +76,12 @@ export default class View {
75
76
  opacityFunction = defaultOpacityFunction;
76
77
 
77
78
  /**
78
- * Not nice! Inconsistent when faceting!
79
- * TODO: Something. Maybe store only width/height
80
- * @type {import("./layout/rectangle.js").default}
79
+ * Coords of the view for each facet, recorded during the last layout rendering pass.
80
+ * Most views have only one facet, so the map is usually of size 1.
81
+ *
82
+ * @type {Map<any, import("./layout/rectangle.js").default>}
81
83
  */
82
- coords;
84
+ facetCoords = new InternMap([], JSON.stringify);
83
85
 
84
86
  /**
85
87
  *
@@ -141,6 +143,16 @@ export default class View {
141
143
  }
142
144
  }
143
145
 
146
+ /**
147
+ * Returns the coords of the view. If view has been faceted, returns the coords
148
+ * of an arbitrary facet. If all or specific facet coords are needed, use `facetCoords`.
149
+ *
150
+ * @returns {import("./layout/rectangle.js").default}
151
+ */
152
+ get coords() {
153
+ return this.facetCoords.values().next().value;
154
+ }
155
+
144
156
  getPadding() {
145
157
  return this._cache("size/padding", () =>
146
158
  Padding.createFromConfig(this.spec.padding)
@@ -379,6 +391,7 @@ export default class View {
379
391
  * Coordinates of the view
380
392
  * @param {import("../utils/interactionEvent.js").default} event
381
393
  * @param {boolean} capturing
394
+ * @protected
382
395
  */
383
396
  handleInteractionEvent(coords, event, capturing) {
384
397
  const listenersByType = capturing
@@ -480,9 +493,15 @@ export default class View {
480
493
  * @type {import("../types/rendering.js").RenderMethod}
481
494
  */
482
495
  render(context, coords, options = {}) {
483
- this.coords = options.clipRect
484
- ? coords.intersect(options.clipRect)
485
- : coords;
496
+ // TODO: When using sample faceting, all facets have the same coords.
497
+ // It would be better to save only single coords with an `undefined` facetId.
498
+ if (options.firstFacet) {
499
+ this.facetCoords.clear();
500
+ }
501
+ this.facetCoords.set(
502
+ options.facetId,
503
+ options.clipRect ? coords.intersect(options.clipRect) : coords
504
+ );
486
505
 
487
506
  // override
488
507
  }
@@ -8,11 +8,11 @@
8
8
  */
9
9
  /**
10
10
  * @param {import("../utils/interactionEvent.js").default} event
11
- * @param {import("./renderingContext/layoutRecorderViewRenderingContext.js").Rectangle} coords The plot area
11
+ * @param {import("./layout/rectangle.js").default} coords
12
12
  * @param {(zoomEvent: ZoomEvent) => void} handleZoom
13
13
  * @param {import("../types/viewContext.js").Hover} [hover]
14
14
  */
15
- export default function interactionToZoom(event: import("../utils/interactionEvent.js").default, coords: import("./renderingContext/layoutRecorderViewRenderingContext.js").Rectangle, handleZoom: (zoomEvent: ZoomEvent) => void, hover?: import("../types/viewContext.js").Hover): void;
15
+ export default function interactionToZoom(event: import("../utils/interactionEvent.js").default, coords: import("./layout/rectangle.js").default, handleZoom: (zoomEvent: ZoomEvent) => void, hover?: import("../types/viewContext.js").Hover): void;
16
16
  export type ZoomEvent = {
17
17
  x: number;
18
18
  y: number;
@@ -1 +1 @@
1
- {"version":3,"file":"zoom.d.ts","sourceRoot":"","sources":["../../../src/view/zoom.js"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;GAKG;AACH,iDALW,OAAO,8BAA8B,EAAE,OAAO,UAC9C,OAAO,0DAA0D,EAAE,SAAS,0BAChE,SAAS,KAAK,IAAI,UAC9B,OAAO,yBAAyB,EAAE,KAAK,QA2EjD;;OAtFS,MAAM;OACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM"}
1
+ {"version":3,"file":"zoom.d.ts","sourceRoot":"","sources":["../../../src/view/zoom.js"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;GAKG;AACH,iDALW,OAAO,8BAA8B,EAAE,OAAO,UAC9C,OAAO,uBAAuB,EAAE,OAAO,0BAC3B,SAAS,KAAK,IAAI,UAC9B,OAAO,yBAAyB,EAAE,KAAK,QA2EjD;;OAtFS,MAAM;OACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM"}