@genome-spy/core 0.48.2 → 0.50.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 (244) hide show
  1. package/dist/bundle/index.es.js +7434 -7107
  2. package/dist/bundle/index.js +116 -103
  3. package/dist/schema.json +3975 -2819
  4. package/dist/src/data/collector.test.d.ts +2 -0
  5. package/dist/src/data/collector.test.d.ts.map +1 -0
  6. package/dist/src/data/dataFlow.test.d.ts +2 -0
  7. package/dist/src/data/dataFlow.test.d.ts.map +1 -0
  8. package/dist/src/data/flow.test.d.ts +2 -0
  9. package/dist/src/data/flow.test.d.ts.map +1 -0
  10. package/dist/src/data/flow.test.js +19 -14
  11. package/dist/src/data/flowNode.test.d.ts +2 -0
  12. package/dist/src/data/flowNode.test.d.ts.map +1 -0
  13. package/dist/src/data/flowOptimizer.test.d.ts +2 -0
  14. package/dist/src/data/flowOptimizer.test.d.ts.map +1 -0
  15. package/dist/src/data/flowOptimizer.test.js +9 -10
  16. package/dist/src/data/formats/fasta.test.d.ts +2 -0
  17. package/dist/src/data/formats/fasta.test.d.ts.map +1 -0
  18. package/dist/src/data/sources/inlineSource.test.d.ts +2 -0
  19. package/dist/src/data/sources/inlineSource.test.d.ts.map +1 -0
  20. package/dist/src/data/sources/inlineSource.test.js +23 -16
  21. package/dist/src/data/sources/sequenceSource.test.d.ts +2 -0
  22. package/dist/src/data/sources/sequenceSource.test.d.ts.map +1 -0
  23. package/dist/src/data/sources/sequenceSource.test.js +59 -42
  24. package/dist/src/data/transforms/clone.test.d.ts +2 -0
  25. package/dist/src/data/transforms/clone.test.d.ts.map +1 -0
  26. package/dist/src/data/transforms/coverage.test.d.ts +2 -0
  27. package/dist/src/data/transforms/coverage.test.d.ts.map +1 -0
  28. package/dist/src/data/transforms/coverage.test.js +1 -1
  29. package/dist/src/data/transforms/filter.d.ts +10 -0
  30. package/dist/src/data/transforms/filter.d.ts.map +1 -1
  31. package/dist/src/data/transforms/filter.js +30 -1
  32. package/dist/src/data/transforms/filter.test.d.ts +2 -0
  33. package/dist/src/data/transforms/filter.test.d.ts.map +1 -0
  34. package/dist/src/data/transforms/flatten.test.d.ts +2 -0
  35. package/dist/src/data/transforms/flatten.test.d.ts.map +1 -0
  36. package/dist/src/data/transforms/flatten.test.js +10 -7
  37. package/dist/src/data/transforms/flattenDelimited.test.d.ts +2 -0
  38. package/dist/src/data/transforms/flattenDelimited.test.d.ts.map +1 -0
  39. package/dist/src/data/transforms/flattenDelimited.test.js +16 -13
  40. package/dist/src/data/transforms/flattenSequence.test.d.ts +2 -0
  41. package/dist/src/data/transforms/flattenSequence.test.d.ts.map +1 -0
  42. package/dist/src/data/transforms/flattenSequence.test.js +1 -1
  43. package/dist/src/data/transforms/formula.test.d.ts +2 -0
  44. package/dist/src/data/transforms/formula.test.d.ts.map +1 -0
  45. package/dist/src/data/transforms/formula.test.js +1 -1
  46. package/dist/src/data/transforms/identifier.test.d.ts +2 -0
  47. package/dist/src/data/transforms/identifier.test.d.ts.map +1 -0
  48. package/dist/src/data/transforms/pileup.test.d.ts +2 -0
  49. package/dist/src/data/transforms/pileup.test.d.ts.map +1 -0
  50. package/dist/src/data/transforms/project.test.d.ts +2 -0
  51. package/dist/src/data/transforms/project.test.d.ts.map +1 -0
  52. package/dist/src/data/transforms/project.test.js +1 -1
  53. package/dist/src/data/transforms/regexExtract.test.d.ts +2 -0
  54. package/dist/src/data/transforms/regexExtract.test.d.ts.map +1 -0
  55. package/dist/src/data/transforms/regexExtract.test.js +6 -3
  56. package/dist/src/data/transforms/regexFold.test.d.ts +2 -0
  57. package/dist/src/data/transforms/regexFold.test.d.ts.map +1 -0
  58. package/dist/src/data/transforms/sample.test.d.ts +2 -0
  59. package/dist/src/data/transforms/sample.test.d.ts.map +1 -0
  60. package/dist/src/data/transforms/stack.test.d.ts +2 -0
  61. package/dist/src/data/transforms/stack.test.d.ts.map +1 -0
  62. package/dist/src/data/transforms/stack.test.js +8 -8
  63. package/dist/src/encoder/accessor.d.ts +17 -14
  64. package/dist/src/encoder/accessor.d.ts.map +1 -1
  65. package/dist/src/encoder/accessor.js +127 -56
  66. package/dist/src/encoder/accessor.test.d.ts +2 -0
  67. package/dist/src/encoder/accessor.test.d.ts.map +1 -0
  68. package/dist/src/encoder/accessor.test.js +145 -31
  69. package/dist/src/encoder/encoder.d.ts +26 -13
  70. package/dist/src/encoder/encoder.d.ts.map +1 -1
  71. package/dist/src/encoder/encoder.js +98 -114
  72. package/dist/src/encoder/encoder.test.d.ts +2 -0
  73. package/dist/src/encoder/encoder.test.d.ts.map +1 -0
  74. package/dist/src/encoder/encoder.test.js +85 -82
  75. package/dist/src/fonts/bmFontManager.d.ts.map +1 -1
  76. package/dist/src/fonts/bmFontManager.js +10 -4
  77. package/dist/src/genome/genome.test.d.ts +2 -0
  78. package/dist/src/genome/genome.test.d.ts.map +1 -0
  79. package/dist/src/genome/scaleIndex.test.d.ts +2 -0
  80. package/dist/src/genome/scaleIndex.test.d.ts.map +1 -0
  81. package/dist/src/genome/scaleLocus.test.d.ts +2 -0
  82. package/dist/src/genome/scaleLocus.test.d.ts.map +1 -0
  83. package/dist/src/genomeSpy.d.ts +3 -2
  84. package/dist/src/genomeSpy.d.ts.map +1 -1
  85. package/dist/src/genomeSpy.js +15 -6
  86. package/dist/src/gl/dataToVertices.d.ts +6 -8
  87. package/dist/src/gl/dataToVertices.d.ts.map +1 -1
  88. package/dist/src/gl/dataToVertices.js +42 -33
  89. package/dist/src/gl/glslScaleGenerator.d.ts +84 -15
  90. package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -1
  91. package/dist/src/gl/glslScaleGenerator.js +260 -73
  92. package/dist/src/gl/includes/common.glsl.js +1 -1
  93. package/dist/src/marks/link.common.glsl.js +1 -1
  94. package/dist/src/marks/link.d.ts +8 -1
  95. package/dist/src/marks/link.d.ts.map +1 -1
  96. package/dist/src/marks/link.fragment.glsl.js +1 -1
  97. package/dist/src/marks/link.js +47 -31
  98. package/dist/src/marks/link.vertex.glsl.js +1 -1
  99. package/dist/src/marks/mark.d.ts +24 -25
  100. package/dist/src/marks/mark.d.ts.map +1 -1
  101. package/dist/src/marks/mark.js +246 -118
  102. package/dist/src/marks/markUtils.d.ts +25 -0
  103. package/dist/src/marks/markUtils.d.ts.map +1 -1
  104. package/dist/src/marks/markUtils.js +41 -1
  105. package/dist/src/marks/point.common.glsl.js +1 -1
  106. package/dist/src/marks/point.d.ts +8 -1
  107. package/dist/src/marks/point.d.ts.map +1 -1
  108. package/dist/src/marks/point.js +34 -25
  109. package/dist/src/marks/point.vertex.glsl.js +1 -1
  110. package/dist/src/marks/rect.d.ts +8 -1
  111. package/dist/src/marks/rect.d.ts.map +1 -1
  112. package/dist/src/marks/rect.js +28 -23
  113. package/dist/src/marks/rule.d.ts +8 -1
  114. package/dist/src/marks/rule.d.ts.map +1 -1
  115. package/dist/src/marks/rule.js +23 -16
  116. package/dist/src/marks/text.d.ts +10 -1
  117. package/dist/src/marks/text.d.ts.map +1 -1
  118. package/dist/src/marks/text.fragment.glsl.js +1 -1
  119. package/dist/src/marks/text.js +53 -47
  120. package/dist/src/marks/text.vertex.glsl.js +1 -1
  121. package/dist/src/scale/scale.test.d.ts +2 -0
  122. package/dist/src/scale/scale.test.d.ts.map +1 -0
  123. package/dist/src/scale/scale.test.js +2 -0
  124. package/dist/src/scale/ticks.test.d.ts +2 -0
  125. package/dist/src/scale/ticks.test.d.ts.map +1 -0
  126. package/dist/src/scale/ticks.test.js +6 -0
  127. package/dist/src/selection/selection.d.ts +39 -0
  128. package/dist/src/selection/selection.d.ts.map +1 -0
  129. package/dist/src/selection/selection.js +78 -0
  130. package/dist/src/spec/channel.d.ts +150 -83
  131. package/dist/src/spec/mark.d.ts +133 -78
  132. package/dist/src/spec/parameter.d.ts +112 -3
  133. package/dist/src/spec/root.d.ts +0 -1
  134. package/dist/src/spec/transform.d.ts +19 -1
  135. package/dist/src/spec/view.d.ts +5 -10
  136. package/dist/src/tooltip/dataTooltipHandler.d.ts +1 -1
  137. package/dist/src/tooltip/dataTooltipHandler.d.ts.map +1 -1
  138. package/dist/src/tooltip/dataTooltipHandler.js +1 -1
  139. package/dist/src/tooltip/refseqGeneTooltipHandler.d.ts +1 -1
  140. package/dist/src/tooltip/refseqGeneTooltipHandler.d.ts.map +1 -1
  141. package/dist/src/types/encoder.d.ts +80 -26
  142. package/dist/src/types/rendering.d.ts +1 -0
  143. package/dist/src/types/selectionTypes.d.ts +44 -0
  144. package/dist/src/types/viewContext.d.ts +1 -4
  145. package/dist/src/utils/addBaseUrl.test.d.ts +2 -0
  146. package/dist/src/utils/addBaseUrl.test.d.ts.map +1 -0
  147. package/dist/src/utils/binnedIndex.test.d.ts +2 -0
  148. package/dist/src/utils/binnedIndex.test.d.ts.map +1 -0
  149. package/dist/src/utils/cloner.test.d.ts +2 -0
  150. package/dist/src/utils/cloner.test.d.ts.map +1 -0
  151. package/dist/src/utils/coalesce.test.d.ts +2 -0
  152. package/dist/src/utils/coalesce.test.d.ts.map +1 -0
  153. package/dist/src/utils/concatIterables.test.d.ts +2 -0
  154. package/dist/src/utils/concatIterables.test.d.ts.map +1 -0
  155. package/dist/src/utils/domainArray.test.d.ts +2 -0
  156. package/dist/src/utils/domainArray.test.d.ts.map +1 -0
  157. package/dist/src/utils/expression.d.ts +2 -2
  158. package/dist/src/utils/expression.d.ts.map +1 -1
  159. package/dist/src/utils/expression.js +11 -2
  160. package/dist/src/utils/indexer.test.d.ts +2 -0
  161. package/dist/src/utils/indexer.test.d.ts.map +1 -0
  162. package/dist/src/utils/inputBinding.d.ts.map +1 -1
  163. package/dist/src/utils/inputBinding.js +4 -0
  164. package/dist/src/utils/iterateNestedMaps.test.d.ts +2 -0
  165. package/dist/src/utils/iterateNestedMaps.test.d.ts.map +1 -0
  166. package/dist/src/utils/kWayMerge.test.d.ts +2 -0
  167. package/dist/src/utils/kWayMerge.test.d.ts.map +1 -0
  168. package/dist/src/utils/mergeObjects.test.d.ts +2 -0
  169. package/dist/src/utils/mergeObjects.test.d.ts.map +1 -0
  170. package/dist/src/utils/numberExtractor.test.d.ts +2 -0
  171. package/dist/src/utils/numberExtractor.test.d.ts.map +1 -0
  172. package/dist/src/utils/propertyCacher.test.d.ts +2 -0
  173. package/dist/src/utils/propertyCacher.test.d.ts.map +1 -0
  174. package/dist/src/utils/propertyCoalescer.test.d.ts +2 -0
  175. package/dist/src/utils/propertyCoalescer.test.d.ts.map +1 -0
  176. package/dist/src/utils/propertyCoalescer.test.js +3 -0
  177. package/dist/src/utils/radixSort.test.d.ts +2 -0
  178. package/dist/src/utils/radixSort.test.d.ts.map +1 -0
  179. package/dist/src/utils/reservationMap.test.d.ts +2 -0
  180. package/dist/src/utils/reservationMap.test.d.ts.map +1 -0
  181. package/dist/src/utils/ringBuffer.test.d.ts +2 -0
  182. package/dist/src/utils/ringBuffer.test.d.ts.map +1 -0
  183. package/dist/src/utils/topK.test.d.ts +2 -0
  184. package/dist/src/utils/topK.test.d.ts.map +1 -0
  185. package/dist/src/utils/trees.test.d.ts +2 -0
  186. package/dist/src/utils/trees.test.d.ts.map +1 -0
  187. package/dist/src/utils/trees.test.js +8 -3
  188. package/dist/src/utils/variableTools.test.d.ts +2 -0
  189. package/dist/src/utils/variableTools.test.d.ts.map +1 -0
  190. package/dist/src/view/axisResolution.d.ts +19 -6
  191. package/dist/src/view/axisResolution.d.ts.map +1 -1
  192. package/dist/src/view/axisResolution.js +16 -7
  193. package/dist/src/view/axisResolution.test.d.ts +2 -0
  194. package/dist/src/view/axisResolution.test.d.ts.map +1 -0
  195. package/dist/src/view/axisResolution.test.js +16 -11
  196. package/dist/src/view/axisView.js +2 -2
  197. package/dist/src/view/facetView.d.ts +1 -1
  198. package/dist/src/view/facetView.d.ts.map +1 -1
  199. package/dist/src/view/flowBuilder.d.ts +1 -1
  200. package/dist/src/view/flowBuilder.d.ts.map +1 -1
  201. package/dist/src/view/flowBuilder.js +34 -5
  202. package/dist/src/view/flowBuilder.test.d.ts +2 -0
  203. package/dist/src/view/flowBuilder.test.d.ts.map +1 -0
  204. package/dist/src/view/flowBuilder.test.js +1 -1
  205. package/dist/src/view/gridView.d.ts +0 -6
  206. package/dist/src/view/gridView.d.ts.map +1 -1
  207. package/dist/src/view/gridView.js +1 -1
  208. package/dist/src/view/layerView.d.ts +0 -6
  209. package/dist/src/view/layerView.d.ts.map +1 -1
  210. package/dist/src/view/layout/flexLayout.test.d.ts +2 -0
  211. package/dist/src/view/layout/flexLayout.test.d.ts.map +1 -0
  212. package/dist/src/view/layout/grid.test.d.ts +2 -0
  213. package/dist/src/view/layout/grid.test.d.ts.map +1 -0
  214. package/dist/src/view/layout/rectangle.test.d.ts +2 -0
  215. package/dist/src/view/layout/rectangle.test.d.ts.map +1 -0
  216. package/dist/src/view/paramMediator.d.ts +39 -5
  217. package/dist/src/view/paramMediator.d.ts.map +1 -1
  218. package/dist/src/view/paramMediator.js +120 -9
  219. package/dist/src/view/paramMediator.test.d.ts +2 -0
  220. package/dist/src/view/paramMediator.test.d.ts.map +1 -0
  221. package/dist/src/view/paramMediator.test.js +37 -1
  222. package/dist/src/view/scaleResolution.d.ts +17 -15
  223. package/dist/src/view/scaleResolution.d.ts.map +1 -1
  224. package/dist/src/view/scaleResolution.js +70 -68
  225. package/dist/src/view/scaleResolution.test.d.ts +2 -0
  226. package/dist/src/view/scaleResolution.test.d.ts.map +1 -0
  227. package/dist/src/view/scaleResolution.test.js +2 -0
  228. package/dist/src/view/testUtils.d.ts.map +1 -1
  229. package/dist/src/view/testUtils.js +15 -3
  230. package/dist/src/view/unitView.d.ts +8 -20
  231. package/dist/src/view/unitView.d.ts.map +1 -1
  232. package/dist/src/view/unitView.js +100 -102
  233. package/dist/src/view/view.d.ts +1 -1
  234. package/dist/src/view/view.d.ts.map +1 -1
  235. package/dist/src/view/view.test.d.ts +2 -0
  236. package/dist/src/view/view.test.d.ts.map +1 -0
  237. package/dist/src/view/view.test.js +73 -55
  238. package/dist/src/view/viewFactory.test.d.ts +2 -0
  239. package/dist/src/view/viewFactory.test.d.ts.map +1 -0
  240. package/dist/src/view/viewFactory.test.js +2 -2
  241. package/dist/src/view/viewUtils.d.ts +1 -1
  242. package/dist/src/view/viewUtils.d.ts.map +1 -1
  243. package/dist/src/view/zoom.js +2 -2
  244. package/package.json +5 -2
