@genome-spy/core 0.30.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.
- package/dist/index.es.js +16373 -0
- package/dist/index.js +43 -43
- package/package.json +10 -7
- package/src/data/collector.js +0 -183
- package/src/data/collector.test.js +0 -84
- package/src/data/dataFlow.js +0 -148
- package/src/data/dataFlow.test.js +0 -5
- package/src/data/facetNode.js +0 -17
- package/src/data/flow.test.js +0 -72
- package/src/data/flowBatch.d.ts +0 -40
- package/src/data/flowNode.js +0 -283
- package/src/data/flowNode.test.js +0 -50
- package/src/data/flowOptimizer.js +0 -123
- package/src/data/flowOptimizer.test.js +0 -193
- package/src/data/flowTestUtils.js +0 -63
- package/src/data/formats/fasta.js +0 -32
- package/src/data/formats/fasta.test.js +0 -27
- package/src/data/sources/dataSource.js +0 -22
- package/src/data/sources/dataSourceFactory.js +0 -24
- package/src/data/sources/dataUtils.js +0 -78
- package/src/data/sources/dynamicCallbackSource.js +0 -57
- package/src/data/sources/dynamicSource.js +0 -37
- package/src/data/sources/inlineSource.js +0 -67
- package/src/data/sources/inlineSource.test.js +0 -56
- package/src/data/sources/namedSource.js +0 -79
- package/src/data/sources/sequenceSource.js +0 -46
- package/src/data/sources/sequenceSource.test.js +0 -46
- package/src/data/sources/urlSource.js +0 -74
- package/src/data/transforms/aggregate.js +0 -70
- package/src/data/transforms/clone.js +0 -40
- package/src/data/transforms/clone.test.js +0 -11
- package/src/data/transforms/coverage.js +0 -187
- package/src/data/transforms/coverage.test.js +0 -123
- package/src/data/transforms/filter.js +0 -37
- package/src/data/transforms/filter.test.js +0 -18
- package/src/data/transforms/filterScoredLabels.js +0 -134
- package/src/data/transforms/flattenCompressedExons.js +0 -57
- package/src/data/transforms/flattenDelimited.js +0 -74
- package/src/data/transforms/flattenDelimited.test.js +0 -87
- package/src/data/transforms/flattenSequence.js +0 -39
- package/src/data/transforms/flattenSequence.test.js +0 -34
- package/src/data/transforms/formula.js +0 -39
- package/src/data/transforms/formula.test.js +0 -19
- package/src/data/transforms/identifier.js +0 -108
- package/src/data/transforms/identifier.test.js +0 -83
- package/src/data/transforms/linearizeGenomicCoordinate.js +0 -101
- package/src/data/transforms/measureText.js +0 -44
- package/src/data/transforms/pileup.js +0 -128
- package/src/data/transforms/pileup.test.js +0 -70
- package/src/data/transforms/project.js +0 -41
- package/src/data/transforms/project.test.js +0 -32
- package/src/data/transforms/regexExtract.js +0 -61
- package/src/data/transforms/regexExtract.test.js +0 -67
- package/src/data/transforms/regexFold.js +0 -141
- package/src/data/transforms/regexFold.test.js +0 -160
- package/src/data/transforms/sample.js +0 -101
- package/src/data/transforms/sample.test.js +0 -38
- package/src/data/transforms/stack.js +0 -137
- package/src/data/transforms/stack.test.js +0 -91
- package/src/data/transforms/transformFactory.js +0 -60
- package/src/embedApi.d.ts +0 -67
- package/src/encoder/accessor.js +0 -82
- package/src/encoder/accessor.test.js +0 -47
- package/src/encoder/encoder.js +0 -394
- package/src/encoder/encoder.test.js +0 -98
- package/src/fonts/Lato-Regular.json +0 -1267
- package/src/fonts/Lato-Regular.png +0 -0
- package/src/fonts/OFL.txt +0 -93
- package/src/fonts/README.md +0 -3
- package/src/fonts/bmFont.d.ts +0 -58
- package/src/fonts/bmFontManager.js +0 -357
- package/src/fonts/bmFontMetrics.js +0 -108
- package/src/genome/genome.js +0 -317
- package/src/genome/genome.test.js +0 -188
- package/src/genome/genomeStore.js +0 -54
- package/src/genome/locusFormat.js +0 -31
- package/src/genome/scaleIndex.d.ts +0 -38
- package/src/genome/scaleIndex.js +0 -166
- package/src/genome/scaleIndex.test.js +0 -78
- package/src/genome/scaleLocus.d.ts +0 -11
- package/src/genome/scaleLocus.js +0 -108
- package/src/genome/scaleLocus.test.js +0 -4
- package/src/genomeSpy.js +0 -785
- package/src/gl/arrayBuilder.js +0 -199
- package/src/gl/dataToVertices.js +0 -636
- package/src/gl/includes/common.glsl +0 -63
- package/src/gl/includes/picking.fragment.glsl +0 -1
- package/src/gl/includes/picking.vertex.glsl +0 -27
- package/src/gl/includes/sampleFacet.glsl +0 -107
- package/src/gl/includes/scales.glsl +0 -112
- package/src/gl/link.fragment.glsl +0 -18
- package/src/gl/link.vertex.glsl +0 -111
- package/src/gl/point.fragment.glsl +0 -123
- package/src/gl/point.vertex.glsl +0 -129
- package/src/gl/rect.fragment.glsl +0 -51
- package/src/gl/rect.vertex.glsl +0 -114
- package/src/gl/rule.fragment.glsl +0 -52
- package/src/gl/rule.vertex.glsl +0 -89
- package/src/gl/text.fragment.glsl +0 -31
- package/src/gl/text.vertex.glsl +0 -246
- package/src/gl/webGLHelper.js +0 -504
- package/src/img/bowtie.svg +0 -1
- package/src/img/genomespy-favicon.svg +0 -34
- package/src/index.html +0 -11
- package/src/index.js +0 -128
- package/src/marks/link.js +0 -175
- package/src/marks/mark.js +0 -975
- package/src/marks/markUtils.js +0 -125
- package/src/marks/pointMark.js +0 -251
- package/src/marks/rectMark.js +0 -241
- package/src/marks/rule.js +0 -250
- package/src/marks/text.js +0 -278
- package/src/node_modules/.vitest/results.json +0 -1
- package/src/scale/colorUtils.js +0 -184
- package/src/scale/glslScaleGenerator.js +0 -502
- package/src/scale/scale.js +0 -451
- package/src/scale/scale.test.js +0 -324
- package/src/scale/ticks.js +0 -203
- package/src/scale/ticks.test.js +0 -40
- package/src/singlePageApp.js +0 -13
- package/src/spec/axis.d.ts +0 -296
- package/src/spec/channel.d.ts +0 -430
- package/src/spec/data.d.ts +0 -196
- package/src/spec/font.d.ts +0 -15
- package/src/spec/genome.d.ts +0 -35
- package/src/spec/mark.d.ts +0 -429
- package/src/spec/root.d.ts +0 -17
- package/src/spec/sampleView.d.ts +0 -180
- package/src/spec/scale.d.ts +0 -273
- package/src/spec/title.d.ts +0 -102
- package/src/spec/tooltip.d.ts +0 -9
- package/src/spec/transform.d.ts +0 -479
- package/src/spec/view.d.ts +0 -201
- package/src/styles/genome-spy.scss +0 -153
- package/src/tooltip/dataTooltipHandler.js +0 -64
- package/src/tooltip/refseqGeneTooltipHandler.js +0 -78
- package/src/tooltip/tooltipHandler.ts +0 -12
- package/src/types/filetypes.d.ts +0 -14
- package/src/types/flatqueue.d.ts +0 -53
- package/src/types/glsl.d.ts +0 -4
- package/src/types/internmap.d.ts +0 -22
- package/src/types/object.d.ts +0 -21
- package/src/types/vega-loader.d.ts +0 -1
- package/src/types/vega-scale.d.ts +0 -60
- package/src/utils/addBaseUrl.js +0 -19
- package/src/utils/addBaseUrl.test.js +0 -22
- package/src/utils/animator.js +0 -83
- package/src/utils/arrayUtils.js +0 -61
- package/src/utils/binnedIndex.js +0 -167
- package/src/utils/binnedIndex.test.js +0 -155
- package/src/utils/clamp.js +0 -8
- package/src/utils/cloner.js +0 -34
- package/src/utils/cloner.test.js +0 -24
- package/src/utils/coalesce.js +0 -11
- package/src/utils/coalesce.test.js +0 -16
- package/src/utils/concatIterables.js +0 -26
- package/src/utils/concatIterables.test.js +0 -8
- package/src/utils/debounce.js +0 -37
- package/src/utils/domainArray.js +0 -216
- package/src/utils/domainArray.test.js +0 -130
- package/src/utils/eerp.js +0 -13
- package/src/utils/expression.js +0 -32
- package/src/utils/field.js +0 -28
- package/src/utils/formatObject.js +0 -31
- package/src/utils/indexer.js +0 -43
- package/src/utils/indexer.test.js +0 -47
- package/src/utils/inertia.js +0 -124
- package/src/utils/interactionEvent.js +0 -33
- package/src/utils/iterateNestedMaps.js +0 -21
- package/src/utils/iterateNestedMaps.test.js +0 -33
- package/src/utils/kWayMerge.js +0 -42
- package/src/utils/kWayMerge.test.js +0 -26
- package/src/utils/layout/flexLayout.js +0 -368
- package/src/utils/layout/flexLayout.test.js +0 -311
- package/src/utils/layout/grid.js +0 -95
- package/src/utils/layout/grid.test.js +0 -71
- package/src/utils/layout/padding.js +0 -120
- package/src/utils/layout/point.js +0 -23
- package/src/utils/layout/rectangle.js +0 -288
- package/src/utils/layout/rectangle.test.js +0 -172
- package/src/utils/mergeObjects.js +0 -99
- package/src/utils/mergeObjects.test.js +0 -42
- package/src/utils/numberExtractor.js +0 -24
- package/src/utils/numberExtractor.test.js +0 -6
- package/src/utils/point.js +0 -14
- package/src/utils/propertyCacher.js +0 -70
- package/src/utils/propertyCacher.test.js +0 -85
- package/src/utils/propertyCoalescer.js +0 -42
- package/src/utils/propertyCoalescer.test.js +0 -22
- package/src/utils/reservationMap.js +0 -103
- package/src/utils/reservationMap.test.js +0 -20
- package/src/utils/scaleNull.js +0 -19
- package/src/utils/setOperations.js +0 -75
- package/src/utils/smoothstep.js +0 -10
- package/src/utils/throttle.js +0 -34
- package/src/utils/topK.js +0 -76
- package/src/utils/topK.test.js +0 -64
- package/src/utils/transition.js +0 -74
- package/src/utils/ui/tooltip.js +0 -189
- package/src/utils/url.js +0 -22
- package/src/utils/variableTools.js +0 -24
- package/src/utils/variableTools.test.js +0 -13
- package/src/view/axisResolution.js +0 -140
- package/src/view/axisResolution.test.js +0 -201
- package/src/view/axisView.js +0 -747
- package/src/view/concatView.js +0 -45
- package/src/view/containerView.js +0 -159
- package/src/view/facetView.js +0 -491
- package/src/view/flowBuilder.js +0 -367
- package/src/view/flowBuilder.test.js +0 -125
- package/src/view/gridView.js +0 -786
- package/src/view/implicitRootView.js +0 -14
- package/src/view/importView.js +0 -19
- package/src/view/layerView.js +0 -74
- package/src/view/rendering.d.ts +0 -44
- package/src/view/renderingContext/compositeViewRenderingContext.js +0 -51
- package/src/view/renderingContext/deferredViewRenderingContext.js +0 -176
- package/src/view/renderingContext/layoutRecorderViewRenderingContext.js +0 -128
- package/src/view/renderingContext/simpleViewRenderingContext.js +0 -64
- package/src/view/renderingContext/svgViewRenderingContext.js +0 -125
- package/src/view/renderingContext/viewRenderingContext.js +0 -41
- package/src/view/scaleResolution.js +0 -797
- package/src/view/scaleResolution.test.js +0 -572
- package/src/view/scaleResolutionApi.d.ts +0 -40
- package/src/view/testUtils.js +0 -51
- package/src/view/title.js +0 -165
- package/src/view/unitView.js +0 -382
- package/src/view/view.js +0 -612
- package/src/view/view.test.js +0 -214
- package/src/view/viewContext.d.ts +0 -62
- package/src/view/viewFactory.js +0 -181
- package/src/view/viewFactory.test.js +0 -17
- package/src/view/viewUtils.js +0 -327
- package/src/view/zoom.js +0 -89
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A bare-bones FASTA-parser
|
|
3
|
-
*
|
|
4
|
-
* @typedef {object} SequenceEntry
|
|
5
|
-
* @prop {string} identifier
|
|
6
|
-
* @prop {string} sequence
|
|
7
|
-
*
|
|
8
|
-
* @param {string} data
|
|
9
|
-
* @param {any} options
|
|
10
|
-
* @returns {SequenceEntry[]}
|
|
11
|
-
*/
|
|
12
|
-
export default function fasta(data, options) {
|
|
13
|
-
/** @type {SequenceEntry[]} */
|
|
14
|
-
const sequences = [];
|
|
15
|
-
|
|
16
|
-
/** @type {SequenceEntry} */
|
|
17
|
-
let currentEntry;
|
|
18
|
-
|
|
19
|
-
for (const line of data.split("\n")) {
|
|
20
|
-
if (line.startsWith(">")) {
|
|
21
|
-
const identifier = line.match(/>(\S+)/)[1];
|
|
22
|
-
currentEntry = { identifier, sequence: "" };
|
|
23
|
-
sequences.push(currentEntry);
|
|
24
|
-
} else if (currentEntry) {
|
|
25
|
-
currentEntry.sequence += line.trim();
|
|
26
|
-
} else {
|
|
27
|
-
throw new Error("Invalid fasta file!");
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return sequences;
|
|
32
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { expect, test } from "vitest";
|
|
2
|
-
import fasta from "./fasta";
|
|
3
|
-
|
|
4
|
-
test("fasta", () => {
|
|
5
|
-
const fileContent = `>A stuff
|
|
6
|
-
--------------------------AGAGTTTGATCCTGGCTCAGGGTGAACGCTGGCG
|
|
7
|
-
GCGTGC----TTAAGACATGCAAGTCGAACGG-CCT------TCTTCG-G-AAGGC-AGT
|
|
8
|
-
---------------------------------
|
|
9
|
-
>B other stuff
|
|
10
|
-
--------------------------AGAGTTTGATCATGGCTCAGGGTGAACGCTGGCG
|
|
11
|
-
GCGTGC----TTAAGACATGCAAGTCGGACGA-TCG------GCTTCG---GCCGGTAGT
|
|
12
|
-
---------------------------------
|
|
13
|
-
`;
|
|
14
|
-
|
|
15
|
-
expect(fasta(fileContent)).toEqual([
|
|
16
|
-
{
|
|
17
|
-
identifier: "A",
|
|
18
|
-
sequence:
|
|
19
|
-
"--------------------------AGAGTTTGATCCTGGCTCAGGGTGAACGCTGGCGGCGTGC----TTAAGACATGCAAGTCGAACGG-CCT------TCTTCG-G-AAGGC-AGT---------------------------------",
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
identifier: "B",
|
|
23
|
-
sequence:
|
|
24
|
-
"--------------------------AGAGTTTGATCATGGCTCAGGGTGAACGCTGGCGGCGTGC----TTAAGACATGCAAGTCGGACGA-TCG------GCTTCG---GCCGGTAGT---------------------------------",
|
|
25
|
-
},
|
|
26
|
-
]);
|
|
27
|
-
});
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import FlowNode from "../flowNode";
|
|
2
|
-
|
|
3
|
-
export default class DataSource extends FlowNode {
|
|
4
|
-
/**
|
|
5
|
-
* @return {string}
|
|
6
|
-
*/
|
|
7
|
-
get identifier() {
|
|
8
|
-
return undefined;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
*
|
|
13
|
-
* @param {import("../flowNode").Datum} datum
|
|
14
|
-
*/
|
|
15
|
-
handle(datum) {
|
|
16
|
-
throw new Error("Source does not handle incoming data!");
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async load() {
|
|
20
|
-
// override
|
|
21
|
-
}
|
|
22
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import InlineSource, { isInlineData } from "./inlineSource";
|
|
2
|
-
import UrlSource, { isUrlData } from "./urlSource";
|
|
3
|
-
import SequenceSource, { isSequenceGenerator } from "./sequenceSource";
|
|
4
|
-
import DynamicSource, { isDynamicData } from "./dynamicSource";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @param {Partial<import("../../spec/data").Data>} params
|
|
8
|
-
* @param {string} [baseUrl]
|
|
9
|
-
*/
|
|
10
|
-
export default function createDataSource(params, baseUrl) {
|
|
11
|
-
if (isInlineData(params)) {
|
|
12
|
-
return new InlineSource(params);
|
|
13
|
-
} else if (isUrlData(params)) {
|
|
14
|
-
return new UrlSource(params, baseUrl);
|
|
15
|
-
} else if (isSequenceGenerator(params)) {
|
|
16
|
-
return new SequenceSource(params);
|
|
17
|
-
} else if (isDynamicData(params)) {
|
|
18
|
-
return new DynamicSource();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
throw new Error(
|
|
22
|
-
"Cannot figure out the data source type: " + JSON.stringify(params)
|
|
23
|
-
);
|
|
24
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validates data source params, infers format if not specified explicitly,
|
|
3
|
-
* returns a complete DataSource params object.
|
|
4
|
-
*
|
|
5
|
-
* @param {import("../../spec/data").DataSource} params
|
|
6
|
-
* DataSource parameters
|
|
7
|
-
*/
|
|
8
|
-
export function getFormat(params) {
|
|
9
|
-
const format = { ...params.format };
|
|
10
|
-
|
|
11
|
-
format.type ??= isUrlData(params) && extractTypeFromUrl(params.url);
|
|
12
|
-
// @ts-expect-error
|
|
13
|
-
format.parse ??= "auto";
|
|
14
|
-
|
|
15
|
-
if (!format.type) {
|
|
16
|
-
throw new Error(
|
|
17
|
-
"Format for the data source was not defined and it could not be inferred: " +
|
|
18
|
-
JSON.stringify(params)
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return format;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @param {string | string[]} url
|
|
27
|
-
*/
|
|
28
|
-
export function extractTypeFromUrl(url) {
|
|
29
|
-
if (Array.isArray(url)) {
|
|
30
|
-
url = url[0];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (url) {
|
|
34
|
-
return url.match(/\.(csv|tsv|json)/)?.[1];
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export const makeWrapper = (/** @type {any} */ d) =>
|
|
39
|
-
typeof d != "object" ? scalarWrapper : nopWrapper;
|
|
40
|
-
|
|
41
|
-
const scalarWrapper = (
|
|
42
|
-
/** @type {import("@genome-spy/core/spec/channel").Scalar} */ x
|
|
43
|
-
) => ({ data: x });
|
|
44
|
-
|
|
45
|
-
const nopWrapper = (/** @type {import("../flowNode").Datum} */ x) => x;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* @param {import("../../spec/data").DataFormat} dataFormat
|
|
49
|
-
* @return {dataFormat is import("../../spec/data").CsvDataFormat}
|
|
50
|
-
*/
|
|
51
|
-
export function isCsvDataFormat(dataFormat) {
|
|
52
|
-
return dataFormat.type == "csv" || dataFormat.type == "tsv";
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* @param {import("../../spec/data").DataFormat} dataFormat
|
|
57
|
-
* @return {dataFormat is import("../../spec/data").DsvDataFormat}
|
|
58
|
-
*/
|
|
59
|
-
export function isDsvDataFormat(dataFormat) {
|
|
60
|
-
return dataFormat.type == "dsv";
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* @param {import("../../spec/data").DataFormat} dataFormat
|
|
65
|
-
* @return {dataFormat is import("../../spec/data").JsonDataFormat}
|
|
66
|
-
*/
|
|
67
|
-
export function isJsonDataFormat(dataFormat) {
|
|
68
|
-
return dataFormat.type == "json";
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
*
|
|
73
|
-
* @param {import("../../spec/data").DataSource} dataSource
|
|
74
|
-
* @return {dataSource is import("../../spec/data").UrlData}
|
|
75
|
-
*/
|
|
76
|
-
export function isUrlData(dataSource) {
|
|
77
|
-
return "url" in dataSource;
|
|
78
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import DataSource from "./dataSource";
|
|
2
|
-
import { makeWrapper } from "./dataUtils";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @param {Partial<import("../../spec/data").Data>} data
|
|
6
|
-
* @returns {data is import("../../spec/data").DynamicCallbackData}
|
|
7
|
-
*/
|
|
8
|
-
export function isDynamicCallbackData(data) {
|
|
9
|
-
return "dynamicCallbackSource" in data;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* A data source that retrieves the data from a callback that returns an iterable.
|
|
14
|
-
*/
|
|
15
|
-
export default class DynamicCallbackSource extends DataSource {
|
|
16
|
-
/**
|
|
17
|
-
* @param {function():Iterable<any>} [callback] Function that provides the data
|
|
18
|
-
*/
|
|
19
|
-
constructor(callback) {
|
|
20
|
-
super();
|
|
21
|
-
|
|
22
|
-
this.callback = callback;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
loadSynchronously() {
|
|
26
|
-
if (!this.callback) {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const iterable = this.callback();
|
|
31
|
-
|
|
32
|
-
if (!iterable || typeof iterable[Symbol.iterator] !== "function") {
|
|
33
|
-
throw new Error(
|
|
34
|
-
"Dynamic data callback didn't return iterable data!"
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
this.reset();
|
|
39
|
-
this.beginBatch({ type: "file" });
|
|
40
|
-
|
|
41
|
-
let wrap;
|
|
42
|
-
|
|
43
|
-
for (const d of iterable) {
|
|
44
|
-
if (!wrap) {
|
|
45
|
-
wrap = makeWrapper(d);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
this._propagate(wrap(d));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
this.complete();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async load() {
|
|
55
|
-
this.loadSynchronously();
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import DataSource from "./dataSource";
|
|
2
|
-
import { makeWrapper } from "./dataUtils";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @param {Partial<import("../../spec/data").Data>} data
|
|
6
|
-
* @returns {data is import("../../spec/data").DynamicData}
|
|
7
|
-
*/
|
|
8
|
-
export function isDynamicData(data) {
|
|
9
|
-
return "dynamicSource" in data;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export default class DynamicSource extends DataSource {
|
|
13
|
-
/**
|
|
14
|
-
*
|
|
15
|
-
* @param {Iterable<any>} iterable
|
|
16
|
-
*/
|
|
17
|
-
publishData(iterable) {
|
|
18
|
-
this.reset();
|
|
19
|
-
this.beginBatch({ type: "file" });
|
|
20
|
-
|
|
21
|
-
let wrap;
|
|
22
|
-
|
|
23
|
-
for (const d of iterable) {
|
|
24
|
-
if (!wrap) {
|
|
25
|
-
wrap = makeWrapper(d);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
this._propagate(wrap(d));
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
this.complete();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async load() {
|
|
35
|
-
// nop
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { read } from "vega-loader";
|
|
2
|
-
import { getFormat, makeWrapper } from "./dataUtils";
|
|
3
|
-
import DataSource from "./dataSource";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @param {Partial<import("../../spec/data").Data>} data
|
|
7
|
-
* @returns {data is import("../../spec/data").InlineData}
|
|
8
|
-
*/
|
|
9
|
-
export function isInlineData(data) {
|
|
10
|
-
return "values" in data;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export default class InlineSource extends DataSource {
|
|
14
|
-
/**
|
|
15
|
-
* @param {import("../../spec/data").InlineData} params
|
|
16
|
-
*/
|
|
17
|
-
constructor(params) {
|
|
18
|
-
super();
|
|
19
|
-
|
|
20
|
-
this.params = params;
|
|
21
|
-
|
|
22
|
-
if (typeof params.values == "string" && !params?.format?.type) {
|
|
23
|
-
throw new Error(
|
|
24
|
-
"Data format type (csv, dsv, ...) must be specified if a string is provided!"
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
loadSynchronously() {
|
|
30
|
-
const values = this.params.values;
|
|
31
|
-
|
|
32
|
-
let data = [];
|
|
33
|
-
|
|
34
|
-
/** @type {(x: any) => import("../flowNode").Datum} */
|
|
35
|
-
let wrap = (x) => x;
|
|
36
|
-
|
|
37
|
-
if (Array.isArray(values)) {
|
|
38
|
-
if (values.length > 0) {
|
|
39
|
-
data = values;
|
|
40
|
-
// TODO: Should check the whole array and abort if types are heterogeneous
|
|
41
|
-
wrap = makeWrapper(values[0]);
|
|
42
|
-
}
|
|
43
|
-
} else if (typeof values == "object") {
|
|
44
|
-
data = [values];
|
|
45
|
-
} else if (typeof values == "string") {
|
|
46
|
-
// It's a string that needs to be parsed
|
|
47
|
-
data = read(values, getFormat(this.params));
|
|
48
|
-
} else {
|
|
49
|
-
throw new Error(
|
|
50
|
-
'"values" in data configuration is not an array, object, or a string!'
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
this.reset();
|
|
55
|
-
this.beginBatch({ type: "file" });
|
|
56
|
-
|
|
57
|
-
for (const d of data) {
|
|
58
|
-
this._propagate(wrap(d));
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
this.complete();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async load() {
|
|
65
|
-
this.loadSynchronously();
|
|
66
|
-
}
|
|
67
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { expect, test } from "vitest";
|
|
2
|
-
import Collector from "../collector";
|
|
3
|
-
import InlineSource from "./inlineSource";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @param {InlineSource} source
|
|
7
|
-
*/
|
|
8
|
-
async function collectSource(source) {
|
|
9
|
-
const collector = new Collector();
|
|
10
|
-
source.addChild(collector);
|
|
11
|
-
|
|
12
|
-
await source.load();
|
|
13
|
-
|
|
14
|
-
return [...collector.getData()];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
test("InlineSource propagates an object", async () => {
|
|
18
|
-
expect(await collectSource(new InlineSource({ values: { x: 1 } }))).toEqual(
|
|
19
|
-
[{ x: 1 }]
|
|
20
|
-
);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
test("InlineSource propagates an array of objects", async () => {
|
|
24
|
-
expect(
|
|
25
|
-
await collectSource(new InlineSource({ values: [{ x: 1 }, { x: 2 }] }))
|
|
26
|
-
).toEqual([{ x: 1 }, { x: 2 }]);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
test("InlineSource wraps scalars to objects", async () => {
|
|
30
|
-
expect(await collectSource(new InlineSource({ values: [1, 2] }))).toEqual([
|
|
31
|
-
{ data: 1 },
|
|
32
|
-
{ data: 2 },
|
|
33
|
-
]);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test("InlineSource parses a string", async () => {
|
|
37
|
-
expect(
|
|
38
|
-
await collectSource(
|
|
39
|
-
new InlineSource({
|
|
40
|
-
values: "a\n1\n2\n3",
|
|
41
|
-
format: {
|
|
42
|
-
type: "csv",
|
|
43
|
-
},
|
|
44
|
-
})
|
|
45
|
-
)
|
|
46
|
-
).toEqual([{ a: 1 }, { a: 2 }, { a: 3 }]);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test("InlineSource throws on a string and a missing format specifier", () => {
|
|
50
|
-
expect(
|
|
51
|
-
() =>
|
|
52
|
-
new InlineSource({
|
|
53
|
-
values: "a\n1\n2\n3",
|
|
54
|
-
})
|
|
55
|
-
).toThrow();
|
|
56
|
-
});
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import DataSource from "./dataSource";
|
|
2
|
-
import { makeWrapper } from "./dataUtils";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @param {Partial<import("../../spec/data").Data>} data
|
|
6
|
-
* @returns {data is import("../../spec/data").NamedData}
|
|
7
|
-
*/
|
|
8
|
-
export function isNamedData(data) {
|
|
9
|
-
return "name" in data;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export default class NamedSource extends DataSource {
|
|
13
|
-
/**
|
|
14
|
-
* Data that has been provided explicitly using the updateDynamicData method
|
|
15
|
-
* @type {any[]}
|
|
16
|
-
*/
|
|
17
|
-
#explicitData;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @param {import("../../spec/data").NamedData} params
|
|
21
|
-
* @param {function(string):any[]} provider Function that retrieves a dataset using a name
|
|
22
|
-
*/
|
|
23
|
-
constructor(params, provider) {
|
|
24
|
-
super();
|
|
25
|
-
|
|
26
|
-
this.provider = provider;
|
|
27
|
-
this.params = params;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @return {string}
|
|
32
|
-
*/
|
|
33
|
-
get identifier() {
|
|
34
|
-
return this.params.name;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Update the named data. If data is omitted, a data provider is used instead.
|
|
39
|
-
*
|
|
40
|
-
* @param {import("../flowNode").Datum[]} [data]
|
|
41
|
-
*/
|
|
42
|
-
updateDynamicData(data) {
|
|
43
|
-
// TODO: Throw is data is undefined and the provider is unable to provide any data
|
|
44
|
-
this.#explicitData = data;
|
|
45
|
-
this.loadSynchronously();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
loadSynchronously() {
|
|
49
|
-
const data =
|
|
50
|
-
this.#explicitData ?? this.provider(this.params.name) ?? [];
|
|
51
|
-
|
|
52
|
-
/** @type {(x: any) => import("../flowNode").Datum} */
|
|
53
|
-
let wrap = (x) => x;
|
|
54
|
-
|
|
55
|
-
if (Array.isArray(data)) {
|
|
56
|
-
if (data.length > 0) {
|
|
57
|
-
// TODO: Should check the whole array and abort if types are heterogeneous
|
|
58
|
-
wrap = makeWrapper(data[0]);
|
|
59
|
-
}
|
|
60
|
-
} else {
|
|
61
|
-
throw new Error(
|
|
62
|
-
`Named data "${this.params.name}" is not an array!`
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
this.reset();
|
|
67
|
-
this.beginBatch({ type: "file" });
|
|
68
|
-
|
|
69
|
-
for (const d of data) {
|
|
70
|
-
this._propagate(wrap(d));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
this.complete();
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async load() {
|
|
77
|
-
this.loadSynchronously();
|
|
78
|
-
}
|
|
79
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import DataSource from "./dataSource";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @param {Partial<import("../../spec/data").Data>} data
|
|
5
|
-
* @returns {data is import("../../spec/data").SequenceGenerator}
|
|
6
|
-
*/
|
|
7
|
-
export function isSequenceGenerator(data) {
|
|
8
|
-
return "sequence" in data;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export default class SequenceSource extends DataSource {
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
* @param {import("../../spec/data").SequenceGenerator} params
|
|
15
|
-
*/
|
|
16
|
-
constructor(params) {
|
|
17
|
-
super();
|
|
18
|
-
this.sequence = params.sequence;
|
|
19
|
-
|
|
20
|
-
if (!("start" in this.sequence)) {
|
|
21
|
-
throw new Error("'start' is missing from sequence parameters!");
|
|
22
|
-
}
|
|
23
|
-
if (!("stop" in this.sequence)) {
|
|
24
|
-
throw new Error("'stop' is missing from sequence parameters!");
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
loadSynchronously() {
|
|
29
|
-
const as = this.sequence.as || "data";
|
|
30
|
-
const step = this.sequence.step || 1;
|
|
31
|
-
const stop = this.sequence.stop;
|
|
32
|
-
|
|
33
|
-
this.reset();
|
|
34
|
-
this.beginBatch({ type: "file" });
|
|
35
|
-
|
|
36
|
-
for (let x = this.sequence.start; x < stop; x += step) {
|
|
37
|
-
this._propagate({ [as]: x });
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
this.complete();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async load() {
|
|
44
|
-
this.loadSynchronously();
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { expect, test } from "vitest";
|
|
2
|
-
import Collector from "../collector";
|
|
3
|
-
import SequenceSource from "./sequenceSource";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @param {SequenceSource} source
|
|
7
|
-
*/
|
|
8
|
-
async function collectSource(source) {
|
|
9
|
-
const collector = new Collector();
|
|
10
|
-
source.addChild(collector);
|
|
11
|
-
|
|
12
|
-
await source.load();
|
|
13
|
-
|
|
14
|
-
return [...collector.getData()];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
test("SequenceSource generates a sequence", async () => {
|
|
18
|
-
expect(
|
|
19
|
-
await collectSource(
|
|
20
|
-
new SequenceSource({ sequence: { start: 0, stop: 3 } })
|
|
21
|
-
)
|
|
22
|
-
).toEqual([{ data: 0 }, { data: 1 }, { data: 2 }]);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
test("SequenceSource generates a sequence with a custom step", async () => {
|
|
26
|
-
expect(
|
|
27
|
-
await collectSource(
|
|
28
|
-
new SequenceSource({ sequence: { start: 0, stop: 5, step: 2 } })
|
|
29
|
-
)
|
|
30
|
-
).toEqual([{ data: 0 }, { data: 2 }, { data: 4 }]);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test("SequenceSource generates a sequence with a custom field name", async () => {
|
|
34
|
-
expect(
|
|
35
|
-
await collectSource(
|
|
36
|
-
new SequenceSource({ sequence: { start: 0, stop: 3, as: "x" } })
|
|
37
|
-
)
|
|
38
|
-
).toEqual([{ x: 0 }, { x: 1 }, { x: 2 }]);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test("SequenceSource throws on missing 'start' parameter", () => {
|
|
42
|
-
expect(() => new SequenceSource({ sequence: { stop: 3 } })).toThrow();
|
|
43
|
-
});
|
|
44
|
-
test("SequenceSource throws on missing 'stop' parameter", () => {
|
|
45
|
-
expect(() => new SequenceSource({ sequence: { start: 0 } })).toThrow();
|
|
46
|
-
});
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { loader as vegaLoader, read } from "vega-loader";
|
|
2
|
-
import { getFormat } from "./dataUtils";
|
|
3
|
-
import DataSource from "./dataSource";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @param {Partial<import("../../spec/data").Data>} data
|
|
7
|
-
* @returns {data is import("../../spec/data").UrlData}
|
|
8
|
-
*/
|
|
9
|
-
export function isUrlData(data) {
|
|
10
|
-
return "url" in data;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export default class UrlSource extends DataSource {
|
|
14
|
-
/**
|
|
15
|
-
* @param {import("../../spec/data").UrlData} params
|
|
16
|
-
* @param {string} [baseUrl]
|
|
17
|
-
*/
|
|
18
|
-
constructor(params, baseUrl) {
|
|
19
|
-
super();
|
|
20
|
-
|
|
21
|
-
this.params = params;
|
|
22
|
-
this.baseUrl = baseUrl;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
get identifier() {
|
|
26
|
-
return JSON.stringify({ params: this.params, baseUrl: this.baseUrl });
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async load() {
|
|
30
|
-
const url = this.params.url;
|
|
31
|
-
|
|
32
|
-
/** @type {string[]} */
|
|
33
|
-
const urls = Array.isArray(url) ? url : [url];
|
|
34
|
-
|
|
35
|
-
/** @param {string} url */
|
|
36
|
-
const load = async (url) =>
|
|
37
|
-
// TODO: Support chunked loading
|
|
38
|
-
/** @type {string} */ (
|
|
39
|
-
vegaLoader({
|
|
40
|
-
baseURL: this.baseUrl,
|
|
41
|
-
})
|
|
42
|
-
.load(url)
|
|
43
|
-
.catch((/** @type {Error} */ e) => {
|
|
44
|
-
// TODO: Include baseurl in the error message. Should be normalized, however.
|
|
45
|
-
throw new Error(
|
|
46
|
-
`Cannot fetch: ${this.baseUrl}${url}: ${e.message}`
|
|
47
|
-
);
|
|
48
|
-
})
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @param {string} text
|
|
53
|
-
* @param {string} [url]
|
|
54
|
-
*/
|
|
55
|
-
const readAndParse = (text, url) => {
|
|
56
|
-
try {
|
|
57
|
-
/** @type {any[]} */
|
|
58
|
-
const data = read(text, getFormat(this.params));
|
|
59
|
-
this.beginBatch({ type: "file", url: url });
|
|
60
|
-
for (const d of data) {
|
|
61
|
-
this._propagate(d);
|
|
62
|
-
}
|
|
63
|
-
} catch (e) {
|
|
64
|
-
throw new Error(`Cannot parse: ${url}: ${e.message}`);
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
this.reset();
|
|
69
|
-
|
|
70
|
-
await Promise.all(urls.map((url) => load(url).then(readAndParse)));
|
|
71
|
-
|
|
72
|
-
this.complete();
|
|
73
|
-
}
|
|
74
|
-
}
|