@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.
- 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 -784
- 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 -489
- 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 -488
- 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 -791
- 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
package/src/view/viewUtils.js
DELETED
|
@@ -1,327 +0,0 @@
|
|
|
1
|
-
import { isObject, isString } from "vega-util";
|
|
2
|
-
import { loader as vegaLoader } from "vega-loader";
|
|
3
|
-
|
|
4
|
-
import UnitView from "./unitView";
|
|
5
|
-
import ImportView from "./importView";
|
|
6
|
-
// eslint-disable-next-line no-unused-vars
|
|
7
|
-
import View, { VISIT_SKIP, VISIT_STOP } from "./view";
|
|
8
|
-
import { buildDataFlow } from "./flowBuilder";
|
|
9
|
-
import { optimizeDataFlow } from "../data/flowOptimizer";
|
|
10
|
-
import { isFieldDef, primaryPositionalChannels } from "../encoder/encoder";
|
|
11
|
-
import { rollup } from "d3-array";
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @typedef {import("./viewContext").default} ViewContext
|
|
15
|
-
* @typedef {import("../spec/mark").MarkConfig} MarkConfig
|
|
16
|
-
* @typedef {import("../spec/channel").ChannelDef} ChannelDef
|
|
17
|
-
* @typedef {import("../spec/view").ContainerSpec} ContainerSpec
|
|
18
|
-
* @typedef {import("../spec/view").ViewSpec} ViewSpec
|
|
19
|
-
* @typedef {import("../spec/view").LayerSpec} LayerSpec
|
|
20
|
-
* @typedef {import("../spec/view").FacetSpec} FacetSpec
|
|
21
|
-
* @typedef {import("../spec/sampleView").SampleSpec} SampleSpec
|
|
22
|
-
* @typedef {import("../spec/view").UnitSpec} UnitSpec
|
|
23
|
-
* @typedef {import("../spec/view").VConcatSpec} VConcatSpec
|
|
24
|
-
* @typedef {import("../spec/view").HConcatSpec} HConcatSpec
|
|
25
|
-
* @typedef {import("../spec/view").ConcatSpec} ConcatSpec
|
|
26
|
-
* @typedef {VConcatSpec | HConcatSpec | ConcatSpec} AnyConcatSpec
|
|
27
|
-
* @typedef {import("../spec/view").ImportSpec} ImportSpec
|
|
28
|
-
* @typedef {import("../spec/view").ImportConfig} ImportConfig
|
|
29
|
-
* @typedef {import("../spec/root").RootSpec} RootSpec
|
|
30
|
-
*
|
|
31
|
-
* @typedef {import("../spec/view").FacetMapping} FacetMapping
|
|
32
|
-
* @typedef {import("../spec/channel").FacetFieldDef} FacetFieldDef
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
*
|
|
37
|
-
* @param {ChannelDef | FacetMapping} def
|
|
38
|
-
* @returns {spec is FacetFieldDef}
|
|
39
|
-
*/
|
|
40
|
-
export function isFacetFieldDef(def) {
|
|
41
|
-
return def && "field" in def && isString(def.field);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
*
|
|
46
|
-
* @param {FacetFieldDef | FacetMapping} def
|
|
47
|
-
* @returns {spec is FacetMapping}
|
|
48
|
-
*/
|
|
49
|
-
export function isFacetMapping(def) {
|
|
50
|
-
return (
|
|
51
|
-
("row" in def && isObject(def.row)) ||
|
|
52
|
-
("column" in def && isObject(def.column))
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
*
|
|
58
|
-
* @param {object} config
|
|
59
|
-
* @returns {config is ImportConfig}
|
|
60
|
-
*/
|
|
61
|
-
export function isImportConfig(config) {
|
|
62
|
-
return "name" in config || "url" in config;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Returns all marks in the order (DFS) they are rendered
|
|
67
|
-
* @param {View} root
|
|
68
|
-
*/
|
|
69
|
-
export function getMarks(root) {
|
|
70
|
-
return getFlattenedViews(root)
|
|
71
|
-
.filter((view) => view instanceof UnitView)
|
|
72
|
-
.map((view) => /** @type {UnitView} */ (view).mark);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Returns the nodes of the view hierarchy in depth-first order.
|
|
77
|
-
*
|
|
78
|
-
* @param {View} root
|
|
79
|
-
*/
|
|
80
|
-
export function getFlattenedViews(root) {
|
|
81
|
-
/** @type {View[]} */
|
|
82
|
-
const views = [];
|
|
83
|
-
root.visit((view) => {
|
|
84
|
-
views.push(view);
|
|
85
|
-
});
|
|
86
|
-
return views;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* @param {View} root
|
|
91
|
-
*/
|
|
92
|
-
export function resolveScalesAndAxes(root) {
|
|
93
|
-
root.visit((view) => {
|
|
94
|
-
if (view instanceof UnitView) {
|
|
95
|
-
view.resolve("scale");
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
// Check that each scale resolution has a unique name
|
|
100
|
-
/** @type {Set<string>} */
|
|
101
|
-
const scaleNames = new Set();
|
|
102
|
-
root.visit((view) => {
|
|
103
|
-
for (const resolution of Object.values(view.resolutions.scale)) {
|
|
104
|
-
const name = resolution.name;
|
|
105
|
-
if (name && scaleNames.has(name)) {
|
|
106
|
-
throw new Error(
|
|
107
|
-
`The same scale name "${name}" occurs in multiple scale resolutions!`
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
scaleNames.add(name);
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
root.visit((view) => {
|
|
115
|
-
if (view instanceof UnitView) {
|
|
116
|
-
view.resolve("axis");
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
root.visit((view) => view.onScalesResolved());
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Gives names to zoomable scales that have been pulled to the root. This allows
|
|
124
|
-
* the zoomed domains to be bookmarked without explicitly specifying the names.
|
|
125
|
-
* This only affects the trivial but common cases, e.g., a genome-browser-like
|
|
126
|
-
* view with a shared x scale.
|
|
127
|
-
*
|
|
128
|
-
* @param {View} root
|
|
129
|
-
*/
|
|
130
|
-
export function setImplicitScaleNames(root) {
|
|
131
|
-
for (const channel of primaryPositionalChannels) {
|
|
132
|
-
const resolution = root.getScaleResolution(channel);
|
|
133
|
-
if (resolution && !resolution.name && resolution.isZoomable()) {
|
|
134
|
-
// TODO: Should actually check that the name is not already reserved
|
|
135
|
-
resolution.name = `${channel}_at_root`;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* @param {View} root
|
|
142
|
-
* @param {import("../data/dataFlow").default<View>} [existingFlow] Add data flow
|
|
143
|
-
* graphs to an existing DataFlow object.
|
|
144
|
-
*/
|
|
145
|
-
export async function initializeData(root, existingFlow) {
|
|
146
|
-
const flow = buildDataFlow(root, existingFlow);
|
|
147
|
-
optimizeDataFlow(flow);
|
|
148
|
-
flow.initialize();
|
|
149
|
-
|
|
150
|
-
/** @type {Promise<void>[]} */
|
|
151
|
-
const promises = flow.dataSources.map((dataSource) => dataSource.load());
|
|
152
|
-
|
|
153
|
-
await Promise.all(promises);
|
|
154
|
-
|
|
155
|
-
return flow;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
*
|
|
160
|
-
* @param {View} view
|
|
161
|
-
*/
|
|
162
|
-
export function findEncodedFields(view) {
|
|
163
|
-
/** @type {{view: UnitView, channel: import("../spec/channel").Channel, field: import("../spec/channel").Field, type: import("../spec/channel").Type}[]} */
|
|
164
|
-
const fieldInfos = [];
|
|
165
|
-
|
|
166
|
-
view.visit((view) => {
|
|
167
|
-
if (view instanceof UnitView) {
|
|
168
|
-
const encoding = view.getEncoding();
|
|
169
|
-
for (const [channel, def] of Object.entries(encoding)) {
|
|
170
|
-
if (isFieldDef(def) && "type" in def) {
|
|
171
|
-
fieldInfos.push({
|
|
172
|
-
view,
|
|
173
|
-
channel,
|
|
174
|
-
field: def.field,
|
|
175
|
-
type: def.type,
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
return VISIT_SKIP; // Skip sample summaries
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
return fieldInfos;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* @param {import("../spec/view").ImportSpec} spec
|
|
188
|
-
* @param {string} baseUrl
|
|
189
|
-
* @param {ViewContext} viewContext
|
|
190
|
-
*/
|
|
191
|
-
async function loadExternalViewSpec(spec, baseUrl, viewContext) {
|
|
192
|
-
if (!spec.import.url) {
|
|
193
|
-
throw new Error(
|
|
194
|
-
"Cannot import, not an import spec: " + JSON.stringify(spec)
|
|
195
|
-
);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const loader = vegaLoader({ baseURL: baseUrl });
|
|
199
|
-
const url = spec.import.url;
|
|
200
|
-
|
|
201
|
-
const importedSpec = JSON.parse(
|
|
202
|
-
await loader.load(url).catch((/** @type {Error} */ e) => {
|
|
203
|
-
throw new Error(
|
|
204
|
-
`Could not load imported view spec: ${url} \nReason: ${e.message}`
|
|
205
|
-
);
|
|
206
|
-
})
|
|
207
|
-
);
|
|
208
|
-
|
|
209
|
-
if (viewContext.isViewSpec(importedSpec)) {
|
|
210
|
-
importedSpec.baseUrl = url.match(/^[^?#]*\//)?.[0];
|
|
211
|
-
return importedSpec;
|
|
212
|
-
} else {
|
|
213
|
-
throw new Error(
|
|
214
|
-
`The imported spec "${url}" is not a view spec: ${JSON.stringify(
|
|
215
|
-
spec
|
|
216
|
-
)}`
|
|
217
|
-
);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* @param {import("./view").default} viewRoot
|
|
223
|
-
*/
|
|
224
|
-
export async function processImports(viewRoot) {
|
|
225
|
-
/** @type {ImportView[]} */
|
|
226
|
-
const importViews = [];
|
|
227
|
-
|
|
228
|
-
viewRoot.visit((view) => {
|
|
229
|
-
if (view instanceof ImportView) {
|
|
230
|
-
importViews.push(view);
|
|
231
|
-
return VISIT_SKIP;
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
for (const view of importViews) {
|
|
236
|
-
const context = view.context;
|
|
237
|
-
|
|
238
|
-
// TODO: Parallelize using promises, don't use await
|
|
239
|
-
const loadedSpec = await loadExternalViewSpec(
|
|
240
|
-
view.spec,
|
|
241
|
-
view.getBaseUrl(),
|
|
242
|
-
context
|
|
243
|
-
);
|
|
244
|
-
|
|
245
|
-
// TODO: Let importSpec have a name
|
|
246
|
-
const importedView = context.createView(
|
|
247
|
-
loadedSpec,
|
|
248
|
-
view.parent,
|
|
249
|
-
view.name
|
|
250
|
-
);
|
|
251
|
-
view.parent.replaceChild(view, importedView);
|
|
252
|
-
|
|
253
|
-
// Import recursively
|
|
254
|
-
await processImports(importedView);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* @param {function(View, View[]):void} visitor
|
|
260
|
-
*/
|
|
261
|
-
export function stackifyVisitor(visitor) {
|
|
262
|
-
/** @type {View[]} */
|
|
263
|
-
const stack = [];
|
|
264
|
-
|
|
265
|
-
/** @type {import("./view").Visitor} */
|
|
266
|
-
const stackified = (view) => visitor(view, stack);
|
|
267
|
-
|
|
268
|
-
stackified.beforeChildren = (view) => {
|
|
269
|
-
stack.push(view);
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
stackified.afterChildren = (view) => {
|
|
273
|
-
stack.pop();
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
return stackified;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Finds the descendants having the given name. The root is included in the search.
|
|
281
|
-
*
|
|
282
|
-
* @param {View} root
|
|
283
|
-
* @param {string} name View name
|
|
284
|
-
* @returns {View[]}
|
|
285
|
-
*/
|
|
286
|
-
export function findDescendantsByPath(root, name) {
|
|
287
|
-
/** @type {View[]} */
|
|
288
|
-
const descendants = [];
|
|
289
|
-
|
|
290
|
-
root.visit((view) => {
|
|
291
|
-
if (view.name == name) {
|
|
292
|
-
descendants.push(view);
|
|
293
|
-
}
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
return descendants;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
*
|
|
301
|
-
* @param {View} root
|
|
302
|
-
*/
|
|
303
|
-
export function findUniqueViewNames(root) {
|
|
304
|
-
/** @type {View[]} */
|
|
305
|
-
const descendants = [];
|
|
306
|
-
|
|
307
|
-
root.visit((view) => {
|
|
308
|
-
descendants.push(view);
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
return new Set(
|
|
312
|
-
[
|
|
313
|
-
...rollup(
|
|
314
|
-
descendants,
|
|
315
|
-
(views) => views.length,
|
|
316
|
-
(view) => view.name
|
|
317
|
-
),
|
|
318
|
-
]
|
|
319
|
-
.filter(([name, count]) => count == 1 && name !== undefined)
|
|
320
|
-
.map(([name, count]) => name)
|
|
321
|
-
);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* @param {string} name
|
|
326
|
-
*/
|
|
327
|
-
export const isCustomViewName = (name) => !/^(layer|concat)\d+$/.test(name);
|
package/src/view/zoom.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef {object} ZoomEvent
|
|
3
|
-
* @prop {number} x
|
|
4
|
-
* @prop {number} y
|
|
5
|
-
* @prop {number} xDelta
|
|
6
|
-
* @prop {number} yDelta
|
|
7
|
-
* @prop {number} zDelta
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @param {import("../utils/interactionEvent").default} event
|
|
12
|
-
* @param {import("./renderingContext/layoutRecorderViewRenderingContext").Rectangle} coords The plot area
|
|
13
|
-
* @param {(zoomEvent: ZoomEvent) => void} handleZoom
|
|
14
|
-
* @param {import("./viewContext").Hover} [hover]
|
|
15
|
-
*/
|
|
16
|
-
export default function interactionToZoom(event, coords, handleZoom, hover) {
|
|
17
|
-
if (event.type == "wheel") {
|
|
18
|
-
event.uiEvent.preventDefault(); // TODO: Only if there was something zoomable
|
|
19
|
-
|
|
20
|
-
const wheelEvent = /** @type {WheelEvent} */ (event.uiEvent);
|
|
21
|
-
const wheelMultiplier = wheelEvent.deltaMode ? 120 : 1;
|
|
22
|
-
|
|
23
|
-
let { x, y } = event.point;
|
|
24
|
-
|
|
25
|
-
// Snapping to the hovered item:
|
|
26
|
-
// We find the currently hovered object and move the pointed coordinates
|
|
27
|
-
// to its center if the mark has only primary positional channels.
|
|
28
|
-
// This allows the user to rapidly zoom closer without having to
|
|
29
|
-
// continuously adjust the cursor position.
|
|
30
|
-
|
|
31
|
-
if (hover) {
|
|
32
|
-
const e = hover.mark.encoders;
|
|
33
|
-
if (e.x && !e.x2) {
|
|
34
|
-
x = +e.x(hover.datum) * coords.width + coords.x;
|
|
35
|
-
}
|
|
36
|
-
if (e.y && !e.y2) {
|
|
37
|
-
y = (1 - +e.y(hover.datum)) * coords.height + coords.y;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (Math.abs(wheelEvent.deltaX) < Math.abs(wheelEvent.deltaY)) {
|
|
42
|
-
handleZoom({
|
|
43
|
-
x,
|
|
44
|
-
y,
|
|
45
|
-
xDelta: 0,
|
|
46
|
-
yDelta: 0,
|
|
47
|
-
zDelta: (wheelEvent.deltaY * wheelMultiplier) / 300,
|
|
48
|
-
});
|
|
49
|
-
} else {
|
|
50
|
-
handleZoom({
|
|
51
|
-
x,
|
|
52
|
-
y,
|
|
53
|
-
xDelta: -wheelEvent.deltaX * wheelMultiplier,
|
|
54
|
-
yDelta: 0,
|
|
55
|
-
zDelta: 0,
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
} else if (
|
|
59
|
-
event.type == "mousedown" &&
|
|
60
|
-
/** @type {MouseEvent} */ (event.uiEvent).button === 0
|
|
61
|
-
) {
|
|
62
|
-
const mouseEvent = /** @type {MouseEvent} */ (event.uiEvent);
|
|
63
|
-
mouseEvent.preventDefault();
|
|
64
|
-
|
|
65
|
-
let prevMouseEvent = mouseEvent;
|
|
66
|
-
|
|
67
|
-
const onMousemove = /** @param {MouseEvent} moveEvent */ (
|
|
68
|
-
moveEvent
|
|
69
|
-
) => {
|
|
70
|
-
handleZoom({
|
|
71
|
-
x: prevMouseEvent.clientX,
|
|
72
|
-
y: prevMouseEvent.clientY,
|
|
73
|
-
xDelta: moveEvent.clientX - prevMouseEvent.clientX,
|
|
74
|
-
yDelta: moveEvent.clientY - prevMouseEvent.clientY,
|
|
75
|
-
zDelta: 0,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
prevMouseEvent = moveEvent;
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
const onMouseup = /** @param {MouseEvent} upEvent */ (upEvent) => {
|
|
82
|
-
document.removeEventListener("mousemove", onMousemove);
|
|
83
|
-
document.removeEventListener("mouseup", onMouseup);
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
document.addEventListener("mouseup", onMouseup, false);
|
|
87
|
-
document.addEventListener("mousemove", onMousemove, false);
|
|
88
|
-
}
|
|
89
|
-
}
|