@@ -21,7 +21,6 @@ import mergeObjects from "../utils/mergeObjects.js";
21
21
  import createScale, { configureScale } from "../scale/scale.js";
22
22
 
23
23
  import {
24
- getChannelDefWithScale,
25
24
  isColorChannel,
26
25
  isDiscreteChannel,
27
26
  isPositionalChannel,
@@ -32,7 +31,7 @@ import {
32
31
  isChromosomalLocus,
33
32
  isChromosomalLocusInterval,
34
33
  } from "../genome/genome.js";
35
- import { NominalDomain } from "../utils/domainArray.js";
34
+ import createDomain, { NominalDomain } from "../utils/domainArray.js";
36
35
  import { easeCubicInOut } from "d3-ease";
37
36
  import { asArray, shallowArrayEquals } from "../utils/arrayUtils.js";
38
37
  import eerp from "../utils/eerp.js";
@@ -52,8 +51,12 @@ export const INDEX = "index";
52
51
 
53
52
  /**
54
53
  * @template {ChannelWithScale}[T=ChannelWithScale]
55
- * @typedef {{view: import("./unitView.js").default, channel: T}} ResolutionMember
56
54
  *
55
+ * @typedef {object} ScaleResolutionMember
56
+ * @prop {import("./unitView.js").default} view TODO: Get rid of the view reference
57
+ * @prop {T} channel
58
+ * @prop {import("../spec/channel.js").ChannelDefWithScale} channelDef
59
+ * @prop {(channel: ChannelWithScale, type: import("../spec/channel.js").Type) => DomainArray} dataDomainSource
57
60
  */
58
61
  /**
59
62
  * Resolution takes care of merging domains and scales from multiple views.
@@ -109,9 +112,9 @@ export default class ScaleResolution {
109
112
  */
110
113
  constructor(channel) {
111
114
  this.channel = channel;
112
- /** @type {ResolutionMember[]} The involved views */
115
+ /** @type {ScaleResolutionMember[]} The involved views */
113
116
  this.members = [];
114
- /** @type {string} Data type (quantitative, nominal, etc...) */
117
+ /** @type {import("../spec/channel.js").Type} Data type (quantitative, nominal, etc...) */
115
118
  this.type = null;
116
119
 
117
120
  /** @type {string} An optional unique identifier for the scale */
@@ -162,11 +165,10 @@ export default class ScaleResolution {
162
165
  * Add a view to this resolution.
163
166
  * N.B. This is expected to be called in depth-first order
164
167
  *
165
- * @param {UnitView} view
166
- * @param {ChannelWithScale} channel
168
+ * @param {ScaleResolutionMember} newMember
167
169
  */
168
- pushUnitView(view, channel) {
169
- const channelDef = getChannelDefWithScale(view, channel);
170
+ addMember(newMember) {
171
+ const { channel, channelDef } = newMember;
170
172
  const type = channelDef.type;
171
173
  const name = channelDef?.scale?.name;
172
174
 
@@ -190,14 +192,14 @@ export default class ScaleResolution {
190
192
  // TODO: Use the same merging logic as in: https://github.com/vega/vega-lite/blob/master/src/scale.ts
191
193
  }
192
194
 
193
- this.members.push({ view, channel });
195
+ this.members.push(newMember);
194
196
  }
195
197
 
196
198
  /**
197
199
  * Returns true if the domain has been defined explicitly, i.e. not extracted from the data.
198
200
  */
199
201
  #isExplicitDomain() {
200
- return !!this.getConfiguredDomain();
202
+ return !!this.#getConfiguredDomain();
201
203
  }
202
204
 
203
205
  #isDomainInitialized() {
@@ -227,10 +229,7 @@ export default class ScaleResolution {
227
229
  */
228
230
  #getMergedScaleProps() {
229
231
  const propArray = this.members
230
- .map(
231
- (member) =>
232
- getChannelDefWithScale(member.view, member.channel).scale
233
- )
232
+ .map((member) => member.channelDef.scale)
234
233
  .filter((props) => props !== undefined);
235
234
 
236
235
  // TODO: Disabled scale: https://vega.github.io/vega-lite/docs/scale.html#disable
@@ -241,9 +240,10 @@ export default class ScaleResolution {
241
240
  * Returns the merged scale properties supplemented with inferred properties
242
241
  * and domain.
243
242
  *
243
+ * @param {boolean} [extractDataDomain]
244
244
  * @returns {import("../spec/scale.js").Scale}
245
245
  */
246
- #getScaleProps() {
246
+ #getScaleProps(extractDataDomain = false) {
247
247
  const mergedProps = this.#getMergedScaleProps();
248
248
  if (mergedProps === null || mergedProps.type == "null") {
249
249
  // No scale (pass-thru)
@@ -260,7 +260,7 @@ export default class ScaleResolution {
260
260
  props.type = getDefaultScaleType(this.channel, this.type);
261
261
  }
262
262
 
263
- const domain = this.#getInitialDomain();
263
+ const domain = this.#getInitialDomain(extractDataDomain);
264
264
 
265
265
  if (domain && domain.length > 0) {
266
266
  props.domain = domain;
@@ -360,13 +360,19 @@ export default class ScaleResolution {
360
360
  }
361
361
  }
362
362
 
363
- #getInitialDomain() {
363
+ /**
364
+ *
365
+ * @param {boolean} extractDataDomain
366
+ */
367
+ #getInitialDomain(extractDataDomain = false) {
364
368
  // TODO: intersect the domain with zoom extent (if it's defined)
365
369
  return (
366
- this.getConfiguredDomain() ??
370
+ this.#getConfiguredDomain() ??
367
371
  (this.type == LOCUS
368
372
  ? this.getGenome().getExtent()
369
- : this.getDataDomain())
373
+ : extractDataDomain
374
+ ? this.getDataDomain()
375
+ : [])
370
376
  );
371
377
  }
372
378
 
@@ -375,12 +381,22 @@ export default class ScaleResolution {
375
381
  *
376
382
  * @return { DomainArray }
377
383
  */
378
- getConfiguredDomain() {
379
- return this.#reduceDomains((member) =>
380
- isSecondaryChannel(member.channel)
381
- ? undefined
382
- : member.view.getConfiguredDomain(member.channel)
383
- );
384
+ #getConfiguredDomain() {
385
+ const domains = this.members
386
+ .map((member) => member.channelDef)
387
+ .filter((channelDef) => channelDef.scale?.domain)
388
+ .map((channelDef) =>
389
+ // TODO: Handle ExprRefs and Param in domain
390
+ createDomain(
391
+ channelDef.type,
392
+ // Chrom/pos must be linearized first
393
+ this.fromComplexInterval(channelDef.scale.domain)
394
+ )
395
+ );
396
+
397
+ if (domains.length > 0) {
398
+ return domains.reduce((acc, curr) => acc.extendAll(curr));
399
+ }
384
400
  }
385
401
 
386
402
  /**
@@ -389,13 +405,12 @@ export default class ScaleResolution {
389
405
  * @return { DomainArray }
390
406
  */
391
407
  getDataDomain() {
392
- // TODO: Optimize: extract domain only once if the views share the data.
393
- // In fact, this should be a responsibility of collectors.
394
- return this.#reduceDomains((member) =>
395
- isSecondaryChannel(member.channel)
396
- ? undefined
397
- : member.view.extractDataDomain(member.channel)
398
- );
408
+ return this.members
409
+ .map((member) =>
410
+ member.dataDomainSource?.(member.channel, this.type)
411
+ )
412
+ .filter((domain) => !!domain)
413
+ .reduce((acc, curr) => acc.extendAll(curr));
399
414
  }
400
415
 
401
416
  /**
@@ -411,7 +426,7 @@ export default class ScaleResolution {
411
426
  const domainWasInitialized = this.#isDomainInitialized();
412
427
  const previousDomain = scale.domain();
413
428
 
414
- const props = this.#getScaleProps();
429
+ const props = this.#getScaleProps(true);
415
430
  configureScale({ ...props, range: undefined }, scale);
416
431
 
417
432
  // Annotate the scale with the new props
@@ -458,6 +473,11 @@ export default class ScaleResolution {
458
473
  // Annotate the scale with props
459
474
  scale.props = props;
460
475
 
476
+ if ("unknown" in scale) {
477
+ // Never allow implicit domain construction
478
+ scale.unknown(null);
479
+ }
480
+
461
481
  this.#scale = scale;
462
482
  this.#configureRange();
463
483
 
@@ -630,27 +650,37 @@ export default class ScaleResolution {
630
650
 
631
651
  // TODO: Intersect the domain with zoom extent
632
652
 
633
- const animator = this.members[0]?.view.context.animator;
653
+ const animator = this.#viewContext.animator;
634
654
 
635
655
  const scale = this.scale;
636
656
  const from = /** @type {number[]} */ (scale.domain());
637
657
 
638
658
  if (duration > 0 && from.length == 2) {
659
+ // Spans
639
660
  const fw = from[1] - from[0];
640
- const fc = from[0] + fw / 2;
641
-
642
661
  const tw = to[1] - to[0];
662
+
663
+ // Centers
664
+ const fc = from[0] + fw / 2;
643
665
  const tc = to[0] + tw / 2;
644
666
 
667
+ // Constant endpoints. Skip calculation to maintain precision.
668
+ const ac = from[0] == to[0];
669
+ const bc = from[1] == to[1];
670
+
645
671
  // TODO: Abort possible previous transition
646
672
  await animator.transition({
647
673
  duration,
648
674
  easingFunction: easeCubicInOut,
649
675
  onUpdate: (t) => {
650
676
  const w = eerp(fw, tw, t);
651
- const wt = (fw - w) / (fw - tw);
677
+ const wt = fw == tw ? t : (fw - w) / (fw - tw);
652
678
  const c = wt * tc + (1 - wt) * fc;
653
- scale.domain([c - w / 2, c + w / 2]);
679
+ const domain = [
680
+ ac ? from[0] : c - w / 2,
681
+ bc ? from[1] : c + w / 2,
682
+ ];
683
+ scale.domain(domain);
654
684
  this.#notifyListeners("domain");
655
685
  },
656
686
  });
@@ -770,7 +800,7 @@ export default class ScaleResolution {
770
800
  }
771
801
 
772
802
  // TODO: Support multiple assemblies
773
- const genome = this.members[0].view.context.genomeStore?.getGenome();
803
+ const genome = this.#viewContext.genomeStore?.getGenome();
774
804
  if (!genome) {
775
805
  throw new Error("No genome has been defined!");
776
806
  }
@@ -825,34 +855,6 @@ export default class ScaleResolution {
825
855
  }
826
856
  return /** @type {number[]} */ (interval);
827
857
  }
828
-
829
- #getViewPaths() {
830
- return this.members.map((v) => v.view.getPathString()).join(", ");
831
- }
832
-
833
- /**
834
- * Iterate all participanting views and reduce (union) their domains using an accessor.
835
- * Accessor may return the an explicitly configured domain or a domain extracted from the data.
836
- *
837
- * @param {function(ResolutionMember):DomainArray} domainAccessor
838
- * @returns {DomainArray}
839
- */
840
- #reduceDomains(domainAccessor) {
841
- const domains = this.members
842
- .filter(
843
- (member) =>
844
- !member.view
845
- .getLayoutAncestors()
846
- // TODO: Should check until the resolved scale resolution
847
- .some((view) => !view.options.contributesToScaleDomain)
848
- )
849
- .map(domainAccessor)
850
- .filter((domain) => !!domain);
851
-
852
- if (domains.length) {
853
- return domains.reduce((acc, curr) => acc.extendAll(curr));
854
- }
855
- }
856
858
  }
