@genome-spy/core 0.29.0 → 0.30.2

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 (234) hide show
  1. package/dist/index.es.js +16373 -0
  2. package/dist/index.js +43 -43
  3. package/package.json +10 -7
  4. package/src/data/collector.js +0 -183
  5. package/src/data/collector.test.js +0 -84
  6. package/src/data/dataFlow.js +0 -148
  7. package/src/data/dataFlow.test.js +0 -5
  8. package/src/data/facetNode.js +0 -17
  9. package/src/data/flow.test.js +0 -72
  10. package/src/data/flowBatch.d.ts +0 -40
  11. package/src/data/flowNode.js +0 -283
  12. package/src/data/flowNode.test.js +0 -50
  13. package/src/data/flowOptimizer.js +0 -123
  14. package/src/data/flowOptimizer.test.js +0 -193
  15. package/src/data/flowTestUtils.js +0 -63
  16. package/src/data/formats/fasta.js +0 -32
  17. package/src/data/formats/fasta.test.js +0 -27
  18. package/src/data/sources/dataSource.js +0 -22
  19. package/src/data/sources/dataSourceFactory.js +0 -24
  20. package/src/data/sources/dataUtils.js +0 -78
  21. package/src/data/sources/dynamicCallbackSource.js +0 -57
  22. package/src/data/sources/dynamicSource.js +0 -37
  23. package/src/data/sources/inlineSource.js +0 -67
  24. package/src/data/sources/inlineSource.test.js +0 -56
  25. package/src/data/sources/namedSource.js +0 -79
  26. package/src/data/sources/sequenceSource.js +0 -46
  27. package/src/data/sources/sequenceSource.test.js +0 -46
  28. package/src/data/sources/urlSource.js +0 -74
  29. package/src/data/transforms/aggregate.js +0 -70
  30. package/src/data/transforms/clone.js +0 -40
  31. package/src/data/transforms/clone.test.js +0 -11
  32. package/src/data/transforms/coverage.js +0 -187
  33. package/src/data/transforms/coverage.test.js +0 -123
  34. package/src/data/transforms/filter.js +0 -37
  35. package/src/data/transforms/filter.test.js +0 -18
  36. package/src/data/transforms/filterScoredLabels.js +0 -134
  37. package/src/data/transforms/flattenCompressedExons.js +0 -57
  38. package/src/data/transforms/flattenDelimited.js +0 -74
  39. package/src/data/transforms/flattenDelimited.test.js +0 -87
  40. package/src/data/transforms/flattenSequence.js +0 -39
  41. package/src/data/transforms/flattenSequence.test.js +0 -34
  42. package/src/data/transforms/formula.js +0 -39
  43. package/src/data/transforms/formula.test.js +0 -19
  44. package/src/data/transforms/identifier.js +0 -108
  45. package/src/data/transforms/identifier.test.js +0 -83
  46. package/src/data/transforms/linearizeGenomicCoordinate.js +0 -101
  47. package/src/data/transforms/measureText.js +0 -44
  48. package/src/data/transforms/pileup.js +0 -128
  49. package/src/data/transforms/pileup.test.js +0 -70
  50. package/src/data/transforms/project.js +0 -41
  51. package/src/data/transforms/project.test.js +0 -32
  52. package/src/data/transforms/regexExtract.js +0 -61
  53. package/src/data/transforms/regexExtract.test.js +0 -67
  54. package/src/data/transforms/regexFold.js +0 -141
  55. package/src/data/transforms/regexFold.test.js +0 -160
  56. package/src/data/transforms/sample.js +0 -101
  57. package/src/data/transforms/sample.test.js +0 -38
  58. package/src/data/transforms/stack.js +0 -137
  59. package/src/data/transforms/stack.test.js +0 -91
  60. package/src/data/transforms/transformFactory.js +0 -60
  61. package/src/embedApi.d.ts +0 -67
  62. package/src/encoder/accessor.js +0 -82
  63. package/src/encoder/accessor.test.js +0 -47
  64. package/src/encoder/encoder.js +0 -394
  65. package/src/encoder/encoder.test.js +0 -98
  66. package/src/fonts/Lato-Regular.json +0 -1267
  67. package/src/fonts/Lato-Regular.png +0 -0
  68. package/src/fonts/OFL.txt +0 -93
  69. package/src/fonts/README.md +0 -3
  70. package/src/fonts/bmFont.d.ts +0 -58
  71. package/src/fonts/bmFontManager.js +0 -357
  72. package/src/fonts/bmFontMetrics.js +0 -108
  73. package/src/genome/genome.js +0 -317
  74. package/src/genome/genome.test.js +0 -188
  75. package/src/genome/genomeStore.js +0 -54
  76. package/src/genome/locusFormat.js +0 -31
  77. package/src/genome/scaleIndex.d.ts +0 -38
  78. package/src/genome/scaleIndex.js +0 -166
  79. package/src/genome/scaleIndex.test.js +0 -78
  80. package/src/genome/scaleLocus.d.ts +0 -11
  81. package/src/genome/scaleLocus.js +0 -108
  82. package/src/genome/scaleLocus.test.js +0 -4
  83. package/src/genomeSpy.js +0 -784
  84. package/src/gl/arrayBuilder.js +0 -199
  85. package/src/gl/dataToVertices.js +0 -636
  86. package/src/gl/includes/common.glsl +0 -63
  87. package/src/gl/includes/picking.fragment.glsl +0 -1
  88. package/src/gl/includes/picking.vertex.glsl +0 -27
  89. package/src/gl/includes/sampleFacet.glsl +0 -107
  90. package/src/gl/includes/scales.glsl +0 -112
  91. package/src/gl/link.fragment.glsl +0 -18
  92. package/src/gl/link.vertex.glsl +0 -111
  93. package/src/gl/point.fragment.glsl +0 -123
  94. package/src/gl/point.vertex.glsl +0 -129
  95. package/src/gl/rect.fragment.glsl +0 -51
  96. package/src/gl/rect.vertex.glsl +0 -114
  97. package/src/gl/rule.fragment.glsl +0 -52
  98. package/src/gl/rule.vertex.glsl +0 -89
  99. package/src/gl/text.fragment.glsl +0 -31
  100. package/src/gl/text.vertex.glsl +0 -246
  101. package/src/gl/webGLHelper.js +0 -489
  102. package/src/img/bowtie.svg +0 -1
  103. package/src/img/genomespy-favicon.svg +0 -34
  104. package/src/index.html +0 -11
  105. package/src/index.js +0 -128
  106. package/src/marks/link.js +0 -175
  107. package/src/marks/mark.js +0 -975
  108. package/src/marks/markUtils.js +0 -125
  109. package/src/marks/pointMark.js +0 -251
  110. package/src/marks/rectMark.js +0 -241
  111. package/src/marks/rule.js +0 -250
  112. package/src/marks/text.js +0 -278
  113. package/src/node_modules/.vitest/results.json +0 -1
  114. package/src/scale/colorUtils.js +0 -184
  115. package/src/scale/glslScaleGenerator.js +0 -488
  116. package/src/scale/scale.js +0 -451
  117. package/src/scale/scale.test.js +0 -324
  118. package/src/scale/ticks.js +0 -203
  119. package/src/scale/ticks.test.js +0 -40
  120. package/src/singlePageApp.js +0 -13
  121. package/src/spec/axis.d.ts +0 -296
  122. package/src/spec/channel.d.ts +0 -430
  123. package/src/spec/data.d.ts +0 -196
  124. package/src/spec/font.d.ts +0 -15
  125. package/src/spec/genome.d.ts +0 -35
  126. package/src/spec/mark.d.ts +0 -429
  127. package/src/spec/root.d.ts +0 -17
  128. package/src/spec/sampleView.d.ts +0 -180
  129. package/src/spec/scale.d.ts +0 -273
  130. package/src/spec/title.d.ts +0 -102
  131. package/src/spec/tooltip.d.ts +0 -9
  132. package/src/spec/transform.d.ts +0 -479
  133. package/src/spec/view.d.ts +0 -201
  134. package/src/styles/genome-spy.scss +0 -153
  135. package/src/tooltip/dataTooltipHandler.js +0 -64
  136. package/src/tooltip/refseqGeneTooltipHandler.js +0 -78
  137. package/src/tooltip/tooltipHandler.ts +0 -12
  138. package/src/types/filetypes.d.ts +0 -14
  139. package/src/types/flatqueue.d.ts +0 -53
  140. package/src/types/glsl.d.ts +0 -4
  141. package/src/types/internmap.d.ts +0 -22
  142. package/src/types/object.d.ts +0 -21
  143. package/src/types/vega-loader.d.ts +0 -1
  144. package/src/types/vega-scale.d.ts +0 -60
  145. package/src/utils/addBaseUrl.js +0 -19
  146. package/src/utils/addBaseUrl.test.js +0 -22
  147. package/src/utils/animator.js +0 -83
  148. package/src/utils/arrayUtils.js +0 -61
  149. package/src/utils/binnedIndex.js +0 -167
  150. package/src/utils/binnedIndex.test.js +0 -155
  151. package/src/utils/clamp.js +0 -8
  152. package/src/utils/cloner.js +0 -34
  153. package/src/utils/cloner.test.js +0 -24
  154. package/src/utils/coalesce.js +0 -11
  155. package/src/utils/coalesce.test.js +0 -16
  156. package/src/utils/concatIterables.js +0 -26
  157. package/src/utils/concatIterables.test.js +0 -8
  158. package/src/utils/debounce.js +0 -37
  159. package/src/utils/domainArray.js +0 -216
  160. package/src/utils/domainArray.test.js +0 -130
  161. package/src/utils/eerp.js +0 -13
  162. package/src/utils/expression.js +0 -32
  163. package/src/utils/field.js +0 -28
  164. package/src/utils/formatObject.js +0 -31
  165. package/src/utils/indexer.js +0 -43
  166. package/src/utils/indexer.test.js +0 -47
  167. package/src/utils/inertia.js +0 -124
  168. package/src/utils/interactionEvent.js +0 -33
  169. package/src/utils/iterateNestedMaps.js +0 -21
  170. package/src/utils/iterateNestedMaps.test.js +0 -33
  171. package/src/utils/kWayMerge.js +0 -42
  172. package/src/utils/kWayMerge.test.js +0 -26
  173. package/src/utils/layout/flexLayout.js +0 -368
  174. package/src/utils/layout/flexLayout.test.js +0 -311
  175. package/src/utils/layout/grid.js +0 -95
  176. package/src/utils/layout/grid.test.js +0 -71
  177. package/src/utils/layout/padding.js +0 -120
  178. package/src/utils/layout/point.js +0 -23
  179. package/src/utils/layout/rectangle.js +0 -288
  180. package/src/utils/layout/rectangle.test.js +0 -172
  181. package/src/utils/mergeObjects.js +0 -99
  182. package/src/utils/mergeObjects.test.js +0 -42
  183. package/src/utils/numberExtractor.js +0 -24
  184. package/src/utils/numberExtractor.test.js +0 -6
  185. package/src/utils/point.js +0 -14
  186. package/src/utils/propertyCacher.js +0 -70
  187. package/src/utils/propertyCacher.test.js +0 -85
  188. package/src/utils/propertyCoalescer.js +0 -42
  189. package/src/utils/propertyCoalescer.test.js +0 -22
  190. package/src/utils/reservationMap.js +0 -103
  191. package/src/utils/reservationMap.test.js +0 -20
  192. package/src/utils/scaleNull.js +0 -19
  193. package/src/utils/setOperations.js +0 -75
  194. package/src/utils/smoothstep.js +0 -10
  195. package/src/utils/throttle.js +0 -34
  196. package/src/utils/topK.js +0 -76
  197. package/src/utils/topK.test.js +0 -64
  198. package/src/utils/transition.js +0 -74
  199. package/src/utils/ui/tooltip.js +0 -189
  200. package/src/utils/url.js +0 -22
  201. package/src/utils/variableTools.js +0 -24
  202. package/src/utils/variableTools.test.js +0 -13
  203. package/src/view/axisResolution.js +0 -140
  204. package/src/view/axisResolution.test.js +0 -201
  205. package/src/view/axisView.js +0 -747
  206. package/src/view/concatView.js +0 -45
  207. package/src/view/containerView.js +0 -159
  208. package/src/view/facetView.js +0 -491
  209. package/src/view/flowBuilder.js +0 -367
  210. package/src/view/flowBuilder.test.js +0 -125
  211. package/src/view/gridView.js +0 -786
  212. package/src/view/implicitRootView.js +0 -14
  213. package/src/view/importView.js +0 -19
  214. package/src/view/layerView.js +0 -74
  215. package/src/view/rendering.d.ts +0 -44
  216. package/src/view/renderingContext/compositeViewRenderingContext.js +0 -51
  217. package/src/view/renderingContext/deferredViewRenderingContext.js +0 -176
  218. package/src/view/renderingContext/layoutRecorderViewRenderingContext.js +0 -128
  219. package/src/view/renderingContext/simpleViewRenderingContext.js +0 -64
  220. package/src/view/renderingContext/svgViewRenderingContext.js +0 -125
  221. package/src/view/renderingContext/viewRenderingContext.js +0 -41
  222. package/src/view/scaleResolution.js +0 -791
  223. package/src/view/scaleResolution.test.js +0 -572
  224. package/src/view/scaleResolutionApi.d.ts +0 -40
  225. package/src/view/testUtils.js +0 -51
  226. package/src/view/title.js +0 -165
  227. package/src/view/unitView.js +0 -382
  228. package/src/view/view.js +0 -612
  229. package/src/view/view.test.js +0 -214
  230. package/src/view/viewContext.d.ts +0 -62
  231. package/src/view/viewFactory.js +0 -181
  232. package/src/view/viewFactory.test.js +0 -17
  233. package/src/view/viewUtils.js +0 -327
  234. package/src/view/zoom.js +0 -89
