higlass 1.11.11 → 1.12.0
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 +19 -10
- package/app/scripts/{AddTrackDialog.js → AddTrackDialog.jsx} +27 -26
- package/app/scripts/{AddTrackPositionMenu.js → AddTrackPositionMenu.jsx} +18 -15
- package/app/scripts/{Autocomplete.js → Autocomplete.jsx} +1 -0
- package/app/scripts/{Button.js → Button.jsx} +7 -6
- package/app/scripts/CenterTiledPlot.jsx +7 -0
- package/app/scripts/{CenterTrack.js → CenterTrack.jsx} +42 -41
- package/app/scripts/ChromosomeGrid.js +8 -16
- package/app/scripts/CloseTrackMenu.jsx +27 -0
- package/app/scripts/CombinedTrack.js +16 -1
- package/app/scripts/{ConfigTrackMenu.js → ConfigTrackMenu.jsx} +12 -12
- package/app/scripts/{ConfigViewMenu.js → ConfigViewMenu.jsx} +35 -36
- package/app/scripts/{ConfigureSeriesMenu.js → ConfigureSeriesMenu.jsx} +2 -2
- package/app/scripts/{ContextMenuContainer.js → ContextMenuContainer.jsx} +5 -7
- package/app/scripts/ContextMenuItem.jsx +37 -0
- package/app/scripts/Cross.jsx +9 -0
- package/app/scripts/CustomTrackDialog.jsx +38 -0
- package/app/scripts/DataFetcher.js +6 -6
- package/app/scripts/{Dialog.js → Dialog.jsx} +40 -31
- package/app/scripts/{DragListeningDiv.js → DragListeningDiv.jsx} +10 -12
- package/app/scripts/{DraggableDiv.js → DraggableDiv.jsx} +25 -24
- package/app/scripts/{ExportLinkDialog.js → ExportLinkDialog.jsx} +2 -2
- package/app/scripts/{FixedTrack.js → FixedTrack.jsx} +0 -0
- package/app/scripts/{GalleryTracks.js → GalleryTracks.jsx} +10 -9
- package/app/scripts/{GenomePositionSearchBox.js → GenomePositionSearchBox.jsx} +14 -16
- package/app/scripts/{HeatmapOptions.js → HeatmapOptions.jsx} +0 -0
- package/app/scripts/HeatmapTiledPixiTrack.js +18 -30
- package/app/scripts/{HiGlassComponent.js → HiGlassComponent.jsx} +206 -85
- package/app/scripts/{HiGlassTrackComponent.js → HiGlassTrackComponent.jsx} +0 -0
- package/app/scripts/HorizontalChromosomeLabels.js +3 -6
- package/app/scripts/HorizontalHeatmapTrack.js +2 -6
- package/app/scripts/{HorizontalItem.js → HorizontalItem.jsx} +0 -0
- package/app/scripts/HorizontalRule.js +2 -0
- package/app/scripts/{HorizontalTiledPlot.js → HorizontalTiledPlot.jsx} +20 -19
- package/app/scripts/{HorizontalTrack.js → HorizontalTrack.jsx} +0 -0
- package/app/scripts/LeftTrackModifier.js +8 -0
- package/app/scripts/{ListWrapper.js → ListWrapper.jsx} +0 -0
- package/app/scripts/{Modal.js → Modal.jsx} +14 -9
- package/app/scripts/{MoveableTrack.js → MoveableTrack.jsx} +0 -0
- package/app/scripts/{NestedContextMenu.js → NestedContextMenu.jsx} +6 -7
- package/app/scripts/OSMTilesTrack.js +2 -6
- package/app/scripts/OverlayTrack.js +2 -0
- package/app/scripts/{PlotTypeChooser.js → PlotTypeChooser.jsx} +0 -0
- package/app/scripts/{PopupMenu.js → PopupMenu.jsx} +1 -1
- package/app/scripts/SearchField.js +5 -3
- package/app/scripts/{SeriesListItems.js → SeriesListItems.jsx} +6 -6
- package/app/scripts/{SeriesListMenu.js → SeriesListMenu.jsx} +29 -32
- package/app/scripts/{SeriesListSubmenuMixin.js → SeriesListSubmenuMixin.jsx} +0 -0
- package/app/scripts/{SketchInlinePicker.js → SketchInlinePicker.jsx} +0 -0
- package/app/scripts/{SortableList.js → SortableList.jsx} +0 -0
- package/app/scripts/Tiled1DPixiTrack.js +2 -5
- package/app/scripts/TiledPixiTrack.js +3 -1
- package/app/scripts/{TiledPlot.js → TiledPlot.jsx} +45 -17
- package/app/scripts/{TilesetFinder.js → TilesetFinder.jsx} +7 -7
- package/app/scripts/Track.js +17 -1
- package/app/scripts/{TrackArea.js → TrackArea.jsx} +0 -0
- package/app/scripts/{TrackControl.js → TrackControl.jsx} +44 -50
- package/app/scripts/{TrackRenderer.js → TrackRenderer.jsx} +44 -38
- package/app/scripts/{VerticalItem.js → VerticalItem.jsx} +0 -0
- package/app/scripts/VerticalRule.js +1 -0
- package/app/scripts/{VerticalTiledPlot.js → VerticalTiledPlot.jsx} +27 -18
- package/app/scripts/{VerticalTrack.js → VerticalTrack.jsx} +0 -0
- package/app/scripts/{ViewConfigEditor.js → ViewConfigEditor.jsx} +66 -58
- package/app/scripts/{ViewContextMenu.js → ViewContextMenu.jsx} +13 -13
- package/app/scripts/{ViewHeader.js → ViewHeader.jsx} +24 -23
- package/app/scripts/ViewportTracker2D.js +1 -2
- package/app/scripts/ViewportTrackerHorizontal.js +1 -2
- package/app/scripts/ViewportTrackerVertical.js +1 -2
- package/app/scripts/api.js +17 -10
- package/app/scripts/configs/available-for-plugins.js +4 -3
- package/app/scripts/configs/index.js +1 -47
- package/app/scripts/configs/positions-by-datatype.js +2 -0
- package/app/scripts/configs/primitives.js +47 -0
- package/app/scripts/configs/tracks-info.js +2 -2
- package/app/scripts/d3-context-menu.js +1 -0
- package/app/scripts/data-fetchers/get-data-fetcher.js +7 -2
- package/app/scripts/{hglib.js → hglib.jsx} +1 -1
- package/app/scripts/hocs/{with-modal.js → with-modal.jsx} +0 -0
- package/app/scripts/hocs/{with-pub-sub.js → with-pub-sub.jsx} +0 -0
- package/app/scripts/hocs/{with-theme.js → with-theme.jsx} +0 -0
- package/app/scripts/{icons.js → icons.jsx} +22 -12
- package/app/scripts/mixwith.js +2 -0
- package/app/scripts/services/tile-proxy.js +1 -5
- package/app/scripts/utils/abs-to-chr.js +1 -1
- package/app/scripts/utils/dec-to-hex-str.js +1 -1
- package/app/scripts/utils/dict-items.js +0 -1
- package/app/scripts/utils/dict-keys.js +0 -1
- package/app/scripts/utils/dict-values.js +0 -1
- package/app/scripts/utils/index.js +1 -0
- package/app/scripts/utils/range-query-2d.js +4 -1
- package/app/scripts/utils/selected-items-to-size.js +2 -3
- package/app/scripts/utils/{test-helpers.js → test-helpers.jsx} +32 -10
- package/app/scripts/utils/timeout.js +4 -1
- package/app/scripts/utils/value-to-color.js +14 -17
- package/app/scripts/worker.js +8 -4
- package/app/styles/GenomePositionSearchBox.module.scss +13 -15
- package/app/styles/HiGlass.scss +5 -5
- package/app/styles/TilesetFinder.css +94 -74
- package/app/styles/TrackControl.module.scss +17 -20
- package/app/styles/TrackOptions.css +23 -24
- package/app/styles/ViewHeader.module.scss +18 -18
- package/dist/hglib.css +1724 -1
- package/dist/hglib.js +80471 -154092
- package/dist/hglib.min.js +382 -2
- package/dist/index.html +251 -250
- package/package.json +57 -117
- package/CHANGELOG.md +0 -1415
- package/app/index.html +0 -273
- package/app/scripts/CenterTiledPlot.js +0 -5
- package/app/scripts/CloseTrackMenu.js +0 -25
- package/app/scripts/ContextMenuItem.js +0 -35
- package/app/scripts/Cross.js +0 -7
- package/app/scripts/factories/index.js +0 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+