857
859
 
858
860
  /**
@@ -0,0 +1,2 @@
1
+ export type Channel = import("../spec/channel.js").Channel;
2
+ //# sourceMappingURL=scaleResolution.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaleResolution.test.d.ts","sourceRoot":"","sources":["../../../src/view/scaleResolution.test.js"],"names":[],"mappings":"sBAWa,OAAO,oBAAoB,EAAE,OAAO"}
@@ -1,3 +1,5 @@
1
+ // @ts-nocheck
2
+
1
3
  import { describe, expect, test } from "vitest";
2
4
  import { createAndInitialize } from "./testUtils.js";
3
5
  import createDomain, { toRegularArray as r } from "../utils/domainArray.js";
@@ -1 +1 @@
1
- {"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../../../src/view/testUtils.js"],"names":[],"mappings":"AAeA;;;GAGG;AACH,2DAHW,OAAO,kBAAkB,EAAE,kBAAkB,6CAqDvD;AAGS,oEAA8C,QAAQ,2BAA4B,GAAG,EAAE,6BAA6B,OAAO,kBAAkB,EAAE,kBAAkB,cAAe;AAgBhL,iFAA8C,QAAQ,2BAA4B,GAAG,EAAE,kBAAkB,WAAW,YAAY;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAC,cAAe;;;;;uBApFpL,OAAO,iBAAiB,EAAE,QAAQ;;;;;0BAClC,OAAO,yBAAyB,EAAE,OAAO"}
1
+ {"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../../../src/view/testUtils.js"],"names":[],"mappings":"AAiBA;;;GAGG;AACH,2DAHW,OAAO,kBAAkB,EAAE,kBAAkB,6CAmDvD;AAGS,oEAA8C,QAAQ,2BAA4B,GAAG,EAAE,6BAA6B,OAAO,kBAAkB,EAAE,kBAAkB,cAAe;AAgBhL,iFAA8C,QAAQ,2BAA4B,GAAG,EAAE,kBAAkB,WAAW,YAAY;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAC,cAAe;;;;;uBApFpL,OAAO,iBAAiB,EAAE,QAAQ;;;;;0BAClC,OAAO,yBAAyB,EAAE,OAAO"}
@@ -7,11 +7,13 @@
7
7
  */
