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.
Files changed (113) hide show
  1. package/README.md +19 -10
  2. package/app/scripts/{AddTrackDialog.js → AddTrackDialog.jsx} +27 -26
  3. package/app/scripts/{AddTrackPositionMenu.js → AddTrackPositionMenu.jsx} +18 -15
  4. package/app/scripts/{Autocomplete.js → Autocomplete.jsx} +1 -0
  5. package/app/scripts/{Button.js → Button.jsx} +7 -6
  6. package/app/scripts/CenterTiledPlot.jsx +7 -0
  7. package/app/scripts/{CenterTrack.js → CenterTrack.jsx} +42 -41
  8. package/app/scripts/ChromosomeGrid.js +8 -16
  9. package/app/scripts/CloseTrackMenu.jsx +27 -0
  10. package/app/scripts/CombinedTrack.js +16 -1
  11. package/app/scripts/{ConfigTrackMenu.js → ConfigTrackMenu.jsx} +12 -12
  12. package/app/scripts/{ConfigViewMenu.js → ConfigViewMenu.jsx} +35 -36
  13. package/app/scripts/{ConfigureSeriesMenu.js → ConfigureSeriesMenu.jsx} +2 -2
  14. package/app/scripts/{ContextMenuContainer.js → ContextMenuContainer.jsx} +5 -7
  15. package/app/scripts/ContextMenuItem.jsx +37 -0
  16. package/app/scripts/Cross.jsx +9 -0
  17. package/app/scripts/CustomTrackDialog.jsx +38 -0
  18. package/app/scripts/DataFetcher.js +6 -6
  19. package/app/scripts/{Dialog.js → Dialog.jsx} +40 -31
  20. package/app/scripts/{DragListeningDiv.js → DragListeningDiv.jsx} +10 -12
  21. package/app/scripts/{DraggableDiv.js → DraggableDiv.jsx} +25 -24
  22. package/app/scripts/{ExportLinkDialog.js → ExportLinkDialog.jsx} +2 -2
  23. package/app/scripts/{FixedTrack.js → FixedTrack.jsx} +0 -0
  24. package/app/scripts/{GalleryTracks.js → GalleryTracks.jsx} +10 -9
  25. package/app/scripts/{GenomePositionSearchBox.js → GenomePositionSearchBox.jsx} +14 -16
  26. package/app/scripts/{HeatmapOptions.js → HeatmapOptions.jsx} +0 -0
  27. package/app/scripts/HeatmapTiledPixiTrack.js +18 -30
  28. package/app/scripts/{HiGlassComponent.js → HiGlassComponent.jsx} +206 -85
  29. package/app/scripts/{HiGlassTrackComponent.js → HiGlassTrackComponent.jsx} +0 -0
  30. package/app/scripts/HorizontalChromosomeLabels.js +3 -6
  31. package/app/scripts/HorizontalHeatmapTrack.js +2 -6
  32. package/app/scripts/{HorizontalItem.js → HorizontalItem.jsx} +0 -0
  33. package/app/scripts/HorizontalRule.js +2 -0
  34. package/app/scripts/{HorizontalTiledPlot.js → HorizontalTiledPlot.jsx} +20 -19
  35. package/app/scripts/{HorizontalTrack.js → HorizontalTrack.jsx} +0 -0
  36. package/app/scripts/LeftTrackModifier.js +8 -0
  37. package/app/scripts/{ListWrapper.js → ListWrapper.jsx} +0 -0
  38. package/app/scripts/{Modal.js → Modal.jsx} +14 -9
  39. package/app/scripts/{MoveableTrack.js → MoveableTrack.jsx} +0 -0
  40. package/app/scripts/{NestedContextMenu.js → NestedContextMenu.jsx} +6 -7
  41. package/app/scripts/OSMTilesTrack.js +2 -6
  42. package/app/scripts/OverlayTrack.js +2 -0
  43. package/app/scripts/{PlotTypeChooser.js → PlotTypeChooser.jsx} +0 -0
  44. package/app/scripts/{PopupMenu.js → PopupMenu.jsx} +1 -1
  45. package/app/scripts/SearchField.js +5 -3
  46. package/app/scripts/{SeriesListItems.js → SeriesListItems.jsx} +6 -6
  47. package/app/scripts/{SeriesListMenu.js → SeriesListMenu.jsx} +29 -32
  48. package/app/scripts/{SeriesListSubmenuMixin.js → SeriesListSubmenuMixin.jsx} +0 -0
  49. package/app/scripts/{SketchInlinePicker.js → SketchInlinePicker.jsx} +0 -0
  50. package/app/scripts/{SortableList.js → SortableList.jsx} +0 -0
  51. package/app/scripts/Tiled1DPixiTrack.js +2 -5
  52. package/app/scripts/TiledPixiTrack.js +3 -1
  53. package/app/scripts/{TiledPlot.js → TiledPlot.jsx} +45 -17
  54. package/app/scripts/{TilesetFinder.js → TilesetFinder.jsx} +7 -7
  55. package/app/scripts/Track.js +17 -1
  56. package/app/scripts/{TrackArea.js → TrackArea.jsx} +0 -0
  57. package/app/scripts/{TrackControl.js → TrackControl.jsx} +44 -50
  58. package/app/scripts/{TrackRenderer.js → TrackRenderer.jsx} +44 -38
  59. package/app/scripts/{VerticalItem.js → VerticalItem.jsx} +0 -0
  60. package/app/scripts/VerticalRule.js +1 -0
  61. package/app/scripts/{VerticalTiledPlot.js → VerticalTiledPlot.jsx} +27 -18
  62. package/app/scripts/{VerticalTrack.js → VerticalTrack.jsx} +0 -0
  63. package/app/scripts/{ViewConfigEditor.js → ViewConfigEditor.jsx} +66 -58
  64. package/app/scripts/{ViewContextMenu.js → ViewContextMenu.jsx} +13 -13
  65. package/app/scripts/{ViewHeader.js → ViewHeader.jsx} +24 -23
  66. package/app/scripts/ViewportTracker2D.js +1 -2
  67. package/app/scripts/ViewportTrackerHorizontal.js +1 -2
  68. package/app/scripts/ViewportTrackerVertical.js +1 -2
  69. package/app/scripts/api.js +17 -10
  70. package/app/scripts/configs/available-for-plugins.js +4 -3
  71. package/app/scripts/configs/index.js +1 -47
  72. package/app/scripts/configs/positions-by-datatype.js +2 -0
  73. package/app/scripts/configs/primitives.js +47 -0
  74. package/app/scripts/configs/tracks-info.js +2 -2
  75. package/app/scripts/d3-context-menu.js +1 -0
  76. package/app/scripts/data-fetchers/get-data-fetcher.js +7 -2
  77. package/app/scripts/{hglib.js → hglib.jsx} +1 -1
  78. package/app/scripts/hocs/{with-modal.js → with-modal.jsx} +0 -0
  79. package/app/scripts/hocs/{with-pub-sub.js → with-pub-sub.jsx} +0 -0
  80. package/app/scripts/hocs/{with-theme.js → with-theme.jsx} +0 -0
  81. package/app/scripts/{icons.js → icons.jsx} +22 -12
  82. package/app/scripts/mixwith.js +2 -0
  83. package/app/scripts/services/tile-proxy.js +1 -5
  84. package/app/scripts/utils/abs-to-chr.js +1 -1
  85. package/app/scripts/utils/dec-to-hex-str.js +1 -1
  86. package/app/scripts/utils/dict-items.js +0 -1
  87. package/app/scripts/utils/dict-keys.js +0 -1
  88. package/app/scripts/utils/dict-values.js +0 -1
  89. package/app/scripts/utils/index.js +1 -0
  90. package/app/scripts/utils/range-query-2d.js +4 -1
  91. package/app/scripts/utils/selected-items-to-size.js +2 -3
  92. package/app/scripts/utils/{test-helpers.js → test-helpers.jsx} +32 -10
  93. package/app/scripts/utils/timeout.js +4 -1
  94. package/app/scripts/utils/value-to-color.js +14 -17
  95. package/app/scripts/worker.js +8 -4
  96. package/app/styles/GenomePositionSearchBox.module.scss +13 -15
  97. package/app/styles/HiGlass.scss +5 -5
  98. package/app/styles/TilesetFinder.css +94 -74
  99. package/app/styles/TrackControl.module.scss +17 -20
  100. package/app/styles/TrackOptions.css +23 -24
  101. package/app/styles/ViewHeader.module.scss +18 -18
  102. package/dist/hglib.css +1724 -1
  103. package/dist/hglib.js +80471 -154092
  104. package/dist/hglib.min.js +382 -2
  105. package/dist/index.html +251 -250
  106. package/package.json +57 -117
  107. package/CHANGELOG.md +0 -1415
  108. package/app/index.html +0 -273
  109. package/app/scripts/CenterTiledPlot.js +0 -5
  110. package/app/scripts/CloseTrackMenu.js +0 -25
  111. package/app/scripts/ContextMenuItem.js +0 -35
  112. package/app/scripts/Cross.js +0 -7
  113. package/app/scripts/factories/index.js +0 -1
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
- [![Build Status](https://travis-ci.org/higlass/higlass.svg?branch=master)](https://travis-ci.org/higlass/higlass)
1
+ ![Build Status](https://github.com/higlass/higlass/actions/workflows/ci.yml/badge.svg)
2
2
  [![Live Docs](https://img.shields.io/badge/docs-live-red.svg?colorB=0f9256)](https://docs.higlass.io/)
3
3
  [![DOI](https://zenodo.org/badge/56026057.svg)](https://zenodo.org/badge/latestdoi/56026057)
4
4
  [![Twitter](https://img.shields.io/badge/news-twitter-red.svg?colorB=6930bf)](https://twitter.com/higlass_io)
5
- [![Slack](https://img.shields.io/badge/join-Slack-red.svg?colorB=ff4000)](https://join.slack.com/t/higlass/shared_invite/zt-nv5h5hsi-tjM9ydx0EH3Svn4jx~tveQ)
5
+ [![Slack](https://img.shields.io/badge/join-Slack-red.svg?colorB=ff4000)](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:8080/.
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. To save time and only run relevant tests, open `karma.conf.js` and select the test files to run before running `test-watch`.
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
- npm run test-watch
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 = this.handleTilesetPickerDoubleClick.bind(
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
- {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
- }
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.isRequired,
224
- host: PropTypes.string.isRequired,
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 styleName="add-track-position-span">Add Track...</div>
16
- <table styleName={tableStyleNames}>
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 styleName="add-track-position-other" />
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 styleName="add-track-position-other" />
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 styleName="add-track-position-other" />
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 styleName="add-track-position-other" />
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
- disable={props.disable}
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 styleName="button-shortcut">{props.shortcut}</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.func.isRequired,
33
- disable: PropTypes.func.isRequired,
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;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+
3
+ function CenterTiledPlot() {
4
+ return <div className="center-plot" />;
5
+ }
6
+
7
+ export default CenterTiledPlot;
@@ -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, event } from 'd3-selection';
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(true, true)
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(true, true, true)
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(true)
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
- !this.sourceEvent ||
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
- !this.sourceEvent ||
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
- !this.sourceEvent ||
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
- !this.sourceEvent ||
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
- !this.sourceEvent ||
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 (!this.sourceEvent) return;
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 && !this.sourceEvent) {
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 && !this.sourceEvent) {
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 && !this.sourceEvent) {
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 rangeSelectorClass = 'stylesTrack.track-range-selection';
458
+ let rangeSelectorName = 'track-range-selection';
459
459
  if (this.props.isRangeSelectionActive) {
460
- rangeSelectorClass += this.props.is1dRangeSelection
460
+ rangeSelectorName += this.props.is1dRangeSelection
461
461
  ? '-active-secondary'
462
462
  : '-active-primary';
463
463
  }
464
464
 
465
- const rangeSelectorGroup1dClass = !this.props.is1dRangeSelection
466
- ? 'stylesTrack.track-range-selection-group-inactive'
467
- : '';
465
+ const rangeSelectorGroup1dClass = clsx(
466
+ !this.props.is1dRangeSelection &&
467
+ stylesTrack['track-range-selection-group-inactive'],
468
+ );
468
469
 
469
- const rangeSelectorGroup2dClass = this.props.is1dRangeSelection
470
- ? 'stylesTrack.track-range-selection-group-inactive'
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
- styleName={rangeSelectorGroup1dClass}
498
+ className={rangeSelectorGroup1dClass}
498
499
  />
499
500
  <g
500
501
  ref={(el) => {
501
502
  this.brushElY = select(el);
502
503
  }}
503
- styleName={rangeSelectorGroup1dClass}
504
+ className={rangeSelectorGroup1dClass}
504
505
  />
505
506
  <g
506
507
  ref={(el) => {
507
508
  this.brushElXY = select(el);
508
509
  }}
509
- styleName={rangeSelectorGroup2dClass}
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.isRequired,
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 = this.options.orientationsAndPositions[i]
144
- .orientation;
145
- const {
146
- left,
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 = this.options.orientationsAndPositions[i]
309
- .orientation;
310
- const {
311
- left,
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({ tracks, createTrackObject }) {
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();