@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
@@ -1,317 +0,0 @@
1
- import { bisect } from "d3-array";
2
- import { tsvParseRows } from "d3-dsv";
3
- import { loader } from "vega-loader";
4
- import { isObject } from "vega-util";
5
- import { formatRange } from "./locusFormat";
6
-
7
- const defaultBaseUrl = "https://genomespy.app/data/genomes/";
8
-
9
- /**
10
- * @typedef {import("../spec/genome").GenomeConfig} GenomeConfig
11
- * @typedef {import("../spec/genome").ChromosomalLocus} ChromosomalLocus
12
- *
13
- * @typedef {object} Chromosome
14
- * @prop {string} name
15
- * @prop {number} size
16
- *
17
- * @typedef {object} ChromosomeAnnotation
18
- * @prop {number} index 0-based index
19
- * @prop {number} number 1-based index
20
- * @prop {number} continuousStart zero-based start, inclusive
21
- * @prop {number} continuousEnd zero-based end, exclusive
22
- * @prop {number[]} continuousInterval
23
- * @prop {boolean} odd true if odd chrom number
24
- */
25
-
26
- export default class Genome {
27
- /**
28
- * @param {GenomeConfig} config
29
- */
30
- constructor(config) {
31
- this.config = config;
32
-
33
- if (!this.config.contigs && typeof this.config.name !== "string") {
34
- throw new Error(
35
- "No name has been defined for the genome assembly!"
36
- );
37
- }
38
-
39
- /** @type {(Chromosome & ChromosomeAnnotation)[]} */
40
- this.chromosomes = [];
41
-
42
- /** @type {Map<string | number, number>} */
43
- this.cumulativeChromPositions = new Map();
44
-
45
- /** @type {Map<string | number, Chromosome & ChromosomeAnnotation>} */
46
- this.chromosomesByName = new Map();
47
-
48
- /** @type {number[]} */
49
- this.startByIndex = [];
50
-
51
- this.totalSize = 0;
52
-
53
- if (this.config.contigs) {
54
- this.setChromSizes(this.config.contigs);
55
- }
56
- }
57
-
58
- get name() {
59
- return this.config.name;
60
- }
61
-
62
- /**
63
- * @param {string} baseUrl
64
- */
65
- async load(baseUrl) {
66
- if (this.config.contigs) {
67
- return;
68
- }
69
-
70
- if (this.config.baseUrl) {
71
- this.baseUrl = /^http(s)?/.test(this.config.baseUrl)
72
- ? this.config.baseUrl
73
- : baseUrl + "/" + this.config.baseUrl;
74
- } else {
75
- this.baseUrl = defaultBaseUrl;
76
- }
77
-
78
- try {
79
- this.setChromSizes(
80
- parseChromSizes(
81
- await loader({ baseURL: this.baseUrl }).load(
82
- `${this.config.name}/${this.name}.chrom.sizes`
83
- )
84
- )
85
- );
86
- } catch (e) {
87
- throw new Error(`Could not load chrom sizes: ${e.message}`);
88
- }
89
- }
90
-
91
- /**
92
- *
93
- * @param {Chromosome[]} chromSizes
94
- */
95
- setChromSizes(chromSizes) {
96
- let pos = 0;
97
- this.startByIndex = [0];
98
-
99
- for (let i = 0; i < chromSizes.length; i++) {
100
- this.startByIndex.push(pos);
101
- const size = chromSizes[i].size;
102
-
103
- const chrom = {
104
- ...chromSizes[i],
105
- continuousStart: pos,
106
- continuousEnd: pos + size,
107
- continuousInterval: [pos, pos + size],
108
- index: i,
109
- number: i + 1,
110
- // eslint-disable-next-line no-bitwise
111
- odd: !(i & 1),
112
- };
113
-
114
- this.chromosomes.push(chrom);
115
-
116
- const plain = chrom.name.replace(/^chr/i, "");
117
- for (const name of [
118
- "chr" + plain,
119
- "CHR" + plain,
120
- "Chr" + plain,
121
- // The number is a bit fragile because it depends on the order of the chromosomes.
122
- // It probably works for autosomes, but X, Y, M, etc., not necessarily.
123
- chrom.number,
124
- "" + chrom.number,
125
- plain,
126
- chrom.name,
127
- ]) {
128
- this.cumulativeChromPositions.set(name, pos);
129
- this.chromosomesByName.set(name, chrom);
130
- }
131
-
132
- pos += chrom.size;
133
- }
134
-
135
- this.totalSize = pos;
136
- }
137
-
138
- getExtent() {
139
- return [0, this.totalSize];
140
- }
141
-
142
- /**
143
- * Returns a chromosomal locus in the continuous domain
144
- *
145
- * @param {string | number} chrom A number or name with or without a "chr" prefix. Examples: 23, chrX, X
146
- * @param {number} pos zero-based coordinate
147
- */
148
- toContinuous(chrom, pos) {
149
- let offset = this.cumulativeChromPositions.get(chrom);
150
- if (offset === undefined) {
151
- throw new Error("Unknown chromosome/contig: " + chrom);
152
- }
153
-
154
- return offset + +pos;
155
- }
156
-
157
- /**
158
- *
159
- * @param {number} continuousPos
160
- */
161
- toChromosome(continuousPos) {
162
- if (continuousPos >= this.totalSize) {
163
- return; // TODO: Consider displaying a warning
164
- }
165
-
166
- continuousPos = Math.floor(continuousPos);
167
-
168
- // TODO: Fix the offset by one
169
- const i = bisect(this.startByIndex, continuousPos) - 1;
170
- if (i > 0 && i <= this.chromosomes.length) {
171
- return this.chromosomes[i - 1];
172
- }
173
- }
174
-
175
- /**
176
- *
177
- * @param {number} continuousPos
178
- * @returns {ChromosomalLocus}
179
- */
180
- toChromosomal(continuousPos) {
181
- const chrom = this.toChromosome(continuousPos);
182
- if (!chrom) {
183
- return undefined;
184
- }
185
-
186
- return {
187
- chrom: chrom.name,
188
- pos: Math.floor(continuousPos) - chrom.continuousStart,
189
- };
190
- }
191
-
192
- /**
193
- *
194
- * @param {string} name
195
- */
196
- getChromosome(name) {
197
- return this.chromosomesByName.get(name);
198
- }
199
-
200
- /**
201
- * Returns a UCSC Genome Browser -style string presentation of the interval.
202
- * However, the interval may span multiple chromosomes, which is incompatible
203
- * with UCSC.
204
- *
205
- * The inteval is shown as one-based closed-open range.
206
- * See https://genome.ucsc.edu/FAQ/FAQtracks#tracks1
207
- *
208
- * @param {number[]} interval
209
- * @returns {string}
210
- */
211
- formatInterval(interval) {
212
- return formatRange(...this.toChromosomalInterval(interval));
213
- }
214
-
215
- /**
216
- * @param {number[]} interval
217
- * @returns {[ChromosomalLocus, ChromosomalLocus]}
218
- */
219
- toChromosomalInterval(interval) {
220
- // Round the lower end
221
- const begin = this.toChromosomal(interval[0] + 0.5);
222
- // Because of the open upper bound, one is first subtracted from the upper bound and later added back.
223
- const end = this.toChromosomal(interval[1] - 0.5);
224
- end.pos += 1;
225
-
226
- return [begin, end];
227
- }
228
-
229
- /**
230
- * Returns a continuous interval. The optional position of the left end defaults to zero,
231
- * the right end defaults to the size of the chromosome. Thus, the chromosome is inclusive
232
- * when positions are omitted.
233
- *
234
- * @param {ChromosomalLocus[]} chromosomal
235
- */
236
- toContinuousInterval(chromosomal) {
237
- let [a, b] = chromosomal;
238
- if (!b) {
239
- // A shortcut for a single chromosome. { domain: [{ chrom: "chr3" }] }
240
- b = a;
241
- }
242
-
243
- return [
244
- this.toContinuous(a.chrom, a.pos ?? 0),
245
- this.toContinuous(
246
- b.chrom,
247
- b.pos ?? this.chromosomesByName.get(b.chrom)?.size
248
- ),
249
- ];
250
- }
251
-
252
- /**
253
- *
254
- * @param {string} str
255
- * @returns {[number, number]}
256
- */
257
- parseInterval(str) {
258
- // TODO: consider changing [0-9XY] to support other species besides humans
259
- const matches = str.match(
260
- /^(chr[0-9A-Z]+)(?::([0-9,]+)(?:-(?:(chr[0-9A-Z]+):)?([0-9,]+))?)?$/
261
- );
262
-
263
- if (matches) {
264
- const startChr = matches[1];
265
-
266
- if (matches.slice(2).every((x) => x === undefined)) {
267
- const chrom = this.getChromosome(startChr);
268
- if (chrom) {
269
- return [chrom.continuousStart, chrom.continuousEnd];
270
- }
271
- return;
272
- }
273
-
274
- const endChr = matches[3] || startChr;
275
-
276
- const startIndex = parseInt(matches[2].replace(/,/g, ""));
277
- const endIndex =
278
- matches[4] !== undefined
279
- ? parseInt(matches[4].replace(/,/g, ""))
280
- : startIndex;
281
-
282
- return [
283
- this.toContinuous(startChr, startIndex - 1),
284
- this.toContinuous(endChr, endIndex),
285
- ];
286
- }
287
- }
288
- }
289
-
290
- /**
291
- *
292
- * @param {string} chromSizesData
293
- */
294
- export function parseChromSizes(chromSizesData) {
295
- // TODO: Support other organisms too
296
- return tsvParseRows(chromSizesData)
297
- .filter((row) => /^chr[0-9A-Z]+$/.test(row[0]))
298
- .map(([name, size]) => ({ name, size: parseInt(size) }));
299
- }
300
-
301
- /**
302
- *
303
- * @param {any} value
304
- * @return {value is ChromosomalLocus}
305
- */
306
- export function isChromosomalLocus(value) {
307
- return isObject(value) && "chrom" in value;
308
- }
309
-
310
- /**
311
- *
312
- * @param {any[]} value
313
- * @return {value is ChromosomalLocus[]}
314
- */
315
- export function isChromosomalLocusInterval(value) {
316
- return value.every(isChromosomalLocus);
317
- }
@@ -1,188 +0,0 @@
1
- import { describe, expect, test } from "vitest";
2
- import Genome from "./genome";
3
-
4
- describe("Human genome, chromosome names prefixed with 'chr'", () => {
5
- // Actually, the chromosomes are just named as in hg38, for example
6
- const chromosomes = [
7
- { name: "chr1", size: 10 },
8
- { name: "chr2", size: 20 },
9
- { name: "chr3", size: 30 },
10
- { name: "chrX", size: 40 },
11
- ];
12
-
13
- const g = new Genome({ name: "random", contigs: chromosomes });
14
-
15
- test("Maps chromosome names to continuous", () => {
16
- expect(() => g.toContinuous("chr0", 2)).toThrow();
17
- expect(g.toContinuous("chr1", 0)).toEqual(0);
18
- expect(g.toContinuous("chr1", 2)).toEqual(2);
19
- expect(g.toContinuous("chr2", 2)).toEqual(12);
20
- expect(g.toContinuous("chrX", 2)).toEqual(62);
21
- // TODO: Should this throw to alert about invalid data..?
22
- // TODO: expect(m.toContinuous("chrX", 40)).toBeUndefined();
23
- });
24
-
25
- test("Maps chromosome numbers to continuous", () => {
26
- expect(() => g.toContinuous(0, 2)).toThrow();
27
- expect(g.toContinuous(1, 2)).toEqual(2);
28
- expect(g.toContinuous(2, 2)).toEqual(12);
29
- expect(g.toContinuous(4, 2)).toEqual(62);
30
- expect(() => g.toContinuous(5, 2)).toThrow();
31
- });
32
-
33
- test("Maps unprefixed names to continuous", () => {
34
- expect(() => g.toContinuous("0", 2)).toThrow();
35
- expect(g.toContinuous("1", 2)).toEqual(2);
36
- expect(g.toContinuous("2", 2)).toEqual(12);
37
- expect(g.toContinuous("X", 2)).toEqual(62);
38
- expect(() => g.toContinuous("Y", 2)).toThrow();
39
- });
40
-
41
- test("Maps string positions to continuous", () => {
42
- expect(g.toContinuous("2", /** @type {any} */ ("2"))).toEqual(12);
43
- });
44
-
45
- test("Maps continuous to chromosome and locus", () => {
46
- expect(g.toChromosomal(-1)).toBeUndefined();
47
- expect(g.toChromosomal(0)).toEqual({ chrom: "chr1", pos: 0 });
48
- expect(g.toChromosomal(12)).toEqual({ chrom: "chr2", pos: 2 });
49
- expect(g.toChromosomal(29)).toEqual({ chrom: "chr2", pos: 19 });
50
- expect(g.toChromosomal(30)).toEqual({ chrom: "chr3", pos: 0 });
51
- expect(g.toChromosomal(62)).toEqual({ chrom: "chrX", pos: 2 });
52
- expect(g.toChromosomal(99)).toEqual({ chrom: "chrX", pos: 39 });
53
- expect(g.toChromosomal(100)).toBeUndefined();
54
- });
55
-
56
- // Testing half-open intervals
57
- test("Maps continuous interval to chromosomal interval", () => {
58
- expect(g.toChromosomalInterval([0, 10])).toEqual([
59
- { chrom: "chr1", pos: 0 },
60
- { chrom: "chr1", pos: 10 },
61
- ]);
62
- expect(g.toChromosomalInterval([10, 100])).toEqual([
63
- { chrom: "chr2", pos: 0 },
64
- { chrom: "chrX", pos: 40 },
65
- ]);
66
- expect(g.toChromosomalInterval([0, 100])).toEqual([
67
- { chrom: "chr1", pos: 0 },
68
- { chrom: "chrX", pos: 40 },
69
- ]);
70
- });
71
-
72
- test("Maps interval with fractional parts to chromosomal interval", () => {
73
- expect(g.toChromosomalInterval([0.1, 99.9])).toEqual([
74
- { chrom: "chr1", pos: 0 },
75
- { chrom: "chrX", pos: 40 },
76
- ]);
77
- expect(g.toChromosomalInterval([0.6, 99.4])).toEqual([
78
- { chrom: "chr1", pos: 1 },
79
- { chrom: "chrX", pos: 39 },
80
- ]);
81
- });
82
-
83
- test("Maps chromosomal interval to continuous interval", () => {
84
- expect(
85
- g.toContinuousInterval([
86
- { chrom: "chr1", pos: 0 },
87
- { chrom: "chr1", pos: 10 },
88
- ])
89
- ).toEqual([0, 10]);
90
- expect(
91
- g.toContinuousInterval([
92
- { chrom: "chr1", pos: 1 },
93
- { chrom: "chr1", pos: 9 },
94
- ])
95
- ).toEqual([1, 9]);
96
- expect(
97
- g.toContinuousInterval([
98
- { chrom: "chr2", pos: 0 },
99
- { chrom: "chrX", pos: 40 },
100
- ])
101
- ).toEqual([10, 100]);
102
- expect(
103
- g.toContinuousInterval([
104
- { chrom: "chr1", pos: 0 },
105
- { chrom: "chrX", pos: 40 },
106
- ])
107
- ).toEqual([0, 100]);
108
- });
109
-
110
- test("Maps chromosomal interval without positions to continuous interval", () => {
111
- expect(
112
- g.toContinuousInterval([{ chrom: "chr1" }, { chrom: "chr1" }])
113
- ).toEqual([0, 10]);
114
- expect(
115
- g.toContinuousInterval([{ chrom: "chr2" }, { chrom: "chrX" }])
116
- ).toEqual([10, 100]);
117
- });
118
-
119
- test("Returns a properly annotated chromosomes array", () => {
120
- expect(g.chromosomes[1]).toEqual({
121
- name: "chr2",
122
- size: 20,
123
- index: 1,
124
- number: 2,
125
- continuousStart: 10,
126
- continuousEnd: 30,
127
- continuousInterval: [10, 30],
128
- odd: false,
129
- });
130
- });
131
- });
132
-
133
- describe("C. elegans genome, chromosome names prefixed with 'chr'", () => {
134
- const chromosomes = [
135
- { name: "chrI", size: 15072434 },
136
- { name: "chrII", size: 15279421 },
137
- { name: "chrIII", size: 13783801 },
138
- { name: "chrIV", size: 17493829 },
139
- { name: "chrV", size: 20924180 },
140
- { name: "chrX", size: 17718942 },
141
- { name: "chrM", size: 13794 },
142
- ];
143
-
144
- const g = new Genome({ name: "random", contigs: chromosomes });
145
-
146
- test("Maps chromosome names to continuous", () => {
147
- expect(g.toContinuous("chrIII", 10)).toEqual(30351865);
148
- });
149
-
150
- test("Maps unprefixed names to continuous", () => {
151
- expect(g.toContinuous("III", 10)).toEqual(30351865);
152
- });
153
- });
154
-
155
- describe("Parse interval strings", () => {
156
- const chromosomes = [
157
- { name: "chr1", size: 1000 },
158
- { name: "chr2", size: 2000 },
159
- { name: "chr3", size: 3000 },
160
- { name: "chrX", size: 4000 },
161
- ];
162
-
163
- const g = new Genome({ name: "random", contigs: chromosomes });
164
-
165
- test("Parses a single chromosome, returns an interval spanning the chromosome", () => {
166
- expect(g.parseInterval("chr2")).toEqual([1000, 3000]);
167
- });
168
-
169
- test("Returns undefined on unknown chromosome", () => {
170
- expect(g.parseInterval("chrZ")).toBeUndefined();
171
- });
172
-
173
- test("Parses a single coordinate without a thousand separator", () => {
174
- expect(g.parseInterval("chr2:1500")).toEqual([2499, 2500]);
175
- });
176
-
177
- test("Parses a single coordinate with a thousand separator", () => {
178
- expect(g.parseInterval("chr2:1,500")).toEqual([2499, 2500]);
179
- });
180
-
181
- test("Parses an interval within a single chromosome", () => {
182
- expect(g.parseInterval("chr2:1,500-1,700")).toEqual([2499, 2700]);
183
- });
184
-
185
- test("Parses an interval spanning multiple chromosomes", () => {
186
- expect(g.parseInterval("chr2:1,500-chr3:1,500")).toEqual([2499, 4500]);
187
- });
188
- });
@@ -1,54 +0,0 @@
1
- import Genome from "./genome";
2
-
3
- export default class GenomeStore {
4
- /**
5
- * @param {import("../genomeSpy").default} genomeSpy
6
- */
7
- constructor(genomeSpy) {
8
- /** @type {Map<string, Genome>} */
9
- this.genomes = new Map();
10
- this.genomeSpy = genomeSpy;
11
- }
12
-
13
- /**
14
- * @param {import("../spec/genome").GenomeConfig} genomeConfig
15
- */
16
- // eslint-disable-next-line require-await
17
- async initialize(genomeConfig) {
18
- const genome = new Genome(genomeConfig);
19
- this.genomes.set(genome.name, genome);
20
-
21
- return Promise.all(
22
- [...this.genomes.values()].map((genome) =>
23
- genome.load(this.genomeSpy.spec.baseUrl)
24
- )
25
- );
26
- }
27
-
28
- /**
29
- * @param {string} [name] If not given, a default genome is returned.
30
- * @returns {Genome}
31
- */
32
- getGenome(name) {
33
- if (!this.genomes.size) {
34
- throw new Error("No genomes have been configured!");
35
- }
36
-
37
- if (name) {
38
- const genome = this.genomes.get(name);
39
- if (!genome) {
40
- throw new Error(
41
- `No genome with the name ${name} has been configured!`
42
- );
43
- }
44
- return genome;
45
- } else {
46
- if (this.genomes.size > 1) {
47
- throw new Error(
48
- "Cannot pick a default genome! More than one have been configured!"
49
- );
50
- }
51
- return this.genomes.values().next().value;
52
- }
53
- }
54
- }
@@ -1,31 +0,0 @@
1
- import { format as d3format } from "d3-format";
2
-
3
- const numberFormat = d3format(",d");
4
-
5
- /**
6
- * @typedef {import("./genome").ChromosomalLocus} ChromosomalLocus
7
- */
8
-
9
- /**
10
- * @param {ChromosomalLocus} locus
11
- */
12
- export function formatLocus(locus) {
13
- return locus.chrom + ":" + numberFormat(Math.floor(locus.pos + 1));
14
- }
15
-
16
- /**
17
- * @param {ChromosomalLocus} begin
18
- * @param {ChromosomalLocus} end
19
- */
20
- export function formatRange(begin, end) {
21
- return (
22
- begin.chrom +
23
- ":" +
24
- numberFormat(Math.floor(begin.pos + 1)) +
25
- "-" +
26
- (begin.chrom != end.chrom ? end.chrom + ":" : "") +
27
- numberFormat(Math.ceil(end.pos))
28
- );
29
- }
30
-
31
- // TODO: parseLocus, parseRange
@@ -1,38 +0,0 @@
1
- export default function scaleIndex(): ScaleIndex;
2
-
3
- export interface ScaleIndex {
4
- (value: number): number;
5
-
6
- invert(x: number): number;
7
-
8
- domain(): number[];
9
- domain(_: Iterable<number>): this;
10
-
11
- range(): number[];
12
- range(_: Iterable<number>): this;
13
-
14
- numberingOffset(): number;
15
- numberingOffset(_: number): this;
16
-
17
- padding(): number;
18
- padding(_: number): this;
19
-
20
- paddingInner(): number;
21
- paddingInner(_: number): this;
22
-
23
- paddingOuter(): number;
24
- paddingOuter(_: number): this;
25
-
26
- align(): number;
27
- align(_: number): this;
28
-
29
- step(): number;
30
-
31
- bandwidth(): number;
32
-
33
- ticks(count: number): number[];
34
-
35
- tickFormat(count?: number, specifier?: string): (x: number) => string;
36
-
37
- copy(): this;
38
- }