higlass 1.13.6 → 2.0.1
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/app/scripts/AddTrackDialog.jsx +8 -1
- package/app/scripts/AddTrackPositionMenu.jsx +26 -5
- package/app/scripts/Annotations1dTrack.js +90 -251
- package/app/scripts/Annotations2dTrack.js +9 -2
- package/app/scripts/Autocomplete.jsx +1 -9
- package/app/scripts/BedLikeTrack.js +549 -441
- package/app/scripts/ContextMenuContainer.jsx +3 -0
- package/app/scripts/ContextMenuItem.jsx +13 -2
- package/app/scripts/FilledLine.js +349 -0
- package/app/scripts/GenomePositionSearchBox.jsx +178 -477
- package/app/scripts/HiGlassComponent.jsx +443 -349
- package/app/scripts/HiGlassComponentContext.js +5 -0
- package/app/scripts/SeriesListMenu.jsx +94 -44
- package/app/scripts/SeriesListSubmenuMixin.jsx +1 -0
- package/app/scripts/Tiled1DPixiTrack.js +0 -1
- package/app/scripts/TiledPixiTrack.js +72 -63
- package/app/scripts/TiledPlot.jsx +530 -77
- package/app/scripts/TrackRenderer.jsx +2 -2
- package/app/scripts/ViewContextMenu.jsx +50 -2
- package/app/scripts/ViewHeader.jsx +3 -2
- package/app/scripts/api.js +87 -6
- package/app/scripts/configs/index.js +6 -1
- package/app/scripts/configs/primitives.js +2 -0
- package/app/scripts/configs/tracks-info.js +1 -0
- package/app/scripts/data-fetchers/genbank-fetcher.js +9 -14
- package/app/scripts/data-fetchers/local-tile-fetcher.js +8 -2
- package/app/scripts/hglib.jsx +61 -70
- package/app/scripts/options-info.js +49 -11
- package/app/scripts/services/tile-proxy.js +0 -4
- package/app/scripts/services/worker.js +1 -0
- package/app/scripts/test-helpers/index.js +2 -1
- package/app/scripts/test-helpers/test-helpers.jsx +154 -66
- package/app/scripts/types.ts +68 -3
- package/app/scripts/utils/copy-text-to-clipboard.js +36 -0
- package/app/scripts/utils/decompress.js +33 -0
- package/app/scripts/utils/default-tracks.js +46 -0
- package/app/scripts/utils/get-default-track-for-datatype.js +2 -1
- package/app/scripts/utils/get-default-tracks-for-datatype.ts +46 -0
- package/app/scripts/utils/index.js +1 -0
- package/app/scripts/utils/positioned-tracks-to-all-tracks.js +55 -0
- package/app/scripts/utils/show-mouse-position.js +0 -16
- package/app/scripts/utils/visit-positioned-tracks.js +4 -1
- package/app/styles/AddTrackPositionMenu.module.scss +37 -0
- package/app/styles/HiGlass.module.scss +3 -1
- package/app/styles/TiledPlot.module.scss +20 -0
- package/dist/app/schema.json +525 -0
- package/dist/app/scripts/AddTrackDialog.d.ts +64 -0
- package/dist/app/scripts/AddTrackPositionMenu.d.ts +5 -0
- package/dist/app/scripts/Annotations1dTrack.d.ts +15 -0
- package/dist/app/scripts/Annotations2dTrack.d.ts +95 -0
- package/dist/app/scripts/ArrowheadDomainsTrack.d.ts +36 -0
- package/dist/app/scripts/Autocomplete.d.ts +102 -0
- package/dist/app/scripts/AxisPixi.d.ts +25 -0
- package/dist/app/scripts/BarTrack.d.ts +28 -0
- package/dist/app/scripts/BedLikeTrack.d.ts +84 -0
- package/dist/app/scripts/Button.d.ts +3 -0
- package/dist/app/scripts/CNVIntervalTrack.d.ts +12 -0
- package/dist/app/scripts/CenterTiledPlot.d.ts +3 -0
- package/dist/app/scripts/CenterTrack.d.ts +92 -0
- package/dist/app/scripts/Chromosome2DAnnotations.d.ts +10 -0
- package/dist/app/scripts/Chromosome2DLabels.d.ts +13 -0
- package/dist/app/scripts/ChromosomeGrid.d.ts +24 -0
- package/dist/app/scripts/ChromosomeInfo.d.ts +14 -0
- package/dist/app/scripts/CloseTrackMenu.d.ts +10 -0
- package/dist/app/scripts/CombinedTrack.d.ts +32 -0
- package/dist/app/scripts/ConfigTrackMenu.d.ts +10 -0
- package/dist/app/scripts/ConfigViewMenu.d.ts +34 -0
- package/dist/app/scripts/ConfigureSeriesMenu.d.ts +3 -0
- package/dist/app/scripts/ContextMenuContainer.d.ts +36 -0
- package/dist/app/scripts/ContextMenuItem.d.ts +34 -0
- package/dist/app/scripts/Cross.d.ts +3 -0
- package/dist/app/scripts/CrossRule.d.ts +24 -0
- package/dist/app/scripts/CustomTrackDialog.d.ts +17 -0
- package/dist/app/scripts/Dialog.d.ts +5 -0
- package/dist/app/scripts/DivergentBarTrack.d.ts +4 -0
- package/dist/app/scripts/DragListeningDiv.d.ts +32 -0
- package/dist/app/scripts/DraggableDiv.d.ts +63 -0
- package/dist/app/scripts/ExportLinkDialog.d.ts +21 -0
- package/dist/app/scripts/FilledLine.d.ts +5 -0
- package/dist/app/scripts/FixedTrack.d.ts +5 -0
- package/dist/app/scripts/GalleryTracks.d.ts +20 -0
- package/dist/app/scripts/GenomePositionSearchBox.d.ts +95 -0
- package/dist/app/scripts/HeatmapOptions.d.ts +30 -0
- package/dist/app/scripts/HeatmapTiledPixiTrack.d.ts +184 -0
- package/dist/app/scripts/HiGlassComponent.d.ts +762 -0
- package/dist/app/scripts/HiGlassComponentContext.d.ts +3 -0
- package/dist/app/scripts/HiGlassTrackComponent.d.ts +37 -0
- package/dist/app/scripts/Horizontal1dHeatmapTrack.d.ts +9 -0
- package/dist/app/scripts/Horizontal2DDomainsTrack.d.ts +21 -0
- package/dist/app/scripts/HorizontalChromosomeLabels.d.ts +47 -0
- package/dist/app/scripts/HorizontalGeneAnnotationsTrack.d.ts +25 -0
- package/dist/app/scripts/HorizontalHeatmapTrack.d.ts +12 -0
- package/dist/app/scripts/HorizontalItem.d.ts +3 -0
- package/dist/app/scripts/HorizontalLine1DPixiTrack.d.ts +23 -0
- package/dist/app/scripts/HorizontalMultivecTrack.d.ts +50 -0
- package/dist/app/scripts/HorizontalPoint1DPixiTrack.d.ts +5 -0
- package/dist/app/scripts/HorizontalRule.d.ts +22 -0
- package/dist/app/scripts/HorizontalTiled1DPixiTrack.d.ts +26 -0
- package/dist/app/scripts/HorizontalTiledPlot.d.ts +49 -0
- package/dist/app/scripts/HorizontalTrack.d.ts +6 -0
- package/dist/app/scripts/Id2DTiledPixiTrack.d.ts +10 -0
- package/dist/app/scripts/IdHorizontal1DTiledPixiTrack.d.ts +6 -0
- package/dist/app/scripts/IdVertical1DTiledPixiTrack.d.ts +7 -0
- package/dist/app/scripts/LeftAxisTrack.d.ts +9 -0
- package/dist/app/scripts/LeftTrackModifier.d.ts +29 -0
- package/dist/app/scripts/ListWrapper.d.ts +64 -0
- package/dist/app/scripts/MapboxTilesTrack.d.ts +9 -0
- package/dist/app/scripts/Modal.d.ts +5 -0
- package/dist/app/scripts/MoveableTrack.d.ts +18 -0
- package/dist/app/scripts/NestedContextMenu.d.ts +7 -0
- package/dist/app/scripts/OSMTileIdsTrack.d.ts +5 -0
- package/dist/app/scripts/OSMTilesTrack.d.ts +129 -0
- package/dist/app/scripts/OverlayTrack.d.ts +13 -0
- package/dist/app/scripts/PixiTrack.d.ts +174 -0
- package/dist/app/scripts/PlotTypeChooser.d.ts +25 -0
- package/dist/app/scripts/PopupMenu.d.ts +28 -0
- package/dist/app/scripts/RasterTilesTrack.d.ts +9 -0
- package/dist/app/scripts/RuleMixin.d.ts +2 -0
- package/dist/app/scripts/SVGTrack.d.ts +15 -0
- package/dist/app/scripts/SearchField.d.ts +13 -0
- package/dist/app/scripts/SeriesListItems.d.ts +2 -0
- package/dist/app/scripts/SeriesListMenu.d.ts +51 -0
- package/dist/app/scripts/SeriesListSubmenuMixin.d.ts +2 -0
- package/dist/app/scripts/SketchInlinePicker.d.ts +25 -0
- package/dist/app/scripts/SortableList.d.ts +22 -0
- package/dist/app/scripts/SquareMarkersTrack.d.ts +22 -0
- package/dist/app/scripts/Tiled1DPixiTrack.d.ts +60 -0
- package/dist/app/scripts/TiledPixiTrack.d.ts +369 -0
- package/dist/app/scripts/TiledPlot.d.ts +313 -0
- package/dist/app/scripts/TilesetFinder.d.ts +65 -0
- package/dist/app/scripts/TopAxisTrack.d.ts +9 -0
- package/dist/app/scripts/Track.d.ts +196 -0
- package/dist/app/scripts/TrackArea.d.ts +26 -0
- package/dist/app/scripts/TrackControl.d.ts +5 -0
- package/dist/app/scripts/TrackRenderer.d.ts +724 -0
- package/dist/app/scripts/UnknownPixiTrack.d.ts +7 -0
- package/dist/app/scripts/ValueIntervalTrack.d.ts +6 -0
- package/dist/app/scripts/VerticalItem.d.ts +3 -0
- package/dist/app/scripts/VerticalRule.d.ts +21 -0
- package/dist/app/scripts/VerticalTiled1DPixiTrack.d.ts +6 -0
- package/dist/app/scripts/VerticalTiledPlot.d.ts +50 -0
- package/dist/app/scripts/VerticalTrack.d.ts +6 -0
- package/dist/app/scripts/ViewConfigEditor.d.ts +53 -0
- package/dist/app/scripts/ViewContextMenu.d.ts +17 -0
- package/dist/app/scripts/ViewHeader.d.ts +75 -0
- package/dist/app/scripts/ViewportTracker2D.d.ts +17 -0
- package/dist/app/scripts/ViewportTracker2DPixi.d.ts +11 -0
- package/dist/app/scripts/ViewportTrackerHorizontal.d.ts +17 -0
- package/dist/app/scripts/ViewportTrackerVertical.d.ts +17 -0
- package/dist/app/scripts/api.d.ts +640 -0
- package/dist/app/scripts/configs/available-track-types.d.ts +2 -0
- package/dist/app/scripts/configs/colormaps.d.ts +2 -0
- package/dist/app/scripts/configs/datatype-to-track-type.d.ts +4 -0
- package/dist/app/scripts/configs/default-tracks-for-datatype.d.ts +38 -0
- package/dist/app/scripts/configs/dense-data-extrema-config.d.ts +2 -0
- package/dist/app/scripts/configs/globals.d.ts +5 -0
- package/dist/app/scripts/configs/index.d.ts +16 -0
- package/dist/app/scripts/configs/positions-by-datatype.d.ts +2 -0
- package/dist/app/scripts/configs/primitives.d.ts +20 -0
- package/dist/app/scripts/configs/themes.d.ts +3 -0
- package/dist/app/scripts/configs/tracks-info-by-type.d.ts +4 -0
- package/dist/app/scripts/configs/tracks-info.d.ts +24 -0
- package/dist/app/scripts/d3-context-menu.d.ts +2 -0
- package/dist/app/scripts/data-fetchers/DataFetcher.d.ts +151 -0
- package/dist/app/scripts/data-fetchers/genbank-fetcher.d.ts +86 -0
- package/dist/app/scripts/data-fetchers/index.d.ts +3 -0
- package/dist/app/scripts/data-fetchers/local-tile-fetcher.d.ts +47 -0
- package/dist/app/scripts/gosling-exports.d.ts +17 -0
- package/dist/app/scripts/hglib.d.ts +24 -0
- package/dist/app/scripts/hocs/with-modal.d.ts +19 -0
- package/dist/app/scripts/hocs/with-pub-sub.d.ts +22 -0
- package/dist/app/scripts/hocs/with-theme.d.ts +13 -0
- package/dist/app/scripts/icons.d.ts +161 -0
- package/dist/app/scripts/mixwith.d.ts +27 -0
- package/dist/app/scripts/options-info.d.ts +1355 -0
- package/dist/app/scripts/plugins/available-for-plugins.d.ts +2338 -0
- package/dist/app/scripts/plugins/get-data-fetcher.d.ts +2 -0
- package/dist/app/scripts/plugins/index.d.ts +2 -0
- package/dist/app/scripts/services/chrom-info.d.ts +10 -0
- package/dist/app/scripts/services/dom-event.d.ts +7 -0
- package/dist/app/scripts/services/element-resize-listener.d.ts +5 -0
- package/dist/app/scripts/services/index.d.ts +5 -0
- package/dist/app/scripts/services/tile-proxy.d.ts +180 -0
- package/dist/app/scripts/services/worker.d.ts +157 -0
- package/dist/app/scripts/symbol.d.ts +13 -0
- package/dist/app/scripts/test-helpers/index.d.ts +1 -0
- package/dist/app/scripts/test-helpers/test-helpers.d.ts +33 -0
- package/dist/app/scripts/track-utils.d.ts +73 -0
- package/dist/app/scripts/types.d.ts +199 -0
- package/dist/app/scripts/utils/DenseDataExtrema1D.d.ts +88 -0
- package/dist/app/scripts/utils/DenseDataExtrema2D.d.ts +97 -0
- package/dist/app/scripts/utils/LruCache.d.ts +44 -0
- package/dist/app/scripts/utils/abs-to-chr.d.ts +14 -0
- package/dist/app/scripts/utils/accessor-transposition.d.ts +14 -0
- package/dist/app/scripts/utils/add-arrays.d.ts +18 -0
- package/dist/app/scripts/utils/add-class.d.ts +8 -0
- package/dist/app/scripts/utils/add-event-listener-once.d.ts +11 -0
- package/dist/app/scripts/utils/assert.d.ts +17 -0
- package/dist/app/scripts/utils/background-task-scheduler.d.ts +47 -0
- package/dist/app/scripts/utils/base64-to-canvas.d.ts +9 -0
- package/dist/app/scripts/utils/chr-to-abs.d.ts +10 -0
- package/dist/app/scripts/utils/chrom-info-bisector.d.ts +4 -0
- package/dist/app/scripts/utils/clone-event.d.ts +12 -0
- package/dist/app/scripts/utils/color-domain-to-rgba-array.d.ts +13 -0
- package/dist/app/scripts/utils/color-to-hex.d.ts +9 -0
- package/dist/app/scripts/utils/color-to-rgba.d.ts +9 -0
- package/dist/app/scripts/utils/copy-text-to-clipboard.d.ts +2 -0
- package/dist/app/scripts/utils/data-to-genomic-loci.d.ts +11 -0
- package/dist/app/scripts/utils/debounce.d.ts +5 -0
- package/dist/app/scripts/utils/dec-to-hex-str.d.ts +8 -0
- package/dist/app/scripts/utils/decompress.d.ts +27 -0
- package/dist/app/scripts/utils/default-tracks.d.ts +3 -0
- package/dist/app/scripts/utils/dict-from-tuples.d.ts +11 -0
- package/dist/app/scripts/utils/dict-items.d.ts +18 -0
- package/dist/app/scripts/utils/dict-keys.d.ts +10 -0
- package/dist/app/scripts/utils/dict-values.d.ts +8 -0
- package/dist/app/scripts/utils/download.d.ts +7 -0
- package/dist/app/scripts/utils/expand-combined-tracks.d.ts +11 -0
- package/dist/app/scripts/utils/fake-pub-sub.d.ts +11 -0
- package/dist/app/scripts/utils/fill-in-min-widths.d.ts +44 -0
- package/dist/app/scripts/utils/flatten.d.ts +9 -0
- package/dist/app/scripts/utils/for-each.d.ts +9 -0
- package/dist/app/scripts/utils/forward-event.d.ts +7 -0
- package/dist/app/scripts/utils/genome-loci-to-pixels.d.ts +9 -0
- package/dist/app/scripts/utils/genomic-range-to-chromosome-chunks.d.ts +21 -0
- package/dist/app/scripts/utils/get-aggregation-function.d.ts +10 -0
- package/dist/app/scripts/utils/get-default-track-for-datatype.d.ts +21 -0
- package/dist/app/scripts/utils/get-default-tracks-for-datatype.d.ts +3 -0
- package/dist/app/scripts/utils/get-element-dim.d.ts +7 -0
- package/dist/app/scripts/utils/get-higlass-components.d.ts +7 -0
- package/dist/app/scripts/utils/get-track-by-uid.d.ts +7 -0
- package/dist/app/scripts/utils/get-track-conf-from-hgc.d.ts +10 -0
- package/dist/app/scripts/utils/get-track-obj-by-id.d.ts +2 -0
- package/dist/app/scripts/utils/get-track-position-by-uid.d.ts +13 -0
- package/dist/app/scripts/utils/get-xylofon.d.ts +2 -0
- package/dist/app/scripts/utils/gradient.d.ts +14 -0
- package/dist/app/scripts/utils/has-class.d.ts +8 -0
- package/dist/app/scripts/utils/has-parent.d.ts +9 -0
- package/dist/app/scripts/utils/hex-string-to-int.d.ts +14 -0
- package/dist/app/scripts/utils/index.d.ts +89 -0
- package/dist/app/scripts/utils/interval-tree.d.ts +109 -0
- package/dist/app/scripts/utils/into-the-void.d.ts +6 -0
- package/dist/app/scripts/utils/is-track-or-child-track.d.ts +7 -0
- package/dist/app/scripts/utils/is-track-range-selectable.d.ts +2 -0
- package/dist/app/scripts/utils/is-within.d.ts +12 -0
- package/dist/app/scripts/utils/lat-to-y.d.ts +9 -0
- package/dist/app/scripts/utils/lng-to-x.d.ts +8 -0
- package/dist/app/scripts/utils/load-chrom-infos.d.ts +8 -0
- package/dist/app/scripts/utils/map.d.ts +13 -0
- package/dist/app/scripts/utils/max-non-zero.d.ts +6 -0
- package/dist/app/scripts/utils/max.d.ts +10 -0
- package/dist/app/scripts/utils/min-non-zero.d.ts +6 -0
- package/dist/app/scripts/utils/min.d.ts +10 -0
- package/dist/app/scripts/utils/mod.d.ts +9 -0
- package/dist/app/scripts/utils/ndarray-assign.d.ts +2 -0
- package/dist/app/scripts/utils/ndarray-flatten.d.ts +2 -0
- package/dist/app/scripts/utils/ndarray-to-list.d.ts +2 -0
- package/dist/app/scripts/utils/numericify-version.d.ts +6 -0
- package/dist/app/scripts/utils/obj-vals.d.ts +8 -0
- package/dist/app/scripts/utils/or.d.ts +8 -0
- package/dist/app/scripts/utils/parse-chromsizes-rows.d.ts +34 -0
- package/dist/app/scripts/utils/pixi-text-to-svg.d.ts +2 -0
- package/dist/app/scripts/utils/positioned-tracks-to-all-tracks.d.ts +26 -0
- package/dist/app/scripts/utils/q.d.ts +18 -0
- package/dist/app/scripts/utils/rad-to-deg.d.ts +7 -0
- package/dist/app/scripts/utils/range-query-2d.d.ts +17 -0
- package/dist/app/scripts/utils/reduce.d.ts +14 -0
- package/dist/app/scripts/utils/rel-to-abs-chrom-pos.d.ts +10 -0
- package/dist/app/scripts/utils/remove-class.d.ts +7 -0
- package/dist/app/scripts/utils/reset-d3-brush-style.d.ts +10 -0
- package/dist/app/scripts/utils/rgb-to-hex.d.ts +8 -0
- package/dist/app/scripts/utils/scales-center-and-k.d.ts +12 -0
- package/dist/app/scripts/utils/scales-to-genome-loci.d.ts +3 -0
- package/dist/app/scripts/utils/segments-to-rows.d.ts +15 -0
- package/dist/app/scripts/utils/selected-items-to-cum-weights.d.ts +12 -0
- package/dist/app/scripts/utils/selected-items-to-size.d.ts +13 -0
- package/dist/app/scripts/utils/show-mouse-position.d.ts +54 -0
- package/dist/app/scripts/utils/some.d.ts +10 -0
- package/dist/app/scripts/utils/sum.d.ts +8 -0
- package/dist/app/scripts/utils/svg-line.d.ts +2 -0
- package/dist/app/scripts/utils/throttle-and-debounce.d.ts +33 -0
- package/dist/app/scripts/utils/tile-to-canvas.d.ts +9 -0
- package/dist/app/scripts/utils/timeout.d.ts +3 -0
- package/dist/app/scripts/utils/to-void.d.ts +3 -0
- package/dist/app/scripts/utils/total-track-pixel-height.d.ts +27 -0
- package/dist/app/scripts/utils/trim-trailing-slash.d.ts +7 -0
- package/dist/app/scripts/utils/type-guards.d.ts +36 -0
- package/dist/app/scripts/utils/value-to-color.d.ts +12 -0
- package/dist/app/scripts/utils/visit-positioned-tracks.d.ts +18 -0
- package/dist/app/scripts/utils/visit-tracks.d.ts +9 -0
- package/dist/esm.html +1 -3
- package/dist/hglib.js +65302 -79868
- package/dist/hglib.min.js +104 -112
- package/dist/higlass.mjs +64214 -78780
- package/dist/index.html +1 -3
- package/dist/package.json +134 -0
- package/package.json +13 -10
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
import clsx from 'clsx';
|
|
3
|
+
import { queue } from 'd3-queue';
|
|
3
4
|
import { select } from 'd3-selection';
|
|
4
5
|
import PropTypes from 'prop-types';
|
|
5
6
|
import React from 'react';
|
|
@@ -9,18 +10,15 @@ import Autocomplete from './Autocomplete';
|
|
|
9
10
|
import ChromosomeInfo from './ChromosomeInfo';
|
|
10
11
|
import PopupMenu from './PopupMenu';
|
|
11
12
|
import SearchField from './SearchField';
|
|
13
|
+
import { THEME_DARK, ZOOM_TRANSITION_DURATION } from './configs';
|
|
12
14
|
|
|
13
|
-
import withPubSub from './hocs/with-pub-sub';
|
|
14
15
|
// Services
|
|
15
16
|
import { tileProxy } from './services';
|
|
16
17
|
|
|
18
|
+
import withPubSub from './hocs/with-pub-sub';
|
|
17
19
|
// Utils
|
|
18
|
-
import {
|
|
20
|
+
import { scalesCenterAndK } from './utils';
|
|
19
21
|
|
|
20
|
-
// Configs
|
|
21
|
-
import { THEME_DARK, ZOOM_TRANSITION_DURATION } from './configs';
|
|
22
|
-
// HOCS
|
|
23
|
-
import withTheme from './hocs/with-theme';
|
|
24
22
|
import { SearchIcon } from './icons';
|
|
25
23
|
|
|
26
24
|
// Styles
|
|
@@ -38,34 +36,28 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
38
36
|
|
|
39
37
|
this.xScale = null;
|
|
40
38
|
this.yScale = null;
|
|
41
|
-
// this.props.zoomDispatch.on('zoom.' + this.uid, this.zoomed.bind(this))
|
|
42
|
-
|
|
43
|
-
/*
|
|
44
|
-
this.xOrigScale = scaleLinear().domain(this.props.xDomain)
|
|
45
|
-
.range(this.props.xRange);
|
|
46
|
-
this.yOrigScale = scaleLinear().domain(this.props.yDomain)
|
|
47
|
-
.range(this.props.yRange);
|
|
48
|
-
|
|
49
|
-
this.zoomedXScale = this.xOrigScale.copy();
|
|
50
|
-
this.zoomedYScale = this.yOrigScale.copy();
|
|
51
|
-
*/
|
|
52
|
-
|
|
53
39
|
this.prevParts = [];
|
|
54
40
|
|
|
55
41
|
this.props.registerViewportChangedListener(this.scalesChanged.bind(this));
|
|
56
42
|
|
|
57
43
|
this.menuPosition = { left: 0, top: 0 };
|
|
58
44
|
|
|
45
|
+
this.currentChromInfoServer = this.props.chromInfoServer;
|
|
46
|
+
this.currentChromInfoId = this.props.chromInfoId;
|
|
47
|
+
|
|
59
48
|
// the position text is maintained both here and in
|
|
60
49
|
// in state.value so that it can be quickly updated in
|
|
61
50
|
// response to zoom events
|
|
62
|
-
this.positionText = '
|
|
51
|
+
// this.positionText = 'no chromosome track present';
|
|
52
|
+
this.positionText = props.error;
|
|
63
53
|
|
|
64
54
|
this.state = {
|
|
55
|
+
value: this.positionText,
|
|
56
|
+
loading: false,
|
|
57
|
+
menuPosition: [0, 0],
|
|
65
58
|
genes: [],
|
|
66
59
|
isFocused: false,
|
|
67
|
-
|
|
68
|
-
autocompleteId: this.props.autocompleteId,
|
|
60
|
+
menuOpened: false,
|
|
69
61
|
availableAssemblies: [],
|
|
70
62
|
selectedAssembly: null,
|
|
71
63
|
};
|
|
@@ -87,29 +79,6 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
87
79
|
border: 'solid 1px #ccc',
|
|
88
80
|
},
|
|
89
81
|
};
|
|
90
|
-
|
|
91
|
-
this.availableAutocompletes = {};
|
|
92
|
-
|
|
93
|
-
if (this.props.autocompleteId) {
|
|
94
|
-
this.availableAutocompletes[this.props.chromInfoId] = new Set([
|
|
95
|
-
{
|
|
96
|
-
server: this.props.autocompleteServer,
|
|
97
|
-
acId: this.props.autocompleteId,
|
|
98
|
-
},
|
|
99
|
-
]);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
this.availableChromSizes = {};
|
|
103
|
-
|
|
104
|
-
/*
|
|
105
|
-
if (this.props.chromInfoServer && this.props.chromInfoId) {
|
|
106
|
-
// if we've been passed a server and chromInfo ID we trust that it exists
|
|
107
|
-
// and use that
|
|
108
|
-
this.availableChromSizes[this.props.chromInfoId] =
|
|
109
|
-
new Set([{server: this.props.chromInfoServer, uuid: this.props.chromInfoId} ]);
|
|
110
|
-
this.fetchChromInfo(this.props.chromInfoId);
|
|
111
|
-
}
|
|
112
|
-
*/
|
|
113
82
|
}
|
|
114
83
|
|
|
115
84
|
componentDidMount() {
|
|
@@ -120,25 +89,7 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
120
89
|
this.autocompleteKeyPress.bind(this),
|
|
121
90
|
);
|
|
122
91
|
|
|
123
|
-
this.
|
|
124
|
-
this.findAvailableChromSizes();
|
|
125
|
-
|
|
126
|
-
if (this.props.chromInfoPath) {
|
|
127
|
-
this.searchPosition = true;
|
|
128
|
-
|
|
129
|
-
ChromosomeInfo(this.props.chromInfoPath, (chromInfo) => {
|
|
130
|
-
if (!chromInfo) {
|
|
131
|
-
this.searchPosition = null;
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
this.chromInfo = chromInfo;
|
|
136
|
-
this.searchField = new SearchField(this.chromInfo);
|
|
137
|
-
|
|
138
|
-
this.setPositionText();
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
|
|
92
|
+
this.fetchChromInfo(this.props.chromInfoServer, this.props.chromInfoId);
|
|
142
93
|
this.setPositionText();
|
|
143
94
|
}
|
|
144
95
|
|
|
@@ -147,161 +98,50 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
147
98
|
this.props.removeViewportChangedListener();
|
|
148
99
|
}
|
|
149
100
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
let changedAtStartOfWord = false;
|
|
162
|
-
|
|
163
|
-
for (let j = 0; j < spaceParts.length; j++) {
|
|
164
|
-
const parts = spaceParts[j].split(/-/);
|
|
165
|
-
|
|
166
|
-
for (let i = 0; i < parts.length; i++) {
|
|
167
|
-
partIndex += 1;
|
|
168
|
-
newParts.push(parts[i]);
|
|
169
|
-
|
|
170
|
-
if (i === 0) changedAtStartOfWord = true;
|
|
171
|
-
else changedAtStartOfWord = false;
|
|
172
|
-
|
|
173
|
-
if (i === this.prevParts.length) {
|
|
174
|
-
// new part added
|
|
175
|
-
this.changedPart = partIndex - 1;
|
|
176
|
-
break;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if (parts[i] !== this.prevParts[i]) {
|
|
180
|
-
this.changedPart = partIndex - 1;
|
|
181
|
-
break;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
this.prevParts = newParts;
|
|
187
|
-
|
|
188
|
-
// no autocomplete repository is provided, so we don't try to autcomplete anything
|
|
189
|
-
if (!(this.state.autocompleteServer && this.state.autocompleteId)) {
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
101
|
+
/**
|
|
102
|
+
* The user has selected an assembly to use for the coordinate search box
|
|
103
|
+
*
|
|
104
|
+
* @param {string} chromInfoServer
|
|
105
|
+
* @param {string} chromInfoId - The name of the chromosome info set to use
|
|
106
|
+
*
|
|
107
|
+
* @returns {void} Once the appropriate ChromInfo file is fetched, it is stored locally
|
|
108
|
+
*/
|
|
109
|
+
fetchChromInfo(chromInfoServer, chromInfoId) {
|
|
110
|
+
if (!chromInfoId) {
|
|
111
|
+
this.positionText = 'no chromosome track present';
|
|
192
112
|
|
|
193
|
-
if (this.changedPart !== null) {
|
|
194
|
-
// if something has changed in the input text
|
|
195
113
|
this.setState({
|
|
196
|
-
|
|
114
|
+
value: this.positionText,
|
|
197
115
|
});
|
|
198
|
-
// send out a request for the autcomplete suggestions
|
|
199
|
-
let url = `${this.state.autocompleteServer}/suggest/`;
|
|
200
|
-
url += `?d=${this.state.autocompleteId}&ac=${newParts[
|
|
201
|
-
this.changedPart
|
|
202
|
-
].toLowerCase()}`;
|
|
203
|
-
tileProxy.json(
|
|
204
|
-
url,
|
|
205
|
-
(error, data) => {
|
|
206
|
-
if (error) {
|
|
207
|
-
this.setState({
|
|
208
|
-
loading: false,
|
|
209
|
-
genes: [],
|
|
210
|
-
});
|
|
211
|
-
} else if (this.changedPart > 0 && !changedAtStartOfWord) {
|
|
212
|
-
// send out another request for genes with dashes in them
|
|
213
|
-
// but we need to distinguish things that have a dash in front
|
|
214
|
-
// from things that just have a space in front
|
|
215
|
-
|
|
216
|
-
const url1 =
|
|
217
|
-
`${this.state.autocompleteServer}/suggest/` +
|
|
218
|
-
`?d=${this.state.autocompleteId}` +
|
|
219
|
-
`&ac=${newParts[this.changedPart - 1].toLowerCase()}` +
|
|
220
|
-
`-${newParts[this.changedPart].toLowerCase()}`;
|
|
221
|
-
tileProxy.json(
|
|
222
|
-
url1,
|
|
223
|
-
(error1, data1) => {
|
|
224
|
-
if (error1) {
|
|
225
|
-
this.setState({
|
|
226
|
-
loading: false,
|
|
227
|
-
genes: data,
|
|
228
|
-
});
|
|
229
|
-
} else {
|
|
230
|
-
this.setState({
|
|
231
|
-
loading: false,
|
|
232
|
-
genes: data1.concat(data),
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
},
|
|
236
|
-
this.props.pubSub,
|
|
237
|
-
);
|
|
238
|
-
} else {
|
|
239
|
-
// we've received a list of autocomplete suggestions
|
|
240
|
-
this.setState({ loading: false, genes: data });
|
|
241
|
-
}
|
|
242
|
-
},
|
|
243
|
-
this.props.pubSub,
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
116
|
|
|
248
|
-
|
|
249
|
-
const chromsizeKeys = new Set(dictKeys(this.availableChromSizes));
|
|
250
|
-
|
|
251
|
-
const commonKeys = new Set([...chromsizeKeys]);
|
|
252
|
-
|
|
253
|
-
if (this.gpsbForm) {
|
|
254
|
-
// only set the state if this comonent is mounted
|
|
255
|
-
this.setState({
|
|
256
|
-
availableAssemblies: [...commonKeys],
|
|
257
|
-
});
|
|
117
|
+
return;
|
|
258
118
|
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
setSelectedAssembly(assemblyName) {
|
|
262
|
-
// component is probably about to be unmounted
|
|
263
|
-
if (!this.mounted) return;
|
|
264
119
|
|
|
265
|
-
if (!this.
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
// use the first available server that we have on record for this chromInfoId
|
|
270
|
-
const serverAndChromInfoToUse = [
|
|
271
|
-
...this.availableChromSizes[assemblyName],
|
|
272
|
-
][0];
|
|
120
|
+
if (!this.mounted)
|
|
121
|
+
// component is probably about to be unmounted
|
|
122
|
+
return;
|
|
273
123
|
|
|
274
124
|
this.setState({
|
|
275
|
-
autocompleteServer:
|
|
125
|
+
autocompleteServer: chromInfoServer,
|
|
276
126
|
});
|
|
277
127
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
const newAcId = [...this.availableAutocompletes[assemblyName]][0].acId;
|
|
284
|
-
this.props.onSelectedAssemblyChanged(assemblyName, newAcId, server);
|
|
128
|
+
ChromosomeInfo(
|
|
129
|
+
`${chromInfoServer}/chrom-sizes/?id=${chromInfoId}`,
|
|
130
|
+
(newChromInfo) => {
|
|
131
|
+
this.chromInfo = newChromInfo;
|
|
132
|
+
this.searchField = new SearchField(this.chromInfo);
|
|
285
133
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
} else {
|
|
292
|
-
this.props.onSelectedAssemblyChanged(assemblyName, null, server);
|
|
134
|
+
this.setPositionText();
|
|
135
|
+
},
|
|
136
|
+
);
|
|
137
|
+
}
|
|
293
138
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
}
|
|
139
|
+
scalesChanged(xScale, yScale) {
|
|
140
|
+
this.xScale = xScale;
|
|
141
|
+
this.yScale = yScale;
|
|
300
142
|
|
|
301
|
-
this
|
|
302
|
-
|
|
303
|
-
serverAndChromInfoToUse.server,
|
|
304
|
-
);
|
|
143
|
+
// make sure that this component is loaded first
|
|
144
|
+
this.setPositionText();
|
|
305
145
|
}
|
|
306
146
|
|
|
307
147
|
setPositionText() {
|
|
@@ -318,166 +158,14 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
318
158
|
this.props.twoD,
|
|
319
159
|
);
|
|
320
160
|
|
|
321
|
-
// ReactDOM.findDOMNode( this.refs.searchFieldText).value = positionString;
|
|
322
161
|
// used for autocomplete
|
|
323
162
|
this.prevParts = positionString.split(/[ -]/);
|
|
324
|
-
|
|
325
163
|
if (this.gpsbForm) {
|
|
326
164
|
this.positionText = positionString;
|
|
327
|
-
|
|
328
|
-
// this.origPositionText is used to reset the text if somebody clicks submit
|
|
329
|
-
// on an empty field
|
|
330
|
-
this.origPositionText = positionString;
|
|
331
|
-
|
|
332
165
|
this.autocompleteMenu.inputEl.value = positionString;
|
|
333
|
-
// this.setState({ value: positionString });
|
|
334
166
|
}
|
|
335
167
|
}
|
|
336
168
|
|
|
337
|
-
scalesChanged(xScale, yScale) {
|
|
338
|
-
this.xScale = xScale;
|
|
339
|
-
this.yScale = yScale;
|
|
340
|
-
|
|
341
|
-
// make sure that this component is loaded first
|
|
342
|
-
this.setPositionText();
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
findAvailableChromSizes() {
|
|
346
|
-
if (!this.props.trackSourceServers) {
|
|
347
|
-
// if we don't know where to look for track source servers then
|
|
348
|
-
// just give up
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
this.props.trackSourceServers.forEach((sourceServer) => {
|
|
353
|
-
tileProxy.json(
|
|
354
|
-
`${sourceServer}/available-chrom-sizes/`,
|
|
355
|
-
(error, data) => {
|
|
356
|
-
if (error) {
|
|
357
|
-
console.error(error);
|
|
358
|
-
} else {
|
|
359
|
-
data.results.forEach((x) => {
|
|
360
|
-
if (!(x.coordSystem in this.availableChromSizes)) {
|
|
361
|
-
this.availableChromSizes[x.coordSystem] = new Set();
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
this.availableChromSizes[x.coordSystem].add({
|
|
365
|
-
server: sourceServer,
|
|
366
|
-
uuid: x.uuid,
|
|
367
|
-
});
|
|
368
|
-
this.setAvailableAssemblies();
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
// we haven't set an assembly yet so set it now
|
|
372
|
-
// props.chromInfoId will be set to the suggested assembly (e.g. "hg19")
|
|
373
|
-
// this will be mapped to an available chromSize (with its own unique uuid)
|
|
374
|
-
if (!this.searchField) {
|
|
375
|
-
// only fetch chromsizes if there isn't a specified chromInfoServer
|
|
376
|
-
this.fetchChromInfo(
|
|
377
|
-
this.props.chromInfoId in this.availableChromSizes
|
|
378
|
-
? [...this.availableChromSizes[this.props.chromInfoId]][0]
|
|
379
|
-
.uuid
|
|
380
|
-
: this.props.chromInfoId,
|
|
381
|
-
this.props.chromInfoId in this.availableChromSizes
|
|
382
|
-
? [...this.availableChromSizes[this.props.chromInfoId]][0]
|
|
383
|
-
.server
|
|
384
|
-
: this.props.chromInfoServer,
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
},
|
|
389
|
-
this.props.pubSub,
|
|
390
|
-
);
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
findAvailableAutocompleteSources() {
|
|
395
|
-
if (!this.props.trackSourceServers) {
|
|
396
|
-
// if there's no available track source servers
|
|
397
|
-
// we can't search for autocomplete sources
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
this.props.trackSourceServers.forEach((sourceServer) => {
|
|
402
|
-
tileProxy.json(
|
|
403
|
-
`${sourceServer}/tilesets/?limit=100&dt=gene-annotation`,
|
|
404
|
-
(error, data) => {
|
|
405
|
-
if (error) {
|
|
406
|
-
console.error(error);
|
|
407
|
-
} else {
|
|
408
|
-
data.results.forEach((x) => {
|
|
409
|
-
if (!(x.coordSystem in this.availableAutocompletes)) {
|
|
410
|
-
this.availableAutocompletes[x.coordSystem] = new Set();
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
this.availableAutocompletes[x.coordSystem].add({
|
|
414
|
-
server: sourceServer,
|
|
415
|
-
acId: x.uuid,
|
|
416
|
-
});
|
|
417
|
-
this.setAvailableAssemblies();
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
if (!this.state.autocompleteId) {
|
|
421
|
-
// We don't have an autocomplete source yet, so set the one matching the current
|
|
422
|
-
// assembly
|
|
423
|
-
if (this.gpsbForm) {
|
|
424
|
-
// only set the state if this component is mounted
|
|
425
|
-
if (this.availableAutocompletes[this.props.chromInfoId]) {
|
|
426
|
-
this.setState({
|
|
427
|
-
autocompleteId: [
|
|
428
|
-
...this.availableAutocompletes[this.props.chromInfoId],
|
|
429
|
-
][0].acId,
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
},
|
|
436
|
-
this.props.pubSub,
|
|
437
|
-
);
|
|
438
|
-
});
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* The user has selected an assembly to use for the coordinate search box.
|
|
443
|
-
* Once the appropriate ChromInfo file is fetched, it is stored locally
|
|
444
|
-
*
|
|
445
|
-
* @param {string} chromInfoId The name of the chromosome info set to use
|
|
446
|
-
*/
|
|
447
|
-
fetchChromInfo(chromInfoId, server) {
|
|
448
|
-
ChromosomeInfo(
|
|
449
|
-
`${server}/chrom-sizes/?id=${chromInfoId}`,
|
|
450
|
-
(newChromInfo) => {
|
|
451
|
-
if (!newChromInfo) {
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
tileProxy.json(
|
|
456
|
-
`${server}/tileset_info/?d=${chromInfoId}`,
|
|
457
|
-
(error2, tilesetInfo) => {
|
|
458
|
-
if (error2) {
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
if (this.gpsbForm) {
|
|
463
|
-
// only set the state if this component is mounted
|
|
464
|
-
this.setState({
|
|
465
|
-
selectedAssembly: tilesetInfo[chromInfoId].coordSystem,
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
},
|
|
469
|
-
this.props.pubSub,
|
|
470
|
-
);
|
|
471
|
-
|
|
472
|
-
this.chromInfo = newChromInfo;
|
|
473
|
-
this.searchField = new SearchField(this.chromInfo);
|
|
474
|
-
|
|
475
|
-
this.setPositionText();
|
|
476
|
-
},
|
|
477
|
-
this.props.pubSub,
|
|
478
|
-
);
|
|
479
|
-
}
|
|
480
|
-
|
|
481
169
|
autocompleteKeyPress(event) {
|
|
482
170
|
const ENTER_KEY_CODE = 13;
|
|
483
171
|
|
|
@@ -486,8 +174,6 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
486
174
|
}
|
|
487
175
|
}
|
|
488
176
|
|
|
489
|
-
genePositionToSearchBarText(genePosition) {}
|
|
490
|
-
|
|
491
177
|
replaceGenesWithLoadedPositions(genePositions) {
|
|
492
178
|
// iterate over all non-position oriented words and try
|
|
493
179
|
// to replace them with the positions loaded from the suggestions
|
|
@@ -569,68 +255,65 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
569
255
|
replaceGenesWithPositions(finished) {
|
|
570
256
|
// replace any gene names in the input with their corresponding positions
|
|
571
257
|
const valueParts = this.positionText.split(/[ -]/);
|
|
572
|
-
|
|
258
|
+
let q = queue();
|
|
573
259
|
|
|
574
260
|
for (let i = 0; i < valueParts.length; i++) {
|
|
575
261
|
if (valueParts[i].length === 0) {
|
|
576
262
|
continue;
|
|
577
263
|
}
|
|
578
264
|
|
|
579
|
-
const retPos = this.searchField.parsePosition(valueParts[i])
|
|
265
|
+
const [, , retPos] = this.searchField.parsePosition(valueParts[i]);
|
|
580
266
|
|
|
581
|
-
if (retPos
|
|
267
|
+
if (retPos == null || Number.isNaN(retPos)) {
|
|
582
268
|
// not a chromsome position, let's see if it's a gene name
|
|
583
|
-
const url = `${this.
|
|
584
|
-
this.
|
|
269
|
+
const url = `${this.props.autocompleteServer}/suggest/?d=${
|
|
270
|
+
this.props.autocompleteId
|
|
585
271
|
}&ac=${valueParts[i].toLowerCase()}`;
|
|
586
|
-
|
|
272
|
+
|
|
273
|
+
const fetchJson = (callback) => {
|
|
274
|
+
tileProxy.json(url, callback, this.props.pubSub);
|
|
275
|
+
};
|
|
276
|
+
q = q.defer(fetchJson);
|
|
587
277
|
}
|
|
588
278
|
}
|
|
589
279
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
const genePositions = {};
|
|
280
|
+
q.awaitAll((error, files) => {
|
|
281
|
+
if (files) {
|
|
282
|
+
const genePositions = {};
|
|
594
283
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
284
|
+
// extract the position of the top match from the list of files
|
|
285
|
+
for (let i = 0; i < files.length; i++) {
|
|
286
|
+
if (!files[i][0]) {
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
600
289
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
}
|
|
290
|
+
for (let j = 0; j < files[i].length; j++) {
|
|
291
|
+
genePositions[files[i][j].geneName.toLowerCase()] = files[i][j];
|
|
604
292
|
}
|
|
293
|
+
}
|
|
605
294
|
|
|
606
|
-
|
|
607
|
-
this.replaceGenesWithLoadedPositions(genePositions);
|
|
295
|
+
this.replaceGenesWithLoadedPositions(genePositions);
|
|
608
296
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
.catch((error) => console.error(error));
|
|
297
|
+
finished();
|
|
298
|
+
}
|
|
299
|
+
});
|
|
613
300
|
}
|
|
614
301
|
|
|
615
302
|
buttonClick() {
|
|
616
|
-
this.setState({
|
|
303
|
+
this.setState({
|
|
304
|
+
genes: [],
|
|
305
|
+
}); // no menu should be open
|
|
617
306
|
|
|
618
|
-
this.replaceGenesWithPositions((
|
|
307
|
+
this.replaceGenesWithPositions(() => {
|
|
619
308
|
const searchFieldValue = this.positionText;
|
|
620
309
|
|
|
621
|
-
if (this.searchField
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
let range2 = rangePair[1];
|
|
625
|
-
|
|
626
|
-
if (!range1) {
|
|
627
|
-
this.setPositionText();
|
|
628
|
-
return;
|
|
629
|
-
}
|
|
310
|
+
if (this.searchField != null) {
|
|
311
|
+
let [range1, range2] =
|
|
312
|
+
this.searchField.searchPosition(searchFieldValue);
|
|
630
313
|
|
|
631
314
|
if (
|
|
632
|
-
(range1 && (Number.isNaN(
|
|
633
|
-
(range2 && (Number.isNaN(
|
|
315
|
+
(range1 && (Number.isNaN(range1[0]) || Number.isNaN(range1[1]))) ||
|
|
316
|
+
(range2 && (Number.isNaN(range2[0]) || Number.isNaN(range2[1])))
|
|
634
317
|
) {
|
|
635
318
|
return;
|
|
636
319
|
}
|
|
@@ -639,21 +322,19 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
639
322
|
range2 = range1;
|
|
640
323
|
}
|
|
641
324
|
|
|
642
|
-
const newXScale = this.xScale.copy()
|
|
643
|
-
const newYScale = this.yScale.copy()
|
|
325
|
+
const newXScale = this.xScale.copy();
|
|
326
|
+
const newYScale = this.yScale.copy();
|
|
644
327
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
range: range1,
|
|
652
|
-
centerX,
|
|
653
|
-
centerY,
|
|
654
|
-
});
|
|
328
|
+
// If someone doesn't enter anything in the searcbar then
|
|
329
|
+
// range1 will be empty. In that case, we'll just stay in the
|
|
330
|
+
// current position
|
|
331
|
+
if (range1) {
|
|
332
|
+
newXScale.domain(range1);
|
|
333
|
+
newYScale.domain(range1);
|
|
655
334
|
}
|
|
656
335
|
|
|
336
|
+
const [centerX, centerY, k] = scalesCenterAndK(newXScale, newYScale);
|
|
337
|
+
|
|
657
338
|
this.props.setCenters(centerX, centerY, k, ZOOM_TRANSITION_DURATION);
|
|
658
339
|
}
|
|
659
340
|
});
|
|
@@ -669,6 +350,66 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
669
350
|
return parts.join(separator).replace(replace, separator);
|
|
670
351
|
}
|
|
671
352
|
|
|
353
|
+
onAutocompleteChange(event, value) {
|
|
354
|
+
this.positionText = value;
|
|
355
|
+
this.setState({
|
|
356
|
+
value,
|
|
357
|
+
loading: true,
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
const parts = value.split(/[ -]/);
|
|
361
|
+
this.changedPart = null;
|
|
362
|
+
|
|
363
|
+
for (let i = 0; i < parts.length; i++) {
|
|
364
|
+
if (i === this.prevParts.length) {
|
|
365
|
+
// new part added
|
|
366
|
+
this.changedPart = i;
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (parts[i] !== this.prevParts[i]) {
|
|
371
|
+
this.changedPart = i;
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
this.prevParts = parts;
|
|
377
|
+
|
|
378
|
+
// no autocomplete repository is provided, so we don't try to autcomplete anything
|
|
379
|
+
if (!(this.props.autocompleteServer && this.props.autocompleteId)) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (this.changedPart != null) {
|
|
384
|
+
// if something has changed in the input text
|
|
385
|
+
this.setState({ loading: true });
|
|
386
|
+
// spend out a request for the autcomplete suggestions
|
|
387
|
+
const url = `${this.props.autocompleteServer}/suggest/?d=${
|
|
388
|
+
this.props.autocompleteId
|
|
389
|
+
}&ac=${parts[this.changedPart].toLowerCase()}`;
|
|
390
|
+
|
|
391
|
+
tileProxy.json(
|
|
392
|
+
url,
|
|
393
|
+
(error, data) => {
|
|
394
|
+
if (error) {
|
|
395
|
+
this.setState({
|
|
396
|
+
loading: false,
|
|
397
|
+
genes: [],
|
|
398
|
+
});
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// we've received a list of autocomplete suggestions
|
|
403
|
+
this.setState({
|
|
404
|
+
loading: false,
|
|
405
|
+
genes: data,
|
|
406
|
+
});
|
|
407
|
+
},
|
|
408
|
+
this.props.pubSub,
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
672
413
|
geneSelected(value, objct) {
|
|
673
414
|
const parts = this.positionText.split(' ');
|
|
674
415
|
let partCount = this.changedPart;
|
|
@@ -676,34 +417,11 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
676
417
|
// change the part that was selected
|
|
677
418
|
for (let i = 0; i < parts.length; i++) {
|
|
678
419
|
const dashParts = parts[i].split('-');
|
|
679
|
-
const geneParts = objct.geneName.split('-');
|
|
680
|
-
|
|
681
420
|
if (partCount > dashParts.length - 1) {
|
|
682
421
|
partCount -= dashParts.length;
|
|
683
422
|
} else {
|
|
684
423
|
dashParts[partCount] = objct.geneName;
|
|
685
|
-
|
|
686
|
-
if (
|
|
687
|
-
geneParts.length === 2 &&
|
|
688
|
-
partCount > 0 &&
|
|
689
|
-
dashParts[partCount - 1].toLowerCase() === geneParts[0].toLowerCase()
|
|
690
|
-
) {
|
|
691
|
-
// the gene to be added contains a dash and is
|
|
692
|
-
// meant to replace a part of the previous gene
|
|
693
|
-
// e.g. SOX2-O should be replaced with SOX2-OT
|
|
694
|
-
|
|
695
|
-
const newDashParts = dashParts.slice(0, partCount - 1);
|
|
696
|
-
newDashParts.push(geneParts.join('-'));
|
|
697
|
-
|
|
698
|
-
if (partCount < dashParts.length - 1) {
|
|
699
|
-
newDashParts.push(dashParts.slice(partCount + 1));
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
parts[i] = newDashParts.join('-');
|
|
703
|
-
} else {
|
|
704
|
-
parts[i] = dashParts.join('-');
|
|
705
|
-
}
|
|
706
|
-
|
|
424
|
+
parts[i] = dashParts.join('-');
|
|
707
425
|
break;
|
|
708
426
|
}
|
|
709
427
|
}
|
|
@@ -719,7 +437,10 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
719
437
|
this.prevParts = parts.join(' ').split(/[ -]/);
|
|
720
438
|
|
|
721
439
|
this.positionText = parts.join(' ');
|
|
722
|
-
this.setState({
|
|
440
|
+
this.setState({
|
|
441
|
+
value: parts.join(' '),
|
|
442
|
+
genes: [],
|
|
443
|
+
});
|
|
723
444
|
}
|
|
724
445
|
|
|
725
446
|
handleMenuVisibilityChange(isOpen, inputEl) {
|
|
@@ -739,11 +460,11 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
739
460
|
return (
|
|
740
461
|
<PopupMenu>
|
|
741
462
|
<div
|
|
742
|
-
className={styles['genome-position-search-bar-suggestions']}
|
|
743
463
|
style={{
|
|
744
464
|
left: this.menuPosition.left,
|
|
745
465
|
top: this.menuPosition.top,
|
|
746
466
|
}}
|
|
467
|
+
className={styles['genome-position-search-bar-suggestions']}
|
|
747
468
|
>
|
|
748
469
|
{items}
|
|
749
470
|
</div>
|
|
@@ -751,15 +472,11 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
751
472
|
);
|
|
752
473
|
}
|
|
753
474
|
|
|
754
|
-
|
|
755
|
-
this.
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
handleAssemblySelect(assembly) {
|
|
759
|
-
this.setSelectedAssembly(assembly);
|
|
475
|
+
handleAssemblySelect(evt) {
|
|
476
|
+
this.fetchChromInfo(evt);
|
|
760
477
|
|
|
761
478
|
this.setState({
|
|
762
|
-
selectedAssembly:
|
|
479
|
+
selectedAssembly: evt,
|
|
763
480
|
});
|
|
764
481
|
}
|
|
765
482
|
|
|
@@ -769,13 +486,19 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
769
486
|
});
|
|
770
487
|
}
|
|
771
488
|
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
489
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
490
|
+
if (
|
|
491
|
+
nextProps.chromInfoId !== this.currentChromInfoId ||
|
|
492
|
+
nextProps.chromInfoServer !== this.currentChromInfoServer
|
|
493
|
+
) {
|
|
494
|
+
this.currentChromInfoId = nextProps.chromInfoId;
|
|
495
|
+
this.currentChromInfoServer = nextProps.chromInfoServer;
|
|
778
496
|
|
|
497
|
+
this.fetchChromInfo(nextProps.chromInfoServer, nextProps.chromInfoId);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
render() {
|
|
779
502
|
return (
|
|
780
503
|
<div
|
|
781
504
|
ref={(c) => {
|
|
@@ -788,20 +511,6 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
788
511
|
this.props.theme === THEME_DARK,
|
|
789
512
|
})}
|
|
790
513
|
>
|
|
791
|
-
{!this.props.hideAvailableAssemblies && (
|
|
792
|
-
<select
|
|
793
|
-
ref={(c) => {
|
|
794
|
-
this.assemblyPickButton = c;
|
|
795
|
-
}}
|
|
796
|
-
className={styles['genome-position-search-bar-button']}
|
|
797
|
-
id={this.uid}
|
|
798
|
-
onChange={this.handleAssemblySelectEvt.bind(this)}
|
|
799
|
-
value={this.state.selectedAssembly || undefined}
|
|
800
|
-
>
|
|
801
|
-
{assemblyMenuItems}
|
|
802
|
-
</select>
|
|
803
|
-
)}
|
|
804
|
-
|
|
805
514
|
<Autocomplete
|
|
806
515
|
ref={(c) => {
|
|
807
516
|
this.autocompleteMenu = c;
|
|
@@ -809,8 +518,6 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
809
518
|
getItemValue={(item) => item.geneName}
|
|
810
519
|
inputProps={{
|
|
811
520
|
className: styles['genome-position-search-bar'],
|
|
812
|
-
title:
|
|
813
|
-
'Current location: enter a symbol or location to change the position of the current view',
|
|
814
521
|
}}
|
|
815
522
|
items={this.state.genes}
|
|
816
523
|
menuStyle={{
|
|
@@ -826,8 +533,8 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
826
533
|
onSubmit={this.searchFieldSubmit.bind(this)}
|
|
827
534
|
renderItem={(item, isHighlighted) => (
|
|
828
535
|
<div
|
|
829
|
-
key={item.
|
|
830
|
-
id={item.
|
|
536
|
+
key={item.geneName}
|
|
537
|
+
id={item.geneName}
|
|
831
538
|
style={
|
|
832
539
|
isHighlighted ? this.styles.highlightedItem : this.styles.item
|
|
833
540
|
}
|
|
@@ -836,12 +543,10 @@ class GenomePositionSearchBox extends React.Component {
|
|
|
836
543
|
</div>
|
|
837
544
|
)}
|
|
838
545
|
renderMenu={this.handleRenderMenu.bind(this)}
|
|
839
|
-
value={
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
}
|
|
844
|
-
wrapperStyle={{ width: '100%' }}
|
|
546
|
+
value={this.props.error || this.positionText}
|
|
547
|
+
wrapperStyle={{
|
|
548
|
+
width: '100%',
|
|
549
|
+
}}
|
|
845
550
|
/>
|
|
846
551
|
|
|
847
552
|
<SearchIcon
|
|
@@ -858,19 +563,15 @@ GenomePositionSearchBox.propTypes = {
|
|
|
858
563
|
autocompleteServer: PropTypes.string,
|
|
859
564
|
chromInfoId: PropTypes.string,
|
|
860
565
|
chromInfoServer: PropTypes.string,
|
|
861
|
-
chromInfoPath: PropTypes.string,
|
|
862
|
-
hideAvailableAssemblies: PropTypes.bool,
|
|
863
566
|
isFocused: PropTypes.bool,
|
|
864
|
-
pubSub: PropTypes.object,
|
|
865
567
|
onFocus: PropTypes.func,
|
|
866
|
-
onGeneSearch: PropTypes.func,
|
|
867
568
|
onSelectedAssemblyChanged: PropTypes.func,
|
|
868
569
|
registerViewportChangedListener: PropTypes.func,
|
|
869
570
|
removeViewportChangedListener: PropTypes.func,
|
|
870
571
|
setCenters: PropTypes.func,
|
|
871
|
-
theme: PropTypes.
|
|
572
|
+
theme: PropTypes.string,
|
|
872
573
|
trackSourceServers: PropTypes.array,
|
|
873
574
|
twoD: PropTypes.bool,
|
|
874
575
|
};
|
|
875
576
|
|
|
876
|
-
export default withPubSub(
|
|
577
|
+
export default withPubSub(GenomePositionSearchBox);
|