|
|
2
2
|
[](https://docs.higlass.io/)
|
|
3
3
|
[](https://zenodo.org/badge/latestdoi/56026057)
|
|
4
4
|
[](https://twitter.com/higlass_io)
|
|
5
|
-
[](https://
|
|
5
|
+
[](https://tinyurl.com/3z3bds4w)
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
### Introduction
|
|
@@ -33,22 +33,31 @@ Kerpedjiev, P., Abdennur, N., Lekschas, F., McCallum, C., Dinkla, K., Strobelt,
|
|
|
33
33
|
To run higlass from its source code simply run the following:
|
|
34
34
|
|
|
35
35
|
```
|
|
36
|
-
npm clean-install
|
|
36
|
+
npm clean-install // use --legacy-peer-deps if you get peer dependency errors
|
|
37
37
|
npm run start
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
This starts a server in development mode at http://localhost:
|
|
40
|
+
This starts a server in development mode at http://localhost:5173/.
|
|
41
|
+
|
|
42
|
+
> **Warning**
|
|
43
|
+
> The following examples need to be migrated to the latest build.
|
|
44
|
+
> Once started, a list of the examples can be found at [http://localhost:8080/examples.html](http://localhost:8080/examples.html).
|
|
45
|
+
> Template viewconfs located at `/docs/examples/viewconfs` can viewed directly at urls such as [http://localhost:8080/apis/svg.html?/viewconfs/overlay-tracks.json](http://localhost:8080/apis/svg.html?/viewconfs/overlay-tracks.json).
|
|
41
46
|
|
|
42
|
-
Once started, a list of the examples can be found at [http://localhost:8080/examples.html](http://localhost:8080/examples.html).
|
|
43
|
-
Template viewconfs located at `/docs/examples/viewconfs` can viewed directly at urls such as [http://localhost:8080/apis/svg.html?/viewconfs/overlay-tracks.json](http://localhost:8080/apis/svg.html?/viewconfs/overlay-tracks.json).
|
|
44
47
|
|
|
45
48
|
### Tests
|
|
46
49
|
|
|
47
|
-
The tests for the React components and API functions are located in the `test` directory.
|
|
50
|
+
The tests for the React components and API functions are located in the `test` directory.
|
|
51
|
+
Tests are run with [`web-test-runner`](https://modern-web.dev/docs/test-runner/overview/), which you can learn more about the CLI in the [documentation](https://modern-web.dev/docs/test-runner/cli-and-configuration/#test-runner-cli-and-configuration).
|
|
48
52
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
Useful commands:
|
|
54
|
+
|
|
55
|
+
- Run all tests: `npm test`
|
|
56
|
+
- Run all tests in interactive "watch" mode: `npm test -- --watch`
|
|
57
|
+
- Run a specific test or "glob" of tests: `npm test -- test/APITests.js [--watch]`
|
|
58
|
+
- Manually run individual tests in an open browser window: `npm test -- --manual`
|
|
59
|
+
|
|
60
|
+
There can sometimes be import issues due to timeouts when running tests after a clean installation. It is best to run `npm run optimize` prior to running tests for the first time.
|
|
52
61
|
|
|
53
62
|
**Troubleshooting:**
|
|
54
63
|
|
|
@@ -27,9 +27,8 @@ class AddTrackDialog extends React.Component {
|
|
|
27
27
|
|
|
28
28
|
this.handleSubmitBound = this.handleSubmit.bind(this);
|
|
29
29
|
|
|
30
|
-
this.handleTilesetPickerDoubleClickBound =
|
|
31
|
-
this
|
|
32
|
-
);
|
|
30
|
+
this.handleTilesetPickerDoubleClickBound =
|
|
31
|
+
this.handleTilesetPickerDoubleClick.bind(this);
|
|
33
32
|
this.selectedTilesetsChangedBound = this.selectedTilesetsChanged.bind(this);
|
|
34
33
|
}
|
|
35
34
|
|
|
@@ -189,27 +188,29 @@ class AddTrackDialog extends React.Component {
|
|
|
189
188
|
onOkay={this.handleSubmitBound}
|
|
190
189
|
title="Add Track"
|
|
191
190
|
>
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
191
|
+
<>
|
|
192
|
+
{form}
|
|
193
|
+
{
|
|
194
|
+
<PlotTypeChooser
|
|
195
|
+
// Only for testing purposes
|
|
196
|
+
ref={(c) => {
|
|
197
|
+
this.plotTypeChooser = c;
|
|
198
|
+
}}
|
|
199
|
+
allTracksSameDatatype={this.state.allTracksSameDatatype}
|
|
200
|
+
datatypes={this.state.selectedTilesets.map((x) => {
|
|
201
|
+
if (x.filetype === 'cooler') {
|
|
202
|
+
// cooler files can also supply chromsizes
|
|
203
|
+
return [x.datatype, 'chromsizes'];
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return [x.datatype];
|
|
207
|
+
})}
|
|
208
|
+
onPlotTypeSelected={this.handlePlotTypeSelected.bind(this)}
|
|
209
|
+
orientation={orientation}
|
|
210
|
+
position={this.props.position}
|
|
211
|
+
/>
|
|
212
|
+
}
|
|
213
|
+
</>
|
|
213
214
|
</Dialog>
|
|
214
215
|
);
|
|
215
216
|
}
|
|
@@ -220,8 +221,8 @@ AddTrackDialog.defaultProps = {
|
|
|
220
221
|
};
|
|
221
222
|
|
|
222
223
|
AddTrackDialog.propTypes = {
|
|
223
|
-
datatype: PropTypes.string
|
|
224
|
-
host: PropTypes.string
|
|
224
|
+
datatype: PropTypes.string,
|
|
225
|
+
host: PropTypes.string,
|
|
225
226
|
onCancel: PropTypes.func.isRequired,
|
|
226
227
|
onTracksChosen: PropTypes.func.isRequired,
|
|
227
228
|
position: PropTypes.string,
|
|
@@ -1,59 +1,62 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
import clsx from 'clsx';
|
|
3
4
|
|
|
4
5
|
import withTheme from './hocs/with-theme';
|
|
5
6
|
import { THEME_DARK } from './configs';
|
|
6
7
|
|
|
7
|
-
import '../styles/AddTrackPositionMenu.module.scss';
|
|
8
|
+
import classes from '../styles/AddTrackPositionMenu.module.scss';
|
|
8
9
|
|
|
9
10
|
function AddTrackPositionMenu(props) {
|
|
10
|
-
let tableStyleNames = 'add-track-position-table';
|
|
11
|
-
if (props.theme === THEME_DARK)
|
|
12
|
-
tableStyleNames += ' add-track-position-table-dark';
|
|
13
11
|
return (
|
|
14
12
|
<div>
|
|
15
|
-
<div
|
|
16
|
-
<table
|
|
13
|
+
<div className={classes['add-track-position-span']}>Add Track...</div>
|
|
14
|
+
<table
|
|
15
|
+
className={clsx(classes['add-track-position-table'], {
|
|
16
|
+
[classes['add-track-position-table-dark']]:
|
|
17
|
+
props.theme === THEME_DARK,
|
|
18
|
+
})}
|
|
19
|
+
>
|
|
17
20
|
<tbody>
|
|
18
21
|
<tr style={{ height: '30px' }}>
|
|
19
|
-
<td
|
|
22
|
+
<td className={classes['add-track-position-other']} />
|
|
20
23
|
<td
|
|
24
|
+
className={classes['add-track-position-top-center']}
|
|
21
25
|
onClick={() => props.onTrackPositionChosen('top')}
|
|
22
|
-
styleName="add-track-position-top-center"
|
|
23
26
|
>
|
|
24
27
|
top
|
|
25
28
|
</td>
|
|
26
|
-
<td
|
|
29
|
+
<td className={classes['add-track-position-other']} />
|
|
27
30
|
</tr>
|
|
28
31
|
<tr style={{ height: '80px' }}>
|
|
29
32
|
<td
|
|
33
|
+
className={classes['add-track-position-middle-left']}
|
|
30
34
|
onClick={() => props.onTrackPositionChosen('left')}
|
|
31
|
-
styleName="add-track-position-middle-left"
|
|
32
35
|
>
|
|
33
36
|
left
|
|
34
37
|
</td>
|
|
35
38
|
<td
|
|
39
|
+
className={classes['add-track-position-middle-middle']}
|
|
36
40
|
onClick={() => props.onTrackPositionChosen('center')}
|
|
37
|
-
styleName="add-track-position-middle-middle"
|
|
38
41
|
>
|
|
39
42
|
center
|
|
40
43
|
</td>
|
|
41
44
|
<td
|
|
45
|
+
className={classes['add-track-position-middle-right']}
|
|
42
46
|
onClick={() => props.onTrackPositionChosen('right')}
|
|
43
|
-
styleName="add-track-position-middle-right"
|
|
44
47
|
>
|
|
45
48
|
right
|
|
46
49
|
</td>
|
|
47
50
|
</tr>
|
|
48
51
|
<tr style={{ height: '30px' }}>
|
|
49
|
-
<td
|
|
52
|
+
<td className={classes['add-track-position-other']} />
|
|
50
53
|
<td
|
|
54
|
+
className={classes['add-track-position-bottom-middle']}
|
|
51
55
|
onClick={() => props.onTrackPositionChosen('bottom')}
|
|
52
|
-
styleName="add-track-position-bottom-middle"
|
|
53
56
|
>
|
|
54
57
|
bottom
|
|
55
58
|
</td>
|
|
56
|
-
<td
|
|
59
|
+
<td className={classes['add-track-position-other']} />
|
|
57
60
|
</tr>
|
|
58
61
|
</tbody>
|
|
59
62
|
</table>
|
|
@@ -371,6 +371,7 @@ class Autocomplete extends React.Component {
|
|
|
371
371
|
this.handleKeyUp.bind(this),
|
|
372
372
|
inputProps.onKeyUp && inputProps.onKeyUp.bind(this),
|
|
373
373
|
)}
|
|
374
|
+
// eslint-disable-next-line jsx-a11y/role-has-required-aria-props
|
|
374
375
|
role="combobox"
|
|
375
376
|
value={this.props.value}
|
|
376
377
|
/>
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
|
|
4
|
-
import '../styles/Button.module.scss';
|
|
4
|
+
import classes from '../styles/Button.module.scss';
|
|
5
5
|
|
|
6
6
|
const Button = React.forwardRef((props, ref) => (
|
|
7
7
|
<button
|
|
8
8
|
ref={ref}
|
|
9
|
-
|
|
9
|
+
className={classes[props.styleName] ?? classes.button}
|
|
10
|
+
disabled={props.disable}
|
|
10
11
|
onBlur={props.onBlur}
|
|
11
12
|
onClick={props.onClick}
|
|
12
13
|
onMouseDown={props.onMouseDown}
|
|
13
14
|
onMouseOut={props.onMouseOut}
|
|
14
15
|
onMouseUp={props.onMouseUp}
|
|
15
|
-
styleName="button"
|
|
16
16
|
type="button"
|
|
17
17
|
>
|
|
18
18
|
{props.children}
|
|
19
19
|
{props.shortcut && (
|
|
20
|
-
<span
|
|
20
|
+
<span className={classes['button-shortcut']}>{props.shortcut}</span>
|
|
21
21
|
)}
|
|
22
22
|
</button>
|
|
23
23
|
));
|
|
@@ -29,8 +29,8 @@ Button.defaultProps = {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
Button.propTypes = {
|
|
32
|
-
children: PropTypes.
|
|
33
|
-
disable: PropTypes.
|
|
32
|
+
children: PropTypes.any,
|
|
33
|
+
disable: PropTypes.bool,
|
|
34
34
|
onBlur: PropTypes.func,
|
|
35
35
|
onClick: PropTypes.func,
|
|
36
36
|
onMouseDown: PropTypes.func,
|
|
@@ -38,6 +38,7 @@ Button.propTypes = {
|
|
|
38
38
|
onMouseUp: PropTypes.func,
|
|
39
39
|
shortcut: PropTypes.string,
|
|
40
40
|
type: PropTypes.string,
|
|
41
|
+
styleName: PropTypes.string,
|
|
41
42
|
};
|
|
42
43
|
|
|
43
44
|
export default Button;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import PropTypes from 'prop-types';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import { brush, brushX, brushY } from 'd3-brush';
|
|
4
|
-
import { select
|
|
5
|
+
import { select } from 'd3-selection';
|
|
6
|
+
import clsx from 'clsx';
|
|
5
7
|
|
|
6
8
|
import TrackControl from './TrackControl';
|
|
7
9
|
|
|
@@ -19,6 +21,10 @@ const STYLES = {
|
|
|
19
21
|
pointerEvents: 'all',
|
|
20
22
|
};
|
|
21
23
|
|
|
24
|
+
function sourceEvent(event) {
|
|
25
|
+
return event && event.sourceEvent;
|
|
26
|
+
}
|
|
27
|
+
|
|
22
28
|
class CenterTrack extends React.Component {
|
|
23
29
|
constructor(props) {
|
|
24
30
|
super(props);
|
|
@@ -27,15 +33,15 @@ class CenterTrack extends React.Component {
|
|
|
27
33
|
isVisible: false,
|
|
28
34
|
};
|
|
29
35
|
|
|
30
|
-
this.brushBehaviorX = brushX(
|
|
36
|
+
this.brushBehaviorX = brushX()
|
|
31
37
|
.on('brush', this.brushedX.bind(this))
|
|
32
38
|
.on('end', this.brushedXEnded.bind(this));
|
|
33
39
|
|
|
34
|
-
this.brushBehaviorY = brushY(
|
|
40
|
+
this.brushBehaviorY = brushY()
|
|
35
41
|
.on('brush', this.brushedY.bind(this))
|
|
36
42
|
.on('end', this.brushedYEnded.bind(this));
|
|
37
43
|
|
|
38
|
-
this.brushBehaviorXY = brush(
|
|
44
|
+
this.brushBehaviorXY = brush()
|
|
39
45
|
.on('start', this.brushStarted.bind(this))
|
|
40
46
|
.on('brush', this.brushedXY.bind(this))
|
|
41
47
|
.on('end', this.brushedXYEnded.bind(this));
|
|
@@ -105,12 +111,6 @@ class CenterTrack extends React.Component {
|
|
|
105
111
|
}
|
|
106
112
|
}
|
|
107
113
|
|
|
108
|
-
/* --------------------------- Getter / Setter ---------------------------- */
|
|
109
|
-
|
|
110
|
-
get sourceEvent() {
|
|
111
|
-
return event && event.sourceEvent;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
114
|
/* ---------------------------- Custom Methods ---------------------------- */
|
|
115
115
|
|
|
116
116
|
addBrush1d() {
|
|
@@ -170,13 +170,13 @@ class CenterTrack extends React.Component {
|
|
|
170
170
|
);
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
brushedX() {
|
|
173
|
+
brushedX(event) {
|
|
174
174
|
// Need to reassign variable to check after reset
|
|
175
175
|
const rangeSelectionMoved = this.rangeSelectionMoved;
|
|
176
176
|
this.rangeSelectionMoved = false;
|
|
177
177
|
|
|
178
178
|
if (
|
|
179
|
-
!
|
|
179
|
+
!sourceEvent(event) ||
|
|
180
180
|
!this.props.onRangeSelectionX ||
|
|
181
181
|
!this.props.is1dRangeSelection ||
|
|
182
182
|
rangeSelectionMoved
|
|
@@ -187,12 +187,12 @@ class CenterTrack extends React.Component {
|
|
|
187
187
|
this.props.onRangeSelectionX(event.selection);
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
brushedXEnded() {
|
|
190
|
+
brushedXEnded(event) {
|
|
191
191
|
const rangeSelectionMovedEnd = this.rangeSelectionMovedEnd;
|
|
192
192
|
this.rangeSelectionMovedEnd = false;
|
|
193
193
|
|
|
194
194
|
if (
|
|
195
|
-
!
|
|
195
|
+
!sourceEvent(event) ||
|
|
196
196
|
!this.props.onRangeSelectionX ||
|
|
197
197
|
!this.props.is1dRangeSelection ||
|
|
198
198
|
rangeSelectionMovedEnd
|
|
@@ -204,13 +204,13 @@ class CenterTrack extends React.Component {
|
|
|
204
204
|
this.props.onRangeSelectionXEnd(event.selection);
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
brushedY() {
|
|
207
|
+
brushedY(event) {
|
|
208
208
|
// Need to reassign variable to check after reset
|
|
209
209
|
const rangeSelectionMoved = this.rangeSelectionMoved;
|
|
210
210
|
this.rangeSelectionMoved = false;
|
|
211
211
|
|
|
212
212
|
if (
|
|
213
|
-
!
|
|
213
|
+
!sourceEvent(event) ||
|
|
214
214
|
!this.props.onRangeSelectionY ||
|
|
215
215
|
!this.props.is1dRangeSelection ||
|
|
216
216
|
rangeSelectionMoved
|
|
@@ -221,12 +221,12 @@ class CenterTrack extends React.Component {
|
|
|
221
221
|
this.props.onRangeSelectionY(event.selection);
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
brushedYEnded() {
|
|
224
|
+
brushedYEnded(event) {
|
|
225
225
|
const rangeSelectionMovedEnd = this.rangeSelectionMovedEnd;
|
|
226
226
|
this.rangeSelectionMovedEnd = false;
|
|
227
227
|
|
|
228
228
|
if (
|
|
229
|
-
!
|
|
229
|
+
!sourceEvent(event) ||
|
|
230
230
|
!this.props.onRangeSelectionY ||
|
|
231
231
|
!this.props.is1dRangeSelection ||
|
|
232
232
|
rangeSelectionMovedEnd
|
|
@@ -238,13 +238,13 @@ class CenterTrack extends React.Component {
|
|
|
238
238
|
this.props.onRangeSelectionYEnd(event.selection);
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
brushedXY() {
|
|
241
|
+
brushedXY(event) {
|
|
242
242
|
// Need to reassign variable to check after reset
|
|
243
243
|
const rangeSelectionMoved = this.rangeSelectionMoved;
|
|
244
244
|
this.rangeSelectionMoved = false;
|
|
245
245
|
|
|
246
246
|
if (
|
|
247
|
-
!
|
|
247
|
+
!sourceEvent(event) ||
|
|
248
248
|
!this.props.onRangeSelectionXY ||
|
|
249
249
|
rangeSelectionMoved ||
|
|
250
250
|
this.props.is1dRangeSelection
|
|
@@ -258,7 +258,7 @@ class CenterTrack extends React.Component {
|
|
|
258
258
|
]);
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
brushedXYEnded() {
|
|
261
|
+
brushedXYEnded(event) {
|
|
262
262
|
if (this.props.is1dRangeSelection) return;
|
|
263
263
|
|
|
264
264
|
const rangeSelectionMovedEnd = this.rangeSelectionMovedEnd;
|
|
@@ -285,14 +285,14 @@ class CenterTrack extends React.Component {
|
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
-
brushStarted() {
|
|
289
|
-
if (!
|
|
288
|
+
brushStarted(event) {
|
|
289
|
+
if (!sourceEvent(event)) return;
|
|
290
290
|
|
|
291
291
|
this.props.onRangeSelectionStart();
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
moveBrushX(rangeSelection, animate = false) {
|
|
295
|
-
if (!this.brushEl
|
|
295
|
+
if (!this.brushEl) {
|
|
296
296
|
return;
|
|
297
297
|
}
|
|
298
298
|
|
|
@@ -319,7 +319,7 @@ class CenterTrack extends React.Component {
|
|
|
319
319
|
}
|
|
320
320
|
|
|
321
321
|
moveBrushY(rangeSelection, animate = false) {
|
|
322
|
-
if (!this.brushEl
|
|
322
|
+
if (!this.brushEl) {
|
|
323
323
|
return;
|
|
324
324
|
}
|
|
325
325
|
|
|
@@ -346,7 +346,7 @@ class CenterTrack extends React.Component {
|
|
|
346
346
|
}
|
|
347
347
|
|
|
348
348
|
moveBrushXY(rangeSelection, animate = false) {
|
|
349
|
-
if (!this.brushEl
|
|
349
|
+
if (!this.brushEl) {
|
|
350
350
|
return;
|
|
351
351
|
}
|
|
352
352
|
|
|
@@ -455,58 +455,59 @@ class CenterTrack extends React.Component {
|
|
|
455
455
|
return false;
|
|
456
456
|
});
|
|
457
457
|
|
|
458
|
-
let
|
|
458
|
+
let rangeSelectorName = 'track-range-selection';
|
|
459
459
|
if (this.props.isRangeSelectionActive) {
|
|
460
|
-
|
|
460
|
+
rangeSelectorName += this.props.is1dRangeSelection
|
|
461
461
|
? '-active-secondary'
|
|
462
462
|
: '-active-primary';
|
|
463
463
|
}
|
|
464
464
|
|
|
465
|
-
const rangeSelectorGroup1dClass =
|
|
466
|
-
|
|
467
|
-
|
|
465
|
+
const rangeSelectorGroup1dClass = clsx(
|
|
466
|
+
!this.props.is1dRangeSelection &&
|
|
467
|
+
stylesTrack['track-range-selection-group-inactive'],
|
|
468
|
+
);
|
|
468
469
|
|
|
469
|
-
const rangeSelectorGroup2dClass =
|
|
470
|
-
|
|
471
|
-
|
|
470
|
+
const rangeSelectorGroup2dClass = clsx(
|
|
471
|
+
this.props.is1dRangeSelection &&
|
|
472
|
+
stylesTrack['track-range-selection-group-inactive'],
|
|
473
|
+
);
|
|
472
474
|
|
|
473
475
|
return (
|
|
474
476
|
<div
|
|
475
|
-
className={this.props.className}
|
|
477
|
+
className={clsx(this.props.className, styles['center-track'])}
|
|
476
478
|
onMouseEnter={this.mouseEnterHandler.bind(this)}
|
|
477
479
|
onMouseLeave={this.mouseLeaveHandler.bind(this)}
|
|
478
480
|
style={{
|
|
479
481
|
height: this.props.height,
|
|
480
482
|
width: this.props.width,
|
|
481
483
|
}}
|
|
482
|
-
styleName="styles.center-track"
|
|
483
484
|
>
|
|
484
485
|
{isBrushable && (
|
|
485
486
|
<svg
|
|
487
|
+
className={stylesTrack[rangeSelectorName]}
|
|
486
488
|
style={{
|
|
487
489
|
height: this.props.height,
|
|
488
490
|
width: this.props.width,
|
|
489
491
|
}}
|
|
490
|
-
styleName={rangeSelectorClass}
|
|
491
492
|
xmlns="http://www.w3.org/2000/svg"
|
|
492
493
|
>
|
|
493
494
|
<g
|
|
494
495
|
ref={(el) => {
|
|
495
496
|
this.brushElX = select(el);
|
|
496
497
|
}}
|
|
497
|
-
|
|
498
|
+
className={rangeSelectorGroup1dClass}
|
|
498
499
|
/>
|
|
499
500
|
<g
|
|
500
501
|
ref={(el) => {
|
|
501
502
|
this.brushElY = select(el);
|
|
502
503
|
}}
|
|
503
|
-
|
|
504
|
+
className={rangeSelectorGroup1dClass}
|
|
504
505
|
/>
|
|
505
506
|
<g
|
|
506
507
|
ref={(el) => {
|
|
507
508
|
this.brushElXY = select(el);
|
|
508
509
|
}}
|
|
509
|
-
|
|
510
|
+
className={rangeSelectorGroup2dClass}
|
|
510
511
|
/>
|
|
511
512
|
</svg>
|
|
512
513
|
)}
|
|
@@ -548,7 +549,7 @@ CenterTrack.defaultProps = {
|
|
|
548
549
|
CenterTrack.propTypes = {
|
|
549
550
|
className: PropTypes.string,
|
|
550
551
|
configTrackMenuId: PropTypes.string,
|
|
551
|
-
editable: PropTypes.bool
|
|
552
|
+
editable: PropTypes.bool,
|
|
552
553
|
height: PropTypes.number.isRequired,
|
|
553
554
|
is1dRangeSelection: PropTypes.bool,
|
|
554
555
|
isRangeSelectionActive: PropTypes.bool,
|
|
@@ -140,14 +140,10 @@ class ChromosomeGrid extends PixiTrack {
|
|
|
140
140
|
this.mask2d.beginFill(0xff0000);
|
|
141
141
|
|
|
142
142
|
for (let i = 0; i < this.options.orientationsAndPositions.length; i++) {
|
|
143
|
-
const orientation =
|
|
144
|
-
.orientation;
|
|
145
|
-
const {
|
|
146
|
-
|
|
147
|
-
top,
|
|
148
|
-
width,
|
|
149
|
-
height,
|
|
150
|
-
} = this.options.orientationsAndPositions[i].position;
|
|
143
|
+
const orientation =
|
|
144
|
+
this.options.orientationsAndPositions[i].orientation;
|
|
145
|
+
const { left, top, width, height } =
|
|
146
|
+
this.options.orientationsAndPositions[i].position;
|
|
151
147
|
|
|
152
148
|
if (orientation === '1d-horizontal') {
|
|
153
149
|
this.mask1dH.drawRect(left, top, width, height);
|
|
@@ -305,14 +301,10 @@ class ChromosomeGrid extends PixiTrack {
|
|
|
305
301
|
|
|
306
302
|
if (this.isOverlay) {
|
|
307
303
|
for (let i = 0; i < this.options.orientationsAndPositions.length; i++) {
|
|
308
|
-
const orientation =
|
|
309
|
-
.orientation;
|
|
310
|
-
const {
|
|
311
|
-
|
|
312
|
-
top,
|
|
313
|
-
width,
|
|
314
|
-
height,
|
|
315
|
-
} = this.options.orientationsAndPositions[i].position;
|
|
304
|
+
const orientation =
|
|
305
|
+
this.options.orientationsAndPositions[i].orientation;
|
|
306
|
+
const { left, top, width, height } =
|
|
307
|
+
this.options.orientationsAndPositions[i].position;
|
|
316
308
|
this.drawLinesSvg(output, orientation, width, height, left, top);
|
|
317
309
|
}
|
|
318
310
|
} else {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
import ContextMenuItem from './ContextMenuItem';
|
|
5
|
+
import { getSeriesItems } from './SeriesListItems';
|
|
6
|
+
|
|
7
|
+
// Styles
|
|
8
|
+
import classes from '../styles/ContextMenu.module.scss';
|
|
9
|
+
|
|
10
|
+
function CloseTrackMenu(props) {
|
|
11
|
+
return (
|
|
12
|
+
<div>
|
|
13
|
+
{getSeriesItems(props.tracks, null, null, props.onCloseTrack)}
|
|
14
|
+
<hr className={classes['context-menu-hr']} />
|
|
15
|
+
<ContextMenuItem onClick={() => props.onCloseTrack(props.tracks[0].uid)}>
|
|
16
|
+
Close all series
|
|
17
|
+
</ContextMenuItem>
|
|
18
|
+
</div>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
CloseTrackMenu.propTypes = {
|
|
23
|
+
onCloseTrack: PropTypes.func.isRequired,
|
|
24
|
+
tracks: PropTypes.array.isRequired,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default CloseTrackMenu;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import slugid from 'slugid';
|
|
2
2
|
|
|
3
3
|
class CombinedTrack {
|
|
4
|
-
constructor(
|
|
4
|
+
constructor(context) {
|
|
5
|
+
this.context = context;
|
|
6
|
+
const { tracks, createTrackObject } = context;
|
|
7
|
+
|
|
5
8
|
this.childTracks = tracks.map(createTrackObject);
|
|
6
9
|
this.createdTracks = {};
|
|
7
10
|
this.uid = slugid.nice();
|
|
@@ -105,6 +108,18 @@ class CombinedTrack {
|
|
|
105
108
|
// }
|
|
106
109
|
// }
|
|
107
110
|
|
|
111
|
+
clickOutside() {
|
|
112
|
+
for (let i = 0; i < this.childTracks.length; i++) {
|
|
113
|
+
this.childTracks[i].clickOutside();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
click(...args) {
|
|
118
|
+
for (let i = 0; i < this.childTracks.length; i++) {
|
|
119
|
+
this.childTracks[i].click(...args);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
108
123
|
draw() {
|
|
109
124
|
// for (let i = 0; i < this.childTracks.length; i++) {
|
|
110
125
|
// this.childTracks[i].draw();
|