higlass
Version:
HiGlass Hi-C / genomic / large data viewer
241 lines (204 loc) • 6.29 kB
JSX
// @ts-nocheck
import PropTypes from 'prop-types';
import React from 'react';
import Dialog from './Dialog';
import PlotTypeChooser from './PlotTypeChooser';
import TilesetFinder from './TilesetFinder';
// Configs
import { AVAILABLE_TRACK_TYPES } from './configs';
// Utils
import { getDefaultTrackForDatatype } from './utils';
// Styles
import '../styles/AddTrackDialog.module.scss';
export class AddTrackDialog extends React.Component {
constructor(props) {
super(props);
this.options = {};
this.state = {
selectedTilesets: [{ datatype: 'none' }],
allTracksSameDatatype: true, // Do all selected tracks have the same datatype
};
this.handleSubmitBound = this.handleSubmit.bind(this);
this.handleTilesetPickerDoubleClickBound =
this.handleTilesetPickerDoubleClick.bind(this);
this.selectedTilesetsChangedBound = this.selectedTilesetsChanged.bind(this);
}
/**
* Get the track available track orientations for the given
* track position. Generally "top" or "bottom" equal "1d-horizontal",
* "left" or "right" correspond to "1d-vertical" and "center" means "2d".
*
* Arguments
* ---------
* position: string
*
* Returns
* -------
*
* A string containing the track orientation.
*/
getOrientation(position) {
let orientation = null;
if (position === 'top' || position === 'bottom') {
orientation = '1d-horizontal';
} else if (position === 'left' || position === 'right') {
orientation = '1d-vertical';
} else {
orientation = '2d';
}
return orientation;
}
handleSubmit(evt) {
if (evt) evt.preventDefault();
this.props.onTracksChosen(
this.state.selectedTilesets,
this.props.position,
this.props.extent,
this.props.host,
);
}
/**
* The user double clicked a tileset in the tileset finder dialog.
* This means that only one is selected.
*
* Arguments
* ---------
* tileset: { uuid: 'CXCX', filetype: 'cooler' ....}
*/
handleTilesetPickerDoubleClick(tileset) {
this.selectedTilesetsChanged([tileset]);
// should iterate over the selected tilesets
this.props.onTracksChosen(
this.state.selectedTilesets,
this.props.position,
this.props.extent,
this.props.host,
);
}
handleOptionsChanged(newOptions) {
this.options = newOptions;
}
handlePlotTypeSelected(newPlotType) {
const { selectedTilesets } = this.state;
for (const tileset of selectedTilesets) {
tileset.type = newPlotType;
}
this.selectedPlotType = newPlotType;
this.setState({
selectedTilesets,
});
}
selectedTilesetsChanged(selectedTilesetsIn) {
let selectedTilesets = null;
if (selectedTilesetsIn.length === 0) {
// no tilesets are selected
selectedTilesets = [{ datatype: 'none' }];
} else {
selectedTilesets = selectedTilesetsIn;
}
let allTracksSameDatatype = true;
const firstDatatype = selectedTilesets[0].datatype;
for (const tileset of selectedTilesets) {
if (tileset.datatype !== firstDatatype) {
allTracksSameDatatype = false;
}
}
if (allTracksSameDatatype) {
// only one datatype is present in the set of selected tilesets
for (const tileset of selectedTilesets) {
tileset.type = this.selectedPlotType;
}
} else {
// more than one dataype present, we assign the default track type
// to each tileset
for (const tileset of selectedTilesets) {
let datatypes = [tileset.datatype];
const orientation = this.getOrientation(this.props.position);
if (tileset.filetype === 'cooler') {
datatypes = [tileset.datatype, 'chromsizes'];
}
const availableTrackTypes = AVAILABLE_TRACK_TYPES(
[datatypes],
orientation,
);
const defaultTrackType = getDefaultTrackForDatatype(
datatypes[0],
this.props.position,
availableTrackTypes,
);
tileset.type = defaultTrackType.type;
}
}
this.setState({ selectedTilesets, allTracksSameDatatype });
}
render() {
const orientation = this.getOrientation(this.props.position);
const form = (
<div>
<TilesetFinder
// Only for testing purposes
ref={(c) => {
this.tilesetFinder = c;
}}
datatype={this.props.datatype}
onDoubleClick={this.handleTilesetPickerDoubleClick.bind(this)}
onTracksChosen={(value) =>
this.props.onTracksChosen(
value,
this.props.position,
this.props.extent,
)
}
orientation={orientation}
selectedTilesetChanged={this.selectedTilesetsChanged.bind(this)}
trackSourceServers={this.props.trackSourceServers}
/>
</div>
);
return (
<Dialog
maxHeight={true}
okayTitle="Submit"
onCancel={this.props.onCancel}
onOkay={this.handleSubmitBound}
title="Add Track"
>
<>
{form}
{
<PlotTypeChooser
// Only for testing purposes
ref={(c) => {
this.plotTypeChooser = c;
}}
allTracksSameDatatype={this.state.allTracksSameDatatype}
datatypes={this.state.selectedTilesets.map((x) => {
if (x.filetype === 'cooler') {
// cooler files can also supply chromsizes
return [x.datatype, 'chromsizes'];
}
return [x.datatype];
})}
onPlotTypeSelected={this.handlePlotTypeSelected.bind(this)}
orientation={orientation}
position={this.props.position}
/>
}
</>
</Dialog>
);
}
}
AddTrackDialog.defaultProps = {
position: 'top',
};
AddTrackDialog.propTypes = {
datatype: PropTypes.string,
extent: PropTypes.string,
host: PropTypes.string,
onCancel: PropTypes.func.isRequired,
onTracksChosen: PropTypes.func.isRequired,
position: PropTypes.string,
trackSourceServers: PropTypes.array.isRequired,
};
export default AddTrackDialog;