Skip to content

Commit

Permalink
Merge pull request #1510 from adamabeshouse/expr-profiles
Browse files Browse the repository at this point in the history
coexpression and enrichment tabs - use same molecular profile options and component
  • Loading branch information
zhx828 authored Nov 9, 2018
2 parents 85654a3 + 559c4f5 commit 07525e8
Show file tree
Hide file tree
Showing 13 changed files with 173 additions and 94 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions end-to-end-tests/specs/screenshot.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ describe("enrichments tab screenshot tests", function() {
browser.click('a=mRNA');
browser.waitForVisible('div[data-test="MRNAEnrichmentsTab"]',20000);
browser.click('b=MERTK');
browser.waitForVisible('div[data-test="MiniBoxPlot"]', 20000);
var res = browser.checkElement('[data-test="enrichmentsTabDiv"]', { hide:['.qtip'] } );
assertScreenShotMatch(res);
});
Expand Down
91 changes: 55 additions & 36 deletions src/pages/resultsView/ResultsViewPageStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,10 +437,46 @@ export class ResultsViewPageStore {

public mutationAnnotationSettings:MutationAnnotationSettings;

@observable.ref selectedEnrichmentMutationProfile: MolecularProfile;
@observable.ref selectedEnrichmentCopyNumberProfile: MolecularProfile;
@observable.ref selectedEnrichmentMRNAProfile: MolecularProfile;
@observable.ref selectedEnrichmentProteinProfile: MolecularProfile;
@observable.ref public _selectedEnrichmentMutationProfile: MolecularProfile;
@observable.ref public _selectedEnrichmentCopyNumberProfile: MolecularProfile;
@observable.ref public _selectedEnrichmentMRNAProfile: MolecularProfile;
@observable.ref public _selectedEnrichmentProteinProfile: MolecularProfile;

@computed get selectedEnrichmentMutationProfile() {
if (!this._selectedEnrichmentMutationProfile && this.mutationEnrichmentProfiles.isComplete &&
this.mutationEnrichmentProfiles.result!.length > 0) {
return this.mutationEnrichmentProfiles.result![0];
} else {
return this._selectedEnrichmentMutationProfile;
}
}

@computed get selectedEnrichmentCopyNumberProfile() {
if (!this._selectedEnrichmentCopyNumberProfile && this.copyNumberEnrichmentProfiles.isComplete &&
this.copyNumberEnrichmentProfiles.result!.length > 0) {
return this.copyNumberEnrichmentProfiles.result![0];
} else {
return this._selectedEnrichmentCopyNumberProfile;
}
}

@computed get selectedEnrichmentMRNAProfile() {
if (!this._selectedEnrichmentMRNAProfile && this.mRNAEnrichmentProfiles.isComplete &&
this.mRNAEnrichmentProfiles.result!.length > 0) {
return this.mRNAEnrichmentProfiles.result![0];
} else {
return this._selectedEnrichmentMRNAProfile;
}
}

@computed get selectedEnrichmentProteinProfile() {
if (!this._selectedEnrichmentProteinProfile && this.proteinEnrichmentProfiles.isComplete &&
this.proteinEnrichmentProfiles.result!.length > 0) {
return this.proteinEnrichmentProfiles.result![0];
} else {
return this._selectedEnrichmentProteinProfile;
}
}

@computed get hugoGeneSymbols(){
if (this.oqlQuery.length > 0) {
Expand Down Expand Up @@ -2508,15 +2544,13 @@ export class ResultsViewPageStore {

readonly mutationEnrichmentProfiles = remoteData<MolecularProfile[]>({
await: () => [
this.molecularProfilesWithData,
this.molecularProfileIdToProfiledSampleCount
],
invoke: async () => {
return _.filter(this.molecularProfilesInStudies.result, (profile: MolecularProfile) =>
return _.filter(this.molecularProfilesWithData.result, (profile: MolecularProfile) =>
profile.molecularAlterationType === AlterationTypeConstants.MUTATION_EXTENDED);
},
onResult:(profiles: MolecularProfile[])=>{
this.selectedEnrichmentMutationProfile = profiles[0];
}
});

readonly mutationEnrichmentData = remoteData<AlterationEnrichment[]>({
Expand All @@ -2541,15 +2575,13 @@ export class ResultsViewPageStore {

readonly copyNumberEnrichmentProfiles = remoteData<MolecularProfile[]>({
await: () => [
this.molecularProfilesWithData,
this.molecularProfileIdToProfiledSampleCount
],
invoke: async () => {
return _.filter(this.molecularProfilesInStudies.result, (profile: MolecularProfile) =>
return _.filter(this.molecularProfilesWithData.result, (profile: MolecularProfile) =>
profile.molecularAlterationType === AlterationTypeConstants.COPY_NUMBER_ALTERATION && profile.datatype === "DISCRETE");
},
onResult:(profiles: MolecularProfile[])=>{
this.selectedEnrichmentCopyNumberProfile = profiles[0];
}
});

readonly copyNumberHomdelEnrichmentData = remoteData<AlterationEnrichment[]>({
Expand Down Expand Up @@ -2597,23 +2629,13 @@ export class ResultsViewPageStore {
}

readonly mRNAEnrichmentProfiles = remoteData<MolecularProfile[]>({
await: () => [
this.molecularProfileIdToProfiledSampleCount
],
invoke: async () => {
let profiles: MolecularProfile[] = _.filter(this.molecularProfilesInStudies.result,
(profile: MolecularProfile) => profile.molecularAlterationType === AlterationTypeConstants.MRNA_EXPRESSION
&& profile.datatype != "Z-SCORE");
// move rna_seq profiles at the top of the list to prioritize them
const rnaSeqProfiles = _.remove(profiles, (p) => {
return p.molecularProfileId.includes("rna_seq");
await:()=>[this.molecularProfilesWithData],
invoke:()=>{
const mrnaProfiles = this.molecularProfilesWithData.result!.filter(p=>{
return p.molecularAlterationType === AlterationTypeConstants.MRNA_EXPRESSION
});
profiles = rnaSeqProfiles.concat(profiles);
return profiles;
return Promise.resolve(filterAndSortProfiles(mrnaProfiles));
},
onResult:(profiles: MolecularProfile[])=>{
this.selectedEnrichmentMRNAProfile = profiles[0];
}
});

readonly mRNAEnrichmentData = remoteData<ExpressionEnrichment[]>({
Expand All @@ -2637,16 +2659,13 @@ export class ResultsViewPageStore {
});

readonly proteinEnrichmentProfiles = remoteData<MolecularProfile[]>({
await: () => [
this.molecularProfileIdToProfiledSampleCount
],
invoke: async () => {
return _.filter(this.molecularProfilesInStudies.result, (profile: MolecularProfile) =>
profile.molecularAlterationType === AlterationTypeConstants.PROTEIN_LEVEL && profile.datatype != "Z-SCORE");
await:()=>[this.molecularProfilesWithData],
invoke:()=>{
const protProfiles = this.molecularProfilesWithData.result!.filter(p=>{
return p.molecularAlterationType === AlterationTypeConstants.PROTEIN_LEVEL;
});
return Promise.resolve(filterAndSortProfiles(protProfiles));
},
onResult:(profiles: MolecularProfile[])=>{
this.selectedEnrichmentProteinProfile = profiles[0];
}
});

readonly proteinEnrichmentData = remoteData<ExpressionEnrichment[]>({
Expand Down
32 changes: 7 additions & 25 deletions src/pages/resultsView/coExpression/CoExpressionTab.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,21 @@
import * as React from "react";
import {
Gene, MolecularProfile, Mutation, NumericGeneMolecularData,
Sample
} from "../../../shared/api/generated/CBioPortalAPI";
import {action, autorun, computed, IReactionDisposer, observable, ObservableMap} from "mobx";
import {Gene, MolecularProfile} from "../../../shared/api/generated/CBioPortalAPI";
import {action, computed, observable} from "mobx";
import {observer, Observer} from "mobx-react";
import {AlterationTypeConstants, ResultsViewPageStore} from "../ResultsViewPageStore";
import Select from "react-select";
import DefaultTooltip from "../../../shared/components/defaultTooltip/DefaultTooltip";
import {remoteData} from "../../../shared/api/remoteData";
import internalClient from "../../../shared/api/cbioportalInternalClientInstance";
import {MobxPromise} from "mobxpromise";
import {CoExpression, CoExpressionFilter} from "../../../shared/api/generated/CBioPortalAPIInternal";
import _ from "lodash";
import {IDataQueryFilter} from "../../../shared/lib/StoreUtils";
import {MSKTab, MSKTabs} from "../../../shared/components/MSKTabs/MSKTabs";
import CoExpressionViz from "./CoExpressionViz";
import GeneMolecularDataCache from "../../../shared/cache/GeneMolecularDataCache";
import LoadingIndicator from "shared/components/loadingIndicator/LoadingIndicator";
import MutationDataCache from "../../../shared/cache/MutationDataCache";
import InfoIcon from "../../../shared/components/InfoIcon";
import {filterAndSortProfiles} from "./CoExpressionTabUtils";
import MobxPromiseCache from "../../../shared/lib/MobxPromiseCache";
import setWindowVariable from "../../../shared/lib/setWindowVariable";
import {ICoExpressionPlotProps} from "./CoExpressionPlot";
import {bind} from "bind-decorator";
import OqlStatusBanner from "../../../shared/components/oqlStatusBanner/OqlStatusBanner";
import {getMobxPromiseGroupStatus} from "../../../shared/lib/getMobxPromiseGroupStatus";
import MolecularProfileSelector from "../../../shared/components/MolecularProfileSelector";

export interface ICoExpressionTabProps {
store:ResultsViewPageStore;
Expand Down Expand Up @@ -131,13 +120,6 @@ export default class CoExpressionTab extends React.Component<ICoExpressionTabPro
if (this.selectedMolecularProfile &&
this.props.store.molecularProfileIdToProfiledSampleCount.isComplete &&
this.props.store.coexpressionTabMolecularProfiles.isComplete) {
let options = this.props.store.coexpressionTabMolecularProfiles.result.map(profile=>{
const profiledSampleCount = this.props.store.molecularProfileIdToProfiledSampleCount.result![profile.molecularProfileId];
return {
label: `${profile.name} (${profiledSampleCount} sample${profiledSampleCount !== 1 ? "s" : ""})`,
value: profile.molecularProfileId
};
});
return (
<div
style = {{
Expand All @@ -147,13 +129,12 @@ export default class CoExpressionTab extends React.Component<ICoExpressionTabPro
>
<span>Data Set:</span>
<div style={{display:"inline-block", width:376, marginLeft:4, marginRight:4, zIndex:10 /* so that on top when opened*/}}>
<Select
<MolecularProfileSelector
name="data-set-select"
value={this.selectedMolecularProfile.molecularProfileId}
onChange={this.onSelectDataSet}
options={options}
searchable={false}
clearable={false}
molecularProfiles={this.props.store.coexpressionTabMolecularProfiles.result}
molecularProfileIdToProfiledSampleCount={this.props.store.molecularProfileIdToProfiledSampleCount.result}
className="coexpression-select-profile"
/>
</div>
Expand Down Expand Up @@ -233,6 +214,7 @@ export default class CoExpressionTab extends React.Component<ICoExpressionTabPro
}
}


render() {
let divContents = null;
if (this.props.store.coexpressionTabMolecularProfiles.isComplete &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default class CopyNumberEnrichmentsTab extends React.Component<ICopyNumbe

@autobind
private onProfileChange(molecularProfile: MolecularProfile) {
this.props.store.selectedEnrichmentCopyNumberProfile = molecularProfile;
this.props.store._selectedEnrichmentCopyNumberProfile = molecularProfile;
}

public render() {
Expand All @@ -33,7 +33,7 @@ export default class CopyNumberEnrichmentsTab extends React.Component<ICopyNumbe
default:
return (
<div>
<EnrichmentsDataSetDropdown dataSets={this.props.store.copyNumberEnrichmentProfiles.result!} onChange={this.onProfileChange}
<EnrichmentsDataSetDropdown dataSets={this.props.store.copyNumberEnrichmentProfiles} onChange={this.onProfileChange}
selectedValue={this.props.store.selectedEnrichmentCopyNumberProfile.molecularProfileId}
molecularProfileIdToProfiledSampleCount={this.props.store.molecularProfileIdToProfiledSampleCount.result!}/>
<AlterationEnrichmentContainer data={this.props.store.copyNumberHomdelEnrichmentData.result!}
Expand Down
42 changes: 22 additions & 20 deletions src/pages/resultsView/enrichments/EnrichmentsDataSetDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import * as React from 'react';
import { observer } from "mobx-react";
import { observable } from 'mobx';
import {computed, observable} from 'mobx';
import { Checkbox, Button, Form, FormGroup, ControlLabel, FormControl } from 'react-bootstrap';
import styles from "./styles.module.scss";
import { MolecularProfile } from 'shared/api/generated/CBioPortalAPI';
import autobind from 'autobind-decorator';
import {filterAndSortProfiles} from "../coExpression/CoExpressionTabUtils";
import MolecularProfileSelector from "../../../shared/components/MolecularProfileSelector";
import {MobxPromise} from "mobxpromise";

export interface IEnrichmentsDataSetDropdownProps {
dataSets: MolecularProfile[];
dataSets: MobxPromise<MolecularProfile[]>;
onChange: (molecularProfile: MolecularProfile) => void;
selectedValue: string;
molecularProfileIdToProfiledSampleCount:{[molecularProfileId:string]:number};
Expand All @@ -17,33 +20,32 @@ export interface IEnrichmentsDataSetDropdownProps {
export default class EnrichmentsDataSetDropdown extends React.Component<IEnrichmentsDataSetDropdownProps, {}> {

@autobind
private change(e: any) {
this.props.onChange(this.props.dataSets.find(d => d.molecularProfileId === e.target.value)!);
private change(o: any) {
// at this point, we know dataSets is complete because otherwise this callback wouldnt be fired
this.props.onChange(this.props.dataSets.result!.find(d => d.molecularProfileId === o.value)!);
}

public render() {

if (this.props.dataSets.length === 1 && (this.props.dataSets[0].molecularAlterationType === "MUTATION_EXTENDED"
|| this.props.dataSets[0].molecularAlterationType === "COPY_NUMBER_ALTERATION")) {
if (this.props.dataSets.isComplete && this.props.dataSets.result!.length === 1 &&
(this.props.dataSets.result![0].molecularAlterationType === "MUTATION_EXTENDED"
|| this.props.dataSets.result![0].molecularAlterationType === "COPY_NUMBER_ALTERATION")) {
return null;
}

const options: JSX.Element[] = [];
this.props.dataSets.forEach(dataSet => {
const sampleCount = this.props.molecularProfileIdToProfiledSampleCount[dataSet.molecularProfileId];
options.push(<option value={dataSet.molecularProfileId}>{dataSet.name} ({sampleCount} sample{sampleCount !== 1 ? "s" : ""})</option>);
});

return (
<div className={styles.DataSet}>
<Form inline>
<FormGroup controlId="formControlsSelect" bsSize="small">
<ControlLabel>Data Set:</ControlLabel>
<FormControl componentClass="select" style={{marginLeft:5}} onChange={this.change} value={this.props.selectedValue}>
{options}
</FormControl>
</FormGroup>
</Form>
<div style={{display:"flex", alignItems:"center"}}>
<strong>Data Set:</strong>
<div style={{display:"inline-block", marginLeft:5, width:400}}>
<MolecularProfileSelector
value={this.props.selectedValue}
molecularProfiles={this.props.dataSets}
molecularProfileIdToProfiledSampleCount={this.props.molecularProfileIdToProfiledSampleCount}
onChange={this.change}
/>
</div>
</div>
</div>
);
}
Expand Down
6 changes: 3 additions & 3 deletions src/pages/resultsView/enrichments/MRNAEnrichmentsTab.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { observer } from "mobx-react";
import { ResultsViewPageStore } from "../ResultsViewPageStore";
import {AlterationTypeConstants, ResultsViewPageStore} from "../ResultsViewPageStore";
import { observable } from 'mobx';
import ExpressionEnrichmentContainer from 'pages/resultsView/enrichments/ExpressionEnrichmentsContainer';
import Loader from 'shared/components/loadingIndicator/LoadingIndicator';
Expand All @@ -18,7 +18,7 @@ export default class MRNAEnrichmentsTab extends React.Component<IMRNAEnrichments

@autobind
private onProfileChange(molecularProfile: MolecularProfile) {
this.props.store.selectedEnrichmentMRNAProfile = molecularProfile;
this.props.store._selectedEnrichmentMRNAProfile = molecularProfile;
}

public render() {
Expand All @@ -31,7 +31,7 @@ export default class MRNAEnrichmentsTab extends React.Component<IMRNAEnrichments

return (
<div data-test="MRNAEnrichmentsTab">
<EnrichmentsDataSetDropdown dataSets={this.props.store.mRNAEnrichmentProfiles.result!} onChange={this.onProfileChange}
<EnrichmentsDataSetDropdown dataSets={this.props.store.mRNAEnrichmentProfiles} onChange={this.onProfileChange}
selectedValue={this.props.store.selectedEnrichmentMRNAProfile.molecularProfileId}
molecularProfileIdToProfiledSampleCount={this.props.store.molecularProfileIdToProfiledSampleCount.result!}/>
<ExpressionEnrichmentContainer data={this.props.store.mRNAEnrichmentData.result!}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/resultsView/enrichments/MiniBoxPlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export default class MiniBoxPlot extends React.Component<IMiniBoxPlotProps, {}>
Boxplots of {this.props.selectedProfile.name} data for altered and unaltered cases
</div>
<div className="posRelative">
<div className="borderedChart inlineBlock posRelative">
<div className="borderedChart inlineBlock posRelative" data-test="MiniBoxPlot">
<DownloadControls
buttons={["SVG", "PNG", "Data"]}
getSvg={this.getSvg}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/resultsView/enrichments/MiniScatterChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export default class MiniScatterChart extends React.Component<IMiniScatterChartP
filename="enrichments-volcano"
dontFade={true}
collapse={true}
style={{position:"absolute", top:10, right:10}}
style={{position:"absolute", top:10, right:10, zIndex:0}}
/>
</div>
{this.tooltipModel &&
Expand Down
4 changes: 2 additions & 2 deletions src/pages/resultsView/enrichments/MutationEnrichmentsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default class MutationEnrichmentsTab extends React.Component<IMutationEnr

@autobind
private onProfileChange(molecularProfile: MolecularProfile) {
this.props.store.selectedEnrichmentMutationProfile = molecularProfile;
this.props.store._selectedEnrichmentMutationProfile = molecularProfile;
}

public render() {
Expand All @@ -30,7 +30,7 @@ export default class MutationEnrichmentsTab extends React.Component<IMutationEnr

return (
<div data-test="MutationEnrichmentsTab">
<EnrichmentsDataSetDropdown dataSets={this.props.store.mutationEnrichmentProfiles.result!} onChange={this.onProfileChange}
<EnrichmentsDataSetDropdown dataSets={this.props.store.mutationEnrichmentProfiles} onChange={this.onProfileChange}
selectedValue={this.props.store.selectedEnrichmentMutationProfile.molecularProfileId}
molecularProfileIdToProfiledSampleCount={this.props.store.molecularProfileIdToProfiledSampleCount.result!}/>
<AlterationEnrichmentContainer data={this.props.store.mutationEnrichmentData.result!}
Expand Down
Loading

0 comments on commit 07525e8

Please sign in to comment.