higlass 1.13.2 → 1.13.4
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/README.md +0 -2
- package/app/globals.d.ts +4 -4
- package/app/missing-types.d.ts +3 -3
- package/app/scripts/AddTrackDialog.jsx +1 -0
- package/app/scripts/AddTrackPositionMenu.jsx +17 -4
- package/app/scripts/Annotations1dTrack.js +1 -0
- package/app/scripts/Annotations2dTrack.js +1 -0
- package/app/scripts/ArrowheadDomainsTrack.js +1 -0
- package/app/scripts/Autocomplete.jsx +1 -0
- package/app/scripts/AxisPixi.js +1 -0
- package/app/scripts/BarTrack.js +1 -0
- package/app/scripts/BedLikeTrack.js +1 -0
- package/app/scripts/Button.jsx +1 -0
- package/app/scripts/CNVIntervalTrack.js +1 -0
- package/app/scripts/CenterTiledPlot.jsx +1 -0
- package/app/scripts/CenterTrack.jsx +1 -0
- package/app/scripts/Chromosome2DAnnotations.js +1 -0
- package/app/scripts/Chromosome2DLabels.js +1 -0
- package/app/scripts/ChromosomeGrid.js +1 -0
- package/app/scripts/ChromosomeInfo.js +1 -0
- package/app/scripts/CloseTrackMenu.jsx +1 -0
- package/app/scripts/CombinedTrack.js +1 -0
- package/app/scripts/ConfigTrackMenu.jsx +1 -0
- package/app/scripts/ConfigViewMenu.jsx +1 -0
- package/app/scripts/ConfigureSeriesMenu.jsx +1 -0
- package/app/scripts/ContextMenuContainer.jsx +1 -0
- package/app/scripts/ContextMenuItem.jsx +1 -0
- package/app/scripts/Cross.jsx +1 -0
- package/app/scripts/CrossRule.js +1 -0
- package/app/scripts/CustomTrackDialog.jsx +1 -0
- package/app/scripts/Dialog.jsx +1 -0
- package/app/scripts/DivergentBarTrack.js +1 -0
- package/app/scripts/DragListeningDiv.jsx +1 -0
- package/app/scripts/DraggableDiv.jsx +1 -0
- package/app/scripts/ExportLinkDialog.jsx +1 -0
- package/app/scripts/FixedTrack.jsx +1 -0
- package/app/scripts/GalleryTracks.jsx +1 -0
- package/app/scripts/GenomePositionSearchBox.jsx +1 -0
- package/app/scripts/HeatmapOptions.jsx +1 -0
- package/app/scripts/HeatmapTiledPixiTrack.js +1 -0
- package/app/scripts/HiGlassComponent.jsx +1 -0
- package/app/scripts/HiGlassTrackComponent.jsx +1 -0
- package/app/scripts/Horizontal1dHeatmapTrack.js +1 -0
- package/app/scripts/Horizontal2DDomainsTrack.js +1 -0
- package/app/scripts/HorizontalChromosomeLabels.js +1 -0
- package/app/scripts/HorizontalGeneAnnotationsTrack.js +1 -0
- package/app/scripts/HorizontalHeatmapTrack.js +1 -0
- package/app/scripts/HorizontalItem.jsx +1 -0
- package/app/scripts/HorizontalLine1DPixiTrack.js +1 -0
- package/app/scripts/HorizontalMultivecTrack.js +1 -0
- package/app/scripts/HorizontalPoint1DPixiTrack.js +1 -0
- package/app/scripts/HorizontalRule.js +1 -0
- package/app/scripts/HorizontalTiled1DPixiTrack.js +1 -0
- package/app/scripts/HorizontalTiledPlot.jsx +1 -0
- package/app/scripts/HorizontalTrack.jsx +1 -0
- package/app/scripts/Id2DTiledPixiTrack.js +1 -0
- package/app/scripts/IdHorizontal1DTiledPixiTrack.js +1 -0
- package/app/scripts/IdVertical1DTiledPixiTrack.js +1 -0
- package/app/scripts/LeftAxisTrack.js +1 -0
- package/app/scripts/LeftTrackModifier.js +1 -0
- package/app/scripts/ListWrapper.jsx +1 -0
- package/app/scripts/MapboxTilesTrack.js +1 -0
- package/app/scripts/Modal.jsx +1 -0
- package/app/scripts/MoveableTrack.jsx +1 -0
- package/app/scripts/NestedContextMenu.jsx +1 -0
- package/app/scripts/OSMTileIdsTrack.js +1 -0
- package/app/scripts/OSMTilesTrack.js +1 -0
- package/app/scripts/OverlayTrack.js +1 -0
- package/app/scripts/PixiTrack.js +0 -1
- package/app/scripts/PlotTypeChooser.jsx +1 -0
- package/app/scripts/PopupMenu.jsx +1 -0
- package/app/scripts/RasterTilesTrack.js +1 -0
- package/app/scripts/RuleMixin.js +1 -0
- package/app/scripts/SVGTrack.js +1 -0
- package/app/scripts/SearchField.js +1 -0
- package/app/scripts/SeriesListItems.jsx +1 -0
- package/app/scripts/SeriesListMenu.jsx +1 -0
- package/app/scripts/SeriesListSubmenuMixin.jsx +1 -0
- package/app/scripts/SketchInlinePicker.jsx +1 -0
- package/app/scripts/SortableList.jsx +1 -0
- package/app/scripts/SquareMarkersTrack.js +1 -0
- package/app/scripts/Tiled1DPixiTrack.js +1 -0
- package/app/scripts/TiledPixiTrack.js +1 -0
- package/app/scripts/TiledPlot.jsx +9 -0
- package/app/scripts/TilesetFinder.jsx +1 -0
- package/app/scripts/TopAxisTrack.js +1 -0
- package/app/scripts/Track.js +0 -1
- package/app/scripts/TrackArea.jsx +1 -0
- package/app/scripts/TrackControl.jsx +1 -0
- package/app/scripts/TrackRenderer.jsx +0 -1
- package/app/scripts/UnknownPixiTrack.js +1 -0
- package/app/scripts/ValueIntervalTrack.js +1 -0
- package/app/scripts/VerticalItem.jsx +1 -0
- package/app/scripts/VerticalRule.js +1 -0
- package/app/scripts/VerticalTiled1DPixiTrack.js +1 -0
- package/app/scripts/VerticalTiledPlot.jsx +1 -0
- package/app/scripts/VerticalTrack.jsx +1 -0
- package/app/scripts/ViewConfigEditor.jsx +1 -0
- package/app/scripts/ViewContextMenu.jsx +1 -0
- package/app/scripts/ViewHeader.jsx +1 -0
- package/app/scripts/ViewportTracker2D.js +1 -0
- package/app/scripts/ViewportTracker2DPixi.js +1 -0
- package/app/scripts/ViewportTrackerHorizontal.js +1 -0
- package/app/scripts/ViewportTrackerVertical.js +1 -0
- package/app/scripts/api.js +1 -0
- package/app/scripts/configs/available-track-types.js +1 -0
- package/app/scripts/configs/colormaps.js +1 -0
- package/app/scripts/configs/datatype-to-track-type.js +1 -0
- package/app/scripts/configs/default-tracks-for-datatype.js +0 -1
- package/app/scripts/configs/dense-data-extrema-config.js +1 -0
- package/app/scripts/configs/globals.js +1 -0
- package/app/scripts/configs/index.js +1 -0
- package/app/scripts/configs/positions-by-datatype.js +1 -0
- package/app/scripts/configs/primitives.js +0 -1
- package/app/scripts/configs/themes.js +1 -0
- package/app/scripts/configs/tracks-info-by-type.js +0 -1
- package/app/scripts/configs/tracks-info.js +0 -1
- package/app/scripts/d3-context-menu.js +1 -0
- package/app/scripts/data-fetchers/DataFetcher.js +193 -153
- package/app/scripts/data-fetchers/genbank-fetcher.js +205 -87
- package/app/scripts/data-fetchers/index.js +1 -0
- package/app/scripts/data-fetchers/local-tile-fetcher.js +37 -4
- package/app/scripts/hglib.jsx +1 -0
- package/app/scripts/hocs/with-modal.jsx +1 -0
- package/app/scripts/hocs/with-pub-sub.jsx +1 -0
- package/app/scripts/hocs/with-theme.jsx +1 -0
- package/app/scripts/icons.jsx +1 -0
- package/app/scripts/mixwith.js +1 -0
- package/app/scripts/options-info.js +1 -0
- package/app/scripts/plugins/available-for-plugins.js +1 -0
- package/app/scripts/plugins/get-data-fetcher.js +1 -0
- package/app/scripts/plugins/index.js +1 -0
- package/app/scripts/services/chrom-info.js +1 -0
- package/app/scripts/services/dom-event.js +1 -0
- package/app/scripts/services/element-resize-listener.js +1 -0
- package/app/scripts/services/index.js +1 -0
- package/app/scripts/services/tile-proxy.js +14 -10
- package/app/scripts/services/worker.js +161 -84
- package/app/scripts/symbol.js +1 -0
- package/app/scripts/test-helpers/index.js +1 -0
- package/app/scripts/test-helpers/test-helpers.jsx +1 -0
- package/app/scripts/track-utils.js +1 -0
- package/app/scripts/types.ts +59 -22
- package/app/scripts/utils/DenseDataExtrema1D.js +32 -19
- package/app/scripts/utils/DenseDataExtrema2D.js +51 -31
- package/app/scripts/utils/LruCache.js +1 -0
- package/app/scripts/utils/abs-to-chr.js +0 -1
- package/app/scripts/utils/accessor-transposition.js +0 -2
- package/app/scripts/utils/add-arrays.js +0 -2
- package/app/scripts/utils/add-class.js +0 -1
- package/app/scripts/utils/add-event-listener-once.js +0 -2
- package/app/scripts/utils/background-task-scheduler.js +0 -2
- package/app/scripts/utils/base64-to-canvas.js +0 -2
- package/app/scripts/utils/chr-to-abs.js +0 -2
- package/app/scripts/utils/chrom-info-bisector.js +0 -1
- package/app/scripts/utils/clone-event.js +0 -2
- package/app/scripts/utils/color-domain-to-rgba-array.js +1 -0
- package/app/scripts/utils/color-to-hex.js +0 -1
- package/app/scripts/utils/color-to-rgba.js +0 -1
- package/app/scripts/utils/data-to-genomic-loci.js +0 -1
- package/app/scripts/utils/debounce.js +0 -2
- package/app/scripts/utils/dec-to-hex-str.js +0 -1
- package/app/scripts/utils/dict-from-tuples.js +0 -2
- package/app/scripts/utils/dict-items.js +0 -2
- package/app/scripts/utils/dict-keys.js +0 -2
- package/app/scripts/utils/dict-values.js +0 -2
- package/app/scripts/utils/download.js +0 -2
- package/app/scripts/utils/expand-combined-tracks.js +1 -0
- package/app/scripts/utils/fill-in-min-widths.js +1 -0
- package/app/scripts/utils/flatten.js +1 -0
- package/app/scripts/utils/for-each.js +0 -1
- package/app/scripts/utils/forward-event.js +0 -1
- package/app/scripts/utils/genome-loci-to-pixels.js +0 -1
- package/app/scripts/utils/genomic-range-to-chromosome-chunks.js +0 -2
- package/app/scripts/utils/get-aggregation-function.js +6 -12
- package/app/scripts/utils/get-default-track-for-datatype.js +1 -0
- package/app/scripts/utils/get-element-dim.js +0 -1
- package/app/scripts/utils/get-higlass-components.js +1 -0
- package/app/scripts/utils/get-track-by-uid.js +1 -0
- package/app/scripts/utils/get-track-conf-from-hgc.js +1 -0
- package/app/scripts/utils/get-track-obj-by-id.js +1 -0
- package/app/scripts/utils/get-track-position-by-uid.js +1 -0
- package/app/scripts/utils/get-xylofon.js +1 -0
- package/app/scripts/utils/gradient.js +0 -2
- package/app/scripts/utils/has-class.js +0 -2
- package/app/scripts/utils/has-parent.js +1 -0
- package/app/scripts/utils/hex-string-to-int.js +0 -1
- package/app/scripts/utils/index.js +0 -1
- package/app/scripts/utils/interval-tree.js +1 -0
- package/app/scripts/utils/into-the-void.js +0 -1
- package/app/scripts/utils/is-track-or-child-track.js +0 -1
- package/app/scripts/utils/is-track-range-selectable.js +0 -1
- package/app/scripts/utils/is-within.js +0 -2
- package/app/scripts/utils/lat-to-y.js +0 -2
- package/app/scripts/utils/lng-to-x.js +0 -1
- package/app/scripts/utils/load-chrom-infos.js +1 -0
- package/app/scripts/utils/map.js +0 -1
- package/app/scripts/utils/max-non-zero.js +0 -1
- package/app/scripts/utils/max.js +0 -1
- package/app/scripts/utils/min-non-zero.js +0 -1
- package/app/scripts/utils/min.js +0 -1
- package/app/scripts/utils/mod.js +0 -1
- package/app/scripts/utils/ndarray-assign.js +1 -0
- package/app/scripts/utils/ndarray-flatten.js +1 -0
- package/app/scripts/utils/ndarray-to-list.js +1 -0
- package/app/scripts/utils/numericify-version.js +0 -1
- package/app/scripts/utils/obj-vals.js +1 -0
- package/app/scripts/utils/or.js +0 -1
- package/app/scripts/utils/parse-chromsizes-rows.js +0 -2
- package/app/scripts/utils/pixi-text-to-svg.js +1 -0
- package/app/scripts/utils/q.js +1 -0
- package/app/scripts/utils/rad-to-deg.js +0 -1
- package/app/scripts/utils/range-query-2d.js +1 -0
- package/app/scripts/utils/reduce.js +1 -0
- package/app/scripts/utils/rel-to-abs-chrom-pos.js +0 -2
- package/app/scripts/utils/remove-class.js +0 -1
- package/app/scripts/utils/reset-d3-brush-style.js +0 -2
- package/app/scripts/utils/rgb-to-hex.js +0 -2
- package/app/scripts/utils/scales-center-and-k.js +0 -2
- package/app/scripts/utils/scales-to-genome-loci.js +0 -1
- package/app/scripts/utils/segments-to-rows.js +1 -0
- package/app/scripts/utils/selected-items-to-cum-weights.js +0 -1
- package/app/scripts/utils/selected-items-to-size.js +0 -1
- package/app/scripts/utils/show-mouse-position.js +0 -1
- package/app/scripts/utils/some.js +0 -1
- package/app/scripts/utils/sum.js +0 -1
- package/app/scripts/utils/svg-line.js +1 -0
- package/app/scripts/utils/throttle-and-debounce.js +0 -1
- package/app/scripts/utils/tile-to-canvas.js +0 -1
- package/app/scripts/utils/timeout.js +0 -1
- package/app/scripts/utils/to-void.js +0 -1
- package/app/scripts/utils/total-track-pixel-height.js +0 -1
- package/app/scripts/utils/trim-trailing-slash.js +0 -1
- package/app/scripts/utils/type-guards.js +0 -2
- package/app/scripts/utils/value-to-color.js +0 -1
- package/app/scripts/utils/visit-positioned-tracks.js +0 -1
- package/app/scripts/utils/visit-tracks.js +0 -1
- package/dist/esm.html +13 -14
- package/dist/hglib.css +1 -1724
- package/dist/hglib.js +122664 -28
- package/dist/hglib.min.js +116 -119
- package/dist/higlass.mjs +122646 -28
- package/dist/index.html +5 -6
- package/package.json +23 -16
|
@@ -12,11 +12,55 @@ import {
|
|
|
12
12
|
// Services
|
|
13
13
|
import { tileProxy } from '../services';
|
|
14
14
|
|
|
15
|
+
/** @typedef {import('../types').DataConfig} DataConfig */
|
|
16
|
+
/** @typedef {import('../types').TilesetInfo} TilesetInfo */
|
|
17
|
+
/**
|
|
18
|
+
* @template T
|
|
19
|
+
* @typedef {import('../types').AbstractDataFetcher<T>} AbstractDataFetcher
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @typedef Tile
|
|
24
|
+
* @property {number} min_value
|
|
25
|
+
* @property {number} max_value
|
|
26
|
+
* @property {DenseDataExtrema1D | DenseDataExtrema2D} denseDataExtrema
|
|
27
|
+
* @property {number} minNonZero
|
|
28
|
+
* @property {number} maxNonZero
|
|
29
|
+
* @property {Array<number> | Float32Array} dense
|
|
30
|
+
* @property {string} dtype
|
|
31
|
+
* @property {string} server
|
|
32
|
+
* @property {number[]} tilePos
|
|
33
|
+
* @property {string} tilePositionId
|
|
34
|
+
* @property {string} tilesetUid
|
|
35
|
+
* @property {number} zoomLevel
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/** @typedef {Pick<Tile, 'zoomLevel' | 'tilePos' | 'tilePositionId'>} DividedTileA */
|
|
39
|
+
/** @typedef {Pick<Tile, 'zoomLevel' | 'tilePos' | 'tilePositionId' | 'dense' | 'denseDataExtrema' | 'minNonZero' | 'maxNonZero'>} DividedTileB */
|
|
40
|
+
/** @typedef {DividedTileA | DividedTileB} DividedTile */
|
|
41
|
+
/** @typedef {Omit<DataConfig, 'children'> & { children?: DataFetcher[], tilesetUid?: string, tilesetInfo: TilesetInfo }} ResolvedDataConfig */
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @template T
|
|
45
|
+
* @param {Array<T>} x
|
|
46
|
+
* @returns {x is [T, T]}
|
|
47
|
+
*/
|
|
48
|
+
function isTuple(x) {
|
|
49
|
+
return x.length === 2;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** @implements {AbstractDataFetcher<Tile | DividedTile>} */
|
|
15
53
|
export default class DataFetcher {
|
|
54
|
+
/**
|
|
55
|
+
* @param {import('../types').DataConfig} dataConfig
|
|
56
|
+
* @param {import('pub-sub-es').PubSub} pubSub
|
|
57
|
+
*/
|
|
16
58
|
constructor(dataConfig, pubSub) {
|
|
59
|
+
/** @type {boolean} */
|
|
17
60
|
this.tilesetInfoLoading = true;
|
|
18
61
|
|
|
19
62
|
if (!dataConfig) {
|
|
63
|
+
// Trevor: This should probably throw?
|
|
20
64
|
console.error('No dataconfig provided');
|
|
21
65
|
return;
|
|
22
66
|
}
|
|
@@ -24,11 +68,14 @@ export default class DataFetcher {
|
|
|
24
68
|
// copy the dataConfig so that it doesn't dirty so that
|
|
25
69
|
// it doesn't get modified when we make objects of its
|
|
26
70
|
// children below
|
|
71
|
+
/** @type {ResolvedDataConfig} */
|
|
27
72
|
this.dataConfig = JSON.parse(JSON.stringify(dataConfig));
|
|
73
|
+
/** @type {string} */
|
|
28
74
|
this.uuid = slugid.nice();
|
|
75
|
+
/** @type {import('pub-sub-es').PubSub} */
|
|
29
76
|
this.pubSub = pubSub;
|
|
30
77
|
|
|
31
|
-
if (
|
|
78
|
+
if (dataConfig.children) {
|
|
32
79
|
// convert each child into an object
|
|
33
80
|
this.dataConfig.children = dataConfig.children.map(
|
|
34
81
|
(c) => new DataFetcher(c, pubSub),
|
|
@@ -41,10 +88,11 @@ export default class DataFetcher {
|
|
|
41
88
|
* and server. Using these, we can use the server to fullfill tile requests
|
|
42
89
|
* from this dataset.
|
|
43
90
|
*
|
|
44
|
-
* @param {
|
|
45
|
-
* @param {string}
|
|
46
|
-
* @param {string}
|
|
47
|
-
* @param {string}
|
|
91
|
+
* @param {object} opts
|
|
92
|
+
* @param {string} opts.server - The server api location (e.g. 'localhost:8000/api/v1')
|
|
93
|
+
* @param {string} opts.url - The location of the data file (e.g. 'encode.org/my.file.bigwig')
|
|
94
|
+
* @param {string} opts.filetype - The type of file being served (e.g. 'bigwig')
|
|
95
|
+
* @param {string=} opts.coordSystem - The coordinate system being served (e.g. 'hg38')
|
|
48
96
|
*/
|
|
49
97
|
async registerFileUrl({ server, url, filetype, coordSystem }) {
|
|
50
98
|
const serverUrl = `${tts(server)}/register_url/`;
|
|
@@ -64,15 +112,16 @@ export default class DataFetcher {
|
|
|
64
112
|
});
|
|
65
113
|
}
|
|
66
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Obtain tileset infos for all of the tilesets listed
|
|
117
|
+
* @param {import('../types').HandleTilesetInfoFinished} finished - A callback that will be called
|
|
118
|
+
*/
|
|
67
119
|
tilesetInfo(finished) {
|
|
68
120
|
// if this track has a url, server and filetype
|
|
69
121
|
// then we need to register those with the server
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
this.
|
|
73
|
-
this.dataConfig.filetype
|
|
74
|
-
) {
|
|
75
|
-
return this.registerFileUrl(this.dataConfig)
|
|
122
|
+
const { server, url, filetype, coordSystem } = this.dataConfig;
|
|
123
|
+
if (server && url && filetype) {
|
|
124
|
+
return this.registerFileUrl({ server, url, filetype, coordSystem })
|
|
76
125
|
.then((data) => data.json())
|
|
77
126
|
.then((data) => {
|
|
78
127
|
this.dataConfig.tilesetUid = data.uid;
|
|
@@ -96,18 +145,15 @@ export default class DataFetcher {
|
|
|
96
145
|
* infos have the same dimensions and then return a common
|
|
97
146
|
* one.
|
|
98
147
|
*
|
|
99
|
-
*
|
|
100
|
-
* ----------
|
|
101
|
-
* @param {function} finished A callback that will be called
|
|
148
|
+
* @param {import('../types').HandleTilesetInfoFinished} finished - A callback that will be called
|
|
102
149
|
* when all tileset infos are loaded
|
|
103
150
|
*/
|
|
104
|
-
tilesetInfoAfterRegister(finished
|
|
105
|
-
// console.log('dataConfig', this.dataConfig);
|
|
106
|
-
|
|
151
|
+
tilesetInfoAfterRegister(finished) {
|
|
107
152
|
if (!this.dataConfig.children) {
|
|
108
|
-
// this data source has no children so we
|
|
109
|
-
// info
|
|
110
|
-
|
|
153
|
+
// this data source has no children so we
|
|
154
|
+
// just need to retrieve one tileset info
|
|
155
|
+
const { server, tilesetUid } = this.dataConfig;
|
|
156
|
+
if (!server || !tilesetUid) {
|
|
111
157
|
console.warn(
|
|
112
158
|
'No dataConfig children, server or tilesetUid:',
|
|
113
159
|
this.dataConfig,
|
|
@@ -116,23 +162,17 @@ export default class DataFetcher {
|
|
|
116
162
|
} else {
|
|
117
163
|
// pass in the callback
|
|
118
164
|
tileProxy.trackInfo(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
(tilesetInfo) => {
|
|
165
|
+
server,
|
|
166
|
+
tilesetUid,
|
|
167
|
+
(/** @type {Record<string, TilesetInfo>} */ tilesetInfo) => {
|
|
122
168
|
// tileset infos are indxed by by tilesetUids, we can just resolve
|
|
123
169
|
// that here before passing it back to the track
|
|
124
|
-
this.dataConfig.tilesetInfo =
|
|
125
|
-
|
|
126
|
-
finished(
|
|
127
|
-
tilesetInfo[this.dataConfig.tilesetUid],
|
|
128
|
-
this.dataConfig.tilesetUid,
|
|
129
|
-
);
|
|
170
|
+
this.dataConfig.tilesetInfo = tilesetInfo[tilesetUid];
|
|
171
|
+
finished(tilesetInfo[tilesetUid], tilesetUid);
|
|
130
172
|
},
|
|
131
|
-
(error) => {
|
|
173
|
+
(/** @type {string} */ error) => {
|
|
132
174
|
this.tilesetInfoLoading = false;
|
|
133
|
-
finished({
|
|
134
|
-
error,
|
|
135
|
-
});
|
|
175
|
+
finished({ error });
|
|
136
176
|
},
|
|
137
177
|
this.pubSub,
|
|
138
178
|
);
|
|
@@ -142,6 +182,7 @@ export default class DataFetcher {
|
|
|
142
182
|
// all of their tileset infos in order to return them to the track
|
|
143
183
|
const promises = this.dataConfig.children.map(
|
|
144
184
|
(x) =>
|
|
185
|
+
/** @type {Promise<TilesetInfo>} */
|
|
145
186
|
new Promise((resolve) => {
|
|
146
187
|
x.tilesetInfo(resolve);
|
|
147
188
|
}),
|
|
@@ -155,50 +196,42 @@ export default class DataFetcher {
|
|
|
155
196
|
}
|
|
156
197
|
}
|
|
157
198
|
|
|
199
|
+
/**
|
|
200
|
+
* @param {string} tilesetUid - Uid of the tileset on the server
|
|
201
|
+
* @param {string} tileId - The tileId of the tile
|
|
202
|
+
* @returns {string} The full tile id that the server will parse.
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```javascript
|
|
206
|
+
* // returns 'xyxx.0.0.0'
|
|
207
|
+
* fullTileId('xyxx', '0.0.0');
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
158
210
|
fullTileId(tilesetUid, tileId) {
|
|
159
|
-
/**
|
|
160
|
-
* Convert a tilesetUid and tileId into a full tile
|
|
161
|
-
* identifier
|
|
162
|
-
*
|
|
163
|
-
* Parameters
|
|
164
|
-
* ----------
|
|
165
|
-
* tilesetUid: string
|
|
166
|
-
* Uid of the tileset on the server
|
|
167
|
-
*
|
|
168
|
-
* tileId: string
|
|
169
|
-
* The tileId of the tile
|
|
170
|
-
*
|
|
171
|
-
* Returns
|
|
172
|
-
* -------
|
|
173
|
-
* fullTileId: string
|
|
174
|
-
* The full tile id that the server will parse.
|
|
175
|
-
* E.g. xyxx.0.0.0.default
|
|
176
|
-
*/
|
|
177
|
-
|
|
178
211
|
return `${tilesetUid}.${tileId}`;
|
|
179
212
|
}
|
|
180
213
|
|
|
214
|
+
/**
|
|
215
|
+
* Fetch a set of tiles.
|
|
216
|
+
*
|
|
217
|
+
* Because the track shouldn't care about tileset ids, the tile ids
|
|
218
|
+
* should just include positions and any necessary transforms.
|
|
219
|
+
*
|
|
220
|
+
* @param {(tiles: Record<string, DividedTile | Tile>) => void} receivedTiles - A function to call once the tiles have been fetched
|
|
221
|
+
* @param {string[]} tileIds - The tile ids to fetch
|
|
222
|
+
* @returns {Promise<Record<string, DividedTile | Tile>>}
|
|
223
|
+
*/
|
|
181
224
|
fetchTilesDebounced(receivedTiles, tileIds) {
|
|
182
|
-
/**
|
|
183
|
-
* Fetch a set of tiles.
|
|
184
|
-
*
|
|
185
|
-
* Because the track shouldn't care about tileset ids, the tile ids
|
|
186
|
-
* should just include positions and any necessary transforms.
|
|
187
|
-
*
|
|
188
|
-
* Parameters
|
|
189
|
-
* ----------
|
|
190
|
-
* receivedTiles: callback
|
|
191
|
-
* A function to call once the tiles have been
|
|
192
|
-
* fetched
|
|
193
|
-
* tileIds: []
|
|
194
|
-
* The tile ids to fetch
|
|
195
|
-
*/
|
|
196
225
|
if (this.dataConfig.type === 'horizontal-section') {
|
|
197
|
-
this.fetchHorizontalSection(receivedTiles, tileIds);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
|
|
226
|
+
return this.fetchHorizontalSection(receivedTiles, tileIds);
|
|
227
|
+
}
|
|
228
|
+
if (this.dataConfig.type === 'vertical-section') {
|
|
229
|
+
return this.fetchHorizontalSection(receivedTiles, tileIds, true);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (!this.dataConfig.children && this.dataConfig.tilesetUid) {
|
|
201
233
|
// no children, just return the fetched tiles as is
|
|
234
|
+
/** @type {Promise<Record<string, Tile>>} */
|
|
202
235
|
const promise = new Promise((resolve) => {
|
|
203
236
|
tileProxy.fetchTilesDebounced(
|
|
204
237
|
{
|
|
@@ -213,8 +246,9 @@ export default class DataFetcher {
|
|
|
213
246
|
);
|
|
214
247
|
});
|
|
215
248
|
|
|
216
|
-
promise.then((returnedTiles) => {
|
|
249
|
+
return promise.then((returnedTiles) => {
|
|
217
250
|
const tilesetUid = dictValues(returnedTiles)[0].tilesetUid;
|
|
251
|
+
/** @type {Record<string, Tile>} */
|
|
218
252
|
const newTiles = {};
|
|
219
253
|
|
|
220
254
|
for (let i = 0; i < tileIds.length; i++) {
|
|
@@ -223,60 +257,50 @@ export default class DataFetcher {
|
|
|
223
257
|
returnedTiles[fullTileId].tilePositionId = tileIds[i];
|
|
224
258
|
newTiles[tileIds[i]] = returnedTiles[fullTileId];
|
|
225
259
|
}
|
|
226
|
-
|
|
227
260
|
receivedTiles(newTiles);
|
|
261
|
+
return newTiles;
|
|
228
262
|
});
|
|
229
|
-
}
|
|
230
|
-
// multiple child tracks, need to wait for all of them to
|
|
231
|
-
// fetch their data before returning to the parent
|
|
232
|
-
const promises = this.dataConfig.children.map(
|
|
233
|
-
(x) =>
|
|
234
|
-
new Promise(
|
|
235
|
-
(resolve) => {
|
|
236
|
-
x.fetchTilesDebounced(resolve, tileIds);
|
|
237
|
-
},
|
|
238
|
-
this.pubSub,
|
|
239
|
-
true,
|
|
240
|
-
),
|
|
241
|
-
);
|
|
242
|
-
|
|
243
|
-
Promise.all(promises).then((returnedTiles) => {
|
|
244
|
-
// if we're trying to divide two datasets,
|
|
245
|
-
if (this.dataConfig.type === 'divided') {
|
|
246
|
-
const newTiles = this.makeDivided(returnedTiles, tileIds);
|
|
263
|
+
}
|
|
247
264
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
265
|
+
// multiple child tracks, need to wait for all of them to
|
|
266
|
+
// fetch their data before returning to the parent
|
|
267
|
+
/** @type {Promise<Record<string, DividedTile | Tile>>[]} Tiles */
|
|
268
|
+
const promises =
|
|
269
|
+
this.dataConfig.children?.map(
|
|
270
|
+
(x) =>
|
|
271
|
+
/** @type {Promise<Record<string, Tile | DividedTile>>} */
|
|
272
|
+
new Promise((resolve) => {
|
|
273
|
+
x.fetchTilesDebounced(resolve, tileIds);
|
|
274
|
+
}),
|
|
275
|
+
) ?? [];
|
|
255
276
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
277
|
+
return Promise.all(promises).then((returnedTiles) => {
|
|
278
|
+
// if we're trying to divide two datasets,
|
|
279
|
+
if (this.dataConfig.type === 'divided' && isTuple(returnedTiles)) {
|
|
280
|
+
const newTiles = this.makeDivided(returnedTiles, tileIds);
|
|
281
|
+
receivedTiles(newTiles);
|
|
282
|
+
return newTiles;
|
|
283
|
+
}
|
|
284
|
+
// assume we're just returning raw tiles
|
|
285
|
+
console.warn(
|
|
286
|
+
'Unimplemented dataConfig type. Returning first data source.',
|
|
287
|
+
this.dataConfig,
|
|
288
|
+
);
|
|
289
|
+
receivedTiles(returnedTiles[0]);
|
|
290
|
+
return returnedTiles[0];
|
|
291
|
+
});
|
|
260
292
|
}
|
|
261
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Return an array consisting of the division of the numerator
|
|
296
|
+
* array by the denominator array
|
|
297
|
+
*
|
|
298
|
+
* @param {ArrayLike<number>} numeratorData - An array of numerical values
|
|
299
|
+
* @param {ArrayLike<number>} denominatorData - An array of numerical values
|
|
300
|
+
*
|
|
301
|
+
* @returns {Float32Array} An array consisting of the division of the numerator by the denominator
|
|
302
|
+
*/
|
|
262
303
|
divideData(numeratorData, denominatorData) {
|
|
263
|
-
/**
|
|
264
|
-
* Return an array consisting of the division of the numerator
|
|
265
|
-
* array by the denominator array
|
|
266
|
-
*
|
|
267
|
-
* Parameters
|
|
268
|
-
* ----------
|
|
269
|
-
* numeratorData: array
|
|
270
|
-
* An array of numerical values
|
|
271
|
-
* denominatorData:
|
|
272
|
-
* An array of numerical values
|
|
273
|
-
*
|
|
274
|
-
* Returns
|
|
275
|
-
* -------
|
|
276
|
-
* divided: array
|
|
277
|
-
* An array consisting of the division of the
|
|
278
|
-
* numerator by the denominator
|
|
279
|
-
*/
|
|
280
304
|
const result = new Float32Array(numeratorData.length);
|
|
281
305
|
|
|
282
306
|
for (let i = 0; i < result.length; i++) {
|
|
@@ -301,11 +325,12 @@ export default class DataFetcher {
|
|
|
301
325
|
/**
|
|
302
326
|
* Extract a slice from a matrix at a given position.
|
|
303
327
|
*
|
|
304
|
-
* @param {
|
|
305
|
-
* @param {
|
|
328
|
+
* @param {Array<number>} inputData - An array containing a matrix stored row-wise
|
|
329
|
+
* @param {Array<number>} arrayShape - The shape of the array, should be a
|
|
306
330
|
* two element array e.g. [256,256].
|
|
307
|
-
* @param {
|
|
308
|
-
* @
|
|
331
|
+
* @param {number} sliceIndex - The index across which to take the slice
|
|
332
|
+
* @param {number=} axis - The axis along which to take the slice
|
|
333
|
+
* @returns {Array<number>} an array corresponding to a slice of this matrix
|
|
309
334
|
*/
|
|
310
335
|
extractDataSlice(inputData, arrayShape, sliceIndex, axis) {
|
|
311
336
|
if (!axis) {
|
|
@@ -322,14 +347,28 @@ export default class DataFetcher {
|
|
|
322
347
|
return returnArray;
|
|
323
348
|
}
|
|
324
349
|
|
|
350
|
+
/**
|
|
351
|
+
* Fetch a horizontal section of a 2D dataset
|
|
352
|
+
* @param {(tiles: Record<string, Tile>) => void} receivedTiles - A function to call once the tiles have been fetched
|
|
353
|
+
* @param {string[]} tileIds - The tile ids to fetch
|
|
354
|
+
* @param {boolean=} vertical - Whether to fetch a vertical section
|
|
355
|
+
* @returns {Promise<Record<string, Tile>>}
|
|
356
|
+
*/
|
|
325
357
|
fetchHorizontalSection(receivedTiles, tileIds, vertical = false) {
|
|
326
358
|
// We want to take a horizontal section of a 2D dataset
|
|
327
359
|
// that means that a 1D track is requesting data from a 2D source
|
|
328
360
|
// because the 1D track only requests 1D tiles, we need to calculate
|
|
329
361
|
// the 2D tile from which to take the slice
|
|
362
|
+
/** @type {string[]} */
|
|
330
363
|
const newTileIds = [];
|
|
364
|
+
/** @type {boolean[]} */
|
|
331
365
|
const mirrored = [];
|
|
332
366
|
|
|
367
|
+
const { slicePos, tilesetInfo } = this.dataConfig;
|
|
368
|
+
if (!slicePos || !tilesetInfo) {
|
|
369
|
+
throw new Error('No slice position or tileset info');
|
|
370
|
+
}
|
|
371
|
+
|
|
333
372
|
for (const tileId of tileIds) {
|
|
334
373
|
const parts = tileId.split('.');
|
|
335
374
|
const zoomLevel = +parts[0];
|
|
@@ -338,37 +377,31 @@ export default class DataFetcher {
|
|
|
338
377
|
// this is a dummy scale that we'll use to fetch tile positions
|
|
339
378
|
// along the y-axis of the 2D dataset (we already have the x positions
|
|
340
379
|
// from the track that is querying this data)
|
|
341
|
-
const scale = scaleLinear().domain([
|
|
342
|
-
this.dataConfig.slicePos,
|
|
343
|
-
this.dataConfig.slicePos,
|
|
344
|
-
]);
|
|
380
|
+
const scale = scaleLinear().domain([slicePos, slicePos]);
|
|
345
381
|
|
|
346
382
|
// there's two different ways of calculating tile positions
|
|
347
383
|
// this needs to be consolidated into one function eventually
|
|
348
384
|
let yTiles = [];
|
|
349
385
|
|
|
350
|
-
if (
|
|
351
|
-
|
|
352
|
-
this.dataConfig.tilesetInfo.resolutions
|
|
353
|
-
) {
|
|
354
|
-
const sortedResolutions = this.dataConfig.tilesetInfo.resolutions
|
|
386
|
+
if ('resolutions' in tilesetInfo) {
|
|
387
|
+
const sortedResolutions = tilesetInfo.resolutions
|
|
355
388
|
.map((x) => +x)
|
|
356
389
|
.sort((a, b) => b - a);
|
|
357
390
|
|
|
358
391
|
yTiles = tileProxy.calculateTilesFromResolution(
|
|
359
392
|
sortedResolutions[zoomLevel],
|
|
360
393
|
scale,
|
|
361
|
-
|
|
362
|
-
|
|
394
|
+
tilesetInfo.min_pos[vertical ? 1 : 0],
|
|
395
|
+
tilesetInfo.max_pos[vertical ? 1 : 0],
|
|
363
396
|
);
|
|
364
397
|
} else {
|
|
365
398
|
yTiles = tileProxy.calculateTiles(
|
|
366
399
|
zoomLevel,
|
|
367
400
|
scale,
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
401
|
+
tilesetInfo.min_pos[vertical ? 1 : 0],
|
|
402
|
+
tilesetInfo.max_pos[vertical ? 1 : 0],
|
|
403
|
+
tilesetInfo.max_zoom,
|
|
404
|
+
tilesetInfo.max_width,
|
|
372
405
|
);
|
|
373
406
|
}
|
|
374
407
|
const sortedPosition = [xTilePos, yTiles[0]].sort((a, b) => a - b);
|
|
@@ -398,12 +431,13 @@ export default class DataFetcher {
|
|
|
398
431
|
true,
|
|
399
432
|
);
|
|
400
433
|
});
|
|
401
|
-
promise.then((returnedTiles) => {
|
|
434
|
+
return promise.then((returnedTiles) => {
|
|
402
435
|
// we've received some new tiles, but they're 2D
|
|
403
436
|
// we need to extract the row corresponding to the data we need
|
|
404
437
|
|
|
405
438
|
const tilesetUid = dictValues(returnedTiles)[0].tilesetUid;
|
|
406
439
|
// console.log('tilesetUid:', tilesetUid);
|
|
440
|
+
/** @type {Record<string, Tile>} */
|
|
407
441
|
const newTiles = {};
|
|
408
442
|
|
|
409
443
|
for (let i = 0; i < newTileIds.length; i++) {
|
|
@@ -413,11 +447,15 @@ export default class DataFetcher {
|
|
|
413
447
|
const yTilePos = +parts[2];
|
|
414
448
|
|
|
415
449
|
const sliceIndex = tileProxy.calculateTileAndPosInTile(
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
this
|
|
450
|
+
tilesetInfo,
|
|
451
|
+
// @ts-expect-error - This is undefined for legacy tilesets, but
|
|
452
|
+
// `calculateTileAndPosInTile` ignores this argument with `resolutions`.
|
|
453
|
+
// We should probably refactor `calculateTileAndPosInTile` to just take
|
|
454
|
+
// the `tilesetInfo` object.
|
|
455
|
+
tilesetInfo.max_width,
|
|
456
|
+
tilesetInfo.min_pos[1],
|
|
419
457
|
zoomLevel,
|
|
420
|
-
+
|
|
458
|
+
+slicePos,
|
|
421
459
|
)[1];
|
|
422
460
|
|
|
423
461
|
const fullTileId = this.fullTileId(tilesetUid, newTileIds[i]);
|
|
@@ -469,9 +507,16 @@ export default class DataFetcher {
|
|
|
469
507
|
}
|
|
470
508
|
|
|
471
509
|
receivedTiles(newTiles);
|
|
510
|
+
return newTiles;
|
|
472
511
|
});
|
|
473
512
|
}
|
|
474
513
|
|
|
514
|
+
/**
|
|
515
|
+
* @typedef {{ zoomLevel: number, tilePos: number[], dense?: ArrayLike<number> }} Dividable
|
|
516
|
+
* @param {[Record<string, Dividable>, Record<string, Dividable>]} returnedTiles
|
|
517
|
+
* @param {string[]} tileIds
|
|
518
|
+
* @returns {Record<string, DividedTile>}
|
|
519
|
+
*/
|
|
475
520
|
makeDivided(returnedTiles, tileIds) {
|
|
476
521
|
if (returnedTiles.length < 2) {
|
|
477
522
|
console.warn(
|
|
@@ -480,9 +525,7 @@ export default class DataFetcher {
|
|
|
480
525
|
);
|
|
481
526
|
}
|
|
482
527
|
|
|
483
|
-
|
|
484
|
-
// const denominatorTilesetUid = dictValues(returnedTiles[1])[0].tilesetUid;
|
|
485
|
-
|
|
528
|
+
/** @type {Record<string, DividedTile>} */
|
|
486
529
|
const newTiles = {};
|
|
487
530
|
|
|
488
531
|
for (let i = 0; i < tileIds.length; i++) {
|
|
@@ -491,21 +534,18 @@ export default class DataFetcher {
|
|
|
491
534
|
const zoomLevel = returnedTiles[0][tileIds[i]].zoomLevel;
|
|
492
535
|
const tilePos = returnedTiles[0][tileIds[i]].tilePos;
|
|
493
536
|
|
|
537
|
+
/** @type {DividedTile} */
|
|
494
538
|
let newTile = {
|
|
495
539
|
zoomLevel,
|
|
496
540
|
tilePos,
|
|
497
541
|
tilePositionId: tileIds[i],
|
|
498
542
|
};
|
|
499
543
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
returnedTiles[1][tileIds[i]].dense
|
|
503
|
-
) {
|
|
504
|
-
const newData = this.divideData(
|
|
505
|
-
returnedTiles[0][tileIds[i]].dense,
|
|
506
|
-
returnedTiles[1][tileIds[i]].dense,
|
|
507
|
-
);
|
|
544
|
+
const denseA = returnedTiles[0][tileIds[i]].dense;
|
|
545
|
+
const denseB = returnedTiles[1][tileIds[i]].dense;
|
|
508
546
|
|
|
547
|
+
if (denseA && denseB) {
|
|
548
|
+
const newData = this.divideData(denseA, denseB);
|
|
509
549
|
const dde =
|
|
510
550
|
tilePos.length === 2
|
|
511
551
|
? new DenseDataExtrema2D(newData)
|