Skip to content

Commit

Permalink
3d support region set view
Browse files Browse the repository at this point in the history
  • Loading branch information
lidaof committed Mar 14, 2022
1 parent cebed7e commit 819a669
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 114 deletions.
21 changes: 12 additions & 9 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,14 @@ interface AppStateProps {
suggestedMetaSets: Set<string>;
}

interface RGBAColor {
rgb: {
r: number;
g: number;
b: number;
a: number;
}
}
// interface RGBAColor {
// rgb: {
// r: number;
// g: number;
// b: number;
// a: number;
// }
// }

class App extends React.PureComponent<AppProps, AppStateProps> {
static propTypes = {
Expand Down Expand Up @@ -265,7 +265,10 @@ class App extends React.PureComponent<AppProps, AppStateProps> {

newHighlight = (start: number, end: number, tag: string = '') => {
const interval = new HighlightInterval(start, end, tag);
this.props.onSetHighlights([...this.props.highlights, interval])
const existing = this.props.highlights.find(h => h.start === start && h.end === end)
if (!existing) {
this.props.onSetHighlights([...this.props.highlights, interval])
}
}

// setHighlightColor = (color: RGBAColor) => {
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/AppLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ function mapStateToProps(state) {
tracks: state.browser.present.tracks,
isShowingVR: state.browser.present.isShowingVR,
layout: state.browser.present.layout,
selectedSet: state.browser.present.regionSetView,
};
}

Expand All @@ -47,6 +48,7 @@ const callbacks = {
onTracksChanged: ActionCreators.setTracks,
onToggleVR: ActionCreators.toggleVR,
onSetLayout: ActionCreators.setLayout,
onSetSelected: ActionCreators.setRegionSetView,
};

class AppLayout extends React.PureComponent {
Expand Down Expand Up @@ -280,7 +282,7 @@ class AppLayout extends React.PureComponent {

render3dmolContainer = (node) => {
const model = node.getModel();
const { viewRegion, genomeConfig, tracks, onNewViewRegion } = this.props;
const { viewRegion, genomeConfig, tracks, onNewViewRegion, onSetSelected, selectedSet } = this.props;
const config = node.getConfig();
const { x, y, width, height } = node.getRect();
const g3dtrack = TrackModel.deserialize(config.trackModel);
Expand Down Expand Up @@ -317,6 +319,8 @@ class AppLayout extends React.PureComponent {
onToggleSync3d={this.toggleSync3d}
onGetViewer3dAndNumFrames={this.getViewer3dAndNumFrames}
imageInfo={this.state.imageInfo}
onSetSelected={onSetSelected}
selectedSet={selectedSet}
/>
);
};
Expand Down
58 changes: 29 additions & 29 deletions frontend/src/components/Nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import PropTypes from "prop-types";
import ReactModal from "react-modal";
import _ from "lodash";
import { connect } from "react-redux";
import { RadioGroup, Radio } from "react-radio-group";
// import { RadioGroup, Radio } from "react-radio-group";
import Button from "@material-ui/core/Button";
import { ArrowBack } from "@material-ui/icons";
import { IconButton } from "@material-ui/core";
import { ActionCreators } from "../AppState";
import DisplayedRegionModel from "../model/DisplayedRegionModel";
import { getSpeciesInfo, allGenomes } from "../model/genomes/allGenomes";
import { getSpeciesInfo } from "../model/genomes/allGenomes";
import TrackRegionController from "./genomeNavigator/TrackRegionController";
import RegionSetSelector from "./RegionSetSelector";
import Geneplot from "./Geneplot/Geneplot";
Expand Down Expand Up @@ -77,8 +77,8 @@ class Nav extends React.Component {
otherGenome: null,
};
this.debounced = _.debounce(this.props.onLegendWidthChange, 250);
this.renderOtherGenomes = this.renderOtherGenomes.bind(this);
this.handleOtherGenomeChange = this.handleOtherGenomeChange.bind(this);
// this.renderOtherGenomes = this.renderOtherGenomes.bind(this);
// this.handleOtherGenomeChange = this.handleOtherGenomeChange.bind(this);
}

componentDidMount() {
Expand Down Expand Up @@ -121,32 +121,32 @@ class Nav extends React.Component {
}
};

handleOtherGenomeChange(value) {
this.setState({ otherGenome: value });
}
// handleOtherGenomeChange(value) {
// this.setState({ otherGenome: value });
// }

renderOtherGenomes() {
const genomeName = this.props.genomeConfig.genome.getName();
const otherGenomes = allGenomes.map((g) => g.genome.getName()).filter((g) => g !== genomeName);
const radios = otherGenomes.map((g) => {
const { name } = getSpeciesInfo(g);
return (
<label key={g} className="otherGenome-label">
<Radio value={g} /> <span className="capitalize">{name}</span> <span className="italic">{g}</span>
</label>
);
});
return (
<RadioGroup
name="otherGenome"
selectedValue={this.state.otherGenome}
onChange={this.handleOtherGenomeChange}
className="otherGenome-container"
>
{radios}
</RadioGroup>
);
}
// renderOtherGenomes() {
// const genomeName = this.props.genomeConfig.genome.getName();
// const otherGenomes = allGenomes.map((g) => g.genome.getName()).filter((g) => g !== genomeName);
// const radios = otherGenomes.map((g) => {
// const { name } = getSpeciesInfo(g);
// return (
// <label key={g} className="otherGenome-label">
// <Radio value={g} /> <span className="capitalize">{name}</span> <span className="italic">{g}</span>
// </label>
// );
// });
// return (
// <RadioGroup
// name="otherGenome"
// selectedValue={this.state.otherGenome}
// onChange={this.handleOtherGenomeChange}
// className="otherGenome-container"
// >
// {radios}
// </RadioGroup>
// );
// }

changeGenome = () => {
this.props.onGenomeSelected(this.state.otherGenome);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import NumberConfig from "./NumberConfig";
*/
function HorizontalLineValueConfig(props) {
return (
<NumberConfig {...props} optionName="horizontalLineValue" label="Horizontal line value:" hasSetButton={true} />
<NumberConfig
{...props}
optionName="horizontalLineValue"
label="Horizontal line value:"
hasSetButton={true}
isFloat={true}
/>
);
}

Expand Down
63 changes: 55 additions & 8 deletions frontend/src/components/trackVis/3dmol/HoverInfo.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
import React from "react";
import { notify } from "react-notify-toast";
import ChromosomeInterval from "model/interval/ChromosomeInterval";
import ChromosomeInterval from "../../../model/interval/ChromosomeInterval";
import Feature from "../../../model/Feature";
import RegionSet from "../../../model/RegionSet";
import FlankingStrategy from "../../../model/FlankingStrategy";

export const HoverInfo = ({ atom, resolution, x, y, onNewViewRegion, viewRegion, removeHover, addToLabel }) => {
export const HoverInfo = ({
atom,
resolution,
x,
y,
onNewViewRegion,
viewRegion,
removeHover,
addToLabel,
selectedSet,
onSetSelected,
genomeConfig,
}) => {
if (!atom) return null;
const navContext = viewRegion.getNavigationContext();
const locus = new ChromosomeInterval(atom.chain, atom.properties.start, atom.properties.start + resolution);
Expand All @@ -16,6 +31,28 @@ export const HoverInfo = ({ atom, resolution, x, y, onNewViewRegion, viewRegion,
}
};

const addToRegionSetView = () => {
const atomFeature = new Feature(undefined, locus);
let newSet;
if (selectedSet) {
newSet = selectedSet.cloneAndAddFeature(atomFeature);
} else {
const currentChrInterval = viewRegion.getGenomeIntervals()[0];
const currentFeature = new Feature(undefined, currentChrInterval);
newSet = new RegionSet(
"3D set",
[currentFeature, atomFeature],
genomeConfig.genome,
new FlankingStrategy()
);
}
onSetSelected(newSet);
};

const closeSetView = () => {
onSetSelected(null);
};

const addAsShape = () => {
addToLabel([locus], true);
};
Expand Down Expand Up @@ -46,12 +83,22 @@ export const HoverInfo = ({ atom, resolution, x, y, onNewViewRegion, viewRegion,
<button className="btn btn-sm btn-primary" onClick={jumpToAtom}>
Browser region
</button>
<button className="btn btn-sm btn-success" onClick={addAsShape}>
Label as shape
</button>
<button className="btn btn-sm btn-info" onClick={addAsArrow}>
Label as arrow
</button>
<div style={{ display: "flex", gap: 5 }}>
<button className="btn btn-sm btn-success" onClick={addToRegionSetView}>
Add to set view
</button>
<button className="btn btn-sm btn-info" onClick={closeSetView}>
Close set view
</button>
</div>
<div style={{ display: "flex", gap: 5 }}>
<button className="btn btn-sm btn-success" onClick={addAsShape}>
Label as shape
</button>
<button className="btn btn-sm btn-info" onClick={addAsArrow}>
Label as arrow
</button>
</div>
<button className="btn btn-sm btn-seconday" onClick={removeHover}>
Close
</button>
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/components/trackVis/3dmol/ThreedmolContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2728,7 +2728,8 @@ class ThreedmolContainer extends React.Component {
spinSpeed,
spinReverse,
} = this.state;
const { tracks, x, y, onNewViewRegion, viewRegion, sync3d } = this.props;
const { tracks, x, y, onNewViewRegion, viewRegion, sync3d, onSetSelected, selectedSet, genomeConfig } =
this.props;
const bwTracks = tracks.filter((track) => getTrackConfig(track).isBigwigTrack());
return (
<div id="threed-mol-container">
Expand Down Expand Up @@ -3595,6 +3596,9 @@ class ThreedmolContainer extends React.Component {
onNewViewRegion={onNewViewRegion}
removeHover={this.removeHover}
addToLabel={this.addAnchors3dToMyArrows}
selectedSet={selectedSet}
onSetSelected={onSetSelected}
genomeConfig={genomeConfig}
/>
<div
className="box1"
Expand Down
Loading

0 comments on commit 819a669

Please sign in to comment.