package/src/view/title.js DELETED
@@ -1,165 +0,0 @@
1
- import { isString } from "vega-util";
2
-
3
- /** @type {Omit<Required<import("../spec/title").Title>, "text" | "style">} */
4
- const BASE_TITLE_STYLE = {
5
- anchor: "middle",
6
- frame: "group",
7
- offset: 10,
8
- orient: "top",
9
- align: undefined,
10
- angle: 0,
11
- baseline: "alphabetic",
12
- dx: 0,
13
- dy: 0,
14
- color: undefined,
15
- font: undefined,
16
- fontSize: 12,
17
- fontStyle: "normal",
18
- fontWeight: "normal",
19
- };
20
-
21
- /** @type {Partial<import("../spec/title").Title>} */
22
- const TRACK_TITLE_STYLE = {
23
- orient: "left",
24
- anchor: "middle",
25
- align: "right",
26
- baseline: "middle",
27
- angle: 0,
28
- fontSize: 12,
29
- };
30
-
31
- /** @type {Partial<import("../spec/title").Title>} */
32
- const OVERLAY_TITLE_STYLE = {
33
- orient: "top",
34
- anchor: "start",
35
- align: "left",
36
- baseline: "top",
37
- offset: -10,
38
- dx: 10,
39
- fontSize: 12,
40
- };
41
-
42
- /** @type {Record<import("../spec/title").TitleAnchor, number>} */
43
- const ANCHORS = {
44
- start: 0,
45
- middle: 0.5,
46
- end: 1,
47
- };
48
-
49
- /** @type {Record<import("../spec/title").TitleAnchor, import("../spec/font").Align>} */
50
- const ANCHOR_TO_ALIGN = {
51
- start: "left",
52
- middle: "center",
53
- end: "right",
54
- };
55
-
56
- /**
57
- * @param {string | import("../spec/title").Title} title
58
- * @returns {import("../spec/view").UnitSpec}
59
- */
60
- export default function createTitle(title) {
61
- if (!title) {
62
- return;
63
- }
64
-
65
- /** @type {import("../spec/title").Title} */
66
- const titleSpec = isString(title) ? { text: title } : title;
67
-
68
- if (!titleSpec.text || titleSpec.orient == "none") {
69
- return;
70
- }
71
-
72
- // TODO: Make these configurable
73
- /** @type {Partial<import("../spec/title").Title>} */
74
- const config =
75
- {
76
- "track-title": TRACK_TITLE_STYLE,
77
- overlay: OVERLAY_TITLE_STYLE,
78
- }[titleSpec.style] ?? {};
79
-
80
- // TODO: frame prop
81
-
82
- /** @type {import("../spec/title").Title} */
83
- const preliminarySpec = {
84
- ...BASE_TITLE_STYLE,
85
- ...config,
86
- ...titleSpec,
87
- };
88
-
89
- /** @type {Partial<import("../spec/title").Title>} */
90
- let orientConfig = {};
91
- let xy = { x: 0, y: 0 };
92
-
93
- const anchorPos = ANCHORS[preliminarySpec.anchor ?? "middle"];
94
-
95
- switch (preliminarySpec.orient) {
96
- case "top":
97
- xy = { x: anchorPos, y: 1 };
98
- orientConfig = { baseline: "alphabetic", angle: 0 };
99
- break;
100
- case "right":
101
- xy = { x: 1, y: 1 - anchorPos };
102
- orientConfig = { baseline: "alphabetic", angle: 90 };
103
- break;
104
- case "bottom":
105
- xy = { x: anchorPos, y: 0 };
106
- orientConfig = { baseline: "top", angle: 0 };
107
- break;
108
- case "left":
109
- xy = { x: 0, y: anchorPos };
110
- orientConfig = { baseline: "alphabetic", angle: -90 };
111
- break;
112
- default:
113
- }
114
-
115
- /** @type {import("../spec/title").Title} */
116
- const spec = {
117
- ...BASE_TITLE_STYLE,
118
- ...orientConfig,
119
- ...config,
120
- ...titleSpec,
121
- };
122
-
123
- const offsets = { xOffset: 0, yOffset: 0 };
124
- switch (preliminarySpec.orient) {
125
- case "top":
126
- offsets.yOffset = -spec.offset;
127
- break;
128
- case "right":
129
- offsets.xOffset = spec.offset;
130
- break;
131
- case "bottom":
132
- offsets.yOffset = spec.offset;
133
- break;
134
- case "left":
135
- offsets.xOffset = -spec.offset;
136
- break;
137
- default:
138
- }
139
-
140
- return {
141
- configurableVisibility: false,
142
- data: { values: [{}] },
143
- mark: {
144
- type: "text",
145
- tooltip: null,
146
- clip: false,
147
-
148
- ...xy,
149
- ...offsets,
150
-
151
- text: spec.text,
152
-
153
- align: spec.align ?? ANCHOR_TO_ALIGN[spec.anchor],
154
- angle: spec.angle,
155
- baseline: spec.baseline,
156
- dx: spec.dx,
157
- dy: spec.dy,
158
- color: spec.color,
159
- font: spec.font,
160
- size: spec.fontSize,
161
- fontStyle: spec.fontStyle,
162
- fontWeight: spec.fontWeight,
163
- },
164
- };
165
- }
@@ -1,382 +0,0 @@
1
- import RectMark from "../marks/rectMark";
2
- import PointMark from "../marks/pointMark";
3
- import RuleMark from "../marks/rule";
4
- import LinkMark from "../marks/link";
5
- import TextMark from "../marks/text";
6
-
7
- import ContainerView from "./containerView";
8
- import ScaleResolution from "./scaleResolution";
9
- import {
10
- isSecondaryChannel,
11
- secondaryChannels,
12
- isPositionalChannel,
13
- isChannelDefWithScale,
14
- primaryPositionalChannels,
15
- getPrimaryChannel,
16
- } from "../encoder/encoder";
17
- import createDomain from "../utils/domainArray";
18
- import AxisResolution from "./axisResolution";
19
- import { isAggregateSamplesSpec } from "./viewFactory";
20
- import { peek } from "../utils/arrayUtils";
21
-
22
- /**
23
- *
24
- * @type {Object.<string, typeof import("../marks/mark").default>}
25
- * TODO: Find a proper place, make extendible
26
- */
27
- export const markTypes = {
28
- point: PointMark,
29
- rect: RectMark,
30
- rule: RuleMark,
31
- link: LinkMark,
32
- text: TextMark,
33
- };
34
-
35
- /**
36
- * @typedef {import("../spec/channel").Channel} Channel
37
- * @typedef {import("./view").default} View
38
- * @typedef {import("./layerView").default} LayerView
39
- * @typedef {import("../utils/domainArray").DomainArray} DomainArray
40
- * @typedef {import("../encoder/accessor").Accessor} Accessor
41
- * @typedef {import("../utils/layout/flexLayout").SizeDef} SizeDef
42
- * @typedef {import("../spec/view").ResolutionTarget} ResolutionTarget
43
- *
44
- */
45
- export default class UnitView extends ContainerView {
46
- /**
47
- *
48
- * @param {import("../spec/view").UnitSpec} spec
49
- * @param {import("./viewUtils").ViewContext} context
50
- * @param {import("./containerView").default} parent
51
- * @param {string} name
52
- */
53
- constructor(spec, context, parent, name) {
54
- super(spec, context, parent, name);
55
-
56
- this.spec = spec; // Set here again to keep types happy
57
-
58
- const Mark = markTypes[this.getMarkType()];
59
- if (Mark) {
60
- /** @type {import("../marks/mark").default} */
61
- this.mark = new Mark(this);
62
- } else {
63
- throw new Error(`No such mark: ${this.getMarkType()}`);
64
- }
65
-
66
- /** @type {(UnitView | LayerView)[]} */
67
- this.sampleAggregateViews = [];
68
- this._initializeAggregateViews();
69
-
70
- /**
71
- * Not nice! Inconsistent when faceting!
72
- * TODO: Something. Maybe store only width/height
73
- * @type {import("../utils/layout/rectangle").default}
74
- */
75
- this.coords = undefined;
76
- }
77
-
78
- /**
79
- * @returns {IterableIterator<View>}
80
- */
81
- *[Symbol.iterator]() {
82
- for (const child of this.sampleAggregateViews) {
83
- yield child;
84
- }
85
- }
86
-
87
- /**
88
- * @param {View} child
89
- * @param {View} replacement
90
- */
91
- replaceChild(child, replacement) {
92
- const i = this.sampleAggregateViews.indexOf(child);
93
- if (i >= 0) {
94
- this.sampleAggregateViews[i] = replacement;
95
- } else {
96
- throw new Error("Not my child view!");
97
- }
98
- }
99
-
100
- /**
101
- * @param {import("./renderingContext/viewRenderingContext").default} context
102
- * @param {import("../utils/layout/rectangle").default} coords
103
- * @param {import("./view").RenderingOptions} [options]
104
- */
105
- render(context, coords, options = {}) {
106
- if (!this.isVisible()) {
107
- return;
108
- }
109
-
110
- this.coords = coords;
111
-
112
- context.pushView(this, coords);
113
- context.renderMark(this.mark, options);
114
- context.popView(this);
115
- }
116
-
117
- getMarkType() {
118
- return typeof this.spec.mark == "object"
119
- ? this.spec.mark.type
120
- : this.spec.mark;
121
- }
122
-
123
- /**
124
- * Pulls scales and axes up in the view hierarcy according to the resolution rules.
125
- * TODO: legends
126
- *
127
- * @param {ResolutionTarget} type
128
- */
129
- resolve(type) {
130
- // TODO: Complain about nonsensical configuration, e.g. shared parent has independent children.
131
-
132
- const encoding = this.mark.encoding;
133
-
134
- for (const [channel, channelDef] of Object.entries(encoding)) {
135
- if (!isChannelDefWithScale(channelDef)) {
136
- continue;
137
- }
138
-
139
- let targetChannel = getPrimaryChannel(
140
- channelDef.resolutionChannel ?? channel
141
- );
142
-
143
- if (type == "axis" && !isPositionalChannel(targetChannel)) {
144
- continue;
145
- }
146
-
147
- // eslint-disable-next-line consistent-this
148
- let view = this;
149
- while (
150
- view.parent instanceof ContainerView &&
151
- ["shared", "excluded"].includes(
152
- view.parent.getConfiguredOrDefaultResolution(
153
- targetChannel,
154
- type
155
- )
156
- ) &&
157
- view.getConfiguredOrDefaultResolution(targetChannel, type) !=
158
- "excluded"
159
- ) {
160
- // @ts-ignore
161
- view = view.parent;
162
- }
163
-
164
- if (!view.resolutions[type][targetChannel]) {
165
- view.resolutions[type][targetChannel] =
166
- type == "scale"
167
- ? new ScaleResolution(targetChannel)
168
- : new AxisResolution(targetChannel);
169
- }
170
-
171
- // Looks silly, but keeps type checking happy
172
- if (isPositionalChannel(channel)) {
173
- view.resolutions[type][targetChannel].pushUnitView(
174
- this,
175
- channel
176
- );
177
- } else if (type == "scale") {
178
- view.resolutions[type][targetChannel].pushUnitView(
179
- this,
180
- channel
181
- );
182
- }
183
- }
184
- }
185
-
186
- /**
187
- *
188
- * @param {import("./view").Channel} channel
189
- */
190
- getAccessor(channel) {
191
- return this._cache("accessor/" + channel, () => {
192
- const encoding = this.mark.encoding; // Mark provides encodings with defaults and possible modifications
193
- if (encoding && encoding[channel]) {
194
- return this.context.accessorFactory.createAccessor(
195
- encoding[channel]
196
- );
197
- }
198
- });
199
- }
200
-
201
- /**
202
- * Returns an accessor that returns a (composite) key for partitioning the data
203
- *
204
- * @param {View} [whoIsAsking]
205
- * @returns {function(object):any}
206
- */
207
- getFacetAccessor(whoIsAsking) {
208
- // TODO: Rewrite, call getFacetFields
209
- const sampleAccessor = this.getAccessor("sample");
210
- if (sampleAccessor) {
211
- return sampleAccessor;
212
- }
213
-
214
- return super.getFacetAccessor(this);
215
- }
216
-
217
- /**
218
- * Returns a collector that is associated with this view.
219
- */
220
- getCollector() {
221
- return this.context.dataFlow.findCollectorByKey(this);
222
- }
223
-
224
- /**
225
- * @param {Channel} channel A primary channel
226
- */
227
- _validateDomainQuery(channel) {
228
- if (isSecondaryChannel(channel)) {
229
- throw new Error(
230
- `getDomain(${channel}), must only be called for primary channels!`
231
- );
232
- }
233
-
234
- const channelDef = this.mark.encoding[channel];
235
- // TODO: Broken. Fix.
236
- if (!isChannelDefWithScale(channelDef)) {
237
- throw new Error("The channel has no scale, cannot get domain!");
238
- }
239
-
240
- return channelDef;
241
- }
242
-
243
- /**
244
- * Returns the domain of the specified channel of this domain/mark.
245
- *
246
- * @param {Channel} channel A primary channel
247
- * @returns {DomainArray}
248
- */
249
- getConfiguredDomain(channel) {
250
- const channelDef = this._validateDomainQuery(channel);
251
-
252
- const specDomain =
253
- channelDef && channelDef.scale && channelDef.scale.domain;
254
- if (specDomain) {
255
- const scaleResolution = this.getScaleResolution(
256
- channelDef.resolutionChannel ?? channel
257
- );
258
- return createDomain(
259
- channelDef.type ?? "nominal",
260
- // Chrom/pos must be linearized first
261
- scaleResolution.fromComplexInterval(specDomain)
262
- );
263
- }
264
- }
265
-
266
- /**
267
- * Extracts the domain from the data.
268
- *
269
- * TODO: Optimize! Now this performs redundant work if multiple views share the same collector.
270
- * Also, all relevant fields should be processed in one iteration: https://jsbench.me/y5kkqy52jo/1
271
- * In fact, domain extraction could be a responsibility of the collector: As it handles data items,
272
- * it extracts domains for all fields (and data types) that need extracted domains.
273
- * Alternatively, extractor nodes could be added to the data flow, just like Vega does
274
- * (with aggregate and extent).
275
- *
276
- * @param {Channel} channel
277
- * @returns {DomainArray}
278
- */
279
- extractDataDomain(channel) {
280
- const channelDef = this._validateDomainQuery(channel);
281
- const type = channelDef.type ?? "nominal"; // TODO: Should check that this is a channel without scale
282
-
283
- /** @param {Channel} channel */
284
- const extract = (channel) => {
285
- /** @type {DomainArray} */
286
- let domain;
287
-
288
- const encodingSpec = this.mark.encoding[channel];
289
-
290
- if (encodingSpec) {
291
- const accessor =
292
- this.context.accessorFactory.createAccessor(encodingSpec);
293
- if (accessor) {
294
- domain = createDomain(type);
295
-
296
- if (accessor.constant) {
297
- domain.extend(accessor({}));
298
- } else {
299
- const collector = this.getCollector();
300
- if (collector?.completed) {
301
- collector.visitData((d) =>
302
- domain.extend(accessor(d))
303
- );
304
- }
305
- }
306
- }
307
- }
308
- return domain;
309
- };
310
-
311
- let domain = extract(channel);
312
-
313
- const secondaryChannel = secondaryChannels[channel];
314
- if (secondaryChannel) {
315
- const secondaryDomain = extract(secondaryChannel);
316
- if (secondaryDomain) {
317
- domain.extendAll(secondaryDomain);
318
- }
319
- }
320
-
321
- return domain;
322
- }
323
-
324
- getZoomLevel() {
325
- /** @param {Channel} channel */
326
- const getZoomLevel = (channel) =>
327
- this.getScaleResolution(channel)?.getZoomLevel() ?? 1.0;
328
-
329
- return primaryPositionalChannels
330
- .map(getZoomLevel)
331
- .reduce((a, c) => a * c, 1);
332
- }
333
-
334
- _initializeAggregateViews() {
335
- if (isAggregateSamplesSpec(this.spec)) {
336
- // TODO: Support multiple
337
- for (const sumSpec of this.spec.aggregateSamples) {
338
- const transform = sumSpec.transform ?? [];
339
- if (transform.length && peek(transform).type != "collect") {
340
- // MergeFacets must be a direct child of Collector
341
- transform.push({ type: "collect" });
342
- }
343
- transform.push({ type: "mergeFacets" });
344
- sumSpec.transform = transform;
345
-
346
- sumSpec.encoding = {
347
- ...(sumSpec.encoding ?? {}),
348
- sample: null,
349
- };
350
-
351
- const summaryView =
352
- /** @type { UnitView | LayerView | DecoratorView } */ (
353
- this.context.createView(sumSpec, this, "summaryView")
354
- );
355
-
356
- /**
357
- * @param {View} [whoIsAsking]
358
- */
359
- summaryView.getFacetFields = (whoIsAsking) => undefined;
360
-
361
- this.sampleAggregateViews.push(summaryView);
362
- }
363
- }
364
- }
365
-
366
- /**
367
- * @param {import("../utils/interactionEvent").default} event
368
- */
369
- propagateInteractionEvent(event) {
370
- event.target = this;
371
- }
372
-
373
- /**
374
- * @param {string} channel
375
- * @param {import("./containerView").ResolutionTarget} resolutionType
376
- * @returns {import("../spec/view").ResolutionBehavior}
377
- */
378
- getDefaultResolution(channel, resolutionType) {
379
- // This affects the sample aggregate views.
380
- return channel == "x" ? "shared" : "independent";
381
- }
382
- }