8
8
 
9
9
  import { checkForDuplicateScaleNames, initializeData } from "./viewUtils.js";
10
- import AccessorFactory from "../encoder/accessor.js";
11
10
  import DataFlow from "../data/dataFlow.js";
12
11
  import { VIEW_ROOT_NAME, ViewFactory } from "./viewFactory.js";
13
12
  import GenomeStore from "../genome/genomeStore.js";
14
13
  import BmFontManager from "../fonts/bmFontManager.js";
14
+ import { reconfigureScales } from "./scaleResolution.js";
15
+ import UnitView from "./unitView.js";
16
+ import ContainerView from "./containerView.js";
15
17
 
16
18
  /**
17
19
  * @param {import("./viewFactory.js").ViewFactoryOptions} [viewFactoryOptions]
@@ -35,8 +37,6 @@ export function createTestViewContext(viewFactoryOptions = {}) {
35
37
 
36
38
  // @ts-expect-error
37
39
  const c = /** @type {ViewContext} */ ({
38
- accessorFactory: new AccessorFactory(),
39
-
40
40
  createView: function (spec, parent, defaultName) {
41
41
  throw new Error("Not implemented: createView");
42
42
  },
@@ -92,6 +92,18 @@ export async function createAndInitialize(spec, viewClass) {
92
92
  const view = await create(spec, viewClass);
93
93
 
94
94
  checkForDuplicateScaleNames(view);
95
+
96
+ if (view instanceof UnitView) {
97
+ view.mark.initializeEncoders();
98
+ } else if (view instanceof ContainerView) {
99
+ view.visit((v) => {
100
+ if (v instanceof UnitView) {
101
+ v.mark.initializeEncoders();
102
+ }
103
+ });
104
+ }
105
+
95
106
  await initializeData(view, view.context.dataFlow);
107
+ reconfigureScales(view);
96
108
  return view;
97
109
  }
@@ -1,11 +1,9 @@
1
1
  /**
2
2
  *
3
- * @type {Object.<string, typeof import("../marks/mark.js").default>}
3
+ * @type {Record<import("../spec/mark.js").MarkType, typeof import("../marks/mark.js").default>}
4
4
  * TODO: Find a proper place, make extendible
5
5
  */
6
- export const markTypes: {
7
- [x: string]: typeof import("../marks/mark.js").default;
8
- };
6
+ export const markTypes: Record<import("../spec/mark.js").MarkType, typeof import("../marks/mark.js").default>;
9
7
  export default class UnitView extends View {
10
8
  /**
11
9
  *
@@ -20,13 +18,7 @@ export default class UnitView extends View {
20
18
  spec: import("../spec/view.js").UnitSpec;
21
19
  /** @type {import("../marks/mark.js").default} */
22
20
  mark: import("../marks/mark.js").default;
23
- /**
24
- * @param {import("./renderingContext/viewRenderingContext.js").default} context
25
- * @param {import("./layout/rectangle.js").default} coords
26
- * @param {import("../types/rendering.js").RenderingOptions} [options]
27
- */
28
- render(context: import("./renderingContext/viewRenderingContext.js").default, coords: import("./layout/rectangle.js").default, options?: import("../types/rendering.js").RenderingOptions): void;
29
- getMarkType(): import("../spec/mark.js").MarkType;
21
+ getMarkType(): "link" | "rect" | "text" | "point" | "rule";
30
22
  /**
31
23
  * Pulls scales and axes up in the view hierarcy according to the resolution rules, using dataParents.
32
24
  * TODO: legends
@@ -35,21 +27,16 @@ export default class UnitView extends View {
35
27
  */
36
28
  resolve(type?: import("../spec/view.js").ResolutionTarget): void;
37
29
  /**
30
+ * Returns an accessor that accesses a field or an evaluated expression,
31
+ * if there is one.
38
32
  *
39
33
  * @param {Channel} channel
40
34
  */
41
- getAccessor(channel: import("../spec/channel.js").Channel): import("../types/encoder.js").Accessor;
35
+ getDataAccessor(channel: import("../spec/channel.js").Channel): import("../types/encoder.js").Accessor<import("../spec/channel.js").Scalar>;
42
36
  /**
43
37
  * Returns a collector that is associated with this view.
44
38
  */
45
39
  getCollector(): import("../data/collector.js").default;
46
- /**
47
- * Returns the domain of the specified channel of this domain/mark.
48
- *
49
- * @param {import("../spec/channel.js").ChannelWithScale} channel A primary channel
50
- * @returns {DomainArray}
51
- */
52
- getConfiguredDomain(channel: import("../spec/channel.js").ChannelWithScale): import("../utils/domainArray.js").DomainArray;
53
40
  /**
54
41
  * Extracts the domain from the data.
55
42
  *
@@ -61,9 +48,10 @@ export default class UnitView extends View {
61
48
  * (with aggregate and extent).
62
49
  *
63
50
  * @param {Channel} channel
51
+ * @param {import("../spec/channel.js").Type} type
64
52
  * @returns {DomainArray}
65
53
  */
66
- extractDataDomain(channel: import("../spec/channel.js").Channel): import("../utils/domainArray.js").DomainArray;
54
+ extractDataDomain(channel: import("../spec/channel.js").Channel, type: import("../spec/channel.js").Type): import("../utils/domainArray.js").DomainArray;
67
55
  getZoomLevel(): number;
68
56
  /**
69
57
  * @param {string} channel
@@ -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;;;;;;;;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"}
1
+ {"version":3,"file":"unitView.d.ts","sourceRoot":"","sources":["../../../src/view/unitView.js"],"names":[],"mappings":"AAsBA;;;;GAIG;AACH,wBAHU,OAAO,OAAO,iBAAiB,EAAE,QAAQ,EAAE,cAAc,kBAAkB,EAAE,OAAO,CAAC,CAc7F;AAEF;IAeI;;;;;;;;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,EAiCzC;IA5BG,yCAAgB;IAIZ,iDAAiD;IACjD,MADW,OAAO,kBAAkB,EAAE,OAAO,CACnB;IAsFlC,2DAIC;IAED;;;;;OAKG;IAEH,iEA+FC;IAED;;;;;OAKG;IACH,4IAEC;IAkBD;;OAEG;IACH,uDAEC;IAED;;;;;;;;;;;;;OAaG;IACH,uEAHW,OAAO,oBAAoB,EAAE,IAAI,iDAqB3C;IAED,uBAQC;IAgBD;;;;OAIG;IACH,8BAJW,MAAM,+DAEJ,OAAO,iBAAiB,EAAE,kBAAkB,CAKxD;;CACJ;iBA/VgB,WAAW"}